Repository navigation
ci(gates): every Lint and Type Check gate runs after a red and each lane ends in one verdict step; Test Core continues past a red package - #23212
Merged
Conversation
Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx Co-authored-by: Claude <noreply@anthropic.com>
…ct step per lane keeps the red; Test Core continues past a red package Every gate step of the eight Lint lanes and the four Type Check lanes now carries continue-on-error and an id; setup, install, the gate-family selector and the workspace builds stay fail-fast. Each lane ends with a Lane verdict step that reads every gate's outcome from the steps context, names the red ones and exits 1, so the lane and its required aggregate still conclude failure. It replaces the unmeasured-tail reporter pair, whose tail is now empty behind a gate red and exact (offline) behind a setup red. Test Core runs turbo with --continue=dependencies-successful and no longer skips the slice leg after a red whole-package leg; STATUS keeps the first non-zero exit. Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx Co-authored-by: Claude <noreply@anthropic.com>
…tes-run-all-verdict
Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx Co-authored-by: Claude <noreply@anthropic.com>
…erted in the next commit A dead docs anchor reddens 'Docs anchors resolve to real headings', the first gate of Lint · repo & tooling gates; a red test in @objectstack/types reddens one Test Core shard. Pushed only to read the jobs API: every later gate of that lane must execute, the lane verdict must name the red gate, and turbo must carry on past the red package. Reverted before review. Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
… fail-fast step that fails, reverted before review lint-eslint gains an id'd continue-on-error gate whose if: is false, so the verdict must read it as skipped in the steps context and turned off by its own condition; lint-scoped-erasure gains a failing step without continue-on-error before its gates, so the verdict must report the fail-fast failure and the two gates it hid. Reverted before review. Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx Co-authored-by: Claude <noreply@anthropic.com>
The head's tree is byte-identical to 5a7b95e again; the proof readings live in the dev report on the card. Claude-Session: https://claude.ai/code/session_012zwsLMxQBwHUYJgPyrpEvx Co-authored-by: Claude <noreply@anthropic.com>
Contributor
Author
维护者速读 · PR #23212(#23191,裁决 B 第 1 条 A1) ·
|
os-zhuang
approved these changes
Oct 13, 2026
os-zhuang
marked this pull request as ready for review
October 13, 2026 09:43
os-zhuang
enabled auto-merge
October 13, 2026 09:44
This was referenced Oct 13, 2026
This was referenced Oct 13, 2026
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.
Fixes #23191
Clause-②: no
Governed surface, Tier H (
.github/workflows/**, andAGENTS.md): this PR stays a draft until the maintainer approves it. No seat readies, queues or arms it.What the ruling binds (verbatim, #23177 ruling B, comment 6139629628, item 1)
What changes
.github/workflows/lint.ymlLint · *lanes and the 4Type Check · *lanes now carryid:andcontinue-on-error: true(eslint 2, repo & tooling 60, docs & code 55, CI/release/engine 58, scoped erasure 2, scoped slot/corpus 3, scoped tooling 3, PM dispatch-gates 1, source gates 33, workspace 2, debt ledger 2, consumer gates 19). Nothing else about any of them moved: base and head were parsed and every step compared with those two keys removed, and all 240 are identical (samerun:,if:,env:, order and comment).id: gate-families), the three workspace builds, andSave Turbo cache (main only).Lane verdict:if: ${{ !cancelled() }}, envOS_LANE_STEPS: ${{ toJSON(steps) }}andOS_LANE_JOB_STATUS: ${{ job.status }},run: node scripts/ci/lane-verdict.mjs. The two aggregates (Lint & Repo Gates,TypeScript Type Check) are unchanged: they read each lane'sresult, and a lane with a red gate still concludesfailurebecause its verdict step exits 1.actions: readscope (it bought only the reporter's jobs-API read). Behind a red gate the tail is now empty by construction; behind a failed setup step the verdict lists the gates that never ran, offline, from thestepscontext.Lane verdict self-test, inlint-ci-enginebesideAggregator roster gate: the instrument's own self-test, the one place the outcome-versus-conclusion read can go red (on a green tree both readings agree).GATE ORDER IS DELIBERATEnote (the ruling's 151–159) is nowEVERY GATE RUNS, AND ONE VERDICT STEP KEEPS THE RED: what is fail-fast and why, whycontinue-on-erroralone would trade the red for silence, what the verdict reads, what a new gate step needs, the one gate that feeds another (check:authorable-surfacewrites the treecheck:docsreads; the second refuses loudly on a missing tree), and that the order no longer shortens a red run. The⛔ Nor is it continue-on-errornote (502–503) stood in the reporter pair's block inlint-eslint; that block is gone, and the verdict step at the same site carries the rewritten note. Thelintaggregate's header and thelint-repo-tooling/lint-eslintheaders that repeated "stops at its first red" are corrected too.scripts/ci/lane-verdict.mjs(new; its header is the authority)GITHUB_WORKFLOW_REFnames it,GITHUB_JOBthe job): every step whosecontinue-on-erroris set. Thestepscontext holds only steps with anid:, so a roster taken from the context could never see a gate added without one; read from the file, such a gate is UNREAD and red, naming it.outcome, never itsconclusion: under the flag a failed step's conclusion issuccess.skippedis two facts, told apart by what is certain: a gate with its ownif:in a job stillsuccesswas turned off by that condition (the scoped families); any otherskippedis "did not run", red.job.statusnotsuccess) is red and names the gates it hid. Zero gates, an unparseable context or a missing input is a refusal (exit 3, PREREQUISITE NOT MET), never a pass.::errorannotation per red gate, and a job-summary table only when not green. Self-test: 31 cases over 9 named batteries with a floor and a handshake (the AGENTS.md shape)..github/workflows/ci.yml(Test Core)Run this shard's testspass--continue=dependencies-successful.breaks the leg loop: the CLI slice leg runs after a red whole-package leg too,STATUSkeeps the first non-zero exit and the step exits with it, so the shard is red exactly when it was before. The⛔ A failing leg STOPS the remaining onesnote is rewritten with the wall argument: the legs together are the shard's own planned work, so a red shard takes what a full one takes, inside the budget the 50-minute wall was sized to.check-shard-attestation's static pins are untouched (pnpm check:shard-attestationgreen below).AGENTS.md(one sentence)That job runs its gates sequentially, so the first stale artifact masks every one behind itbecame false with this change; it now says the lanes run every gate after a red, so one run reports every stale artifact. This file is outside the claim's declared surface; it is here because the change makes the sentence wrong.scripts/report-unmeasured-gate-tail.mjs(deleted)Its only caller was the step pair this PR replaces; nothing else in the tree imports or names it (
git grepover the whole tree: zero hits outside the two files this PR edits). Its self-test wiring left with it, andcheck:self-test-wiredis green below.The PR's mechanism assumptions, measured
outcomeversusconclusion. GitHub recordsoutcomebeforecontinue-on-erroris applied andconclusionafter it, so a failed gate under the flag readsoutcome: failure,conclusion: success. The verdict readsoutcome; the self-test batteryoutcome, never conclusionfeeds it exactly that shape and goes red ifconclusionwere read. The live half (that the runner really records it so, and that a skipped scoped gate appears in the context asskipped) is what the proof run below reads.continue-on-erroron these lanes: the guards that read the key pin job-level flags (check-required-contexts) or named steps elsewhere (ci.yml's attestation pair,pr-automation.yml, release.yml's gate job, the queue guard's toolchain install), none of which this touches. Thelint.ymlnote about ci: every Test Core run publishes the slowest test files and packages beside their pinned weights (maintainer-directed, part B measurement) #16454 is about ci.yml's timing steps and is unchanged. The aggregators andcheck-aggregator-roster.mjsare unchanged and green. The unmeasured-tail printing is replaced, not duplicated.a#testexits 1,cdepends ona): with the flagbandcran and turbo exited 1 withFailed: a#test; without it the run stopped ata(Tasks: 1 successful, 4 total), exit 1. The flag moves no task hash:--dry=jsonon this tree, plain against flagged, 5 of 5 identical, so main-seeded caches still replay.5301220aa, and its revert: a dead docs anchor that reddensDocs anchors resolve to real headings(the first gate ofLint · repo & tooling gates, 59 gates behind it) and a deliberately red test in@objectstack/types(one Test Core shard). The final head's tree is byte-identical to5a7b95e15, the commit before the throwaway. The readings from that run's jobs API (every later gate's step conclusion, the lane and aggregate conclusions, the verdict's named red, the Test Core shard's turbo tally) are in the dev report comment on ci(gates): every Lint and Type Check gate step runs after a red and each lane ends in one verdict step; Test Core continues past a failed package (#23177 ruling B, item A1) #23191; this body was written once, at creation, before that run finished.Local verification
Run on
1e695d6b1(this branch merged withorigin/mainat44e2d505c). The next commit,5a7b95e15, changed comments only (the rewritten note inlint-eslint, one sentence of the verdict script's header); the same union re-run on5a7b95e15was still running when this body was written, and its reconciliation is in the dev report.node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: 68 derived commands; all 68 run and reconciled with--ran: 64 exit 0, 4 NOT MEASURED (exit 3, PREREQUISITE NOT MET:check:dts-closure,check:dual-build-cjs-loads,check:lean-entry-closure,check:sourcemap-no-sources-contentread builtdist/trees; this diff changes no package source, and CI's Type Check and Build Core lanes run them). Among the 64:check:pm-dispatch-gates,check:required-contexts,check:shard-attestation,check:select-gate-families,check:self-test-wired,check:self-test-workflow-commands,check:step-collectors,node scripts/check-aggregator-roster.mjs(gate and self-test),check:workflow-status-functions,check:workflow-step-name-quoting,check:nul-bytes,check:pm-governed-prose,check:type-check-debt,node scripts/ci/lane-verdict.mjs --self-test.lint.yml, every lane, with a context built from the file: all 12 lanes OK when every gate succeeds (the four scoped lanes as "turned off by their own if:"), and every lane with an unconditional gate FAILED naming it when its first gate's outcome isfailureunder conclusionsuccess.scripts/ci/lane-verdict.mjs(eslint --no-inline-config --format json: 1 file, 0 errors, 0 warnings);eslint.config.mjsnever enables type-aware linting, so no untouched file's verdict can move, and the deleted script has no importer.Acceptance notes
check-test-completeness.mjs's NEITHER branch (a package that printed no summary on a run that did not complete is a note, not red) was written for a turbo that stopped at the first red. Under--continuenothing is cancelled except a failed build's dependents, so that note could now be upgraded to red for a silent package beside an unrelated red. Not done: it is the gate's own judging logic, which this card does not touch. Carrier: none.continue-on-erroris fail-fast again (still red, one red per cycle); without anid:the verdict reds the lane naming it. The new note abovejobs:says both. No structural gate for the first case was added (new gates default to no).维护者速读(草稿)
Lint · *八条与Type Check · *四条车道里的 240 个门禁步骤,前一个红了后面照跑;每条车道最后一步「Lane verdict」读每个门禁的结果,点名红的并退出 1,车道和两个必需聚合(Lint & Repo Gates、TypeScript Type Check)照样红。Test Core 的 turbo 加--continue=dependencies-successful,一个包红不再停掉同分片其它包。原「未测尾巴」报告步骤由裁决步取代,脚本删除。outcome不读conclusion、名单从 workflow 文件读、读不到即红,并有自测与 CI 实证。回滚:revert 本 PR 即恢复原 fail-fast 与报告步骤。Generated by Claude Code