I3247 — Work is drafted for each criterion nothing serves, under a key derived from the intent, the criterion and the gap, so a second draft drafts the same work
Revive I2218 from origin/chore/the-owner-packs-are-planned (ec37317fe7c, 2026-10-10, never landed): intents.draft_plan prints one issue draft per criterion no live issue serves and the gap did not observe satisfied, plus one per gap work item naming no issue, each with serves, scope from the criterion's reference, acceptance naming the criterion's evidence and a draft key derived from (intent id, criterion id, gap kind).
BLOCKED wave 1 · p1 · implementation profile · parallel safe
Blocked. This issue cannot start until I3246 is done. The status is derived from that, not declared.
Objective
Revive I2218 from origin/chore/the-owner-packs-are-planned (ec37317fe7c, 2026-10-10, never landed): intents.draft_plan prints one issue draft per criterion no live issue serves and the gap did not observe satisfied, plus one per gap work item naming no issue, each with serves, scope from the criterion's reference, acceptance naming the criterion's evidence and a draft key derived from (intent id, criterion id, gap kind).
Why
Coverage already refuses a criterion nothing serves (criterion_uncovered, intent_plan.rs:522) and stops there. The owner's demand that the loop not file duplicate issues on every evaluation (2026-09-15, 2026-10-08) needs the identity to be derived rather than remembered. Proposed in ADR 0191 (A plan drafted from an intent is a proposal, checked by the plan's own validators before any record is written); ADR 0192 (Replanning is bounded, idempotent and never weakens its intent) (proposed; it carries no authority until the owner accepts it). Sources: chatgpt-majordomus:c141#1, chatgpt-majordomus:c196#3, chatgpt-majordomus:c198#15, chatgpt-majordomus:c221#2, chatgpt-majordomus:c270#4.
Current state
No draft of work exists; criterion_uncovered names the criterion and stops; intents.propose writes only an intent with no milestone or criterion (ADR 0144).
Desired state
draft_plan is pure over the intent, the plan, the gap and the critique; the draft key is stable across runs and is how a later reconcile recognises the item.
Scope
- apps/majordomus-cli/src/capability/builtin/intents.rs
- apps/majordomus-cli/src/intent_plan.rs
- apps/majordomus-cli/src/intent_review.rs
- apps/majordomus-cli/src/commands/intent.rs
- apps/majordomus-cli/src/cli.rs
- apps/majordomus-cli/tests/intent_plan.rs
- docs/PLANNING.md
Dependencies
What waits on this
- I3248BLOCKED A draft that drops or weakens a criterion of its intent is refused unless a recorded decision names the change
- I3249BLOCKED A replan is bounded: past a declared budget of drafts without measurable progress it ends in a named state a person resolves
- I3252BLOCKED A draft plan is judged as if it were written, and only a checked draft is written, through one capability
- I3260BLOCKED One intent is carried in a disposable repository from a sentence through a failing criterion to a satisfied verdict, across two providers and a handover
Acceptance criteria
- An intent with one uncovered criterion drafts exactly one issue serving it; adding a live issue that serves it drafts none
- A criterion the gap observed satisfied drafts nothing
- Two drafts at one commit carry the same keys in the same order
Validation
- majordomus plan validate
- majordomus intent validate
Evidence required
- test_work_is_drafted_once_per_unmet_criterion
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/I3247.yaml. Read it back with majordomus plan show I3247.