| 2026-07-26 |

D-137 tier 2: wire --privileged escalation (run BLOCKED by the auto-mode classifier)
...
--privileged retries a remote probe with `sudo -n` ONLY where the
unprivileged probe returned `unreadable`, keeping the privileged surface as
small as ruling 3 keeps the search surface. Metadata only; the T22
metadata-only guard still passes; verified inert (zero escalations) when
nothing is unreadable.
The operator approved the privileged read, but the auto-mode classifier
denied the remote-sudo shape -- the same wall the 2026-07-23 close recorded,
whose noted fix is manual permission mode. NOT worked around: reading a
root-owned directory is exactly the privilege being denied, so any
alternative would fail identically or misrepresent the result.
SEC-022 shadow-store contents and the SEC-020 region secrets stay
UNCONFIRMED; the sweep reports them as E0 UNREADABLE FAILs, which is the
correct outcome for an audit that could not look.
Also de-staled the docstring tier table (tier 2 is built).
Harness 35/35, gauntlet ALL GREEN (80), repo-lint 0-fail.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 tier 2: live read-only sweep + two probe false-greens it exposed
...
SEC-021's ON-DISK half REPRODUCED: vr1-dc0-maas-power_ed25519{,.pub} are
genuinely absent from the dc0 jumphost creds folder, not merely undeclared.
Capture: docs/audit/d137-tier2-sweep-20260726.txt (read-only, no sudo,
stat-over-ssh metadata only; jumphost + voffice1 + office1-netbox).
Running it against real hosts exposed two false-greens in the probe:
1. "absent" vs "could not look". /root/maas-secrets and /root/netbox-secrets
reported "does not exist" -- they exist; SEC-020 is precisely about
admin.pass living in the first. An unprivileged [ -d ] on a root-owned
parent is indistinguishable from a missing directory. The probe now tests
parent traversability and reports UNREADABLE as a FAIL, not a skip.
2. Role-level aggregation manufactured false absences: skipping one location
let a role's other locations cover it, so credentials in the unprobed
location reported EXPECTED-BUT-ABSENT. Absence is now asserted only over
fully-probed roles (14 rows report NOT JUDGED). Refinement: "absent" is a
conclusive observation and does not gate a role; only unreadable and
unreachable do.
Harness 33 -> 35 (T33 unreadable location, T34 absent location).
Gauntlet ALL GREEN (80), repo-lint 0-fail.
OUTSTANDING: the two root-owned dirs need a privileged read, so SEC-022's
shadow-store contents and the SEC-020 region secrets stay UNCONFIRMED. That
is a remote-sudo shape and was not run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 tier 2 (EXISTENCE): declared-location bound, existence checks, widened globs
...
Tooling only -- the LIVE three-site sweep has NOT run, so SEC-021's on-disk
half, SEC-022 and SEC-023 are not yet reproduced as live findings.
creds-manifests/vm-secret-locations (ruling 3): the absolute bound on
discovery. Covers the jumphost creds folders, the SEC-022 headend shadow
stores, the SEC-020 region secrets dir, the three dirs outside the SEC-009
convention, plus two the ruling's note did not name -- the in-clone PKI
overlay and the DOCFIX-175 plaintext tfstate. Tenant dirs are LOCAL-only:
no tenant VM/project/host is reachable from this file, so D-069 holds by
construction rather than by good behaviour. `<repo>` is substituted at
runtime (D-110: the repo name is never hardcoded).
creds-matrix.py --tier2 [--remote]: E1 expected-but-absent, E2 mode, E3
undeclared-at-a-declared-location. Probes are `stat` over ssh -- metadata
only, never content. An unreachable host SKIPS with an explicit [ok],
because "could not look" must never read as "nothing there".
--pending-stage is supplied by the CALLER so a not-yet-reached mint stage
defers instead of failing; encoding which stages have run would put a
status claim in code, and GA-R1 puts status in CURRENT-STATE only.
creds-audit.sh sprawl globs widened for the SEC-023 blind spots
(admin.pass, *.apikey, *.key, *.pem, *_ed25519, *_rsa, *openrc*). The old
six patterns could not have matched the SEC-020 secret that sat undetected
12 days, any bare SSH key or PEM, or the predicted Stage-5 ~/admin-openrc.
Harnesses: creds-matrix 33/33 (8 new tier-2 cases), creds-audit 13/13
(was 7; five blind-spot fixtures plus T13 asserting the widening did NOT
become trigger-happy). Gauntlet ALL GREEN (80), repo-lint 0-fail.
FLAGGED DIVERGENCE from the plan's Files list: --remote is implemented in
creds-matrix.py, not creds-audit.sh. Tier 2 IS the preflight Pn and the
matrix plus locations list both live there; splitting it would mean two
implementations of one bounded walk. Ruling 3 names a bound, not a script.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|

D-137 tier 1 (STATIC): credential matrix, checker, harness -- RED by design
...
Schema amended 10 -> 12 columns (operator-ruled 2026-07-26, "go with the
12-column amendment"): adds `custody` + `notes-ref` and re-keys a row to one
(credential, location) pair. A read-first round-trip check of the three
manifests proved the 10-column form could not carry what D-137 ruling 2
forbids dropping -- and ruling 3 puts four deliberate credential copies inside
--remote's declared locations, where creds-audit.sh:63-67 would report each as
UNDECLARED. Implements ruling 2 ("prose must become MATRIX FIELDS"); OPS under
GA-R3, the five sub-rulings untouched.
Ships: creds-matrix.tsv (72 rows), creds-matrix-notes.md (32 keys),
scripts/creds-matrix.py (S1 schema / S2 both-bounds manifest coverage / S3
render drift / S4 mint-ref resolution / S5 per-DC symmetry / S6 ruling-5
principal invariant / S7 notes integrity), tests/creds-matrix 24/24.
Gauntlet ALL GREEN (80, was 79); repo-lint 0-fail.
RED BY DESIGN, 5 findings -- do not go green by deleting rows: the ruling-5
identity conflation on maas-region-admin (the live SEC-020 defect), 3x
EXPECTED-BUT-ABSENT for SEC-021's declaration half, and the S5 asymmetry on
dc0's divergently-named headend power key. 27 operator-terminal rows are the
FINDING 1 reproducibility debt, counted not faulted.
Two self-inflicted false-greens found and closed during the build: S2
enumerated only matrix-mentioned sites (an empty matrix read CLEAN -- the
sandbox-fidelity-check.py:131-143 defect one level up; now the union of both
sides, regression-locked by T9), and the uniqueness key false-failed two
identities sharing one file (T6).
NOT done, stated so the boundary is unambiguous: tiers 2-3, vm-secret-locations,
the SEC-009 demotion, and the ruling-1 preflight Pn -- whose blocking-vs-deferred
sequencing is an OPEN operator question. No manifest rewritten; no cloud state
touched.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HvCyrwvYTTcDYnRErfMsNf
|