Skip to content

perf(pr-pipeline): remove every dead listing-carry lookup and the listing upload - #13040

Merged
kyle-sexton merged 6 commits into
mainfrom
perf/dispatch-verdict-exact-name
Nov 4, 2026
Merged

kyle-sexton merged 6 commits into
mainfrom
perf/dispatch-verdict-exact-name

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

No related issue: GITHUB_TOKEN spend cut from the hub's counter-B attribution of the 2026-11-03 22:52-23:52Z window; open-issue intake is closed while issues are driven to zero.

Summary

#12558 (FAIL index mode) turned off the whole-artifact listing except for a pull request past INDEX_NAMES_CAP (100) index names, so in practice no gate has saved verify-listing.json since: the last pr-merge-verify-listing artifact is from run 41571354158 (2026-11-03T03:22:28Z), the run just before #12558 merged at 03:28:44Z. Every listing-carry.mjs call site still went looking for one. It walks main's pr-merge runs up to MAX_RUNS = 10 (rotation.mjs:41-42) and finds nothing: "no earlier artifact listing; the verdict reader lists every page" (dispatch job 126277059871, script=listing-carry github-token=11).

The reader doesn't need the carry. It is in index mode on every path (verify-legacy-fails.json loads, index_mode() at babysit_verify_evidence.py:2704-2708, _targeted reads by exact name), and it reads a carried listing only on the whole-listing path (_incremental_base, :1531-1546). The carry was live only for a PR past that cap (independent security review); there, a dispatcher's FAIL-cap read now lists in full (about 50-58 s for 69 pages, inside its 120 s deadline), and a read that misses its deadline runs the round under its own caps, as before. The hub's other counter-B bucket, actions/artifacts (~7 a job), is the reader's exact-name ?name= reads and stays.

Fix

  • pr-feedback-dispatch / pr-unblock-dispatch: verify-cap.mjs no longer runs listing-carry. The one-time carry fires when the job names BABYSIT_RUN_CACHE or BABYSIT_VERIFY_HEAD_REFS.
  • pr-merge.yml: the merge and enable-auto-merge listing-carry steps, all four BABYSIT_VERIFY_LISTING_CARRY env lines, and the pr-merge-verify-listing upload with its scan step (nothing else reads that artifact).
  • pr-require-checks.yml: the merge-queue reader's listing-carry call, env line and sparse-checkout path.
  • listing-carry.mjs and its test are deleted. Its floor row in docs/conventions/pr-pipeline.yaml and its artifact-retention.json entry go too. scripts/sync-hold-floor.py regenerated the floor copies, and the floor pins move by one gate row. BABYSIT_VERIFY_LISTING stays everywhere, because _targeted falls back to a whole listing past INDEX_NAMES_CAP.

Merge-gate verdicts are unchanged: a failed or missing listing only removes the incremental path, and every refusal but verify:missing/spec-changed/untrusted-spec holds (merge-holds.mjs:1419-1449). Also, each removed step was continue-on-error and wrote nothing on a miss. A failed read still fails closed through the same reader.

Call delta (R34), GITHUB_TOKEN, counter B routes (actions/runs/{n}/artifacts):

Where Delta Basis
dispatchers about -9 per job that reaches a FAIL-cap read measured: listing-carry 11 in job 126277059871; carry-run-cache picks up ~2 of its shared reads
pr-merge merge job about -9 per scheduled or hand-started run code: the shared reads already hold the runs page and the newest run's artifacts
pr-merge enable-auto-merge about -9 per scheduled or dispatched run same
ci-status merge-queue reader about -9 per lanes App merge_group run same, PR_MERGE_READS_PATH shared with head-ref-map

Verification

  • Red before (pre-change workflows restored): workflow.test.mjs 3 FAIL, including the new "no job keeps, fetches or names a carried artifact listing"; ci-lanes-pr-hold.test.sh FAIL=1; verify-cap.test.mjs 8 of 28 FAIL.
  • Green after, on the branch merged with main: pr-merge and verify-cap node suites 864/864; log-api-budget, resolve-config callers, check-trusted-trigger and pr-unblock 2099/2099; babysit-prs pytest 4093 passed; workflow.test.mjs 107/107 after the main merge; sync-hold-floor.py --check clean; ci-lanes-pr-hold 303/0; check-artifact-retention 39/0; the ci-* and check-* suites naming a changed workflow all pass.
  • Independent security review: PASS, 3 P5. Taken: the "no gate saves a listing" wording, corrected in 3eb156d. Left for a follow-up: the reader's unused LISTING_CARRY_ENV input, and making a dispatcher's readFailed skip the round instead of running it.
  • After merge: R21 on the next two runs of pr-merge, pr-feedback-dispatch and the merge-group ci-status, and actions/runs/{n}/artifacts per job re-read from the api-routes annotations.

Related

🤖 Generated with Claude Code

https://claude.ai/code/session_01MWmASQQUMmnivZUuzgYfbe

kyle-sexton and others added 4 commits November 3, 2026 20:00
… listing no gate saves

The verdict reader reads the FAIL index by exact name once the legacy
FAILs file loads, so pr-merge's gate never writes verify-listing.json and
no pr-merge-verify-listing artifact has been uploaded since 03:22Z on
2026-11-03. verify-cap.mjs still ran listing-carry.mjs before the first
FAIL-cap read of each address-feedback and pr-unblock dispatch job: one
run listing and ten runs' artifact listings (MAX_RUNS), finding nothing,
for a carried listing the index-mode reader never reads.

Drop listing-carry.mjs from carrySteps and fetch the carry when the job
names the run cache or head-ref map, and remove
BABYSIT_VERIFY_LISTING_CARRY from both dispatch steps. Verdicts are
unchanged: the reader reads the carry file only on its whole-listing path,
and no such file has existed since the index turned on.

Dispatch job 126277059871 (run 41739470521): listing-carry 11 calls,
carry-run-cache 3, job total 45. Expected after: listing-carry 0,
carry-run-cache about 5 (it now pays the run listing and the newest run's
artifact listing the shared reads used to hold), about 9 fewer a job that
reaches a FAIL-cap read.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWmASQQUMmnivZUuzgYfbe
…ting upload

The verdict reader reads the FAIL index by exact name, so no gate saves
an artifact listing and no pr-merge-verify-listing artifact exists to
carry. Every remaining reader of that carry looked for one each run and
found none:

- pr-merge's merge job ran listing-carry.mjs after rotation, the
  head-ref map and the run-cache carry: about 9 run-artifact listings a
  run (runs 2 to 10 of MAX_RUNS; the run page and the newest run's
  artifacts were already in the job's shared reads);
- enable-auto-merge ran it after the head-ref map: the same 9;
- ci-status's merge-queue reader ran it in each lanes App merge_group
  run: 9, or 10 when the run page was not yet shared.

Remove those steps and calls, every BABYSIT_VERIFY_LISTING_CARRY env
line, and the merge job's pr-merge-verify-listing upload and its
credential scan, which nothing reads now. With no caller left,
listing-carry.mjs, its test, its floor row and retention entry go too;
sync-hold-floor.py regenerates the hold-floor copies and the floor pins
drop that one gate-class row. BABYSIT_VERIFY_LISTING stays wherever a
reader can still save a listing (_targeted's whole-listing fallback,
ci-status's pass-name file).

Verdicts are unchanged: the reader reads a carried listing only on its
whole-listing path, and no carry file has existed since index mode
turned on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWmASQQUMmnivZUuzgYfbe
@kyle-sexton
kyle-sexton marked this pull request as ready for review November 4, 2026 02:08
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 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-11-04T02:10:53.847852Z 7dcc812 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

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

…s cap

The changelog fragment and the reader's carried-reads comment said no gate
saves a listing in index mode. A pull request past INDEX_NAMES_CAP index
names takes the whole-listing path, and that path saves one, so the carry
was rarely live, not dead. Past that cap a dispatcher's FAIL-cap read now
lists in full (independent security review, P5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MWmASQQUMmnivZUuzgYfbe
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

claude-security-review reviewed 963a1570e4a4f6711e8dfb34a62521415f6e8ab0: read 21 of 21 changed file(s); 0 finding(s), 0 as inline comments.

Security review: PR #13040 (remove the dead listing-carry lookups and the listing upload)

No security issues found.

I read every hunk of all 21 listed files and the two files the PR deletes (listing-carry.mjs and its test). I also read the head carrySteps, fetchCarry and verifyReader in verify-cap.mjs and checked who calls them. This head is a merge from main on top of the commit reviewed before (7dcc812); the PR's own diff has the same substance.

Trust controls and merge holds checked

  • Merge holds (merge-holds.mjs, clear-escalations.mjs, the gate steps in pr-merge.yml, the ci-status merge-queue reader in pr-require-checks.yml, babysit_verify_evidence.py):
    • The removed steps only fetched an incremental base for the verdict reader's artifact listing. Each was continue-on-error and wrote nothing when no listing was found.
    • Without a carried base, the reader reads the FAIL index by exact name or lists every page. It reads more, never less, so no FAIL it counted before is dropped.
    • An unreadable result still fails closed through the same reader.
    • clear-escalations.mjs changes only a comment. babysit_verify_evidence.py changes only a docstring and a comment, and its carry_path still reads LISTING_CARRY_ENV.
    • No hold verdict path is narrowed. Removing the carry also removes an artifact input to the gate rather than adding one.
  • verify-cap.mjs carry trigger (L223):
    • The carry now runs when carrySteps(env) is non-empty, which happens only when the job names BABYSIT_RUN_CACHE or BABYSIT_VERIFY_HEAD_REFS.
    • The only callers are dispatch.mjs and feedback-dispatch.mjs, run from the two dispatch workflows. Both workflows name both variables, so the carry fires exactly as before.
    • The child scripts and their token (ACTIONS_TOKEN || GITHUB_TOKEN) are unchanged. No token scope grows and no new input reaches a lane.
  • Removed pr-merge-verify-listing upload, its scan-upload-7 credential scan, and the retention entry: this removes an artifact surface rather than exposing one. The scan went only because the upload it guarded went too.
  • Kill switch, trusted-trigger check, lane-token scope, token-broker config: unchanged.
  • docs/conventions/pr-pipeline.yaml: the only change removes the floor row for the deleted file. No lane slot, activity effect or other merge setting changes.

Throughput-phase exemption

One path-hold floor row is removed: .github/scripts/pr-merge/listing-carry.mjs, class gate. The removal appears in merge-holds.mjs, pr-pipeline.yaml, the generated hold_patterns in pr-require-checks.yml, and the review workflows' path lists. The file itself is deleted, and loading a file at that path again would take a change to a workflow that is still held. Under the owner's threat model this removal of a named friction hold (a path hold) is not a finding.

Other notes

  • Instruction surface: no standing instruction (CLAUDE.md, AGENTS.md, a rules file, a skill or agent body, a hook list) is deleted or softened.
  • Plugin manifests: none are touched.
  • Embedded text: the PR context has no text directing this lane.
  • Spend: the change lowers GITHUB_TOKEN API reads by about 9 calls per affected job. That is not a cost item.

critical-findings: 0

@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

claude-review reviewed 963a1570e4a4f6711e8dfb34a62521415f6e8ab0: read 21 of 21 changed file(s); 0 finding(s), 0 as inline comments.

Code review: PR #13040, removing the dead listing-carry lookups (head 963a1570)

No findings. I read every hunk of all 21 listed files. I also read the two whole-file deletions, .github/scripts/pr-merge/listing-carry.mjs and its test. The new head is a merge of origin/main. The PR's own change matches the head the previous round reviewed (7dcc812), and that round also found nothing.

What I checked

  • References left behind after the main merge. I searched the head again for listing-carry, BABYSIT_VERIFY_LISTING_CARRY, pr-merge-verify-listing and scan-upload-7. The only matches are:

    • the changelog fragments;
    • the reader's own LISTING_CARRY_ENV support, kept on purpose, at babysit_verify_evidence.py:307, and its unit test;
    • the new tests that check the names are absent.

    The merge from main brought in no new caller, env line or sparse-checkout entry that still points at the deleted script.

  • The carry trigger in verify-cap.mjs. The trigger changed from env.BABYSIT_VERIFY_LISTING_CARRY to carrySteps(env).length > 0. Both dispatchers still set BABYSIT_RUN_CACHE and BABYSIT_VERIFY_HEAD_REFS, so the one-time carry still runs on the first FAIL-cap read.

    • A job that names only the old variable now runs no carry. A new test covers that case.
    • The rewritten default-carry test now runs carry-run-cache.mjs against a stale pr-merge-carried.json.
  • pr-merge.yml. The removed steps had no id that another step reads. The one exception is scan-upload-7, and the upload that read it is removed with it. The merge job's list in the credential-scan test drops scan-upload-7 to match.

  • Merge-queue reader in pr-require-checks.yml. The listing-carry.mjs call, its env line and its sparse-checkout path are all removed. rotation.mjs stays in the sparse checkout. The transitive import walk in ci-lanes-pr-hold.test.sh now starts from head-ref-map.mjs and carry-run-cache.mjs only.

  • Hold floor. The listing-carry.mjs gate row is removed from every copy:

    • docs/conventions/pr-pipeline.yaml
    • HOLD_PATH_CLASSES in merge-holds.mjs
    • the path lists in both hosted review workflows
    • the generated hold_patterns in pr-require-checks.yml

    The pinned counts each drop by one: gate 56→55, high 75→74, author_review 16→15, classes 130→129. I did not recompute the sha256 pins because this lane has no shell. The author says sync-hold-floor.py --check and the test suites pass; I have not checked that.

  • Changelog fragments. Both are bump: patch. That fits: only workflow plumbing changes, verdicts do not, and the source-control part is comments and test pins. No plugin manifest changed.

  • Closing issue. The PR closes none, so there are no acceptance criteria to check.

Spend

The change only lowers GITHUB_TOKEN Actions API reads, by about 9 per job that used to run the carry. It starts no billed resource, so I set no hold.

Untrusted text

The PR context file and the prior-findings file contain no instructions aimed at this review.

@kyle-sexton
kyle-sexton added this pull request to the merge queue Nov 4, 2026
Merged via the queue into main with commit f095f1f Nov 4, 2026
76 checks passed
@kyle-sexton
kyle-sexton deleted the perf/dispatch-verdict-exact-name branch November 4, 2026 02:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant