Repository navigation
Host baseline recorder: read-only probe and receipts for the 24.04 and 26.04 hosts (guard unit A PR-0) - #710
Conversation
…l-configuration facts (unit A PR-0) tools/adoption/host_baseline_probe.py runs unchanged on Ubuntu 24.04 and 26.04 (stdin; no checkout needed) and prints one JSON object of names, versions and booleans: coreutils/findutils/sudo identities, launcher presence and versions, kernel Landlock ABI, bwrap namespaces and ptrace_scope, the passwd shell, client versions, and rendered Codex inherit/shell_snapshot/allow_login_shell and Claude CLAUDE_CODE_SHELL presence by name only. No sudo invocation; it refuses to print (exit 3) if a home path or the login name would appear. Adds the NativeStack 24.04 reference receipt and a sanitized record of the 2026-10-04 rust-coreutils 0.8.0 -> 0.10.0 upgrade on NativeStack2604. The 26.04 host receipts follow in this PR after the read-only runs. GPT-6.1 Sol build pr0-baseline-1 through the packaged SDK worker; the coordinator commits. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ll anchor), privacy gate on every exception, login-shell run command, both 26.04 artifacts (Opus p2s) GPT-6.1 Sol repair round pr0-baseline-r1 (answers the Claude Opus batch-7 read) through the packaged SDK worker; the coordinator commits. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 00e23803a2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…egistry plus the owned rows) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…tch, archived r1 source, recounts, self-reported hash, dpkg status, observation class) - Login check: host_baseline_probe.py matches the login only as a whole token or path component in observation outputs and stderr. Fixed labels and tool identities are excluded. Logins such as ubuntu, codex or user no longer force exit 3; a real disclosure still exits 3 silently. - The exact r1 probe source is archived as evidence/artifacts/host-baseline-20261004/ host-baseline-probe-r1.txt, and the NativeStack receipt binds that copy, so the live entrypoint can change without rewriting historical evidence. The two 26.04 receipts keep their r0 archive bindings. - The decision record's counts were recounted by script from the committed artifacts. NativeStack: 64 observations (52 exit 0, 11 exit 1, one exit 127). Each 26.04 capture: 56 observations (50 exit 0, six exit 1). A test now checks them. - The probe labels its canonical-source hash as self-reported and unverified. The guide hashes the exact bytes with sha256sum on the coordinator side before piping them. Historical receipts keep the executed-input hash as unknown. - Package rows record dpkg's db:Status-Status. The guide no longer treats the dpkg-query exit code as an installation predicate, and the historical rows are marked status-unrecorded with their captured values unchanged. - The historical coreutils upgrade receipt uses the policy's independent-observation class instead of local_integration. Every fix has a regression test that was red before it (12 tests now pass). No host was re-captured. Built by GPT-6.1 Sol through the packaged SDK worker (round pr0-baseline-t1); committed by the coordinator. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…xemptions, profile-path patterns, dated amendments) - Each tool's name is exempt everywhere in its own version banner, and the os-release ID is exempt in distribution vendor tags. Logins such as claude or ubuntu no longer collide with the committed Claude banners or an Ubuntu gdb banner, and identity paths still fail closed. - The probe's whole-document check carries scripts/validate.py's personal-home and Windows-user path patterns unchanged, and rejects attached -u<login> forms. A WSL profile path such as /mnt/c/Users/<login>.HOST/... now fails at the probe. The guide records which compound <login>-x and <login>.x tokens are accepted by design. - Each of the four receipts gains a dated amendment entry (2026-10-05T05:02:52Z, from date -u) that references t1 (7ec3f2a) and t2, lists the changed fields and keeps the prior values of the two fields rewritten in place. Captured artifact values are unchanged. - The guide names the 26.04 command as the coordinator's command for the two r0 captures (repair round r1). Every fix has a regression test that was red before it. Built by GPT-6.1 Sol through the packaged SDK worker (round pr0-baseline-t2); committed by the coordinator. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…on, and compound forms are refused again (privacy gate) - Explicit identity forms (USER=, LOGNAME=, --user=, -u <login>, <login>@, ~<login>, uid=N(<login>), <login>:x:) and standalone-login values are now checked on the unstripped value, before any exemption. Tool-name exemptions apply only between the stated delimiters, and the vendor-tag exemption covers only the first parenthesized group. This closes t2's fail-open for a login equal to a tool name or the os-release ID. - Login matching uses ASCII alphanumeric boundaries again. Numeric suffixes (alice123) and attached user/group option clusters are refused. The fixed sudoers marker path is exempted as a whole path instead of weakening the match. - 42 new regression cases were all red before the fix. A replay over the three committed artifacts with logins claude, codex, ubuntu, user and alice passes 15/15, so the real captures show no false positive. The guide and the decision record follow the code. The coordinator re-ran tests.test_host_baseline_probe: OK. Built by GPT-6.1 Sol through the packaged SDK worker (round pr0-baseline-t3); committed by the coordinator. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…d home normalization - Version-label exemptions now cover only the leading product-label segment, and vendor groups must follow it immediately on the same line. Later tool-name occurrences are still checked for account syntax, including in merged stderr. Regression tests add 128 account-annotation cases and the vendor/stderr cases. They failed against the t3 code and pass now. - Home normalization rewrites only values equal to the current home, or values that start with its complete path component followed by a slash. Prefix-sharing sibling paths and embedded references keep their path and fail closed. 16 regression cases cover output, stderr and commands. Built by GPT-6.1 Sol through the packaged SDK worker (round pr0-baseline-t4); committed by the coordinator. The builder ran these, each exit 0: - tests.test_host_baseline_probe (24 tests); - a local dry run, with zero login, home-prefix or actual-home matches; - validate, evidence_manifest --check and git diff --check. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…egistry plus the owned rows) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…egistry plus the owned rows) Co-Authored-By: Claude Opus 5.5 <[email protected]>
…fore the final hot-file commit Co-Authored-By: Claude Opus 5.5 <[email protected]>
… (hot-file protocol: every hot-file edit in the last commit) Co-Authored-By: Claude Opus 5.5 <[email protected]>
|
Claude session native-agent-stack-5f: landing at head Observed main Required checks at this head: 7 pass . Unresolved review threads: 0. |
|
Claude session native-agent-stack-5f: post-merge observation. Landed as |
… refused, home traversal refused, distinct subtest ids This addresses the three P2 residuals that the configuration owner accepted at #710's merge, and fixes the two leak paths as asked. - **Claude version strip.** It no longer erases prerelease or build suffixes, so the login checks see them. `2.1.289-alice (Claude Code)`, `2.1.289+build.alice (Claude Code)` and `2.1.289+claude (Claude Code)` with the matching login now fail closed. The committed banners and a benign-suffix control still pass. - **Home traversal.** Absolute values with a `..` component are refused. Values are normalized lexically with posixpath.normpath, without resolving symlinks, before the complete-home membership check. So `/home/alice/../bob/bin/env` no longer passes as a child of home. Traversal fixtures cover output, stderr, commands and keys. - **Subtest ids.** The sibling-home subtests use per-case ids: 18 distinct. Each fix has a regression that failed against main ec0b8fd and passes now. Built by GPT-6.1 Sol through the packaged SDK worker (round baseline-privacy-r5, on the #710 builder thread); committed by the coordinator. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ne-ending traversal, exact guide claim, subtest-id regression This fixes the three P2s from the Claude Opus cross-family read of r5: - normpath runs only on single-line, whitespace-free absolute values. Other values keep their remainder verbatim after the home prefix is replaced, as base did, so error lines and combined output are no longer rewritten. 12 controls cover output, stderr, commands and keys. - The '..' refusal checks the slash-delimited components on each line. Newline and carriage-return traversal fixtures cover four locations, and each exits 3 with empty output. - The guide, code comment and decision record now say that whole-document home detection is guaranteed for homes under /home/, and they document the limit for embedded references to homes elsewhere. This is documentation only; the gate is not extended (the user's no-over-engineering rule). - A committed regression asserts that the sibling-home subtest ids are unique. It fails when the old shared label is restored. Each new control failed against 26d6bdd (where applicable) and passes now. tests.test_host_baseline_probe: 28 OK. The six historical artifacts and four receipts are byte-identical. validate.py and evidence_manifest --check exit 0. Built by GPT-6.1 Sol through the packaged SDK worker (round baseline-privacy-r6, on the #710 builder thread); committed by the coordinator. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…, home traversal per line, path-only normalization, distinct subtest ids (#748) ### Scope - **What this PR changes:** the host baseline probe's privacy follow-up to #710. It addresses the three P2 residuals accepted at #710's merge and two leak paths. - **Claude version strip.** It no longer erases prerelease or build suffixes, so the login-name checks see them. A banner such as `2.1.289-<login> (Claude Code)` is refused. - **Home normalization.** Absolute values with a `..` component are refused, checked per line. Values are normalized lexically with `posixpath.normpath` only when single-line and whitespace-free. Every other value keeps its remainder verbatim after the home prefix is replaced. - **Subtest ids.** The sibling-home subtests have distinct ids, with a committed regression for it. - **Docs.** The guide states exactly where whole-document detection holds: for homes under /home/. - **Base:** the #710 merge `ec0b8fd82`. The four source files are unchanged on main since then; manifests/evidence.json is refreshed at landing (hot-file protocol). - **Lane:** `lane:foundation`. ### SOTA sources - CPython `posixpath.normpath`: lexical normalization that resolves no symlinks. - `str.splitlines` and `str.isspace`: the Unicode line-boundary set is a subset of whitespace, verified across all code points. - The #710 decision record, `docs/decisions/2026-10-04-host-baseline-recorder.md`, and its accepted residuals. ### Evidence-class table | Claim | Evidence class | Command / receipt | | --- | --- | --- | | Each leak path is refused | synthetic (unit tests) | `python3 -m unittest tests.test_host_baseline_probe`: 28 OK (builder-reported). Each new control failed against the prior head. | | Trailing text is preserved | synthetic | 12 controls across output, stderr, command and key | | Line-ending traversal is refused | synthetic | newline and carriage-return fixtures in 4 locations; the reviewer also checked U+2028, U+2029, U+0085, \v, \f and \x1c | | The historical artifacts are unchanged | local check | 6 artifacts and 4 receipts are byte-identical | ### Local commands run ``` $ python3 -m unittest tests.test_host_baseline_probe OK (28) $ python3 scripts/validate.py exit 0 $ python3 scripts/evidence_manifest.py --check exit 0 $ git diff --check exit 0 ``` ### Review Built by GPT-6.1 Sol through the packaged SDK worker (rounds baseline-privacy-r5 and r6, on the #710 builder thread) and committed by the coordinator (Claude session 5f). - **r5:** the Claude Opus cross-family read returned ACCEPT with 3 P2s. All were fixed in r6. - **r6:** the Opus delta read returned ACCEPT and confirmed all 4 prior items fixed. It raised one new doc-only P2, recorded as a residual below. ### Checklist - [x] No GitHub Actions or workflow changes. - [x] No secrets printed, logged or committed. - [x] No new paid hosting, subscription or billing surface. 🤖 Generated with [Claude Code](https://claude.com/claude-code) ### Recorded residuals (Claude Opus 5.5 delta read at c9ec642) - **P2 (documentation only; non-blocking).** `tools/adoption/host_baseline_probe.py:204-206`; `tools/adoption/host-baseline.md:69-75`. - **The case:** values that contain whitespace are no longer normalized. So for a home outside the /home/ tree, a leading home reference that is spelled non-canonically (a doubled slash or a `.` component) in a value that also contains whitespace or a line break is neither converted nor caught. The previous head normalized it. - **Exposure:** hosts whose homes are under /home/ are not exposed, since the home-prefix gate refuses such values with exit 3. - **Suggested fix:** one guide clause naming this case for homes outside /home/. No code change.
Scope
This adds a read-only host baseline recorder for the credential-guard work, unit A PR-0 of the 2026-10-04 guard and agent-shell convergence. It also adds the baselines it recorded:
tools/adoption/host_baseline_probe.py. A stdlib probe that runs unchanged on Ubuntu 24.04 and 26.04 from stdin and prints names, versions and booleans only:inherit,shell_snapshotandallow_login_shell, and ClaudeCLAUDE_CODE_SHELLpresence, all by name only.It never invokes sudo. Every exception exits 3 with empty output, so no path can leak.
Plain evidence receipts (kind
host_baseline,local_integration) for three hosts:inherit=noneandshell_snapshot=false.inheritis not set and Claude Code is 2.1.288.A sanitized record of the 2026-10-04 rust-coreutils 0.8.0 → 0.10.0 upgrade.
The documented run command:
wsl.exeby its full path, throughbash -lcso the probe sees the agents' login PATH.Lane:
lane:foundation.SOTA sources
rust-v0.160.0(allow_login_shell); uutils/coreutils0.10.0; torvalds/linuxv6.18(Landlock, Yama).scripts/host_receipts.pyanddocs/contributing-evidence.md: the receipt and registration conventions.Evidence-class table
local_integration, read-only native observationevidence/receipts/host-baseline-*.jsonandevidence/artifacts/host-baseline-20261004/tests.test_host_baseline_probeLocal commands run
Decision record
docs/decisions/2026-10-04-host-baseline-recorder.md.Host evidence
nice -n 19, with no sudo invocation.Checklist
Review chain
00e23803a2f7(0 p1, 4 p2).Recorded residuals (p2; the bounded review loop ends here):
Recorded residuals (bounded review, 2026-10-05)
Claude Opus delta read t4 at
ed7cbafcfff1returned ACCEPT with no p1. Under the bounded review rule these p2 items land as recorded residuals, each owed as a follow-up:tools/adoption/host_baseline_probe.py:254-255 (Claude label strip), :230 (raw pre-check), :262 (token check); before-fix ce2c11ba0:tools/ado: New fail-open introduced by t4.tools/adoption/host_baseline_probe.py:200 (child test), :211-214 (whole-document gate), :238-239 (command -v parent check), :262; tools/adop: Pre-existing, not a t4 regression: t3's replace() gives the same result.tests/test_host_baseline_probe.py:206 (case paths at :199-202): Each subTest is labelledpath_kind=path.name, and all four case paths end inenv.🤖 Generated with Claude Code