feat(#2646): surface unresolved deferred-items.md at milestone close (#2983)

* feat(#2646): surface unresolved deferred-items.md at milestone close

auditOpenArtifacts scanned eight categories; deferred-items.md was not
among them. #2287 made that file readable at the PHASE boundary
(audit-uat, /gsd-progress check 7), but one boundary up it stayed
invisible — and phase directories archive to milestones/vX.Y-phases/ by
default (#1871), so an out-of-scope discovery a phase agent correctly
recorded rather than fixed left the live tree at milestone close having
never reached the [R]/[A]/[C] prompt that exists to catch exactly this.

Adds deferred_items as a ninth scanner plus its count, its items entry
and its report section. The workflow needed no change: complete-milestone
branches on "any section with count > 0", so the new category flows
through the existing prompt.

The resolved/unresolved predicate is NOT reimplemented. uat.cjs already
exports parseDeferredItems, which owns the parsing rule (entries under a
`## Deferred Items` level-2 heading, else the whole file fail-safe;
RESOLVED only on an explicit case-insensitive `status: resolved` field).
The scanner requires it lazily, inside the scan, so audit-command-router's
property that a route never loads the module it does not need is
preserved. Two readers of one file sharing one predicate is the point —
duplicating the inequality is how they drift into disagreeing about what
"open" means.

Regression test proves fail-first: 9 of its 10 cases go red against the
pre-change tree. The tenth is the deliberate no-regression boundary (a
clean tree emits no section) and is green both ways.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015TQU48ETJjEmGLJjA6hdQ4

* docs(#2646): document the pre-close artifact audit and its nine categories

The /gsd-complete-milestone entry did not mention the audit at all, so
the gate that can stop a close was undocumented — and this change adds a
category to it. Tabulates all nine with their source artifact and what
makes each one "open", plus the [R]/[A]/[C] outcomes.

Also disambiguates the one genuinely confusing thing: the per-phase
deferred-items.md scanned here is NOT the `## Deferred Items` section the
[A] path writes into STATE.md. Same name, different artifact, opposite
ends of the flow.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015TQU48ETJjEmGLJjA6hdQ4

* chore(#2646): backfill changeset pr number

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015TQU48ETJjEmGLJjA6hdQ4

---------

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Co-authored-by: Tom Boucher <trekkie@nomorestars.com>
This commit is contained in:
Adnan
2026-08-02 02:27:33 +01:00
committed by GitHub
parent c61dd49d95
commit fc3fde05ee
5 changed files with 323 additions and 2 deletions

View File

@@ -454,6 +454,24 @@ Archive milestone, tag release.
/gsd-complete-milestone
```
**Pre-close artifact audit.** Before archiving, the workflow runs `gsd-tools audit-open` and reports every unresolved item across nine categories:
| Category | Source | Open when |
|----------|--------|-----------|
| Debug sessions | `.planning/debug/` | status not `resolved` / `complete` |
| Quick tasks | `.planning/quick/` | SUMMARY missing or not `complete` |
| Threads | `.planning/threads/` | status not terminal |
| Pending todos | `.planning/todos/pending/` | present |
| Seeds | `.planning/seeds/` | not yet implemented |
| UAT gaps | `*-UAT.md` | scenarios still pending |
| Verification gaps | `*-VERIFICATION.md` | verdict `gaps_found` / `human_needed` |
| CONTEXT questions | `*-CONTEXT.md` | questions left open |
| **Deferred items** | `deferred-items.md` | entry lacks `status: resolved` |
If any category is non-empty you are prompted with `[R] Resolve` / `[A] Acknowledge all` / `[C] Cancel`. `[A]` records the items to `STATE.md` under its own `## Deferred Items` heading and closes as `override_closeout`; an all-clear closes as `verified_closeout`.
> **Note:** the `deferred-items.md` category is the per-phase SCOPE BOUNDARY log a phase agent writes when it finds a defect it should not fix. It is a different artifact from the `## Deferred Items` section `[A]` writes into `STATE.md`, which records what you acknowledged at close.
---
### `/gsd-milestone-summary`