Sekce /why/ webu uvádí provozní způsoby selhání, na které je tento nástroj odpovědí. Každý záznam v ní je deklarativní objekt vrstvy a každý výpis, trasa, filtr, počet, zpětný odkaz, odpověď API, zdroj MCP a diagnóza je z těchto objektů odvozena. Chování tak, jak je implementováno a testováno; kde se tento dokument a spustitelný soubor rozcházejí, dokument je špatně a mění se ve stejném commitu. Rozhodnutí je ADR 18; pravidlo je project.why-catalogue-is-canonical; vlastní smlouva adresáře je .ai/repo/why/README.md.
Tři druhy
.ai/repo/why/moments/<id>.md one operational failure mode schema: moment/v1
.ai/repo/why/audiences/<id>.md who recognises it schema: audience/v1
.ai/repo/why/areas/<id>.md the operational area schema: area/v1
Název souboru je id je slug je route. moments/two-agents-one-bug.md je majordomus://moment/two-agents-one-bug je /why/two-agents-one-bug/ a žádná tabulka nikde jedno na druhé nemapuje. audiences, areas, graph a index jsou rezervované: používají je vlastní routy sekce a moment, který si jedno z nich nárokuje, je odmítnut.
Tok
Nic v tomto řetězu není specifické pro katalog kromě doménového modelu uprostřed: objevování, parsování front matter, validace schématu a zdroj MCP jsou mechanismus, kterým už prochází každý druh vrstvy.
flowchart TD MD["Markdown under .ai/repo/why/<br/>front matter + body"] SRC["sources.yaml<br/>three pathspecs"] KIND["kinds.yaml<br/>three kinds"] SCH["share/schemas/*.schema.json<br/>the contract"] IDX["Index<br/>typed objects, validated"] CAT["why::Catalogue<br/>records, references resolved,<br/>relations derived, indexes built"] CAP["why.list · why.moment · why.audiences<br/>why.areas · why.diagnose · why.validate"] CLI["majordomus why"] HTTP["GET /api/v1/why*"] OAS["openapi.json + /docs/api/"] MCP["majordomus_why* tools<br/>majordomus://moment/<id>"] GEN["generate site<br/>site/data/registry/why.json<br/>+ why-graph.json"] SITE["/why/ · /why/<id>/<br/>/why/audiences/<id>/ · /why/areas/<id>/"] MD --> IDX SRC --> IDX KIND --> IDX SCH --> IDX IDX --> CAT CAT --> CAP CAP --> CLI CAP --> HTTP CAP --> MCP CAP --> GEN HTTP --> OAS GEN --> SITE
Katalog se sestaví jednou, když se skládá kontext schopností, a sdílí ho každá projekce; požadavek ho nikdy nesestavuje znovu (project.rust-hot-path). Jeho otisk je hash jeho vlastních zdrojů a ničeho jiného, takže dva průchody generate příkazu scripts/derive — které běží na obou stranách generátoru webu — vytvoří stejné bajty.
Napsané a odvozené
Rozdíl je celý návrh a schémata ho vynucují: odvozený klíč je klíč, který kontrakt nemá.
| psáno v souboru | odvozeno a odmítáno ve zdrojovém souboru |
|---|---|
| název, krátký název, háček, shrnutí, tělo | route a cesta API |
| publikum, oblasti, životní cyklus, tagy | okamžiky publika nebo oblasti a jejich počty |
| závažnost, frekvence, váha, zvýrazněno | odpovědnosti, kterých se okamžik dotýká (přes jeho tvrzení) |
| signály, příklady | zpětné odkazy: co jmenuje tento okamžik, toto tvrzení, tuto schopnost |
| příkazy, schopnosti, tvrzení, doktríny, případy užití | sousedé: explicitní, pak zpětní, pak nejbližší podle sdílených metadat |
explicitní related | každý facet, každý počet, hledaný text, diagnóza |
Reference
Každý odkaz je typovaný a vyřeší se proti tomu, co jmenuje. Nevyřešený název je chyba s nabídnutým nejbližším kandidátem, nikdy odkaz na stránku, která neexistuje.
| klíč | rozlišuje se proti |
|---|---|
audiences, areas, related | samotný katalog |
commands | registr příkazů (share/commands.yaml, objekt indexu) |
capabilities | registr schopností exekutoru |
claims | docs/CLAIMS.yaml |
doctrines | efektivní sada pravidel (majordomus rules list) |
use_cases | .ai/repo/use-cases/ |
Diagnóza
majordomus why diagnose --signal <id> a dotazník na /why/ odpovídají na stejnou otázku stejnou aritmetikou a ta aritmetika je počítání:
a selection signal ids, or moment ids
resolves to the moments that own them
an area scores how many of those moments name it
a recommendation is a capability, command, claim, rule or use case those moments name,
carrying the moments that produced it
Neexistuje žádné vážení ani procento, protože za ním není žádný model. Každý řádek je vysvětlitelný: matched_because jmenuje momenty a čtenář to může zkontrolovat.
Jak to číst
majordomus why # the catalogue, with the counts computed
majordomus why list --audience solo-builder --severity high
majordomus why show two-agents-one-bug
majordomus why audiences # each with the moments that name it, derived
majordomus why areas
majordomus why diagnose # the questionnaire, from the catalogue's own signals
majordomus why diagnose --signal same-subsystem-twice --format json
majordomus why validate # exit 10 on any error
Přes HTTP: GET /api/v1/why, /api/v1/why/moment?id=…, /api/v1/why/audiences, /api/v1/why/areas, /api/v1/why/diagnose?signals=a,b, /api/v1/why/validate; každá z nich je v docs/generated/openapi.json a na /docs/api/, protože ji tam dal registr. Přes MCP: nástroje majordomus_why, majordomus_why_moment, majordomus_why_audiences, majordomus_why_areas, majordomus_why_diagnose a majordomus_why_validate, zdroje majordomus://why, majordomus://why/audiences a majordomus://why/areas a každá položka jako majordomus://moment/<id>, majordomus://audience/<id> a majordomus://area/<id>.
Diagnóza je GET, protože nic nemění: POST v tomto spustitelném souboru znamená schopnost s účinkem na proces (CapabilityKind::Command). Její výběr je proto parametr oddělený čárkami, který se váže stejně v query stringu, přes MCP i na příkazovém řádku.
Přidání jedné
cp .ai/repo/why/moments/two-agents-one-bug.md .ai/repo/why/moments/<id>.md
$EDITOR .ai/repo/why/moments/<id>.md
majordomus why validate
just derive && git add -A
To je celý postup. Žádný registr k úpravě, žádný navigační soubor, žádný seznam šablon, žádný Rust a žádná změna schématu.
Co co vynucuje
| záležitost | zdroj | vynucování |
|---|---|---|
| tvar front matter | share/schemas/majordomus/{moment,audience,area}/*.v1.schema.json | index validuje každý objekt při sestavení; neznámý klíč, neznámá hodnota enum nebo nepodporovaná verze schema: soubor vyloučí a zhorší index |
| název souboru je id | id záznamu | why validate — filename_mismatch, jmenující soubor, kterým by měl být |
| okamžik si nenárokuje route, kterou vlastní sekce | why::RESERVED | why validate — reserved_identity |
| jedna identita na soubor | index | oba nárokující jsou vyloučeni; katalog přijme diagnostiku, místo aby se hlásil jako platný |
| references | katalog, registry, sada pravidel | why validate — unknown_reference, s nejbližším kandidátem |
| co veřejný záznam dluží | status: stable | why validate — missing_content varování; draft je vyňato a říká to |
| publikum, které nikdo nepoznává | okamžiky | why validate — thin_audience |
| CLI, HTTP, OpenAPI, MCP | po jedné deklaraci capability! | majordomus capabilities validate a generate --check pro dokumenty |
| stránky a data webu | site/data/registry/why.json | scripts/generate-site-data zamítne katalog, který neprojde validací; scripts/site-check zamítne stránku, kterou nevytvořil záznam, a odkaz, který se nerozliší oběma směry |
| přidat jeden soubor, odebrat jeden soubor | — | test/cases/98_why_catalogue.sh a apps/majordomus-cli/tests/why.rs |
| dotazy zůstávají levné, i když to roste | — | apps/majordomus-cli/benches/why.rs při 10, 100 a 1000 záznamech |
Čím není
Nejde o katalog případů užití. Moment je bolest, řečená čtenářovými slovy; případ užití (docs/USE_CASES.md) je workflow, které na ni odpovídá, se scénářem, který nástroj provede; schopnost je mechanismus. Odkazují na sebe podle id a nikdy neopakují text toho druhého.
Není to ani matice tvrzení. To, co nástroj zaručuje, je docs/CLAIMS.yaml, se stavem, implementací a testem; okamžik pojmenovává tvrzení a nezopakovává jejich znění.