Observed since 21 Oct, 09:04 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
agience-chorus
Agience Chorus — the tekton standard library: operators by domain, and the host that serves them.
Operators, by domain. Chorus is the tekton standard library: seven MCP services, each holding the operators of one domain, served from one host or deployed one at a time.
A tekton is a chorus member — a condensor whose tools are organons, invoked by condensation.
Each declares a module-level PERSONA in its own server.py, and
src/agience_chorus/personas.py discovers them and hands the roster to the host:
| tekton | domain | mount |
|---|---|---|
| aria | Presentation & Interface | /aria/mcp |
| astra | Ingestion & Indexing | /astra/mcp |
| sage | Research & Retrieval | /sage/mcp |
| iris | Routing & Communication | /iris/mcp |
| ophan | Economic Operations | /ophan/mcp |
| seraph | Security & Governance | /seraph/mcp |
| lumen | Wisdom & Inference | /lumen/mcp |
Tektons are reached over the wire — HTTP and MCP — and are independently deployable, so an operator runs only the ones they need. Each constructs its own server auth and signs with its own identity, and no tekton imports another.
pip install agience-chorus # every tekton
pip install "agience-chorus[iris,seraph]" # only what those two need
python -m agience_chorus.server # every tekton on one process, :8082
MCP_HOST (default 0.0.0.0), MCP_PORT (default 8082) and LOG_LEVEL (default INFO)
configure the host. uvicorn agience_chorus.server:app resolves too — the app is built at import
time. CHORUS_CRYSTALS=aria,seraph boots a node holding a subset.
The import name is agience_chorus, and the tektons are subpackages of it —
agience_chorus.aria, .astra, .iris, .lumen, .ophan, .sage, .seraph.
The extras select dependencies, not modules. agience-chorus[ophan] installs all seven tektons
and adds Stripe; Python has no mechanism for an extra to exclude code. What it saves is real, all
the same: a node running only iris and seraph otherwise installs Stripe, HuggingFace datasets,
pypdf, sympy and numpy to run none of them. Whether an operator may discharge is still the
capability gate's answer, not the installer's.
For a checkout, pip install -e ".[all,dev]" — which is what requirements.txt
resolves to.
pytest -q src tests --rootdir=src
Both paths, and --rootdir=src, are load-bearing. Each tekton carries its own pyproject.toml,
so without the flag pytest picks one of them as the rootdir and src/conftest.py
— which wires the organons — never loads; the symptom is a phantom _op_retrieve is None rather
than an error naming the cause.
pytest tests/ on its own does not work, and the way it fails is misleading: it stops at a
collection error on import seraph.server, which reads like a broken test. The import is correct
(seraph is its own distribution, agience-server-seraph); what is missing is the environment the
invocation above sets up. Verified 2026-09-16 — under the full command that file collects and its
twenty tests pass. Reach for the whole command before concluding anything from a subset that fails.
src/agience_chorus/bundles/ holds the operator payloads, one JSON
per group, built from the sources named in
src/agience_chorus/seraph/bundle_spec.json. Each
carries a sha256 that the mesh publishes.
They live inside the package so the wheel carries them: the runtime executes the payload, so an installed chorus without them could not discharge an operator at all.
The runtime reads the payload, not the source file. An edit to a tekton that is not rebuilt has
no effect, and the published sha then disagrees with the tree.
src/tests/test_bundles_match_source.py fails when they drift.
| path | what it is |
|---|---|
src/agience_chorus/<tekton>/server.py | one deployable tekton service, with its own manifest.py, tests/ and ui/ |
src/agience_chorus/<tekton>/ui/<top>/<sub>/type.json | the content types that tekton owns; it registers them with the gateway at host startup |
src/agience_chorus/server.py | the unified host, mounting every tekton on one process |
src/agience_chorus/_chorus_identity.py · _persona.py · _host_seams.py | the identity, artifact and host-seam helpers tektons load at runtime |
src/agience_chorus/reach_host.py · reach_wiring.py · reading_junction.py | the reach surfaces shared across tektons |
src/agience_chorus/personas.py | tekton discovery and host binding: module loading, service-identity boot, and the roster the host consumes |
src/agience_chorus/corpus_fts.py · corpus_stats.py · live_service.py | the corpus and live-service surfaces shared across tektons |
src/conftest.py · src/tests/ | the test process's environment, and the cross-tekton suite — outside the package, so neither ships |
tests/ | the repo-level invariants, one file per property: that every persona transport verifies its caller, that no persona shells out, that the runtime data a node reads is declared package-data, and that the Facet source tree stays out of the distribution. Each names the incident it exists for |
pyproject.toml | the distribution: dependencies, per-tekton extras, and what goes in the wheel |
A tekton's answer path is grounded operators over the artifact graph, so nothing imports a
judgement made elsewhere that a caller cannot re-derive. Reaching a model stays legitimate as a
deliberate act through a tekton that offers it, where the call is explicit and the provenance
records who chose it. resolve_llm_credentials in
src/agience_chorus/seraph/server.py raises and names the
rule in the @mcp.tool description a caller reads.
Security issues: email connect@agience.ai rather than opening a public issue.
Dual-licensed — see LICENSE, COMMERCIAL_LICENSE.md,
NOTICE and CLA.md.
The author used Anthropic's Claude Opus (versions 4.8, 5, and 5.5) in the preparation of this work. Its contribution was to write code, and to generate and validate content. The ideas, the construction and the claims are the author's. No other generative AI tool was used. The author reviewed and edited all output and takes full responsibility for the content of this publication.
Download counts and popularity will appear here as the collector receives them.
| Package / target | Requirement | Relationship |
|---|---|---|
mcpEnvironment{
"extras": "cli",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | mcp[cli]<2,>=1.6.0 | runtime |
httpxEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | httpx>=0.27 | runtime |
fastapiEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | fastapi>=0.115 | runtime |
starletteEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | starlette>=0.37 | runtime |
uvicornEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | uvicorn>=0.30 | runtime |
cryptographyEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | cryptography>=42.0 | runtime |
python-joseEnvironment{
"extras": "cryptography",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | python-jose[cryptography]>=3.3 | runtime |
pydanticEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pydantic>=2.0 | runtime |
agience-prismEnvironment{
"extras": "trust,wire",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | agience-prism[trust,wire]>=0.1.4 | runtime |
agience-crystalEnvironment{
"extras": "ontology,service",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | agience-crystal[ontology,service]>=0.1.0 | runtime |
agience-mantleEnvironment{
"extras": "",
"marker": null,
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | agience-mantle>=0.1.3 | runtime |
pypdfEnvironment{
"extras": "",
"marker": "extra == \"astra\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pypdf>=5.0; extra == "astra" | runtime |
numpyEnvironment{
"extras": "",
"marker": "extra == \"astra\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | numpy>=1.24; extra == "astra" | runtime |
datasetsEnvironment{
"extras": "",
"marker": "extra == \"astra\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | datasets>=2.14; extra == "astra" | runtime |
numpyEnvironment{
"extras": "",
"marker": "extra == \"lumen\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | numpy>=1.24; extra == "lumen" | runtime |
sympyEnvironment{
"extras": "",
"marker": "extra == \"lumen\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | sympy>=1.12; extra == "lumen" | runtime |
sympyEnvironment{
"extras": "",
"marker": "extra == \"sage\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | sympy>=1.12; extra == "sage" | runtime |
stripeEnvironment{
"extras": "",
"marker": "extra == \"ophan\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | stripe>=9.0; extra == "ophan" | runtime |
agience-chorusEnvironment{
"extras": "aria,astra,iris,lumen,ophan,sage,seraph",
"marker": "extra == \"all\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | agience-chorus[aria,astra,iris,lumen,ophan,sage,seraph]; extra == "all" | runtime |
pytestEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest>=8; extra == "dev" | runtime |
pytest-asyncioEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest-asyncio>=0.23; extra == "dev" | runtime |
pytest-timeoutEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | pytest-timeout>=2.2; extra == "dev" | runtime |
buildEnvironment{
"extras": "",
"marker": "extra == \"dev\"",
"requires_python": ">=3.11",
"evaluation": "NOT_EVALUATED"
} | build>=1.0; extra == "dev" | runtime |
bdist_wheel · 985.6 KB · Python py3
sdist · 881.46 KB · Python source
Observed since 21 Oct, 09:04 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package_version:da8caca146119e58a31ed8fc15b2acef3dcbe89ef867e5f72a2e42f59cfde7a4