Skip to content

v1.35.0 ·

The report that said nothing was wrong

The problem

aidlc amend refuses a Reopens: naming the phase you are standing in ("a reopen moves backwards"). On inbox-intake-bar, in testing, a one-line criterion fix therefore reopened requirements, design, implementation and testing.

Three things the roadmap item did not know, found by reading the code and re-running the command on 2026-09-27:

  1. Reopens: none already exists (first-run-gaps, 2026-09-15, eight days before the incident). It records the amendment and reopens nothing. Nothing pointed at it: the phase-ahead-of-current error does not mention it, and neither the requirements skill nor docs/lifecycle.md documents it.
  2. Reopens: none is taken on the author's word. No check stands behind it, so today it is exactly the "skip the reopen on the operator's say-so" path the item rules out.
  3. The impact report was not correct. The item says it reported "no citations of AC-17 found outside requirements.md" and was right. It was wrong: inbox-intake-bar/design.md:120 cites AC-17, and design was a completed phase. The walk resolves bare ids in the instance's own artifacts by the cross-instance uniqueness rule, so once a second instance defined an AC-17 the citation was dropped as "ambiguous" (17 files, re-run 2026-09-27). A check built on the report as it stands would have let design stay complete while citing a retired criterion — the exact silent disagreement the protocol exists to stop.

So the fix is not "loosen the rule". It is: make the citation data trustworthy for the instance's own artifacts, make the write path refuse any reopen that leaves a citing phase complete, and then let a correction confined to the current phase through on that evidence.

How it could be solved

Three decisions, and the first one reversed what the roadmap item assumed.

The item asked for a way to skip a reopen when a correction is confined to the current phase, and pointed at the impact report as the evidence: on inbox-intake-bar it had said nothing outside the requirements cited the retired criterion. Re-running it showed the report was wrong. That instance's own completed design.md cited the criterion, and the walk had dropped the citation as "ambiguous" because another instance defined the same id. Building on the report as it stood would have produced exactly the failure the amendment protocol exists to stop: a completed phase quietly disagreeing with the requirements. So the first change is not to the reopen rule at all. A bare id inside an instance's own files now means that instance, because there is no other instance it could mean. Test files keep the stricter rule.

The second was whether to add a way through at all. Reopens: none already existed, taken on the author's word, and simply documenting it would have been the cheapest fix. It was rejected because the author's word is the thing a tired operator will give. Instead the tool checks: any reopen, none included, is refused if it would leave a completed phase still citing a retired criterion, and the refusal prints the Reopens: it would accept. There is no flag to skip it. Naming the current phase became legal and means the same as none, because that is what people type when a correction belongs to the phase they are in.

The third was how far the check could reach without breaking an older decision. The original design forbade the citation walk from choosing what gets reopened, because a destructive write should not depend on scanning prose. That still holds. The walk can now stop a write, never cause one, so the worst a false match can do is ask for a wider reopen than needed, which is what every amendment cost before. The check then ran on its own instance: a second amendment tried to reopen too little, was refused, and named the phase it had to reach.

How AIDLC solves it

aidlc amend no longer forces a full reopen for a correction confined to the phase you are in, and no longer trusts the author's word that nothing else is affected.

  • Reopens: may name the current phase. It means the same as Reopens: none: the amendment is recorded, no phase moves, no transition record. Before, it was refused as "a reopen moves backwards", and the only way through reopened every phase back to the criterion's.
  • Every reopen is checked against the citations. aidlc amend refuses — new error code uncovered-citation — any Reopens:, none included, that would leave a completed phase still citing a retired criterion. It names each phase with its count and prints the Reopens: it would accept. No flag skips it; --override and --confirm do not.
  • The citation walk now sees the instance's own artifacts. A bare AC-n in the instance's own design.md was dropped as "ambiguous" whenever another instance defined the same id. On inbox-intake-bar that hid the one citation that mattered.
  • --impact ends with a verdict line, and --json carries a coverage object. The suggested reopen never names a phase the write path would refuse.

No state format or config key changes. AmendEnvelope gains coverage; ImpactReport gains phaseCitations; the error-code set gains uncovered-citation — all additive.

Behaviour change to call out: an amendment that declared Reopens: none while a completed phase still cites the retired id was accepted before and is refused now. That is the point.