I2741 — Merged work the plan has not recorded is drift, and on the trunk past a window it is red
Add plan.drift over plan.delivery with the classes merged_not_recorded, active_without_work and done_without_trace (advisory), and a gate scripts/ci/plan-drift-check that refuses merged_not_recorded older than a window declared in .ai/repo/ci/plan.yaml on the trunk, naming majordomus plan verify|done <id>.
DONE wave 1 · p0 · implementation profile · parallel safe
Objective
Add plan.drift over plan.delivery with the classes merged_not_recorded, active_without_work and done_without_trace (advisory), and a gate scripts/ci/plan-drift-check that refuses merged_not_recorded older than a window declared in .ai/repo/ci/plan.yaml on the trunk, naming majordomus plan verify|done <id>.
Why
ADR 0166 decision 2. Nothing compares declared status with merged work; the drift is what made the public roadmap a parallel universe.
Current state
No drift report exists between an issue's stamps and its delivery.
Desired state
majordomus plan drift [--json] lists every contradiction with its proof; the gate runs in validate, reports PENDING on a head and inside the window, and refuses past it; a missing or unreadable window refuses.
Scope
- apps/majordomus-cli/src/capability/builtin/plan.rs
- apps/majordomus-cli/src/plan
- apps/majordomus-cli/tests/plan_drift.rs
- scripts/ci/plan-drift-check
- .ai/repo/ci/plan.yaml
- .ai/repo/ci/README.md
- .github/workflows/validate.yml
- .ai/repo/automation/inventory.jsonl
- docs/PLANNING.md
- test/cases/3101_merged_work_unrecorded_is_drift.sh
Dependencies
What waits on this
- I2748BLOCKED The drift already on the trunk is settled before the gate is made blocking
- I2749READY A commit that only plans an issue is not its delivery
- I2750READY The trunk's drift gate reads the forge before it judges
- I3271READY plan.drift reports a source it could not observe as unknown, never as a drift finding
Acceptance criteria
- A READY issue whose merged pull request names it is reported merged_not_recorded with the pull request and merge commit
- The trunk's gate refuses it past the window and passes it inside the window, naming the settling command
- done_without_trace never refuses
Validation
- cargo test --manifest-path apps/majordomus-cli/Cargo.toml --test plan_drift
- bash test/run.sh 3101_merged_work_unrecorded_is_drift
Evidence required
- drift_case
- mutations_fail_the_case
Evidence
| covers | type | command | result | at commit |
|---|---|---|---|---|
| drift_case | test | bash test/run.sh 3101_merged_work_unrecorded_is_drift | ok 3101: merged_not_recorded with PR and merge commit, forge-title proof, trunk gate exit 10 past window / 0 inside / head pending / advisory 0, missing or unreadable window exit 12, done_without_trace never refuses | ee02079 |
| mutations_fail_the_case | test | 6 code mutations of plan/drift.rs and plan/delivery.rs, one at a time, then bash test/run.sh 3101_merged_work_unrecorded_is_drift | 6 of 6 killed: never-merged, ignore-open-pr, no-forge-titles, trunk-never-refuses, done-refuses, no-window-judged | ee02079 |
| drift_case | ci | validate run 39438896504 at master 9a5a9b77520: suite-shard (1) jobs 118683336189 and 118758852434 run 3101_merged_work_unrecorded_is_drift; rust (3) jobs 118683336401 and 118758853049 run cargo test incl. tests/plan_drift.rs | success (the run's only red job is pages, which runs no test) | 573df96 |
Timeline
- started
- 2026-10-20T22:13:26Z
- verified
- 2026-10-20T22:14:08Z
- completed
- 2026-10-20T22:15:11Z
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/I2741.yaml. Read it back with majordomus plan show I2741.