Skip to content

Match the user name as a whole token in host_receipts.sanitize() - #227

Merged
seathatflowsinourveins merged 2 commits into
mainfrom
claude/user-name-token-sanitize-20260924
Sep 25, 2026
Merged

seathatflowsinourveins merged 2 commits into
mainfrom
claude/user-name-token-sanitize-20260924

Conversation

@seathatflowsinourveins

Copy link
Copy Markdown
Owner

host_receipts.sanitize() replaced $USER as a substring. A short account name is often part of ordinary words, so under an account named ed (inside recorded), hardware_profile.py --record-host recorded-host-20260101 refused the id ("contains the local user name or a home path"), and host_receipts.py record excerpts lost letters (cached became cach<user>). CI runs as runner and never hit this. On unmodified main it breaks tests.test_new_host_grand_list.RecordHostToGrandListTests.test_recorded_host_gets_non_null_measured_in_the_grand_list on any host whose account name occurs inside that id.

Change. sanitize() now replaces the name only as a whole token (user_name_pattern()): no letter, digit or underscore may touch it on either side. An escape that ends in a letter or digit just before it (JSON \n, \r, \t, \u002f, a \x2f or a URL's %2F) still counts as a separator, so encoded home paths stay redacted. The $HOME to ~ replacement and the PRIVATE_CONTENT patterns are unchanged. Another account whose name merely starts with this one (/home/ed_old/...) is still redacted, by the personal-home-path pattern.

Trade-off. A name glued to a letter, digit or underscore (edmbp, ed2, ed_old) is no longer redacted or refused on its own. A name set off by -, ., /, \, @, quotes or whitespace still is, so ed-mbp-20260101 is still refused.

Tests simulate the ed account on every host:

  • SanitizeUserNameTests: words that contain the name are kept, the name as a token is redacted, home paths stay redacted in eight forms (literal $HOME, Linux and Windows layouts, a Claude project slug, URL-encoded, \u002f and \x2f escapes, another account's home), as does the name after a JSON \n, and a record round trip keeps cached in the excerpt.
  • RecordHostTests: recorded-host-20260101 is accepted with its label and evidence path intact; ed-mbp-… and mbp-ed-… are refused. The existing refusal test used ramstation for user ram, which is the substring rule itself; it now uses ram-station.
  • RecordHostToGrandListTests: the grand-list round trip, rerun under that account.

Against the old sanitize(), 8 of these checks fail, including when the process itself runs as runner. All pass with the fix. Home paths in the test source are spelled through variables so that scripts/validate.py's own publication scan passes. The sanitize_values() docstring and docs/contributing-evidence.md now describe the whole-token rule, and manifests/evidence.json re-registers the three hash-listed files.

Checks (macOS 26.5.1 arm64, Python 3.13.15, on 5112084, rebased onto d478fd5):

  • Every validate.yml step, run locally with the CI-pinned zizmor 1.30.1, actionlint 1.7.12 and gitleaks 8.30.1: all 25 steps exit 0. validate.py passed (5338 hashed files, 145 receipts), verdict_review_gate.py reports no verdict rows changed, and gitleaks found no leaks in 508 commits or the tree. The promotion-gate venv provisioning was not run locally.
  • Full python3 -m unittest: base 4289143 ran 4713 tests, failures=2, errors=1, skipped=647. This branch ran 4719 tests, failures=1, errors=1, skipped=647. The differences are the grand-list test above, which now passes, and the 6 new tests.

Two failures remain locally in tests.test_adoption_bootstrap_macos on both base and branch. Both are environment-specific, unrelated to the user name, and not changed here:

  • LlamaWrapperQuotingTests.test_install_path_with_shell_syntax_is_data_in_the_wrapper: its fake llama-server is a #!/bin/sh script. With SIP enabled, dyld purges DYLD_* when it launches the protected /bin/sh, so the script never sees the DYLD_LIBRARY_PATH that the generated wrapper exports. The same export does reach an unprotected interpreter. The test passes on hosted macos-15 (validate-macos).
  • PlatformDependencyInstallTests.test_places_the_verified_tarball_correctly_when_the_prefix_is_reached_through_a_symlink: it uses the npm-packed fixtures but, unlike its npm-dependent siblings, lacks @unittest.skipUnless(NPM, ...), so it errors when npm is not on PATH.

🤖 Generated with Claude Code

sanitize() replaced $USER as a substring, so a short account name was cut
out of ordinary words. A two-letter name inside "recorded-host-20260101"
made hardware_profile.py --record-host refuse that id ("contains the local
user name"), and captured excerpts lost letters from words ("cached"
became "cach<user>" for user "ed"). The name is now replaced only where no
letter, digit or underscore touches it. An escape that ends in a letter or
digit just before it (JSON \n, \r, \t, /, a \x2f or a URL's %2F)
still counts as a separator, so encoded home paths stay redacted; the
$HOME replacement and the PRIVATE_CONTENT patterns are unchanged.

The tests simulate a two-letter account name on every host; CI runs as
"runner" and never hit this. The existing refusal test used "ramstation"
for user "ram", which is the substring assumption itself; it now uses the
name as a token ("ram-station") and adds two-letter cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

# Conflicts:
#	manifests/evidence.json
@seathatflowsinourveins
seathatflowsinourveins enabled auto-merge (squash) September 25, 2026 13:55
@seathatflowsinourveins
seathatflowsinourveins merged commit 720e294 into main Sep 25, 2026
26 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the claude/user-name-token-sanitize-20260924 branch September 25, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant