Kompilátor nad tím, co tento repozitář už uvádí, a zapisovatel toho, co se epizoda naučila. sources, nodes, edges, search, show, related, candidates a check jsou jen pro čtení; derive, promote a reject zapisují záznamy znalostí a řádky knihy a nic jiného.
Není to wiki, databáze, paměťová služba ani druhé místo, kam si věci zapisovat. Každý zdroj, který čte, je soubor, který už někdo udržuje, vše, co vytváří, je odvozené a regenerovatelné a nic z toho nepřebíjí soubor, z něhož to pochází. Výsledek je ukazatel na kanonické znalosti, nikdy přepsaná odpověď.
knowledge není search. search je doslovné prohledání trvalých provozních záznamů — předávek, checkpointů, rozhodnutí, otázek, promptů, knihy — bez indexu, protože tento korpus je hrstka souborů. knowledge pokrývá kanonické artefakty repozitáře: politiku, profily, prompty, smlouvy milníků a úkolů, matici tvrzení a dokumenty. Dva korpusy, dvě smlouvy a žádná nemění tu druhou.
-
sources [--scope shared|operational|all]vypíše kurátorované třídy zdrojů a soubory, které každá objevuje, s třídou, rozsahem, druhem, hashem obsahu a cestou relativní k repozitáři. -
nodes [--scope ...] [--kind <k>]odvodí jeden uzel na kanonický objekt: jeho identitu, druh, zdroj, ze kterého pochází, a hash tohoto zdroje. Skončí s10, když dva objekty nárokují jednu identitu. -
edges [--scope ...] [--type <t>]odvozuje jednu hranu na každý uvedený vztah, se souborem a polem nebo řádkem, kde byl pozorován. -
search <query> [--scope ...]vrací uzly, které dotaz odpovídá, v pořadí, které je pravidlem, ne skóre. Uzel se zařadí na první příčku, kterou dosáhne:id(dotaz je jeho kanonické id),title(dotaz je jeho titulek),title-prefix(jeho titulek začíná dotazem),path(jeho zdrojová cesta obsahuje dotaz),body(jeho zdrojový soubor obsahuje dotaz doslova); každé porovnání ignoruje velikost písmen. V rámci příčky je pořadí bajtové pořadí id. Každý výsledek uvádí příčku, na kterou byl zařazen (matchedarungv--json), takže důvod pořadí je v odpovědi. Uzly nenesou tagy, proto neexistuje příčka tagů. -
show <id> [--scope ...]vypíše jeden uzel s jeho druhem, rozsahem, titulkem, cestou zdroje a hashem obsahu. Skončí s12, když žádný uzel to id nemá. -
related <id> [--scope ...]vypíše hrany z jednoho uzlu a do něj, každou s jejím typem a souborem a polem nebo řádkem, kde byla pozorována. Skončí s12, když žádný uzel nemá toto id.Žádný ze tří nezapisuje a žádný nic nepřestavuje: není tu uložený index, který by mohl zastarat, takže každé volání zkompiluje to, co checkout v tu chvíli obsahuje, přesně jako
nodes. Případ 3037 ověřuje žebřík, pole každého výsledku a že pracovní strom po všech třech vypadá stejně. -
derive [--episode <id>] [--dry-run] [--json]odvozuje znalosti, které epizoda vytvořila, do kandidátních záznamů pod.ai/repo/knowledge/candidates/, z knihy a gitu a nikdy z konverzace: zaznamenané rozhodnutí se staneconvention, vyřešená otázkafact, zablokovaná nebo selhaná úlohalesson, dokončení s ověřovacím příkazemfact. Otevřená epizoda, nebo ta pojmenovaná. Deterministické: stejná kniha, stejný git, stejné bajty a druhý běh hlásí každý záznam jakounchanged.--dry-runřekne, co by zapsal, a nedotkne se stromu ani knihy. -
candidates [--json]vypíše každý záznam čekající na revizi — id, třídu, datum, větev epizody, ze které pochází, název — čtením adresáře, ne indexu, takže se vypíše i kandidát, kterého hook právě zapsal a nikdo ho nepřidal. -
promote <id> [--class <c>] < evidence.mdpřesune kandidáta docurated/jakoverified, s důkazy ze standardního vstupu připojenými pod# Evidencea třídou, kterou zvolil člověk. Deriver nikdy nezapisujeverified; toto je akt, který ano. -
reject <id> --reason "<why>" [--by <id>]označí kandidátasupersededna místě s důvodem pod# Rejecteda pojmenuje záznam, který ho nahrazuje, když ho--byuvede. -
check [--json]validuje každý záznam podcandidates/acurated/: schéma, žádný neznámý klíč, jedinečná id rovná názvu souboru, původ vedleverified, každý odkaz se řeší, důvod vedlesuperseded, žádný kandidát nenárokujícíverified, žádná konverzace. Stejnou kontrolu spouštějícheckadoctor.
Čtecí stranu téhož úložiště obsluhuje spustitelný soubor — bin/majordomus-cli knowledge candidates, knowledge record <id> a knowledge status, každá schopnost deklarovaná jednou a odpovídající stejně přes HTTP, MCP i příkazovou řádku (CAPABILITIES.md); status hlásí poslední derivaci, nejnovější uzavření a to, zda zapisovatel přestal běžet. KNOWLEDGE.md obsahuje tabulku derivací, oba okamžiky a pravidla.
Zapisuje: derive zapíše .ai/repo/knowledge/candidates/<id>.md, jeden na záznam, přes dočasný soubor ve stejném adresáři přejmenovaný přes soubor pojmenovaný id, nikdy neindexovaný, a vypíše written, unchanged nebo skipped na záznam se shrnutím na konci; připojí knowledge.derived do účetní knihy — epizodu, počty, cesty — i když nezapsal nic. promote zapíše .ai/repo/knowledge/curated/<id>.md stejným způsobem, odstraní kandidáta, připojí knowledge.promoted a nakonec vypíše cestu k vybranému záznamu. reject přepíše kandidáta na místě a připojí knowledge.rejected. Id záznamu je id epizody a digest důkazů, takže stejný fakt vždy skončí ve stejném souboru.
Nikdy nestaguje, necommituje ani neupravuje žádný jiný soubor. Nikdy nečte konverzaci, prompt ani předávku; nikdy nevolá model ani síť. Nikdy nezapisuje verified.
Odmítá (10) promote s prázdným stdin, se stdin nesoucím značku přepisu, na záznamu, jehož stav není candidate, nebo s třídou mimo výčet; reject na záznamu, jehož stav není candidate, nebo když --by nejmenuje žádný záznam; derive když se politika nedá zpracovat; check na jakémkoli selhávajícím záznamu. (12) promote nebo reject, když id nenese žádný kandidát. (2) reject bez neprázdného --reason. (13) zápis, který nedoběhl. derive bez epizody, z níž by se dalo odvozovat, to řekne a skončí s 0.
$ majordomus decision add "Tabs are refused in the parser" --why "two encodings of one thing"
$ majordomus knowledge derive
written .ai/repo/knowledge/candidates/s-20260912101500-7f1a-3b9c2e4d1a05.md
knowledge derive: 1 written, 0 unchanged, 0 skipped for episode s-20260912101500-7f1a
$ majordomus knowledge derive
unchanged .ai/repo/knowledge/candidates/s-20260912101500-7f1a-3b9c2e4d1a05.md
knowledge derive: 0 written, 1 unchanged, 0 skipped for episode s-20260912101500-7f1a
$ printf 'Verified by reading lib/yaml.sh.\n' | majordomus knowledge promote s-20260912101500-7f1a-3b9c2e4d1a05 --class constraint
.ai/repo/knowledge/curated/s-20260912101500-7f1a-3b9c2e4d1a05.md
Žádná hrana bez původu. Každá hrana pojmenovává, kde byl vztah uveden, a hrana, které chybí from, to, type nebo provenance, se odmítne a nevydá s prázdnou hodnotou — prázdný zdroj se čte jako „neznámý“ a nelze jej odlišit od zdroje, který nikdo nezaznamenal. Hrana, kterou nikdo nedokáže vysledovat k řádku, není fakt, je to dohad v šatech faktu, a je to dohad, u něhož člověk, který by si nejlépe všiml, že je špatně, to nikdy neuvidí.
Nic se neodvozuje z prózy. Repozitář své vztahy již uvádí explicitně, v polích, která někdo udržuje, a ta jsou zároveň zdarma i správná. Typy hran tvoří uzavřenou množinu; nedeklarovaný typ je chyba, a ne nové slovo slovníku:
| typ | z → do | uvedeno v |
|---|---|---|
part_of | úkol → milník | milestone úkolu |
depends_on | issue → issue, milestone → milestone | depends_on záznamu |
declares | milestone → claim | claims milníku |
specified_by | tvrzení → dokument | docs/CLAIMS.yaml's source |
implemented_by | tvrzení → implementace | jeho implementation |
tested_by | claim → test, doctrine → test | jeho test |
supports | doktrína → tvrzení | claims doktríny |
references | dokument → dokument | vložený odkaz v Markdownu |
Odkazy jsou jediný zdroj hran, který není kurátorovaný, a čtou se konzervativně. Nejprve se zahodí oplocený kód, protože cesta uvnitř ukázky kódu je příkladem cesty, ne odkazem na ni. Cíl se schématem, cíl relativní k protokolu a absolutní cesta se přeskočí; fragment se ořízne, protože docs/CLI.md#session odkazuje na docs/CLI.md.
Závažnost rozlišuje, co vlastní Majordomus a co napsal autor. Deklarovaný vztah ukazující na soubor, který repozitář neobsahuje, je FAIL: je to porušený slib. Odkaz v dokumentu ukazující na nic je WARN: dokument může záměrně ukazovat mimo repozitář a samotný cíl tyto dva případy nerozliší. Vztah ukazující na skutečný soubor, který tento kompilátor nemodeluje jako jediný uzel — kontejner mnoha objektů nebo něco mimo vybranou množinu — je tichý, protože zpráva, která je záměrně obrovská, je zpráva, kterou lidé přestanou číst.
nodes a edges jsou dva pohledy na jedno odvození, takže vada v kterémkoli končí kódem 10 u obou. Nad rozbitým grafem neexistuje čistý výpis uzlů.
Identita uzlu nikdy není hash jeho obsahu. Je to vlastní kanonické id objektu, pokud ho má — claim:policy-parse, issue:I0801, milestone:M003, profile:debugging — a cesta v repozitáři, pokud ne, jako v document:docs/CONTINUITY.md. Hash říká, zda se něco změnilo; nikdy nemůže říct, čím něco je, protože pak by každá úprava smazala uzel a vytvořila cizince a každá reference na něj by mířila nikam, aniž by to cokoli řeklo. Hash jede s uzlem a měří se jím aktuálnost.
Důsledek je záměrný: úprava dokumentu zachovává jeho uzel a mění jeho hash; přejmenování je smazání a přidání a neruší žádný jiný uzel.
Druh vychází ze struktury, nikdy z prózy. Určuje ho třída zdroje, ve které byl soubor objeven, a pole, která soubor sám deklaruje. Nic nečte tělo dokumentu a nehledá slovo, které by naznačovalo typ: dokument, který pojednává o plánech rozvoje a milnících, je dokument, který o nich pojednává. Kde se nepoužije žádné pravidlo, je druh unknown a uzel se přesto vydá, s jedním nálezem pojmenovávajícím třídu — explicitní neznámo je informace, sebejistá chybná odpověď není.
Název se převezme, nebo se nechá prázdný, nikdy se nevymýšlí. Z vlastního title nebo description záznamu, nebo z prvního nadpisu první úrovně dokumentu. Dokument bez nadpisu nedostane žádný název, ne název souboru, protože název souboru nahrazující titul se čte jako fakt a je to odhad.
Dvě úložiště nemají vlastní pole id. Rozhodnutí je klíčováno svým názvem a otázka svým textem — v obou případech přesně tím, co zaznamenává kniha a na co odkazuje obálka relace, takže tři místa pojmenovávají totéž stejně a nic mezi nimi nemapuje. Zodpovězení otázky přepíše řádek, na kterém žije, a identita to přežije: připojená odpověď se odstraní, a jen když to, co zbude, končí datem otevření záznamu, takže otázka, jejíž vlastní text obsahuje pomlčku, zůstane celá a neřízne se naslepo.
Objevování řídí index repozitáře, ne procházení souborového systému. Procházení vrací výstup buildu, vendorované stromy a odpadky z editorů; vrací je v pořadí, které se mezi dvěma stroji liší; a může vrátit soubor, který nikdo nechtěl publikovat. Výpis sledovaných souborů místo toho dává pravdu repozitáře ve stabilním pořadí a nesledovaný soubor není nikdy zdrojem. Provozní záznamy se objevují ze stavového adresáře, který si Majordomus sám vlastní pod .ai/local/ a který se nikdy nesleduje — a odnikud jinud. Žádný skrytý adresář se neprohledává jen proto, že existuje.
Třídy zdrojů jsou deklarovány dvakrát, dvěma vlastníky: repozitář deklaruje své sdílené zdroje ve své AI vrstvě, .ai/repo/knowledge/sources.yaml, a nástroj dodává provozní třídy, záznamy, které zapisuje sám, v share/knowledge-sources.yaml. Rozsah třídy určuje to, který soubor ji deklaroval; ani jeden soubor nejmenuje druhý:
| scope | význam |
|---|---|
shared | znalosti repozitáře; smí se promítnout na veřejný povrch |
operational | vlastní pracovní záznamy tohoto checkoutu; nikdy součást sdílené projekce |
Rozsah je vlastnost třídy, takže hranice publikace se rozhoduje na jednom místě, ne u každého producenta. Každý sledovaný pathspec nese prefix :(glob), pod kterým * nepřekračuje oddělovač adresářů. To není úprava pro pořádek: bez něj docs/*.md odpovídá i docs/claims/*.md, dvě třídy se tiše překrývají a jeden soubor se stává dvěma uzly. test/cases/64_knowledge_discovery.sh na této mutaci selže.
Jedno překrytí řeší soubor, ne třídy. README.md sekce odpovídá jak .ai/**/README.md, třídě context, tak vlastnímu pathspecu své sekce (.ai/repo/features/*.md, .ai/repo/rules/**/*.md a tak dále). Deklaruje kind: context, takže je to uzel context, jednou: druhá třída, která jej objeví, nepřidá nic. Index uplatňuje stejnou přednost v apps/majordomus-cli/src/discovery/mod.rs a test/cases/330_a_contract_is_the_kind_it_declares.sh ji prokazuje pro knowledge nodes. Kde žádný soubor druh nedeklaruje, zůstávají dvě třídy nad jednou cestou odmítnutím (twin v případu 73).
init deklaruje nejdřív třídu context, takže smlouvy nového repozitáře jsou od začátku objekty jeho indexu. Bez toho se context resolve, který čte soubory, a každá schopnost čtoucí index neshodly v tom, co se na cestu vztahuje; test/cases/130_context_compiler.sh bez této třídy selže.
Třída označená required, která nic nenajde, se hlásí jako WARN. Cenou za kurátorský seznam je, že na cestu lze zapomenout, a zapomenutá cesta se neliší od repozitáře, který takový soubor nemá, pokud to něco neřekne.
Zda soubor odpovídá schématu svého druhu, je verdikt indexu spustitelného souboru, ne čtenáře: knowledge nodes se indexu ptá, které soubory odmítl, vyřadí je a každé odmítnutí hlásí jako FAIL (test/cases/405_the_knowledge_reader_honours_the_schema.sh). Bez sestaveného spustitelného souboru nebo bez jq hlásí WARN, že schéma zůstalo nezkontrolováno; nikdy se nečte jako úspěch. MAJORDOMUS_KNOWLEDGE_SCHEMA=unasked říká, aby se neptal, a čtenář pak hlásí INFO, že se kontrola nevyžádala. To nastavuje zaznamenaný scénář případu užití: zda se index mohl zeptat, je fakt o nahrávajícím stroji a důkaz, který se musí na každém stroji číst stejně, jej nést nemůže (#713, test/cases/777_a_recorded_scenario_does_not_depend_on_the_recorder.sh).
$ majordomus knowledge sources --scope shared
policy shared policy 4f2a9c1d8b30 .ai/repo/policy.yaml
profile shared profile a1b2c3d4e5f6 .ai/repo/profiles/debugging.yaml
...
issue shared issue 0e5a7b9c3f51 .ai/repo/project/issues/I0801.yaml
claims shared claim 7c9e1b3d5f70 docs/CLAIMS.yaml
document shared document 9b1e2d4f8c3a docs/CONTINUITY.md
knowledge sources: 169 file(s) in scope shared