admin_reason: missing-secondary-reviewer — self-authored overnight sweep; two orthogonal agent reviews ran (isolated adversarial REQUEST-CHANGES with all six findings dispositioned, plus a bypass/consumer-lens APPROVE) and the sha-pinned bench passed 46362/0 on the merged head.
65 lines
2.8 KiB
Markdown
65 lines
2.8 KiB
Markdown
# Gap Closure Mode — Planner Reference
|
|
|
|
Triggered by `--gaps` flag. Creates plans to address verification or UAT failures.
|
|
|
|
**Important: Skip deferred items.** When reading VERIFICATION.md, only the `gaps:` section contains actionable items that need closure plans. The `deferred:` section (if present) lists items explicitly addressed in later milestone phases — these are NOT gaps and must be ignored during gap closure planning. Creating plans for deferred items wastes effort on work already scheduled for future phases.
|
|
|
|
**1. Find gap sources:**
|
|
|
|
Use init context (from load_project_state) which provides `phase_dir`:
|
|
|
|
```bash
|
|
# Check for VERIFICATION.md (code verification gaps)
|
|
ls "$phase_dir"/*-VERIFICATION.md 2>/dev/null
|
|
|
|
# Check for UAT.md with diagnosed status (user testing gaps)
|
|
grep -l "status: diagnosed" "$phase_dir"/*-UAT.md 2>/dev/null
|
|
```
|
|
|
|
**2. Parse gaps:** Each gap has: truth (failed behavior), reason, artifacts (files with issues), missing (things to add/fix).
|
|
|
|
**3. Load existing SUMMARYs** to understand what's already built.
|
|
|
|
**4. Find next plan number:** If plans 01-03 exist, next is 04.
|
|
|
|
**5. Group gaps into plans** by: same artifact, same concern, dependency order (can't wire if artifact is stub → fix stub first).
|
|
|
|
**6. Create gap closure tasks:**
|
|
|
|
```xml
|
|
<task name="{fix_description}" type="auto">
|
|
<files>{artifact.path}</files>
|
|
<action>
|
|
{For each item in gap.missing:}
|
|
- {missing item}
|
|
|
|
Reference existing code: {from SUMMARYs}
|
|
Gap reason: {gap.reason}
|
|
</action>
|
|
<verify>{How to confirm gap is closed}</verify>
|
|
<done>{Observable truth now achievable}</done>
|
|
</task>
|
|
```
|
|
|
|
**7. Assign waves using standard dependency analysis** (same as `assign_waves` step):
|
|
- Plans with no dependencies → wave 1
|
|
- Plans that depend on other gap closure plans → max(dependency waves) + 1
|
|
- Also consider dependencies on existing (non-gap) plans in the phase
|
|
|
|
**8. Write PLAN.md files:**
|
|
|
|
```yaml
|
|
---
|
|
phase: XX-name
|
|
plan: NN # Sequential after existing
|
|
type: execute
|
|
wave: N # Computed from depends_on (see assign_waves)
|
|
depends_on: [...] # Other plans this depends on (gap or existing)
|
|
files_modified: [...]
|
|
autonomous: true
|
|
gap_closure: true # Flag for tracking
|
|
---
|
|
```
|
|
|
|
**9. Number threat IDs after the phase's existing registers** (#4683): when `security_enforcement` is on, read the `<threat_model>` blocks of the phase's existing PLAN files and continue after their highest `T-{phase}-NN` — do not renumber from `T-{phase}-01`. Every ID already names a specific threat in an earlier plan; reusing it makes `SECURITY.md` rows and `VALIDATION.md`'s Threat Ref column ambiguous. `T-{phase}-SC` is reserved and every plan keeps it. The execute-phase init reports any cross-plan duplicates and hard-stops on them (`threat_id_duplicates`), so a collision surfaces here as a failed plan check.
|