Repository navigation
fix(ci): enforce PR-owned manifest registration continuity - #1070
Merged
seathatflowsinourveins merged 3 commits intoOct 13, 2026
Merged
Conversation
…d-only timeline fetches
seathatflowsinourveins
force-pushed
the
codex/ns2604-pr-owned-registry-ci-20261013
branch
from
October 13, 2026 11:20
dd660c2 to
fbcc256
Compare
seathatflowsinourveins
marked this pull request as ready for review
October 13, 2026 15:22
seathatflowsinourveins
deleted the
codex/ns2604-pr-owned-registry-ci-20261013
branch
October 13, 2026 15:24
This was referenced Oct 13, 2026
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 13, 2026
…'s count, 353, and the freshness workflow provisions the bun its suite needs Two rulings of the command center on the landing rebase onto 77cc7ef, in one commit. - docs/decisions/2026-10-13-claude-agent-drift-check.md: the dotdot delta was re-derived over main after #1070 (344 of the baseline snapshot, scripts/adoption_status.py 4, tools/credentials/set_credential.py 4, scripts/validate.py 1), so it accounts for 353 reads; the sentence that describes it said 352, the count on the previous base. A record must match the delta it describes. - .github/workflows/catalog-freshness.yml (the local review's P1 on the rebased head): the freshness job runs the whole suite (python3 -m unittest --durations 50) under GitHub Actions, where the tests that need the real bun fail rather than skip (tests/test_adoption_status.py unavailable()), and only validate.yml provisioned the pinned bun, so the scheduled and the manual run failed at RealBunTests and the vendor-definition tests and its propose job never started. The job now has the same step, with the same version and checksum, before its suite. - tests/test_adoption_status.py: test_every_job_that_runs_the_suite_provisions_the_pinned_bun_before_it reads every workflow, finds each job whose unittest step reaches the module (a bare unittest, a named tests.test_adoption_status, the shard runner) and holds the step, the version and the checksum equal to validate.yml's; it fails at the freshness job before the change (receipts/fail-before-freshness-bun.txt). test_the_reader_tells_the_suite_runners_from_the_named_modules holds the reader's own cases. - Evidence: receipts/freshness-bun-local-check.txt runs the step's own script and the module (215 tests OK with the exported variable, FAILED without it); 13 of 13 mutants killed (receipts/mutants-freshness-bun-13.txt); the record has a section for the review. The workflow was not dispatched: its propose job force-creates an evidence branch and opens a pull request. - Nothing else changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
5 tasks done
seathatflowsinourveins
added a commit
that referenced
this pull request
Oct 13, 2026
…epository's (CPA-V-10) (#1062) * Detect drift between the installed Claude agent definitions and the repository's: adoption_status --client-wiring counts them and the wiring rule requires zero CPA-V-10 of the Claude-family practice audit. The client serves the definitions in ~/.claude/agents to every project that does not define the name itself; tools/adoption/install_claude_profile.py copies the 11 of adoption/agents/claude there verbatim, and nothing compared them afterwards (the audit found five of 11 host copies stale; scripts/adoption_status.py had no reference to the Claude agent paths). A stale copy is old text; a wider one is a different kind of risk, since an omitted tools field means every tool (anthropics/claude-code@3deb87368737 plugins/plugin-dev/skills/agent-development/SKILL.md L152-L154). - scripts/adoption_status.py: claude.stack_agents_drift, a count that is 0 when every *.md of adoption/agents/claude is installed byte for byte under <Claude home>/agents and nothing else is there but the four vendor-installed search definitions (codebase-memory, codebase-memory-auditor, codebase-memory-scout, semble-search: listed, not counted). A copy that is absent, a link, a folder or another kind of file counts (a link's target is not what the client was shown); a *.md not shipped here and not listed counts; backups, other extensions and anything below the top of the folder do not. null (the comparison cannot be made: the source folder has no definition or cannot be read, the agents path is a link or not a folder, an installed copy cannot be read) makes complete false like every other null. A non-zero count makes complete false: the fail-first of the audit item, a fixture with one stale user agent that reported complete: true. - docs/token-efficiency-stack.md: the coverage check and its rule; docs/decisions/2026-10-13-claude-agent-drift-check.md: the decision, the evidence, what is not covered; evidence/artifacts/agent-drift-check-20261013: the receipts (the run on the first host: 0 and complete true; the fail-before; the mutants). Tests: 12 new ClientWiringTests and the wired, unwired and wrong-type fixtures updated (153 tests in the module). 16 of them fail on the script at c63c83a (constants aside), among them the stale-agent fixture. 20 of 20 mutants killed. The practice page note (reference/workers.md L13, "four host copies differ") is stale; it is corrected with the next re-pin of the practice skill, which pins the page. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Review fix of the Claude agent drift check: the agents folder is read through descriptors and at any depth, a vendor file that declares a shipped name is drift, and the catalog citation is repaired Astra's first read of e70d2de (CHANGES_REQUESTED: one P1, one P2, three follow-ups) and the command center's Claude read of the same head (one P1, one P2, four P3), folded into one commit. - P1 (Astra): the check inspected a path with lstat and opened it again, so a shipped file, or the whole agents folder, replaced by a link in between was read through (outside bytes equal to the source: drift 0 and complete true). The Claude home is opened, then agents with O_DIRECTORY|O_NOFOLLOW, then every entry with O_NOFOLLOW relative to the descriptor of its folder, and what is described is fstat of the descriptor that was opened. There is no fallback to a path check: a platform without O_NOFOLLOW, O_DIRECTORY or descriptor-relative open, stat and listdir reads nothing (null). The shared reader read_regular_bytes and its Codex caller stack_roles_matching read the same way, as the read asked. python/cpython@cbc944f4bc59 Modules/_io/fileio.c L404, Doc/library/os.rst L1272, L1364-L1365, L3507, L3551. - P1 (Claude read): the client loads the folder recursively (https://code.claude.com/docs/en/sub-agents.md L176-L182; the installed 2.1.296 loader enters every folder, follows links and lists hidden files), so a nested definition read as no drift. Every *.md at any depth is counted, a link, pipe or socket named *.md included; a link that leads to a folder, an entry that vanishes while it is read, a tree deeper than 8 folders or with more than 5,000 entries are null. - P3 (Claude read): a vendor-named file whose front matter declares the name of a shipped definition is counted (one name, one definition wins); a vendor name below the top, or as a link, is not exempt. - P2 (Astra): the inserted lines moved the source cited for codex:host:RTK.md in the catalog, and two citation assertions failed; the citation is scripts/adoption_status.py:532-553 (valid whether lines are counted by splitlines or by LF) and its registry binding is refreshed. - P2 and P3 (Claude read, Astra): the record cites its sources (documentation page, loader, CHANGELOG L8578 for CLAUDE_CONFIG_DIR and L7088 narrowed), its two wrong claims about links and nested files are corrected, it has a registry row, and its host command is as the receipt records it. Tests (170): 16 tests fail on the sources of e70d2de (FAILED failures=24, errors=3, counting subtests), among them the four replacement tests, which try a replacement after every file-system call of the read (the old check answered 0); 49 of 49 mutants killed. The installer's link handling, the non-default Claude home and the 18 hostname lines are follow-ups in the pull request body. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Round 2 of the Claude agent drift check: a vendor file's name is read as the client reads it or the count is unknown, the descriptor opens are accounted in the push gate's advisory inventory, and the record's counts are held to the receipts Astra's second read of e22358e (CHANGES_REQUESTED: two P2, five P3) and the command center's Claude read of the same head (one blocker, three P3), folded into one commit. - P2 (Astra): the descriptor opens added three reads to the OpenHands push gate's advisory inventory (9 to 12 for scripts/adoption_status.py), and tests.test_runtime_worker_openhands_push_gate failed two tests. A new dated monitoring delta (unclassified-gate-reads-20261013-pr1062-delta.json, derived with the native GitTree and derive_ci_protected, index entry appended, earlier snapshots and deltas unchanged, both registered) accounts for them: 347 reads against the 344 of the baseline it names; the three are the opens in open_below, stack_roles_matching and stack_agents_drift. - P2 (Astra): the vendor-name rule read the plain `name:` line only, so a vendor-named file that declared a shipped name through a quoted key, a block scalar, an escape sequence or a byte order mark gave 0 and complete wiring. agent_identity applies the client's block extraction and reads the plain spellings; every other spelling is unknown (the count null, complete false), and so is a shipped definition whose name it cannot read. Measured against the installed 2.1.296 client's own parser (its functions copied unchanged by byte interval and run on Bun 1.4.2; the client embeds 1.4.3): 0 misses over 8,582 generated texts and 26 real definitions, and over five further seeds of 34,556 texts. The first review's claim for the vendor rule is narrowed to what is measured. - Blocker (command center): the record quoted 46 of 46 killed for a receipt of 49. Each line that names a mutation receipt now carries that receipt's own count, and tests/test_agent_drift_record.py holds it. - P3 (command center): a pipe, a socket, a device and a link to nothing are not counted (the client's walker keeps regular files only); a *.md with no name stays counted, now said in the record and the docstring; a link is told by the ELOOP of the open and not by a later look; `name:` with its value on the next line is read. - P3 (Astra): the locator in tools/adoption/host-baseline.md follows launcher_resolution. Tests: 178 in the module; 9 of them fail on the sources of e22358e (failures=42, errors=62, counting subtests), the record test fails on its record, and the push-gate module's 127 tests pass here and fail two at e22358e; 92 of 92 mutants killed. The installer's link handling and non-default Claude home, the hostname lines of the touched files and the upstream captures are follow-ups in the pull request body. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Design round of the Claude agent drift check: a vendor file's name is asked of the client's own YAML parser or the count is unknown The command center's Claude read of e7260fd (one P1, reproduced) and Astra's second delta (CHANGES_REQUESTED: one P2, the same case, and four P3) found that the hand-written name reader, rewritten in each of two rounds, still returned none for a name followed by a comment line at the left margin, so a vendor-named file declaring a shipped name gave drift 0 and complete wiring. The adjudication ruled a design round: parse the front matter with the client's own implementation, failing closed. - agent_front_matter extracts the block as the client's loader does (a byte order mark dropped, /^---\s*\n([\s\S]*?)---\s*\n?/); agent_names hands every block of the check to Bun.YAML.parse through bun at CLIENT_BUN_VERSION (1.4.3, the version the installed 2.1.296 client embeds) in one call, in an empty scratch directory with an empty configuration, that directory as home and a three-variable environment, the blocks as JSON on stdin. A name, none or a throw; a throw, no bun, another version, a bun that fails or does not answer in 30 s is unknown (the count null, complete false), never 0. agent_identity and its regexes are removed. - Measured against the installed client itself (each text written as a project agent, the client started in headless mode and killed after its init record): 16,428 generated texts, 0 misses with bun 1.4.3 and with 1.4.2; the reader of e7260fd missed 501, all of them comment lines between a key and its value and nine CRLF texts. The 2,987-text subset and the client's answers are committed (tests/fixtures/agent_frontmatter/client-oracle.json) and replayed by the tests. - The tests that need the real bun skip on a developer's machine and fail under GitHub Actions (the pattern of tests/test_token_full_save_evidence.py); validate.yml installs bun 1.4.3 from the release at its checksum. - P3: a test holds every test name that the record and the README cite; the README states the real definitions once; the oracle receipt names the client's whole parse path by function and byte interval and the record states Iwt's other refusals; the superseded oracle receipt is marked; the advisory delta of the design round states the edited read line; the hostname count is 57 occurrences on 55 lines. Tests: 203 in tests.test_adoption_status; on the sources of e7260fd the same file gives failures=1, errors=58 in the 196 tests that run there (counting subtests; 24 tests and the setup of the real-bun class raise AttributeError for the API the parser call adds; the 7 tests of that class cannot start); 38 of 38 mutants killed. Host step, not applied here: bun 1.4.3 (mise install [email protected], or AGENT_FRONTMATTER_BUN) on the first host, where mise has 1.4.2 and the count is null until then. The installer's link handling and non-default Claude home, the upstream captures and the hostname lines of the touched files are follow-ups in the pull request body. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Record of the Claude agent drift check: the departure from the ruling's wording on a non-string name, and that mise install keeps the active version The command center's Claude delta of fb968af (PASS_WITH_P3) accepted two points on condition that the record say them: a successful parse that is not a mapping, or whose name is not a string, is none and not unknown, which departs on purpose from the adjudication's wording (item 2 asked for unknown) because the client's own loader serves a definition only under a string name (measured: the client served nothing in all 1,829 oracle texts the pipeline answered none for, and no text where it said none and the client served a name); and `mise install [email protected]` does not change the active version, so the check needs AGENT_FRONTMATTER_BUN (the shim in a scratch home resolves 1.4.2, measured by the command center). Record text only: no code, test or receipt changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Claude agent drift check: the front matter extraction keeps the client's delimiter precheck, so an unterminated block of whitespace is read in linear time The local codex review of the rebased head 2723f8f said "patch is incorrect" (one P2) and the command center ruled one bounded, scope-locked round. A vendor-named file of "---" followed by many whitespace bytes and no closing line made the front matter pattern backtrack quadratically over the whitespace (64 KiB of newlines took 18.9 s, 32 Ki pairs of a space and a newline 10.7 s, a file may be 1 MiB), and the extraction runs before bun, so no timeout of bun bounds it. The design round had removed the client's check that "---" occurs after the first three characters as one that changes no result; it changes no result and it bounds the work. - scripts/adoption_status.py agent_front_matter: return none when "---" does not occur after the first three characters, the check of the client's own oi (Claude Code 2.1.296, bytes 211908840-211910460: e.indexOf("---",3)<0?null:e.match(RE)). With the check the pattern is tried only on a text that has a closing line, where it succeeds at the first candidate; 1 MiB of newlines now takes 2 ms. - tests: two extraction tests (five fillers of 64 KiB under a second; a closing line far below a long run still found) and one client_wiring test (the whole call under ten seconds, no bun asked). On the sources of 2723f8f the extraction tests fail at 19 s, 6 s and 9 s and the wiring test at 19 s (receipts/fail-before-precheck.txt); 4 of 4 mutants of the check are killed (receipts/mutants-precheck.txt). - The record has a section for this review, the evidence row and the receipts README rows. Nothing else changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Claude agent drift check: the bun that is selected is an absolute path before either launch, so a relative AGENT_FRONTMATTER_BUN or a relative PATH entry names the same file in the scratch directory The local codex re-review of b3da64d said "patch is incorrect" (one P2) and the command center adjudicated it as fixed in this landing, as one bounded commit. find_bun kept a relative AGENT_FRONTMATTER_BUN, or a bun found through a relative PATH entry (./bin), relative, and both launches of agent_names run with cwd=scratch, where subprocess looks for a relative executable relative to cwd (python/cpython@cbc944f4bc59, Doc/library/subprocess.rst L572-L576, Lib/subprocess.py L1912-L1919). The bun that parses from its absolute path gave Unknown from a relative path to the same file (reproduced with bun 1.4.3), and the check then said null and complete false. - scripts/adoption_status.py find_bun: the selection is made absolute before either launch. A value of the variable with a directory is made absolute against the caller's directory; a value with none is a name, looked up on PATH as a shell does, never as a file of the caller's directory; with no variable the first bun on PATH is found and made absolute; a caller whose own directory is gone cannot make a relative path absolute, which is None and so Unknown. Which bun is selected does not change (the mise shim remains the adjudicated follow-up). - tests: three stand-in tests (six framings of a relative selection run from the caller's directory; a name is a PATH lookup and never a file of the caller's directory; a vanished directory is Unknown) and one with the real bun, run from the bun's own directory. All four fail on the sources of b3da64d (receipts/fail-before-absolute-bun.txt); 9 of 9 mutants of the change are killed (receipts/mutants-absolute-bun.txt). - The record has a section for this review, the evidence row and the receipts README rows. Nothing else changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Claude agent drift check: a relative bun is made absolute without normalizing it, so a ".." after a link keeps the meaning the file system gives it The second local codex re-review of 9720257 said "patch is incorrect" (one P2) and the command center adjudicated it as fixed in this landing, as one bounded commit. find_bun made a relative selection absolute with os.path.abspath, which removes each ".." lexically, before the file system resolves the link in front of it: with current a link to actual/subdir, current/../bun is the file actual/bun and became the bun beside current, so healthy wiring gave Unknown (reproduced with bun 1.4.3). - scripts/adoption_status.py find_bun: the caller's directory is put in front of a relative path and nothing is normalized, so the components stay as written and the kernel resolves them at the launch as it resolves the relative path from the caller's directory (python/cpython@cbc944f4bc59, Doc/library/subprocess.rst L572-L576). An absolute value is passed as it is. A link is not resolved either: os.path.realpath would replace the mise shim, a link to mise, by mise, and an executable can be known by its name. - tests: a stand-in test (a relative value, a relative PATH entry and an absolute value through the link; a decoy of another version beside the link) and one with the real bun fail on the sources of 9720257 and pass here (receipts/fail-before-dotdot.txt); a test that a link to the bun keeps its name holds at both heads; 5 of 5 mutants are killed (receipts/mutants-dotdot.txt). The stand-in bun found its behavior file by os.path.abspath(sys.argv[0]), the same mistake; it now uses the real path of the file that ran. - The record has a section for this review, the evidence row and the receipts README rows. Nothing else changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Claude agent drift check: the working directory read of a relative bun is accounted in the push gate's advisory inventory The second re-review commit (31d377e) put the caller's directory in front of a relative bun path with os.getcwd(), which the OpenHands push gate's derivation counts as one unclassified read of scripts/adoption_status.py (os.path.abspath made the same read inside the library and was not counted). tests.test_runtime_worker_openhands_push_gate derives its reads from the committed tree; it was run on the working tree before that commit, so the continuous integration found the read first (validate-shard-2: test_advisory_baseline_and_explicit_categories_stay_bounded_on_this_repository and test_baseline_refresh_regression_accepts_a_committed_outer_observation). - blueprints/runtime-workers/openhands/evidence: the delta unclassified-gate-reads-20261013-pr1062-dotdot-delta.json (352 reads; the one new read, classified as a user status observation with the scope read-only client-wiring status; no worker execution authority) and its index entry, derived with the native GitTree and derive_ci_protected at the committed head. - the record and the receipts README name the read and the delta. Nothing else changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> * Claude agent drift check: the decision record gives the rebased delta's count, 353, and the freshness workflow provisions the bun its suite needs Two rulings of the command center on the landing rebase onto 77cc7ef, in one commit. - docs/decisions/2026-10-13-claude-agent-drift-check.md: the dotdot delta was re-derived over main after #1070 (344 of the baseline snapshot, scripts/adoption_status.py 4, tools/credentials/set_credential.py 4, scripts/validate.py 1), so it accounts for 353 reads; the sentence that describes it said 352, the count on the previous base. A record must match the delta it describes. - .github/workflows/catalog-freshness.yml (the local review's P1 on the rebased head): the freshness job runs the whole suite (python3 -m unittest --durations 50) under GitHub Actions, where the tests that need the real bun fail rather than skip (tests/test_adoption_status.py unavailable()), and only validate.yml provisioned the pinned bun, so the scheduled and the manual run failed at RealBunTests and the vendor-definition tests and its propose job never started. The job now has the same step, with the same version and checksum, before its suite. - tests/test_adoption_status.py: test_every_job_that_runs_the_suite_provisions_the_pinned_bun_before_it reads every workflow, finds each job whose unittest step reaches the module (a bare unittest, a named tests.test_adoption_status, the shard runner) and holds the step, the version and the checksum equal to validate.yml's; it fails at the freshness job before the change (receipts/fail-before-freshness-bun.txt). test_the_reader_tells_the_suite_runners_from_the_named_modules holds the reader's own cases. - Evidence: receipts/freshness-bun-local-check.txt runs the step's own script and the module (215 tests OK with the exported variable, FAILED without it); 13 of 13 mutants killed (receipts/mutants-freshness-bun-13.txt); the record has a section for the review. The workflow was not dispatched: its propose job force-creates an evidence branch and opens a pull request. - Nothing else changes. Co-Authored-By: Claude Sonnet 5.5 <[email protected]> --------- Co-authored-by: Claude Sonnet 5.5 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope
Fail CI when a PR loses a required
manifests/evidence.jsonrow or its row disagrees with the committed file. The validator now compares committed Git trees against the registration policy indocs/lanes.md: changed paths registered at base, new evidence, and paths registered by the PR must keep matching rows while the files still exist.The validation workflow supplies the event base and paginated prior force-push heads. The validator follows registry-bearing ancestors as well, so a second push cannot erase the earlier registration intent. Removed files may remove their rows; never-registered non-evidence source files retain their existing policy.
107bcca66133db379e9bf31560ba617519c59bec(freshorigin/main).lane:foundation..github/workflows/validate.yml,scripts/validate.py, newtests/test_registry_rows.py, the workflow-hardening permission assertion, least-privilege record and dated monitoring delta/index; the last round adds one fast-forward correction commit and updates only its own registration rows.SOTA sources
107bcca6,docs/lanes.md:119-126: register files already listed at base, new evidence and any other new file registered by the branch; deleted files remove their row.scripts/host_receipts.py:710-727is the supported writer, exercised in the fixtures. The writer remains unchanged.67ad42147a7acc2af6074753ebd03d904476118f:Documentation/diff-options.adoc:303-319documents NUL-separated path output; lines 485 and 622 document rename control and diff filtering.Documentation/rev-list-options.adoc:717documents--full-historywalking every edge. Installed Git 2.53.0 executes these mechanisms.58b1e0c00b39b9e46c24dc4a0ba6a2669c90e9c1,components.schemas.webhook-pull-request-synchronize:beforeandafterare required strings;pull_request.base.shasupplies the base. The review packet retains a projection of these exact schema fields with the pinned source and JSON pointer.HeadRefForcePushedEvent.beforeCommit.oid, verified through the live schema and PR Route each Claude agent definition to its table's model and effort #1045's persistent timeline, supplies heads that no longer appear in the current ancestry. cli/cli at mirror pinec5b512045db67e5a2a4ff4a1b02660b2fb24390,pkg/cmd/api/api.go:134-137documents native GraphQL pagination withendCursorandpageInfo. Installed gh 2.102.0 reproduced the unchanged workflow history query and fetched all four public prior heads for Route each Claude agent definition to its table's model and effort #1045.be38ec5d78e24172587e61b3c6ff40ace1865c71,data/reusables/actions/github-token-scope-descriptions.md:1,27defines explicit token scopes and the pull-request permission. The validation job adds onlypull-requests: readfor its timeline read, preservingcontents: read; the repository's least-privilege table and exact-scope assertion now reflect that need. Git v2.53.0Documentation/pull-fetch-param.adoc:32supports a fully spelled hexadecimal object ID as the fetch source. The native GraphQL schema capture authenticatesHeadRefForcePushedEvent.beforeCommitas the before-commit SHA.be38ec5d,src/graphql/data/fpt/schema-pulls.json:2153,2181-2185,7189-7222defines the force-push before-commit and separate nodes/pageInfo/count fields; cli/cli v2.102.0 atfc4b137c,pkg/cmd/api/api.go:134-137documents native pagination. Git v2.53.0Documentation/git-config.adoc:479-493andDocumentation/config/http.adoc:98-103document process-scoped configuration and HTTP headers; the history fetch reuses the repository's existing transient authentication form, with no token in Git argv or persisted config.37aa5bbaf1a591aa134913efeb3775f0235dc5ab,pkg/jq/jq.go:84-85,109-110renders JSON null as an empty line; gh v2.102.0go.mod:21pins that version. Native gh 2.102.0 reproduces exactly one LF byte (0a) for a null projection. A success sentinel preserves trailing node lines through command substitution; the loop warns/counts empty node lines while a genuinely empty timeline remains zero nodes.Evidence-class table
syntheticsyntheticregistry-green.log: 25 tests, including empty/trailing-null/empty-timeline controls, command-scoped fake private authentication and reachable current-manifest commit:path diagnosticslocal_integration6c8348d29939b41bd3a5d806a5fd4827e4fd2427with prior head70ff2753bea0858b153ab9239f79ddc0841d85dd: exit 1, precisely the three new agents and decision record missinglocal_integration7906b883b68748c2771789b4121ca8e801834a78: exit 0local_integrationmain-validator-before.log,main-registration-check.logat base107bcca6native_provennative-timeline-fetch.log, unchanged workflow script against public #1045: all four prior heads fetched, exit 0syntheticlocal_integrationLocal commands run
Task scratch and test outputs use an explicit
/var/tmpTMPDIR. Complete execution captures and exact cited source blobs are retained in a hashed review packet for the co-op's two-family reads.Decision record
This PR records correction #207's CI guard. Registration intent is inferred from native Git registry history and GitHub's persistent force-push history; no private reviewer packet path enters the repository. Unavailable Git objects and failed API requests refuse. Malformed historical manifests emit a warning naming the commit/path and are skipped; the current manifest stays strict. An accidental manifest self-row may be removed because the manifest is excluded from its own registration policy. Prior refs stay scoped to the validation step via
GITHUB_OUTPUT.The wider check covers registry-only edits, a second push after loss, force-pushed history, still-present versus deleted files, valid repairs through
register_file, and a worktree restored to old bytes while the committed head contains changed bytes. No registry writer or blanket source-registration policy is introduced. SHA/byte comparison reads committed blobs. Workflow permissions are exactlycontents: readandpull-requests: read. Last-round Git fetches receive the existing read-only token through command-scoped environment configuration; the fake private-fetch test uses actual Git's configuration reader and verifies no config-file change, no token argv and no residual header afterward. No actual private repository or credential is used in that fixture.Authenticated-fetch trigger and scope: on a private-repository
synchronizerun, checkout'spersist-credentials: falseleaves subsequent Git history fetches without authentication;GH_TOKENauthenticates the timeline request through gh, but does not authenticate Git. The transient header addresses that private-repository boundary, reproduced with a fake-token fixture rather than an observed private hosted failure. It applies only to each prior-head Git fetch and uses the job's existing ephemeral, read-only token through command-scopedGIT_CONFIG_*configuration. The encoded header is masked; no repository configuration is written, no token is passed in Git argv, and no additional permission or secret is introduced. The public-repository hosted proof below establishes history recovery; it does not establish private-repository authentication.Round 1 corrects the missing read scope and actionlint's SC2016 on the literal GraphQL query. Escaped dollar signs in a double-quoted query preserve GraphQL variables without suppression. Earlier local actionlint lacked ShellCheck; the package-pinned native ShellCheck control now reproduces the hosted error and passes the fixed script. Historical first-head logs remain separate from final results.
The monitoring delta/index append records the native-derived 349 reads versus the prior 348, one extra committed-blob read in the validator, with
permission_change: false. Prior baselines/deltas remain immutable. The recorded source is the original public head; final-source native derivation confirms the same counters/shapes after line movement. Existing monitoring assertions remain unchanged.Fail-before controls cover each blocker, including a rule-removed negative control that fails both direct hash/byte assertions while ordinary publication validation passes. The single CC-authorized leased replacement of the registration-only tail creates #1070's first actual force-push event, before
dd660c28and afterfbcc2564. Native measurement corrected the CC's initial event count: the previous head had zero filtered force-push nodes. The script counts projected nodes, never unfilteredtotalCount.Hosted proof at exact
fbcc2564fead3b4413ca958a05e73afbf45f6b44: run 38389505326, shard-0 job115269503336, steps 9 (pinned actionlint), 10 (prior-head timeline/fetch), 11 (publication and committed registration checks) and 12 (host receipts) all SUCCESS at the 11:22:59Z native job read. Its one actual timeline node names the orphaneddd660c28a3ed2f26df45afd3fc945dbeeb114567; the fail-closed step successfully fetches that full object ID. The timeline API uses the job's scoped token; public Git transport retainspersist-credentials: false. Full matrix/aggregate checks remain in progress. The in-progress job log endpoint is not yet available, so retained job metadata plus the exact timeline authenticate this step result.Publication correction: an initial full upstream REST schema capture triggered the private packet's gitleaks scan on unrelated key-shaped examples. Publication stopped, and the full capture was removed from the deliverable. The packet now contains only the cited schema-field projection and passes the complete uncapped scan. No scanner suppression or allowlist was added; no finding value was displayed.
Correction #209: the earlier literal
nullrecovery claim was wrong at the pinned gh version. Native gh emits an empty line, and shell command substitution would strip trailing empty node lines. Last-round controls fail before the fix and pass after preserving output with a success-only sentinel, counting every actual node line and warning on empty lines. The private-history authentication and pinned GraphQL/gh citations are included in the same final correction.InvalidPublicationis caught before genericValueError, preserving the current-manifest commit:path diagnostic; its direct regression fails before that exception-order fix. No pass/fail refusal is weakened.The LAST round is one normal child commit,
0764bb6f72e0315dc8cc98b3712d74c581194fbf, after the reviewedfbcc2564head. Final author-head OpenHands gate module: 127 tests / 108.229 seconds / exit 0. Full author-head validation includes both registration base107bcca6and before headfbcc2564, and passes 71 components / 11880 hashes / 4 profiles / 240 receipts. Only the three edited source/test/workflow registrations are refreshed; the frozen monitoring delta/index and all unrelated manifest fields stay unchanged. The final push is fast-forward, with no force or rebase. Current-head hosted checks and the three delta reads follow publication; the earlier hosted proof above remains explicitly atfbcc2564.Follow-ups
Host evidence
Not applicable; no
evidence/hosts/edits.Checklist
{}; the changed job grants exactlycontents: readandpull-requests: readfor its read-only inputs.