Skip to content

Landing scripts: validate the merge with the shard-0 currency checks, and an optional squash body file - #1027

Open
seathatflowsinourveins wants to merge 4 commits into
mainfrom
cc/landing-merge-currency-and-squash-body
Open

seathatflowsinourveins wants to merge 4 commits into
mainfrom
cc/landing-merge-currency-and-squash-body

Conversation

@seathatflowsinourveins

@seathatflowsinourveins seathatflowsinourveins commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Scope

  • What this PR changes, in one or two sentences: it ports the CC's two live-copy patches of 2026-10-12 into tools/landing. After scripts/validate.py, nas_land.sh now also validates the merge onto current main with every shard-0 step of validate.yml that runs a Python script with --check (CC correction macOS arm64 SYN evidence for the adaptive-paper engine and mover trial mode #176, exit 10; since round 3 the steps are read from the merge's own validate.yml). Both scripts take an optional SQUASH_BODY_FILE as the squash commit's body (gh pr merge --body-file; exit 2 before any call when it is not a readable, non-empty file). The tests fail at the base. README digest cells withheld (CC 2026-09-24 community sweep: effort-guard SessionStart notice, working plugin-install commands, dated dispositions #161).
  • Review fix, Astra's P1 at d6be1b0 (CHANGES_REQUESTED, reproduced on this PR's own harness): the scripts read no byte of SQUASH_BODY_FILE, so a body holding a home path, an account name, an address that is not a no-reply one or a token shape went into main's history (her four synthetic payloads each gave exit 0 and one merge call). Both scripts now copy the file once to a private snapshot (mktemp in TMPDIR, mode 0600, removed on every exit), scan the snapshot with the new tools/landing/squash_body_scan.py and with scripts/validate.py --scan-file, and give gh that same snapshot. A match, a copy or scan that fails, a missing scanner or names file and any answer that is not a scan's own clean line stop the landing with exit 2 and one fixed line, before the lock and every gh and git call (fail closed). Nothing of the body, no path and no scanner output is printed, but one count (below).
  • The CC's rulings of 2026-10-12 on that scan, each with tests: (1) a names-list entry equal to the running host's own name (compared with hostname when the scan runs, never printed) is a warning count and not a refusal, every other name still refuses; (2) a systemd unit instance, <name>@<instance>.service|.timer|.socket|.path|.mount whose <name>@<instance> is no address, is not an address (round 2 dropped .target); (3) a short list of vendor co-author trailer addresses, each with its vendor source, passes (now one, the Codex co-author address in the vendor's own history), compared whole, and a real-provider address is still refused. Measured on the last 600 commit messages of main, the scan refuses 8: 0 names, 5 addresses, 3 home paths (37 before the allowances: 26 names, 8 addresses, 3 home paths), with round 2's rule as before it.
  • Round 2 (the CC's adjudication at e203d01, below): quoted local parts are found and read as CPython's RFC 5322 parser reads them, the allowances compare the complete address, and a unit instance is kept only when <name>@<instance> is no address, with target dropped. Both README blockers are fixed. One commit on e203d01; the scripts are unchanged.
  • Round 3 (below): one commit on 37e242c, on the CC's Claude micro and the GPT family's fix3 verdict at 37e242c, the Codex connector's three threads and the CC's rulings of 2026-10-12. Every @ of a squash body is judged by CPython's RFC 5322 parser itself; two shapes pass by ruling, a source locator <repository>@<object name> and the repository's scratch co-author address; the host's own name is a warning through both real scans on any host; the names file is read only in a form a shell reads as the same list; and nas_land.sh reads the currency checks from the merge's own validate.yml.
  • Base commit: 86fa384421b1ca50134bd56d89cc72e0f7547816
  • Lane: lane:shared, as tools(landing): move the CC's landing scripts into the repository, with offline tests #975 was: the scripts land both lanes' pull requests (uet_land.sh the trading repository's).
  • Owned paths touched: tools/landing/nas_land.sh, tools/landing/uet_land.sh, tools/landing/README.md, tools/landing/squash_body_scan.py (new), tests/test_landing_scripts.py, and since round 3 scripts/host_name_scan.py (one opt-in, off unless set), tests/test_host_name_scan.py and docs/decisions/2026-10-09-host-name-scan.md (one sentence on it); manifests/evidence.json only re-registers those eight files.

Round 2

The CC's adjudication at e203d01 (2026-10-12T09:03:43Z; both families CHANGES_REQUESTED) upheld three P1s, each a way for an address to pass both real scanners into the merge, and two README blockers. Commit 37e242c0, one commit on e203d01, fixes them in squash_body_scan.py, the tests and the README; nas_land.sh, uet_land.sh and codex_gate.py are unchanged, so the README's "Here" digests stand.

  • P1-a (Astra 1), quoted local parts. "x"@<provider> is a valid RFC 5322 address that the atext-only shape never matched (squash_body_scan.py:46-47 at e203d01). The shape's local part now also holds quoted strings, and the scan reads each address with CPython's RFC 5322 parser, email._header_value_parser.get_addr_spec: quotes and quoted pairs are undone, so a quoted local part is refused or passed as its unquoted form is (RFC 5322 3.2.4, "quoted-string is identical to atom, semantically"). Decision point for the readers: a quoted form of an allowed address (the vendor's local part, or noreply, in quotes) therefore passes, as RFC 5322 makes it the same address; refusing every quoted local part instead is a one-line change.
  • P1-b (Astra 2), the complete address. The vendor allowance stripped every leading non-word character (:100-106 at e203d01), so +codex at the vendor's domain was compared as the vendor's address. The allowances now compare the whole local part and the whole domain as the parser reads them: +codex, !codex, +noreply, !no-reply and a domain that goes on past the vendor's are other addresses. Backticks, asterisks and quotes count as markup only when they wrap the address, closing right after its domain; a mark that does not close stays in the local part, as the parser reads it. An address the parser reads with a defect, an obsolete form included, passes no allowance.
  • P1-c (Claude B1), unit instances. <local>@<provider>.com followed by any of the six unit types had a unit instance's shape (:107-108 at e203d01; 12 of 12 end-to-end runs landed). A unit is kept only when its instance is not an address's domain, so that <name>@<instance> is no address, and target is no longer a kept type: .target is a delegated top-level domain (IANA list version 2026101200), so an address at <x>.target had the shape too. A bare unit has no @ and needs no allowance. A dotted instance shaped like a domain (client.conf) is now refused (fail closed).
  • B2 (Claude), stale claims. README "Provenance and digests": the paragraph on the CC's 00:10Z/00:37Z patches is in the past tense, and one sentence records that the CC replaced the live copies whole with d6be1b0's scripts at 2026-10-12T03:15:27Z (the three host paths filled in, codex_gate.py byte for byte, no squash_body_scan.py, read on 2026-10-12), and that the CC syncs them again after this PR lands (ruling C). The live-copy column's header no longer reads as current.
  • B3 (Claude), provenance. README sources: the cli/cli row says the files were read through the GitHub contents API at fc4b137c, with the sha256 values matching (read again for round 2: the same three); the local mirror, a blobless clone at ec5b5120, did not hold that commit. The section's intro no longer says that every row was read from a mirror.
  • The oracle (rule 4). The tests take the installed CPython parser as the one RFC 5322 oracle, the parser Astra ran (get_addr_spec, Lib/email/_header_value_parser.py:1682-1696 at v3.13.16, cbc944f4bc59; the installed 3.13.16 file has the pinned bytes). On every text the tests give it, CPython 3.12.3 (CI's), 3.13.16 and 3.14.4 answer the same (measured 2026-10-12). Each test has it read its addresses first, and one test checks 3,672 cases against the allowances applied to its reading.
  • Measured: the 600-message figure at 3a8a846 is the same with round 2's rule: 8 refused (0 names, 5 addresses, 3 home paths), 26 host-warning messages (66 occurrences), 2 unit instances (both .service), 1 vendor co-author address and 402 vendor noreply trailers passing, 37 refused without the allowances; on main's last 600 at bb945f1, the same 8.

Round 3

One commit, cb0429d7, on 37e242c0. Its inputs, which hold the reproductions (they are not repeated here; each fix is stated by what it guarantees):

  • the CC's Claude micro at 37e242c, command-center/research-cc-role-20261008/pr1027-claude-micro-37e242c0.md (W1, W2, C1, P3-A to P3-C);
  • the GPT family's fix3 verdict at 37e242c, fix3-pr1027-37e242c03/GPT-VERDICT.md (blockers 1 to 3, follow-ups 1 to 8);
  • the Codex connector's three review threads on e203d01 (nas:430, nas:259 and the address rule);
  • the CC's rulings of 2026-10-12 on this round: the two allowances below, and the host-name fix in scripts/host_name_scan.py.

What the commit guarantees:

  • No address passes for want of a pattern that finds it (Claude W1, W2 and C1; GPT blockers 1 and 2; the Codex address thread). squash_body_scan.py no longer searches for an address shape. On each line it judges every @ with the oracle, CPython's get_addr_spec (Lib/email/_header_value_parser.py at v3.13.16, cbc944f4bc59): the local part before the @ and the domain after it are read as the parser reads them, with quoted strings, comments and white space around the @, domain literals and domains of any form, and an @ inside a quoted string is judged inside it as well. An @ with no local part before it or no domain after it is no address. Text around an @ that the parser cannot read whole and without a defect is refused.

  • An allowance passes only a whole address that holds no other address and that no other touches (Claude W1 and W2). The allowances compare the complete parsed address, refuse a local part that holds an @, and refuse an address whose domain a quote or an @ follows; since each @ is judged by itself, an address inside or beside an allowed one is refused there too.

  • The allowances of the CC's ruling on this round. Judging every @ makes this repository's own locators and its scratch co-author trailer addresses to the parser; on main's last 600 commit messages the rule alone would refuse 399. The CC ruled two shapes not addresses:

    • a source locator, <repository>@<object name>, this repository's repo@pin:path:line form (CLAUDE.md:7): the whole domain is a git object name, 7 to 64 hex digits, and the local part has only the characters of a repository's path;
    • one exact address, the co-author address of this repository's synthetic scratch identity, cited to its source in the repository as the vendor list is.

    A tag, a branch or any other revision after an @, and every other domain without a dot, stay refused; such a body is rewritten (<repo> at <tag>; a mention in a code span of its own).

  • A body whose only hit is the host's own name lands with the warning on any host, and an identity spelled as the host is still refused (GPT blocker 3; the Codex thread on nas:259). The scripts run their second scan with NATIVE_AGENT_PUBLIC_HOSTNAME=1, a new opt-in of scripts/host_name_scan.py that drops the hostname source, as that file already does on a WSL host whose hostname is its WSL_DISTRO_NAME, and with it a Windows computer name of the same spelling (on WSL the hostname is by default that name); the account, profile and email sources stay. Nothing else sets it, so the pre-push scan is unchanged.

  • No listed identity goes unchecked for text that a shell and the scan would read differently (Claude P3-1 at e203d01; GPT follow-up 2). The names file's value is read only as a bare list or a list in one pair of quotes; any other form stops both scripts as unscannable. The CC's names file is in a documented form (checked by count, 3 names).

  • A merge is validated with the shard-0 checks that main's CI will run on it (the Codex thread on nas:430; neither read reproduced it, and this round did, through the PR's harness at 37e242c). nas_land.sh holds no list any more: shard0_checks reads the steps from the merge's own .github/workflows/validate.yml, in the workflow's order, so a step that the merge adds or changes runs as the merge writes it. The reader fails closed: a validate.yml in which it reads no check, and a step whose words are not plain ones, stop the landing with exit 10 before any check runs, the step's text not printed. A merge with no validate.yml runs none: main's CI has no such workflow to run on it, and a head that removes the file has no validate check run, which the CI gate requires.

  • The scan's cost is linear in the text (Claude P3-A). 60 KB on one line takes at most 0.18 s; round 2's rule took 24 s on 60 KB of one of the measured texts.

  • The README says which signals remove the snapshot (Claude P3-2 at e203d01; GPT follow-up 3): SIGINT, SIGTERM and SIGHUP, each measured and tested; SIGKILL leaves the mode-0600 snapshot, and the README says how to remove it.

  • Provenance (Claude P3-B): tools(landing): move the CC's landing scripts into the repository, with offline tests #975's cli/cli row names the mirror that holds fc4b137c (cli/cli-2.102.0; the three digests read again from it).

The three threads, for the CC's replies:

  • nas:430 (thread 4245825570): reproduced at 37e242c and fixed here; the checks are read from the merge's own validate.yml.
  • the address rule (thread 4245825578): reproduced by both reads and fixed here; every @ is judged by the parser, whatever the domain's form.
  • nas:259 (thread 4245825585): reproduced by the GPT read and fixed here; the second scan drops the host's own name only, on any host.

Measured (2026-10-12, counts only): on the last 600 commit messages of main at 5421e5d the scan refuses 70: 0 names, 67 addresses, 3 home paths (round 2's rule: 8, with 5 addresses). Of the 67, 31 hold a tag or a version after an @, 21 another domain without a dot, 13 white space or a comment at the @, 5 the addresses round 2 refused, 3 text the parser reads with a defect and 1 a commit id after a local part that is no repository path (a message may hold several kinds). It passes the 400 messages with a no-reply local part, the 341 with the scratch co-author trailer, the 78 with GitHub's no-reply domain, the 62 with a source locator, the 2 with a unit instance, the 1 that names a template unit and the 1 with the vendor co-author address; 26 messages (66 occurrences) name the host, a warning. Without the CC's allowances it refuses 417 (26 names, 400 addresses, 3 home paths).

Fail before, pass after: on a git archive of 37e242c with this round's two test files, the 19 new or changed tests give 2,254 failing cases and one error in 16 tests; the three that pass there are the controls' test, the signal test and #176's own test. At the fix all 19 pass, on CPython 3.12.3, 3.13.16 and 3.14.4, and the module's 150 tests pass.

For the CC to know:

  • A template unit, <name>@.<type>, passes: the parser reads no address there (no domain starts with a dot), and 1 of the 600 messages names one. It is not an allowance of an address, and it is tested.
  • The CC's own regression for macOS arm64 SYN evidence for the adaptive-paper engine and mover trial mode #176 (test_merge_validate_currency.sh in its tools directory) reports a failure on this merge_validate, because its scratch repository holds no validate.yml. A copy whose scratch repository holds one, and which cuts shard0_checks out with merge_validate, passes. It is a deployment item beside ruling C.
  • The GPT verdict names thread 4245825570 under its address blocker; in the packet's thread list that id is the nas:430 thread and the address thread is 4245825578.

SOTA sources

  • gh pr merge --body-file (GitHub CLI): cli/[email protected] (commit fc4b137c), pkg/cmd/pr/merge/merge.go:

    • :176-177 defines --body and --body-file/-F, "Read body text from file (use "-" to read from standard input)";
    • :138-144 makes the two mutually exclusive;
    • :146-153 reads the file when the command starts and sets BodySet. This is the mechanism of Astra's P1: gh reads the file when the merge call starts, over an hour after a check made at the start of a landing (the Codex wait takes up to 20 minutes, the CI wait up to 50), so the scanned bytes must be the bytes gh reads. The scripts scan a snapshot and give gh the snapshot;
    • :292-293 puts the body in the merge payload.

    pkg/cmd/pr/merge/http.go:72-75 turns a set body, an empty one included, into the mutation's CommitBody. pkg/cmdutil/file_input.go:8-16: - reads standard input. The gh manual: https://cli.github.com/manual/gh_pr_merge. (The reader function is pkg/cmdutil/file_input.go; pkg/cmd/pr/shared/file_input.go does not exist at the tag.)

  • The merge's body field: the GitHub GraphQL schema, https://docs.github.com/public/fpt/schema.docs.graphql, lines 26080-26082. Its sha256 is 3ed09565…, the bytes the README's earlier rows cite. MergePullRequestInput.commitBody is "Commit body to use for the merge commit; if omitted, a default message will be used".

  • The squash commit message setting: github/rest-api-description@58b1e0c00b39 descriptions/api.github.com/api.github.com.json:138199-138208. full-repository.squash_merge_commit_message is one of PR_BODY, COMMIT_MESSAGES and BLANK, where "COMMIT_MESSAGES - default to the branch's commit messages". GitHub Docs at github/docs@be38ec5d:

    Both repositories read COMMIT_MESSAGES from GET /repos/{owner}/{repo} at 2026-10-12T02:23:46Z.

  • The merge-queue rationale: GitHub Docs "Managing a merge queue" (https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/managing-a-merge-queue) at github/docs@be38ec5d:

    • data/reusables/pull_requests/merge-queue-overview.md:1, :3, :7: a queue keeps "the branch ... never broken by incompatible changes", like Require branches to be up to date before merging, by testing each pull request "applied to the latest version of the target branch and any pull requests already in the queue";
    • managing-a-merge-queue.md:84;
    • data/reusables/gated-features/merge-queue.md:2: queues are available in organization-owned repositories only.

    The queue is the native control for the Generate the canonical final-stack manifest (W4 PR 2) #1007/Move the claude-native-practice skill row to the commit that holds #1001, #1005 and #986 #1018 class. Both repositories are owned by one user account, so until the owner's organization step the landing script runs the merge check itself, as CC correction macOS arm64 SYN evidence for the adaptive-paper engine and mover trial mode #176 records. The rules of both main branches were read from GET /repos/{owner}/{repo}/rules/branches/main at 2026-10-12T02:23:46Z:

    • the trading repository has strict_required_status_checks_policy: true for ci-gate, so its CI already ran on the merge's tree and uet_land.sh needs no such step (its ci.yml at 0e987311 has no generated-artifact check);
    • this repository has false.
  • The checks themselves: this repository's .github/workflows/validate.yml:135-177 at the base (shard 0). Since round 3 the script reads them from the merge's own copy of that file, and a test holds its reader to those steps, in their order, the folded run: >- step of gap_wave_ledger.py (:166-174) included. Which file CI runs: github/docs@be38ec5d data/reusables/actions/about-triggers.md:18, "Each workflow run will use the version of the workflow that is present in the associated commit SHA or Git ref of the event" (sha256 76d0a30b…), and content/actions/reference/workflows-and-actions/events-that-trigger-workflows.md:780-784, a push runs at the "Tip commit pushed to the ref" (sha256 69e251c1…); workflow-syntax.md:619-621 and :849-851 for a step's if and run (sha256 50c73cf5…). A folded >- run is its lines joined by spaces: YAML 1.2.2 (https://yaml.org/spec/1.2.2/, fetched 2026-10-12, sha256 2fe1bf40…), 6.5 "the line break is converted to a single space", 8.1.3 and 8.1.1.2.

  • The squash body scan (the P1 fix and the CC's rulings):

    • The repository's own scans, reused: scripts/validate.py:38-61 (PRIVATE_CONTENT, the table for published text), :316-345 (scan_file_for_private_content) and :737-780 (--scan-file, the scan the pre-push hook runs: exit 0 clean, 1 findings, 2 unavailable), scripts/host_name_scan.py:164 (the native private-email rule whose character classes squash_body_scan.py uses for addresses) and :144-150 (the boundary rule for a name). Nothing of them is copied.
    • WSL UNC home paths, which PRIVATE_CONTENT does not match (measured 2026-10-12: no finding for either form, one for the same path with forward slashes): MicrosoftDocs/WSL@a1473a69d10c WSL/release-notes.md:24, "Switch the \wsl prefix to \wsl.localhost to avoid issues when there is a machine on the network named "wsl". \wsl$ will continue to work." (sha256 7c889022…), and WSL/wsl-config.md:162, the path of a distribution's file as \\wsl.localhost\<distro>\etc\wsl.conf (2f846065…).
    • No-reply addresses: github/docs@be38ec5d content/account-and-profile/reference/email-addresses-reference.md:47-48: [email protected] (accounts created after July 18, 2017) and [email protected] (older accounts that kept their address private) (sha256 fbbf1c5f…). The vendor trailer Co-Authored-By: ... <[email protected]> is this repository's convention: 402 of the last 600 commit messages of main at 3a8a846 carry it.
    • Ruling 2, systemd unit instances: systemd/systemd@c7a8e871de34 man/systemd.unit.xml (sha256 520150b1…): :121-124 a unit name prefix is ASCII letters, digits, :, -, _, . and \; :125-128 the type suffix is one of eleven (.service, .socket, .device, .mount, .automount, .swap, .target, .path, .timer, .slice, .scope; the ruling named six, and round 2 keeps five); :130-135 an instance name is inserted between the @ and the type suffix. So an instance of a template such as [email protected] has the shape of an address and is a unit.
    • Ruling 3, vendor co-author trailers: openai/codex commit db22c91e61cc80defa5bbafc22bd8a8c7672e5e1 (2026-05-05), message line 38: the Co-authored-by: Codex trailer with the local part codex at the vendor's domain, the vendor's own repository carrying the form, which is why it is on the list. The vendor's current attribution code writes Co-authored-by: Codex <[email protected]> (openai/codex@092d3acd6bec codex-rs/ext/git-attribution/src/world_state.rs:11 and :19, sha256 5d202fa0…), which passes as a no-reply address. No other primary source holds the older form: the five openai/* mirrors at their HEADs and the 36 Codex pages of developers.openai.com hold no such address (measured 2026-10-12). GitHub code search finds the exact trailer in 988 files (a count, not a source).
    • Round 2, how an address is read: RFC 5322 (https://www.rfc-editor.org/rfc/rfc5322.txt, fetched 2026-10-12, sha256 cb459acc…): :961 local-part = dot-atom / quoted-string / obs-local-part; :735-744 a quoted-string is qtext or quoted pairs between two DQUOTEs; :746-757 "quoted-string is identical to atom, semantically", the quote characters not part of it; :939-940 "Comments and folding white space SHOULD NOT be used around the "@" in the addr-spec"; :1939 obs-local-part. CPython's parser, python/[email protected] (cbc944f4bc59, the local mirror; sha256 7beea37a…, the bytes of the installed 3.13.16 file): Lib/email/_header_value_parser.py:1682-1696 get_addr_spec, :1486-1523 get_local_part, :1525-1575 get_obs_local_part, :1235-1275 get_bare_quoted_string, :1315-1331 get_quoted_string, :1644-1680 get_domain, :634-654 LocalPart.local_part, :544-547 AddrSpec.domain. The scan reads each address with it (the CC's ruling allowed importing the stdlib parser), and the tests take it as the oracle.
    • Round 3, every @ is judged by the parser: RFC 5322 (the same file, sha256 cb459acc…): :959-969 addr-spec = local-part "@" domain, domain = dot-atom / domain-literal / obs-domain and the domain literal's grammar; :695 dot-atom = [CFWS] dot-atom-text [CFWS], so comments and white space may stand on either side of the @; :939-940 says they "SHOULD NOT be used" there, which leaves them valid. CPython's parser at the same pin (cbc944f4bc59, sha256 7beea37a…): :83-97 its specials and white space, :1219-1233 get_atext (an atom's text is any character that is neither, letters of any script included), :1277-1300 get_comment, :1302-1313 get_cfws, :1605-1642 get_domain_literal, :1644-1680 get_domain (a domain needs no dot). Measured on 3.13.16, and asserted by the tests: it reads an address at an undotted domain, at a domain of CJK labels, with a comment or white space around the @, at a domain literal and with an address inside its quoted local part, each with no defect.
    • Round 3, a source locator: git/[email protected] (the local upstream mirror at 67ad4214): Documentation/revisions.adoc:14-16, an object name is "the full SHA-1 object name (40-byte hexadecimal string), or a leading substring that is unique within the repository" (sha256 3835ec56…); object-name.h:137 FALLBACK_DEFAULT_ABBREV 7 and object-name.c:857-858, git's own abbreviation is never shorter (sha256 6703e4d1…, 9fcb9e54…); hash.h:201-202, :208, the longest name is SHA-256's 64 hex digits (sha256 d7467a59…). This repository's locator form is repo@pin:path:line (CLAUDE.md:7). A domain without a dot is a top-level domain, and none of the 1,437 in IANA's list (version 2026101200, the same bytes as above) is a run of 7 to 64 hex digits (the longest of hex digits alone has 4), so no address at a delegated domain has a locator's form.
    • Round 3, the scratch identity: this repository, evidence/artifacts/omniroute-post-terminal-drain-20261005/scripts/build-drain.sh.txt:36, the name and address the scratch scripts commit with; a test reads that line. local is no top-level domain of IANA's list.
    • Round 2, .target: IANA, https://data.iana.org/TLD/tlds-alpha-by-domain.txt, version 2026101200 (fetched 2026-10-12, sha256 45d9f126…): TARGET is listed; SERVICE, TIMER, SOCKET, PATH and MOUNT are not.
    • Ruling 1, the host's own name: python/[email protected] Doc/library/socket.rst:988-991: socket.gethostname() returns "the hostname of the machine where the Python interpreter is currently executing" (sha256 fa1ad5f4…; measured equal to uname -n on the CC's host). scripts/host_name_scan.py:65-68 drops the hostname source of validate.py --scan-file when it equals WSL_DISTRO_NAME: "WSL can expose its public distro/project label as the Linux hostname. Exclude that hostname source only; coincident private sources remain." On the CC's host it does (measured 2026-10-12: a body naming the host passed both scans).
    • Isolated mode: python/[email protected] Doc/using/cmdline.rst:308-316: -I "also implies -E, -P and -s" and leaves "neither the script's directory nor the user's site-packages directory" in sys.path. Measured 2026-10-12: python3 -I scripts/validate.py --scan-file exits 2 (host_name_scan is not importable), python3 -E -s -B exits 0, which is why the scripts run it with -E -s -B as merge_validate runs validate.py (sha256 ef999234…).
    • EXIT trap: the bash manual, [email protected] doc/bashref.texi:4777-4778, "If a sigspec is 0 or EXIT, action is executed when the shell exits" (sha256 f3d37d57…, from git.savannah.gnu.org). The manual does not say that a terminating signal counts, so it was measured with bash 5.3.9: SIGTERM and SIGHUP each ran the trap, which removed the file, and the shell then died of the signal. A test repeats it on both scripts.
    • A private file: mktemp creates it with mode 0600; the README's earlier row for uutils/[email protected] and Stebalien/[email protected] (imp/unix.rs:23) is the source.
  • How the sources were read: from local upstream mirrors at the pins, except where noted.

    • The three cli/cli files fetched from raw.githubusercontent.com/cli/cli/v2.102.0/... at 2026-10-12T02:37Z have the mirror's sha256 (ca3849b4…, 17eb5418…, 94076f62…).
    • For the P1 fix the cli/cli mirror is a blobless clone at ec5b5120 with no tags and no fc4b137c, so the same three files were read again through the GitHub contents API at fc4b137cdef0a6bd28fd461b7cf9c84a5812a8cd; their sha256 equal the digests above (follow-up 7). github/docs (be38ec5d), python/cpython (v3.13.16), systemd/systemd (c7a8e871de34) and openai/codex (092d3acd6bec, and the commit db22c91e61) were read from the local mirrors, MicrosoftDocs/WSL through the contents API at a1473a69d10c, and the bash manual from git.savannah.gnu.org at bash-5.3.
    • The docs URLs above answered HTTP 200 at 02:37Z. Their line numbers are those of the github/docs content files at be38ec5d, and the published pages may have changed since.

Evidence-class table

Claim Evidence class Command / receipt
A merge that passes validate.py and fails scripts/final_stack.py --check stops nas_land.sh with 10. The output names the check, nothing is merged and the check's output is not printed. It merged at 86fa384. synthetic EndToEndTests.test_nas_stops_with_10_when_the_merge_passes_validate_py_but_fails_a_currency_check: fails at 86fa384, passes here
The checks nas_land.sh runs are exactly the shard-0 Python --check steps of the merge's validate.yml, in order; its reader gives the eight on this repository's workflow. A landing whose checks pass merges. synthetic test_nas_runs_the_currency_checks_of_validate_ymls_shard_0_in_the_workflows_order, test_nas_runs_each_currency_check_of_the_merges_own_workflow_and_then_lands, test_the_workflow_reader_takes_one_line_and_folded_runs_and_nothing_else (each fails at 37e242c, which held a list)
The provenance section carries a 64-hex digest only in its "Here" column synthetic test_the_provenance_section_carries_a_digest_only_for_the_repository_copies (fails at 86fa384)
The CC's regression for #176 passed on merge_validate up to 37e242c. On round 3's it reports a failure, because its scratch repository holds no validate.yml; a copy whose scratch repository holds one, and which cuts shard0_checks out with merge_validate, passes local_integration the CC's test_merge_validate_currency.sh: exit 0 on 37e242c's nas_land.sh, exit 1 on this one; the adapted copy on this one: exit 0, PASS (2026-10-12)
A SQUASH_BODY_FILE that is missing, empty, a directory, - or unreadable stops both scripts with 2 before any call, printing no path synthetic test_a_squash_body_file_that_is_not_a_readable_non_empty_file_stops_both_scripts_with_2_before_any_call (10 subtests fail at 86fa384)
P1: a body with a home path of any form (Linux, macOS, Windows with either slash, the WSL mount, the WSL UNC forms with one or doubled backslashes, the dash-encoded and graph-id forms, percent-encoded), a name of the names list, an address that is not a no-reply one or a token shape (seven kinds) stops both scripts with exit 2 and one fixed line before any gh or git call; no merge, nothing of the body printed, no snapshot left synthetic EndToEndTests.test_a_squash_body_with_a_home_path_..., ..._with_a_name_of_the_names_file_..., ..._with_an_address_that_is_not_a_no_reply_one_..., ..._with_a_token_shape_... (64 subtests fail at d6be1b0: exit 0 and one merge call)
P1: a missing or failing validate.py, scanner or names file, a scanner that exits 2, prints nothing, another line or a warning count that is not a number, has a syntax error, or refuses, and every answer of validate.py --scan-file but its clean line, refuse the landing (fail closed) synthetic test_a_squash_body_is_not_landed_when_a_scanner_or_the_names_file_is_missing_or_fails (36 subtests fail at d6be1b0)
P1, the valid-body control: a clean body (GitHub's no-reply form, the vendor noreply trailer, a synthetic name inside a longer word, the placeholder account's home path) lands with exit 0 and one merge call; the merge reads the body's bytes, byte for byte, from a mode-0600 snapshot in a TMPDIR whose name has a space, not from the caller's file, both scans having run on that snapshot first; an empty value adds no scan and no --body-file synthetic test_a_squash_body_file_is_passed_to_the_merge_as_one_body_file_argument (replaces the d6be1b0 test of that name; 2 subtests fail at d6be1b0)
P1: a file rewritten after the scan does not reach the merge synthetic test_the_merge_reads_the_scanned_bytes_even_when_the_file_changes_after_the_scan (2 subtests fail at d6be1b0)
P1: the snapshot exists during the run and is gone after exits 0, 3 and 7 and after SIGTERM and SIGHUP (and SIGINT, round 3) synthetic test_the_snapshot_exists_while_the_landing_runs_and_is_removed_wherever_it_stops, test_the_snapshot_is_removed_when_a_signal_ends_the_landing (4 and 4 subtests fail at d6be1b0; with the trap line deleted both fail)
P1: without LANDING_SCANNER and LANDING_NAMES_FILE the scan uses the clone's scripts/validate.py and the names file under the coordination tree, and fails closed when it is absent synthetic test_the_scanner_and_the_names_default_to_the_clone_and_the_coordination_tree (4 failures and 2 errors at d6be1b0)
P1: the real validate.py --scan-file passes the clean body and refuses a body naming the account that runs the tests local_integration test_the_repository_scanner_runs_on_the_snapshot_with_the_hosts_own_sources (2 subtests fail at d6be1b0; skipped where Betterleaks 1.9.0 is not installed, as in CI)
P1: the order (check, snapshot call, lock; the merge line names the snapshot; only the check and the call read the caller's file), and squash_body_scan.py by itself (the names file's formats and that no line of it runs, the address, unit and vendor rules, the host name, a name as a whole token, its one output line) synthetic ScriptTextTests.test_the_squash_body_is_scanned_before_the_lock_and_the_merge_is_given_only_the_snapshot (2 errors at d6be1b0), SquashBodyScanTests (7 tests; the class errors at d6be1b0, the scanner not existing)
Ruling 1: a body that names the host lands with the count printed and the name not; a body that also names another listed name is refused; a list that does not hold the host changes nothing synthetic test_a_squash_body_that_names_this_host_lands_with_a_count_and_the_other_names_still_refuse (4 subtests fail at d6be1b0, 2 on the scan without the allowance); SquashBodyScanTests.test_a_name_equal_to_the_hosts_own_name_is_counted_and_never_refused
Ruling 2: unit instances land; a domain, a type outside the ruling, a local part no unit has, a longer domain and a provider address (the control) are refused synthetic test_a_squash_body_with_a_systemd_unit_instance_lands_and_a_look_alike_does_not (10 subtests fail at d6be1b0, 2 on the scan without the allowance); SquashBodyScanTests.test_systemd_unit_instances_are_not_addresses_and_their_look_alikes_are
Ruling 3: the vendor co-author address lands in any letter case, with the vendor's noreply form; another local part at the vendor's domain, the vendor's local part at another domain, a longer local part and a provider address (the control) are refused synthetic test_a_squash_body_with_a_vendor_co_author_trailer_lands_and_a_provider_address_does_not (8 subtests fail at d6be1b0, 4 on the scan without the allowance); SquashBodyScanTests.test_a_vendor_trailer_address_passes_only_as_the_exact_address
On the CC's host with its real names list: a body naming the host twice is clean with warnings=2 and passes validate.py --scan-file; a body naming the host and the account is refused by both; neither output holds either name local_integration squash_body_scan.py and validate.py --scan-file run by hand on two bodies built from hostname and the account, 2026-10-12
The scan on main's last 600 commit messages at 3a8a846: 8 refused (0 names, 5 addresses, 3 home paths); 26 messages (66 occurrences) name the host (a warning); 2 carry a unit instance, 1 the vendor co-author address and 402 the vendor noreply trailer, all passing. Before the three rulings: 37 refused (26 names, 8 addresses, 3 home paths). The 5 addresses: 3 at a mail provider, 2 at a reserved test domain measured a script over git log -600, counts only (follow-up 5)
The eight checks exit 0 on main at 86fa384 in about 8 s (6.3 s of it build_ecosystem.py) local_integration each check run as merge_validate runs it, python3 -E -s -B <script> ... --check, at 2026-10-12T02:18Z
The trading repository needs no merge check (strict up-to-date rule), and both squash defaults are COMMIT_MESSAGES source_review read-only gh api reads of the rules and the repositories at 2026-10-12T02:23:46Z; ci.yml at 0e987311
Round 2, P1-a: a quoted local part at a mail provider (alone, with a space, a quoted pair or nothing in it, in a trailer, in a code span, after an atom and a dot, percent-encoded) stops both scripts with exit 2 and the fixed line before any gh or git call, no snapshot left, with the canned and with the real validate.py --scan-file synthetic EndToEndTests.test_a_quoted_local_part_is_refused_by_both_scripts_as_its_unquoted_form_is (28 of its 32 subtests fail at e203d01 with exit 0 and a merge; the percent-encoded form's raw text was refused there)
Round 2, P1-b: the vendor's local part behind + or ! (in its trailer, in prose, in a code span, quoted) or behind a backtick that does not close, and noreply or no-reply behind + or !, stop both scripts with exit 2 synthetic test_a_vendor_or_no_reply_local_part_behind_a_prefix_is_refused_by_both_scripts (32 subtests fail at e203d01)
Round 2, P1-c: a provider address before each of the six unit types (also in a code span, with more after its domain, quoted), an address at .target and a target instance stop both scripts with exit 2 synthetic test_an_address_before_a_unit_type_and_an_address_at_target_are_refused_by_both_scripts (44 subtests fail at e203d01); the target look-alike in test_a_squash_body_with_a_systemd_unit_instance_lands_and_a_look_alike_does_not (2)
Round 2, the controls: the exact vendor trailer, the vendor's noreply trailer, GitHub's two no-reply forms, a no-reply local part, two real unit instances and markup that wraps an allowed address land (exit 0, one merge call, no snapshot left) in both scripts and both scan modes synthetic test_the_vendor_trailer_the_no_reply_forms_and_unit_instances_still_land_through_both_scripts (passes at e203d01 and here: a control)
Round 2, the oracle: 24 local parts at 17 domains in nine forms (3,672 cases): the scan refuses exactly the addresses that the allowances do not pass on CPython's reading of them; the unit tests of the address, unit and vendor rules synthetic SquashBodyScanTests.test_each_address_is_judged_as_the_rfc_5322_oracle_reads_it_and_markup_counts_only_when_it_wraps_it (2,544 cases fail at e203d01), test_the_address_rule_passes_no_reply_addresses_and_refuses_every_other (12), test_systemd_unit_instances_are_not_addresses_and_their_look_alikes_are (13), test_a_vendor_trailer_address_passes_only_as_the_exact_address (10)
Round 2: through both scripts and both real scanners (Betterleaks at the pin), a quoted provider address, +codex and !codex at the vendor's domain, a provider address before .service and an address at .target landed at e203d01 (exit 0, one merge call) and stop at 37e242c0 (exit 2, no merge, no snapshot left) local_integration the PR's harness with FAKE_VALIDATE_SCAN_PYTHON, five probes on each script, 2026-10-12
Round 2: the oracle's answers on every text the tests give it are the same on CPython 3.12.3, 3.13.16 and 3.14.4, and the 14 tests of the squash body scan pass on each local_integration the texts' readings hashed under each interpreter (one digest), and the 14 tests run under each, 2026-10-12
Round 2: the 600-message figure is unchanged measured the measurement script of the CC's Claude read, run with each scanner at 3a8a846 and with round 2's at bb945f1, counts only
Round 3: an address inside an allowed one's quoted local part, or directly after an allowed one, stops both scripts with exit 2 and the fixed line before any gh or git call, no snapshot left, with the canned and with the real validate.py --scan-file synthetic test_an_address_in_a_quoted_local_part_or_glued_to_an_allowed_one_is_refused_by_both_scripts (52 subtests fail at 37e242c: each landed)
Round 3: an address at a domain without a dot, at a domain of CJK labels, with a comment or white space around the @, at a domain literal, and a quoted local part over a line end stop both scripts with exit 2 synthetic test_an_address_at_any_domain_or_with_comments_or_white_space_around_its_at_is_refused_by_both_scripts (28 subtests fail at 37e242c: each landed)
Round 3, the ruling's allowances: source locators (bare, with a path, in a code span) and the scratch co-author trailer land; a tag or a branch after the @, six hex digits, an object name inside a longer domain, and another local part or a longer domain beside the scratch identity's stop both scripts with exit 2 synthetic test_a_source_locator_and_the_scratch_identity_land_and_their_look_alikes_are_refused_by_both_scripts (20 subtests fail at 37e242c), SquashBodyScanTests.test_a_source_locator_and_the_scratch_identity_pass_only_in_their_whole_forms (an error at 37e242c, which has no such table; it reads the cited line of the scratch script)
Round 3, the controls: an @ with no local part, a mention and a decorator in code spans, a template unit, a quoted no-reply address and one in parentheses, and a body with CRLF line ends land in both scripts and both scan modes synthetic test_an_at_with_no_address_and_the_allowed_forms_of_round_3_still_land_through_both_scripts (passes at 37e242c too: a control)
Round 3, the oracle: 29 local parts at 29 domains in nine forms (7,569 cases): the scan refuses exactly the addresses that the allowances do not pass on CPython's reading of them; each @ is judged, also inside a quoted string synthetic SquashBodyScanTests.test_each_address_is_judged_as_the_rfc_5322_oracle_reads_it_and_markup_counts_only_when_it_wraps_it (2,100 subtests fail at 37e242c), test_every_at_is_judged_and_an_allowance_passes_only_a_whole_address_that_holds_no_other (12), test_the_address_rule_passes_no_reply_addresses_and_refuses_every_other (3)
Round 3: a body whose only hit is the host's own name lands through the real second scan with the warning on a host that is not WSL, and is refused when the git email's local part has the host's spelling local_integration test_a_body_whose_only_hit_is_the_hosts_name_lands_through_the_real_second_scan_on_any_host (2 subtests fail at 37e242c; skipped where Betterleaks 1.9.0 is not installed, as in CI), tests.test_host_name_scan test_a_public_hostname_is_excluded_on_any_host_only_from_the_hostname_source (fails at 37e242c)
Round 3: a names file that a shell would read otherwise stops both scripts as unscannable; the documented forms are read as before synthetic test_a_names_file_that_a_shell_would_read_otherwise_stops_both_scripts_before_any_call (12 subtests fail at 37e242c: each landed), SquashBodyScanTests.test_the_names_file_is_parsed_and_never_executed (9)
Round 3, nas:430: a failing check that the merge's validate.yml adds stops nas_land.sh with 10; a step whose arguments the merge changes runs as the merge writes it; a validate.yml in which no check can be read, or one of whose steps is not plain words (eight kinds), stops it with 10 before any check runs, the step's text not printed synthetic test_nas_validates_a_merge_with_the_checks_that_its_own_workflow_adds_or_changes (fails at 37e242c: it landed), test_nas_stops_with_10_when_it_cannot_read_or_run_the_merges_currency_checks_as_written (9 subtests fail at 37e242c)
Round 3: the snapshot is gone after SIGINT as after SIGTERM and SIGHUP; SIGKILL leaves it, mode 0600 synthetic, measured test_the_snapshot_is_removed_when_a_signal_ends_the_landing (now with SIGINT; passes at 37e242c too); both scripts signalled by hand through the harness, 2026-10-12
Round 3: the scan's cost is linear: 15 KB on one line at most 0.05 s, 60 KB at most 0.18 s; round 2's rule 1.5 s and 24 s on one of the texts measured the scan timed on fourteen repeated texts at both sizes, three runs, and 37e242c's scanner on one, 2026-10-12
Round 3: the 600-message figure: 70 refused (0 names, 67 addresses, 3 home paths) at 5421e5d; round 2's rule 8 there measured the measurement script of the CC's Claude read at e203d01, run with each scanner, and the refused and passed kinds counted with the scanner's own functions, counts only
Round 3: the 19 tests pass on CPython 3.12.3, 3.13.16 and 3.14.4 local_integration the 19 run under each interpreter, 2026-10-12

Local commands run

$ python3 -E -s -B -m unittest -v <the 15 new or changed test functions and SquashBodyScanTests>   # this test file on d6be1b02's tools/landing (a worktree)
Ran 15 tests in 52.2s
FAILED (failures=140, errors=5)                                 (exit 1: every new test fails before the fix; the 7 tests of
                                                                 SquashBodyScanTests are one setUpClass error, the scanner not existing)
$ the same command on the fix commit
Ran 22 tests in 22.6s
OK                                                              (exit 0)
$ python3 -E -s -B -m unittest tests.test_landing_scripts -v   # jq 1.7.1 first on PATH (CI's), LANDING_PROHIBITED_NAMES set (3 names)
Ran 135 tests in 93.6s
OK                                                              (exit 0)
$ python3 -E -s -B -m unittest tests.test_landing_scripts -v   # the host's jq 1.8.1, LANDING_PROHIBITED_NAMES set
Ran 135 tests in 99.5s
OK                                                              (exit 0)
$ python3 scripts/evidence_manifest.py --check                  # after host_receipts.register_file of the five changed files
{"files": 11690, "status": "passed"}                            (exit 0)
$ python3 scripts/validate.py
{"components": 70, "hashed_files": 11690, "profiles": 4, "receipts": 239, "status": "passed"}   (exit 0)
$ python3 -E -s -B tools/landing/squash_body_scan.py <the commit message> scripts/validate.py <the names file>; validate.py --scan-file <the commit message>
squash body scan: clean (names_checked=3); {"matching_locations": 0, "scanned_files": 1, "source": "host", "status": "passed"}   (exit 0 each)
$ privacy scan of the diff, the commit message and this body (the CC's names list, emails, home paths; counts only; the positive control is detected)
names-with-hits=0 other-emails=0 home-paths=0 names_checked=3     (CLEAN)
$ bash test_merge_validate_currency.sh tools/landing/nas_land.sh   # the CC's regression for #176, on the fix commit's nas_land.sh
PASS: merge_validate stopped the landing (rc 1): #1 the currency check scripts/final_stack.py --check on the merge ...   (exit 0)
$ gitleaks git --log-opts=d6be1b02..HEAD                        # and the pre-commit hook's staged scan
1 commits scanned. no leaks found
$ the pre-push hook's three checks, by hand on the fix commit: host-name scan of the tracked tree and the history range, the registry tests, the published-digest guard
{"matching_locations": 0, "scanned_files": 12493, "source": "host", "status": "passed"}; Ran 3 tests OK; Ran 1 test OK   (exit 0 each)

Round 2 (commit 37e242c0, 2026-10-12):

$ python3 -B -m unittest <SquashBodyScanTests and the six end-to-end tests of the unit, vendor and round 2 cases>   # this test file on a git archive of e203d014
Ran 14 tests in 89.8s
FAILED (failures=2685)                                          (exit 1: 8 tests fail, every new or changed one but the controls';
                                                                 106 of the cases are landings, 52 in each scan mode and 2 more)
$ the same command at 37e242c0
Ran 14 tests in 36.0s
OK                                                              (exit 0)
$ the same 14 tests under CPython 3.12.3 and under 3.14.4, at 37e242c0
Ran 14 tests in 32.7s / 32.4s, OK                               (exit 0 each)
$ python3 -B -m unittest tests.test_landing_scripts             # LANDING_PROHIBITED_NAMES exported inside a runner that sources the CC's names file (3 names)
Ran 140 tests in 116.9s
OK                                                              (exit 0)
$ python3 scripts/validate.py
{"components": 70, "hashed_files": 11690, "profiles": 4, "receipts": 239, "status": "passed"}   (exit 0)
$ python3 scripts/evidence_manifest.py --check                  # after the three changed files were re-registered (sha256 and bytes)
{"files": 11690, "status": "passed"}                            (exit 0)
$ gitleaks git --log-opts=e203d014..37e242c0                    # gitleaks 8.30.1, and the pre-commit hook's staged scan
1 commits scanned. no leaks found                               (exit 0)
$ git merge-tree --write-tree origin/main 37e242c0              # origin/main at bb945f1cf9cb, the remote's main
1b079cce24b52771e1c58ddcae1d8ded94767d57                        (exit 0, clean; validate.py and evidence_manifest.py --check on that tree: passed, 11757 files)
$ privacy_scan.sh <the commit's added lines> <the commit message> <this body>   # the CC's scan: names, emails, home paths, tokens; counts only
clean (names_checked=3) on each                                 (exit 0; the -U0 diff counts 12 addresses, every one in a removed line of e203d014's text)
$ python3 -E -s -B tools/landing/squash_body_scan.py <the commit message> scripts/validate.py <the names file>; validate.py --scan-file <the commit message>
squash body scan: clean (names_checked=3); {"matching_locations": 0, "scanned_files": 1, "source": "host", "status": "passed"}   (exit 0 each)

Round 3 (commit cb0429d7 on 37e242c0, 2026-10-12):

$ python3 -B -m unittest <the 19 new or changed tests> tests.test_landing_scripts tests.test_host_name_scan   # this round's two test files on a git archive of 37e242c0
Ran 19 tests in 106.5s
FAILED (failures=2254, errors=1)                                (exit 1: 16 tests fail; the controls' test, the signal test and #176's own pass)
$ the same command at the fix
Ran 19 tests in 40.7s
OK                                                              (exit 0)
$ the same 19 tests under CPython 3.12.3 and under 3.14.4, at the fix
Ran 19 tests in 44.5s / 41.4s, OK                               (exit 0 each)
$ python3 -B -m unittest tests.test_landing_scripts             # LANDING_PROHIBITED_NAMES exported inside a runner that sources the CC's names file (3 names)
Ran 150 tests in 187.4s
OK                                                              (exit 0; no /var/tmp/nas-land-* left)
$ python3 -B -m unittest tests.test_host_name_scan
Ran 39 tests in 62.6s
OK                                                              (exit 0)
$ python3 -B -m unittest tests.test_published_digest_privacy tests.test_pre_push_gate tests.test_final_stack   # the other modules that read the changed files
Ran 116 tests in 1547.4s
OK (skipped=1)                                                  (exit 0)
$ python3 scripts/validate.py
{"components": 70, "hashed_files": 11690, "profiles": 4, "receipts": 239, "status": "passed"}   (exit 0)
$ python3 scripts/evidence_manifest.py --check                  # after the eight changed files were re-registered (sha256 and bytes)
{"files": 11690, "status": "passed"}                            (exit 0)
$ the Codex thread on nas:430 through the harness: a merge whose validate.yml adds a shard-0 --check step that fails
at 37e242c0: exit 0, one merge call, the added check not run; at the fix: exit 10, no merge call, the added check run
$ bash test_merge_validate_currency.sh tools/landing/nas_land.sh   # the CC's regression for #176, unchanged
FAIL: merge_validate returned rc 0 ...                          (exit 1: its scratch repository holds no validate.yml; exit 0, PASS, at 37e242c0)
$ the same regression with a validate.yml in its scratch repository and shard0_checks cut out with merge_validate
PASS: merge_validate stopped the landing (rc 1): #1 the currency check scripts/final_stack.py --check on the merge ...   (exit 0)
$ each script signalled during a landing with a squash body, through the harness: INT, TERM, HUP, KILL
INT, TERM, HUP: no snapshot left; KILL: one snapshot left, mode 0600   (both scripts)
$ gitleaks git --log-opts=37e242c0..cb0429d7                    # gitleaks 8.30.1
1 commits scanned. no leaks found                               (exit 0)
$ git merge-tree --write-tree origin/main cb0429d7              # origin/main at d8f7e2051b61, the remote's main
6b39558e56e944c7792072d03ba34da1663f9dc4                        (exit 0, clean; on that tree validate.py and evidence_manifest.py --check passed,
                                                                 11796 files, and tests.test_landing_scripts ran 150 tests, OK)
$ privacy_scan.sh <the commit's added lines> <the commit message> <this body>   # the CC's scan: names, emails, home paths, tokens; counts only
clean (names_checked=3) on each                                 (exit 0)
$ python3 -E -s -B tools/landing/squash_body_scan.py <the commit message> scripts/validate.py <the names file>; validate.py --scan-file <the commit message>
squash body scan: clean (names_checked=3); {"matching_locations": 0, "scanned_files": 1, "source": "host", "status": "passed"}   (exit 0 each)

Decision record

No new record. Round 3 adds one sentence to docs/decisions/2026-10-09-host-name-scan.md, on the hostname opt-in that the landing scripts set for their second scan. The change carries CC correction #176 (the CC's corrections log), the CC's SQUASH_BODY_FILE patch and the CC's ruling of 2026-10-12 (the ledger check; README digest cells withheld, CC #161). The P1 fix carries Astra's finding at d6be1b0 and the CC's three rulings of 2026-10-12 on its scan (the host's own name, systemd unit instances, vendor co-author trailers). tools/landing/README.md ("The currency checks", "The squash body", "Provenance and digests") records the evidence and the port's differences from the live copies. A merge queue on an organization-owned repository would replace the merge check. Round 2 carries the CC's adjudication at e203d01 (P1-a, P1-b, P1-c, B2, B3, the tests, the follow-ups, rule 4's oracle). Round 3 carries the two reads at 37e242c, the Codex connector's three threads and the CC's rulings of 2026-10-12 on the two allowances and on the host-name fix (Round 3, above).

Host evidence

Not applicable: no file under evidence/hosts/ changes.

Checklist

  • New/changed GitHub Actions are pinned to a full commit SHA with a
    version comment (no floating tags). (none changed)
  • New/changed workflows declare top-level permissions: {} and grant each job
    only what it needs (contents: read, or an explicitly justified addition). (none changed)
  • No secrets are printed, logged or committed; no new required secret was
    added without a documented owner.
  • No new paid hosting, subscription or billing surface was introduced.
  • Peer-owned untracked files and worktrees were preserved (not deleted,
    moved or overwritten).

Follow-ups

  1. Only shard 0's Python --check steps run on the merge (README, "Known gaps"). The shard's validators (validate_catalogs.py, validate_convergence.py and others) and its checks that are not one Python command (the example workflows' sha256sum --check, the contract suites, zizmor and actionlint) do not. Since round 3 the steps are read from the merge's validate.yml in the one form this repository writes them; a --check step written another way (a literal block, a pipe, another spelling of the condition, a step with no condition) is not read, and the steps and scripts the landing runs are the merge's own (the sandboxing follow-up).
  2. Deployment: after the reads of both families pass and this PR lands, the CC syncs the live cc-tools copies from the merged repository copies, the three host paths filled in (README, "Provenance and digests"), and installs squash_body_scan.py beside them, as with tools(landing): move the CC's landing scripts into the repository, with offline tests #975. The scan finds scripts/validate.py in the clone LANDING_NAS_REPO names (the CC's checkout by default, for both scripts) and the names list at its default path under the coordination tree, so no further host path is needed. Until then the CC scans each squash body by hand. A copy without the scanner stops every landing that sets SQUASH_BODY_FILE with exit 2 (fail closed).
  3. The scan's limits (README, "Known gaps"): it decodes percent-escapes and not hex, base64, \u, HTML entities or doubly encoded text; it finds a WSL UNC home path and no other UNC share; the names file is parsed in Python and not sourced (a line of it never runs), and only its last LANDING_PROHIBITED_NAMES assignment counts. validate.py --scan-file runs only where Betterleaks at host_name_scan.py's pin is installed and, on WSL, powershell.exe answers: elsewhere, and in CI, a landing with SQUASH_BODY_FILE exits 2 and the test of the real scan skips. Since round 3 its hostname source is dropped on any host, and a names file in another form than the documented ones stops the landing. NATIVE_AGENT_HOST_NAMES_JSON in the CC's shell makes validate.py report synthetic sources, which the scripts refuse.
  4. Refuse email addresses in the publication scan #1002's email registry replaces the short vendor co-author list in squash_body_scan.py (VENDOR_TRAILER_ADDRESSES) when Refuse email addresses in the publication scan #1002 lands.
  5. History residual: the 3 messages with a home path and the 3 with an address at a mail provider among main's last 600 commit messages (5 and 4 in the whole history at the base) already sit in main's commit history. It is immutable, as for CC correction Linux/WSL2 bootstrap keeps a newer native Claude Code: the pin is a floor (stacked on #159) #177, and this change rewrites none of it. Check whether any of them is identity-bearing.
  6. Unify the detection of the squash body, the PR body (Scan the pull request description for home paths and credentials #991's normalize-then-scan) and email addresses (Refuse email addresses in the publication scan #1002) into one shared module (CC rule 4).
  7. The cli/cli mirror is a blobless clone at ec5b5120 that did not hold fc4b137c when the files were read (a later reader's lazy fetch, at 07:57:07Z, added that commit's objects); the contents-API read above, with its matching sha256, stands as the record. A sibling mirror, cli/cli-2.102.0, is checked out at the pin (since 2026-10-11T13:59:41Z) and holds the same bytes. Make the mirror the README rows name carry the pin (CC rule 9). README:616 (tools(landing): move the CC's landing scripts into the repository, with offline tests #975's row, already on main) says "the local upstream mirror at fc4b137c" too; that sibling holds its three digests, so the phrase may be accurate there, and the record should name the mirror.
  8. A merge queue would close the Generate the canonical final-stack manifest (W4 PR 2) #1007/Move the claude-native-practice skill row to the commit that holds #1001, #1005 and #986 #1018 class on GitHub's side once the repository is organization-owned.
  9. Astra's P3 1 at e203d01: unit names with a directory prefix (getty.target.wants/ before an instance, from systemd.unit.xml) are refused, since / is atext; decide whether A2 should cover them (a conservative refusal, not a bypass).
  10. Astra's P3 2: the source and measurement captures are incomplete (the WSL files, the Bash manual, the mktemp sources, the rules API responses, the trading CI file, the page captures, the historical measurement); keep them as receipts.
  11. Astra's P3 3: manifests/evidence.json holds 20 inherited occurrences of the host's name on 18 lines outside this PR's edits (hygiene, by the CC's 10-11 ruling).
  12. Astra's P3 4: the archive and sandbox limits of a blanket test pass (the hardcoded /var/tmp/nas-land-* worktree template).
  13. Claude's P3-2 at e203d01 and the GPT family's follow-up 3 at 37e242c, done in round 3: the README names the signals after which the snapshot is removed (SIGINT, SIGTERM, SIGHUP; each tested) and says that SIGKILL leaves it and how to remove it. A cleanup of stale snapshots by the scripts themselves is not built.
  14. Claude's other P3s at e203d01: P3-1 (the names file) and P3-7 (the host name against the real validate.py) are done in round 3. Open: P3-3, "before any of the landing's own gh or git calls" (validate.py --scan-file runs git config); P3-4, a crashing validate.py --scan-file is reported as a refusal; P3-5, load validate.py at a pinned revision; P3-6, the README's "every shard-0 step that runs a Python script with --check" (the reader takes one-line and folded runs that end in --check).
  15. Round 2's declared limits of the address rule are closed in round 3 (comments and white space around the @, a domain literal, a quoted local part over a line end, the scan's cost). What round 3 declares instead (README, "Known gaps"): the rule does not join lines, and it refuses some text that names no one, which a body writes another way: a word, white space and an @, a tag or a branch after an @, a placeholder such as <repo>@pin, an address at localhost, a URL whose path holds an @, and a code span that holds more than the @-name. For the shared module of follow-up 6.
  16. The decision point of P1-a (Round 2, above): a quoted form of an allowed address passes, as its unquoted form does; the readers may rule that every quoted local part is refused.
  17. Round 3, deployment: the CC's test_merge_validate_currency.sh needs a validate.yml in its scratch repository and shard0_checks cut out with merge_validate (Round 3, above); the live copies need squash_body_scan.py beside them, as before, and a checkout whose scripts/host_name_scan.py has the opt-in (until then the second scan refuses the host's name where the hostname is not WSL_DISTRO_NAME, as it did).
  18. Round 3, the GPT family's follow-ups at 37e242c that stay open: 1 (unit names with a directory prefix are refused; this is follow-up 9), 4 (this is follow-up 14's open part), 5 (source and measurement captures; follow-up 10), 6 (inherited host-name rows of the manifest; follow-up 11), 7 (archive and sandbox limits; follow-up 12) and 8 (no test fails on the old prose of the two provenance corrections).
  19. Round 3, a tag or a branch after an @ is refused, since nothing tells such a revision from a host name. If squash bodies need <repo>@<tag>, that is a ruling for the shared module of follow-up 6 (31 of the last 600 messages hold one).

🤖 Generated with Claude Code

…176) and take a squash body file

The CC patched its live copies of the landing scripts twice on 2026-10-12. This ports both patches into tools/landing,
with tests that fail at 86fa384:

- nas_land.sh, CC correction #176: #1007 bound a file's sha256 in final-stack.json and #1018 changed that file. Each
  was green on its own base, and validate.py passed on the merge, so #1018 landed and main's validate-shard-0 failed on
  scripts/final_stack.py --check. After validate.py, merge_validate now runs every shard-0 step of validate.yml that
  runs a Python script with --check, as the step runs it and in the workflow's order: audit_reports, build_verdicts,
  component_matrix, new_host_grand_list, final_stack, gap_crosswalk build, gap_wave_ledger (its --wave and --owner
  arguments) and build_ecosystem. #176 named seven; the CC's ruling of 2026-10-12 added the ledger check. Each check
  runs only when its script is in the merge. The first that fails is exit 10, named by its command. Its output stays
  in the validation's 0600 file and is not printed (the live copy prints its last 300 bytes, which #975 P2-C removed
  for validate.py). On main at 86fa384 the eight exit 0 in about 8 s.
- both scripts, SQUASH_BODY_FILE: both repositories' squash default is COMMIT_MESSAGES, so a commit message whose
  claim was corrected after review landed in main. When the variable is set, the merge passes the file with
  gh pr merge --body-file. A value that is not a readable, non-empty regular file stops with exit 2 before the lock
  and any call. That includes "-", which gh reads as standard input. The check is the group's first statement after
  the arguments; the live copies put it after set -u and before the group, which this copy parses whole.
- README digest cells withheld (CC #161): the provenance table keeps the line counts of the live copies and the
  digests of the repository copies only.

uet_land.sh needs no currency step: the trading repository's main rules count ci-gate only on a head that is up to
date with main (strict), so its CI ran on the tree the squash merge makes. This repository's rules are not strict.

Tests:
- merge_validate's checks equal validate.yml's shard-0 Python --check steps, in order, the folded run: >- one
  included. The step reader is also run on a synthetic workflow.
- The provenance section carries a 64-hex digest only in its "Here" column.
- A merge that fails final_stack.py --check stops with 10. It merged at 86fa384.
- A check runs only when its script is in the merge.
- A missing, empty, directory, "-" or unreadable SQUASH_BODY_FILE stops both scripts with 2 before any call.
- A body file whose path has a space reaches the merge as one --body-file argument.

The fake python3 answers currency checks itself, so they never take one of the gate's answers. The CC's own
regression, test_merge_validate_currency.sh, passes on this merge_validate and fails on 86fa384's.

The README records the checks, the body file, the exit codes, the variable, the port's three differences from the
live copies, the sources (cli/cli v2.102.0, the GraphQL schema, the REST description and GitHub Docs) and the new
digests of the repository copies.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@seathatflowsinourveins seathatflowsinourveins added the lane:shared Touches files owned by both lanes; needs both lanes' acknowledgement label Oct 12, 2026
…e scanned snapshot (#1027 P1)

Astra's P1 at d6be1b0 (CHANGES_REQUESTED, reproduced on this PR's own EndToEndTests harness): nas_land.sh and uet_land.sh checked that
SQUASH_BODY_FILE was a readable, non-empty regular file and nothing more, so a body holding a home path, an account name, an address that
is not a no-reply one or a token shape went into main's permanent history through gh pr merge --body-file (her four synthetic payloads
each gave exit 0 and one merge call). gh reads the file when the merge call starts (cli/cli v2.102.0 pkg/cmd/pr/merge/merge.go:146-153;
:292-293 and http.go:72-75 send it as CommitBody; pkg/cmdutil/file_input.go:8-16), up to an hour or more after any check, so the scanned
bytes must also be the bytes gh reads.

When SQUASH_BODY_FILE is set, both scripts now, before the lock and every gh and git call:
- copy the file once to a snapshot (mktemp in TMPDIR, mode 0600; an EXIT trap removes it on every exit, SIGTERM and SIGHUP included);
- scan the snapshot with the new tools/landing/squash_body_scan.py (the repository's PRIVATE_CONTENT table from scripts/validate.py, a WSL
  UNC home path that table misses, an address that is not a no-reply one, and the names of the CC's landing-prohibited-names list; the
  list is parsed, never sourced) and with scripts/validate.py --scan-file (the scan the pre-push hook runs);
- stop with exit 2 and one fixed line on a match, a copy or scan that fails, a scanner or names file that is missing or unreadable, and any
  answer that is not a scan's own clean line (fail closed); nothing of the body, no path and no scanner output is printed;
- give gh the same snapshot, never the caller's file.
New variables: LANDING_BODY_SCAN, LANDING_SCANNER (default: scripts/validate.py of LANDING_NAS_REPO, which also fits the CC's live copies)
and LANDING_NAMES_FILE (default: the file under the coordination tree).

Three allowances, the CC's rulings of 2026-10-12, each with its tests:
- a names-list entry equal to the running host's own name (compared with hostname when the scan runs, never printed) is a warning count,
  not a refusal; every other name still refuses;
- a systemd unit instance, <name>@<instance>.service|timer|socket|target|path|mount (systemd/systemd man/systemd.unit.xml:121-135), is
  not an address;
- a short list of vendor co-author trailer addresses, each with the vendor source it comes from, passes: [email protected], as the
  vendor's own repository carries it (openai/codex@db22c91, message line 38). #1002's email registry
  replaces the list. A real-provider address is still refused (the control).

Tests (22 new or changed; at d6be1b0 they give 140 failures and 5 errors, here they pass; the allowance tests also fail on the scan
without the allowance):
- a body with a home path of each form (Linux, macOS, Windows with either slash, the WSL mount, the WSL UNC forms with one or doubled
  backslashes, the dash-encoded and graph-id forms, percent-encoded), a name of a synthetic names file, an address that is not a no-reply
  one (with look-alikes) or a token shape (seven kinds) is refused by both scripts with exit 2 before any call;
- a missing or failing scanner, names file or validate.py, a scanner that prints nothing or another line, and every answer of
  validate.py --scan-file but its clean one refuse the landing;
- the valid-body control lands (exit 0, one merge call) with the body's bytes read from a mode-0600 snapshot, after both scans ran on it;
- a file rewritten after the scan does not reach the merge; the snapshot exists during the run and is gone after exits 0, 3 and 7 and
  after SIGTERM and SIGHUP; the defaults of the new variables; the real validate.py --scan-file where Betterleaks is installed;
- the allowances: a body naming the host lands with the count printed and the name not, and another listed name still refuses; unit
  instances land, their look-alikes and a provider address do not; the vendor address lands, another local part at the vendor's domain,
  the vendor's local part at another domain and a provider address do not;
- squash_body_scan.py by itself: the names file's formats and that no line of it runs, the address, unit and vendor rules, the host name,
  a name as a whole token, and its one output line.

Measured on the last 600 commit messages of main at 3a8a846 (counts only): 8 refused: 0 names, 5 addresses, 3 home paths; 26
messages name the host (a warning); 402 carry the vendor noreply trailer, which passes. main's history keeps 3 messages with a home path and
3 with an address at a mail provider; history is immutable, as for CC correction #177, and nothing here rewrites it.

The README records the scan, the variables, the exit-2 cases, the known gaps and the sources: cli/cli v2.102.0, MicrosoftDocs/WSL,
github/docs, systemd/systemd, openai/codex, the bash manual, CPython's -I and socket. The README digests and manifests/evidence.json
follow the changed files.

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
@seathatflowsinourveins

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 12, 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-12T15:29:45.338681Z cb0429d Manual request
ℹ️ 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: e203d014b4

ℹ️ 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/landing/nas_land.sh Resolved
Comment thread tools/landing/squash_body_scan.py Resolved
Comment thread tools/landing/nas_land.sh Resolved
…er does, and keep no target units (#1027 round 2)

Round 2 of 2 of #1027, under the CC's adjudication at e203d01 (2026-10-12T09:03:43Z): both families landed an address
through both real scanners at e203d01.

- P1-a (Astra 1): a quoted local part, "x"@<provider>, matched no address shape. The shape's local part now holds quoted
  strings too, and squash_body_scan.py reads each address with CPython's RFC 5322 parser (email._header_value_parser
  get_addr_spec, Lib/email/_header_value_parser.py:1682-1696 at v3.13.16, cbc944f4bc59): quotes and quoted pairs are
  undone, so a quoted form is refused or passed as its unquoted form is (RFC 5322 3.2.4, rfc5322.txt:746-757).
- P1-b (Astra 2): the vendor allowance stripped every leading non-word character, so +codex at the vendor's domain was
  compared as the vendor's address. The allowances now compare the whole address, local part and domain as the parser
  reads them; backticks, asterisks and quotes are outside an address only when they wrap it, and an address the parser
  reads with a defect passes no allowance.
- P1-c (Claude B1): <local>@<provider>.com followed by a unit type had a unit instance's shape, for all six types. A unit
  is kept only when its instance is not an address's domain, and target is no longer a kept type: .target is a delegated
  top-level domain (IANA tlds-alpha-by-domain.txt, version 2026101200).
- B2: the README's paragraph on the live copies is in the past tense and records the CC's sync of the live cc-tools
  copies to d6be1b0's scripts at 2026-10-12T03:15:27Z; the CC syncs them again after #1027 lands (ruling C).
- B3: the README's cli/cli provenance names the contents API at fc4b137c, with the sha256 values matching; the local
  mirror, a blobless clone at ec5b5120, did not hold that commit.

Tests: through both scripts, once with the canned validate.py --scan-file answer and once with the real scan where
Betterleaks is at its pin, the quoted, prefixed and unit-suffixed addresses, an address at .target and a target
instance are refused (exit 2, no gh or git call, no snapshot left), and the controls land (the exact vendor trailer,
the no-reply forms, real unit instances, markup that wraps an allowed address). The oracle is the installed CPython
parser; its answers on every text the tests give it are the same on CPython 3.12.3, 3.13.16 and 3.14.4. One test runs
24 local parts at 17 domains in nine forms (3,672 cases) against the allowances applied to the oracle's reading. At
e203d01 the 14 tests of the squash body scan gave 2,685 failing cases in 8 tests, 106 of them landings; here they pass.
The 600-message figure at 3a8a846 is unchanged: 8 refused (0 names, 5 addresses, 3 home paths). The README's
sources, known gaps and tests sections and manifests/evidence.json follow the changed files.

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

Copy link
Copy Markdown
Collaborator Author

@codex review

@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.

… parser; currency checks from the merge (#1027 round 3)

Round 3 of #1027, one commit on 37e242c. Its inputs hold the reproductions, which are not repeated here: the CC's Claude
micro at 37e242c (W1, W2, C1, P3-A to P3-C), the GPT family's fix3 verdict at 37e242c (blockers 1 to 3, follow-ups 2
and 3), the Codex connector's three threads on e203d01 (nas:430, nas:259, the address rule) and the CC's rulings of
2026-10-12 on the allowances and on the host-name fix. Each change is stated by what it guarantees.

- No address passes for want of a pattern that finds it. squash_body_scan.py no longer searches for an address shape: on
  each line it judges every at sign with CPython's get_addr_spec (Lib/email/_header_value_parser.py at v3.13.16,
  cbc944f4bc59), reading the local part before it and the domain after it as the parser does, with quoted strings,
  comments and white space around the at sign, domain literals and domains of any form (RFC 5322 3.4.1,
  rfc5322.txt:959-969). An at sign inside a quoted string is judged inside it too. One with no local part before it or
  no domain after it is no address, and text the parser cannot read whole and without a defect is refused.
- An allowance passes only a whole address that holds no other address and that no other touches.
- By the CC's ruling, two shapes are not addresses: a source locator, a repository path, an at sign and a git object
  name of 7 to 64 hex digits as the whole domain (git v2.53.0 Documentation/revisions.adoc:14-16, object-name.h:137,
  hash.h:201-208; this repository's locator form, CLAUDE.md:7), and the one co-author address of this repository's
  synthetic scratch identity, cited to its source in the repository. A tag, a branch and every other domain without a
  dot stay refused.
- A body whose only hit is the host's own name lands with the warning on any host, and an identity spelled as the host
  is still refused: the scripts run validate.py --scan-file with NATIVE_AGENT_PUBLIC_HOSTNAME=1, a new opt-in of
  scripts/host_name_scan.py that drops the hostname source, as that file does on a WSL host whose hostname is its
  WSL_DISTRO_NAME, and a Windows computer name of the same spelling. Nothing else sets it.
- No listed identity goes unchecked for text that a shell and the scan would read differently: the names file's value
  is read only as a bare list or a list in one pair of quotes, and any other form fails closed.
- A merge is validated with the shard-0 checks that main's CI will run on it: nas_land.sh holds no list any more and
  reads the steps from the merge's own .github/workflows/validate.yml, in the workflow's order (GitHub Docs at
  be38ec5d, data/reusables/actions/about-triggers.md:18: a run uses the workflow of the event's commit). The reader
  fails closed on a validate.yml in which it reads no check and on a step whose words are not plain ones (exit 10, the
  step's text not printed); a merge with no validate.yml runs none.
- The scan's cost is linear in the text: 60 KB on one line takes at most 0.18 s, where round 2's rule took 24 s on one
  of the measured texts.
- README: the signals after which the snapshot is removed are named (SIGINT, SIGTERM and SIGHUP, each tested; SIGKILL
  leaves it), #975's cli/cli row names the mirror that holds the pinned commit, and the sources, known gaps and tests
  sections follow the change. docs/decisions/2026-10-09-host-name-scan.md gains one sentence on the opt-in.

Tests: on a git archive of 37e242c with this commit's two test files, the 19 new or changed tests give 2,254 failing
cases and one error in 16 tests (100 landings of a refused address, 12 landings past a names file read otherwise, a
landing with a failing check that the merge added); the three that pass there are the controls' test, the signal test
and #176's own. Here all 19 pass, on CPython 3.12.3, 3.13.16 and 3.14.4, and the landing module's 150 tests pass. The
oracle's test runs 29 local parts at 29 domains in nine forms (7,569 cases).

Measured on the last 600 commit messages of main at 5421e5d (counts only): 70 refused, 0 names, 67 addresses and
3 home paths (round 2's rule: 8); 341 messages with the scratch co-author trailer and 62 with a source locator pass.
The CC's own regression for #176 needs a validate.yml in its scratch repository to pass on this merge_validate.

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

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: cb0429d77e

ℹ️ 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".

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lane:shared Touches files owned by both lanes; needs both lanes' acknowledgement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant