Kontext není jeden soubor. Je to strom dokumentů, z nichž každý platí pro adresář, ve kterém leží, a vše pod ním, čtený od kořene dolů k místu, kterého se worker chystá dotknout. Nejbližší dokument přidává k předkům; nenahrazuje je a dva sourozenecké adresáře se nikdy navzájem nevidí.
Tento dokument popisuje model: co je kontextový dokument, jak se skládá efektivní kontext pro cestu, co vyhrává, když se dokumenty neshodují, jak se změna vystopuje k dokumentům, které ovlivňuje, a co selže, když je strom špatně. Formát je v SCHEMAS.md, příkazy v CLI.md, pravidlo, které říká, kam věta patří, v .ai/repo/rules/project/context-locality.v1.md.
Co je kontextový dokument
Soubor Markdown pod stromem .ai/ (adresář manifestu bez local/ a bez rules/vendor/), jehož front matter deklaruje schema: context/v1 a kind: context. Názvy souborů jsou konvence, ne identita: identitou je id ve front matter a přežije přesun. Manifest jmenuje názvy souborů, které musí kontrakt nést všude, kde se ve stromu objeví:
context:
documents: [README.md]
README.md ve stromě bez smlouvy je chyba. Jakýkoli jiný soubor Markdown bez front matter se ignoruje a soubor, jehož front matter je jiného druhu — pravidlo, prompt — není kontextový dokument.
Adresář stromu bez dokumentu je také chyba: viz Pokrytí.
Každý dokument deklaruje svůj scope: directory platí jen pro vlastní adresář, subtree pro jeho adresář a vše pod ním, explicit pro adresáře uvedené v paths. Deklaruje providers, jemuž je určen ("*" nebo názvy z projekcí politiky), audience (human, agent), status (active nebo deprecated: objeveno a vypsáno, nikdy neuplatněno), celé číslo order a volitelně git pathspecs, které tracks: kód nebo dokumenty, které popisuje, aby je změna jmenovala k review.
Složení
Účinný kontext pro cestu se počítá, nikdy se neskládá ručně:
- Cíl je adresář relativní k repozitáři; soubor se převede na svůj adresář. Cesta, která ještě neexistuje, se řeší stejně, jako soubor v rodičovském adresáři, pokud není zapsána s koncovým
/, a řekne to: adresář, který neexistuje, neobsahuje dokument, takže platí dokumenty jeho předků. Symlink nebo.., které uniká z repozitáře, se odmítne. - Uvnitř stromu jsou kandidáty dokumenty, jejichž adresář je cíl nebo jeho předek, každý připuštěný svým rozsahem:
directoryjen když jsou adresáře shodné,subtreekdyž je adresář dokumentu cílem nebo nad ním,explicitkdyž cíl leží uvnitř vypsané cesty. - Mimo strom —
lib/,docs/, cokoli, co není pod.ai/— jsou kandidáty kořenový řetěz (dokumenty podstromu v samotném.ai/) plus každý dokument, jehožtracksodpovídá cíli. - Pořadí je podle hloubky vzestupně, od nejméně specifického; pak podle
ordervzestupně; pak podle cesty vzestupně. Nikdy ne v pořadí, v jakém souborový systém soubory zrovna vypíše. - Filtry se uplatní: poskytovatel, publikum a
status: active. Odfiltrovaný dokument ve výsledku chybí a ve vysvětlení je přítomen, s důvodem. - Kompozice se uplatní naposled.
extendpřipojuje.replacepřipojuje a každé id, které jmenuje vsupersedes, označí jako nahrazené: zůstane v provenienci, ale vypadne z efektivního seznamu.finalnesmí být nahrazeno žádným potomkem.
majordomus context resolve <path> vypíše výsledek, číslovaný, v efektivním pořadí. majordomus context explain <path> vypíše totéž a u každého posuzovaného dokumentu proč je uvnitř (předek v hloubce N, sleduje, adresář) nebo venku (odfiltrován, nahrazen).
Přednost
Méně specifické je první a specifičtější později, takže čtenář, který výsledek čte shora dolů, narazí na obecné tvrzení před lokálním. Proto také nejbližší dokument tiše nevyhrává: lokální dokument, který odporuje předkovi, aniž by řekl replace a jmenoval jej, jsou dvě tvrzení platná současně, což recenzent vidí ve vyřešeném řetězci a opraví u zdroje. V rámci jedné hloubky rozhoduje order; rovnost v order se rozhodne cestou, takže výsledek je na každém stroji stejný.
Kořenový dokument .ai/README.md je final: nic pod kořenem nesmí zastoupit protokol, který říká, jak se strom čte.
Konflikty
Validace odmítne strom v kterémkoli z těchto stavů a pojmenuje dokumenty:
| třída | význam |
|---|---|
invalid-front-matter | dokument, který manifest vyžaduje, nemá kontrakt, nebo požadovaný klíč chybí či je chybný |
unsupported-schema | hodnota schema není taková, kterou tato verze čte |
unknown-key | klíč front matter mimo share/allow/context.txt |
duplicate-id | dva dokumenty si nárokují jedno id |
broken-reference | supersedes jmenuje id, které není předek, nebo neexistuje |
cycle | supersedes se řetězí zpět na sebe |
illegal-override | potomek nahradí dokument označený final |
unknown-provider | providers jmenuje poskytovatele, pro něhož politika nemá projekci |
invalid-manifest | blok context manifestu se nenaparsuje nebo nejmenuje nic |
refused-path | cíl uniká z repozitáře |
missing-contract | adresář stromu nenese žádný kontextový dokument a nic ho nevyjímá |
Dva dokumenty ve stejné hloubce, order a cestě nemohou nastat: to je jeden soubor.
Pokrytí
Každý adresář stromu nese kontextový dokument. Strom je tentýž, který čte resolver — adresář manifestu bez poloviny, kterou manifest sám deklaruje jako nesledovanou (local.tracked: false) — a adresář v něm bez dokumentu je missing-contract, s uvedením adresáře a, když požadavek explicitně stanovil některý předek, i smlouvy, která to udělala. Nic jiného se podle jména nepřeskakuje: podstrom, který smlouvu nedluží, to říká ve smlouvě nad sebou.
Výjimku deklaruje kontrakt, který řídí podstrom, nikdy seznam v kořeni, takže se přesouvá se stromem, který popisuje:
scope: subtree
children:
require_contract: false
Hodnota, která platí pro adresář, je ta z nejbližšího předka, jehož kontrakt ji deklaruje; kde ji nedeklaruje nic, dokument je dlužen. Pole se skládá jen zúžením: potomek smí pro svůj podstrom zvýšit false na true a snížení zděděného true na false je illegal-override — stejná třída, jakou potomek dostane za nahrazení dokumentu final. Je to tvrzení o potomcích, takže se přijímá jen na dokumentu subtree a jeho hodnotou je true nebo false a nic jiného.
Podstrom, který vrstva nese, ale nevytváří, se místo toho uvolní jménem, podle smlouvy, která ho řídí:
scope: subtree
children:
require_contract: true
exempt: [.ai/repo/rules/vendor]
Vše v pojmenovaném adresáři a pod ním nedluží nic. Položka musí ležet uvnitř vlastního rozsahu dokumentu a nesmí být vlastním adresářem dokumentu — smlouva uvolňuje adresáře, které řídí, a žádné jiné, jinak by se pravidlu zužování dalo uniknout vyjmutím podstromu z boku, a oba pokusy jsou illegal-override. Takto je vyňat vendorovaný balíček pravidel: je nainstalován, ne zde napsán, a jeho integrita je věcí jeho vlastního manifestu. Adresář, který tento repozitář píše, stále dluží smlouvu, ať má vendorovaného souseda, nebo ne.
Podstrom vyjměte pomocí require_contract: false, když jsou adresáře pod ním instancemi druhu, a ne sekcemi vrstvy: dovednost je SKILL.md a její příklady a smlouva v každém adresáři instance by opakovala formát, který sekce uvádí jednou. Všude jinde nový adresář řekne, k čemu slouží, dřív než půjde commitnout větev, která ho přidává — context validate běží v pre-commit hooku přes doctor. Rozhodnutí je .ai/repo/adrs/0011-every-directory-in-the-layer-carries-a-contract.md.
Na webu
/context/ vykresluje tentýž strom: každý adresář vrstvy, kontrakt, který nese nebo který ho vyjímá, a co každý kontrakt deklaruje. Stránka čte site/data/generated/context.json, které scripts/generate-site-data zapisuje z jednoho majordomus context list --json — verdiktu samotného nástroje, ne druhého průchodu týmiž soubory — a build odmítne publikovat strom s adresářem, který kontrakt dluží a nemá.
Poskytovatelé
providers: ["*"] oslovuje každého workera; seznam jmenuje projekce z politiky, pro jejichž workery je dokument určen. resolve --provider claude-code vrací, co by měl ten worker číst, a nic, co je adresováno jinam. Soubory poskytovatelů v kořeni (CLAUDE.md, AGENTS.md, GEMINI.md) jsou bootstrapy: říkají workeru, aby vyřešil kontext pro cestu, které se chystá dotknout, nebo aby přečetl řetěz README.md od .ai/ dolů, a nenesou žádný vlastní kontext. Nativní načítání vnořených souborů poskytovatele je optimalizací téhož čtení; když se obojí liší, platí rozlišení uvedené výše.
Dopad
majordomus context affected čte sadu změn z gitu — pracovní strom proti HEAD ve výchozím stavu, --staged pro index, --base <ref> pro <ref>..HEAD plus pracovní strom — a hlásí, čeho se změna dotýká:
- změněný kontextový dokument: jeho rozsah, každý potomkový adresář, každý dokument, který nahrazuje nebo který nahrazuje jeho, a projekce, které nesou razítko politiky;
- přesunutý nebo přejmenovaný adresář: změněné předky; identita se přesouvá se souborem a duplicita nebo rozbitý odkaz po přesunu je chyba;
- smazaný dokument: každý
supersedes, který ho jmenoval, je rozbitý odkaz; - změněný manifest nebo změněný seznam povolených: každý dokument;
- cesta odpovídající
tracksdokumentu: nálezWARNs uvedením dokumentu a cesty, protože nástroj nedokáže rozhodnout, zda próza stále popisuje kód; pojmenuje, co musí člověk přečíst.
Změna zdroje, který nesleduje žádný dokument, nevytvoří nic. Zjištění review jsou WARN, což se nikdy nedotkne exit kódu: smysl je v tom, že si nikdo nemusí pamatovat, které README popisovalo soubor, který se právě změnil.
Check-sync
majordomus context check-sync [--base <ref>] je jediný příkaz, který spouští hook nebo CI: validace celého stromu, projekce aktuální vůči politice a dotčené položky revize pro sadu změn. Neplatný strom je FAIL, exit 10; ručně upravená projekce je DRIFT, exit 11; chybějící projekce je INFO, protože „missing“ vlastní doctor; položky revize jsou WARN; jinak exit 0. .github/workflows/validate.yml jej spouští v tomto repozitáři a převzaté pravidlo majordomus.context-integrity odesílá stejnou validaci z doctor a watch.
Čtení z příkazové řádky
majordomus context list every document: id, path, scope, composition, providers, status
majordomus context resolve <path> [--provider P] [--audience A]
majordomus context explain <path> [--provider P] [--audience A]
majordomus context validate the whole tree; exit 10 on any failure
majordomus context affected [--base <ref>|--staged|--worktree]
majordomus context check-sync [--base <ref>] validate, projections, affected; exit 10 / 11 / 0
Všechny jsou jen pro čtení a přijímají --json. Samotné majordomus context je stále sestavovač briefingu a jeho briefing získává sekci CONTEXT DOCUMENTS s výpisem účinného řetězce pro cesty rozsahu aktivní úlohy.
Způsoby selhání
Strom je odmítnut, nikoli opraven: chybějícímu povinnému klíči se nedoplní výchozí hodnota, dokumentu bez id se žádné nevymyslí, pořadí se nehádá. Pracovník, který čte strom, jejž nástroj odmítá, ho čte na vlastní riziko, a check-sync v hooku brání tomu, aby to byl stav větve. Co nástroj rozhodnout nemůže, to pojmenuje: zda dokument stále popisuje kód, který sleduje, je zjištění WARN, nikdy ne průchod.
Migrace
Repozitář na vrstvě před tímto modelem má README bez smluv. Přidání smlouvy je přidání front matteru; tělo zůstává. Začněte v kořeni (.ai/README.md, final), pak repo/README.md, pak každá sekce; spouštějte majordomus context validate, dokud není ticho; pak přidejte tracks tam, kde dokument popisuje kód, aby jej další změna toho kódu jmenovala. Nic jiného se nehýbe a repozitář, který nikdy nepřidá druhý dokument, má přesně ten kontext, který měl předtím, nyní vyřešitelný.
test/cases/69_context_documents.sh dokazuje pořadí rozlišení, pravidla skládání, každou třídu konfliktu, filtry, report dopadu a kontrolu synchronizace mutací.