spec 1.0 · normativo
Manifesto de contexto do Leji (leji.json)
Tradução assistida por agentes de IA. Em caso de divergência, prevalece a página em inglês. Se você encontrar algum problema no texto, abra uma issue ou envie um pull request.
O ponto de entrada de máquina de uma camada de contexto Leji. Fica na raiz do repositório, com o nome leji.json.
Campos
- #
lejistringobrigatório A linha da especificação Leji que esta camada de contexto tem como alvo, por exemplo "1.0". A chave que dá nome a si mesma segue a convenção do OpenAPI e identifica o arquivo como um manifesto Leji.
Padrão
^\d+\.\d+$- #
namestringobrigatório Um identificador curto e estável para esta camada de contexto, por exemplo "acme-billing-context".
- #
descriptionstring Resumo em uma linha do que esta camada de contexto cobre.
- #
rootPathstringobrigatório A raiz do contexto, um caminho POSIX relativo à raiz do repositório. Ela declara onde a camada de contexto vive; ela não recalcula os caminhos que governa: as entradas do índice, as páginas fixadas, os caminhos dos perfis e todo outro caminho dos artefatos Leji são resolvidos a partir da raiz do repositório. O
homepage, ologoe ofavicondo visualizador são a exceção: eles são escritos relativos à raiz do contexto, e um caminho relativo à raiz do repositório que fique sob ela também é aceito.Padrão
^(?!/)(?!\./)(?!.*(^|/)\.\.(/|$))(?!.*\\).*$- #
bootProfilePathstringobrigatório O caminho até o perfil de boot, o ponto de entrada independente de agente por onde toda pessoa e todo host começam.
Padrão
^(?!/)(?!\./)(?!.*(^|/)\.\.(/|$))(?!.*\\).+\.md$- #
categoriesobjectobrigatório O mapeamento de cada categoria lógica para os arquivos de índice dela. As chaves são os cinco identificadores de categoria; cada uma aponta para um ou mais arquivos de índice curados que listam o conteúdo daquela categoria.
indexesarray de stringsobrigatórioUm ou mais arquivos de índice desta categoria, com caminhos relativos à raiz do repositório. Cada arquivo de índice é markdown curado que carrega um bloco
leji-indexcercado, cujas linhas- path: <diretório-ou-arquivo>selecionam o conteúdo que pertence a esta categoria. O conteúdo permanece onde vive; o arquivo de índice apenas declara a inclusão.domainobjectOnde vive o conteúdo de domain: a linguagem do negócio e a semântica do produto.
systemobjectOnde vive o conteúdo de system: a arquitetura e os invariantes que toda mudança respeita.
practiceobjectOnde vive o conteúdo de practice: as convenções e os padrões já comprovados.
governanceobjectOnde vive o conteúdo de governance: as travas de proteção dos agentes e as regras de operação.
decisionsobjectOnde vivem os registros de decisão: os registros datados de por que as coisas são como são.
- #
machineobject Onde ficam os artefatos legíveis por máquina: o índice, o changelog, os perfis e os registros de decisão.
indexPathstringO caminho até o índice de contexto gerado.
changelogPathstringO caminho até o changelog de contexto legível por máquina.
agentProfilesPathstringO diretório que guarda os documentos de perfil de agente.
decisionRecordsPathstringO diretório que guarda os registros de decisão.
- #
agentsmapa A associação entre papel e perfil de agente. As chaves são identificadores de papel (por exemplo "thought-partner", "reviewer"); os valores são caminhos até documentos de perfil de agente. Os protocolos acionam papéis; este mapa decide quem os ocupa.
- #
actorsmapa Um registro dos atores que podem ocupar papéis; opcional. As chaves são identificadores de ator estáveis. Um ator declara os papéis para os quais está habilitado e um modelo de comando por papel. Use quando um papel tiver mais de um ator habilitado, ou quando um mesmo ator precisar de uma invocação diferente conforme o papel que estiver ocupando; qualquer um dos dois já é razão suficiente. Um papel cujo único ator precisa de um único comando já é atendido pelo host e pelo invocation do próprio perfil de agente.
- #
ownersobjectobrigatório Quem responde pela saúde da camada de contexto. Os donos respondem por mantê-la atual e podada; eles não a escrevem nem fazem a curadoria dela sozinhos (governance.md).
namestringobrigatórioO nome da pessoa.
contactstringComo falar com ela, por exemplo um endereço de e-mail.
primaryobjectobrigatórioA pessoa que responde pela atualidade da camada de contexto. Camadas de contexto sem dono apodrecem.
continuityobjectOpcional. Uma outra pessoa que assume a mesma responsabilidade quando a principal está indisponível ou vai embora; adoções acompanhadas devem nomear alguém antes que a ajuda externa se retire. Nomear a pessoa principal de novo não cria continuidade nenhuma, e um agente não pode ocupar esse lugar: donos são pessoas que respondem.
- #
conformanceobject O nível de conformidade que esta camada de contexto declara, verificável por ferramentas.
claimedLevel"core" · "indexed" · "governed" · "federated"O nível de conformidade declarado: core, indexed, governed ou federated.
claimedAtstringA data em ISO 8601 em que a declaração foi feita pela última vez.
- #
federationobject As camadas irmãs montadas neste repositório (especificação: distribution.md, padrão 3). O círculo compõe a propriedade; não a centraliza.
mountsarray de objetosCada mount é uma camada de contexto irmã lida em uma versão fixada, através de uma projeção de camada hidratada pelo resolvedor, e que preserva o próprio repositório, a própria propriedade e o próprio processo de revisão e aprovação. O conteúdo materializado vive no cache do resolvedor, ignorado pelo git, e nunca é commitado aqui.
namestringobrigatórioO nome da camada irmã; precisa coincidir com o
nameno manifesto da própria irmã.sourcestringobrigatórioO localizador de repositório normalizado da camada irmã: uma URL remota https://, ssh:// ou no estilo SCP. É a raiz da resolução e o espaço de nomes do pin. Caminhos locais do sistema de arquivos só valem em dicas locais à máquina, nunca aqui.
pinstringobrigatórioO id de commit completo e imutável (SHA-1 ou SHA-256) da revisão da irmã que esta hospedeira lê. É o estado desejado, guardado no manifesto: atualizar um pin é curadoria deliberada e revisada.
trackingRefstringUma ref testemunha totalmente qualificada na origem (refs/heads/* ou refs/tags/*) contra a qual o relato de pin desatualizado e a alcançabilidade federada são comparados; opcional. Na ausência dela, o branch padrão anunciado pela origem é usado e registrado na saída do comando.
ownerobjectobrigatórioO dono da camada irmã. A propriedade continua com a equipe da irmã; a hospedeira nunca absorve o conteúdo dela.
rolestringO que esta camada irmã carrega, em prosa, por exemplo "contexto do lado do produto". É para pessoas; o roteamento usa os campos estruturados abaixo.
categoriesarray de "domain" · "system" · "practice" · "governance" · "decisions"Os escopos de categoria de conteúdo que esta irmã pode atender. São apenas metadados de roteamento; o conteúdo da irmã continua na irmã. Obrigatório para a conformidade federated.
topicsarray de stringsRótulos curtos de tópico, visíveis para a hospedeira, usados para rotear uma tarefa até esta irmã, por exemplo "billing", "checkout". São apenas metadados de roteamento.
requiredWhenarray de stringsAs condições de tarefa em que quem lê precisa resolver este mount, ou então parar e relatar contexto incompleto se não conseguir (falhar fechado). É visível para a hospedeira; não pode revelar nada que o público da hospedeira não possa ver.
- #
vendorAdaptersarray de strings Os arquivos de ponto de entrada de fornecedores presentes neste repositório; cada um precisa redirecionar para o perfil de boot.
- #
viewerobject As preferências de apresentação que o
leji viewerlê. É configuração de conveniência, não normativa; a apresentação em si está fora do escopo normativo.portintegerA porta preferida da pré-visualização local do
leji viewer serve. A flag --port tem precedência; o padrão é 5354 (LEJI no teclado do telefone).logostringA imagem de logo do visualizador, como um caminho sob a raiz do contexto (por exemplo "assets/logo.svg"). O padrão é o símbolo do Leji.
titlestringO título exibido pelo visualizador (cabeçalho da barra lateral e título da página). O padrão é o nome da camada de contexto.
agentsLabelstringO rótulo do grupo de perfis de agente na barra lateral (emoji é bem-vindo). O padrão é "🤖 Agents". O grupo lista os perfis de agente da camada e é ordenado por viewer.groupOrder como qualquer outro grupo.
faviconstringO favicon do visualizador, como um caminho sob a raiz do contexto (por exemplo "assets/icon.svg"). O padrão é o símbolo do Leji.
homepagestringA página de entrada do visualizador, como um caminho relativo à raiz do contexto (por exemplo "README.md"). O padrão é o overview.md semeado.
pinsarray de itensAs páginas fixadas no topo da barra lateral: caminhos de markdown relativos à raiz do repositório, ou {path, label} para um rótulo curado. Fixar o perfil de boot substitui a linha padrão dele.
groupOrderarray de stringsA sequência curada dos grupos da barra lateral, pelo rótulo exato de cada grupo (o H1 do arquivo de índice). Os grupos listados vêm primeiro, nesta ordem; os não listados seguem na ordem derivada.
themeobjectAjustes de tema do visualizador.
primarystringA cor principal, de destaque, como uma cor CSS em hexadecimal (por exemplo "#009F71"). Ela comanda a moldura do visualizador, os estados ativos e os destaques dos diagramas; os links no corpo do texto e o código em linha usam o tom acessível fixo, a menos que viewer.theme.link ofereça um que passe na verificação de contraste.
linkstringA cor dos links, como uma cor CSS em hexadecimal (por exemplo "#5A50F9"). Só é aplicada aos links no corpo do texto e ao código em linha quando alcança 4,5:1 sobre o fundo do código em linha, o mais estreito dos dois fundos em que eles pousam; caso contrário o tom acessível fixo permanece e o
leji view/leji exportavisam.mermaidbooleanRenderiza os blocos de código ```mermaid cercados como diagramas no visualizador. O padrão é true.
poweredBybooleanMostra o pequeno selo "Powered by Leji" no canto do visualizador. O padrão é true; use false para removê-lo.
categoryEmojisobjectSubstitui os emojis padrão exibidos ao lado de cada categoria no mapa da camada gerado. (Os grupos da barra lateral são rotulados pelo próprio H1 de cada arquivo de índice.)
Schema e exemplo
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://leji.org/schemas/v1.0/context-manifest.schema.json",
"title": "Leji context manifest (leji.json)",
"description": "The machine entrypoint of a Leji context layer. Lives at the repository root as leji.json.",
"type": "object",
"required": [
"leji",
"name",
"rootPath",
"bootProfilePath",
"categories",
"owners"
],
"additionalProperties": false,
"properties": {
"$schema": {
"description": "Optional pointer to this schema, for editor validation and tooling.",
"type": "string"
},
"leji": {
"type": "string",
"description": "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+$"
},
"name": {
"description": "A short, stable identifier for this context layer, e.g. \"acme-billing-context\".",
"type": "string",
"minLength": 1
},
"description": {
"description": "One-line summary of what this context layer covers.",
"type": "string"
},
"rootPath": {
"type": "string",
"description": "Context root, POSIX path relative to the repository root. Declares where the context layer lives; it does not re-base the paths it governs: index entries, pinned pages, profile paths, and every other path in Leji artifacts resolve from the repository root. The viewer's `homepage`, `logo`, and `favicon` are the exception: they are written relative to the context root, and a repository-root-relative path under it is accepted too.",
"pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).*$"
},
"bootProfilePath": {
"description": "Path to the boot profile, the agent-agnostic entrypoint every host and person starts from.",
"type": "string",
"pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).+\\.md$"
},
"categories": {
"type": "object",
"description": "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.",
"additionalProperties": false,
"minProperties": 1,
"properties": {
"domain": {
"description": "Where domain content lives: business language and product semantics.",
"$ref": "#/$defs/categoryMapping"
},
"system": {
"description": "Where system content lives: architecture and the invariants every change respects.",
"$ref": "#/$defs/categoryMapping"
},
"practice": {
"description": "Where practice content lives: conventions and proven patterns.",
"$ref": "#/$defs/categoryMapping"
},
"governance": {
"description": "Where governance content lives: agent guardrails and operating rules.",
"$ref": "#/$defs/categoryMapping"
},
"decisions": {
"description": "Where decision records live: dated records of why things are the way they are.",
"$ref": "#/$defs/categoryMapping"
}
}
},
"machine": {
"description": "Locations of the machine-readable artifacts: index, changelog, profiles, and decision records.",
"type": "object",
"additionalProperties": false,
"properties": {
"indexPath": {
"description": "Path to the generated context index.",
"$ref": "#/$defs/relPath"
},
"changelogPath": {
"description": "Path to the machine-readable context changelog.",
"$ref": "#/$defs/relPath"
},
"agentProfilesPath": {
"description": "Directory holding agent profile documents.",
"$ref": "#/$defs/relPath"
},
"decisionRecordsPath": {
"description": "Directory holding decision records.",
"$ref": "#/$defs/relPath"
}
}
},
"agents": {
"type": "object",
"description": "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.",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9]+(-[a-z0-9]+)*$": {
"$ref": "#/$defs/relPath"
}
}
},
"actors": {
"type": "object",
"description": "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.",
"additionalProperties": false,
"patternProperties": {
"^[a-z0-9]+(-[a-z0-9]+)*$": {
"$ref": "#/$defs/actor"
}
}
},
"owners": {
"type": "object",
"description": "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).",
"required": [
"primary"
],
"additionalProperties": false,
"properties": {
"primary": {
"$ref": "#/$defs/owner",
"description": "The person accountable for the context layer's currency. Ownerless context layers rot."
},
"continuity": {
"$ref": "#/$defs/owner",
"description": "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."
}
}
},
"conformance": {
"description": "The conformance level this context layer claims, checkable by tooling.",
"type": "object",
"additionalProperties": false,
"properties": {
"claimedLevel": {
"description": "The conformance level claimed: core, indexed, governed, or federated.",
"enum": [
"core",
"indexed",
"governed",
"federated"
]
},
"claimedAt": {
"description": "ISO 8601 date the claim was last asserted.",
"$ref": "#/$defs/isoDate"
}
}
},
"federation": {
"type": "object",
"additionalProperties": false,
"properties": {
"mounts": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"source",
"pin",
"owner"
],
"additionalProperties": false,
"properties": {
"name": {
"type": "string",
"minLength": 1,
"description": "The sibling layer's name; must match the `name` in the sibling's own manifest."
},
"source": {
"type": "string",
"minLength": 1,
"description": "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."
},
"pin": {
"type": "string",
"pattern": "^([0-9a-f]{40}|[0-9a-f]{64})$",
"description": "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."
},
"trackingRef": {
"type": "string",
"pattern": "^refs/(heads|tags)/.+$",
"description": "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."
},
"owner": {
"$ref": "#/$defs/owner",
"description": "The owner of the sibling layer. Ownership stays with the sibling's team; the host never absorbs its content."
},
"role": {
"type": "string",
"description": "What this sibling layer carries, in prose, e.g. \"product-side context\". For humans; routing uses the structured fields below."
},
"categories": {
"type": "array",
"items": {
"enum": [
"domain",
"system",
"practice",
"governance",
"decisions"
]
},
"minItems": 1,
"description": "The content-category scopes this sibling can answer for. Routing metadata only; the sibling's content stays in the sibling. Required for federated conformance."
},
"topics": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"description": "Short host-visible topic labels used to route a task to this sibling, e.g. \"billing\", \"checkout\". Routing metadata only."
},
"requiredWhen": {
"type": "array",
"items": {
"type": "string",
"minLength": 1
},
"description": "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."
}
}
},
"description": "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."
}
},
"description": "Sibling layers mounted into this repository (spec: distribution.md pattern 3). The circle composes ownership; it doesn't centralize it."
},
"vendorAdapters": {
"type": "array",
"description": "Vendor entrypoint files present in this repository; each must redirect to the boot profile.",
"items": {
"$ref": "#/$defs/relPath"
}
},
"viewer": {
"type": "object",
"description": "Presentation preferences read by `leji viewer`. Non-normative convenience configuration; presentation itself is out of normative scope.",
"additionalProperties": false,
"properties": {
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535,
"description": "Preferred local-preview port for `leji viewer serve`. The --port flag overrides; the default is 5354 (LEJI on a phone keypad)."
},
"logo": {
"type": "string",
"description": "Logo image for the viewer, as a path under the context root (e.g. \"assets/logo.svg\"). Defaults to the Leji mark."
},
"title": {
"type": "string",
"description": "Display title for the viewer (sidebar header and page title). Defaults to the context layer name."
},
"agentsLabel": {
"type": "string",
"description": "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."
},
"favicon": {
"type": "string",
"description": "Favicon for the viewer, as a path under the context root (e.g. \"assets/icon.svg\"). Defaults to the Leji mark."
},
"homepage": {
"type": "string",
"description": "The viewer's landing page, as a path relative to the context root (e.g. \"README.md\"). Defaults to the seeded overview.md."
},
"pins": {
"type": "array",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"additionalProperties": false,
"required": [
"path"
],
"properties": {
"path": {
"type": "string",
"description": "Repository-root-relative markdown path to pin."
},
"label": {
"type": "string",
"description": "Curated sidebar label for the pin (emoji welcome). Derived from the file when omitted."
}
}
}
]
},
"description": "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."
},
"groupOrder": {
"type": "array",
"items": {
"type": "string"
},
"description": "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."
},
"theme": {
"type": "object",
"additionalProperties": false,
"description": "Viewer theme overrides.",
"properties": {
"primary": {
"type": "string",
"description": "Primary/accent color as a hex CSS color (e.g. \"#009F71\"). Drives the viewer chrome, active states, and diagram accents; body links and inline code use the fixed accessible tone unless viewer.theme.link supplies one that clears the contrast guard."
},
"link": {
"type": "string",
"description": "Link color as a hex CSS color (e.g. \"#5A50F9\"). Applied to body links and inline code only when it reaches 4.5:1 against the inline-code ground, the narrower of the two backgrounds they land on; otherwise the fixed accessible tone stays and `leji view` / `leji export` warn."
}
}
},
"mermaid": {
"type": "boolean",
"description": "Render fenced ```mermaid code blocks as diagrams in the viewer. Defaults to true."
},
"poweredBy": {
"type": "boolean",
"description": "Show the small \"Powered by Leji\" mark in the viewer's corner. Defaults to true; set false to remove it."
},
"categoryEmojis": {
"type": "object",
"additionalProperties": {
"type": "string"
},
"propertyNames": {
"enum": [
"domain",
"system",
"practice",
"governance",
"decisions"
]
},
"description": "Override the default emoji shown beside each category in the generated layer map. (Sidebar groups are labeled by each index file's own H1.)"
}
}
}
},
"$defs": {
"relPath": {
"type": "string",
"pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).+$"
},
"isoDate": {
"type": "string",
"pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])([T ].*)?$"
},
"owner": {
"type": "object",
"required": [
"name"
],
"additionalProperties": false,
"properties": {
"name": {
"description": "The person's name.",
"type": "string",
"minLength": 1
},
"contact": {
"description": "How to reach them, e.g. an email address.",
"type": "string"
}
}
},
"categoryMapping": {
"type": "object",
"required": [
"indexes"
],
"additionalProperties": false,
"properties": {
"indexes": {
"description": "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.",
"type": "array",
"minItems": 1,
"items": {
"type": "string",
"pattern": "^(?!/)(?!\\./)(?!.*(^|/)\\.\\.(/|$))(?!.*\\\\).+\\.md$"
}
}
}
},
"actor": {
"type": "object",
"required": [
"roles",
"commands"
],
"additionalProperties": false,
"properties": {
"roles": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {
"$ref": "#/$defs/roleId"
},
"description": "Role identifiers this actor is eligible to fill. Every entry must have a matching key in commands."
},
"commands": {
"type": "object",
"minProperties": 1,
"propertyNames": {
"$ref": "#/$defs/roleId"
},
"additionalProperties": {
"$ref": "#/$defs/actorCommand"
},
"description": "Command templates keyed by role identifier. The key set must equal roles. Keying by role is the point: one actor can need different invocations for different roles."
}
}
},
"actorCommand": {
"type": "string",
"minLength": 1,
"pattern": "<prompt>",
"description": "Command template used to engage this actor in the keyed role. Must carry the <prompt> placeholder, standing as its own unquoted shell word; the pattern verifies the substitution site exists, placement is the spec's rule."
},
"roleId": {
"type": "string",
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
"description": "A role identifier, lowercase and hyphen-separated, as used by the agents map."
}
}
}Um manifesto em conformidade na raiz de um repositório.
{
"$schema": "https://leji.org/schemas/v1.0/context-manifest.schema.json",
"leji": "1.0",
"name": "acme-billing-context",
"description": "Camada de contexto compartilhada do monorepo da plataforma de faturamento da Acme.",
"rootPath": "docs/",
"bootProfilePath": "docs/boot-profile.md",
"categories": {
"domain": {
"indexes": [
"docs/context/domain.md"
]
},
"system": {
"indexes": [
"docs/context/system.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": {
"thought-partner": "docs/agents/thought-partner.md"
},
"owners": {
"primary": {
"name": "Acme Platform Team",
"contact": "platform@acme.example"
}
},
"conformance": {
"claimedLevel": "indexed",
"claimedAt": "2026-06-10"
}
}