I2873 — The manifest schema is generated from typed sections
Manifest.sections becomes a typed struct, one documented optional path per section the layer knows, and share/schemas/majordomus/manifest/manifest.v1.schema.json is generated from the manifest's Rust types by majordomus generate (as the graph schema is), so the section list, its descriptions and the closed shape live in one place and the hand-written schema goes away.
BLOCKED wave 2 · p1 · implementation profile · parallel safe
Blocked. This issue cannot start until I2870, I1980 are done. The status is derived from that, not declared.
Objective
Manifest.sections becomes a typed struct, one documented optional path per section the layer knows, and share/schemas/majordomus/manifest/manifest.v1.schema.json is generated from the manifest's Rust types by majordomus generate (as the graph schema is), so the section list, its descriptions and the closed shape live in one place and the hand-written schema goes away.
Why
Split out of I2870 on 2026-10-21. The hand-written manifest schema closes `sections` with a fixed list of names and descriptions, while the Rust type reads them as an open map: generating the schema from today's types would quietly accept any section name on every App::load, a validation regression. Typing the sections first keeps the closed shape and makes the schema a projection (ADR 0004).
Current state
manifest.v1.schema.json is hand-written; Manifest.sections is a BTreeMap<String, String>; the two describe the section list twice.
Desired state
The sections are typed once; the schema is generated from them and generate --check holds it.
Scope
- apps/majordomus-cli/src/repository.rs
- apps/majordomus-cli/src/generate.rs
- share/schemas/majordomus/manifest
- .ai/repo/project/issues/I2873.yaml
Out of scope
- New sections or layout fields (I2870, I1980)
Dependencies
- I2870READY The layer's layout is declared as typed data: what each half holds, excludes, and the lifecycle of its contents
- I1980READY A layer names the tool version it was written for, and doctor tells version skew from defects
What waits on this
Acceptance criteria
- Manifest.sections is a typed struct and every reader of a section reads its field
- manifest.v1.schema.json is generated from the Rust types, keeps the closed section list and its descriptions, and generate --check holds it
Validation
- cargo test --workspace --all-features
- majordomus generate --check
Evidence required
- manifest_schema_generated
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I2873.yaml. Read it back with majordomus plan show I2873.