# Changelog 2026-07-19 -- GA Phase-5 sweep session (one changelog for the whole
# session per GA-R2 amendment D1; batches append here as they close)

Executing session for the Phase-5 repair sweep (`docs/audit/phase5-sweep-plan.md`,
reviewed PASS + S1-S5). Every batch is operator-gated at its stated gate point;
every commit names its GA-F/GA-R trace and carries its own revert note. Status
lives in `docs/CURRENT-STATE.md` (GA-R1) -- this file records what CHANGED.

## Batch 0 -- tooling first (OPENED by operator 2026-07-19; repo-only, no cloud contact)

1. **0.1 repo-lint L10 status-coupling check (GA-R1 rule 8 / C1)** -- commit `0b991a5`.
   - WHAT: `repo_lint.py` gains L10: a change set modifying a state-bearing surface
     (anything under `docs/audit/`; a `**Status:` line in design-decisions.md; a
     gate row `| G<n> |` in session-ledger.md) without touching CURRENT-STATE.md is
     flagged. Pending working-tree set when dirty, HEAD commit when clean. WARN this
     batch (`L10_FAIL = False`); the flip to FAIL is a one-constant change due at
     Batch 1 open (sweep plan: "WARN for one batch").
   - WHY: amendment C1's Phase-5 implementation clause, verbatim. DIVERGENCE NOTED:
     the sweep plan's item 0.1 paraphrase said "CURRENT-STATE gate rows", which is
     vacuous (editing a CURRENT-STATE row touches CURRENT-STATE by construction);
     the ratified utterance says "ledger gate rows" and the ruling wins. The ledger
     carries no gate rows today; the pattern guards their reappearance.
   - Harness: tests/repo-lint T34-T41 (git fixtures), 42/42 PASS.
   - REVERT: `git revert 0b991a5`.

2. **0.2 ledger-scan SEC reporting repointed at security-ledger.md (GA-R4/F3)** --
   commit `b504cb6`.
   - WHAT: scan emits open COUNT + ID list + register-of-record pointer; row-level
     disposition text dropped from scan output. Session-ledger machine-derived SEC
     bullet re-seeded to pointer + count form. G14 evidence cell repointed at
     `docs/security-ledger.md` same commit.
   - WHY: F3 verbatim ("pointer and a scan-derived count, never row-level
     dispositions"). MEASUREMENT CORRECTION (GA-R1/C2): G14's count said 9; its own
     enumeration and the scan both measure 8 OPEN rows -- corrected to 8, divergence
     noted in the cell.
   - Harness: tests/ledger-scan +4 checks, 41/41 PASS.
   - REVERT: `git revert b504cb6` (restores the 2026-07-18 cell incl. its count error).

3. **0.3 ledger-scan wrap-aware next-free exclusion (GA-F15)** -- commit `527f1fd`.
   - WHAT: the "next-free"/"reproduc*" exclusion now suppresses the matching line
     AND the immediately following line (window exactly one line, reset per file),
     so a quoted next-free value whose hyphenated token wraps no longer counts as an
     assignment. Chose this over assignment-site counting: DOCFIX/BUNDLEFIX have no
     single register file to key assignment sites on (unlike D headers).
   - WHY: GA-F15 -- the wrap class fired twice live inside the audit itself
     (CURRENT-STATE section 9, now marked FIXED). Live counters re-verified
     UNCHANGED post-fix: D=130, DOCFIX=197, BUNDLEFIX=052.
   - Harness: tests/ledger-scan +3 checks, 44/44 PASS.
   - REVERT: `git revert 527f1fd`.

4. **0.4 record-audit status scan keyed to the legal token set (GA-F10 / vocab H1)**
   -- commit `f7580fd`.
   - WHAT: extractor knows Option A: legal OPEN/BLOCKED/HELD/CLOSED (OPEN was
     previously UNSCANNED -- post-migration OPEN-vs-CLOSED contradictions would have
     been invisible); DONE/TO RUN/RUNNING added; new report section 6 classifies
     every distinct token and flags illegal tokens + event words (VOID/REOPENED/
     SUPERSEDED) minted in status position. Prose event words stay legitimate
     row-history vocabulary. Report-only: 0/1/2 exit contract unchanged.
   - WHY: H1 requires the scan before any token migration (Batch 2.5 dependency).
     Live sanity run (scratch --out; the committed Phase-1 capture untouched):
     12 distinct tokens, 163 flagged counted occurrences = Batch 2.5's work-list.
     Contradiction groups 12 -> 13 on the scratch run: the OPEN-token detection
     gain, not drift.
   - Harness: tests/record-audit +9 checks, 33/33 PASS.
   - REVERT: `git revert f7580fd`.

Batch 0 verification: all three touched harnesses green (42/42, 44/44, 33/33),
full gauntlet + repo-lint results recorded in the batch completion report and the
ledger entry for this session.

## Batch 1 -- D-130 verification pair, decision, and the plan gate rebuild
## (OPENED by operator 2026-07-19)

1. **L10 flip WARN -> FAIL at batch open** -- commit `9683a18`. One constant
   (`L10_FAIL = True`) + harness rc updates, 42/42. Per the Batch 0 revert note.
   REVERT: `git revert 9683a18`.

2. **1.1 v8 plan-only verification (GA-F01, G4)** -- captures
   `docs/audit/outer-plan-20260719-baseline.txt` (7/2/7, zero drift from
   2026-07-18) and `outer-plan-20260719-v8-ignorechanges.txt` (6/2/6, ZERO
   forces-replacement). Suppression CONFIRMED; the operator's contingent lean
   survived its verification.

3. **1.2 v7 throwaway exercise (GA-F01, G4)** -- capture
   `docs/audit/throwaway-v7-20260719.txt`. Isolated `throwaway-v7-*` root
   (own scratch pool under the AppArmor-covered parent, no networks, no OS):
   defect reproduced (seed volume "must be replaced" after staging-ISO loss);
   replacement applied UNDER the running domain, rc=0, NO bounce (domid 3->3);
   teardown verified zero residue (0 domains, 0 pools, dir gone). New fact
   recorded: the bounce path is the autostart/domain Update, not the volume
   replace.

4. **1.3+1.4 D-130 ADOPTED (a) + implemented** -- commit `dac10e0`.
   GA-R5 ruling (question + utterance in the D-130 register entry);
   `lifecycle { ignore_changes = [create] }` on `libvirt_volume.seed` in
   `modules/cloudinit-vm`; NEW harness `tests/cloudinit-vm/run-tests.sh` (6/6:
   guard placement, exact attribute, no leak onto the data disk, tofu
   validate). G4 + G5 CLOSED. REVERT: `git revert dac10e0`.

5. **1.5-1.7 G6 reconcile + triple + G7 re-plan** -- commit `5a4f5eb`.
   Operator ruled (ii) state surgery (S3/GA-R5): autostart:true injected into
   both domain resources (were None), serial 22->23, backup
   `opentofu/terraform.tfstate.pre-G6-20260719`; guests untouched (ids 1/2,
   running). Re-plan capture `docs/audit/outer-plan-20260719-postG6.txt` =
   **6/0/6**, equals the section-5 recorded triple exactly -- G6 + G7 CLOSED.
   REVERT: docs via `git revert 5a4f5eb`; state via push of the pre-G6 backup.

## Out-of-batch: permission posture extension (operator-directed 2026-07-19)

- WHAT: `.claude/settings.json` `ask` list extended -- `Bash(git merge*)`,
  `Bash(git revert*)`, `Bash(git reset*)`, `Bash(git rebase*)`,
  `Bash(git branch -D *)`, `Bash(bash scripts/* apply*)`,
  `Bash(bash scripts/* install*)`, `Bash(ssh * sudo *)`, `Skill(*)`.
  Nothing added to `allow`; `deny` + the PreToolUse guard hook unchanged.
- WHY: operator drives sessions via Remote Control without a second terminal;
  remaining auto-mode classifier HARD-DENIALS (walls) on mutation surfaces
  matching no ask rule blocked the approve flow entirely (hit live: a Skill
  invocation hard-denied 2026-07-19). Extends the 2026-07-18 "ask preempts
  classifier" posture; targeted ask rules chosen over a catch-all `Bash(*)`
  per doc-cited guidance (ask appears to preempt allow -- a catch-all would
  destroy frictionless reads). `Skill(*)` syntax is undocumented; verified
  EMPIRICALLY (post-change Skill invocation prompted + ran; pre-change
  identical call hard-denied). Remaining walls get their own ask rule when
  hit -- the settings edit itself now prompts instead of denying.
- REVERT: `git revert` this commit, or `cp .claude/settings.json.bak` per the
  operator backup if the bak is refreshed first.

## Batch 2 -- record fixes (OPENED by operator 2026-07-19; commits per-GA-F)

1. **2.4 GA-F05 hostname** (`02af860`): vcloud on CLAUDE.md + SKILL.md + a
   discovered fourth surface (environment.md:43). Memory copy = Batch 3.
2. **2.2 GA-F03 tofu pins** (`b5981a9`): four sites demoted to the
   CURRENT-STATE section-7 pointer; the one LIVE false claim (workflow :360)
   corrected. A fifth site (platform-traps:19) fixed at batch close.
3. **2.3 GA-F04 OPNsense rows** (`6232dd3`): skill pin row -> pointer; trap
   sections requalified as entered-at-26.1-persisting; env.md's stale tofu
   pin (GA-F03 class) caught on the same surface.
4. **2.1 GA-F02 readiness doc** (`360e8d6`): three contradictory plan-count
   forms -> section-5 pointers; falsified deploy-ready blockquote reframed
   as history; fresh-session banner -> one-line pointer at the G9 canonical
   entry doc (operator scope addition, probe hole H1).
5. **2.5+2.6 H1 migration + GA-R1 demotions** (`47423c6`): mapping record
   docs/audit/h1-token-map-20260719.md (no token unmapped); workflow doc 26
   flags -> 0 (8 State lines demoted, tracker model dropped from the
   header); runbooks 18 -> 0 with close-out instructions RETARGETED at
   CURRENT-STATE; CURRENT-STATE 6 -> 0 (G9 STOPPED -> BLOCKED w/ named
   blocker; stale "GA-R1 NOT yet ratified" header fixed per C2); gate rows
   gained GA-R6/E1 [V]/[R] type tags; CLAUDE.md expectation line demoted
   (S5b). History classes deliberately untouched (Batch 4 / GA-R3).
6. **2.8 GA-F14 banner** on the D-127 changelog (content preserved).
7. **2.9 GA-F11/F12 adjudication**: one real live version row fixed
   (env.md:29 -> pin authorities); 192 non-history broken-ref rows
   adjudicated ALL false-positive (provider-repo doc paths, glob/range
   forms, slash-phrases, wraps) or VR0-era history docs routed to Batch 4.
   Spot-checks: as-built:59 "netbox/tailscale" = slash-phrase; workflow:473
   retired-script mention = history; env.md:86 "phase-00..08" = range glob.
8. **2.10 S1 R3-F disposition**: all 13 items accounted -- F01-F07/F09/F10
   closed by the 2026-07-16 Phase A/B + rulings + SEC-010 artifact;
   F08 CLOSED-SUPERSEDED (R-3's 4th storage node restored rebuild
   headroom); F11 FIXED (supernet-unassigned clause dropped; vr1-dc1 stays
   HELD on transit addressing, G12); F12 CLOSED (committed budget model,
   186 GiB headroom covers transient N+1 amphora; Stage-6 drill exercises
   the real path); F13 CLOSED as recorded observation. Stale readiness C5
   queue corrected (it queued amendments that landed 2026-07-16).
9. **2.7 GA-R3 D-tags (operator-ruled)**: D-121..125 [ARCH], D-126..129
   [OPS], D-130 [ARCH]; register template gains the class-tag convention;
   D-129's ARCH fragment (Roosevelt metal-edge profile) split to a dated
   D-122 AMENDMENT per A1 (utterance: "Tags as proposed + D-122
   amendment").

**Batch-2 verification + the criterion-mechanics finding.** Extractor
re-run: live-surface vocab flags = 0; the remaining flagged occurrences
(110) and contradiction groups (12) sit ENTIRELY on history-class surfaces
(session ledger, changelogs, the append-only register, VR0-era docs --
Batch 4's rotation/consolidation) or are extractor MECHANICS: the global
plan key conflates different roots' plans (Stage-1's 13-object plan vs the
DC0 triple), charm channels/step numbers read as juju versions, the
provider (2.7.2) vs MAAS-server (3.7.2) attribution, compatibility
thresholds (LXD >= 6.7), and prose like "Stage-4 concerns" keying a stage
status. FINDING (logged, not silently absorbed): the sweep plan's Batch-2
exit criterion "contradiction groups on counted non-changelog surfaces
reach ZERO" is not literally computable by the extractor's changelog-only
exclusion -- ledger/register/finding classes are counted non-changelog but
their ruled disposition is Batch 4/GA-R3 retention, and the status
authority itself must narrate history (7/2/7 -> 6/2/6 -> 6/0/6) to comply
with GA-R1 rule 2. The achieved, verifiable state: zero contradiction
among LIVE-surface status claims (mechanical classification script in the
session record); final ZERO-on-counted comes with Batch 4's rotation +
Batch 6.1 as the plan already sequences.

## Batch 3 -- memory hygiene (OPENED by operator 2026-07-19; edits per-file gated)

Pre-edit evidence: full memory dir copied to docs/archive/memory-20260718/.
1. **GA-F06**: `review-after-each-step.md` REMOVED. Repo copy of the
   provenance ruling: grounding-audit-20260718.md GA-F06 ("It was not a
   standing instruction. It was only supposed to be for a one time / very
   short sequence of steps."). No durable observation survives it -- the
   drift-catch anecdote is repo-recorded in the review changelogs.
2. **GA-F07**: `project-posture-closed-test.md` REMOVED. Repo copy of the
   provenance ruling: GA-F07 (stance never ruled; posture returns NEUTRAL;
   the closed-test FACT is repo-carried; SEC gates were never deferred).
3. **GA-F05**: hostname -> vcloud in `multi-workstation-remote-control.md`
   (the last of the four surfaces).
4. **GA-F08**: MEMORY.md index rebuilt -- two defective lines gone, the two
   surviving entries re-described accurately.
5. **GA-R7 rule 6 skill line**: "Claude Code sessions launch from the repo
   root, always" added to SKILL.md's session-bootstrap loop with the
   GA-F06-origin rationale (subdirectory launch = divergent auto-memory).
6. **G1 full review (rules 1-4)**: `creds-folder-convention.md` found
   duplicating a repo-carried convention + linking both removed entries --
   registered as **GA-F16** and reduced to a pointer entry (one
   possibly-unduplicated fact retained with a verify-then-graduate note).
   `multi-workstation-remote-control.md` reviewed: workflow facts operator-
   confirmed (the 2026-07-19 walls-vs-gates entry quotes a same-session
   directive; policy copy lives in the repo changelog it points at).
   Post-review state: 3 files, zero rule-1..4 violations, zero stale refs
   (grep-verified).
REVERT: restore any file from docs/archive/memory-20260718/ (pre-edit
copies); git revert the batch commit for the repo surfaces.
Note on the archive copies: `memory-20260718/MEMORY.md`'s em-dashes were
ASCII-normalized (`--`) to satisfy the repo L1 rule; the transform is
whitespace/punctuation-only and content-faithful (this note is the record
of it). No gauntlet run for this batch: zero script/tooling changes
(memory + docs + one skill prose line); repo-lint 0-fail + fence check OK.
