Skip to content

Host baseline recorder: read-only probe and receipts for the 24.04 and 26.04 hosts (guard unit A PR-0) - #710

Merged
seathatflowsinourveins merged 27 commits into
mainfrom
foundation/host-baseline-2604-20261004
Oct 5, 2026
Merged

seathatflowsinourveins merged 27 commits into
mainfrom
foundation/host-baseline-2604-20261004

Conversation

@seathatflowsinourveins

@seathatflowsinourveins seathatflowsinourveins commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

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:

    • coreutils, findutils and sudo identities;
    • launcher presence and versions;
    • the Landlock ABI, bwrap namespaces and ptrace_scope;
    • the passwd shell;
    • client versions;
    • rendered Codex inherit, shell_snapshot and allow_login_shell, and Claude CLAUDE_CODE_SHELL presence, 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:

    • NativeStack: the 24.04 reference.
    • NativeStack2604: recorded after the command center's F9 apply. It runs uutils 0.10.0, sudo resolves to sudo-rs, and Codex has inherit=none and shell_snapshot=false.
    • StackMeasure2604: the same OS and sudo-rs, but Codex inherit is 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.exe by its full path, through bash -lc so the probe sees the agents' login PATH.

Lane: lane:foundation.

SOTA sources

  • The final unit A record (guard and agent shell), implementation unit PR-0. Its sources: the Claude Code sandboxing, settings and permissions docs at client 2.1.289; openai/codex rust-v0.160.0 (allow_login_shell); uutils/coreutils 0.10.0; torvalds/linux v6.18 (Landlock, Yama).
  • scripts/host_receipts.py and docs/contributing-evidence.md: the receipt and registration conventions.

Evidence-class table

Claim Class Source
Host facts on three hosts local_integration, read-only native observation evidence/receipts/host-baseline-*.json and evidence/artifacts/host-baseline-20261004/
Probe privacy gate and no sudo structural plus unit tests tests.test_host_baseline_probe

Local commands run

python3 -m unittest tests.test_host_baseline_probe   7 OK
python3 scripts/validate.py                          exit 0
python3 scripts/evidence_manifest.py --check         exit 0
git diff --check                                     exit 0

Decision record

docs/decisions/2026-10-04-host-baseline-recorder.md.

Host evidence

  • Every probe ran read-only at nice -n 19, with no sudo invocation.
  • StackMeasure2604 was read inside its owner's window.
  • NativeStack2604 was read after the command center's cue.

Checklist

  • No workflow change.
  • No secret, login name or home path in any artifact (scanned).
  • No paid surface.

Review chain

  • Claude Opus first read: ACCEPT (0 p1, 8 p2).
  • GPT-6.1 Sol repair round through the packaged SDK worker; the coordinator committed it.
  • Claude Opus delta read of the repair: ACCEPT at 00e23803a2f7 (0 p1, 4 p2).

Recorded residuals (p2; the bounded review loop ends here):

  • tools/adoption/host_baseline_probe.py:95-100 (format at :96; field at :251); evidence/artifacts/host-baseline-20261004/nativestack-2404.json (launcher_packages.: In the r1 24.04 artifact, the repair's new launcher_packages.gdb field has exit 0 and output 'gdb ' (empty version), while debuggers.gdb.path exits 1 ('absent') and debuggers.gdb.version exits 127. package_observation's dpkg-query format '$...
  • evidence/receipts/host-baseline-nativestack-20261004.json:39-43; tests/test_host_baseline_probe.py:218-248 (artifact hash check :228, probe.output check :238): The 24.04 receipt binds role probe_source to the live tool path tools/adoption/host_baseline_probe.py (sha256 33fb4dd8...). The new test recomputes that path's hash and compares it with both the receipt and the artifact's probe.output. The...
  • commits c3eb5d0, a442a25, 8589f16, 40d093e, a69e997, 00e2380 (manifests/evidence.json); docs/lanes.md:96: Prior p2 Install native token-saving tools and publish portable lifetime evidence #8 is still open, and the repair repeats the pattern. 40d093e edits manifests/evidence.json (+45/-15), a69e997 resets it (-65), and 00e2380 adds the net back (+65). Six branch commits now touch this hot file, against lanes.md...
  • docs/decisions/2026-10-04-host-baseline-recorder.md:72-77, :163-171: Lines 72-77 still say the NativeStack stdin probe's '56 fields retain ten exit-1 observations' and that 'all 56 date queries exited 0'. That describes the r0 capture, which was replaced in place at evidence/artifacts/host-baseline-20261004/...

Recorded residuals (bounded review, 2026-10-05)

Claude Opus delta read t4 at ed7cbafcfff1 returned 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 labelled path_kind=path.name, and all four case paths end in env.

🤖 Generated with Claude Code

Scout and others added 6 commits October 4, 2026 20:32
…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]>
@seathatflowsinourveins seathatflowsinourveins added the lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers label Oct 5, 2026
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-05T02:39:07.099388Z 00e2380 PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread tools/adoption/host_baseline_probe.py Resolved
Comment thread tools/adoption/host_baseline_probe.py Resolved
Comment thread tools/adoption/host-baseline.md Resolved
Scout and others added 21 commits October 4, 2026 23:22
…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]>
@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator Author

Claude session native-agent-stack-5f: landing at head 7d917f07ffc011103d27584abe7d77b05065ccdd. The command center (wsl-architecture-design) gave its ACK at ed7cbafcfff1, which reaches this head only through recorded mechanical refreshes whose owned non-registry patch-ids are equal (its carry rule); under the user's 2026-10-04 decision it owns merges that touch the hot registry. The read-only cross-family review (GPT-6.1 Sol max, the packaged Codex SDK worker) returned ACCEPT at 00e23803a2f7; this head is reached from it through recorded carry edges (equal owned patch-ids, or a cross-family delta read returning ACCEPT at the edge's target), with no P1 item.

Observed main fead5d8f8042f01ffc1a785f3b8ad6c410ccb506. coordination/merge_tree_landing_check.py (sha256 a11649fcf2e5844c…) exit 0:

main fead5d8f8042f01ffc1a785f3b8ad6c410ccb506 head 7d917f07ffc011103d27584abe7d77b05065ccdd base f3ebf469b49c3e8a41efd28d3d30d53b2edbbac1 merged-tree 83dd414ee42fe246a03a12572cf72ac5c8712fb6 merge-tree-exit 0
ok   1: clean three-way merge
ok   2: merged-vs-main paths 15, outside PR-owned 0 []
ok   3: main drift 8 paths, overlap with PR-owned inputs (registry excluded) []
ok   4: registry foreign rows equal True, order preserved True, PR-owned rows 14, unowned top-level keys differing []
ok   5: merged files[] sorted by path with no duplicates: True (10118 rows)
LANDABLE
condition 5: merged files[] sorted and unique (tree 83dd414ee42fe246a03a12572cf72ac5c8712fb6)

Required checks at this head: 7 pass . Unresolved review threads: 0.

@seathatflowsinourveins
seathatflowsinourveins merged commit ec0b8fd into main Oct 5, 2026
25 checks passed
@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator Author

Claude session native-agent-stack-5f: post-merge observation. Landed as ec0b8fd821a7b2004c331d2185b33d9e5ed47896 (parent fead5d8f8042f01ffc1a785f3b8ad6c410ccb506), tree 83dd414ee42fe246a03a12572cf72ac5c8712fb6. The landed tree equals the checked merged tree and the parent is the observed main.

@seathatflowsinourveins
seathatflowsinourveins deleted the foundation/host-baseline-2604-20261004 branch October 5, 2026 09:04
seathatflowsinourveins pushed a commit that referenced this pull request Oct 5, 2026
… 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]>
seathatflowsinourveins pushed a commit that referenced this pull request Oct 5, 2026
…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]>
seathatflowsinourveins added a commit that referenced this pull request Oct 5, 2026
…, 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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant