Agience Crystal
Condensation and routing — signal to content type.
Crystal condenses incoming signal into typed content and routes it. As the dispatcher/gateway it maps a request by its content type to one of the chorus tekton services (aria, astra, iris, lumen, ophan, sage, seraph) and carries the gateway concerns: identity, topology, and the MCP client.
It reaches everything over the wire; nothing links it. Origin is called at ORIGIN_URI over
HTTP, and the store is injected by the host rather than imported — crystal imports neither.
Install
pip install agience-crystal # the contract and the ontology driver
pip install agience-crystal[service] # the gateway that boots — fastapi, uvicorn, httpx, …
pip install agience-crystal[ontology] # adds the coordinate, and numpy with it
The three are a measured split, not a preference. 23 of crystal's 34 non-test modules import on
agience-prism and the stdlib alone; 11 are the ones that serve, and those are what [service]
carries. [ontology] is separate again because crystal.ontology.geometry imports numpy at module
scope, and a gateway that never computes a coordinate should not install it.
Requires Python 3.11 or newer. The one base dependency is
agience-prism, Apache-2.0, whose own base install has
no dependencies at all.
Run it
Crystal is two servable surfaces on the same package, and they are different jobs.
The gateway — routes a request by content type to the tekton that owns it:
pip install 'agience-crystal[service]'
CRYSTAL_HOST=127.0.0.1 CRYSTAL_PORT=8085 \
MANTLE_URI=http://localhost:8082 ORIGIN_URI=http://localhost:8080 \
python -m crystal.main
The host — serves a set of tektons discovered at boot, assembling each with an embodiment:
MCP_HOST=127.0.0.1 MCP_PORT=8086 python -m crystal.host
Bind loopback and put a reverse proxy in front of anything public.
Configuration is the environment, and it is read in two places:
| read by | variables |
|---|---|
config.py — the gateway |
CRYSTAL_HOST, CRYSTAL_PORT (8085), CRYSTAL_EVENTS_ENABLED, MANTLE_URI, MANTLE_API_KEY, ORIGIN_URI, KEYS_DIR, EMBEDDINGS_URI, EMBEDDINGS_API_KEY, TYPE_CONTENT_TYPE, LOG_LEVEL |
host.py — the tekton host |
MCP_HOST, MCP_PORT, CRYSTAL_UPSTREAMS, CRYSTAL_APEX_PERSONA, CRYSTAL_HOST_DOMAIN, CRYSTAL_TLS_CERT, CRYSTAL_TLS_KEY, LOG_LEVEL |
type_registration.py additionally reads CRYSTAL_URI, CHORUS_PUBLIC_URI and
AGIENCE_SERVER_HOST_URI when a tekton pushes its types.
A gateway with no Mantle and no Origin still starts; it answers what it can reach.
The embodiment is injected, never imported
import crystal pulls no instrument and no numpy — checked in CI on a bare install, not asserted
here. The embodiment that measures arrives from the host at assembly, which is what lets the same
crystal run on a full node and on a constrained store. The two test files that do reach an
instrument (tests/test_crystal.py, tests/test_embodiment_injection.py) are where the host lives:
they assemble a real node, and that reach is test-only by design.
Layout
| Path | Purpose |
|---|---|
src/crystal/ |
The dispatcher/gateway service — dispatch, identity, topology, MCP client, registries, host and entrypoint. |
src/crystal/ontology/ |
The coordinate: coupling, geometry, lookup, freshness, transducer. Behind the ontology extra, because geometry imports numpy at module scope. |
src/types/ |
Builtin content-type skeletons — type.json plus optional schema.json, behaviors.json, preview.json and handlers/. Repository content, read by a test; not shipped in the wheel, because nothing at runtime loads it from the package. |
tests/ |
The suite, including the ratchets that hold the import boundaries above. |
pyproject.toml |
Build, packaging and every dependency. There is no requirements.txt — the service extra is the one list. |
A tekton owns its own types. Each one ships ui/<top>/<sub>/type.json and pushes it to the
gateway's /register endpoint at host startup, signed with a service JWT. Types and tektons are
gateway state; the store never sees them.
Where it sits
agience-prism the contract, dependency-free crystal depends on it
agience-crystal this repository the gateway
agience-ember the observer unit depends on crystal, never the reverse
agience-mantle the store reached over the wire, never imported
Crystal is below ember and mantle in the dependency graph. That direction is what the licence section below is about.
Contributing
See CONTRIBUTING.md. The suite needs two things the package does not — an
AGIENCE_BUNDLE_ROOT and an installed agience-ember — and that file says why.
License
Apache-2.0 (see LICENSE and NOTICE).
The permissive licence is load-bearing, and pyproject.toml argues it at length: pip install agience-crystal must not resolve copyleft onto the install path. That is why crystal declares no
dependency on ember even though ember sits above it. A dependency that would pull a copyleft package
onto the install path is a design conversation, not a dependency bump.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agience_crystal-0.1.0.tar.gz.
File metadata
- Download URL: agience_crystal-0.1.0.tar.gz
- Upload date:
- Size: 253.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d08870ab8bf69179bcfd8c7baafce9b1eab402a5c276e41739ebb2dd06530a4
|
|
| MD5 |
8bd3f0f2e874aaa7895740e256081b22
|
|
| BLAKE2b-256 |
d9f45b5b79589d6ed1348ecc4293336e6091b91b64ace6835ca318bbc89621f4
|
Provenance
The following attestation bundles were made for agience_crystal-0.1.0.tar.gz:
Publisher:
publish.yml on Agience/agience-crystal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agience_crystal-0.1.0.tar.gz -
Subject digest:
4d08870ab8bf69179bcfd8c7baafce9b1eab402a5c276e41739ebb2dd06530a4 - Sigstore transparency entry: 2741749075
- Sigstore integration time:
-
Permalink:
Agience/agience-crystal@85f2f459708e9ebb6c3b2563f4dd4d4a1290b1c4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Agience
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@85f2f459708e9ebb6c3b2563f4dd4d4a1290b1c4 -
Trigger Event:
push
-
Statement type:
File details
Details for the file agience_crystal-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agience_crystal-0.1.0-py3-none-any.whl
- Upload date:
- Size: 174.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d5154a168680190d7ca4a63811a5ba197c0ac67c0916ed909d13f1589ddb99c8
|
|
| MD5 |
4ce318f96830169f09e9abd2a56dcf30
|
|
| BLAKE2b-256 |
5979e6de64c9c8d95cee91c1e45c1ee8ffe21be0eaa457f6d97b4ce6da296cde
|
Provenance
The following attestation bundles were made for agience_crystal-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Agience/agience-crystal
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
agience_crystal-0.1.0-py3-none-any.whl -
Subject digest:
d5154a168680190d7ca4a63811a5ba197c0ac67c0916ed909d13f1589ddb99c8 - Sigstore transparency entry: 2741749125
- Sigstore integration time:
-
Permalink:
Agience/agience-crystal@85f2f459708e9ebb6c3b2563f4dd4d4a1290b1c4 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Agience
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@85f2f459708e9ebb6c3b2563f4dd4d4a1290b1c4 -
Trigger Event:
push
-
Statement type: