Repository navigation
Move the three untested inline workflow step bodies into scripts/ci with self-tests - #26386
Merged
Merged
Conversation
…ripts/ci/scheduled-full-run-card.mjs with a --self-test The github-script step keeps its token, retries and permissions and now imports the module. The self-test's expected values were captured by running the inline body at 6390fe5 under the same doubles; the full call traces (bodies included) match on all seven scenarios. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADHkmQq9EYQdTQwmRutQTS
…/ci/test-nightly-tiers-card.mjs with a --self-test The github-script step keeps its token, retries and permissions and imports the module. Expected bodies were captured from the inline step at 6390fe5 under the same doubles; full call traces match on all seven scenarios. The moved bodies' self-tests run as one lint-ci-engine gate step. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADHkmQq9EYQdTQwmRutQTS
…s/ci/board-snapshot-r2-upload.sh with a self-test The step runs the script under the same env. The body is byte-identical to the inline block; the self-test (stub aws, throwaway archive with known committer times) passes against the inline body at 6390fe5 and against the moved script, and a dropped --delete turns it red. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADHkmQq9EYQdTQwmRutQTS
…ow needs Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADHkmQq9EYQdTQwmRutQTS
…which .gitignore does not match The root .gitignore ignores test-*.mjs, so the module the step imports never reached the branch under its first name. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADHkmQq9EYQdTQwmRutQTS
The R2 upload self-test used associative arrays, which bash 3.2 lacks; its roster is now parallel indexed arrays. The lint step runs its three self-tests through a run_self_test collector so one red does not hide the others. The nightly card self-test builds its log-tail fixture names instead of spelling them, and says it reads no tracked population. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ADHkmQq9EYQdTQwmRutQTS
os-zhuang
approved these changes
Oct 27, 2026
os-zhuang
marked this pull request as ready for review
October 27, 2026 01:49
os-zhuang
enabled auto-merge
October 27, 2026 01:49
Contributor
Author
席位核对 · ACCEPT · devx seat 2 · 2026-10-27T01:49ZSeat
PR 2 (switch to |
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.
Requested by Steve · project thread
Part of #26086
Clause-②: no
Metadata-protocol: none
维护者速读
scripts/ci/,每个都配了离线自测,并接进lint-ci-engine道。retries:和权限,只是改成 import 模块后薄调用;bash 主体逐字节不变。回滚就是 revert 这个 PR。scripts/ci/scheduled-full-run-card.mjs(调用和回调接线)、scripts/ci/nightly-tiers-card.mjs、.github/workflows/lint.yml新增的那一步。node scripts/ci/scheduled-full-run-card.mjs --self-test && node scripts/ci/nightly-tiers-card.mjs --self-test && bash scripts/ci/board-snapshot-r2-upload.selftest.sh,三行 ✓,共 7 + 7 + 5 个用例。.github/workflows/**),需要 GOVERNED_APPROVERS(os-zhuang 或 hotlong)批准;PR 1 的范围(只搬没有测试台的部分,还是照卡全搬)在项目线程里等 Steve 裁决。What changes
Three inline step bodies that no test reached move into
scripts/ci/, each with an offline self-test:scheduled-full-run-card.yml· File or refresh the card (github-script)scripts/ci/scheduled-full-run-card.mjs·fileCardSteptest-nightly-tiers.yml· File or refresh the card (github-script)scripts/ci/nightly-tiers-card.mjs·fileNightlyCardboard-snapshot.yml· Upload the archive to R2 (run)scripts/ci/board-snapshot-r2-upload.shscripts/ci/board-snapshot-r2-upload.selftest.sh, 5 cases / 27 checksawait import(GITHUB_WORKSPACE + '/scripts/ci/X.mjs')and calls the exported function with the samegithub/context/core. That keeps the token, theretries:/retry-exempt-status-codes:policy and the job'spermissions:exactly as they were. It followsscheduled-full-run-card.yml's existing import ofscripts/ci/scheduled-full-run.mjs. This is a deliberate deviation from the card's literal "the YAML step becomesnode scripts/ci/X.mjs": a barenodestep would need its own octokit, token plumbing and retry policy, which is a behaviour change. Both jobs already check out the repository.scripts/ci/board-snapshot-r2-upload.shis the inline block plus a header and theset -ethat GitHub's defaultbash -e {0}shell supplied.cmpagainst the YAML-parsed block is identical. The step keeps itsenv:and runsbash scripts/ci/board-snapshot-r2-upload.sh.require('fs')/require('path')became static imports.process.envbecame anenvparameter that defaults toprocess.env. The twonew Date()reads that stamp a body became an injectablenowthat defaults tonew Date(). The import ofscheduled-full-run.mjsbecame static.lint-ci-engine,Moved workflow step bodies self-test(with anid:andcontinue-on-error: true, so the lane verdict reads it), runs all three self-tests through the repo'srun_self_testcollector, so one red does not hide the others.board-snapshot.yml's header andscripts/pm/board-snapshot.mjs's docblock both said "copy FOUR files". The R2 step now needs a fifth, so both lists name it. That is the one prose edit, and it is the card's own carve-out: a literal the touched step makes false..gitignoreignorestest-*.mjs, so the nightly module could not be namedtest-nightly-tiers-card.mjs. Its first push silently left it out, and it is nownightly-tiers-card.mjs.Tests
Behaviour preservation was checked before each move, against the inline bodies at
6390fe52(main when this branch was cut):actions/github-scriptcompiles it) and then the module, under identical doubles, files and a frozen clock. It recorded every API call with its full parameters, bodies included, and everycorecall. The traces are identical:scheduled-full-run-card7/7 scenarios,nightly-tiers-card7/7. The committed self-tests pin the values taken from those traces. For the scheduled card the body is pinned as exactrenderBody(...)arguments, so a wording change inscheduled-full-run.mjsdoes not red this file. For the nightly card it is pinned as the SHA-256 of the inline body's bytes.6390fe52) and against the moved script. Negative control: with--deletedropped from the sync line, two checks go red.--self-test").Derived gate families:
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackgives 60 commands. Results are below. CI runs the rest.60 derived, 60 run, 0 red.
node scripts/pm/dispatch-gates.mjs --ran ran.listgives60 derived famil(ies) accounted for — 60 run, 0 NOT-MEASURED. The first round had 4 reds, all caused by this diff and fixed inb422bbdf:pnpm check:bash32-floor: the R2 self-test's roster useddeclare -A. It now uses parallel indexed arrays.node scripts/check-step-collectors.mjs(and its--self-test): the new lint step ran its three self-tests as a bare sequence. It now uses therun_self_testcollector.pnpm check:declared-population-live: the nightly self-test spelled its$RUNNER_TEMPfixture paths as literals, so they read as a declared population. It now builds them and carries ano-path-populationmarker.Not in the derived list, run by hand:
bash scripts/ci/board-snapshot-r2-upload.selftest.shpasses (5 cases, 27 checks), and the new lint step'srun:block, extracted from the YAML and run underbash -e, prints threePASSlines.Second-round results (exit code, command, seconds)
Acceptance notes
The card's premise holds for a minority of the volume. On
6390fe52: 20 inline bodies over 80 lines, 4,414 lines. Most of those lines are already exercised byte-for-byte by a gate that reads the YAML, so moving them buys no test reach and means rewriting the harness:check-merge-queue-triage-outcome.mjscompiles it as github-script does, 28 mutations; its P0 also pins that the job holds nocontents:grant, which a checkout for an import would needdocs-audit/check-drift-comment.mjsruns it against fixture diffscheck-cross-repo-closer-outcome.mjs(executes),check-closing-keyword-parity.mjs(mutates its regex)release-verify-npm.mjsbatteries 12/13 run the step textcheck-merged-branch-reaper-outcome.mjs(executes)ci/select-shard-timings-run.mjsruns bothci/select-shard-timings-run.mjspull_requestrun of the lane (theDRY_RUNleg)check-empty-changeset.mjscheck-platform-checklist-watchdog.mjsscans the script for board writes; moving it would blind that negative pincheck-closing-keyword-parity.mjsmutates its regexpublishjob checks out the VERSION COMMIT, so a moved guard would be read from the tree it is guardingchangeset versionhas written the working tree, so a moved validator would be read from the tree it validatesAfter this PR: 17 bodies over 80 lines, 4,010 lines (the census re-run on the branch). Whether the harnessed bodies should move anyway, which means rewriting about ten harnesses and granting
contents: readto jobs that hold none today, is the open scope question for this card's PR 1. It is in front of the maintainer in the project thread. This PR is the part both answers need.Verification
Tier H (
.github/workflows/**): draft until a GOVERNED_APPROVERS approval (os-zhuang, hotlong).Generated by Claude Code
🤖 Generated with Claude Code
https://claude.ai/code/session_01ADHkmQq9EYQdTQwmRutQTS