# Grounding-audit findings register (GA-F) -- opened in Phase 1, 2026-07-18

Consolidated register per charter Phase 5; OPENED during Phase 1 so findings
land in one place from the start (no parallel scratch registers). FREEZE is in
effect: entries here are findings + proposed fixes ONLY. No fix is applied
until Phase 5, operator-gated, and every fix commit must name its GA-F number.

Evidence sources: `record-inventory.md` (mechanical extraction, HEAD 148dcef),
`env-snapshot-20260718.md` + `outer-plan-20260718.txt` (measured live),
operator provenance rulings quoted verbatim from the 2026-07-18 charter
amendment. Severity: CRITICAL = blocks/falsifies a deploy gate; HIGH =
corrupts trust in a load-bearing record surface; MED = stale/contradictory
record needing adjudication; LOW = hygiene.

---

## GA-F01 -- CRITICAL -- live outer plan is 7/2/7; no recorded gate count matches

**Evidence:** `docs/audit/outer-plan-20260718.txt` (Plan: 7 to add, 2 to
change, 7 to destroy); decomposition in `env-snapshot-20260718.md`. Recorded
gate values: 5/0/6 (`docs/dc0-deploy-readiness.md:59`, `docs/session-ledger.md:278`)
and 5/2/6 (`docs/dc0-deploy-readiness.md:37`). The delta over 5/0/6 is entirely
voffice1's cloud-init seed: the live volume was deleted (post-reboot), and
`module.voffice1.libvirt_volume.seed` is a FORCED REPLACEMENT
(`create.content.url`) that would bounce the running Office1 headend; plus 2
in-place domain updates. This is the defect that STOPPED the DC0 apply
(`43b29d7`).
**Proposed fix:** D-130 mechanism ruling in Phase 5, informed by the two
charter-exempted verifications (v0.9.8 volume-replace-under-running-domain;
`ignore_changes` suppression). Operator lean (a) `lifecycle { ignore_changes }`
is CONTINGENT on the suppression verification; if refuted, fall back to (b).
**Authoring direction (operator, 2026-07-18):** the true EXPECTED plan count
is currently nobody's -- 5/0/6 was pre-reboot, 7/2/7 is the post-reboot
symptom of the D-130 defect, and the post-fix expected triple does not exist
until D-130 is ruled. CURRENT-STATE.md must record exactly that (expected:
UNRESOLVED pending D-130; last captured: 7/2/7; pre-reboot gate: 5/0/6), not
pick a number.
**Traces to:** GA-R6 (executable definition of done), D-130.

## GA-F02 -- HIGH -- deploy-gate doc carries two live contradictory plan counts

**Evidence:** `docs/dc0-deploy-readiness.md:37` (`5 add / 2 in-place / 6
destroy`) vs `:59` (`5/0/6`) vs `:48`/`:167` (`5-add/(0-or-2)-change/
6-destroy-empty`). Mechanically caught: record-inventory contradiction group
`plan` (10 distinct triples repo-wide). All three forms are presented as the
current gate in the same document.
**Proposed fix:** GA-R1 -- the gate count lives ONLY in CURRENT-STATE.md,
cited to the captured plan file; the readiness doc demotes to checklist.
**Traces to:** GA-R1, GA-R6.

## GA-F03 -- MED -- tofu version pin stale: records say 1.12.3, binary is 1.12.4

**Evidence:** measured `tofu version` -> v1.12.4 (env snapshot). Stale 1.12.3
claims: `opentofu/README.md:41` (CORRECTED 2026-07-18 -- the charter and this
register's first draft said root README; root README.md carries no pin, and
`opentofu/README.md` is outside the extractor's scan scope, a noted scope
gap), `docs/dc-dc-deployment-workflow.md:47`, `:360`, `:875`
(record-inventory `version tofu` group; `docs/session-ledger.md:214` already
records the 1.12.4 observation).
**Proposed fix:** GA-R1 pin table in CURRENT-STATE.md cited to `--version`
output; README drops its own pin.
**Traces to:** GA-R1.

## GA-F04 -- MED -- operating skill pins OPNsense 26.1; live edge is 26.7

**Evidence:** live: `docs/vr1-office1-as-built.md:42` (OPNsense 26.7, updated
2026-07-18, D-129 review). Stale skill surfaces:
`references/platform-traps.md:22`, `:322`, `:351`;
`references/environment.md:35` (all 26.1). Skill divergence-rule case: facts
in the skill go stale fast; repo wins.
**Proposed fix:** Phase-5 skill sweep updates the version rows (or replaces
them with pointers to `runbooks/appendix-B` / CURRENT-STATE.md).
**Traces to:** GA-R1, Phase-5 skill sweep.

## GA-F05 -- MED -- always-loaded surfaces name the jumphost `vopenstack-jesse`; the host is `vcloud`

**KNOWN-STALE, registered per operator ruling.** Evidence: measured
`hostname` -> `vcloud` (env snapshot); D-128 records the operating model.
Stale: `CLAUDE.md:4`, `.claude/skills/openstack-cloud-ops/SKILL.md:46`, and
memory `multi-workstation-remote-control.md:13`. CLAUDE.md is loaded into
EVERY session -- do not trust it for environment identity until fixed.
**Proposed fix:** Phase-5 hygiene batch corrects all three surfaces.
**Traces to:** GA-R1, GA-R7 (memory), Phase-5 skill sweep.

## GA-F06 -- HIGH -- one-time instruction over-generalized into an always-loaded standing rule (churn mechanism candidate)

**Operator provenance ruling (quoted, 2026-07-18):** "It was not a standing
instruction. It was only supposed to be for a one time / very short sequence
of steps."
**Evidence:** memory `review-after-each-step.md` (mtime 2026-07-16 06:41,
originSessionId `839ad1a8...` -- a session launched from the `opentofu/`
subdirectory, per the sibling project dir; that dir holds NO memory). The
frontmatter generalizes to "on multi-step work ... after EVERY step", and
mandates a per-step drift sweep ("reconcile code vs the decision record vs
the docs/ledger") plus "Fix what the review finds THEN proceed" -- i.e. it
structurally mandates inline reconciliation fixes after every step.
**Timeline correlation (measured from git):** the 06:41 stamp falls inside the
Stage-3 review sweep (between commits 114d392 05:53 and 5175365 07:31 on
07-16 -- exactly when a one-time per-step review WAS in effect). From 15:47
the same day the commit stream turns to reconciliation (8496c2e, 87f9d75,
788911c, 4d490cf -- four consecutive reconcile/drift subjects), and
reconciliation/record work dominates 07-17 (ledger re-seeds, markers) and
07-18 (findings, STOP). Assessment: CONSISTENT with this memory being a
primary mechanism of the 07-16..07-18 churn -- every subsequent session
loaded a rule requiring a records-reconciliation pass (with inline fixes)
after every step, which is the charter's "every fix to one copy creates
drift in another" loop made policy. It is not the SOLE mechanism (the
multi-surface hand-copied status problem predates it; 31 changelogs were
filed 2026-07-09), but it made the loop mandatory.
**Handling this session:** NOT followed (operator directive).
**Proposed fix:** Phase-5 memory hygiene -- remove or rewrite the file as a
narrowly-scoped observation; GA-R7 governs future memory writes.
**Traces to:** GA-R7, GA-R5.

## GA-F07 -- HIGH -- memory records an operator "ruling" that was never ruled (security posture)

**Operator provenance ruling (2026-07-18):** the recorded stance ("prioritize
deployment tooling/runbooks over real-world security") was NEVER ruled; it
emerged from the operator repeatedly de-escalating security spirals; the
operator did not know the stance had been adopted.
**Evidence:** memory `project-posture-closed-test.md:12` asserts "(operator
ruling, 2026-07-15)"; `MEMORY.md:4` propagates it as a standing prioritization.
**Directive now in force:** security posture returns to NEUTRAL -- industry
best practice with sourced debate. The underlying fact (VR1 is a closed
rehearsal environment) is already carried by the repo and needs no memory
entry. SEC-gated invariants (e.g. SEC-010's pre-apply pin) were never
deferred and remain gates.
**Proposed fix:** Phase-5 memory hygiene -- remove the file (or reduce to the
repo-carried fact with no priority claim); GA-R7 makes any memory entry
claiming operator intent PROPOSED until confirmed.
**Traces to:** GA-R7, GA-R5.

## GA-F08 -- MED -- MEMORY.md index propagates both defective entries into every session

**Evidence:** `MEMORY.md:4` (posture) and `:6` (review-after-each-step, stated
as "operator wants ... after EVERY step"). The index is the highest-blast-
radius record surface: loaded automatically at session start whenever
auto-memory is enabled.
**Proposed fix:** Phase-5 memory hygiene alongside GA-F06/GA-F07.
**Traces to:** GA-R7.

## GA-F09 -- MED -- docs/ working set: 141 files (incl. 6 new audit outputs), 95 changelogs, all densely self-referential

**Evidence:** record-inventory census (95 changelog-class files confirmed
mechanically; 31 filed 2026-07-09 per charter). Notably the "unreferenced
changelog" consolidation heuristic returns ZERO -- every changelog is cited by
at least one other record surface (ledger/changelogs cite changelogs), so
reference-counting cannot prune this set; only the GA-R2 class rule
(changelogs are session-scoped scratch, consolidated at stage close, never
citable as status authority) can.
**Proposed fix:** GA-R2 per-stage consolidation; target < 25 files in docs/.
**Traces to:** GA-R2.

## GA-F10 -- MED -- stage-status vocabulary is inconsistent across surfaces (5 mechanical groups)

**Evidence:** record-inventory `status` groups: stage-1 CLOSED/COMPLETE,
stage-2 CLOSED/COMPLETE, stage-3 BLOCKED/HELD, stage-4 CLOSED/HELD, stage-5
BLOCKED/CLOSED. Some rows are historical prose, but the vocabulary itself is
unpinned -- there is no single legal status set, so mechanical checking of
stage state is impossible today.
**Proposed fix:** GA-R1 (stage status lives only in CURRENT-STATE.md) + a
fixed status vocabulary; GA-R6 makes CLOSED executable.
**Phase-4 note (operator, 2026-07-18):** the legal status set is an explicit
operator A/B ruling to be presented in Phase 4 -- load-bearing because GA-R6
mechanizes CLOSED, and a word with five meanings cannot be mechanized.
**Traces to:** GA-R1, GA-R6.

## GA-F11 -- MED -- version-pin contradiction groups for juju/lxd/maas/netbox (adjudication needed)

**Evidence:** record-inventory `version` groups. Measured ground truth this
session: MAAS 3.7.2, LXD 5.21.5 (voffice1, snap list); OpenTofu 1.12.4. Most
non-matching rows are historical or refer to different components (providers,
pylxd, VR0); a minority are live-surface stale pins. The pin table in
CURRENT-STATE.md (Phase 2) adjudicates each product against captured
`--version` output.
**Traces to:** GA-R1.

## GA-F12 -- MED -- reference rot at scale (raw mechanical counts, false-positive rate unadjudicated)

**Evidence:** record-inventory: 319 broken path references, 170 orphan/
unregistered number references, 115 commit hashes not in this repo, 0 bad
file:line refs. The raw counts include placeholder-style mentions and
references to legitimately-retired files from historical changelogs; the
signal is that nothing currently distinguishes a live citation from a dead
one. Phase-2/5 adjudicate the live-surface subset (non-changelog classes
first).
**Traces to:** GA-R1, GA-R2.

## GA-F13 -- LOW -- session ledger at 1142 lines with no rotation rule

**Evidence:** `wc -l docs/session-ledger.md` -> 1142 (charter measured 1125
two commits earlier; still growing). Fence integrity itself is OK
(`ledger-scan.sh --fences`: 0 errors).
**Proposed fix:** GA-R4 rotation (bounded close-out summary + docs/archive/).
**Traces to:** GA-R4.

## GA-F14 -- MED -- changelog asserted a plan outcome that reality falsified (changelogs-as-status-authority defect)

**Evidence:** `docs/changelog-20260717-d127-iac-autostart-and-guest-updates.md:32`
("5 add / 2 in-place / 6 destroy; the 2 in-place collapse to 0 once the
bookend sets those two autostart") -- the bookend HAS run, autostart IS enable
on both guests (measured), yet the live plan is 7/2/7 with 2 in-place changes
still present and a forced replacement the changelog did not anticipate. The
claim was plausible when written and is false now; nothing marks it stale.
This is the proof-case for GA-R2's "changelogs are NEVER citable as status
authority".
**Traces to:** GA-R2, GA-R1, GA-F01.

## GA-F15 -- MED -- ledger-scan mention-derived counters are inflatable by quoting them (demonstrated twice, by the audit itself)

**Evidence:** `scripts/ledger-scan.sh:121-129` derives DOCFIX/BUNDLEFIX
next-free from the highest TOKEN MENTION in docs/ + runbooks/, excluding
lines containing "next-free" (:124). A quoted next-free value whose token
wraps onto the next line defeats the exclusion and permanently raises the
counter. Demonstrated 2026-07-18 by the audit's own outputs: the Phase-1 env
snapshot (first draft of line 59-60) raised the BUNDLEFIX counter by one, and
CURRENT-STATE.md's first draft of its section 9 raised the DOCFIX counter by
one -- inside the sentence asserting DOCFIX was unaffected. Both surfaces
were reworded token-free the same day; re-run confirms true values D=130,
DOCFIX=197, BUNDLEFIX=052. The script's own CAUTION comment (:112-120)
documents the failure class (DOCFIX-173's changelog once pushed a counter to
1005). The D counter is header-authoritative and immune.
**Proposed fix (Phase 5):** harden the scanner -- e.g. count only assignment
sites (headers / register rows), or apply the exclusion over a joined
paragraph rather than per-line; plus a standing rule: next-free values are
quoted token-free everywhere.
**Traces to:** GA-R1 (derived numbers must come from one authority), GA-R6.

## GA-F14 addendum (Phase-2 sharpening)

CURRENT-STATE.md section 2.3-ii, backed by
`docs/finding-20260718-voffice1-cloudinit-seed-replace.md:140-184`: live
autostart is `enable` on both guests but the attribute is ABSENT from tofu
state (provider v0.9.8 never reads it back), so the changelog's "2 in-place
collapse to 0 post-bookend" claim was STRUCTURALLY impossible -- the diff is
driven by state, not live, and an autostart-only apply bounces the guest.
The false claim was not just stale; it was unverifiable at write time.

---

## Phase-1 disposition notes

- R3-F09 (D-115 ledger-scan false positive): RESOLVED -- fix landed 2026-07-16
  (`docs/changelog-20260716-review-sweep-phaseAB.md:32`); today's `ledger-scan`
  run confirms D-115 is not flagged. No finding.
- Ledger fences: VALID (1 fence, 0 errors). No finding.
- The 2026-07-18 issue list (D-130 candidates, platform-traps items,
  doc-integrity items, env reconcile) remains EVIDENCE to be folded in and
  re-verified during Phase 5 per the charter; items already covered above:
  seed-volume diff (GA-F01), tofu pin (GA-F03), OPNsense 26.1 refs (GA-F04).
