Skip to content

Check private host names in files, commit diffs and identities - #934

Merged
seathatflowsinourveins merged 4 commits into
mainfrom
codex/ns2604-name-scan-f11-20261009
Oct 9, 2026
Merged

seathatflowsinourveins merged 4 commits into
mainfrom
codex/ns2604-name-scan-f11-20261009

Conversation

@seathatflowsinourveins

@seathatflowsinourveins seathatflowsinourveins commented Oct 9, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

F11 checks runtime private host names in files, pushed diffs and commit identities through Betterleaks 1.9.0 native rules. The final privacy correction masks the Windows-computer token joined to Backup in a historical scheduled-task name and corrects the decision record's earlier explanation. Joined words remain a documented bare-name scanner limit; the token was corrected manually.

  • Base commit: 3497f50ce66ff193fabec1196b39b3d83eed12fe.
  • Lane: lane:foundation.
  • Final privacy correction: 1654df5694f1f186c2eb04b2d3336a17ade96268, one commit on reviewed head c6b70c13ca394ac1620b1a32a11c25d53213aa2c, without rebase.
  • Overall owned paths: scanner, validator, pre-push hook/tests; existing source trust/resolver compatibility; scanner setup action and its callers; dated decision record; two explicitly authorized current-tree privacy corrections and manifest registrations. The final correction changes only the two named decision documents and their manifest entries.

The prior scanner fixes preserve names after raw U+001E/U+001F by normalizing those characters before framing, and exclude only a Linux hostname equal to the public distro identifier ignoring case. Coincident private sources remain active. Discriminating tests cover no-reply email, private email without @, safe stderr and source-labelled fallback with an unknown count. Windows commands request UTF-8 output with a 30-second timeout.

The existing source trust inventory and resolver now recognize isolated exact-file Python loading while retaining conservative dependencies for direct scripts and mixed/reassigned bindings. GitHub's native $/ action references bind to the running workflow commit; existing readers retain their composite/script dependencies. A literal trusted runner.temp PATH append satisfies native zizmor without suppressions. These code and workflow bytes are unchanged by the final privacy correction.

SOTA sources

Evidence-class table

Claim Evidence class Command / receipt
Scheduled-task token manually masked and explanation corrected source_review Two named documents; only their manifest hashes/byte counts refreshed. Historical execution claims remain unchanged
Joined-word boundary source_review Existing native Unicode letter/number neighbor filter; joined words are excluded, with no detection guarantee claimed
Fresh native/source checks synthetic Source32/32 rc0 and validator81/81 rc0 on the final correction's document/manifest bytes; unchanged scanner/test bytes
Prior immutable-tip/per-ref push checks local_integration / synthetic Hook28/28, no skips, rc0, 646.707 seconds, log SHA256 951922c56d4bd582643d2cfc42e78f34f4b8482ec24e19a0063a8c39fa6618f7; hook bytes unchanged by final correction
Prior compatibility and trust checks local_integration CI-related318/319 and resolver/trust146/147, one existing skip in each; nine bounded classifier cases pass
Prior native PowerShell encoding native_proven / synthetic Non-ASCII round-trip rc0, 0.418758 seconds; no cold-host timing guarantee
Prior native signed release verification native_proven Existing cosign/checksum commands rc0; retained sigstore-native-20261009T180701Z.json
Prior real-host check native_proven Clean c6b70c1: rc0, source=host, zero locations/11811 files, 23.935 seconds; does not establish joined-word detection
Prior exact-head CI local_integration Current validation run37987281613 SUCCESS/13 jobs and six other latest workflows SUCCESS at c6b70c1; final correction needs its own CI
BASE expectations at c6b70c1 local_integration, declared changes Unchanged required pre-cue rc1: seven old expectations in three of five files; original pre-push/resolver modules pass
Final correction FULL validation local_integration rc0: 70 components/11051 hashed files/4 profiles/239 receipts, 50.872 seconds; manifest ordering rc0/11051 files
Final correction native scan native_proven Clean 1654df5 from the actual native session: rc0, source=host, zero locations/11811 files, 27.111 seconds, peak RSS2319924KB; synthetic override absent
Distro environment dependency native_proven, declared limit A service-context invocation at the same head lacked the distro environment source and returned rc1/513 locations; the native session retains that source and returns rc0. No environment-independent coverage is claimed

Local commands run

Prior measurements and hashes remain in the detailed checkpoint and retained logs. Fresh final-correction checks used the same two document/manifest byte sets committed as 1654df5:

python3 -B -m unittest tests.test_host_name_scan
rc0: 32/32; 9.739 seconds in unittest, 9.946 overall

python3 -B -m unittest tests.test_validate
rc0: 81/81; 4.602 seconds in unittest, 4.777 overall

python3 -B scripts/validate.py
FULL rc0: 70 components/11051 hashed files/4 profiles/239 receipts, 50.872 seconds

python3 -B scripts/evidence_manifest.py --check
rc0: 11051 registered files, 0.070 seconds

python3 -B scripts/validate.py --scan-tracked
rc0 at clean 1654df56 from the actual native session: source=host,
matching_locations=0, scanned_files=11811; synthetic override absent

Heavy checks require a fresh Windows free-memory measurement of at least 13 GiB and capped systemd scopes. Resource refusals before launch are not scanner/test results.

The actual native-session host scan launched after Windows free14.576GiB and
completed in27.111seconds, peak RSS2319924KB. Its output SHA256 is
cb65522b22aaea34c67065896ecc9f50d3cc487bbb40f2fbad8b7090cd8b3b30.
An earlier invocation through the context service lacked the distro environment
source and returned rc1/513locations at the same head. The native session's
source-presence boolean was verified without printing its value. This
reproduces the declared non-blocking environment dependency; the failed
invocation is retained separately and is not relabelled as a passing scan.

The unchanged required BASE pre-cue at c6b70c1 completed rc1 in 491.981 seconds. Two workflow-reader subcases and two action ownership/pinning tests predate native $/ references; three validator cases expect the former text output. Current corresponding modules pass. These seven intentional expectation changes are declared for CC disposition; no passing BASE result is claimed.

Decision record

docs/decisions/2026-10-09-host-name-scan.md records primary sources, reproduced fixes, the corrected task-token explanation and scope limits. Joined words such as <name>Backup, commit messages, annotated tags/ref names, native binary/merge behavior, the all-remotes new-ref exclusion and additional delimiter escapes remain outside current detection guarantees. Native codec minimums/larger nested spans and source-directory ignore fingerprints remain upstream limits.

The final micro's non-blocking P3 follow-ups remain open: derive the distro identifier without environment reliance; retain non-import file coverage for isolated inline Python in patch_policy; encoded record separators before a name; stale pre-push/RESOLVER.md comments; and nullable scanned_files. They are listed, without changing the scanner or widening this required correction.

Host evidence

N/A: no evidence/hosts change or platform-status flip. The CC explicitly authorized the two current-tree privacy corrections. Publication hashes are refreshed without rewriting historical execution claims.

  • Host-receipt validation/review: N/A; no new or changed host receipt.
  • No platform status changes from a host receipt alone.

Checklist

  • Third-party action pins and native $/ exact workflow-commit binding retained.
  • Existing workflow permissions and job scopes retained.
  • No credentials read, printed or committed; no required secret added.
  • No paid hosting, subscription or billing surface introduced.
  • Peer-owned paths/worktrees and protected namespaces preserved.

The CC micro, final-head CI, declared BASE disposition, maintained pre-cue activation and explicit CC cue remain required. Landing order is after #926. Diagnostic output incidents remain transparently recorded in R43 and R50; no passing privacy-output claim is made for those incidents.

@seathatflowsinourveins seathatflowsinourveins added the lane:foundation Foundation lane: Claude/Codex setup, hosts, memory, RAG, research, workers label Oct 9, 2026
@socket-security

socket-security Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Dependency limit exceeded — report not shown.

This pull request scan exceeded the 10,000-dependency limit applied to this scan, so the results are incomplete and may be inaccurate. To avoid reporting false positives, Socket has not posted a report.

Upgrade your plan to raise the dependency limit and get complete reports, or view the partial scan in the dashboard.

Socket is always free for open source. If this is a non-commercial open source project, contact us to request a free Team account.

@seathatflowsinourveins seathatflowsinourveins changed the title Add host-local bare-name checks through native Betterleaks rules Check private host names in committed files and pushed history Oct 9, 2026
@seathatflowsinourveins seathatflowsinourveins changed the title Check private host names in committed files and pushed history Check private host names in files, commit diffs and identities Oct 9, 2026
@seathatflowsinourveins
seathatflowsinourveins marked this pull request as ready for review October 9, 2026 21:31
@seathatflowsinourveins
seathatflowsinourveins merged commit 3c01bdd into main Oct 9, 2026
38 of 49 checks passed
@seathatflowsinourveins
seathatflowsinourveins deleted the codex/ns2604-name-scan-f11-20261009 branch October 9, 2026 21:31
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 9, 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-09T21:37:07.116317Z 1654df5 Draft marked ready
ℹ️ 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.

seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…rd in pre-push (#1010 round 1)

B1 (CC adjudication of #1010 round 1): catalogs/north-star/readiness.json still pinned the pre-change sha256 of the three qualification receipts this PR re-pins, in 15 places. Each receipt had five: the repo:<receipt>@<digest> key, that entry's sha256 and expected_sha256, and two nested receipt objects. Rebuilt from the new bytes and a guessed name, each old receipt matched its pin, which is the second-order oracle of correction #161. Each pin now names the receipt's current sha256:
- markitdown-018: d9a1a348 -> 74d066a1;
- mcporter-0141: 5379b1e3 -> 9b69956e;
- rtk-050: 9de293b6 -> b47326a1.
Byte counts are unchanged. tools/north-star/build_readiness.py --write was not used, because it would also fold in readiness drift that predates this PR.

tests/test_published_digest_privacy.py:
- ReadinessPinTests needs no names. Every readiness binding of a receipt changed since the merge base with origin/main must hash that receipt's current bytes. It fails at 7a03593 (15 stale pins) and passes after.
- The guard is now enforced. scripts/git-hooks/pre-push runs it on each pushed tip with PUBLISHED_DIGEST_GUARD_HOST_NAMES=1, so the names come from scripts/host_name_scan.py host_names(), the runtime source of #934's scan (docs/decisions/2026-10-09-host-name-scan.md); NATIVE_AGENT_HOST_NAMES_JSON replaces them in fixtures. The hook's runner refuses a skip, and an unavailable source errors. CI keeps the name-free tests.
- The legacy check is one-directional, so it works in a clone whose names differ. An unlisted site fails. A listed site the names do not reproduce is reported only as a count. test_the_frozen_list_only_shrinks still fails, without names, once a listed digest is gone from its file.
- The mask set adds the repository's existing markers <user-home>, <SCRATCH_HOME>, %USERPROFILE% (as C:\Users\<name>, C:/Users/<name> or /mnt/c/Users/<name>), <WSL_USER> and <hostname>. Every subset of up to four present masks is tried; beyond four, all of them or one at a time.
  - Measured with LANDING_PROHIBITED_NAMES (3 names) and with host_names() (5 names), the guard finds exactly the 106 listed sites both times. There is no new site, so the list and LEGACY_COUNT are unchanged.
- Caching texts and resolved paths halves the whole-tree walk, from 24 s to 11 s with 3 names.

tests/test_pre_push_gate.py overlays the guard module on the fixture tip, as it does the scanner sources. A clean push runs the guard once. A committed receipt whose output_sha256 hashes its excerpt with the fixture home put back is refused without echoing the name.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
seathatflowsinourveins added a commit that referenced this pull request Oct 11, 2026
…ence, blueprints and manifests (#1010)

* Re-derive 10 published digests that hashed unmasked bytes, and guard evidence, blueprints and manifests

Correction #161: the 2026-10-11 masked-digest audit of main at 7b76a88 found 8 sha256 values under evidence/artifacts that hash bytes from before sanitization. Its residual list found 2 more under blueprints. Each sits beside a copy in which the home directory is replaced by ~ or the user name by <user>. Anyone could put a guessed value back, hash the result and confirm the guess offline.

Each value is now the sha256 of the published bytes. That is the basis scripts/host_receipts.py record has used for output_sha256 since #492 (scripts/host_receipts.py:1012-1029 at 7b76a88).

- sota-refresh-20260925 markitdown (2), mcporter (3) and rtk (1) results.json: files[].run_copy_sha256 is now the sha256 of the committed file, the same value as the entry's sha256. byte_identical_to_run_copy stays false. Each record gets a corrections entry; mcporter had no list, so one is added.
- The withdrawn nemotron vLLM use receipt -2: commands[1] and commands[4] output_sha256 are now the sha256 of output_excerpt (UTF-8), and its README records the change. This removes no oracle, because 4 registered evidence/hosts receipts keep the same digests (commands[1]'s in 4, commands[4]'s in 3).
- blueprints/retrieval-quality-v2/review-293-repro-20260926.json: inputs.files[0].as_run_sha256 is now the committed driver's sha256. A corrections entry in the record's own shape records the change.
- The withdrawn byterover-cli install receipt: commands[0].output_sha256 is now the excerpt digest. retained-outputs.json, the byterover-cli README and the trials README record the exception to "kept byte-for-byte".

The sha256 of a file before this change would confirm a guess the same way: rebuild the old file from a guess, hash it and compare. Every digest of an old file is therefore re-pinned or dropped:
- the three evidence/receipts qualification receipts re-pin results.json in provenance[], as #314 did;
- retained-outputs.json gives the new receipt bytes for both private_original and published;
- the review-293 correction records no as_recorded_sha256;
- manifests/evidence.json re-registers the 13 files through host_receipts.register_file.

tests/test_published_digest_privacy.py walks every JSON file under evidence/, blueprints/ and manifests/. It flags a 64-hex digest that hashes none of the published texts or files in its own or enclosing object, but does hash one of them once a home directory or name is put back. The masks are ~, <home>, <HOME>, <host-home>, $HOME, ${HOME}, <user>, <USER> and $USER, under /home/<name> and /Users/<name>. Names come from LANDING_PROHIBITED_NAMES. Without them, as in CI, that check skips.

LEGACY_SITES freezes the 106 remaining sites by path, key and 8-hex prefix, with a count assertion:
- 96 output_sha256 values in evidence/hosts receipts recorded before 2026-09-29, append-only since #492;
- 10 that the audit's probe could not reach, because it put back only ~ and <user> and read only files named in the digest's own object.

A new site fails. A listed site that is gone also fails until it is removed, so the list only shrinks. Two checks run in CI too: every listed site is still present, and the 10 fixed sites hash the published bytes.

Fail-before: on the 7b76a88 tree, the guard reports exactly the 10 fixed sites and the fixed-site check fails 10 subtests, with or without names. After this change, all 11 tests pass, or 10 pass and 1 skips without names.

Not changed: git history keeps the old digests. No rewrite is proposed, because the exposure is a home directory or account name, not a credential.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* Re-pin readiness to the re-pinned receipts and enforce the digest guard in pre-push (#1010 round 1)

B1 (CC adjudication of #1010 round 1): catalogs/north-star/readiness.json still pinned the pre-change sha256 of the three qualification receipts this PR re-pins, in 15 places. Each receipt had five: the repo:<receipt>@<digest> key, that entry's sha256 and expected_sha256, and two nested receipt objects. Rebuilt from the new bytes and a guessed name, each old receipt matched its pin, which is the second-order oracle of correction #161. Each pin now names the receipt's current sha256:
- markitdown-018: d9a1a348 -> 74d066a1;
- mcporter-0141: 5379b1e3 -> 9b69956e;
- rtk-050: 9de293b6 -> b47326a1.
Byte counts are unchanged. tools/north-star/build_readiness.py --write was not used, because it would also fold in readiness drift that predates this PR.

tests/test_published_digest_privacy.py:
- ReadinessPinTests needs no names. Every readiness binding of a receipt changed since the merge base with origin/main must hash that receipt's current bytes. It fails at 7a03593 (15 stale pins) and passes after.
- The guard is now enforced. scripts/git-hooks/pre-push runs it on each pushed tip with PUBLISHED_DIGEST_GUARD_HOST_NAMES=1, so the names come from scripts/host_name_scan.py host_names(), the runtime source of #934's scan (docs/decisions/2026-10-09-host-name-scan.md); NATIVE_AGENT_HOST_NAMES_JSON replaces them in fixtures. The hook's runner refuses a skip, and an unavailable source errors. CI keeps the name-free tests.
- The legacy check is one-directional, so it works in a clone whose names differ. An unlisted site fails. A listed site the names do not reproduce is reported only as a count. test_the_frozen_list_only_shrinks still fails, without names, once a listed digest is gone from its file.
- The mask set adds the repository's existing markers <user-home>, <SCRATCH_HOME>, %USERPROFILE% (as C:\Users\<name>, C:/Users/<name> or /mnt/c/Users/<name>), <WSL_USER> and <hostname>. Every subset of up to four present masks is tried; beyond four, all of them or one at a time.
  - Measured with LANDING_PROHIBITED_NAMES (3 names) and with host_names() (5 names), the guard finds exactly the 106 listed sites both times. There is no new site, so the list and LEGACY_COUNT are unchanged.
- Caching texts and resolved paths halves the whole-tree walk, from 24 s to 11 s with 3 names.

tests/test_pre_push_gate.py overlays the guard module on the fixture tip, as it does the scanner sources. A clean push runs the guard once. A committed receipt whose output_sha256 hashes its excerpt with the fixture home put back is refused without echoing the name.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
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