Přeskočit na obsah

Tato stránka byla automaticky přeložena z angličtiny, jediného jazyka, ve kterém se tento web píše. Číst originál.

Schémata souborů

každý soubor: schéma, konkrétní příklad, který příkaz jej čte a zapisuje

Vykresleno z docs/SCHEMAS.md — stejný Markdown, který zobrazuje GitHub.

Tak, jak je implementováno. Každé zde uvedené pole je něčím zapisováno a něčím čteno. Pole, které ztratí jedno z toho, se odstraní, nezachovává se „na později“.

Conventions:

  • YAML pro vše, co edituje člověk. JSON Lines pro vše, k čemu jen připisuje Majordomus.
  • YAML je podmnožina a podmnožina je zúžení: žádné flow mapy, žádné skládání, žádné kotvy. Soubor, který tento repozitář přijme, se proto musí parsovat jako YAML i pro všechny ostatní, protože share/ je vendorován do repozitářů, jejichž nástroje nejsou naše. Tři konstrukce čtou naše zploštěvače tak, jak byly myšleny, a pro všechny ostatní parsery jsou syntaktickými chybami: nekvotovaný : uvnitř prostého skaláru, prostý skalár začínající indikačním znakem (`, %, @) a vnořené závorky uvnitř flow sekvence. Skalár ocitujte — oba stroje odstraní odpovídající okolní uvozovky, takže se hodnota nepohne. test/cases/128_the_subset_is_a_subset.sh se zeptá nezávislého parseru a selže, když kanonický soubor opustí jazyk.
  • Neznámé klíče jsou chyby na každé úrovni.
  • Pole identity (repository_id, branch, head, working_tree, changed_files) se vždy počítají z gitu při zápisu. Worker nebo člověk, který je dodá, je chyba, ne přepsání.
  • Časová razítka jsou UTC ISO 8601 se sekundami: 2026-09-03T19:30:12Z.

.ai/manifest.yaml

Registr sekcí vrstvy AI repozitáře. Discovery čte tento soubor a nikdy neprochází .ai/; soubor pod repo/, který nepokrývá žádná sekce, není kontext a nenese žádnou autoritu. init jej zapisuje z kostry; verze formátu je to, co spustitelný soubor ověří před čtením čehokoli jiného, a tu, kterou nečte, odmítne s uvedením důvodu.

schema: ai-repository/v1

repo:
  path: repo              # tracked canonical context
local:
  path: local             # this checkout's own; ignored by git
  tracked: false
  implicit_context: false

sections:                 # relative to .ai/; each one resolves to a path the tool reads
  policy: repo/policy.yaml
  profiles: repo/profiles
  rules: repo/rules
  prompts: repo/prompts
  skills: repo/skills
  workflows: repo/workflows
  knowledge: repo/knowledge
  adrs: repo/adrs
  project: repo/project

Každý klíč je povinný, kromě toho, že project se smí rozřešit na adresář, který neexistuje, což je repozitář bez plánu. Neznámé klíče jsou chyby (share/allow/manifest.txt). doctor selže, když chybí sekce, kterou manifest jmenuje, když local/ není ignorován nebo nese sledovaný soubor, nebo když projektová data z doby před .ai stále leží pod .majordomus/.


.ai/repo/policy.yaml

Jediná kanonická politika nezávislá na poskytovateli.

version: 1                               # schema version; only 1 is valid

context:
  always_loaded_budget_lines: 150        # hard cap on the always-loaded projection
  builder_budget_lines: 300              # hard cap on what `majordomus context` prints
  recent_decisions: 5                    # decisions offered to a worker, newest first
  max_list_items: 20                     # cap on any list inside the assembled context
  strategy: minimum-sufficient           # documentation of intent; projected into instructions
  transcript_is_state: false             # projected as a rule; never true

profiles:
  default: implementation                # must name a file in profiles/
  checkpoint_interval_default: 15m       # profiles may override

verification:
  required_for_changes: true             # finish requires --verify-command when files changed
  finish_requires:                       # the contract; order is display order
    - scope_respected
    - verification_ran
    - state_updated
    - no_open_blockers
    - note_present

checkpoint:
  max_body_lines: 40                     # a body over this is refused, not truncated
  retention_max_files: 500               # doctor reports when exceeded

handover:
  required_sections: [Objective, Current State, Next Action]
  retention_max_files: 200               # doctor reports when exceeded

ledger:
  retention_max_lines: 5000

benchmark:
  samples: 10            # warm samples per target in `majordomus bench`
  warmup: 2              # unsampled runs before them
  regression:            # fractions over the baseline that `bench --check` refuses
    p50: 0.5
    p95: 0.5
    p99: 0.6
  budget:                # doctor and watch report their own wall time against these (WARN, never the exit code)
    doctor_ms: 20000     # the skeleton's values, measured on a freshly adopted repository
    watch_ms: 20000      # re-derive with `majordomus bench` once your catalogue has grown

enforcement:                             # what doctor reconciles; each must be wired
  - name: doctor-on-commit
    path: majordomus                       # on PATH, repo-relative, absolute, or named in the hook line
    args: [doctor]
    wired_by: git-hook:pre-commit
  - name: finish-on-push
    path: majordomus
    args: [finish, --check]
    wired_by: git-hook:pre-push

projections:
  - provider: claude-code
    target: CLAUDE.md
    mode: region                         # file (default) | region
    always_loaded: true                  # exactly one projection may be always_loaded
  - provider: codex
    target: AGENTS.md
  - provider: gemini
    target: GEMINI.md
  - provider: generic
    target: docs/AI_INSTRUCTIONS.md

mode: file generuje celý cíl a vlastní každý jeho bajt. mode: region generuje jen text mezi dvěma značkami a nevlastní nic jiného v souboru:

Whatever the repository already wrote. Majordomus never reads or rewrites this.

<!-- majordomus:begin 7b88abe0f22a -->
... generated from the policy ...
<!-- majordomus:end -->

Hash v počáteční značce jmenuje politiku, ze které oblast pochází; není součástí hashovaného obsahu, takže opakované spuštění update po nesouvisející úpravě politiky není ruční úprava. update nahradí existující oblast na místě a v souboru, který žádnou nemá, jednu připojí. Neuzavřené, nesprávně seřazené nebo opakované značky se odmítnou (15), nikdy se nehádají. fingerprints.yaml zaznamenává mode vedle hashe a u oblasti hash pokrývá oblast — úprava mimo značky je věcí repozitáře a nikdy se nehlásí jako drift.

Hodnoty wired_by: git-hook:<name> (vyřešeno přes core.hooksPath nebo .git/hooks/), ci:<path> (soubor, který musí existovat a obsahovat volání), git-config:<key> (klíč, který musí vlastní konfigurace gitu klonu nastavit na hodnotu jmenující nástroj), toolchain:<file> (připnutý toolchain Rustu, který soubor jmenuje, je na tomto stroji nainstalován, takže scripts/derive a prs repair --apply umějí buildovat), manual (zdokumentováno, neověřeno; doctor to uvádí jako neověřené, nikdy jako zapojené). Řádek hooku nesmí spolknout návratový kód (|| true, || exit 0).


.ai/repo/scope.yaml

Rozsah repozitáře: co worker čte a co nikdy nečte. Jmenuje jej sekce scope manifestu; manifest, který žádný nejmenuje, znamená, že platí výchozí nastavení distribuce (share/skeleton/ai/repo/scope.yaml). Schéma je share/schemas/majordomus/scope/scope.v1.schema.json; allow-list shell nástroje se z něj generuje. SCOPE.md vysvětluje posouzení.

version: 1
in:                                   # pathspecs anchored at the root; a trailing / is the directory and everything beneath
  - .ai/repo/**
  - src/**
out:                                  # wins over in; every key optional
  paths: ['.git/', '.ai/local/', '**/target/']
  binary: true                        # a NUL byte in the first 8 KiB
  max_bytes: 1048576
  archive: { names: [...] }           # written as a block mapping; the subset has no flow maps
  image: { names: [...] }
  video: { names: [...] }
  pdf: { names: [...] }
  database_dump: { names: [...] }
  generated: { paths: [...], names: [...] }
  secret: { paths: [...], names: [...] }
  fixtures: { paths: [...], names: [...], max_bytes: 65536 }

names se porovnávají jen s názvem souboru a nesmí nést lomítko; vzor s úvodním lomítkem, prefixem :( nebo segmentem .. se odmítne se jménem klíče.


.ai/repo/profiles/<name>.yaml

Pět nezávislých os. Nic zde nepojmenovává model žádného dodavatele.

name: debugging
description: reproduce, isolate, fix, and prove a defect fixed

capability: strong            # fast | standard | strong | strongest — projections map this
effort: high                  # low | medium | high | xhigh | max; omit to inherit the default
effort_escalation:            # optional; projected as guidance, not enforced
  after_blocked_attempts: 2
  to: xhigh
verbosity: concise            # terse | concise | detailed
presentation: engineering     # machine | engineering | summary

context:                      # toggles; projections turn them into loading guidance
  task: true
  current_state: true
  decisions: true
  relevant_files: true
  failing_output: true
  recent_history_depth: 50    # commits; 0 disables
  architecture_notes: false
  knowledge: true             # knowledge pointers: what the task's issue references
  knowledge_max_items: 8      # at most this many; capped by context.max_list_items

verification:
  verify_command_required: true
  regression_test_required: true
  decision_record_required: false

checkpoint_interval: 15m

output_contract:              # fields a completion note must carry for this profile
  - outcome
  - changes
  - verification
  - blockers
  - next_action

Čtyři dodávané profily:

routineimplementationdebuggingdeep-work
schopnostrychlýstandardsilnýnejsilnější
effortnízkástřednívysokáhigh, eskaluje na xhigh
podrobnoststručnýstručněstručněpodrobný
prezentacemachineinženýrstvíinženýrstvíinženýrství
kontextúloha, stav+ rozhodnutí, soubory, znalosti 8+ selhávající výstup, historie 50+ architektura, historie 200, znalosti 12
ověřovací příkazpokud se soubory změnilypovinnépovinnépovinné
regresní testnenepovinnéne
záznam rozhodnutínenenepovinné
kontrolní bod30m15m15m30m

.ai/repo/rules/**/*.md — objekty pravidel

Pravidlo je soubor Markdown s YAML front matter. Baseline, kterou nástroj dodává, žije v share/standard/majordomus/ a je vendorována do repozitáře pod .ai/repo/rules/vendor/majordomus/ (manifest.yaml jmenující každý soubor s hashem a rules/*.md); vlastní pravidla repozitáře žijí pod .ai/repo/rules/project/. Model viz DOCTRINE.md, formát tak, jak ho repozitář čte, viz .ai/repo/rules/README.md.

---
id: majordomus.scope-integrity        # identity, with version; never the file name
version: 1
kind: rule
title: Scope integrity
description: A task touches only the paths it claimed; work found elsewhere is not accepted as done.
statement: Work outside the paths a task claimed is not accepted as that task's work.
status: active                        # active | deprecated
class: blocking                       # blocking | advisory — nothing else parses
depends_on: [majordomus.one-worker-one-scope@1]   # exact id@version references, or []
tags: [scope, verification]

x-majordomus:                         # present only on a rule the tool enforces
  validator: scope                    # runs mj_validate_scope; a name with no function is a failure
  category: scope                     # the finding category a violation is reported under
  enforced_by: [check, finish, watch]
  policy_key: scope_respected         # finish doctrines only: the name used in verification.finish_requires
  exit_code: 10                       # from the existing contract; a rule invents no code
  claims: [scope-enforcement, scoped-task]   # ids in docs/CLAIMS.yaml
  tests: [test/cases/04_start_check.sh]
---

# Rationale
...
# Required behaviour
...
# Failure behaviour
...
# Verification
...
polepovinnévýznam
id, versionanoidentita; projektové pravidlo nesmí používat jmenný prostor majordomus.. Slug URL na webu je id bez jmenného prostoru
kindanorule
title, description, statementanojeden řádek každý, vykreslený doslova
statusanoactive nebo deprecated; zastaralé pravidlo není v efektivní sadě a nesmí se na něm záviset
classanoblocking příkaz zastaví; advisory ohlásí a nechá ho projít. Jakákoli jiná hodnota selže celou množinu uzavřeně
depends_onanopřesné reference id@version; chybějící nebo cyklus množinu shodí
tagsnevolné štítky; principle označuje deset principů
x-majordomus.validators blokempřípona mj_validate_<validator>; funkce musí existovat v lib/
x-majordomus.categorys blokemkategorie nálezu, aby výstup zůstal jedním slovníkem
x-majordomus.enforced_bys blokempříkazy, které jej vyvolávají; každý musí existovat a volat mj_doctrine_dispatch
x-majordomus.exit_codes blokem0 pro poradní, jinak kód ze smlouvy o návratových kódech
x-majordomus.policy_keynepřítomno jen u doktrín, které repozitář může vybrat v verification.finish_requires
x-majordomus.claimsneid tvrzení, která tato doktrína podporuje; každé musí existovat v docs/CLAIMS.yaml
x-majordomus.testss blokempřípady, které dokazují chování; každý soubor musí existovat

Povolené klíče jsou share/allow/rule.txt; jakýkoli jiný klíč je chyba. majordomus doctor ověřuje každé z těchto omezení proti zdroji, že vendorovaný balík odpovídá svému manifestu a navíc že neexistuje žádná funkce mj_validate_*, kterou by nedeklarovalo žádné pravidlo.

.ai/**/README.md — kontextové dokumenty

Kontextový dokument je soubor Markdown ve stromu .ai/ (bez local/ a rules/vendor/), jehož front matter deklaruje níže uvedený kontrakt. context.documents v manifestu pojmenovává názvy souborů, které ho musí nést všude, kde se ve stromu objeví; dnes je to README.md. Model viz CONTEXT.md.

---
schema: context/v1
id: ai.repo.rules                 # identity; ^[a-z][a-z0-9-]*(\.[a-z0-9-]+)*$ ; unique across the tree; survives a move
kind: context
title: Repository rules
description: One sentence.
status: active                    # active | deprecated (discovered and listed, never applied)
scope: subtree                    # directory | subtree | explicit
paths: []                         # explicit only: repo-relative directories inside the tree
providers: ["*"]                  # "*" or provider names from the policy's projections
audience: [human, agent]          # who it addresses; resolve --audience filters
composition: extend               # extend | replace | final
order: 100                        # integer; ties within one depth are broken by path
supersedes: []                    # replace only: ids of ancestor-chain documents, none of them final
tracks: [lib/rules.sh]            # git pathspecs this document describes
children:                         # subtree only: what the directories below owe
  require_contract: true          # true | false; the default where nothing declares it is true
  exempt: []                      # subtrees this layer carries but does not author
---
polepovinnévýznam
schemaanocontext/v1; novější hodnota se odmítne, nikdy se neodhaduje
idanoidentita, jedinečná v celém stromu; název souboru je konvence
kindanocontext; jiný druh je jiný druh souboru
title, descriptionanokaždý na jednom řádku
statusanoactive nebo deprecated
scopeanodirectory, subtree nebo explicit
pathss explicitadresáře relativní k repozitáři uvnitř stromu, na který se dokument vztahuje
providersano"*" nebo názvy projekcí v politice; neznámý název neprojde validací
audiencenehuman, agent; filtr, nikdy oprávnění
compositionanoextend, replace nebo final
orderanocelé číslo; méně je dříve v rámci jedné hloubky
supersedess replaceid v řetězci předků, za které tento dokument stojí; předka final nelze jmenovat
tracksnepathspecy, jejichž změna určuje tento dokument k revizi
children.require_contractneJen subtree: zda každý adresář pod tímto dluží kontextový dokument. Chybějící všude nad adresářem znamená true. Potomek smí false zvýšit na true; snížení zděděného true je illegal-override
children.exemptneJen subtree: adresáře relativní k repozitáři uvnitř vlastního rozsahu tohoto dokumentu, které nedluží kontextový dokument, a nedluží ho ani nic pod nimi — podstrom, který vrstva nese, ale nepíše, například nainstalovaný balíček, jehož integrita je věcí jeho vlastního manifestu. Jmenovat adresář mimo rozsah dokumentu nebo jeho vlastní adresář je illegal-override; adresář, který neexistuje, je broken-reference

Povolené klíče jsou share/allow/context.txt; jakýkoli jiný klíč je chyba. Neexistují výchozí hodnoty: povinný klíč, který chybí, je invalid-front-matter, nikoli tichá hodnota. majordomus context validate kontroluje každé omezení nad celým stromem a majordomus doctor posílá stejnou kontrolu přes majordomus.context-integrity.

.ai/repo/sessions/<stamp>--<id>--<branch>--<head>--<digest>.md

Jedna uzavřená epizoda provedení, zapsaná majordomus session close a ničím jiným. Sdílený objekt vrstvy: objevovaný třídou zdrojů session, promítaný do indexu, majordomus://session/<id>, tras objektů, grafu a webu, bez seznamu relací vedeného kdekoli (ADR 0014).

---
schema: session/v1                # the contract; a version this executable does not read is refused
kind: session
session_id: s-20260906035523-7b6c # identity, allocated at open, never reused
created_at: 2026-09-06T03:55:24Z  # when the record was written: the close
started_at: 2026-09-06T03:55:23Z
closed_at: 2026-09-06T03:55:24Z
outcome: closed                   # closed | interrupted
title: "Session s-… on feature/x" # one line for a listing; the task's title when it had one
task_id: none                     # the task the episode belonged to, or none
profile: none
worker: "claude-code/opus-5"      # what did the work, as it identified itself
repository_id: git@github.com:…   # the remote; `local:<hash>` when there is none
worktree_id: e2d0ee3a34301bd5     # the working copy, named without naming a path
branch: feature/session-records
start_head: 4658856…              # the commit the episode started from
head: 4658856…                    # the commit it ended at
start_working_tree: dirty         # clean | dirty, at open
working_tree: dirty               # and at close
commits: []                       # between the two heads, oldest first
changed_files: []                 # repository-relative, as git reported them
tasks: []                         # every list below is read from the ledger's events
issues: []                        # for this episode: nothing here is authored
milestones: []
checkpoints: []
handovers: []
decisions: []
questions: []
evidence: []
---

The body: a summary of the work, given on standard input at close.
KlíčVyžadovánoVýznam
schemaanosession/v1
kindanosession
session_idanoidentita; název souboru je jen pohodlí
started_at, closed_atanoRFC 3339, UTC
outcomeanoclosed nebo interrupted
title, task_id, profile, workernečím epizoda byla a co na ní pracovalo
repository_id, worktree_idnekde běželo, bez uvedení cesty
branch, start_head, headnez gitu
start_working_tree, working_treeneclean nebo dirty
commits, changed_filesnez gitu
tasks, issues, milestones, checkpoints, handovers, decisions, questions, evidencenez událostí knihy pro tuto epizodu

Neznámé klíče jsou chyby a žádná hodnota nesmí být absolutní cesta: sdílený záznam nese to, co repozitář dokáže dokázat, nikdy fakt o stroji, který jej pořídil. Pro konverzaci neexistuje žádné pole, což je project.never-store-transcripts vynucené smlouvou, nikoli zvykem. Vlastní soubor stavu otevřené epizody je jiný objekt s vlastním schématem (session) a zůstává v polovině lokální pro checkout.

.ai/repo/rules/vendor/majordomus/manifest.yaml

Manifest balíčku: každý soubor pravidel, který vendorovaný základ drží, jeho identita a hash souboru. Zapisuje jej init a majordomus rules vendor update, nikdy ručně; doctor selže, když uvedený soubor chybí, liší se od svého hashe, deklaruje jinou identitu, nebo když soubor pod rules/ uveden není.

vendor: majordomus
package: majordomus-standard-rules
version: 1
format: ai-rules/v1
source_revision: 0.1.0          # the executable version the package was taken from
rules:
  - id: majordomus.scope-integrity
    version: 1
    file: rules/scope-integrity.v1.md
    sha256: 6b737b27...

Tentýž manifest popisuje balíček, který distribuce dodává v share/standard/majordomus/; rules vendor status oba porovná a nový distribuční balíček ohlásí, aniž by ho aplikoval.


.ai/repo/project/project.yaml

Kořen kanonického projektového modelu. Přítomný jen v repozitáři, který plánuje přes milníky a úkoly; model je dobrovolný a doctor ho přeskočí tam, kde chybí.

schema_version: 1
name: Prismatic Majordomus
repository: korczis/prismatic-majordomus     # owner/name; the projection target
default_branch: master

Nic odvozeného se tu neukládá. Neexistuje pole active_milestone: aktivní milník je ten s nejnižším pořadím, který je ACTIVE, jinak ten s nejnižším pořadím, který není dokončen, vypočtený při každém čtení.


.ai/repo/project/milestones/<ID>.yaml

Jedna spustitelná specifikace výsledku. Název souboru je id; záznam, jehož id se s názvem souboru rozchází, se odmítne, nikoli smíří.

id: M000
title: Milestone and DAG driven development
slug: milestone-dag-driven-development
order: 0                              # integer; decides which milestone is active
priority: p0                          # p0 | p1 | p2 | p3
problem: "What is wrong today."       # single-line scalars; the YAML subset has no folding
outcome: "What is true when it ends."
current_state: "Where it stands."
desired_state: "Where it is going."
scope: [...]                          # what this outcome covers
non_scope: [...]                      # what it deliberately does not
acceptance_criteria: [...]            # what would make the outcome true
validation: [...]                     # commands that demonstrate it
evidence_required: [...]              # tokens gating milestone acceptance
risks: [...]
cancelled: false                      # optional
evidence:                             # appended; each entry covers one required token
  - covers: suite
    type: test                        # test | build | ci | artifact | manual
    command: "bash test/run.sh"
    result: "every case passed"
    artifact: "…"                     # optional: a path, URL or hash
    commit: 60f83e3…                  # written by the tool
    recorded_at: 2026-09-04T03:14:00Z # written by the tool
created_at: 2026-09-04
updated_at: 2026-09-04

Neexistuje seznam issues:. Úkol pojmenovává svůj milník a relace se čte v tomto jediném směru, takže dva záznamy se nemohou rozcházet v tom, které úkoly k výsledku patří. Neexistuje pole status:; viz níže.


.ai/repo/project/issues/<ID>.yaml

Jeden omezený kontrakt provedení, nesoucí dost pro workera bez historie konverzace.

id: I0007
milestone: M000
title: Enforce the canonical model as doctrine
slug: model-doctrine
priority: p1
profile: implementation               # which execution profile suits this work
parallel_safe: true                   # false forces serialisation regardless of the graph
objective: "What this issue produces."
why: "Why it exists."
current_state: "…"
desired_state: "…"
scope: [...]                          # the paths this issue may touch
non_scope: [...]
depends_on: [I0005]                   # issue ids; the edges of the DAG
acceptance_criteria: [...]            # required; an issue without one is a placeholder
validation: [...]                     # required; the commands that demonstrate it
evidence_required: [...]              # tokens that gate completion
risk: "…"
owner: alice                          # optional
completion: "…"                       # optional one-line completion report

# lifecycle markers — written only by `majordomus plan`, never by hand
started_at: 2026-09-04T03:00:00Z
verified_at: 2026-09-04T03:20:00Z
completed_at: 2026-09-04T03:31:00Z
cancelled: false
evidence:                             # same shape as a milestone's
  - covers: doctrine_test
    type: test
    command: "bash test/run.sh 44_model_doctrine"
    result: "1 passed, 0 failed"
    commit: aa90a8b…
    recorded_at: 2026-09-04T03:30:11Z

Na žádném záznamu není pole status. BLOCKED, READY, ACTIVE, VERIFY, DONE a CANCELLED odvozuje lib/project.awk ze značek životního cyklu, pokrytí důkazy a stavu závislostí úkolu; stav milníku se odvozuje z jeho úkolů a jeho vlastních důkazů. Zápis status: do kteréhokoli souboru je neznámý klíč a shodí majordomus plan validate i majordomus doctor.

Neznámé klíče se kontrolují proti share/allow/project.txt, share/allow/milestone.txt a share/allow/issue.txt, stejným mechanismem, který používají politika a profily.


.ai/local/state/current.yaml

Jediná aktivní úloha. Chybí, když není aktivní nic.

id: t-20260903-193012-a4f1          # t-<utc compact>-<4 hex>
task: fix OAuth callback
profile: debugging
owner: alice                          # free-form string
scope:                                # normalised at start; no trailing slashes
  - lib/auth
started_at: 2026-09-03T19:30:12Z
checkpoint_at: 2026-09-03T20:02:41Z   # updated by check --checkpoint and by finish
outcome: active                       # active | completed | partial | blocked | no_match | failed | handed_over

# computed from git at start; refreshed at finish; never authored
repository_id: /abs/path/.git         # git rev-parse --git-common-dir
worktree: /abs/path                   # the checkout this task belongs to
branch: main
head: 3f2a9c1e...                     # full SHA
working_tree: dirty                   # clean | dirty

.ai/local/state/ se nikdy nesleduje, takže tento záznam zůstává u checkoutu, který jej zapsal. Kopie, která se dostane do jiného worktree na téže větvi, jej přečte a nesmí být držena rozsahem, který si nikdy nenárokovala, proto worktree říká, kterému checkoutu úloha patří. check, finish --check a watch hlásí záznam z jiného checkoutu a nic z něj nevynucují; finish do něj odmítá zapisovat vůbec. Záznam zapsaný před vznikem tohoto pole nemá názor a bere se jako lokální, takže upgrade nezabarví stávající instalaci červeně.

outcome a checkpoint_at jsou jediná pole, která příkaz po start mění. active zamítne nové start; každý jiný výsledek nechá start archivovat záznam do state/archive/<id>.yaml a začít novou úlohu.


.ai/local/state/decisions.md

Jen přidávané, datované, jedna položka na rozhodnutí. Psané člověkem. Čte je decision list, context (který vypíše tolik položek, kolik context.recent_decisions dovolí, pro tuto úlohu nebo pro repozitář podle profilu), search a prompt asset, který používá {{DECISIONS}}. check je čte jen proto, aby hlásil položky, které nelze přiřadit žádné úloze ani headu. Projekce na něj odkazují cestou a nikdy jej nevkládají.

Jen přidávání. decision add zapíše jeden záznam s vypočtenými Task a Head; zbývající pole pocházejí z jeho voleb. --why je povinné, protože rozhodnutí bez zaznamenaného důvodu nelze později posoudit, jen znovu obhajovat. Chybějící volitelná pole se zapisují jako - místo vynechání, takže každý záznam má stejný tvar.

Záznam se nikdy neupravuje ani nemaže. --supersedes zaznamenává, že pozdější rozhodnutí nahradilo dřívější, a odmítne text, který neodpovídá žádnému zaznamenanému rozhodnutí.

## 2026-09-03 — token refresh uses the existing session store
Task: t-20260903193012-a4f1
Head: 9b1e2d4f8c3a5e7b1d0f2a4c6e8b0d3f5a7c9e1b
Why: one source of truth for expiry; a second cache would mean two expiry clocks
Rejected: a separate refresh cache
Evidence: lib/auth/session_store.rb#expiry
Supersedes: -

check, doctor a watch hlásí položku bez Task, Head nebo Why jako varování: soubor je záměrně ručně editovatelný a položka, kterou nelze nikomu přičíst, je rozhodnutí, které nenajde žádná kontrola. Text uvnitř komentáře HTML je šablonou samotného souboru a položkou není.

.ai/local/state/open-questions.md

Věci blokované na člověku. finish --outcome completed odmítá, dokud je kterákoli položka pro aktuální úlohu unresolved.

Zapisuje question add a přepisuje na místě question resolve. Řešení upravuje řádek, protože index toho, co je ještě otevřené, se nesmí hromadit; záznam každého otevření a vyřešení s jeho odpovědí, jen přidávaný, je ledger.

- [unresolved] t-20260903193012-a4f1 — token refresh window: 15 or 60 minutes? (2026-09-03)
- [resolved 2026-09-02] t-20260902120000-b3d1 — keep the legacy callback path — yes, until Q4

Platné jsou přesně dva tvary řádku:

- [unresolved] <task id> — <question> (<YYYY-MM-DD>)
- [resolved <YYYY-MM-DD>] <task id> — <question> — <answer>

— odděluje pole, takže otázka jej nesmí obsahovat. Každý jiný řádek - [ je selhání v check, doctor a watch, ne varování: tento soubor je bránou přijetí a brána, která nepřečte položku, je brána, kterou lze obejít překlepem.


.ai/local/state/handovers/<file>.md

Název souboru: <utc-compact>--<branch-key>--<short-head>--<16 hex>.md, např. 20260903T201455Z--main--9b1e2d4--c0ffee1234567890.md. branch-key je větev, v níž je každý znak mimo [A-Za-z0-9._-] nahrazen -, nebo DETACHED.

---
schema_version: 1
created_at: 2026-09-03T20:14:55Z
task_id: t-20260903-193012-a4f1
profile: debugging
owner: "alice"
repository_id: /abs/path/.git
worktree: /abs/path
branch: main
head: 9b1e2d4f...
working_tree: clean
changed_files:
  - lib/auth/oauth.rb
  - test/auth/oauth_test.rb
---

# Objective
Fix the OAuth callback dropping state on redirect.

# Current State
Root cause found: state param stripped by the proxy rewrite. Fix in oauth.rb applied,
regression test added, suite green.

# Next Action
Decide the refresh window (open question) and then finish.

# Decisions
See decisions.md 2026-09-03.

# Verification
make test — exit 0, 41s, at head 9b1e2d4.

Front matter zapisuje Majordomus. Tělo obsahující řádek, který vypadá jako klíč front matter, se odmítne. Režim 0600. Vytvořeno atomicky. Nikdy se nepřipravuje do indexu.


.ai/local/state/checkpoints/<file>.md

Název souboru a front matter jsou přesně jako u předávky; liší se jen adresář a pravidla těla. Zapisuje checkpoint, režim 0600, vytvořeno atomicky, nikdy nezařazeno do stage.

---
schema_version: 1
created_at: 2026-09-03T19:45:00Z
task_id: t-20260903193012-a4f1
profile: debugging
owner: "alice"
repository_id: /abs/path/.git
worktree: /abs/path
branch: main
head: 9b1e2d4f8c3a5e7b1d0f2a4c6e8b0d3f5a7c9e1b
working_tree: dirty
changed_files:
  - lib/auth/oauth.rb
---

OAuth state mismatch reproduced with test/fixtures/callback.json.
The cause is in callback normalisation, not in the comparison.
Next: regression test before touching the implementation.

Tělo je volný text, ne sekce, a je omezeno na checkpoint.max_body_lines řádků. Tělo nad limit je odmítnuto, ne zkráceno, s návrhem napsat místo toho předávku: limit je to, co drží checkpoint dost krátký na to, aby se dal celý citovat do příštího briefingu, místo aby se stal druhým druhem zprávy.

Tělo obsahující jakékoli pole identity je odmítnuto, stejně jako u předávky. Prázdné tělo je povoleno a nezapisuje žádný soubor — aktualizuje jen checkpoint_at, což dělá check --checkpoint.

Čte checkpoint --show a --list a také context, vše přes stejný resolver jako předávky: stejný worktree a větev, jinak stejná větev, jinak nic.


.ai/local/state/sessions-open/<provider session>.yaml

Jedna otevřená epizoda provádění. Jedna na relaci poskytovatele, ne jedna na worktree: dvě okna téhož poskytovatele otevřená na jednom checkoutu jsou dva pracovníci a jejich sloučení do jednoho záznamu označí řádky ledgeru jednoho pracovníka id druhého a nechá konec kteréhokoli okna uzavřít obě. Soubor je klíčován relací poskytovatele, která ho otevřela; epizoda, kterou nikdo nepojmenoval, je klíčována hand a taková je nejvýše jedna, protože poskytovatel, který neposílá identitu relace, je k nerozeznání od člověka u terminálu.

session start odmítne běžet, dokud je vaše epizoda otevřená, místo aby ji nahradil; jiná relace poskytovatele dostane vlastní epizodu. session close je jediný zapisovatel, který jednu odstraňuje, a odstraňuje jen svou vlastní.

.ai/local/state/session-current.yaml je relativní symlink do tohoto úložiště: ukazatel na epizodu tohoto checkoutu, namířený na epizodu otevřenou zde naposledy a přemířený uzavřením na jedinou stále otevřenou epizodu, je-li právě jedna. Je to to, přes co se řeší proces, který nedokáže pojmenovat relaci poskytovatele — continuity.state čte tuto cestu a každý její čtenář (sed, plochovač YAML, čtečka celých dokumentů v Rustu) následuje odkaz, aniž by o tom věděl. Symlink, ne kopie: dva účty jedné otevřené epizody jsou drift, kterému se tento záznam má vyhnout.

Která epizoda patří danému procesu, se rozhoduje v mj_session_here_file (lib/common.sh): relace poskytovatele pojmenovaná na příkazové řádce, jinak relace poskytovatele, uvnitř které tento proces běží, když je zde epizoda s tímto klíčem otevřená (MAJORDOMUS_PROVIDER_SESSION nebo proměnná, kterou deklaruje adaptér životního cyklu v lib/capture.sh — CLAUDE_CODE_SESSION_ID pro Claude Code), jinak ukazatel.

session_id: s-20260904153733-fc51
started_at: 2026-09-04T15:37:33Z
owner: "alice"
worker: "some-provider/some-model"      # optional; recorded only when supplied
provider: "claude-code"                 # optional; only a provider hook can supply it
provider_session: "cc-1"                # optional; the key this episode is filed under
# computed from git; never authored
repository_id: /abs/path/.git
worktree: /abs/path
branch: master
start_head: 9b1e2d4f8c3a5e7b1d0f2a4c6e8b0d3f5a7c9e1b
start_working_tree: dirty

session_id je s- následované kompaktní časovou značkou UTC s odstraněnými T a Z a čtyřmi hex znaky, což je tvar, který už má id úlohy. worker je volný řetězec a jediné pole, které člověk nebo pracovník dodává nad owner; nic ho neověřuje a nic ho neodvozuje, když chybí — nezaznamenaný pracovník zůstává nezaznamenaný, místo aby se stal věrohodným odhadem.

Neznámé klíče jsou chyba, stejně jako v každém jiném YAML souboru Majordomu.

Tyto soubory nejsou sledovány. Ostatní soubory stavu ano, protože je čte něco mimo checkout: záznam úlohy nese claim rozsahu, s nímž porovnávají jiné worktree, úložiště otázek je správou verzí vázáno na větev a záznamy jen pro připojování musí putovat. Otevřená relace nic z toho nenese, takže její commit by jen způsobil, že by každý checkout na větvi zdědil epizodu, kterou neotevřel. Uzavřené relace jsou trvalé záznamy a sledují se.

Obrana zůstává na místě bez ohledu na to: záznam relace z jiného worktree se hlásí a nepovažuje se za otevřenou relaci tohoto checkoutu, přesně jako cizí záznam úlohy.


.ai/local/session-contexts/<stamp>--<session-id>.md

Omezený pracovní kontext jedné epizody, zapisovaný session start a doplňovaný session close. Jeho kontrakt je majordomus.session-context/v1 (share/schemas/majordomus/session-context/); druh je deklarován v share/kinds.yaml jako každý jiný a žádná zdrojová třída jej neobjevuje.

---
schema: session-context/v1
kind: session-context
session_id: s-20260906035523-7b6c
opened_at: 2026-09-06T03:55:23Z
opened_by: hook                      # hook | hand
provider: claude-code                # only when a provider's event opened it
provider_session: "abc-123"          # the provider's own identity, as it sent it
branch: master
head: 9b1e2d4f8c3a5e7b1d0f2a4c6e8b0d3f5a7c9e1b
task_id: none
profile: none
worker: "some-provider/some-model"   # optional; recorded only when supplied
---

# Working context of session s-20260906035523-7b6c

## Context at open
<the context builder's output, verbatim>

## Notes
<the worker's own account of the work>

## Close                              # appended by `session close`
- closed_at: 2026-09-06T05:12:04Z
- outcome: closed
- head: 9b1e2d4f…
- record: .ai/repo/sessions/20260906T051204Z--s-…--master--9b1e2d4--c0ffee1234567890.md

opened_by je hook přesně tehdy, když otevření pojmenovalo poskytovatele, který událost doručil, což dokáže jen něco, co běží uvnitř hooku toho poskytovatele; proto je to fakt, a ne tvrzení. provider_session je řetězec, který spojuje epizodu s archivem promptů, jehož záznamy nesou tentýž.

Dokument se jen připisuje, nikdy nepřepisuje: front matter popisuje otevření a uzavření přidá sekci, takže přežije vše, co pracovník mezi oběma událostmi napsal. Je nesledovaný a na rozdíl od ostatního lokálního stavu je nesledovaný i z druhého důvodu: je to snapshot projekce, takže jeho opětovné rozlišení později vytvoří jiný dokument a žádný povrch ho nemůže reprodukovat (ADR 0015).

Nikdy to není přepis. Odvozená polovina je výstup builderu a ručně psaná polovina shrnuje práci; klíč front-matter jmenující seznam zpráv, dokončení nebo odpověď modelu doktrína majordomus.session-lifecycle odmítne, a tak se project.never-store-transcripts zde udržuje mechanicky, ne pamětí.


.ai/repo/sessions/<file>.md

Neměnný záznam uzavřené relace. Název souboru: <utc-compact>--<session-id>--<branch-key>--<short-head>--<16 hex>.md, např. 20260904T171402Z--s-20260904153733-fc51--master--3c9ba2f--c0ffee1234567890.md.

Gramatika je gramatikou předávky s id relace vloženým za časové razítko a nese stejné čtyři vlastnosti. Úvodní časové razítko UTC činí lexikografické pořadí chronologickým. branch-key je bezpečné pro větve už konstrukcí. Krátký hlavní commit říká, proti které historii byl záznam zapsán. Šestnáct náhodných hexadecimálních znaků plus atomická publikace tvrdým odkazem činí záznam bezpečným proti kolizím: už použité jméno se zkusí znovu, nikdy se nepřepíše. Nic nečte čas změny souboru, který klon nepřežije a není časem, který záznam tvrdí.

---
schema_version: 1
created_at: 2026-09-04T17:14:02Z
task_id: t-20260904153733-fc51
profile: deep-work
owner: "alice"
repository_id: /abs/path/.git
worktree: /abs/path
branch: master
head: 3c9ba2f1d0e5a7b9c3f5e7a9b1d3f5e7a9b1d3f5
working_tree: dirty
changed_files:
  - lib/session.sh
session_id: s-20260904153733-fc51
started_at: 2026-09-04T15:37:33Z
closed_at: 2026-09-04T17:14:02Z
outcome: closed
worker: "some-provider/some-model"
start_head: 9b1e2d4f8c3a5e7b1d0f2a4c6e8b0d3f5a7c9e1b
start_working_tree: dirty
commits:
  - 2c4dc6f
  - 3c9ba2f
tasks:
  - t-20260904153733-fc51
issues:
  - I0801
milestones:
  - M003
checkpoints:
  - .ai/local/state/checkpoints/20260904T161122Z--master--2c4dc6f--a1b2c3d4e5f60718.md
handovers: []
decisions:
  - "2026-09-04 — The session envelope is derived from the ledger, not accumulated"
questions: []
evidence:
  - I0801:boundary_rewritten
---

Optional. Free text, written by whoever closed the session, or absent.

created_at, head a working_tree popisují uzavření, takže se záznam čte zpět tímtéž resolverem a týmž štítkem divergence jako předávka: head je commit, na kterém relace skončila, a štítek ho porovnává s aktuálním. start_head a start_working_tree popisují otevření.

commits je seznam commitů mezi start_head a head, v nejkratší formě. Když počáteční commit není předkem koncového — rebase během epizody — hodnotou je jediná položka diverged, ne seznam spočítaný napříč historií, která už nesouvisí.

Referenční seznamy nesou identitu, kterou každý druh skutečně má, a nic žádnou nevymýšlí:

PolePoužitá identitaProč právě tento
tasksid úlohyExistuje a je stabilní.
issues, milestoneskanonické idSame.
checkpoints, handoverscesta relativní k repozitářiSoubory jsou neměnné, takže cesta je identita.
decisionsdatovaný názevdecisions.md nemá pole id; datovaný titul je nadpis, který již používá, a to je to, co ledger zaznamenává.
questionstext otázkyopen-questions.md také nemá pole id; klíčem jeho řádkového formátu je text.
evidence<issue>:<token>Dvojice, ke které je záznam důkazu připojen.

Dvě z nich jsou slabší identity než ostatní a to je zaznamenáno, ne zamlčeno: rozhodnutí nebo otázka se odkazuje textem, takže úprava toho textu odkaz rozbije a validace relace to hlásí jako visící odkaz, místo aby se tiše vyřešila v nic.

Seznamy se odvozují, nenahromadí se. Počítají se při uzavření čtením ledger.jsonl a ničím jiným. Žádný jiný příkaz nezapisuje do záznamu relace; checkpoint, decision, question a plan jsou beze změny a o relacích nic nevědí.

Alternativa — každý příkaz připojuje svůj odkaz k otevřenému souboru relace, jak běží — byla zamítnuta dvakrát: dává zápis na horkou cestu příkazů, které dnes jen připojují jeden řádek ledgeru, a vytváří druhé měnitelné úložiště faktů, které ledger už drží, čemuž se má tento záznam právě vyhnout.

Výběr probíhá podle razítka relace na každém řádku, ne podle časového rozsahu. Každý řádek registru nese pole session jmenující epizodu, která jej zapsala, vedle head a branch, které už nesl; všechna tři se počítají, žádné není ručně psané. Časový rozsah se zkusil jako první a byl špatně: registr je jeden soubor na repozitář a jeho první skutečný běh sebral úlohy, kontrolní body a předávky jiného pracovníka, protože nic v časovém razítku souběžné pracovníky neodliší.

Řádek bez session nepatří do žádné epizody a žádná obálka si jej nenárokuje. To je správná odpověď, ne mezera — relace jsou volitelné a práce provedená mimo ně se připisuje nikomu, ne tomu, kdo měl náhodou poblíž otevřenou relaci.

Cenou je, že se ledger stává nosným pro druhý účel. Je jen přidávaný, zapisuje jej pouze Majordomus a už jej validuje majordomus.ledger-integrity, což z něj činí bezpečnou věc, ze které odvozovat. Pořadí řádků ledgeru se zachovává, takže dvě události zapsané ve stejné sekundě nepotřebují vůbec žádný tiebreak.

Front matter zapisuje Majordomus. Tělo obsahující řádek, který vypadá jako klíč front matteru, je odmítnuto, stejně jako u předávky. Režim 0600. Vytvořeno atomicky. Nikdy se nepřepisuje, nikdy se dodatečně needituje: uzavřená relace je nahrazena pozdějšími informacemi, ne opravena.


.ai/repo/prompts/<name>.md

Znovupoužitelné zarámování, verzované s repozitářem. Front matter je psaný, ne počítaný — nejsou to záznamy o práci.

---
name: debug
description: frame a defect so that the fix is proven, not asserted
profile: debugging
---
Task {{TASK_ID}} on branch {{BRANCH}} at {{HEAD}}: {{TASK}}

Open questions that block acceptance:
{{OPEN_QUESTIONS}}
KlíčVyžadovánoVýznam
nameanomusí se rovnat názvu souboru bez .md
descriptionanoneprázdné; zobrazuje prompt list
profileneprofil, kterému toto zarámování vyhovuje; jen dokumentace, nic podle něj nevybírá

Neznámé klíče jsou chyby, jako všude jinde.

Tokeny jsou uzavřená množina. Inline, dosazované kdekoli v řádku: {{TASK}}, {{TASK_ID}}, {{PROFILE}}, {{SCOPE}}, {{OWNER}}, {{BRANCH}}, {{HEAD}}, {{WORKING_TREE}}, {{REPOSITORY}}, {{NOW}}. Blokové, platné jen samostatně na řádku: {{OPEN_QUESTIONS}}, {{DECISIONS}}, {{CHECKPOINT}}, {{HANDOVER}}, {{CONTEXT}}.

Jakýkoli jiný {{...}} nebo blokový token použitý inline je chyba. Neexistuje žádný šablonovací jazyk: žádné podmínky, žádné cykly, žádné includy, žádný shell. Prompt, který tiše vykreslí {{TSAK}} jako doslovný text, je horší než ten, který odmítne. doctor a watch validují každý asset ze stejného důvodu.

Asset, jehož tělo obsahuje {{CONTEXT}}, se z context --prompt vyloučí místo vykreslení a vyloučení se pojmenuje: výsledkem by byl stejný kontext vnořený sám do sebe, který by rozpočet zaplatil dvakrát.


.ai/repo/skills/<id>/SKILL.md

Dovednost: postup nezávislý na poskytovateli pro jeden ohraničený druh práce. Front matter se píše, validuje se proti share/schemas/majordomus/skill/skill.v1.schema.json (allow-list share/allow/skill.txt se z něj generuje); tělo je postup. Identita dovednosti je id, které se musí rovnat názvu adresáře, a její URI MCP je majordomus://skill/<id>. Objevování je třída zdrojů skill v .ai/repo/knowledge/sources.yaml; nic jiného dovednost neregistruje.

---
schema: skill/v1
id: repo-review
version: 1
title: Repository review
description: An evidence-driven review of the actual state of the repository before work is recommended or done.
status: active
tags: [review, evidence]
related: []
inputs:
  - a checkout of the repository with git history available
outputs:
  - findings, each with severity, evidence, location and the smallest correct fix
---
# Purpose
...
# Procedure
...
# Output
...
KlíčVyžadovánoVýznam
schemaanoskill/v1
idano^[a-z][a-z0-9-]*$; musí se rovnat názvu adresáře
versionanocelé číslo alespoň 1
titleanoneprázdné
descriptionanojedna věta; ukazuje ji každý výpis
statusanodraft, active nebo deprecated
tagsneid, stejný vzor jako id
relatedneid jiných dovedností; každé musí existovat
inputs, outputsnejeden řetězec na položku; co worker potřebuje a co postup zanechává

Neznámé klíče jsou chyby. Tělo nese neprázdné sekce první úrovně # Purpose, # Procedure a # Output; majordomus skills check odmítne dovednost bez nich. examples/*.md vedle souboru jsou volitelné dokumenty, každý začínající nadpisem první úrovně. Viz CLI.md pro majordomus skills.


.ai/repo/adrs/<NNNN>-<slug>.md

Architektonické rozhodnutí: co bylo rozhodnuto, proč a co to stojí. Front matter je autorský nebo navržený nástrojem, validovaný proti share/schemas/majordomus/adr/adr.v1.schema.json (z něj se generuje povolená množina share/allow/adr.txt); tělo je vyprávění. Identita je adr-NNNN, přidělená jednou, nikdy znovu nepoužitá, a určuje prefix názvu souboru, takže přejmenování posune slug, nikdy číslo. Objevování je zdrojová třída adr v .ai/repo/knowledge/sources.yaml; nic jiného rozhodnutí neregistruje.

---
schema: adr/v1
id: adr-0004
kind: adr
title: One canonical declaration, composed modules, derived projections
status: accepted
date: 2026-09-05
tags: [architecture, capabilities]
supersedes: [adr-0002]
related:
  - rule:majordomus.capability-registry
  - claim:capability-registry
  - file:apps/majordomus-cli/src/capability
  - test:test/cases/91_canonical_architecture.sh
provenance:
  origin: extracted
  derived_from:
    - decision:t-2026-09-05-a
    - file:docs/CAPABILITIES.md
---
## Context
...
## Decision
...
## Consequences
...
KlíčVyžadovánoVýznam
schemaanoadr/v1
idano^adr-[0-9]{4}$; číslo se rovná předponě názvu souboru
kindanoadr
titleanojeden řádek, rozhodnutí, ne téma
statusanoproposed, accepted, superseded nebo rejected
dateanoYYYY-MM-DD, den, kdy dosáhlo tohoto stavu
tagsneid, stejný vzor jako jinde
supersedesnerozhodnutí, která toto zastupuje; každé musí existovat a odkazovat zpět na toto
superseded_bynepřítomno přesně tehdy, když je stav superseded
relatedneco rozhodnutí uvedlo v platnost: rule:<id>, claim:<id>, file:<path>, test:<path>. Každé se validuje a graf znalostí z něj dělá hranu — declares, supports, references, tested_by — takže opačný směr je dotaz, nikdy druhá hrana k údržbě
provenance.originneauthored (napsal člověk) nebo extracted (odvodil adr propose)
provenance.derived_fromnetypované odkazy: decision:, session:, commit:, issue:, file:, test:

Neznámé klíče jsou chyby. Tělo nese neprázdné sekce druhé úrovně ## Context, ## Decision a ## Consequences; ## Alternatives rejected je volitelná.

propose nikdy nezapisuje accepted. Zapisuje status: proposed a nemá žádný flag, který by říkal jinak, protože přijetí je úkon člověka: nástroj, který umí zapsat accepted, může z vlastní inference udělat pravdu repozitáře a čtenář o měsíce později nepozná, která je která. Záznam extracted musí jmenovat, z čeho byl odvozen — kandidát bez důkazů je tvrzení — a odmítne se, pokud si nárokuje accepted. Může být superseded, aniž by byl kdy přijat, protože to s ním udělal pozdější záznam, nikoli rozhodnutí, které si nárokuje sám.

Nahrazení je vzájemné. Řetěz, po kterém se dá jít jen z jednoho konce, není řetěz: supersedes na jednom záznamu vyžaduje superseded_by na druhém a adr check hlásí, že chybí kterákoli polovina. Identity se přidělují pod zámkem nad adresářem sekce, takže dva worktree navrhující ve stejný okamžik dostanou dvě čísla, ne jedno číslo dvakrát. Viz CLI.md pro majordomus adr.


.ai/repo/deployments/<id>.yaml

Jedno nasazení spustitelného souboru tohoto repozitáře a jediné autoritativní prohlášení o něm. Definice image kontejneru (deploy/Dockerfile) a jeho ignore soubor (.dockerignore) jsou z tohoto objektu generovány; každý nese hlavičku původu jmenující tento soubor a příkaz, který jej regeneruje, a majordomus generate --check selže, když je ručně upraven. Smlouva: share/schemas/majordomus/deployment/deployment.v1.schema.json (deployment/v1); klíče jsou uzavřeny share/allow/deployment.txt, generovaným z ní.

schema: deployment/v1
kind: deployment
id: majordomus                  # identity, [a-z][a-z0-9-]*
title: ...                      # one line, for a listing
description: ...                # one line: what it serves and to whom
status: declared                # declared | active | retired

application: majordomus         # the application's name, for a listing

build:
  package: majordomus-cli       # the Cargo package built
  binary: majordomus            # the binary target the image runs
  profile: release              # the Cargo profile
  inputs: [apps/majordomus-cli, share, .ai, Cargo.toml, Cargo.lock]
  site: site/public             # what the canonical site pipeline writes; absent = no site

listen:
  port: 8080                    # >= 1024: the process runs as a non-root user
  interface: all                # loopback | all — `all` is stated intent, not a suppressed warning

health:
  liveness: /api/v1/live        # must be a route a capability registers
  readiness: /api/v1/ready      # likewise
  grace_seconds: 2
  interval_seconds: 15
  timeout_seconds: 2

resources:
  cpu_kind: shared              # shared | performance
  cpus: 1
  memory_mb: 256                # a hypothesis until a measured run under it passes

machines:
  count: 1                      # the deployed inventory is asserted against this
  min_running: 0                # 0 with autostop: the cheap profile
  autostart: true
  autostop: true

region: fra                     # required; no generated artifact reads it now

budgets:                        # each written by the run that measured it; none guessed
  image_bytes: ...
  binary_bytes: ...
  build_context_bytes: ...
  cold_start_ms: ...
  resident_memory_mb: ...
  blocking_check_ms: ...
  request_p99_ms: ...

Není jmenován žádný hostingový poskytovatel. Žádný není cílem: dodává se binárky release, GitHub Pages a image GHCR sestavený z deploy/Dockerfile. Objekt dříve nesl blok provider jmenující Fly.io, vykreslený do fly.toml; nikdy tam nic neběželo a 2026-10-12 byly blok, jeho čtečka i fly.toml odstraněny společně. Klíč provider je nyní odmítnut jako jakýkoli jiný klíč, který kontrakt nemá.

Port je uveden jednou. Proces i image čtou toto jediné pole; doslovný port kdekoli jinde je drift, jemuž tento druh má předejít. Totéž platí pro health trasy a vstupy buildu.

Žádné přihlašovací údaje sem nepatří. Token, který nasazení autorizuje, přichází zvenčí repozitáře a nikdy se nezapisuje do objektu, do generovaného souboru, do vrstvy image ani do logu.

Schéma rozhoduje o tvaru; majordomus deploy doctor rozhoduje o smyslu — zdravotní trasa, kterou neregistruje žádná schopnost, balíček nebo binárka, kterou pracovní prostor neobsahuje, vstup sestavení, který se nepřekládá, min_running nad count — a každé odmítnutí uvede soubor, klíč, nalezenou hodnotu a opravu.

Image se sestavuje ve fázích, které cache unese. deploy/Dockerfile se vykresluje se čtyřmi builder fázemi před runtime (BUILDER_STAGES v src/deploy/render.rs): toolchain (image Rustu na přesném channel z rust-toolchain.toml — generátor odmítne repozitář bez něj, místo aby připnul druhou verzi), recipe (manifest a lockfile s maskovanou vlastní verzí balíčku, takže bump release dosáhne téhož receptu), deps (každá závislost zkompilovaná proti stub zdrojům, jako obsah vrstvy) a build (skutečné zdroje; jediná fáze, která čte commit). Cache mount by držel zkompilované závislosti jen na stroji, který je sestavil; vrstva putuje s exportem registry cache, takže čerstvý runner kompiluje jen balíček. .github/workflows/docker-image.yml sestaví image, spustí ho a zkontroluje, že /api/v1/live pojmenovává commit, a publikuje ghcr.io/korczis/prismatic-majordomus:sha-<commit> teprve poté, co běh validate toho commitu na masteru uspěl; jen on zapisuje sdílený ref :buildcache. Release image nic nekompiluje: .github/workflows/release.yml stáhne publikované linuxové musl archivy release, každý ověří proti SHA256SUMS, jeho atestaci původu a otagovanému commitu a sestaví s MAJORDOMUS_BINARY_FROM=release a build kontextem release-binary, takže image publikovaný jako :<tag> spouští bajty, které archivy dodávají, pro každou platformu, kterou dodávají.

$ docker buildx build -f deploy/Dockerfile \
    --cache-from type=registry,ref=ghcr.io/korczis/prismatic-majordomus:buildcache \
    --build-arg MAJORDOMUS_BUILD_COMMIT="$(git rev-parse HEAD)" -t majordomus:dev --load .

.ai/repo/workspaces/<id>.yaml

Jeden externí workspace, který smí tento repozitář číst: těleso obsahu drženého jiným dodavatelem — projekt ChatGPT a později projekt Claude nebo jeho ekvivalent — u kterého je operátor již přihlášen. Workspace není poskytovatel: poskytovatel je nástroj, který pracuje v tomto repozitáři (ADR 0024, share/providers.yaml), a workspace je šipka mířící opačným směrem. Oba jsou pojmenovány po stejných dodavatelích, proto je rozdíl zapsán a ne odvozován. Smlouva: share/schemas/majordomus/workspace/workspace.v1.schema.json (workspace/v1); klíče uzavírá share/allow/workspace.txt, generované z něj.

schema: workspace/v1
kind: workspace
id: chatgpt-majordomus          # identity, [a-z][a-z0-9-]*; stable across a rename upstream
title: ...                      # one line, for a listing
description: ...                # one line: what it holds and why this repository reads it
status: declared                # declared | active | retired

vendor:
  id: chatgpt                   # [a-z][a-z0-9-]*
  name: ChatGPT
  origins:                      # the only origins an adapter may observe; scheme and host
    - https://chatgpt.com

upstream:
  id: g-p-...                   # the vendor's own identifier, carried opaquely
  kind: project                 # the vendor's word for this shape of container
  url: https://...              # where a person opens it; nothing resolves it

authorisation:
  asserted_by: ...              # who asserts it
  asserted_at: 2026-09-09
  statement: "..."              # what is authorised, in a sentence a person would defend
  write: false                  # false until a separate decision says otherwise

access:
  browser_profile: default      # a label the operator's configuration resolves, outside
                                # this repository — never a path, a variable or a secret
  transports: [browser]         # official | browser | private_http, in preference order

capabilities:                   # expectation, not permission
  - workspace.read
  - conversations.read
  - messages.read
  - instructions.read
  - files.read

Obsah tu není a nikdy nebude. Konverzace, zprávy a přílohy workspace se synchronizují do .ai/local/workspaces/<id>/, což je stav tohoto checkoutu a nikdy zdroj (ADR 0005, ADR 0025). Nic pod ním se neindexuje, negeneruje z něj, nepublikuje ani nenese větví. Kus z něj se stane vlastním tvrzením repozitáře, až když ho člověk povýší do .ai/repo/, záměrně, kus po kuse.

Ani sem nepatří žádné přihlašovací údaje. access.browser_profile je schématem omezeno na ^[a-z][a-z0-9-]*$, aby se tam, kam patří štítek, nedala zapsat cesta souborového systému, proměnná prostředí ani token; to, na co se štítek rozliší, žije mimo repozitář. test/cases/93_workspace_kind.sh čte každou deklaraci a odmítne tu, která nese klíč nebo hodnotu ve tvaru přihlašovacích údajů.

Deklarace omezuje adaptér dříve, než se cokoli stáhne. vendor.origins je rozsah pozorování, ne nápověda — provoz k čemukoli, co tam není jmenováno, se nikdy nezaznamená, ne že by se filtroval až poté. authorisation.statement je tvrzení člověka jeho vlastními slovy a adaptér je nesmí překročit. capabilities je očekávání: to, které vendor stáhl, je diagnostika, a adaptér, který jedno nemůže poskytnout, jej hlásí jako nedostupné, místo aby vracel prázdný úspěch.


.ai/repo/knowledge/sources.yaml

Deklarované zdroje znalostí repozitáře: které sledované soubory jsou znalost, v jaké třídě. Objevování jde přes index správy verzí s pathspecem zde uvedeným, nikdy průchodem souborovým systémem, takže nesledovaný soubor, výstup sestavení nebo vendorovaný strom nikdy není zdrojem a dva stroje hlásí tentýž seznam ve stejném pořadí. Nástroj dodává provozní třídy (záznamy, které zapisuje pod stavový adresář) v share/knowledge-sources.yaml, s cestami relativními k tomu adresáři; rozsah třídy (shared nebo operational) rozhoduje, který ze dvou souborů ji deklaroval.

version: 1
sources:
  - id: policy              # the class, unique; also the order sources are reported in
    kind: policy            # the node kind every source in this class produces
    discovery: vcs          # the tracked files matching the pathspec
    pathspec: ':(glob).ai/repo/policy.yaml'
    required: true          # a class that discovers nothing is a finding, not a silence

Každý pathspec vcs nese předponu :(glob), aby * nikdy nepřekročil oddělovač adresářů a žádné dvě třídy si nenárokovaly jeden soubor. Čte se zpět pomocí majordomus knowledge sources.


.ai/repo/knowledge/candidates/<id>.md — kandidátní záznam znalostí

Co nástroj odvodil o repozitáři na hranici epizody a nikdo to ještě neposoudil. Zapisuje majordomus knowledge derive — při uzavření každé epizody, z události compaction, nebo ručně — přes dočasný soubor ve stejném adresáři přejmenovaný přes soubor pojmenovaný podle id, nikdy nestagovaný. Validuje se proti share/schemas/majordomus/knowledge/knowledge.v1.schema.json (allow-list share/allow/knowledge.txt se z něj generuje), tomu samému schématu, proti kterému se validuje kurátorská poznámka pod curated/: kandidát a ověřený záznam jsou jeden druh, o jeden stav dál. Objevování je zdrojová třída candidates v .ai/repo/knowledge/sources.yaml. Identita je id, která se rovná názvu souboru a odvozuje se z důkazů: id epizody následované digestem kanonického řetězce důkazů, takže stejný fakt vždy přistane ve stejném souboru a dva worktrees nikdy nezapíšou jeden název pro různý obsah.

---
schema: knowledge/v1
id: s-20260912101500-7f1a-3b9c2e4d1a05
kind: knowledge
class: convention
title: "Tabs are refused in the parser"
description: "Recorded as a decision under task t-20260912101512-b7c2 in episode s-20260912101500-7f1a."
status: candidate
epistemics: decided
date: 2026-09-12
tags:
  - derived
  - decision
provenance:
  origin: extracted
  derived_from:
    - session:s-20260912101500-7f1a
    - decision:t-20260912101512-b7c2
    - commit:3f2a9c1e4b7d8a05c1119f2b6e0d7a3c8e5f1b42
relations:
  - type: relates_to
    target: file:.ai/repo/rules/project/yaml-has-one-encoding.md
---

# Tabs are refused in the parser

Recorded as a decision under task t-20260912101512-b7c2 in episode s-20260912101500-7f1a.
KlíčVyžadovánoVýznam
schemaanoknowledge/v1
idano^[a-z][a-z0-9-]*$; rovná se názvu souboru; u odvozeného záznamu <episode-id>-<digest>
kindanoknowledge
classanofact, convention, constraint, memory nebo lesson; deriver zapisuje convention pro rozhodnutí, fact pro vyřešenou otázku nebo ověřené dokončení, lesson pro blokovanou, selhanou nebo nespárovanou úlohu; povýšení je místo, kde to člověk mění
titleanotvrzení, jeden řádek, v dvojitých uvozovkách s escapovanými \ a "
descriptionanojedna řádka říkající, odkud důkaz pochází
statusanocandidate pod candidates/; verified jen pod curated/; superseded, když jej člověk odmítl
epistemicsanodecided pro rozhodnutí, observed pro vyřešenou otázku nebo prošlé ověření, inferred pro výsledek úlohy
dateanoYYYY-MM-DD, den řádku s důkazem — deterministický, nikdy hodiny; stáří review se místo toho měří z knihy a gitu
tagsnederived a druh důkazu: decision, question nebo task
provenance.originano pro extractedextracted pro odvozený záznam; authored pro kurátorskou poznámku, kterou napsal člověk
provenance.derived_fromano pro extractedtypované odkazy: session:<episode>, pak decision:<task-id> nebo task:<task-id>, pak commit:<sha> pro každý commit epizody, který se dotkl pravidla nebo záznamu rozhodnutí; rozhodnutí zaznamenané mimo úlohu jmenuje samotnou relaci
relationsnerelates_to file:<path> pro každý záznam pravidla nebo rozhodnutí, kterých se tyto commity dotkly; přítomno jen když není prázdné
superseded_bykdyž supersededzáznam, který ho nahrazuje, když ho reject --by uvedl; jinak tělo nese # Rejected a důvod

Neznámé klíče jsou chyby. Tělo je název jako nadpis první úrovně a popis; povýšený záznam získá # Evidence s tím, co člověk dodal, zamítnutý # Rejected s důvodem.

Deriver nikdy nezapisuje verified. Zapisuje status: candidate a nic jiného; majordomus knowledge promote s důkazy na standardním vstupu přesune záznam do curated/ a nastaví verified a osoba, která soubor upraví, je ten druhý akt. Záznam pod candidates/ tvrdící verified je odmítnut příkazy check, doctor a majordomus knowledge check.

Tělo je tvrzení, nikdy přepis. Titulek, popis a tělo podléhají kontrole, která drží project.never-store-transcripts; řádek jmenující seznam zpráv, dokončení nebo odpověď modelu je blokující selhání a deriver odmítne zapsat záznam, jehož důkazy takový řádek nesou, místo aby jej zapsal, aby jej kontrola odmítla.

Každý odkaz se vyřeší. Relace v úložišti relací nebo ledgeru, úloha či rozhodnutí v ledgeru nebo adresáři stavu, commit v gitu, soubor či test ve stromě, úkol v sekci projektu, záznam znalostí v kterémkoli adresáři, pravidlo či záznam rozhodnutí ve vrstvě. decision:none a task:none se odmítají. Kompilátor grafu bere cíle v ledgeru a gitu jako externí a nikdy je nehlásí jako visící; integritní validátor je ten, kdo je řeší.


.ai/local/state/ledger.jsonl

Jen se připojuje. Zapisuje jen Majordomus. Jeden objekt JSON na řádek. Retence je omezena stropem; doctor hlásí překročení a history --rotate přesune nejstarší řádky do ledger.<utc>.jsonl.archived (nikdy nemaže).

Jeden řádek je jedna událost historie: co se stalo, kdy, pro kterou úlohu, na kterém headu a v které relaci. majordomus history je čte zpět.

Společná obálka:

{"ts":"2026-09-03T19:30:12Z","event":"task.started","head":"3f2a9c1e...","branch":"main","by":"majordomus/0.1.0","session":"s-20260903193010-a4f1","task_id":"t-20260903193012-b7c2"}

session je přítomno, když je v tomto worktree otevřena relace, a jinak chybí. Stejně jako head a branch se počítá, nikdy nepíše ručně. Podle něj se vybírají seznamy odkazů uzavřené relace a existuje proto, že alternativa nefunguje: ledger je jeden soubor na repozitář, takže výběr podle časového rozsahu nerozliší dva souběžné workery a první skutečný běh si přivlastnil záznamy jiného workera. Řádek bez session nepatří k žádné epizodě, což je poctivá odpověď pro práci mimo ni.

ts, event, head, branch, by a session jsou klíče obálky a payload nesmí žádný z nich použít jako název pole. JSON připouští zdvojený klíč a neříká, který z obou vyhrává, takže takový řádek znamená jedno pro čtenáře, který bere první, a něco jiného pro toho, který bere poslední. mj_ledger_append kolizi odmítne jako vnitřní chybu a pojmenuje pole; payload, který chce zaznamenat něco téhož tvaru, to pojmenuje jinak, což je důvod, proč potvrzení poskytovatelů nesou provider_event a ne event. Každý čtenář bere první výskyt klíče — klíč obálky — jedinou extrakcí, kterou deklaruje MJ_LEDGER_FIELD_AWK, takže řádek zapsaný starší verzí se čte tak, jak ho myslel jeho autor.

Slovník událostí je uzavřený. share/events.yaml deklaruje každé jméno, které ledger přijímá, co je zapisuje a klíče payloadu, které musí nést; mj_ledger_append neregistrované jméno odmítne, history --event odmítne podle něj filtrovat a history --validate ohlásí uložený řádek, jehož jméno nepozná žádný čtenář. Přidání události znamená přidat tam záznam — stejné pravidlo, které činí neznámý klíč politiky chybou.

Události a jejich další pole:

událostdalší pole
task.startedprofile, scope[], owner
task.checkpointcheckpoint_path, když bylo tělo napsáno; chybí, když se pohnulo jen checkpoint_at; task_id, když byla úloha otevřená, jinak chybí — checkpoint je záznam epizody a epizoda nemusí mít úlohu (ADR 0052)
task.evidencetask, covers (token povinnosti), kind, inputs_hash (nad deklarovanými vstupy povinnosti) a command, artifact, result, když jsou zadány
task.finishedoutcome, contract (objekt id doktríny → pass/fail/skipped), verify (command, exit, seconds) nebo null, checkpoints (počet)
task.refusedoutcome (ten, který je nárokován), unmet (počet selhaných řádků smlouvy), refused[] (mezi nimi doktríny), contract (objekt id doktríny → pass/fail/skipped); jeden řádek za každé odmítnuté finish, žádný pro finish --check
task.handed_overhandover_path, closed (pravda s --close); task_id, když byla otevřená úloha, jinak chybí
decision.recordeddecision (název položky)
question.openedquestion
question.resolvedquestion, answer
session.startedowner, worker když byl zadán
session.closedoutcome, session_path
session.recoveredsession_id (obnovená epizoda, která není nikdy ta, jíž je pojmenován razítkem session v obálce), reason (důkaz, který rozhodl — poslední známka života a její zdroj u opuštěné epizody, počet sloučených záznamů u duplikátu), session_path
provider.event.receivedprovider, provider_event (start/end/compact), provider_session, když poskytovatel nějaké jmenoval. Zapsáno jako první akt každého adaptéru životního cyklu, než jakákoli ochrana rozhodne, co s událostí dělat
provider.event.failedprovider, provider_event, reason. Druhá polovina potvrzenky: událost dorazila a práce, kterou měla vykonat, se nedokončila. Potvrzenka bez výsledného záznamu i bez jednoho z těchto vedle sebe je sama nálezem
observation.recordedtask_id (none mimo úlohu), kind, subject, statement, evidence (seznam typovaných odkazů, případně prázdný). Zapisuje knowledge observe; hranice epizody z něj odvozuje kandidáta (ADR 0118)
knowledge.derivedepisode, written, unchanged, paths; skipped, když byl řádek odmítnut. Zapisuje každé odvození bez dry-run, které vyřešilo epizodu, i když nic nezapsalo; episode je explicitní, protože razítko session obálky je přítomné, jen dokud je epizoda otevřená
knowledge.promotedid, path (cesta kurátorského záznamu relativní k repozitáři). Člověk povýšil kandidáta na ověřeného s důkazy
knowledge.rejectedid, reason; superseded_by, když --by pojmenovalo záznam, který ho nahrazuje. Člověk kandidáta zamítl; je nahrazen na místě
ledger.rotatedarchived (přesunuté řádky), kept, archive (cesta)
session.archivedarchived (přesunuté záznamy), kept (strop), archive (adresář, relativně k repozitáři). Zapisuje se jen tehdy, když majordomus session archive něco přesunulo; žádný záznam se nemaže
prompts.reconciledrecords (záznamy promptů znovu prozkoumány), linked, unlinked. Každý záznam v archivu se znovu přiřadí epizodě, ke které patří, z důkazů, které stále existují; záznam, jehož důkazy zmizely, se započítá jako nepropojený, nehádá se
task.gatetask, gate, exit, inputs_hash (nad sjednocením cest tříd CI, které kontrolu vybírají, takže změna kterékoli z nich činí běh zastaralým, a ne jen starým). Kontrola, která tuto událost nikdy nevydala, se hlásí jako zařazená do fronty, nikdy jako prošlá
prompts.prunedrecords (dotčené záznamy promptů), pruned (těla nahrazená náhrobkem), bytes_left. Záznam se nikdy nemaže: bere se tělo a záznam, který zůstane, stále říká, kdy se prompt udál, v jaké epizodě a jaký je digest a délka odebraného
projections.updatedpolicy_sha256, targets (počet)
use_cases.ranran, failed (počty; kroky nesou důkazy pod .ai/local/evidence/use-cases/)
plan_startissue
plan_verifyissue
plan_evidenceissue, covers (požadavek, který splňuje), type
plan_doneissue
layout.migratedfrom, to, backup (kopie místního stavu pořízená před přesunem, nebo prázdná)
rules.vendoredpackage (revize balíčku, který je nyní vendorován)
adr.proposedadr (zapsaná identita), title; nikdy se nezapisuje pro přijetí, což je úprava souboru člověkem

doctor, check (bez --checkpoint), watch, context, history, search, prompt, knowledge check a knowledge candidates nezapisují nic, ani do účetní knihy.

Každý řádek musí být objekt JSON nesoucí ts a event. Řádek, který není, je selhání v history --validate, check, doctor a watch: kniha, kterou nástroj nedokáže parsovat, je kniha, kterou nelze použít jako důkaz. Čtenář takový řádek přeskočí, místo aby spadl, takže poškozená kniha je stále čitelná, zatímco se o ní hlásí.

Protože created_at má rozlišení na sekundy, dva záznamy zapsané během jedné sekundy by se vyřešily v pořadí určeném náhodnými příponami jejich názvů souborů. Registr je pouze přidávací a zapisuje se v pořadí, v jakém příkazy běžely, což z něj dělá rozhodčí kritérium, které resolver používá — jediné přenosné monotónní pořadí dostupné bez podsekundových časových razítek.

history --rotate přesune všechny řádky kromě nejnovějších ledger.retention_max_lines do ledger.<utc-compact>.jsonl.archived a připíše událost ledger.rotated. Nikdy nic nemaže a odmítne přepsat existující archiv.

session archive je tentýž slib pro sekci relací: přesune nejstarší uzavřené záznamy nad session.retention_max_files do adresáře archive/ sekce a připojí událost session.archived. Běží jen na požádání a jen když je session.archive politiky true, nikdy nemaže a před prvním přesunem odmítne, je-li záznam stejného jména už archivován.


.ai/local/benchmarks/runs/<run-id>.json — běh benchmarku

Zapisuje majordomus bench, jeden soubor na běh, plus latest.json (nejnovější běh) a history.jsonl (jeden kompaktní řádek na běh). Lokální důkazy pod ignorovanou polovinou vrstvy; nikdy baseline.

{"schema":"majordomus/benchmark-result/v1",
 "run_id":"b-20260905T031200Z-9f1c","recorded_at":"2026-09-05T03:12:00Z",
 "repository":{"commit":"<40 hex>","branch":"main","dirty":false},
 "environment":{"os":"Darwin","arch":"arm64","bash":"5.3.15","clock":"epochrealtime"},
 "profile":{"samples":10,"warmup":2,"mode":"both"},
 "results":[{"command":"doctor","mode":"warm","class":"read-only","scenario":"fixture not-wired",
             "status":"ok","samples":10,"min_ms":2601,"p50_ms":2640,"p90_ms":2760,"p95_ms":2790,
             "p99_ms":2790,"max_ms":2790,"mean_ms":2655.2,"stddev_ms":58.1}]}

status je ok, setup-failed nebo exit-<code>, když příkaz skončil kódem, který jeho scénář nepřijímá. Percentily jsou nearest-rank přes seřazené vzorky. clock pojmenovává zdroj milisekund (epochrealtime nebo seconds).

baseline.json pod .ai/repo/benchmarks/ — přijatá základní hodnota

Tentýž dokument se schématem majordomus/benchmark-baseline/v1, zapisovaný jen příkazem majordomus bench --write-baseline na čistém stromě (nebo s --force), sledovaný a posuzovaný jako každá jiná změna. bench --check proti němu porovnává p50, p95 a p99 čerstvého běhu pro každý cíl a režim podle zlomků benchmark.regression v politice; baseline s jiným schématem se hlásí jako nesrovnatelná, nikdy jako číslo.

Časový report

S nastaveným MJ_TIMING=1 příkaz hlásí na stderr, kam se podíval jeho čas: každou fázi, kterou deklaruje, s milisekundami, které zabrala, a četností, pak každý čítač práce (parse YAML, volání gitu) sečtený. stdout zůstává vlastní výstup příkazu. Textová forma je pro člověka:

TIMING clock=epochrealtime total=2640 ms
phase      2178 ms     1 x  ctxd:cross_check
count         9     git

Pod --json jsou tatáž data jedním řádkem JSON, takže kontrola může porovnat rozpis jednoho běhu s jiným:

{"timing":{"clock":"epochrealtime","total_ms":2640,
 "phases":[{"name":"ctxd:cross_check","ms":2178,"calls":1}],
 "counters":[{"name":"git","count":9}]}}

Obě podoby se čtou z jedné agregace v jednom pořadí (fáze podle času, čítače podle počtu, shoda se rozhodne jménem), takže žádná nenese fázi ani čítač, který druhá postrádá; drží to případ 886. clock jmenuje zdroj milisekund (epochrealtime, nebo seconds, kde shell nemá EPOCHREALTIME) a total_ms běží od prvního řádku příkazu po report.

Razítko projekce

Každý generovaný cíl popisuje sám sebe; vedle něj není žádný soubor s původem, takže čerstvý klon nese stejné důkazy jako checkout, který jej vygeneroval.

Cíl v souborovém režimu začíná:

<!-- generated by `majordomus update` from .ai/repo/policy.yaml (policy 8e1d2c3b4a5f, content 4b2f9a01c7d3e6f8) — do not edit; edit the policy and regenerate -->

policy je hash politiky a všech profilů, zřetězených, v době generování. content je hash všeho pod řádkem razítka. Cíl v režimu oblasti nese stejné dvě hodnoty ve své počáteční značce:

<!-- majordomus:begin 8e1d2c3b4a5f 4b2f9a01c7d3e6f8 -->
...generated region...
<!-- majordomus:end -->

a content pak pokrývá jen tělo oblasti, nikdy hostitelský dokument kolem ní.

doctor selže na každém cíli, jehož obsah se liší od hashe, který jmenuje jeho razítko (ručně upraveno), i na cíli bez razítka (nezapsán příkazem update). watch hlásí drift politiky, když razítko jmenuje hash politiky, který už není politikou na disku, a update odmítne přepsat cíl, jehož obsah neodpovídá ani jeho razítku, ani novému výstupu.


Hlavička generovaného artefaktu

Bootstrapy poskytovatelů nesou výše uvedené razítko, které patří majordomus update. Každý jiný generovaný artefakt — vše, co zapisuje majordomus generate — nese hlavičku původu ve formě, kterou jeho kódování dovoluje, a tři řádky říkají v každém totéž:

<!-- GENERATED FILE — DO NOT EDIT DIRECTLY
     Source: <what it was derived from>; regenerate with `majordomus generate`
     Generator: majordomus-cli <version> -->
# GENERATED FILE — DO NOT EDIT DIRECTLY
# Source: <what it was derived from>; regenerate with `majordomus generate`
# Generator: majordomus-cli <version>

Dokument JSON je nese místo toho jako členy, schema první, když má kontrakt:

{
  "schema": "majordomus/capability-registry/v1",
  "generated": "GENERATED FILE — DO NOT EDIT DIRECTLY; source: …; regenerate with `majordomus generate`",
  "generator": "majordomus-cli 0.1.0"
}

a dokument, jehož vlastní specifikace pevně určuje názvy jeho členů — jediný takový je dokument OpenAPI — nese místo toho x-majordomus-generated a x-majordomus-generator. Řádkově orientované textové artefakty (share/allow/*.txt) mají tvar #; každý čtenář jednoho z nich přeskakuje řádky komentářů.

Žádná hlavička nenese časové razítko, absolutní cestu ani otisk, který se mění s nesouvisející úpravou. Index každého artefaktu s dokumentem, který promítá, jeho kódováním, smlouvou, zdrojem, velikostí a hashem je docs/generated/artifacts.json (schéma majordomus/generated-artifacts/v1) a sám je generován; smlouvy generovaných dokumentů jsou share/schemas/generated/*.schema.json, každá připnutá ke svému dokumentu členem const v schema dokumentu. Pravidlo je project.generated-artifacts-are-typed@1.


Koordinace worktree

Neexistuje žádný vedlejší registr. start a check --overlap čtou git worktree list a vlastní .ai/local/state/current.yaml každého worktree. Autoritou je git; nic nemůže shnít.


Poznámka o dokončení (když se nezapisuje žádná předávka)

finish přijímá --note <file>. Pro completed potřebuje povinné sekce předávky; pro partial/blocked položku # Next Action; pro no_match/failed položku # Reason. Pole output_contract profilu mohou úvodem tvořit blok YAML; finish poznámku zaznamená, ale tento blok nevaliduje. Při úspěchu se poznámka zkopíruje do state/completed/<id>.md.

---
outcome: completed
changes: 2
verification: make test — exit 0
blockers: []
next_action: none
---
# Objective
...
# Current State
...
# Next Action
none

Soubory schémat

63 souborů pod share/schemas/, každý odkazuje na svůj zdroj. Schéma druhu je pojmenováno jeho identitou; druhy, které ho deklarují, odkazují na místo, kde je druh publikován. Schéma generovaného dokumentu nepatří žádnému druhu.

schemasouborformátdruh
— share/schemas/generated/benchmark-matrix.schema.json json-schema —
— share/schemas/generated/capability-graph.schema.json json-schema —
— share/schemas/generated/capability-registry.schema.json json-schema —
— share/schemas/generated/changelog.schema.json json-schema —
— share/schemas/generated/cli.schema.json json-schema —
— share/schemas/generated/design-system.schema.json json-schema —
— share/schemas/generated/economics-summary.schema.json json-schema —
— share/schemas/generated/generated-artifacts.schema.json json-schema —
— share/schemas/generated/providers.schema.json json-schema —
— share/schemas/generated/site-design.schema.json json-schema —
— share/schemas/generated/site-evidence-subjects.schema.json json-schema —
— share/schemas/generated/site-product.schema.json json-schema —
— share/schemas/generated/site-registry.schema.json json-schema —
— share/schemas/generated/site-why.schema.json json-schema —
— share/schemas/generated/web-topology.schema.json json-schema —
majordomus.adr/v1 share/schemas/majordomus/adr/adr.v1.proto protobuf adr
majordomus.adr/v1 share/schemas/majordomus/adr/adr.v1.schema.json json-schema adr
majordomus.application/v1 share/schemas/majordomus/application/application.v1.proto protobuf aplikace
majordomus.application/v1 share/schemas/majordomus/application/application.v1.schema.json json-schema aplikace
majordomus.area/v1 share/schemas/majordomus/area/area.v1.schema.json json-schema oblast
majordomus.audience/v1 share/schemas/majordomus/audience/audience.v1.schema.json json-schema publikum
majordomus.capture/v1 share/schemas/majordomus/capture/capture.v1.proto protobuf —
majordomus.capture/v1 share/schemas/majordomus/capture/capture.v1.schema.json json-schema —
majordomus.claim/v1 share/schemas/majordomus/claim/claim.v1.schema.json json-schema claim
majordomus.command/v1 share/schemas/majordomus/command/command.v1.schema.json json-schema command
majordomus.context/v1 share/schemas/majordomus/context/context.v1.proto protobuf kontext
majordomus.context/v1 share/schemas/majordomus/context/context.v1.schema.json json-schema kontext
majordomus.critique/v1 share/schemas/majordomus/critique/critique.v1.schema.json json-schema kritika
majordomus.current/v1 share/schemas/majordomus/current/current.v1.schema.json json-schema —
majordomus.deployment/v1 share/schemas/majordomus/deployment/deployment.v1.schema.json json-schema nasazení
majordomus.derive-offload/v1 share/schemas/majordomus/derive-offload/derive-offload.v1.schema.json json-schema derive-offload
majordomus.distribution/v1 share/schemas/majordomus/distribution/distribution.v1.schema.json json-schema distribution-model
majordomus.document/v1 share/schemas/majordomus/document/document.v1.schema.json json-schema dokument
majordomus.domain/v1 share/schemas/majordomus/domain/domain.v1.schema.json json-schema doména
majordomus.feature/v1 share/schemas/majordomus/feature/feature.v1.schema.json json-schema funkce
majordomus.gap/v1 share/schemas/majordomus/gap/gap.v1.schema.json json-schema mezera
majordomus.intent/v1 share/schemas/majordomus/intent/intent.v1.schema.json json-schema intent
majordomus.issue/v1 share/schemas/majordomus/issue/issue.v1.schema.json json-schema issue
majordomus.knowledge/v1 share/schemas/majordomus/knowledge/knowledge.v1.proto protobuf knowledge
majordomus.knowledge/v1 share/schemas/majordomus/knowledge/knowledge.v1.schema.json json-schema knowledge
majordomus.manifest/v1 share/schemas/majordomus/manifest/manifest.v1.schema.json json-schema —
majordomus.mesh-declaration/v1 share/schemas/majordomus/mesh-declaration/mesh-declaration.v1.schema.json json-schema mesh-declaration
majordomus.milestone/v1 share/schemas/majordomus/milestone/milestone.v1.schema.json json-schema milestone
majordomus.moment/v1 share/schemas/majordomus/moment/moment.v1.schema.json json-schema okamžik
— share/schemas/majordomus/options.proto protobuf —
majordomus.policy/v1 share/schemas/majordomus/policy/policy.v1.schema.json json-schema policy
majordomus.profile/v1 share/schemas/majordomus/profile/profile.v1.schema.json json-schema profil
majordomus.project/v1 share/schemas/majordomus/project/project.v1.schema.json json-schema projekt
majordomus.prompt/v1 share/schemas/majordomus/prompt/prompt.v1.proto protobuf prompt
majordomus.prompt/v1 share/schemas/majordomus/prompt/prompt.v1.schema.json json-schema prompt
majordomus.release/v1 share/schemas/majordomus/release/release.v1.schema.json json-schema release-record
majordomus.rule/v1 share/schemas/majordomus/rule/rule.v1.proto protobuf pravidlo
majordomus.rule/v1 share/schemas/majordomus/rule/rule.v1.schema.json json-schema pravidlo
majordomus.scope/v1 share/schemas/majordomus/scope/scope.v1.schema.json json-schema scope
majordomus.session-context/v1 share/schemas/majordomus/session-context/session-context.v1.schema.json json-schema session-context
majordomus.session-record/v1 share/schemas/majordomus/session-record/session-record.v1.schema.json json-schema session
majordomus.session/v1 share/schemas/majordomus/session/session.v1.schema.json json-schema —
majordomus.skill/v1 share/schemas/majordomus/skill/skill.v1.proto protobuf dovednost
majordomus.skill/v1 share/schemas/majordomus/skill/skill.v1.schema.json json-schema dovednost
majordomus.taxonomy/v1 share/schemas/majordomus/taxonomy/taxonomy.v1.schema.json json-schema taxonomie
majordomus.use-case/v1 share/schemas/majordomus/use-case/use-case.v1.proto protobuf use-case
majordomus.use-case/v1 share/schemas/majordomus/use-case/use-case.v1.schema.json json-schema use-case
majordomus.workspace/v1 share/schemas/majordomus/workspace/workspace.v1.schema.json json-schema workspace

Tvrzení, která tento dokument definuje

Každý odkazuje na vlastní stránku s implementací, testem a místy použití.

Prohledává názvy a popisy všech stránek, které tento web publikuje.