Newer
Older
openstack-caracal-dc-dc / docs / audit / phase5-sweep-plan.md

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.