guide
Federation
Federation lets teams read separately owned context layers together without merging them or transferring responsibility for keeping them current.
Why compose instead of centralize
A context layer stays current because its owners read and correct it while they work. Centralizing another team's content separates it from the people accountable for it. Federation keeps each repository, owner, and review workflow intact. The rationale argues it fully.
What a sibling mount is
A sibling is another team's context layer, declared by the host in federation.mounts. The declaration pins the full immutable commit the host reads and records ownership and task routing. Tooling reads the sibling's manifest-defined layer projection at that pin into an ignored cache. It never copies sibling content into the host.
The projection is the union of what the sibling's own manifest makes readable at the pin: its leji.json, its context root, its boot profile, its category index files, the profiles its agents bindings name, its agent-profile and decision-record trees, its machine index and changelog, and every governed path its generated index lists, wherever those live.
A sibling usually sits inside a larger product repository, so that boundary is what stops a mount vendoring the product to read its context.
A mount is a reference, not a fork or an access grant. The sibling stays authoritative and its version control still decides who may read it. Mounting makes the relationship and its chosen revision legible to those who already have access.
"federation": {
"mounts": [
{
"name": "product-context",
"source": "https://github.com/acme/product-context",
"pin": "7d3f2a19c4e8b6a0d5f1c2e9b8a7f6d5c4b3a2e1", // full commit id: the version of record
"trackingRef": "refs/heads/main", // staleness is judged against this
"owner": { "name": "Product team", "contact": "product@acme.example" },
"role": "product-side context, owned by the product team",
// routing: when this mount is relevant to a task
"categories": ["domain", "decisions"],
"requiredWhen": ["a task changes how a plan or entitlement is represented"]
}
]
}Pin updates are reviewed changes to leji.json. The host declares the relationship; the sibling keeps its own repository, owner, review gate, changelog, and conformance claim.
Working the mounts
leji mounts hydrate --fetch # materialize each sibling's layer projection at its pin
leji mounts status # availability, integrity, and how far each pin is behind
leji mounts locate <name> # where a reader should read the sibling fromUse hydrate --fetch to materialize every projection at its pin, with an explicit network fetch. Usestatus to inspect availability, integrity, and pin staleness. Use locate to get the resolver-managed path where a reader should open one sibling.
Hydration publishes no partial projection. The cache sits under .leji/mounts/, which init adds to the root .gitignore. Treat that path as an implementation detail: locate reports where to read a sibling, and hardcoding a cache path breaks when publication changes.
The viewer shows the same state without a terminal. leji viewer generates a Manifest page graphing the host and its siblings, then a row per mount: availability, drift, owner, pin, and source. Regenerate it after hydrating.
Claiming federated
An unhydrated mount is a warning, never a build failure. CI can opt into availability enforcement with leji validate --federation=available|required. Ordinary validation does not fetch or require every mount.
Local availability is not conformance. The pin must be reachable from an advertised ref of source, which requires the network. Run leji conformance --federation=verify for that check. If the check cannot reach the source, it reports unknown; unknown never awards the level.
Verification is necessary, not sufficient. federated also requires that this context layer is itself consumed by another repository as a pinned mount, that stale-pin reporting is in place, and that the boot profile and generated index surface every sibling.
The first two are process-attested, so verifiedLevel never asserts them on your behalf. Materializing on one machine is not a conformance input.
Choose the distribution pattern first
A docs-only git submodule lets many repositories consume one context layer. Federation connects several teams that each already own one. These patterns answer different questions, so federation does not supersede the submodule. The adoption guide keeps the full submodule procedure.
Read distribution for the normative projection closure, failure boundary, and complete federation rules.