spec 1.0 · reference

The manifest: leji.json

The machine entrypoint of a Leji context layer. Lives at the repository root as leji.json.

The manifest is Leji's only fixed filename: the one file tooling can always expect at the repository root.

Field rows are generated from the schema, so nothing here drifts from the contract. This page covers top-level and selected nested fields; for deeper shapes such as an actor's roles and commands, read the schema itself. Required fields are marked.

Fields

#lejistringrequired

The Leji spec line this context layer targets, e.g. "1.0". The self-naming key follows the OpenAPI convention and identifies the file as a Leji manifest.

Pattern ^\d+\.\d+$

#namestringrequired

A short, stable identifier for this context layer, e.g. "acme-billing-context".

#descriptionstring

One-line summary of what this context layer covers.

#rootPathstringrequired

Context root, POSIX path relative to the repository root. Declares where the context layer lives; it does not re-base other paths: all paths in all Leji artifacts resolve from the repository root.

Pattern ^(?!/)(?!\./)(?!.*(^|/)\.\.(/|$))(?!.*\\).*$

#bootProfilePathstringrequired

Path to the boot profile, the agent-agnostic entrypoint every host and person starts from.

Pattern ^(?!/)(?!\./)(?!.*(^|/)\.\.(/|$))(?!.*\\).+\.md$

#categoriesobjectrequired

Logical category to index-file mapping. Keys are the five category identifiers; each maps to one or more curated index files that list the category's content.

Each key below takes the same shape:

indexesarray of stringsrequired

One or more repository-root-relative index files for this category. Each index file is curated markdown carrying a fenced `leji-index` block whose `- path: <dir-or-file>` lines select the content that belongs to this category. Content stays where it lives; the index file declares inclusion.

domainobject

Where domain content lives: business language and product semantics.

systemobject

Where system content lives: architecture and the invariants every change respects.

practiceobject

Where practice content lives: conventions and proven patterns.

governanceobject

Where governance content lives: agent guardrails and operating rules.

decisionsobject

Where decision records live: dated records of why things are the way they are.

#machineobject

Locations of the machine-readable artifacts: index, changelog, profiles, and decision records.

indexPathstring

Path to the generated context index.

changelogPathstring

Path to the machine-readable context changelog.

agentProfilesPathstring

Directory holding agent profile documents.

decisionRecordsPathstring

Directory holding decision records.

#agentsmap

Role to agent-profile binding. Keys are role identifiers (e.g. "thought-partner", "reviewer"); values are paths to agent profile documents. Protocols engage roles; this map decides who fills them.

#actorsmap

Optional registry of actors that can fill roles. Keys are stable actor identifiers. An actor declares the roles it is eligible for and a command template per role. Use it when a role has more than one eligible actor, or when one actor needs a different invocation depending on which role it is filling; either alone is reason enough. A role whose single actor needs only one command is served by the agent profile's own host and invocation.

#ownersobjectrequired

Who is accountable for the context layer's health. Owners answer for the context layer staying current and pruned; they do not author or curate it alone (governance.md).

Each key below takes the same shape:

namestringrequired

The person's name.

contactstring

How to reach them, e.g. an email address.

primaryobjectrequired

The person accountable for the context layer's currency. Ownerless context layers rot.

continuityobject

Optional. A different person who carries the same accountability when the primary is unavailable or steps away; assisted adoptions should name one before outside help leaves. Naming the primary again provides no continuity, and an agent cannot fill it: owners are accountable people.

#conformanceobject

The conformance level this context layer claims, checkable by tooling.

claimedLevel"core" · "indexed" · "governed" · "federated"

The conformance level claimed: core, indexed, governed, or federated.

claimedAtstring

ISO 8601 date the claim was last asserted.

#federationobject

Sibling layers mounted into this repository (spec: distribution.md pattern 3). The circle composes ownership; it doesn't centralize it.

mountsarray of objects

Each mount is a sibling context layer read at a pinned version through a resolver-hydrated layer projection, keeping its own repository, ownership, and review gate. Materialized content lives in the gitignored resolver cache, never committed here.

namestringrequired

The sibling layer's name; must match the `name` in the sibling's own manifest.

sourcestringrequired

Normalized repository locator of the sibling layer: an https://, ssh://, or SCP-style remote URL. The resolution root and the pin's namespace. Local filesystem paths are valid only in machine-local hints, never here.

pinstringrequired

Full immutable commit id (SHA-1 or SHA-256) of the sibling revision this host reads. Manifest-held desired state: pin updates are deliberate, reviewed curation.

trackingRefstring

Optional fully qualified witness ref on the source (refs/heads/* or refs/tags/*) that stale-pin reporting and federated reachability compare against. Absent, the source's advertised default branch is used and recorded in command output.

ownerobjectrequired

The owner of the sibling layer. Ownership stays with the sibling's team; the host never absorbs its content.

rolestring

What this sibling layer carries, in prose, e.g. "product-side context". For humans; routing uses the structured fields below.

categoriesarray of "domain" · "system" · "practice" · "governance" · "decisions"

The content-category scopes this sibling can answer for. Routing metadata only; the sibling's content stays in the sibling. Required for federated conformance.

topicsarray of strings

Short host-visible topic labels used to route a task to this sibling, e.g. "billing", "checkout". Routing metadata only.

requiredWhenarray of strings

Task conditions under which a reader must resolve this mount, or stop and report incomplete context if it cannot (fail closed). Host-visible; must not disclose anything the host's audience may not see.

#vendorAdaptersarray of strings

Vendor entrypoint files present in this repository; each must redirect to the boot profile.

#viewerobject

Presentation preferences read by `leji viewer`. Non-normative convenience configuration; presentation itself is out of normative scope.

portinteger

Preferred local-preview port for `leji viewer serve`. The --port flag overrides; the default is 5354 (LEJI on a phone keypad).

logostring

Logo image for the viewer, as a path under the context root (e.g. "assets/logo.svg"). Defaults to the Leji mark.

titlestring

Display title for the viewer (sidebar header and page title). Defaults to the context layer name.

agentsLabelstring

Sidebar label for the agent-profiles group (emoji welcome). Defaults to "🤖 Agents". The group lists the layer's agent profiles and is ordered by viewer.groupOrder like any other group.

faviconstring

Favicon for the viewer, as a path under the context root (e.g. "assets/icon.svg"). Defaults to the Leji mark.

homepagestring

The viewer's landing page, as a path relative to the context root (e.g. "README.md"). Defaults to the seeded overview.md.

pinsarray of items

Pages pinned at the top of the sidebar: repository-root-relative markdown paths, or {path, label} for a curated label. Pinning the boot profile replaces its default line.

groupOrderarray of strings

Curated sidebar group sequence, by exact group label (the index file's H1). Listed groups come first in this order; unlisted groups follow in derived order.

themeobject

Viewer theme overrides.

primarystring

Primary/accent color as a hex CSS color (e.g. "#009F71"). Drives links, the active state, and diagram accents.

mermaidboolean

Render fenced ```mermaid code blocks as diagrams in the viewer. Defaults to true.

poweredByboolean

Show the small "Powered by Leji" mark in the viewer's corner. Defaults to true; set false to remove it.

categoryEmojisobject

Override the default emoji shown beside each category in the generated layer map. (Sidebar groups are labeled by each index file's own H1.)

A worked example

A federated, organization-wide context layer that mounts a sibling, using far more of the manifest than a real one needs. Most context layers declare only the subset they use: leji init scaffolds a handful of these fields, and a core manifest is much shorter.

Two things about the shape are easy to misread: each category points at authored index files, not at content directories, and agents binds role identifiers to profile documents, a directory of roles rather than a load order, so binding one never causes it to be read.

{
  "$schema": "https://leji.org/schemas/v1.0/context-manifest.schema.json",
  "leji": "1.0",
  "name": "acme-context",
  "description": "Organization-wide context layer for Acme: consumed by product repos and composing one sibling layer.",
  "rootPath": "docs/",
  "bootProfilePath": "docs/boot-profile.md",
  "categories": {
    "domain": {
      "indexes": [
        "docs/context/domain.md"
      ]
    },
    "system": {
      "indexes": [
        "docs/context/system.md"
      ]
    },
    "practice": {
      "indexes": [
        "docs/context/practice.md"
      ]
    },
    "governance": {
      "indexes": [
        "docs/context/governance.md"
      ]
    },
    "decisions": {
      "indexes": [
        "docs/context/decisions.md"
      ]
    }
  },
  "machine": {
    "indexPath": "docs/context-index.json",
    "changelogPath": "docs/context-changelog.json",
    "agentProfilesPath": "docs/agents/",
    "decisionRecordsPath": "docs/decisions/"
  },
  "agents": {
    "core": "docs/agents/core.md",
    "reviewer": "docs/agents/reviewer.md"
  },
  "owners": {
    "primary": {
      "name": "Sam Park",
      "contact": "sam@acme.example"
    },
    "continuity": {
      "name": "Ada Okafor",
      "contact": "ada@acme.example"
    }
  },
  "conformance": {
    "claimedLevel": "federated",
    "claimedAt": "2026-06-12"
  },
  "federation": {
    "mounts": [
      {
        "name": "acme-product-context",
        "source": "https://github.com/acme/product-context",
        "pin": "7d3f2a19c4e8b6a0d5f1c2e9b8a7f6d5c4b3a2e1",
        "trackingRef": "refs/heads/main",
        "owner": {
          "name": "Product team",
          "contact": "product@acme.example"
        },
        "role": "product-side context, owned and curated by the product team",
        "categories": [
          "domain",
          "decisions"
        ],
        "topics": [
          "pricing",
          "entitlements",
          "billing plans"
        ],
        "requiredWhen": [
          "a task changes how a plan, price, or entitlement is represented"
        ]
      }
    ]
  },
  "vendorAdapters": [
    "CLAUDE.md",
    "AGENTS.md"
  ],
  "viewer": {
    "port": 5354,
    "title": "Acme Billing",
    "logo": "assets/brand.svg",
    "favicon": "assets/icon.svg",
    "pins": [
      "docs/dashboard.md",
      "docs/TODO.md"
    ],
    "theme": {
      "primary": "#009F71"
    }
  }
}

See the machine-readable surface for how the manifest relates to the index, changelog, and profiles, and versioning for the leji spec-line key.