spec 1.0 · normative

The Context Layer

A Leji context layer is a versioned, governed set of human-readable documents that encodes how a team thinks about its work: domain language, system invariants, conventions, guardrails, and decision records. People and agents both read it in the course of real work, and both propose changes to it through the same review gate. It lives under version control so that history, currency, and approval stay verifiable; the mechanics are in Requirements below, and who takes part and how is in Participation.

Participation#

Participation in a context layer is role-based, not tool-based. Reading, proposing, reviewing, and approving happen through whatever interface preserves the repository’s review and approval semantics; direct git or command-line knowledge is not required to take part.

  • Everyone with access reads. Access means practical access through the team’s normal tools, not shell access to the repository.
  • Anyone proposes; people approve. A proposal is an intentional request to change the context layer. It MAY be authored directly by a person, generated by an agent from a person’s request, or generated by an agent from observed work. In practice agents draft most context changes; the irreducibly human contribution is governance: proposing intent and approving what becomes canonical. A person approving a change is accountable for its meaning and consequence, not for personally operating the version control system.
  • Human meaning, machine-readable surface. The human-readable documents are the normative source of a team’s operating context. The machine-readable files (manifest, index, changelog) exist so tools can locate, index, validate, and synchronize that meaning; they never replace it.

The normative form of these flows, the circle (everyone reads, anyone proposes, people approve), is defined in governance.md.

Reading a record#

Governed content comes in two kinds, defined in content-categories.md: intent, maintained as present truth, and records, dated evidence that later state supersedes rather than corrects. Both are equally governed; what differs is what a reader may do with what it loads. A reader MUST NOT treat a record as current intent: a record informs with the standing of evidence true within its stated boundary, and a reader that presents a record’s claims as the present state of things, without saying so, is manufacturing currency the document does not have. This mirrors the degraded-mode rule below: in both cases, the reader’s obligation is to know, and to say, what kind of currency it is holding.

Requirements#

  1. The context layer MUST live in a git repository and MUST be versioned with the work it describes (same repo, or a dedicated context repository consumed per distribution.md). The git repository is what makes the context layer’s history, checkout currency, and append-only changelog integrity verifiable; conforming tooling derives all three from it. Reading the context layer without that repository is a supported but degraded mode, defined in Reading modes.

  2. A repository adopting Leji MUST carry a manifest file, leji.json, at the repository root, valid against context-manifest.schema.json. The manifest is the machine entrypoint: it declares the spec version (the self-naming leji key), the context layer name, the context root, the boot profile path, the category mappings, an optional conformance claim, and ownership. It MAY also carry an agents map binding role identifiers (e.g. thought-partner, reviewer) to agent profile documents: protocols engage roles; the map decides who fills them. The map is a directory of roles, not a load order: a binding, including one at the default key, never causes a profile to be read; only the boot profile’s Loading section does that.

  3. The manifest MAY declare actors: named participants that can fill roles. Each actor declares the roles it is eligible for and a command template per role. Keying the command by role is the point: one actor can require a different invocation depending on which role it is filling, so a single command per actor cannot express it. An actor’s declared roles and its command keys MUST be the same set. Where a role has actors, its bound agent profile MUST NOT also declare invocation: two authoritative commands with no stated precedence is a contradiction, and the layer resolves it by declaring the command in one place. Actors are optional and most layers need none. They earn their place when a role has more than one eligible actor, or when one actor needs a different invocation depending on the role it is filling; either alone is reason enough, and a role whose single actor needs only one command is served by the profile’s own host and invocation. Declaring an actor grants no authority: it says who may be asked to fill a role, never who may approve.

    Command templates, wherever they appear (an actor’s commands values and an agent profile’s invocation.command), follow one rule. A template is a command line for the shell the invoker selects; engagement that is not shell-shaped (a structured argv call, an in-process spawn) is not representable by these fields in the 1.0 line. Every template MUST carry the <prompt> placeholder, and each occurrence MUST stand as its own unquoted shell word in an argument position, never inside quotes or joined to other text. Substitution is one-pass: the occurrences present in the authored template are replaced simultaneously, exactly once, so the literal string <prompt> inside prompt text stays data and is never re-expanded. The invoker owns delivery, and the required outcome, not the quoting algorithm, is the contract: each occurrence yields exactly one argument whose value equals the prompt text, with none of it evaluated as shell syntax. What the schemas verify is the presence of a substitution site; placement and delivery are this rule’s to require and the invoker’s to honor.

  4. The manifest MUST declare a context root (rootPath). The RECOMMENDED default is docs/. All context layer paths are POSIX-style, relative to the repository root. rootPath declares where the context layer lives; it does not re-base other paths: every path in every Leji artifact resolves from the repository root, including those that repeat the rootPath prefix. Category and machine paths SHOULD fall under rootPath; validators warn when they don’t.

  5. The context layer MUST have a boot profile per boot-profile.md. The RECOMMENDED default location is docs/boot-profile.md; the manifest’s bootProfilePath declares the actual location.

  6. Context layer content MUST be human-readable first. Markdown is the RECOMMENDED format for prose; structured metadata uses YAML frontmatter or the JSON artifacts defined in machine-readable-surface.md. A document that only a machine can read doesn’t belong in the context layer.

  7. The context layer MUST have a named owner (owners.primary in the manifest): a person accountable for its currency. Ownerless context layers rot.

Reading modes: canonical and degraded#

A context layer is read in two modes; a reader MUST know which mode it is in, because the guarantees differ. A reader determines its mode from what it can resolve: a reachable leji.json at the repository root and either a git working tree or the host platform’s repository revision identity is canonical; content reached as plain files with neither is degraded.

  1. Canonical. The reader resolves the context layer through its git repository: a checkout, or the repository view of the host platform. History, checkout currency, and changelog integrity are verifiable, and approved content is known current to the revision read.
  2. Degraded. The reader reaches the context layer as plain file content with no accessible git working tree or version metadata: files uploaded, synced, or copied into another interface without the repository. Plain-file reading is first-class for reading (the documents are human-readable by requirement, and the machine-readable changelog still conveys declared recency), but a degraded reader MUST treat checkout currency and approval state as unknown, never as current (see governance.md, Freshness). The changelog is the portable declared-recency surface in this mode; it does not by itself establish that the copy matches the canonical repository.

Degraded reading widens who and what can consume a context layer; it is never a path to canonical authority. A change becomes canonical only through the git-backed review gate, and a degraded copy cannot satisfy the canonical-mode checks federation depends on (pin currency, stale-pin status, ownership intactness, and restricted-mount access per distribution.md).

The vendor-adapter rule#

Agent-host configuration files (for example CLAUDE.md, AGENTS.md, GEMINI.md, .cursorrules, .cursor/rules, .windsurfrules, .github/copilot-instructions.md):

  1. MUST NOT hold canonical context layer content.
  2. If present, MUST redirect to the boot profile (typically a one-line pointer).
  3. MAY carry host-specific mechanics that have no meaning outside that agent host (model selection, runner settings), provided no team knowledge lives there.
  4. Tooling discovers which entrypoints to check from two sources: the manifest’s optional vendorAdapters list, and a published well-known set (the files named above). The example list above is that well-known set for this line; a host whose entrypoint is not in it is checked only when the manifest names it in vendorAdapters.

The entrypoint conventions that exist tell an agent host where to look; Leji defines what the agent finds there. One source of truth, every participant reading it.

What the context layer is not (non-normative)#

  • Not a wiki. Nothing forces a wiki current. The context layer stays alive because agents read it on every task (wrong context produces wrong output that is felt immediately), changes ride review like code, and tooling makes staleness visible.
  • Not documentation in the traditional sense. Documentation describes what the system does, after the fact. The context layer describes how the team thinks, in the present tense, and is read constantly by people and agents alike.
  • Not a template to import. Borrowed context goes stale immediately. The value of a context layer is that it is the team’s own representation; Leji standardizes the shape and the governance, not the contents.