# Phase-5 sweep plan -- REVIEWED (authored 2026-07-18; external review PASS
with amendments S1-S5, applied 2026-07-18)

STATUS: REVIEWED. External review PASSED with five amendments (S1-S5),
folded in below and diffable against the reviewed draft (`687dfa8`). No fix
executes until each batch is operator-gated at its stated gate point. Authored
at the close of the grounding-audit session (Phases 1-4 complete, all GA-R
rulings ratified -- `docs/audit/ga-rulings.md`). The executing session is a
FRESH normal operator session (auto-memory ENABLED per GA-R7 rule 8) whose
first action is reading this plan and `docs/CURRENT-STATE.md`.

Standing rules over every batch: FREEZE holds until a batch is gated open;
every fix commit names its GA-F number (charter Phase 5 -- "a fix without a
finding number does not ship"); every script change ships with its green
harness + repo-lint 0-fail (delivery discipline); every status-bearing
commit touches CURRENT-STATE.md (GA-R1 rule 8); one changelog for the whole
session (GA-R2 rule 5/D1); revert path = the per-batch commits are
individually revertable, each commit message carrying its own revert note.
The session ends with a GA-R4 close. Mid-sweep session breaks happen ONLY
at batch boundaries, each with a GA-R4 close; the successor session
re-reads this plan and CURRENT-STATE.md before its first gate (S5a).
Per-batch completion reports carry the batch verification output + the
ls-remote proof-of-push hash.

## Batch 0 -- tooling first (so later batches run under the new checks)

Gate point: operator opens the batch; items are non-cloud, repo-only.
| Item | Traces to |
|---|---|
| 0.1 repo-lint gains the GA-R1 rule-8 check: a commit modifying state-bearing surfaces (docs/audit/ captures, ga-rulings.md, design-decisions Status lines, CURRENT-STATE gate rows) without touching CURRENT-STATE.md is flagged | GA-R1/C1 |
| 0.2 ledger-scan: SEC reporting repointed at security-ledger.md (pointer + count in the session ledger only); G14 evidence cell repointed same commit | GA-R4/F3 |
| 0.3 ledger-scan: mention-derived counter hardening (assignment-site counting or paragraph-joined exclusion) | GA-F15 |
| 0.4 record-audit extractor: status scan keyed to the legal token set (OPEN/BLOCKED/HELD/CLOSED), flags illegal tokens and event-words-as-status | GA-F10, vocab H1 |
Ordering rationale: 0.1 first so every later batch commits under the C1
check; 0.2/0.3 before anything cites G14 or a next-free number; 0.4 before
any token migration or extractor-based verification (H1 requires the scan).
Post-batch verification: all four harnesses green; gauntlet ALL GREEN;
repo-lint 0-fail (now including the C1 check).
Revert: per-item `git revert`; the C1 check is a WARN for one batch before
becoming FAIL, so a bad rule cannot wedge the sweep.

## Batch 1 -- D-130 verification pair, decision, and the plan gate rebuild

This is the ordered chain the whole deploy path waits on.
1. **v8 (plan-only):** add `lifecycle { ignore_changes }` on the seed
   volume in a WORKING-TREE-ONLY edit; `tofu plan` captured to a dated
   file. Question answered: does it suppress the forced replacement?
   No apply; edit reverted or kept per D-130 outcome. Traces: GA-F01, G4.
2. **v7 (gated mutation):** v0.9.8 volume-replace-under-running-domain
   exercised on a THROWAWAY domain (create -> observe replace behavior ->
   destroy). Presented as an individually gated block; touches nothing
   live. Per S4: every created object uses the collision-proof name
   prefix `throwaway-v7-*`; volumes live in scratch/named storage (never
   a live pool path); the closing checks VERIFY destroy + undefine + the
   deletion of every `throwaway-v7-*` volume (virsh list --all + pool
   listing show zero residue). Output captured to a dated file.
   Traces: GA-F01, G4.
3. **D-130 DECISION POINT (operator, GA-R5 format).** The operator's
   recorded contingent lean (charter 1a, GA-F01): (a) `ignore_changes` --
   in-repo, environment-independent, the Roosevelt-shaped property --
   CONTINGENT on v8 confirming suppression. **If v8 refutes it, the lean
   is DEAD -- do not rescue.** Fallback (b): persistent `$TMPDIR` staging
   path + a runbook-enforced env guard, with the fragility concern stated
   and accepted. The decision text quotes the captured v7/v8 output.
4. **Implement the ruled mechanism** (gated; module edit + harness).
5. **G6 state reconcile -- OPERATOR RULING in GA-R5 format (S3):** the
   mechanism choice (`tofu import` / state surgery / maintenance-window
   apply) is presented as a single question with per-option captured
   evidence; the ruling records the paired question and utterance.
   Outcome: autostart + seed reconciled WITHOUT bouncing guests
   (`-refresh-only` is a proven no-op).
6. **CURRENT-STATE section 5 update:** record the new expected triple and
   WHY, in the SAME commit as the capture that evidences it (C2).
7. **Re-plan to a dated capture; must equal the recorded triple (G7).**
Ordering rationale: v8 before D-130 (the lean is contingent on it); D-130
before any seed fix; reconcile before re-plan so the triple is clean.
Post-batch verification: the G7 capture equals section 5 exactly.
Revert: the mechanism commit reverts cleanly; state operations are
operator-gated one at a time with a named rollback in the block.

## Batch 2 -- record fixes (the GA-F backlog, all repo-only)

Gate point: operator opens the batch; commits land per-GA-F.
| Item | Traces to |
|---|---|
| 2.1 readiness doc: plan counts corrected to POINT at CURRENT-STATE section 5; fresh-session banner DEMOTED to a one-line pointer at the G9 canonical entry path | GA-F02 + scope addition |
| 2.2 tofu pin: opentofu/README.md:41 + workflow doc :47/:360/:875 demoted to pointers | GA-F03, GA-R1 rule 3 |
| 2.3 skill references: OPNsense 26.1 rows -> 26.7 or pointer to CURRENT-STATE pin table | GA-F04 |
| 2.4 hostname: CLAUDE.md:4, SKILL.md:46 -> vcloud | GA-F05 |
| 2.5 H1 token migration: extractor scan lists EVERY distinct status token; each mapped per the vocabulary ruling (TO RUN/RUNNING -> OPEN etc.); no token survives unmapped; gate rows gain their GA-R6/E1 type tag | GA-F10, vocab H1, GA-R6/E1 |
| 2.6 GA-R1 rule-3 demotions: workflow stage table -> identity + links; README pin drops; CLAUDE.md's embedded expectation line ("expect 0 fail / 1 legacy WARN") demoted to a pointer under GA-R1 rule 1 (S5b) | GA-R1 |
| 2.7 D-number class tags: register template + one-time D-121..129 review (tags proposed to operator as a ruling-type item; D-129 ARCH fragment split per GA-R3/A1) | GA-R3 |
| 2.8 D-127 changelog: stale-claim banner added (points at GA-F14; content preserved for history) | GA-F14 |
| 2.9 GA-F11/GA-F12 adjudication: live-surface version rows and broken refs on NON-changelog surfaces fixed or pointed; changelog-class rows left to Batch 4 consolidation | GA-F11, GA-F12 |
| 2.10 (S1) R3-F residual disposition: every open item from the 2026-07-16 adversarial review (R3-F12 Octavia transient headroom, the netem D-100 sub-item, any other open R3-F) -- verify current state, then CLOSE with evidence or route into CURRENT-STATE's open-decision queue; none may remain unaccounted | R3-F register, GA-F, charter Phase 5 |
Post-batch verification: extractor re-run -- contradiction groups on
counted non-changelog surfaces reach ZERO; broken-ref count on live
surfaces reported and reviewed.
Revert: per-GA-F commits, individually revertable.

## Batch 3 -- memory hygiene (GA-R7 rule 6; first stage-close memory review)

Gate point: operator opens; each file edit shown before write (memory is
outside the repo -- edits are mutation-gated).
Items: correct/remove `review-after-each-step.md` (GA-F06) and
`project-posture-closed-test.md` (GA-F07) per the recorded provenance
rulings; update MEMORY.md index (GA-F08); fix hostname in
`multi-workstation-remote-control.md` (GA-F05); add the skill line
"Claude Code sessions launch from the repo root, always"; run the full
GA-R7/G1 memory review against rules 1-4 and register any further
violations as findings.
Post-batch verification: memory directory re-read in full; zero rule-1..4
violations; repo copies of the two provenance rulings cited.
Revert: memory files are backed up to docs/archive/memory-20260718/
before edit (evidence preserved; GA-R7/G3 pointer discipline).

## Batch 4 -- consolidation and rotation (GA-R2 + GA-R4)

Gate point: operator opens; one sub-commit per stage, message MANIFESTS
the source files consolidated (GA-R2/D2).
Items: 95 changelogs -> per-stage consolidated records (durable content
routed: configuration -> as-builts, traps -> platform-traps/skill,
rulings -> design-decisions; narrative -> stage record/archive); EVERY
docs/ file dispositioned (durable home / archive / retained with one-line
justification); under-25 top-level target (archive + dated captures
excluded); GA-R4 rule-6 one-time ledger rotation (bodies -> docs/archive/,
bounded summaries retained, live set under 300 lines -- after which the
F1 cap semantics are enforceable). Traces: GA-F09, GA-F13, GA-R2, GA-R4.
Post-batch verification: `ls docs/*.md | wc -l` < 25; ledger < 300 lines;
`ledger-scan --fences` OK; extractor re-run shows no NEW groups.
Revert: consolidation commits are per-stage; each manifest allows
mechanical restoration from git history.

## Batch 5 -- skill sweep (chartered mandatory item)

Gate point: operator opens. Implement the RATIFIED GA-R rulings in
`openstack-cloud-ops` (reconciling `skill-additions-proposed.md` against
the ratified text where they differ); keep the skill TIGHT -- facts
delegate to CURRENT-STATE.md/as-builts, invariants live in the skill.
Traces: charter Phase 5 skill sweep, GA-R1..R7.
Post-batch verification: repo-lint clean; a skill read-through against
ga-rulings.md line by line (checklist committed with the batch).
Revert: single-commit sweep, revertable.

## Batch 6 -- Phase-6 exit runs (charter section 7, in order)

1. Extractor re-run: ZERO contradictory status-claim pairs on counted
   surfaces.
2. docs/ working set at the GA-R2 target, history preserved.
3. Fresh probe trio -- NEW agents, clean context, auto-memory DISABLED
   (GA-R7 rule 8): 7/7 on at least two of three, no question failed by
   all three.
4. Captured outer plan reads EXACTLY the section-5 recorded triple.
5. (S2) Before G9 is declared open: confirm G9's gate row names the
   SEC-010 pre-apply dependency (`site-headend-install.sh --host-nodes
   --check` on vvr1-dc0 at deploy step B) and any other SEC row gated on
   apply, so the sweep-to-apply gap cannot swallow a security gate.
6. Operator reads CURRENT-STATE.md top to bottom and re-signs (signature
   REPLACES section 11 per GA-R1 rule 7).
Then, and only then, the DC0 apply path resumes from its gate (G9).

## Dependency summary

0.1 -> all later batches (C1 check active). 0.2/0.3 -> any G14/next-free
citation. 0.4 -> 2.5 and every extractor verification. 1.1(v8) -> 1.3
(D-130) -> 1.4-1.7 -> 6.4. Batch 2 before Batch 4 (consolidate corrected
records, not lies). Batch 5 after Batches 1-4 (sweep stable rulings +
facts). Batch 6 last, in charter order.
