From Gitea issue #97. Authored by the PM agent's worker; the merge gate is the approver. Refs #97. Agent: pm-agent (issue #97, mode implement)
44 KiB
date, branch, title
| date | branch | title |
|---|---|---|
| 2026-10-31 | docs/source-comment-audit | Audit — historical narrative in source comments (read-only inventory, sample not exhaustive) |
What changed
Nothing but this file. This is the read-only audit asked for in issue #97. No source file was edited; the pruning is to be briefed afterwards, per directory, from this list.
What was asked, and the calibration applied
From the reporter (issue #97, 2026-10-31T16:42:30Z): "'historical' talks about previous issues or intent that have changed and why/how it is used today within comments of source files rather than keeping them in the decisions and documentation. Source file comments should only talk about the current files and sections of code/yaml purposes, uses, expectations."
Each row below is classified:
historical— narrative about a superseded state, a past incident, a corrected earlier belief, or a closed issue. Says nothing about what the line does today.load-bearing— phrased as history, but the sentence is the only record of a current non-obvious constraint. Per the brief these get rewrite, never delete.ambiguous— I could not rule without the operator. Left for a human, deliberately not resolved here.
THIS IS A SAMPLE, NOT AN EXHAUSTIVE INVENTORY
The brief caps the audit at roughly 40–50 findings and asks for honesty over padding. Measured candidate volume, tree-wide, with the keyword sweep below:
git ls-files -z | xargs -0 grep -nEi '#.*(used to|previously|formerly|no longer|we had|
before we|historically|in the past|originally|superseded|turned out|was wrong|predates|
legacy|issue #[0-9]+|PR #[0-9]+|measured 20|as of 20[0-9][0-9]-|see decisions/|DECISIONS-LOG)'
| Directory | candidate hits | files | coverage here | findings listed |
|---|---|---|---|---|
platform/ |
107 | 56 | sampled | 9 |
infra/ |
75 | 44 | sampled | 8 |
conformance/ (excl. runs/) |
72 | ~31 | sampled | 5 |
clusters/ |
43 | 19 | sampled | 7 |
ci/ |
42 | 15 | sampled | 6 |
catalog/ |
39 | 9 | sampled | 7 |
.gitea/ |
10 | 5 | full | 5 |
bootstrap/ |
4 | 3 | full | 3 |
platform-config/ |
3 | 1 | full | 3 |
apps/vms/ (hand-authored) |
3 | 2 | full | 2 |
apps/wave-* (generated) |
15 | — | excluded — see below | 0 |
conformance/runs/ (archived logs) |
8 | 18 files | excluded — see below | 0 |
runbooks/ |
11 | — | not audited (prose docs, not source comments) | 0 |
| total | ~420 | ~190 | — | 55 |
Covered fully: .gitea/, bootstrap/, platform-config/, apps/vms/.
Covered by sample only: platform/, infra/, conformance/, clusters/, ci/,
catalog/. Roughly 365 candidate hits remain unexamined, and candidate ≠ finding —
the keyword sweep's precision on the parts I did read was well under half, so the true
residual is smaller than 365 but is certainly in the low hundreds.
The issue's premise holds, with one qualification the operator should price in: of the
55 rows below, 22 are load-bearing and get a rewrite rather than a deletion. The
narrative is genuinely excessive, but a mechanical "delete the history" sweep would destroy
real constraints. That ratio is the single most important number in this report.
Two structural warnings that change how the follow-up PRs must be written
1. apps/wave-0/, apps/wave-1/, apps/wave-2/ are GENERATED. Do not edit comments there.
They are goldens produced by one canonical invocation of catalog/render.py
(ci/render-golden.sh:21), and ci/render-golden.sh:136-150 byte-compares every rendered
file against its committed golden — any diff is a hard exit 1 that blocks the merge.
So the 15 candidate hits under apps/wave-* are copies of comments whose source is
catalog/*.yaml or catalog/render.py; e.g. apps/wave-0/gitea.yaml:130 is the rendered
form of catalog/gitea.yaml:100. Edit the catalog source, then re-render with the canonical
command and commit both. A pruning PR that hand-edits apps/wave-* will sit red.
2. conformance/runs/*/run.log are archived evidence artifacts, not source. 8 candidate
hits sit in 18 committed run logs. They are the recorded output of past conformance runs —
the comments inside them are copies of the test bodies as they stood at run time. Rewriting
them would falsify evidence. Excluded from scope entirely; recommend the operator confirm.
A dangling pointer, replicated across 18 files — fix this before any "replace with a pointer" work
18 files cite DECISIONS-LOG: "Headlamp gating stall" as their rationale pointer, and no
such entry exists. grep -ci "gating stall" DECISIONS-LOG.md → 0; the phrase appears
nowhere in decisions/ either. Citers:
clusters/base/crafty.yaml clusters/base/headlamp.yaml
clusters/base/homepage.yaml clusters/base/kustomization.yaml
clusters/base/runbooks.yaml clusters/base/vpn-ingress.yaml
platform-config/kustomization.yaml platform/crafty/deployment.yaml
platform/crafty/kustomization.yaml platform/headlamp/kustomization.yaml
platform/homepage/kustomization.yaml platform/homepage/README.md
runbooks/kustomization.yaml runbooks/flux-reconcile.md
conformance/tests/l0-static/alert-runbooks-resolvable/check.sh (+3 more)
This is the audit's clearest warning about its own remedy: "replace the narrative with a
pointer" is only an improvement if the target exists and keeps existing. The archive is
frozen and has no index, so a title-based citation into it cannot be checked by anything.
Recommendation: when the operator takes the pruning PRs, either write a real
decisions/ entry for the leaf-gating lesson and repoint all 18 citations at its filename,
or drop the citation. Pointer targets of the form decisions/<file>.md are checkable;
DECISIONS-LOG: "<title>" is not. Nothing below recommends a pointer target I did not
confirm exists.
platform/ — 107 candidates, 9 listed (sampled). NOT sensitive, except platform/kyverno/**
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 1 | platform/crafty/service-l4.yaml:33-91 |
"CORRECTED 2026-09-14 after an 8-DAY LAN OUTAGE … This file used to say Local" — 58 lines of outage narrative |
load-bearing | rewrite. Keep the current constraints (Cilium's L2 announcer is not backend-aware; SNAT mode loses client IP; /ban-ip degrades so use /ban; remote-node is subsumed by cluster so do NOT add it; no loadBalancerSourceRanges deliberately). Drop the outage story, the lease-age detail and the per-protocol tell |
no |
| 2 | platform/longhorn/helmrelease.yaml:191-200 |
"orphanAutoDeletion: true USED TO BE HERE AND WAS INERT. Removed 2026-09-13" |
load-bearing | rewrite to the forward-looking rule: Longhorn ≥1.9 replaced it with orphanResourceAutoDeletion and the chart silently drops unknown defaultSettings keys — so do not set it |
no |
| 3 | platform/longhorn/helmrelease.yaml:249-254 |
"CORRECTION, re-measured 2026-09-13 later the same day: the line originally recorded here read …" — corrects a superseded measurement | historical | delete. The correct reading is already stated at :246-248 |
no |
| 4 | platform/monitoring/alerts.yaml:625-636 |
"Both rules below used to read == 2 / == 3, with the comment 0=unknown 1=healthy…" |
load-bearing | rewrite. Keep "longhorn_volume_robustness is a one-hot state-labelled gauge, value 0 or 1" — that is why the expressions look as they do. Drop the old-enum story |
no |
| 5 | platform/monitoring/alerts.yaml:869-875 |
"This alert originally used severity: info. That was WRONG, and wrong in the silent direction" |
load-bearing | rewrite to the current rule: carries no severity deliberately, because general.rules' InfoInhibitor would swallow an info-severity deploy notification |
no |
| 6 | platform/monitoring/pvc-capacity-alerts.yaml:12-27 |
"LonghornVolumeCapacityHigh … never did, for two different reasons in sequence, and it is now GONE" — dated 2026-09-06/2026-09-13 timeline |
load-bearing | rewrite. Keep only "these rules key on kubelet_volume_stats_* because longhorn_volume_actual_size_bytes measures allocation, not filesystem use". Delete the sequence |
no |
| 7 | platform/headlamp/helmrelease.yaml:77-85 |
"These two used to be keys INSIDE headlamp-oidc-credentials.sops.yaml. That was the bug…" + the dev-Keycloak i/o timeout story |
load-bearing | rewrite to the current rule: issuer and callback URLs are public and MUST be cleartext, because Flux's ${BASE_DOMAIN} postBuild substitution cannot reach inside an encrypted Secret. Keep the [parity] note at :87-92 as-is |
no |
| 8 | platform/vpn-egress/egress-steering.yaml:79 |
"CORRECTION 2026-09-12 — this comment used to say the host nftables kill-switch 'is the…'" | load-bearing | rewrite to state the actual mechanism (Cilium's eBPF egress-gateway drop) without the correction framing | no |
| 9 | platform/keycloak/passkey-reconciler.yaml:18 |
"It used to be duplicated here almost verbatim" | historical | delete, or replace with pointer decisions/2026-10-18-keycloak-passkey-reconciler.md (confirmed present) |
no |
Also seen in platform/ and left unlisted for the cap, same shapes: platform/cilium/helmrelease.yaml:57-65
(load-bearing — the k3s_api_host/k3s_apiserver_endpoint split is the current parity contract),
platform/kubevirt/kubevirt-cr.yaml:7 (useEmulation was previously true), platform/external-snapshotter/kustomization.yaml:35
(Previously these were REMOTE), platform/kustomization.yaml:7 (the same pattern by which kyverno was previously deferred),
platform/pm-agent/configmap.yaml:22, platform/monitoring/tests/run.sh:61 and :129,
platform/cnpg/alerts.promtool-test.yaml:20, platform/oauth2-proxy/auth-visibility-alerts.yaml:36-42
and :98-101, platform/vpn-ingress/daemonset.yaml:165.
infra/ — 75 candidates, 8 listed (sampled). NOT sensitive, except infra/gitea/**
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 10 | infra/plex/claim-ship.sh:29-32 |
"Branch prefix is now cosmetic. It used to matter: gate.yml's push trigger covered feature/** … Those per-branch push triggers were deleted" | historical | delete. The live trigger set is already documented at .gitea/workflows/gate.yml:48-56 and CLAUDE.md §4 |
no |
| 11 | infra/ansible/inventory/hosts.ini:105 |
"GROUP-NAME GAP: CLOSED 2026-08-31. The roles and playbooks used to hardcode the…" | historical | delete — the gap is closed and the current variable is named at playbooks/node-health.yml:12 |
no |
| 12 | infra/ansible/inventory/hosts.ini:147-153 |
"NOTE (CORRECTED 2026-09-12): this used to read 'node 3 also has wlp1s0 up on 192.168.2.195 (wifi)'. It does not" | load-bearing | rewrite as a positive present-tense assertion: node 3 has no wl* netdev and a single IPv4 uplink on eno1. That fact is load-bearing for the kill-switch datapath; only the correction framing should go |
no |
| 13 | infra/ansible/roles/node_health/defaults/main.yml:110-121 |
"The first real run of this role FAILED k3s-prod-1's Crucial/Micron C400 on reallocated=61440 … That verdict was WRONG" |
load-bearing | rewrite. Keep the current rule (SMART raw values are vendor-defined; Micron TN-FD-20 scales ID 5 by Block_Sector_Count, so ID 170/196 are the trustworthy corroborators). Drop "the first real run failed" |
no |
| 14 | infra/ansible/roles/unattended_upgrades/tasks/main.yml:304-309 |
"This was originally a find over /etc/kernel/postinst.d … That theory was wrong" |
load-bearing | rewrite to the current justification: the sentinel writer is ours at two known paths, and two exact stats are strictly stronger than a glob that would match Debian's own conffile |
no |
| 15 | infra/ansible/roles/node_health/tasks/assess.yml:398 |
"measurement was right; the inference from the log line was wrong — the memattr block below…" | historical | delete | no |
| 16 | infra/devcontainer/dev.sh:103-108 |
"SUPERSEDED but still honoured: DEV_KUBECONFIG used to be the only way to reach a cluster other…" |
load-bearing | rewrite. "Still honoured" is current behaviour and CLAUDE.md §3 tells every agent to set DEV_KUBECONFIG=/dev/null, so this must keep documenting the variable — just not as history |
no |
| 17 | infra/vpn-ingress/new-peer.sh:136 |
"COMMENT LINES ARE NOT ALLOCATIONS. This used to grep the whole file and so matched the…" | load-bearing | rewrite, replacing the history with pointer decisions/2026-10-06-new-peer-ignores-template-comments.md (confirmed present) |
no |
Unlisted, same shapes: infra/ansible/inventory/group_vars/all.yml:31,
infra/ansible/inventory/group_vars/k3s_prod/vars.yml:86 ("CORRECTION 2026-09-06: an earlier
version of this comment claimed…"), infra/ansible/roles/node_baseline/tasks/disks.yml:559,
infra/ansible/roles/node_baseline/tasks/main.yml:801, infra/ansible/roles/kube_vip/tasks/main.yml:68,
infra/ansible/roles/cilium/defaults/main.yml:30, infra/ansible/playbooks/node-health.yml:12,
infra/ansible/roles/vpn_egress_gateway/templates/vpn-egress-up.sh.j2:39 and
vpn-egress-down.sh.j2:15, infra/devcontainer/kubeconfig.sh:26, infra/agent/Containerfile:216,
infra/agent/build-image.sh:30, infra/agent/pm-worker:97, infra/agent/probe-validation.sh:98.
catalog/ — 39 candidates, 7 listed (sampled). NOT sensitive — but every edit here re-renders apps/wave-*
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 18 | catalog/qbittorrent.yaml:7-12 |
"BULK DOWNLOADS TIER — DELIVERED 2026-09-12 (the deferral below is CLOSED; kept for the record). This entry used to ship config-only, with a comment promising … 'once OQ-2 is resolved'" | historical | delete. Self-describes as "kept for the record", which is precisely the issue's complaint | no |
| 19 | catalog/qbittorrent.yaml:141-151 |
"It USED to be a doubled-dollar default-operator expansion of a WEBUI_PORT env var … That MISDIAGNOSIS is preserved in this service's own marker log at 2026-09-13T05:35Z" | load-bearing | rewrite. Keep "PORT is a literal matching ingressRoutes[0].port; a literal cannot be mangled by envsubst". Drop the misdiagnosis story (it is already preserved in the marker log the comment itself cites) |
no |
| 20 | catalog/plex.yaml:43-46 |
"(This comment previously asserted '~4 minutes' as established fact. It was … Measured 2026-09-29: the full loop is ~2m45s and fits.)" | historical | rewrite to the measured figure alone; delete the self-correction parenthesis | no |
| 21 | catalog/plex.yaml:65 |
"So the earlier 'a placeholder claim Secret would crashloop the pod' note was WRONG about the…" | historical | delete | no |
| 22 | catalog/plex.yaml:318 |
"actually granted access (device-cgroup EPERM, measured 2026-10-01), so there was nothing to keep" | historical | rewrite with pointer decisions/2026-10-01-quicksync-via-device-plugin.md and/or decisions/2026-10-03-cilium-cgroup-hostroot.md (both confirmed present) |
no |
| 23 | catalog/gitea.yaml:14 |
"Headless-install bootstrap (formerly apps/gitea-bootstrap-patch.yaml; now first-class via the…)" |
historical | delete the "formerly" clause; keep the description of what the block does | no |
| 24 | catalog/render.py:159-166 |
"THE SCRAPE WORKS AS OF 2026-10-05 — but it took THREE independent pieces … (PR #28) … (PR #49)" | load-bearing | rewrite. The three-part requirement and "do not read this flag alone as 'metrics are working'" are current and genuinely non-obvious; drop the PR numbers and the "63.7h" incident, pointing at decisions/2026-10-05-oauth2-sidecar-scrape-verified.md (confirmed present) |
no |
catalog/pihole.yaml:210 and :218 are the exemplar to copy: narrative already reduced to
see decisions/2026-10-04-pihole-multi-replica.md / -pihole-declare-state.md, both of which
exist. Unlisted: catalog/gitea.yaml:100-130, catalog/nextcloud.yaml:211 and :226-240,
catalog/semaphore.yaml:84, catalog/pihole.yaml:179, catalog/qbittorrent.yaml:389-417,
catalog/sonarr.yaml:120, catalog/render.py:672, :1371, :2161.
catalog/jackett.yaml:73 ("floor only, no ceiling; 0.24.x runs as of 2026-10-30") is
load-bearing, leave alone — a dated version constraint, exactly the carve-out the brief names.
.gitea/ — 10 candidates, 5 listed (FULL coverage). SENSITIVE (.gitea/**)
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 25 | .gitea/workflows/gate.yml:14-16 |
"(it used to print '— not green' and then 'MERGE GATE: PASS', exit 0 — fail-open in the gate itself)" | historical | delete the parenthesis; the surrounding GATE_STRICT_SKIPS rationale is current and stays |
yes |
| 26 | .gitea/workflows/gate.yml:48-56 |
"There is NO per-branch push trigger. There used to be a prefix list (feature/** fix/** …) and it was a net negative here" + the 2026-09-29 plex-claim cost | load-bearing | rewrite. "Do not re-add a push trigger; act_runner is capacity 1 and the duplicate run serialises ahead of the PR run" is a live constraint a future editor needs. Drop the plex-claim anecdote |
yes |
| 27 | .gitea/workflows/gate.yml:118-123 |
"WIDENED TOLERANCE, DECLARED: || [ "$?" -eq 3 ] used to cover exactly one skip (spec-immutability)" |
load-bearing | rewrite. This documents a deliberate current weakening plus its exit condition (REQUIRE_GITEA_SETTINGS=true once the secret is seen green). Keep the instruction, drop "used to" |
yes |
| 28 | .gitea/workflows/renovate.yaml:72-76 |
"CORRECTED 2026-10-30. This list used to name only write:repository + read:user … Run 350 then failed at GET /api/v1/orgs/… 403" |
load-bearing | rewrite to the required scope list as a plain present-tense requirement; point at decisions/2026-10-30-renovate-auth.md (confirmed present) for the run-350 story |
yes |
| 29 | .gitea/workflows/merge-gate.yaml:15 |
"The text that used to sit here…" | historical | delete | yes |
Remaining .gitea/ candidates examined and judged not findings (current-state
measurements, correctly phrased): renovate.yaml:6, :34, :259, images.yaml:44,
scripts/images.sh:11.
ci/ — 42 candidates, 6 listed (sampled). SENSITIVE (ci/**)
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 30 | ci/decisions-log.sh:5-23 |
19-line "WHY THIS STAGE EXISTS" block reproducing the four-PR conflict table verbatim | historical | replace with a pointer. It is a near-verbatim duplicate of decisions/README.md:9-30, which the comment itself already cites at :23. Cut to the assertion list + that pointer (and decisions/2026-09-29-decisions-log-conflict-free.md, confirmed present) |
yes |
| 31 | ci/gitea-settings.sh:7-23 |
"On 2026-09-29 that blind spot was measured … PR #1 … sat pending for 30.6 minutes … PRs #5-#9 merged with zero approvals" |
load-bearing | rewrite. "No other check can see Gitea's own database; assert-scripts do not detect drift from their own target" is the current reason the stage exists. Drop the PR-by-PR history | yes |
| 32 | ci/l0.sh:15-23 |
"That union replaces what used to be a hand-written 'UNCONDITIONAL' stage per whole-repo check (3c subst-safety / 3d keycloak-client-secrets / 3e bulk-tier)" | historical | rewrite to describe the present selection rule only (touched-requirement subset ∪ every test declaring scope: whole-repo) |
yes |
| 33 | ci/lib.sh:138-142 |
"WHY THIS EXISTS: ci/l0.sh used to carry a hand-written stage per whole-repo check, each with its own summary … line" |
historical | rewrite to "names every offline check that ran and its verdict" | yes |
| 34 | ci/approval-policy.sh:107-112 |
"Blocking on that turned 'CI cannot read your override' into a message that said 'you did not post one', and cost a real debugging session on PR #38" | load-bearing | rewrite. The token-scope fact and the fail-direction guarantee ("an unreadable source can only cause a false BLOCK, never a false pass") are current; the debugging-session cost is not | yes |
| 35 | ci/touched-requirements.sh:288-293 |
"R-TEST-06 added 2026-09-12. The comment in changed_diff()'s rule 3 above records why it was ABSENT: R-TEST-06 used to be enforced by the spec-immutability STAGE" |
load-bearing | rewrite. Keep why a ci/ change must attribute R-TEST-06 today; drop the absence history |
yes |
Unlisted: ci/approval-policy.sh:30-38 and :182, ci/conformance.sh:73, ci/gate.sh:133,
:233-234, ci/l0.sh:86, ci/l1.sh:33, ci/lib.sh:65, ci/render-golden.sh:5-6 and :24,
ci/touched-requirements.sh:39, :316, plus ci/tests/*.test.sh (5 files — note these are
test rationale headers, where a "this used to fail on main" line arguably earns its keep;
I would send the whole ci/tests/ group to ambiguous).
clusters/ — 43 candidates, 7 listed (sampled). SENSITIVE (clusters/**)
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 36 | clusters/base/cluster-vars.yaml:244-251 |
"IT IS NO LONGER A CROSS-NETWORK KNOB (2026-10-07). This used to read 'the two clusters are on OPPOSITE SIDES of pfSense'…" | load-bearing | rewrite. Keep "exactly one storage host, 192.168.2.30; still a knob only because the renderer reads it per-environment" and the immutability warning at :253+. Replace the pfSense/DNAT history with pointer decisions/2026-10-07-bulk-nfs-truenas.md (confirmed present) |
yes |
| 37 | clusters/prod/kustomization.yaml:335-351 |
"APEX AS OF 2026-09-13 … Prerequisites completed and VERIFIED before this flip, in this order: 1. dev's 18 A records released … 2. dev's 18 LEGACY UNPREFIXED TXT registry entries deleted by hand … 3. dev's Certificate deleted" | historical | rewrite. The three completed prerequisites are done and unrepeatable. Keep only the still-true NOTE at :348-351 (the zone's two wildcards point at the legacy stack's public IP and prod's specific records shadow them) |
yes |
| 38 | clusters/prod/kustomization.yaml:472-479 |
"*** DECIDED 2026-09-06 by the operator: the VIP, as intended. *** (This block previously read 'Not yet decided' while shipping .10 …)" | load-bearing | rewrite. Keep "this is the control-plane VIP, NOT .20 the ingress VIP and NOT .10 the single node address" and why a node-pinned CNI endpoint fails silently. Drop the previous-wording parenthesis | yes |
| 39 | clusters/base/apps-vms.yaml:51-55 |
"postBuild.substituteFrom ENABLED 2026-08-31 (R-ENV-02). It was previously omitted because Flux's envsubst runs over the ENTIRE manifest…" | load-bearing | rewrite. The envsubst hazard over VM cloud-init and the $${...} escape obligation are live constraints for anyone adding a VM manifest; the enablement date and prior omission are not |
yes |
| 40 | clusters/dev/kustomization.yaml:282-287 |
"THIS VALUE IS INERT — dev is decommissioned, its nodes no longer exist, and the Proxmox host this used to name (192.168.1.9) went with the pools it held" | load-bearing | keep, trim. "Inert, restated per this overlay's supply-every-knob convention, unproven because there is no dev node" is honest current state and the kind of comment the issue wants | yes |
| 41 | clusters/base/apps-wave-0.yaml:4, apps-wave-1.yaml:4, apps-wave-2.yaml:4 |
"wait:true health-gates ONLY this wave's resources, so a later wave can no longer stall an earlier one" (×3, and the same sentence is emitted by catalog/render.py:2385) |
load-bearing | rewrite the "no longer" to plain present tense. Note the renderer emits this string, so fix render.py:2385 and re-render rather than editing the three files by hand |
yes |
| 42 | clusters/base/headlamp.yaml:9-12, homepage.yaml:10, crafty.yaml:11, kustomization.yaml:53, runbooks.yaml:15, vpn-ingress.yaml:9 |
six files citing DECISIONS-LOG: "Headlamp gating stall" — target does not exist (see above) |
historical | rewrite to the present-tense rule (a leaf UI belongs in its own post-platform-config Kustomization so its crashloop cannot stall the chain) and drop or repoint the dead citation |
yes |
Unlisted: clusters/base/cilium.yaml:52, cluster-vars.yaml:29, :51, :264,
platform.yaml:17, :56, platform-config.yaml:6, platform-config-cdi.yaml:13,
oauth2-proxy.yaml:10, clusters/dev/kustomization.yaml:67, :81, :222,
clusters/dev/sync.yaml:8, clusters/prod/kustomization.yaml:277-283, :317, :363, :546, :554.
conformance/ — 72 candidates (excl. runs/), 5 listed (sampled). SENSITIVE (conformance/**)
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 43 | conformance/tests/l3-fault-injection/vpn-killswitch/chainsaw-test.yaml:16-24 |
"MECHANISM CORRECTED 2026-09-12: this comment used to credit 'the host nftables kill-switch' … The ASSERTION below is unchanged and still the right one — only the explanation was wrong" | load-bearing | rewrite to state the real mechanism (Cilium's eBPF egress-gateway drop, netfilter never invoked) in the present tense. Pairs with finding #8 — same correction duplicated in platform/vpn-egress/ |
yes |
| 44 | conformance/tests/l3-fault-injection/vm-data-survival/chainsaw-test.yaml:18-27 |
"(Feature-gate note, revalidated 2026-08: an earlier revision of this comment also claimed the containerDisk BOOT path was broken … That premise is now STALE: the cluster is k3s v1.36.4, where ImageVolume is ENABLED)" | historical | rewrite to the one current sentence that matters — DataVolume is used because only it survives a rebuild — and drop the whole stale-premise parenthesis | yes |
| 45 | conformance/tests/l0-static/ha-control-plane-as-code/chainsaw-test.yaml:51-60 |
"TWO GAPS CLOSED 2026-09-06 (they used to be listed above; recorded so the change is legible)" | historical | rewrite. Both gaps are closed and now asserted; state the assertions, drop the gap history. Same in check.sh:98 and :500 ("This section used to be an ESCALATION in the header's gap list") |
yes |
| 46 | conformance/lib/status.py:303-310 |
"It used to be, and that mis-reported a SAFETY-CRITICAL requirement … A previous engineer worked around it by rewording prose" | load-bearing | rewrite. "Scaffold detection must name the idioms it hunts for, because a placeholder-detection test legitimately contains the words" is the current design constraint; the R-STATE-03 misreport and the previous engineer are not | yes |
| 47 | conformance/tests/l0-static/bulk-tier-distinct-from-replicated/check.sh:447-455 |
"It used to assert … in L0: ci/l0.sh carried a hand-written 'UNCONDITIONAL' stage per whole-repo check" — the same paragraph is duplicated verbatim in 3 files (also flux-postbuild-substitution/check.sh:604, keycloak-client-secret-reconciler/check.sh:678) |
historical | rewrite all three to the present mechanism (the test declares scope: whole-repo; ci/l0.sh unions declaring tests via --include-scope; both halves checked). Good candidate for one small PR — identical edit ×3 |
yes |
Unlisted: conformance/incluster/chainsaw-job.yaml:44, conformance/incluster/rbac.yaml:105
(also sensitive as **/rbac.yaml — "superseded design" for the gluetun Deployment;
load-bearing, since it explains why the fault Job needs no RBAC), conformance/lib/common.sh:33,
conformance/lib/status.py:114, and ~10 further tests/l0-static/*/check.sh headers of the
same shape (alert-metrics-have-scrape-targets, alert-rules-unit-tested,
alert-runbooks-resolvable, auditability-proofs-producible, keycloak-passkey-reconciler).
bootstrap/ — 4 candidates, 3 listed (FULL coverage). SENSITIVE (bootstrap/**)
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 48 | bootstrap/flux/components/kustomization.yaml:36-38 |
"On 2026-09-01 that shipped k8sServiceHost: "" into the Cilium HelmRelease and put 2 of 3 agents into Init:Error (DECISIONS-LOG, INCIDENT entry)" |
load-bearing | rewrite. The fail-open default and what the feature gate changes are the current justification; the incident is one clause. Pointer is vague ("INCIDENT entry") — grep finds 2026-09-01 material in the archive, so if a citation is kept it should name a locatable heading, not "INCIDENT entry" |
yes |
| 49 | bootstrap/flux/bootstrap.sh:84-86 |
"see ./components/kustomization.yaml and the 2026-09-01 INCIDENT entry in DECISIONS-LOG.md" | historical | rewrite to keep only the cross-reference to ./components/kustomization.yaml, which is checkable; drop the archive citation (duplicate of #48) |
yes |
| 50 | bootstrap/sops/secret-templates/pia-custom-ovpn.yaml.example:6 |
See DECISIONS-LOG "Phase 3 VPN — custom .ovpn" |
ambiguous | operator call. The target does exist (10 hits for "Phase 3 VPN" in the archive), so this is a working pointer of the discouraged form. Keep, or repoint if a decisions/ entry is written. Cited by path+line only; no content quoted (secret-adjacent .example template) |
no (*.sops.yaml.example is not matched by **/*.sops.yaml) |
Remaining candidate bootstrap/flux/bootstrap.sh:122 ("a patch target that no longer exists
after a Flux…") examined — not a finding, it describes current failure behaviour.
platform-config/ — 3 candidates, 3 listed (FULL coverage). SENSITIVE (platform-config/kustomization.yaml)
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 51 | platform-config/kustomization.yaml:8 |
"See clusters/base/platform-config.yaml + DECISIONS-LOG." |
historical | rewrite to keep the checkable half (clusters/base/platform-config.yaml) and drop the bare, untargeted DECISIONS-LOG reference — it names no entry and cannot be resolved |
yes |
| 52 | platform-config/kustomization.yaml:93 |
"Invisible on dev, whose CDI CRDs have existed for months. See DECISIONS-LOG 2026-09-05." | load-bearing | rewrite. "THE RULE" at :95-96 is the keeper; the dev-invisibility observation is stale (dev is decommissioned — see finding #40) and should go |
yes |
| 53 | platform-config/kustomization.yaml:167 |
"headlamp: httproute MOVED OUT … Keeping it here … meant a headlamp crashloop stalled platform-config. See DECISIONS-LOG 'Headlamp gating stall'." | historical | rewrite to the present-tense statement of where the HTTPRoute lives now; dead pointer, see the dangling-pointer section | yes |
apps/vms/ — 3 candidates, 2 listed (FULL coverage). Hand-authored, NOT generated
| # | path:lines | comment (gist) | class | action | sensitive |
|---|---|---|---|---|---|
| 54 | apps/vms/unifi/50-service-l4.yaml:27-78 |
"CORRECTED 2026-09-14 after an 8-DAY LAN OUTAGE … This file used to say Local … BOTH HALVES OF THAT WERE FALSE" — ~52 lines |
load-bearing | rewrite, same treatment as #1 (its near-twin). Keep: L2 announcer is not backend-aware; KubeVirt masquerade already destroyed the client IP so Cluster costs nothing here; cluster subsumes remote-node so do NOT "fix" the CNP; no loadBalancerSourceRanges deliberately. Drop the outage story |
no |
| 55 | apps/vms/unifi/30-virtualmachine.yaml:119, 40-networkpolicy.yaml:36 |
# legacy Network UI (still served), # legacy UI on port 8443 |
load-bearing | keep. "legacy" here is the upstream product's own name for a port that is still served — it describes current behaviour, not history. Listed so a keyword-driven sweep does not delete it | no |
Per-directory counts (findings listed above)
| Directory | historical | load-bearing | ambiguous | total | sensitive-path? |
|---|---|---|---|---|---|
platform/ |
2 | 7 | 0 | 9 | no (except kyverno/**) |
infra/ |
3 | 5 | 0 | 8 | no (except gitea/**) |
catalog/ |
4 | 3 | 0 | 7 | no |
clusters/ |
2 | 5 | 0 | 7 | yes |
ci/ |
3 | 3 | 0 | 6 | yes |
conformance/ |
3 | 2 | 0 | 5 | yes |
.gitea/ |
2 | 3 | 0 | 5 | yes |
bootstrap/ |
1 | 1 | 1 | 3 | yes (×2) |
platform-config/ |
2 | 1 | 0 | 3 | yes |
apps/vms/ |
0 | 2 | 0 | 2 | no |
| total | 22 | 32 | 1 | 55 | 29 of 55 sensitive |
The ambiguous bucket is thin because I could rule on most rows against the reporter's
calibration. Two groups I am deliberately not ruling on and want the operator's call:
ci/tests/*.test.shheaders (5 files). These say things like "this suite exists becauseci/gate.shused to set BLOCK=1 for a FAILED stage but…" and "a stage was added to gate.sh by PR #17, never added here, so 15 of 50 assertions failed onmain". For a regression test, the regression it guards is arguably the test's subject rather than fluff. Ruling thesehistoricalwould strip the only record of what each assertion is for. Operator to decide.- In-repo
README.mdprose (platform/vpn-egress/README.md:91,platform/crafty/README.md:52,infra/devcontainer/README.md:126,infra/gitea/README.md:253). These are documentation, not source comments, so arguably already in the place the issue wants narrative to live. I did not audit them as findings.
Suggested order for the follow-up PRs — cheapest and least sensitive first
catalog/+ re-renderapps/wave-*(7 findings, not sensitive). Highest value per unit of review: it also fixes the generated copies underapps/wave-*. Must re-runpython3 catalog/render.py --all catalog -o apps --wave-layout --no-image-automation, drop the not-onboarded outputs, and commit the goldens, orrender-goldenfails.platform/excludingkyverno/**(9 findings, not sensitive). Biggest residual too (107 candidates) — worth splitting by component (monitoring/,longhorn/,crafty/,headlamp/,vpn-egress/) into 2–3 PRs rather than one sweep.infra/excludinggitea/**(8 findings, not sensitive).ansible/roles/*is most of it;infra/plex/claim-ship.sh:29-32(#10) is a clean one-paragraph deletion and a good first commit.apps/vms/(2 findings, not sensitive). Self-contained; #54 is the twin of #1, so do it right afterplatform/crafty/service-l4.yamlwhile the reasoning is fresh.- The dangling-pointer fix (18 files, crosses sensitive and non-sensitive). Either
write one
decisions/entry for the leaf-gating lesson and repoint all 18, or drop the citations. Doing this before steps 6–9 means those PRs do not have to re-litigate it. platform-config/kustomization.yaml(3 findings, sensitive). One file, three edits — the smallest possible sensitive-path PR, so it is the cheapest review.bootstrap/(3 findings, sensitive). Two files..gitea/(5 findings, sensitive). Keep #27 (gate.yml:118-123) in its own commit — it documents a live, deliberate tolerance-widening and is the one most likely to be misread as a behaviour change.ci/thenclusters/thenconformance/(6 + 7 + 5, all sensitive, largest residuals). Last, because each needs a non-author approving review or an operator/approve-override, and becauseci/edits touch the thing doing the approving.
A note on review cost: 29 of the 55 findings are on sensitive paths, so roughly half this work cannot merge on a green gate alone. Steps 1–4 (26 findings) are the portion that can. That is the argument for the ordering above.
What I verified
Everything below was run in this container, offline, against the tree at
466f63e on branch docs/source-comment-audit.
- The tree layout, against the brief's believed list.
git ls-files→ 855 tracked files. The brief's list was broadly right but differs in three ways worth recording: (a) there is noscripts/and notools/directory; (b)docs/does exist in this repo (9 files:docs/BULK-NFS-STORAGE.md+docs/plans/*.md) and is not the sibling spec repo'sdocs/— I audited neither, since both are prose, not source comments; (c)platform-config-cdi/exists as a separate top-level directory (1 file, 0 candidate hits). - Candidate volume, per directory, with the keyword sweep quoted verbatim above:
platform/107 hits / 56 files,infra/75 / 44,conformance/80 / 40 (72 excluding the 8 inconformance/runs/),clusters/43 / 19,ci/42 / 15,catalog/39 / 9,apps/18 (15 under the generatedapps/wave-*, 3 under hand-authoredapps/vms/),runbooks/11,.gitea/10 / 5,bootstrap/4 / 3,platform-config/3 / 1,platform-config-cdi/0. Total ≈ 420 candidate hits in ≈190 files. apps/wave-*is generated and byte-enforced. Readci/render-golden.sh: the canonical command is at:21/:120, and the comparison loop at:136-150iterates the rendered output, requiring each golden to exist and to be byte-identical,exit 1on any diff. Confirmed the duplication concretely: the "HARDENED (was a silent first-boot RACE)" paragraph appears at bothcatalog/gitea.yaml:100andapps/wave-0/gitea.yaml:130. Confirmedapps/vms/is not produced by that loop (the renderer emitswave-N/paths only), so it is hand-authored and directly editable.- The dangling pointer.
grep -ci "gating stall" DECISIONS-LOG.md→ 0;grep -ci "Headlamp gating stall" DECISIONS-LOG.md→ 0;grep -ril "gating stall" decisions/→ no output;git grep -il "gating stall"→ 18 files. So 18 files cite a rationale entry that exists in neither the frozen archive nordecisions/. - Every
decisions/...mdpointer I recommend exists. Checked againstls decisions/(71 entries +README.md+ARCHIVE.sha256):2026-10-18-keycloak-passkey-reconciler.md,2026-10-06-new-peer-ignores-template-comments.md,2026-10-01-quicksync-via-device-plugin.md,2026-10-03-cilium-cgroup-hostroot.md,2026-10-05-oauth2-sidecar-scrape-verified.md,2026-10-07-bulk-nfs-truenas.md,2026-10-30-renovate-auth.md,2026-09-29-decisions-log-conflict-free.md,2026-10-04-pihole-multi-replica.md,2026-10-04-pihole-declare-state.md— all present. I recommend no pointer target I did not list inlsoutput. - Archive-citation targets, for the rows where I say a
DECISIONS-LOGpointer does or does not resolve:"Remote Path"5 hits,"Phase 3 VPN"10,"Phase 4 image-automation"1,F-DNS13,F-OPS11,2026-09-016 — all present in the 5,733-line archive."Headlamp gating stall"0, as above. - The sensitive-path column is from the policy data, not the brief. Read
infra/gitea/approval-policy.json:sensitive_paths=ci/**,.gitea/**,conformance/**,clusters/**,bootstrap/**,infra/gitea/**,platform/kyverno/**,platform-config/kustomization.yaml,.sops.yaml,**/*.sops.yaml,**/rbac.yaml,CLAUDE.md. This matches the brief, and adds the root.sops.yamland the explicit**/glob forms. Note**/*.sops.yamldoes not match*.sops.yaml.example, which is why findings #50 and theplatform/headlamp/...sops.yaml.examplerow are marked not sensitive. - Every cited
path:line-rangewas opened and read, not matched and trusted. All 55 rows quote text I read withsed -nat the line numbers given, at466f63e. Line numbers are from that commit and this PR changes no source file, so they remain valid on merge. - Secret-adjacent files: no
*.sops.yamlcontent is quoted anywhere in this report, and no.data/.stringDatavalue or key name appears. The two.sops.yaml.examplerows (#50, andplatform/headlamp/headlamp-oidc-credentials.sops.yaml.example:15in the unlisted set) are cited by path and line only. I ran nosops -d. - The gate. Result recorded in the PR; see "What I did NOT verify" for the stages that cannot run in this container.
git diff --statagainstmain: one added file,decisions/2026-10-31-source-comment-audit.md, and nothing else — which is the brief's "done means" condition.
What I did NOT verify
- Anything about the live cluster. I hold no cluster credentials — no kubeconfig and no
ServiceAccount token is mounted in this container, so
kubectlcannot work here. This audit is a pure text analysis of the tree and makes no claim about the running platform. That is appropriate (no behaviour changes), but it also means every factual assertion quoted inside the comments I audited — the measured Cilium lease holders, thelonghorn_volume_robustnessseries counts, the 192.168.2.30 NFS reachability, the k3s version, the oauth2-proxy scrape targets — is unverified by me. I classified comments by what they talk about, not by whether their measurements are still true. A rewrite PR that restates one of those measurements as current fact should re-measure it first. - The two gate stages that cannot run in this container, per the environment notes and
CLAUDE.md§3:spec-immutability(the sibling spec repo has no git remote and is not reachable from the cluster) andgitea-settings(needsSETTINGS_API_TOKEN, which I deliberately do not hold). So R-TEST-06 is not actually exercised on this run. - ~365 of the ~420 candidate hits were not examined. The per-directory table marks which
directories are full and which are sampled. For
platform/,infra/,conformance/,clusters/,ci/andcatalog/the listed findings are representative, not complete, and thehistorical : load-bearingratio I report (22:32) is measured over the 55 rows I judged, not over the whole corpus — do not project it onto the residual. - The keyword sweep is not a complete detector. It finds English phrasings I thought of. Historical narrative that avoids all of them — a dated war story with no "used to", a stale rationale phrased entirely in the present tense, a comment that is simply wrong about today — is invisible to it. The most dangerous category (a confidently present-tense comment describing a superseded state) is precisely the one this method cannot find. A complete audit needs a reader per directory, not a grep.
runbooks/(11 candidate hits), the repo-root markdown (README.md,DESIGN-waves.md), and the in-repodocs/tree were not audited. They are prose documentation rather than source comments, so they fall outside the reporter's wording — butCLAUDE.md§1 already records thatrunbooks/contains stalegit push origin maininstructions, so there is known stale narrative there that this audit does not cover.- The sibling spec repo (
R-*requirements, ADRs) was not read or assessed at all — it is not present in this container and is human-owned and immutable to agents (R-TEST-06). Nothing here proposes a change to it. Where a comment cites a spec document (e.g.docs/06/R-STATE-01in finding #44), I did not verify that the citation resolves. - I did not verify that any recommended rewrite is correct, only that the current comment is historical. Each "rewrite" row names what I believe is the load-bearing residue; the engineer doing the pruning must confirm that residue is still true before writing it as present-tense fact. I wrote no replacement text.
- Whether the operator agrees with my
historical/load-bearingline. I applied the calibration from issue #97 literally plus the brief's one carve-out. The 22:32 split is a judgement call, and the two groups in theambiguousdiscussion above are explicitly unresolved and need a human ruling before theci/tests/and README rows are touched. conformance/runs/*/run.logandapps/wave-*were excluded by my own judgement, on the structural grounds given (archived evidence; gate-enforced goldens). The operator has not confirmed either exclusion.- Nothing here traces to an
R-*requirement, deliberately — this is housekeeping, per the brief. I did not attempt to attribute one, and I did not check whetherci/touched-requirements.shexpects an attribution for adecisions/-only change.