Agience Ember
An observer unit — the local leaf.
Ember runs on your machine, holds its own shards, answers from them, and reaches the mesh only on a miss. It is two-way: it serves your local services to the network, and the network to your local services.
Install
pip install agience-ember # the leaf
pip install 'agience-ember[optics]' # ...and the instrument that measures
Requires Python 3.11 or newer.
ember status # what this leaf holds, and whether it is seeded
ember ask "..." # answer from local shards, citing what it grounded on
ember ingest --anchors <path> ... # observe and describe into the durable store, then index
ember reindex --anchors <path> # rebuild the derived index from the store alone
ember serve # an OpenAI-compatible /v1 endpoint on 127.0.0.1:8091
--anchors is a path to the canonical AnchorSet artifact and is required on both ingest and
reindex. An anchor id is content-addressed over (label, model_id, embedding), so anchors are
provisioned rather than derived locally: a home-made set would route into cells no peer shares.
First light
A leaf runs disconnected and is initialised from outside, once. Two things have to arrive:
- The canonical AnchorSet — without it there is no routing.
- The authority's public key — without it a cached shard cannot be verified, and an unverified shard is a rumour rather than a cache.
seed(anchors, authority_pub) is an explicit call, and boot is purely local — tested by making
socket.connect raise — so startup is fast, offline, and cannot hang on a dead network.
Until it is seeded a leaf is uninitialised, which is its own condition with its own remedy. An
empty leaf answers "I don't hold that"; an uninitialised one cannot route, so status says which
it is.
Cache with a socket
Every shard is content-addressed and authority-signed, so a cached shard is exactly as trustworthy as the origin's, verified independently of who served it. Replication is blind: Ember can hold ciphertext it cannot read, decrypting only what the holder has grants for. Caching decisions and authorization decisions are therefore separable — a neighbourhood can be pre-warmed while reads stay bounded by grants.
| cache concern | mechanism |
|---|---|
| invalidation | monotonic version per region; gossip surfaces "newer exists" |
| working set / eviction | route_query_regions() — what answers a query is computable |
| refill source | the gossip directory ranks providers freshest → most-coherent → densest |
| integrity | Merkle content_root plus an Ed25519 authority signature |
A region id is a path of artifact identities — {principal}/{collection_id}/{anchor_id} — which is
why two nodes that never met agree on what a cell is called. Ember's local collection is an artifact
it authors, with id uuid5(principal), so one person's laptop and desktop derive the same id and
can sync directly.
Reasoning over evidence
Reasoning is lightweight. Knowledge lives in artifacts and is retrieved.
The engine's signature is the whole contract:
answer(query: str, evidence: Sequence[Evidence]) -> Answer
evidence is its only knowledge input, so a wrong answer can only come from wrong evidence — which
is inspectable, attributable and fixable.
Composing prose is a persona act, so ember.runtime.engine.build() raises NoAnswerer and an
answerer arrives by injection: Ember(..., engine=<answerer>). Left unwired, ask() reports that it
has no answer. EMBER_ENGINE is still read into settings, and selects nothing.
The local projection
A leaf embeds queries locally or disconnected operation is a fiction — but region ids are derived from the canonical anchors, so a leaf that embedded with its own model would mint its own ids and name cells nobody else uses. Its shards would be unshareable, silently, because routing would still appear to work.
So Ember caches the canonical AnchorSet and projects into it with a cross-walk: same dimension → orthogonal Procrustes, cross dimension → rectangular least squares. A 384-dim leaf routes against a 1024-dim canonical space and lands on the same region ids.
The fit is offline. An anchor carries both its label and its canonical embedding, so Ember
embeds the cached labels with its own model, pairs them against the canonical vectors already
present, and solves. The network is called only to learn about new anchors. "Small while
disconnected, upgrade during sync" is then: refresh the AnchorSet and refit.
The cross-walk is itself an artifact — derived data with provenance and a measured error_bound,
deterministic given (embedder, AnchorSet), so every leaf on the same embedder computes the identical
matrix. Fit once, publish, adopt. Its id includes an anchorset fingerprint, because a walk fitted
against older anchors still projects and still routes — into yesterday's cells. The fingerprint turns
that into an ordinary cache miss.
Semantic retrieval is the computed ontology coordinate: an exact Jiang–Conrath vector derived
from our own WordNet information content. HashEmbedder (ember.embed) is the deterministic
plumbing exerciser and is not a retrieval path.
The instrument
ember/optics.py is the one module here that imports entroptics, enforced by an AST test
(tests/test_one_instrument.py). It pins ENTROPTICS_REQUIRED = "0.2" and matches major.minor
exactly with patch floating, so a version skew fails at import rather than inside a reading.
The dependency is the [optics] extra: a node that carries frames installs the base, a node that
measures them installs [optics], and prism.instrument reports an absent measurement at the
point of measurement.
Importing ember registers the instrument as the process-default through a factory, so import ember loads numpy and entroptics only at the first measurement. The registration is process-global,
which is why an import ember line elsewhere is a host declaration and carries # noqa: F401 with a
header saying so.
Configuration
EMBER_CACHE_DIR · EMBER_PRINCIPAL · EMBER_COLLECTION_ID · EMBER_ENGINE · EMBER_EMBED_MODEL
· EMBER_CLOUD_URI · EMBER_NPROBE. The cache defaults to %LOCALAPPDATA%\agience-ember on
Windows and $XDG_CACHE_HOME/agience-ember elsewhere.
Layout
| module | role |
|---|---|
runtime/boot.py |
the assembly — Ember.boot() · .seed() · .connect() · .ask() · .remember() · .revise() · .status() |
runtime/read_path.py |
query → route → hit? answer local : miss → refill → answer |
runtime/relay.py |
the two-way channel: Channel · Disconnected · MeshChannel, transport injected |
runtime/engine.py |
the reasoning half; the answerer is injected |
runtime/seams.py |
the host seam table, bound at package scope so any process holding ember is a host |
config.py |
env-driven settings |
optics.py |
the instrument — the one module importing entroptics |
genesis.py |
the operator corpus and the provenance rungs |
ontology/ |
activation (spreading activation over the taxonomy), match (the propagation kernel and its measured constants), information, corpus_stats |
signal/ |
projection · forgetting · pooling · signal · state |
corpus/ |
ingest, the stage-0 sources and full-text search |
consolidate/ |
colimit and diagram |
surface/ |
serve (the inward HTTP direction), console, stats |
embed.py |
Embedder, HashEmbedder and the Aligner that fits the cross-walk |
cli.py |
the ember console script |
Status
Scaffold. The read path is real and tested disconnected, the cache survives a restart, and the
outward relay refill — miss → pull → verify → answer — is live over an injected transport, so it is
tested with no socket. The inward serve() direction is a seam.
To work on Ember itself, see CONTRIBUTING.md, which lists what the suite needs.
Security issues: email connect@agience.ai rather than opening a public issue.
Dual-licensed — see LICENSE, COMMERCIAL_LICENSE.md,
NOTICE and CLA.md.
Declaration of generative AI use
The author used Anthropic's Claude Opus (versions 4.8 and 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.
Metadata
Release files for agience-ember 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agience_ember-0.1.1.tar.gz | 813.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agience_ember-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 1.3 MB
Release files / agience_ember-0.1.1.tar.gz
| Download URL | agience_ember-0.1.1.tar.gz |
|---|---|
| Size | 813.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c2059b32c0b27a99ff2a2a67ea68b96f8a13b588d8a37db4fbb233368ead25b2
|
|
BLAKE2b-256 checksum How to use checksums |
b5c7e71c57c2c2452abef766f3dc855571ccce6242b09a4de07a54b8bdba4944
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.
Transparency logRelease files / agience_ember-0.1.1-py3-none-any.whl
| Download URL | agience_ember-0.1.1-py3-none-any.whl |
|---|---|
| Size | 473.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2111ee2210f697b8bb8501071bbd02732c32ced6c1371ba30a7a4af3b3cd61f8
|
|
BLAKE2b-256 checksum How to use checksums |
0824d4e9d7f1188cb1ca3564250bd28a83bd58c44bc1472e745c2e9add73a9e7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 17, 2026.
Transparency log