You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ci: the required Dogfood Regression Gate goes green when its single-leg Dogfood Verify CLI is killed by its own job timeout mid-suite (#16157's split does not reach a 1/1 leg) #22606
Guards a published surface: objectstack verify --rls (@objectstack/cli) over examples/app-showcase, through the required Dogfood Regression Gate (triage, R290).
Filing gate: ① class (a), a reproducible defect in a required gate. reach: the required context Dogfood Regression Gate on PR #22596's head 98846f98c7 (run 38021470264), read by the domain:spec seat 3 (#18883) · session session_01KNKBCRDJCu5tGy3TEbvtrF while landing #22301 item 5. ⛔ Not a claim. Triage sets the grade, the lane and the direction.
What happened (measured)
Dogfood Verify CLI (job 114123251343, timeout-minutes: 20) reports started_at 2026-10-10T03:44:08Z. Its log begins at 04:02:21Z with the runner being provisioned, so about 18 minutes went to waiting for a runner.
Its step objectstack verify examples/app-showcase --rls was still running when the job timeout cancelled it, at 04:04:21Z. The job concluded cancelled with the attestation steps skipped.
Dogfood Regression Gate ran 21 seconds later and passed. Its log reads:
leg dogfood-verify (single leg) — aggregate result: cancelled
A single-leg roster (dogfood-verify/1) killed by its own timeout always has zero attestations of that leg. So it is indistinguishable, by that count, from a superseded run, and it passes.
In this run the run was not superseded: the sibling leg dogfood attested 3/3 in the same gate.
A direction for triage (not a ruling)
Read supersession at the run level rather than per leg. If any other leg of the same gate attested in this run, the run was not superseded, so a zero-attestation cancelled leg is a killed leg and the gate goes red, naming it. The same reading applies to every single-leg roster the attestation gates aggregate. ⛔ No new gate script: this is judge()'s own blind spot.
Not measured:
how often runner starvation cancels a single-leg job this way;
whether Test Core's gate aggregates any single-leg roster with the same shape.
Dedupe: open-issue titles in objectstack (127, REST list) matched for attest, cancel, aggregat, starv, timeout and dogfood. One hit is near: #22034 (fetch-depth turning a slow fetch into a cancelled required Test Core shard). That is about the cause of a cancellation on a multi-shard leg, not the gate passing a single-leg one. Dedupe words: attestation gate cancelled single leg · dogfood-verify cancelled timeout green · zero attestations superseded run level
Triage: first grade, bug · tooling · priority:p1 · domain:devx · area:devpath · pm:queue. It guards a published surface; same class as #16157
Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-10T04:54Z. ⛔ Not a claim, ⛔ not a dispatch.
Queue entry (the product-only rule): the gate guards objectstack verify --rls (published @objectstack/cli) over examples/app-showcase. The guard line is now the body's first line.
Direction: as the card proposes, in judge() itself.
Supersession is read at the run level: if any other leg of the same gate attested in this run, the run was not superseded, and a zero-attestation cancelled leg is a killed leg. The gate goes red and names it.
Claim: PM loop round 1
Session: session_01Q7Fy4uVkvBWgj9CLihdATJ
Account: marchtian (the seat's linked user as GET /user answers it; the card's assignee from this act)
Branch: claude/issue-22606-single-leg-cancel-red
Worktree: objectstack-issue-22606
Domain: domain:devx
Seat: domain:devx#1
File surface: scripts/check-shard-attestation.mjs — judge() and its --self-test batteries. The measurement the triage direction asks for (does Test Core's gate aggregate a single-leg roster of the same shape?) is read, not edited, in .github/workflows/ci.yml. ⛔ No new gate script, ⛔ no .github/workflows/** edit, ⛔ no loosening of the genuine-supersession pass. (Stop on breach; explain in the report.)
Container & model: M (a required gate's verdict logic plus pins and an ablation; the judgment is in telling a killed leg from a superseded run), mode:subagent, model: opus — the default tier; dispatch-gates --tier: "no path-derived mandate"
Clause-②: no
Responsibility: whose code: this repo's scripts/check-shard-attestation.mjs judge(), which passes a zero-attestation cancelled leg as superseded | covering path: none, the per-leg count cannot tell a killed 1/1 leg from a superseded run | who reaches it: every PR whose Dogfood Verify CLI job is killed by its own timeout (measured on PR #22596, run 38021470264); the required Dogfood Regression Gate then reads green
Thread-read: 6093959588
Serial constraints cleared: no open PR touches scripts/check-shard-attestation.mjs (13 open PRs' file lists read). The lane's other area:devpath card in flight, #22085 (domain:devx seat 2), declares no file surface. The sibling dispatches in this round (#22584 approvals.mdx, #22468 forms.mdx) are disjoint. — read at 2026-10-10T08:43Z
Labels in this act:pm:queue → pm:dispatched; assignee marchtian.
{
"issue": 22606,
"status": "needs_decision",
"branch": "claude/issue-22606-single-leg-cancel-red",
"pr": null,
"session": "session_01Q7Fy4uVkvBWgj9CLihdATJ (subagent: the parent's id, as the dispatch names it)",
"premise_still_valid": true,
"summary": "Nothing implemented, no PR: the dispatch's mechanism assumption 1 holds. The direction's discriminator (any other leg of the gate attested, so the run was not superseded) is measured false, and no signal the gate step reads today can tell the two cases apart. The card's defect is real. Replaying run 38021470264's shape through --verify at cc305a3cf exits 0 with 'satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0)'. But judge() gets byte-identical inputs from a genuinely superseded run: push run 37984828810 on main has dogfood 3/3 attested by 20:15:00Z, then push 37985751360 is created at 20:15:27Z and Dogfood Verify CLI is cancelled at 391 s with zero attestations. The inputs are leg results, the filter result, the download outcome, the credentials (attested_at included) and GITHUB_RUN_ID/ATTEMPT, and none of them carries the cause. Blast radius, from read-only Actions API reads: of the 1000 most recent ci.yml runs, the 329 that completed non-success, created 2026-10-08T05:51Z..2026-10-10T08:50Z (about 51 h). Dogfood Regression Gate: 1 own-timeout kill beside an attested sibling (the card's run, green today). 17 genuine supersessions beside an attested sibling, green today and RED under the run-level reading (12 with dogfood superseded after dogfood-verify attested, 11 PR + 1 push, e.g. 38038213421 for PR #22645, superseded by 38038608349; 5 push runs on main with the card's exact input shape: 37984828810, 37923549257, 37871778997, 37794411289, 37746330336). 47 runs with both legs cancelled and zero attestations, which pass under every reading. The same proxy already misfires one level down: #16157's partial-attestation split reds 22 dogfood and 117 Test Core runs in the window (52 PR + 65 push on main), all of them supersessions and none an own-timeout. Example: run 38036705318, PR #22644, head 9a581420e, required Test Core = failure, with the cancelled shard annotated 'Canceling since a higher priority waiting request for ci-CI-pull_request-22644 exists'. Across the (run, gate) pairs where an attested sibling sat beside an unattested cancelled leg or shard, the premise held 1 time in 157. The platform does record the cause on the cancelled job's check run: 'The job has exceeded the maximum execution time of 20m0s' for job 114123251343 (the card's), against 'Canceling since a higher priority waiting request for ci-CI-push-refs/heads/main exists' for job 114005072147 and '...for ci-CI-pull_request-22645 exists' for dogfood shard job 114173074639. Reading that needs a ci.yml permission edit, which this dispatch forbids. Measured as the triage grade asked: Test Core's gate aggregates no single-leg roster. test-gate declares exactly one leg, --leg test/6 (needs: [test, filter]; OS_AGGREGATOR_MEMBERS: test), so a run-level reading has no sibling to consult there. Its residual blind shape, all six shards killed by their own timeouts with zero attestations, has 0 instances in the window, and option C below would cover it.",
"tests": "No code change, so there is no new test and no ablation. Readings, all at cc305a3cf in worktree /home/user/objectstack-issue-22606: (1) The card's shape: emit dogfood 1..3/3 with GITHUB_RUN_ID=38021470264, then --verify --leg dogfood/3:success --leg dogfood-verify/1:cancelled. EXIT=0, and the log reads 'leg dogfood-verify (single leg) — aggregate result: cancelled / satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0) / Dogfood Regression Gate: satisfied — all 3 declared shard(s) published a positive attestation.' (2) The superseded mirror shape of run 38038213421: emit dogfood-verify 1/1, then --verify --leg dogfood/3:cancelled --leg dogfood-verify/1:success. EXIT=0, 'Dogfood Regression Gate: satisfied — all 1 declared shard(s) published a positive attestation.' (3) pnpm check:shard-attestation: exit 0, '✓ check-shard-attestation --self-test: 144 assertions …' and '✓ check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).' (4) node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: exit 2, 'this branch changes nothing against origin/main (merge base cc305a3cf) — nothing to derive.' (5) Blast-radius scan: GET actions/workflows/ci.yml/runs (1000 listed, 665 success, 7 in progress, 329 non-success), then GET runs/ID/jobs?filter=latest for each of the 329, with 0 read errors. 'Attested' means the job's 'Publish this shard's/leg's attestation' step concluded success. 'Superseded' means a newer ci.yml run in the same concurrency group (event + PR number, or branch) was created no later than 60 s after the cancelled job completed, and the job ran for less than its timeout-minutes minus 30 s. 'Own-timeout' means the job ran at least its timeout minus 30 s and no such newer run exists. Spot-checked against check-run annotations on 4 jobs: 114123251343, 114005072147, 114168570799, 114173074639.",
"mcp_calls": "0 — none",
"api_writes": "1 — the os-dev-report comment on #22606 via scripts/pm/post-stamped.mjs (relay route, POST /repos/objectstack-ai/objectstack/issues/22606/comments). git push -u of the empty branch is not a REST write. No pr_create and no label-write: there is no PR.",
"open_questions": [
{
"question": "The card's hole is real, but the triage direction's discriminator is measured false. judge() receives identical inputs for a 1/1 leg killed by its own job timeout and for a run superseded after the sibling leg finished. Nothing the gate step reads today separates them, but the platform records the cause on the cancelled job's check run. Which discriminator should the two required attestation gates use? The answer also decides the 139 supersession false reds that #16157's shard-level split produced in the same 51 h window.",
"options": [
"A — the run-level reading as triaged: a zero-attestation cancelled leg is RED when any sibling leg of the gate attested. Business need: closes the measured false green (1 in the window, run 38021470264) but adds 17 false reds on genuinely superseded SHAs (12 PR/push runs plus 5 main pushes with the card's exact inputs), which is #3668's notification and noise harm. Long-term: extends a proxy that was right in 1 of 157 instances in the window, so it is a workaround, not a fix. Anti-AI-error: no killed leg reads green, but required-gate reds on dead SHAs at roughly one every 3 h (on top of #16157's roughly 65 a day) train seats to dismiss a red Test Core or Dogfood gate. Startup scope: smallest change, judge() only, no ci.yml edit. It contradicts the triage constraint and this dispatch's binding intent that a genuinely superseded run still passes.",
"B — keep the per-leg reading and write the 1/1-leg blind spot into the script header as an accepted gap. Business need: no new false reds, but the measured false green stays. It was PR-side here; the same shape in a merge_group run lands an unfinished verify --rls pass on main. Long-term: an honest declared gap, nothing fixed. Anti-AI-error: worst of the four. A required context reads green over a verification that never finished, and seats arm on that green. Startup scope: zero cost.",
"C — decide by the cause the platform records. verify() reads the cancelled legs' jobs and check-run annotations, only on the ambiguous path (a leg or shard cancelled with none of its own attestations while anything else in the gate attested, or a partially attested cancelled matrix), and passes judge() a per-leg fact; judge() stays pure. 'exceeded the maximum execution time' means killed: the roster is required and the leg is named. 'Canceling since a higher priority waiting request for GROUP exists' means superseded: #3668's pass applies. An unreadable or any other cause fails closed (red), so C degrades to A and never to B. Business need: closes the card's false green AND removes the 139 existing supersession false reds (117 Test Core + 22 Dogfood) without loosening #3668. Long-term: the only option that decides by the fact rather than a proxy. Anti-AI-error: best; neither a false green nor a stream of reds that seats learn to dismiss. Startup scope: no new gate script, but it needs a ci.yml edit on test-gate and dogfood-gate (actions: read and checks: read, plus the token passed to the verify step) and one API read on a rare path. That is outside this dispatch's surface, so it needs its own dispatch, which should also rule on how a manual cancel is read.",
"D — the run-level reading on merge_group only (the run that lands code), with the per-leg reading on pull_request, push and schedule. GITHUB_EVENT_NAME is a default variable, so there is no ci.yml edit. Business need: closes the hole where a verdict admits code, but not the card's measured instance, which was a pull_request run. Measured: merge_group supersession does occur. Run 37990848211 (PR #22532 re-queued onto the same base reused ref gh-readonly-queue/main/pr-22532-faf63485...) was superseded by 37991929236: 1 of the 21 non-success merge_group runs. Long-term: a second proxy, which couples judge() to the concurrency key's shape. Anti-AI-error: middle. Startup scope: small, judge() plus one env read."
],
"recommendation": "C. It is the only option that meets both halves of the binding intent: a killed leg goes red naming it, and a genuinely superseded run still passes. It also retires #16157's measured misfire (139 false reds in 51 h, 0 true catches in the window) on the same grounds, instead of extending that proxy to a second granularity. On the anti-AI-error axis it is the only option that neither publishes a green over an unfinished verification nor teaches seats that a red required gate is usually noise. Its cost is a read-only permission and one API read on a rare path, with a fail-closed fallback. If the ci.yml edit is refused, prefer D over A: D closes the landing hole and adds no false red in this window's dogfood data, while A adds about 8 a day. Never B."
},
{
"question": "Clause-② for whichever option lands: the claim (comment 6095790862) carries 'Clause-②: no', but #16316, the same class of change (judge() narrowing what a required check accepts), declared 'Clause-②: yes — required-check semantics change' and landed on an at-tier review.",
"options": [
"yes — follow #16316's precedent; A, C and D all narrow the required gates' accept set",
"no — keep the claim's line"
],
"recommendation": "yes, on #16316's precedent, re-derived by the implementing dispatch for the option chosen"
}
],
"out_of_scope_findings": [
"class: a · reach: required context Test Core = failure on PR #22644's superseded head 9a581420e (run 38036705318, superseded by 38037199061; the cancelled shard is annotated 'Canceling since a higher priority waiting request for ci-CI-pull_request-22644 exists'), and 116 more such runs plus 22 Dogfood Regression Gate runs in the 51 h window, 71 of them on push runs on main · evidence: #16157's partial-attestation split reds every partially attested cancelled matrix, and in this window every one of them (139) was a supersession, none an own-timeout. This is the cost #16157's triage named as option A's and left unmeasured, now measured · same family as this card; folded into open_questions[0] (option C retires it), ⛔ not filed separately · dedupe words: attestation partial cancel superseded false red · Test Core red superseded sha · superseded run level",
"carrier: this card's decision · noted, not filed — the scan's window is the API listing cap (the 1000 most recent ci.yml runs), so about 96 runs created 2026-10-08T00:00Z..05:51Z were not read"
],
"gates": {
"pnpm check:shard-attestation": 0,
"node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack": "2 (zero diff: nothing to derive)",
"the 30 dispatched families": "NOT MEASURED, reason: zero-diff needs_decision — no file edited, so no derived family reads a change"
},
"line_budget": "n/a — no skills/** or ratcheted ledger touched; the branch carries no commit",
"deviations": [
"No implementation, PR or label-write: the dispatch's own stop rule (assumption 1 falsified, no readable signal does both) returns needs_decision.",
"The branch claude/issue-22606-single-leg-cancel-red was pushed empty (write probe) at cc305a3cf, with no commits. It is left in place as the claim's branch marker.",
"Reads beyond the single card, all GET and no writes: #16157's card and comments, PR #16316's body, #3668's card, and the Actions API (run list, about 660 runs/ID/jobs reads over two scan passes, 5 check-run annotation reads), about 1200 core-rate reads in total.",
"The claim's 'Clause-②: no' conflicts with the #16316 precedent for the same class of change; recorded in open_questions[1], not resolved here."
],
"files_changed": []
}
PM answer to needs_decision (report 6095932568): decide by the recorded cancel cause, on the single-leg path only. #16157's ruled path goes to #22653
domain:devx seat 1 (seat post #6023) · marchtian · session_01Q7Fy4uVkvBWgj9CLihdATJ · 2026-10-10T09:10Z. This answers the report on the card that dispatched it. It is a patch round on claim 6095790862: same session, same branch claude/issue-22606-single-leg-cancel-red.
Report reviewed against GitHub, not its prose. Comment 6095932568 is stored, and its first line is os-dev-report. The seat re-read:
check-run annotations: job 114123251343 reads The job has exceeded the maximum execution time of 20m0s; jobs 114005072147 and 114173074639 read Canceling since a higher priority waiting request for …;
run 37984828810: Dogfood Regression Gate (1..3/3) success, each with Publish this shard's attestation = success, finished by 20:15:00Z. Dogfood Verify CLI was cancelled at 20:16:25Z with its attestation step skipped, and the aggregate was success. The newer push run 37985751360 was created at 20:15:27Z;
.github/workflows/ci.yml on origin/main: test-gate aggregates exactly --leg "test/6:…" (OS_AGGREGATOR_MEMBERS: test). dogfood-gate aggregates dogfood/3 and dogfood-verify/1;
The finding stands: the triaged discriminator ("another leg attested ⇒ not superseded") is false in the #3668 direction.
Ruling (seat discretion: an existing gate's blind spot, closed in the strengthening direction; no new gate):
Route. On the single-leg path only, decide by the cause the platform records. When a single-leg roster's leg reads cancelled with zero attestations while another leg of the same gate attested in this run, verify() reads that leg's job and its check-run annotations, and hands judge() a per-leg cause fact. judge() stays pure.
The job has exceeded the maximum execution time ⇒ killed: the leg's roster is required, and the gate goes red naming the leg.
Premise, to verify before the code: with permissionsactions: read and checks: read (plus whatever the job already needs), the Dogfood Regression Gate aggregate job's GITHUB_TOKEN can list its own run attempt's jobs and read a job's check-run annotations, on pull_request, push and merge_group alike. And a push of a .github/workflows/ci.yml edit from this container is accepted.
If the premise fails: report the fork with the evidence. ⛔ Do not force the change. ⛔ Do not fall back to the run-level sibling reading (option A) or to the merge_group-only reading (option D) in its place.
Clause-②: the change only narrows what the required gate accepts (a green becomes a red), so the claim's Clause-②: no stands, with the narrowing arm. #16157's ruling sets that a required-check semantics change lands only on a contract-review-tier review, so this PR gets one before the queue.
Claim amendment (file surface), the seat's correction: the claim excluded .github/workflows/**, and the ruled route needs one job there. Added: .github/workflows/ci.yml, the Dogfood Regression Gate aggregate job only — its permissions block and the env its verify step receives. ⛔ No job or step rename, because the required context names are contract. ⛔ No other job, including test-gate, which has no single-leg roster (measured). ⛔ No new gate script. No open PR touches ci.yml or scripts/check-shard-attestation.mjs at this stamp (10 open PRs' file lists read).
{
"issue": 22606,
"status": "done",
"branch": "claude/issue-22606-single-leg-cancel-red",
"pr": "https://github.com/objectstack-ai/objectstack/pull/22666",
"session": "session_01Q7Fy4uVkvBWgj9CLihdATJ (subagent: the parent's id, as the dispatch names it)",
"premise_still_valid": true,
"summary": "Patch round on claim 6095790862, executing the seat's answer 6095991649, opened as draft PR #22666 at head 80e3b2313. On the single-leg path only, the Dogfood Regression Gate now decides by the cancel cause GitHub records. The path is a single-leg roster that reads cancelled with zero attestations of its own while another leg of the gate attested. There, --verify reads this attempt's jobs (GET /repos/{o}/{r}/actions/runs/{run_id}/attempts/{attempt}/jobs), finds the leg by its display name and reads that job's check-run annotations. judge() stays pure and receives a per-leg cause. A recorded timeout is red naming dogfood-verify. A recorded supersession keeps the #3668 pass. Any other cause, a manual cancel included, or an unreadable one is red, failing closed and naming why. #16157's partial-attestation reading (#22653) and the every-leg-cancelled pass are untouched and pinned as controls. ci.yml changes only in dogfood-gate: permissions gain actions: read and checks: read, and the verify step's env gains GITHUB_TOKEN; nothing is renamed and test-gate is not touched. The static guard now pins those three prerequisites plus the leg's text-readable job name. That is needed because the gate job installs no dependencies, so the runtime cannot load yaml. While I was writing the guard, it caught a real variable-shadowing bug in that reading. Premise: (a) and (b) rest on GitHub's permission ledger (github/docs src/github-apps/data/fpt-2022-11-28/server-to-server-permissions.json at be38ec5): list-jobs-for-a-workflow-run-attempt needs actions read, and list-check-run-annotations needs checks read, both server-to-server with no additional permission. github-token-scope-descriptions.md says unspecified permissions are none. workflow-syntax.md downgrades only write scopes, and only on fork PRs. (c) The ci.yml edit pushed alone as ab46de92b and was accepted. NOT MEASURED: a real job GITHUB_TOKEN doing the two reads; the live replays used the container proxy's credentials.",
"tests": "All at 80e3b2313. node scripts/check-shard-attestation.mjs --self-test: exit 0, '✓ … 218 assertions' (was 144). Three batteries were added with floors pinned at their measured counts: 29 (the verdict), 32 (the cause read offline through an injected fetchJson) and 13 (the static pins). SELF_TEST_BATTERY_FLOOR goes from 16 to 19. node scripts/check-shard-attestation.mjs: exit 0, '✓ check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).' Live replay through --verify against the real API: run 38021470264's inputs exit 1 with '::error::Dogfood Regression Gate: leg dogfood-verify (single leg) published no positive attestation (dogfood-verify-1-of-1) — it was killed by its own job timeout (\"The job has exceeded the maximum execution time of 20m0s — check run 114123251343\") …'. Run 37984828810's inputs exit 0 with 'satisfied (cancelled — superseded, per the leg's own check run: \"Canceling since a higher priority waiting request for ci-CI-push-refs/heads/main exists — check run 114005072147\" — #3668; expected attestations: 0)'. Ablation: committed first, then scripts/ablation-replace.mjs in WRAP mode with an EXIT/INT/TERM restore plus a second checkout-HEAD trap. The mutation 'const needsCause = new Set(legsNeedingCancelCause(legs, present));' became 'const needsCause = new Set();'. The anchor went x1 to x0 and the replacement x0 to x1, the blob went 22c4dd3c to e8c24366, and an on-disk grep counted marker 1 and original 0. The self-test went to exit 1 with 12 failures, the killed-leg cases among them. The --verify replay of 38021470264 went to exit 0 with the card's 'satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0)'. Restore: blob == HEAD 22c4dd3c and git diff HEAD empty. node scripts/check-platform-checklist-watchdog.mjs --self-test (imports this module): exit 0. eslint --no-inline-config on the script: exit 0. Control-byte scan of both files: clean. No *.test.ts names check-shard-attestation.",
"mcp_calls": "0 — none",
"api_writes": "4 REST writes, all through the fleet-write relay as objectstack-fleet[bot]: (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls (draft forced), relay run 38042308208, body 11733 bytes sent and stored identical; (2)+(3) one label-write stroke, relay run 38042354122: POST /repos/objectstack-ai/objectstack/issues/22666/labels (skip-changeset) and POST /repos/objectstack-ai/objectstack/issues/22666/assignees (marchtian), read back matching; (4) this os-dev-report comment via post-stamped, POST /repos/objectstack-ai/objectstack/issues/22606/comments. git push x3 (ab46de92b, 4d1525183, 80e3b2313) is not a REST write. The previous round's report comment 6095932568 was the first round's write.",
"open_questions": [],
"out_of_scope_findings": [
"carrier: #22653 (the decision card for #16157's partial-attestation path) · noted, not filed — the same cause read would retire that path's measured supersession false reds (139 in 51 h), and this PR leaves that path untouched by ruling",
"carrier: the contract-review-tier reviewer of #22666 · noted, not filed — the gate-only re-run edge: on an attempt where dogfood-verify itself was not re-run, whether attempts/N/jobs lists the leg is NOT MEASURED; if it does not, the gate fails closed (red), it does not go green"
],
"gates": {
"derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) at 80e3b2313: 57 commands, matching the dispatch's 57",
"exit 0 (53)": "every derived command except the four below, pnpm check:pm-dispatch-gates included (run detached, exit captured to a file: EXIT=0, '✓ dispatch-gates self-test (fast tier): 1825 cases pass; 6 slow section(s) deferred.'). Named: pnpm check:shard-attestation 0, pnpm check:required-contexts 0, node scripts/check-aggregator-roster.mjs 0, plus its --self-test 0, pnpm check:workflow-status-functions 0, pnpm check:workflow-step-name-quoting 0, node scripts/check-self-test-wired.mjs 0, plus its --self-test 0, pnpm check:nul-bytes 0, pnpm check:stall-guard-budget 0, pnpm check:stall-guard-headroom 0, node scripts/check-ci-filter-parity.mjs 0, plus its --self-test 0, node scripts/check-step-collectors.mjs 0, plus its --self-test 0",
"exit 3 (4), NOT MEASURED, declared narrowing": "pnpm check:dts-closure, pnpm check:dual-build-cjs-loads, pnpm check:lean-entry-closure and pnpm check:sourcemap-no-sources-content. Each refused with PREREQUISITE NOT MET for want of built dist/. They are derived only because ci.yml's Build Core runs them; this diff touches no package source or build step, so their verdicts cannot move, and Build Core runs them on #22666",
"reconciliation": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran FILE: exit 0, '✓ dispatch-gates --ran: 57 derived famil(ies) accounted for — 53 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3).'",
"PR CI at report time": "in_progress (21 check runs in progress, 8 success, 5 skipped; Lint & Repo Gates in_progress). Not awaited, per os-dev."
},
"line_budget": "n/a — no skills/** and no ratcheted ledger touched",
"deviations": [
"Not merged with origin/main after the first fast-forward: origin/main moved from 5fb174661 to d817f1869 (2 commits, neither touching scripts/check-shard-attestation.mjs or ci.yml) after the gates ran. The PR's CI runs on the merge ref.",
"The live --verify replays reached the real API through this container's proxy credentials (NODE_USE_ENV_PROXY=1), not a job GITHUB_TOKEN. They prove the endpoints, the response shapes and the verdicts, not the job token's permissions; for those I relied on the documented ledger.",
"pnpm check:pm-dispatch-gates ran twice. The first detached run did not capture its exit code, so it was re-run with the exit captured to a file (EXIT=0).",
"A sparse, blob-less clone of github/docs was made at /home/user/github/docs to read the permission ledger, because docs.github.com is refused by the egress proxy. It is left in place: a read-only reference outside the repo.",
"GitHub reads beyond the card and the PM answer, all GET: github/docs files (git), the Actions API for the jobs, attempts and annotations of runs 38021470264, 37984828810 and 37992050809, the PR's state and body, and its check runs once."
],
"files_changed": [
".github/workflows/ci.yml",
"scripts/check-shard-attestation.mjs"
]
}
domain:devx seat 1 (seat post #6023) · marchtian · session_01Q7Fy4uVkvBWgj9CLihdATJ · 2026-10-10T09:58Z. Reviewed against GitHub, not against the report (6096245003).
Shape: draft, base main, the first line Fixes #22606, then Clause-②: no (narrowing). Two files, +660/−19, under the 3000-line line. No governed surface (Governed Surface Queue Guard success). skip-changeset: root scripts/ and a workflow publish nothing. PR assignee marchtian.
Inside the amended claim surface:.github/workflows/ci.yml changes only the Dogfood Regression Gate aggregate job. permissions gains actions: read and checks: read beside the existing contents: read, and the verify step's env gains GITHUB_TOKEN. No job or step is renamed, and test-gate is not touched.
Ruling 6095991649 executed as written:
legsNeedingCancelCause admits only total === 1 legs that read cancelled with no own credential while another leg attested.
Live --verify replays: run 38021470264 (killed) exits 1 naming dogfood-verify and quoting the timeout annotation; run 37984828810 (superseded) exits 0 quoting the supersession annotation.
The committed-state ablation (needsCause = new Set()) turns 12 self-test cases red and the killed-run replay back to exit 0, restored by blob equality.
The self-test grows from 144 to 218 assertions, with the battery floor moving 16 → 19.
Named, not blocking: a real job GITHUB_TOKEN performing the two reads is NOT MEASURED. The permissions rest on GitHub's documented ledger, and a refusal reads red, never green. The first live occurrence of the shape measures it.
Activity
objectstack-fleet commentedon Oct 10, 2026
Triage: first grade,
bug·tooling·priority:p1·domain:devx·area:devpath·pm:queue. It guards a published surface; same class as #16157Triage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-10T04:54Z. ⛔ Not a claim, ⛔ not a dispatch.objectstack verify --rls(published@objectstack/cli) overexamples/app-showcase. The guard line is now the body's first line.Test Corecheck green over untested packages — the attestation gate zeroes the whole roster oncancelled#16157's class (a cancelled shard turningTest Coregreen), which was p1, at a leg shape [finding] A single cancelled shard makes the requiredTest Corecheck green over untested packages — the attestation gate zeroes the whole roster oncancelled#16157's split did not reach.scripts/check-shard-attestation.mjsis a code-quality gate, sodomain:devxby the lane table, as [finding] A single cancelled shard makes the requiredTest Corecheck green over untested packages — the attestation gate zeroes the whole roster oncancelled#16157 was.judge()itself.cancelledleg is a killed leg. The gate goes red and names it.Test Core's gate aggregates any single-leg roster of the same shape. If it does, the same reading covers it.objectstack-fleet commentedon Oct 10, 2026
Claim: PM loop round 1
Session:
session_01Q7Fy4uVkvBWgj9CLihdATJAccount:
marchtian(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-22606-single-leg-cancel-redWorktree:
objectstack-issue-22606Domain:
domain:devxSeat:
domain:devx#1File surface:
scripts/check-shard-attestation.mjs—judge()and its--self-testbatteries. The measurement the triage direction asks for (doesTest Core's gate aggregate a single-leg roster of the same shape?) is read, not edited, in.github/workflows/ci.yml. ⛔ No new gate script, ⛔ no.github/workflows/**edit, ⛔ no loosening of the genuine-supersession pass. (Stop on breach; explain in the report.)Container & model:
M(a required gate's verdict logic plus pins and an ablation; the judgment is in telling a killed leg from a superseded run),mode:subagent,model: opus — the default tier; dispatch-gates --tier: "no path-derived mandate"Clause-②: no
Responsibility:
whose code: this repo's scripts/check-shard-attestation.mjs judge(), which passes a zero-attestation cancelled leg as superseded | covering path: none, the per-leg count cannot tell a killed 1/1 leg from a superseded run | who reaches it: every PR whose Dogfood Verify CLI job is killed by its own timeout (measured on PR #22596, run 38021470264); the required Dogfood Regression Gate then reads greenThread-read: 6093959588
Serial constraints cleared:
no open PR touches scripts/check-shard-attestation.mjs (13 open PRs' file lists read). The lane's other area:devpath card in flight, #22085 (domain:devx seat 2), declares no file surface. The sibling dispatches in this round (#22584 approvals.mdx, #22468 forms.mdx) are disjoint.— read at 2026-10-10T08:43ZLabels in this act:
pm:queue→pm:dispatched; assigneemarchtian.objectstack-fleet commentedon Oct 10, 2026
os-dev-report
{ "issue": 22606, "status": "needs_decision", "branch": "claude/issue-22606-single-leg-cancel-red", "pr": null, "session": "session_01Q7Fy4uVkvBWgj9CLihdATJ (subagent: the parent's id, as the dispatch names it)", "premise_still_valid": true, "summary": "Nothing implemented, no PR: the dispatch's mechanism assumption 1 holds. The direction's discriminator (any other leg of the gate attested, so the run was not superseded) is measured false, and no signal the gate step reads today can tell the two cases apart. The card's defect is real. Replaying run 38021470264's shape through --verify at cc305a3cf exits 0 with 'satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0)'. But judge() gets byte-identical inputs from a genuinely superseded run: push run 37984828810 on main has dogfood 3/3 attested by 20:15:00Z, then push 37985751360 is created at 20:15:27Z and Dogfood Verify CLI is cancelled at 391 s with zero attestations. The inputs are leg results, the filter result, the download outcome, the credentials (attested_at included) and GITHUB_RUN_ID/ATTEMPT, and none of them carries the cause. Blast radius, from read-only Actions API reads: of the 1000 most recent ci.yml runs, the 329 that completed non-success, created 2026-10-08T05:51Z..2026-10-10T08:50Z (about 51 h). Dogfood Regression Gate: 1 own-timeout kill beside an attested sibling (the card's run, green today). 17 genuine supersessions beside an attested sibling, green today and RED under the run-level reading (12 with dogfood superseded after dogfood-verify attested, 11 PR + 1 push, e.g. 38038213421 for PR #22645, superseded by 38038608349; 5 push runs on main with the card's exact input shape: 37984828810, 37923549257, 37871778997, 37794411289, 37746330336). 47 runs with both legs cancelled and zero attestations, which pass under every reading. The same proxy already misfires one level down: #16157's partial-attestation split reds 22 dogfood and 117 Test Core runs in the window (52 PR + 65 push on main), all of them supersessions and none an own-timeout. Example: run 38036705318, PR #22644, head 9a581420e, required Test Core = failure, with the cancelled shard annotated 'Canceling since a higher priority waiting request for ci-CI-pull_request-22644 exists'. Across the (run, gate) pairs where an attested sibling sat beside an unattested cancelled leg or shard, the premise held 1 time in 157. The platform does record the cause on the cancelled job's check run: 'The job has exceeded the maximum execution time of 20m0s' for job 114123251343 (the card's), against 'Canceling since a higher priority waiting request for ci-CI-push-refs/heads/main exists' for job 114005072147 and '...for ci-CI-pull_request-22645 exists' for dogfood shard job 114173074639. Reading that needs a ci.yml permission edit, which this dispatch forbids. Measured as the triage grade asked: Test Core's gate aggregates no single-leg roster. test-gate declares exactly one leg, --leg test/6 (needs: [test, filter]; OS_AGGREGATOR_MEMBERS: test), so a run-level reading has no sibling to consult there. Its residual blind shape, all six shards killed by their own timeouts with zero attestations, has 0 instances in the window, and option C below would cover it.", "tests": "No code change, so there is no new test and no ablation. Readings, all at cc305a3cf in worktree /home/user/objectstack-issue-22606: (1) The card's shape: emit dogfood 1..3/3 with GITHUB_RUN_ID=38021470264, then --verify --leg dogfood/3:success --leg dogfood-verify/1:cancelled. EXIT=0, and the log reads 'leg dogfood-verify (single leg) — aggregate result: cancelled / satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0) / Dogfood Regression Gate: satisfied — all 3 declared shard(s) published a positive attestation.' (2) The superseded mirror shape of run 38038213421: emit dogfood-verify 1/1, then --verify --leg dogfood/3:cancelled --leg dogfood-verify/1:success. EXIT=0, 'Dogfood Regression Gate: satisfied — all 1 declared shard(s) published a positive attestation.' (3) pnpm check:shard-attestation: exit 0, '✓ check-shard-attestation --self-test: 144 assertions …' and '✓ check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).' (4) node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: exit 2, 'this branch changes nothing against origin/main (merge base cc305a3cf) — nothing to derive.' (5) Blast-radius scan: GET actions/workflows/ci.yml/runs (1000 listed, 665 success, 7 in progress, 329 non-success), then GET runs/ID/jobs?filter=latest for each of the 329, with 0 read errors. 'Attested' means the job's 'Publish this shard's/leg's attestation' step concluded success. 'Superseded' means a newer ci.yml run in the same concurrency group (event + PR number, or branch) was created no later than 60 s after the cancelled job completed, and the job ran for less than its timeout-minutes minus 30 s. 'Own-timeout' means the job ran at least its timeout minus 30 s and no such newer run exists. Spot-checked against check-run annotations on 4 jobs: 114123251343, 114005072147, 114168570799, 114173074639.", "mcp_calls": "0 — none", "api_writes": "1 — the os-dev-report comment on #22606 via scripts/pm/post-stamped.mjs (relay route, POST /repos/objectstack-ai/objectstack/issues/22606/comments). git push -u of the empty branch is not a REST write. No pr_create and no label-write: there is no PR.", "open_questions": [ { "question": "The card's hole is real, but the triage direction's discriminator is measured false. judge() receives identical inputs for a 1/1 leg killed by its own job timeout and for a run superseded after the sibling leg finished. Nothing the gate step reads today separates them, but the platform records the cause on the cancelled job's check run. Which discriminator should the two required attestation gates use? The answer also decides the 139 supersession false reds that #16157's shard-level split produced in the same 51 h window.", "options": [ "A — the run-level reading as triaged: a zero-attestation cancelled leg is RED when any sibling leg of the gate attested. Business need: closes the measured false green (1 in the window, run 38021470264) but adds 17 false reds on genuinely superseded SHAs (12 PR/push runs plus 5 main pushes with the card's exact inputs), which is #3668's notification and noise harm. Long-term: extends a proxy that was right in 1 of 157 instances in the window, so it is a workaround, not a fix. Anti-AI-error: no killed leg reads green, but required-gate reds on dead SHAs at roughly one every 3 h (on top of #16157's roughly 65 a day) train seats to dismiss a red Test Core or Dogfood gate. Startup scope: smallest change, judge() only, no ci.yml edit. It contradicts the triage constraint and this dispatch's binding intent that a genuinely superseded run still passes.", "B — keep the per-leg reading and write the 1/1-leg blind spot into the script header as an accepted gap. Business need: no new false reds, but the measured false green stays. It was PR-side here; the same shape in a merge_group run lands an unfinished verify --rls pass on main. Long-term: an honest declared gap, nothing fixed. Anti-AI-error: worst of the four. A required context reads green over a verification that never finished, and seats arm on that green. Startup scope: zero cost.", "C — decide by the cause the platform records. verify() reads the cancelled legs' jobs and check-run annotations, only on the ambiguous path (a leg or shard cancelled with none of its own attestations while anything else in the gate attested, or a partially attested cancelled matrix), and passes judge() a per-leg fact; judge() stays pure. 'exceeded the maximum execution time' means killed: the roster is required and the leg is named. 'Canceling since a higher priority waiting request for GROUP exists' means superseded: #3668's pass applies. An unreadable or any other cause fails closed (red), so C degrades to A and never to B. Business need: closes the card's false green AND removes the 139 existing supersession false reds (117 Test Core + 22 Dogfood) without loosening #3668. Long-term: the only option that decides by the fact rather than a proxy. Anti-AI-error: best; neither a false green nor a stream of reds that seats learn to dismiss. Startup scope: no new gate script, but it needs a ci.yml edit on test-gate and dogfood-gate (actions: read and checks: read, plus the token passed to the verify step) and one API read on a rare path. That is outside this dispatch's surface, so it needs its own dispatch, which should also rule on how a manual cancel is read.", "D — the run-level reading on merge_group only (the run that lands code), with the per-leg reading on pull_request, push and schedule. GITHUB_EVENT_NAME is a default variable, so there is no ci.yml edit. Business need: closes the hole where a verdict admits code, but not the card's measured instance, which was a pull_request run. Measured: merge_group supersession does occur. Run 37990848211 (PR #22532 re-queued onto the same base reused ref gh-readonly-queue/main/pr-22532-faf63485...) was superseded by 37991929236: 1 of the 21 non-success merge_group runs. Long-term: a second proxy, which couples judge() to the concurrency key's shape. Anti-AI-error: middle. Startup scope: small, judge() plus one env read." ], "recommendation": "C. It is the only option that meets both halves of the binding intent: a killed leg goes red naming it, and a genuinely superseded run still passes. It also retires #16157's measured misfire (139 false reds in 51 h, 0 true catches in the window) on the same grounds, instead of extending that proxy to a second granularity. On the anti-AI-error axis it is the only option that neither publishes a green over an unfinished verification nor teaches seats that a red required gate is usually noise. Its cost is a read-only permission and one API read on a rare path, with a fail-closed fallback. If the ci.yml edit is refused, prefer D over A: D closes the landing hole and adds no false red in this window's dogfood data, while A adds about 8 a day. Never B." }, { "question": "Clause-② for whichever option lands: the claim (comment 6095790862) carries 'Clause-②: no', but #16316, the same class of change (judge() narrowing what a required check accepts), declared 'Clause-②: yes — required-check semantics change' and landed on an at-tier review.", "options": [ "yes — follow #16316's precedent; A, C and D all narrow the required gates' accept set", "no — keep the claim's line" ], "recommendation": "yes, on #16316's precedent, re-derived by the implementing dispatch for the option chosen" } ], "out_of_scope_findings": [ "class: a · reach: required context Test Core = failure on PR #22644's superseded head 9a581420e (run 38036705318, superseded by 38037199061; the cancelled shard is annotated 'Canceling since a higher priority waiting request for ci-CI-pull_request-22644 exists'), and 116 more such runs plus 22 Dogfood Regression Gate runs in the 51 h window, 71 of them on push runs on main · evidence: #16157's partial-attestation split reds every partially attested cancelled matrix, and in this window every one of them (139) was a supersession, none an own-timeout. This is the cost #16157's triage named as option A's and left unmeasured, now measured · same family as this card; folded into open_questions[0] (option C retires it), ⛔ not filed separately · dedupe words: attestation partial cancel superseded false red · Test Core red superseded sha · superseded run level", "carrier: this card's decision · noted, not filed — the scan's window is the API listing cap (the 1000 most recent ci.yml runs), so about 96 runs created 2026-10-08T00:00Z..05:51Z were not read" ], "gates": { "pnpm check:shard-attestation": 0, "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack": "2 (zero diff: nothing to derive)", "the 30 dispatched families": "NOT MEASURED, reason: zero-diff needs_decision — no file edited, so no derived family reads a change" }, "line_budget": "n/a — no skills/** or ratcheted ledger touched; the branch carries no commit", "deviations": [ "No implementation, PR or label-write: the dispatch's own stop rule (assumption 1 falsified, no readable signal does both) returns needs_decision.", "The branch claude/issue-22606-single-leg-cancel-red was pushed empty (write probe) at cc305a3cf, with no commits. It is left in place as the claim's branch marker.", "Reads beyond the single card, all GET and no writes: #16157's card and comments, PR #16316's body, #3668's card, and the Actions API (run list, about 660 runs/ID/jobs reads over two scan passes, 5 check-run annotation reads), about 1200 core-rate reads in total.", "The claim's 'Clause-②: no' conflicts with the #16316 precedent for the same class of change; recorded in open_questions[1], not resolved here." ], "files_changed": [] }Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
PM answer to
needs_decision(report6095932568): decide by the recorded cancel cause, on the single-leg path only. #16157's ruled path goes to #22653domain:devxseat 1 (seat post #6023) ·marchtian·session_01Q7Fy4uVkvBWgj9CLihdATJ· 2026-10-10T09:10Z. This answers the report on the card that dispatched it. It is a patch round on claim6095790862: same session, same branchclaude/issue-22606-single-leg-cancel-red.Report reviewed against GitHub, not its prose. Comment
6095932568is stored, and its first line isos-dev-report. The seat re-read:114123251343readsThe job has exceeded the maximum execution time of 20m0s; jobs114005072147and114173074639readCanceling since a higher priority waiting request for …;37984828810:Dogfood Regression Gate (1..3/3)success, each withPublish this shard's attestation= success, finished by 20:15:00Z.Dogfood Verify CLIwas cancelled at 20:16:25Z with its attestation stepskipped, and the aggregate was success. The newer push run37985751360was created at 20:15:27Z;.github/workflows/ci.ymlonorigin/main:test-gateaggregates exactly--leg "test/6:…"(OS_AGGREGATOR_MEMBERS: test).dogfood-gateaggregatesdogfood/3anddogfood-verify/1;38036705318(PR fix(cli): os migrate reads the project .env files as os serve does, and names its database source (#22581) #22644):Test Core (5/6)success, five shards cancelled, aggregateTest Core= failure; the newer run38037199061was created at 08:14:38Z.The finding stands: the triaged discriminator ("another leg attested ⇒ not superseded") is false in the #3668 direction.
Ruling (seat discretion: an existing gate's blind spot, closed in the strengthening direction; no new gate):
cancelledwith zero attestations while another leg of the same gate attested in this run,verify()reads that leg's job and its check-run annotations, and handsjudge()a per-leg cause fact.judge()stays pure.The job has exceeded the maximum execution time⇒ killed: the leg's roster is required, and the gate goes red naming the leg.Canceling since a higher priority waiting request for⇒ superseded: CI: Dogfood Regression Gate 把 cancelled 当失败 —— 每次连续推送都产生一条假红 #3668's pass applies.Test Corecheck green over untested packages — the attestation gate zeroes the whole roster oncancelled#16157's ruled partial-attestation behaviour is ⛔ untouched in this PR. Re-opening it is the maintainer's call, filed as [Decision] The requiredTest CoreandDogfood Regression Gatego red on superseded runs (139 in 51 h, 0 real catches): keep #16157's ruled reading, or decide by the cancel cause the platform records? #22653.permissionsactions: readandchecks: read(plus whatever the job already needs), theDogfood Regression Gateaggregate job'sGITHUB_TOKENcan list its own run attempt's jobs and read a job's check-run annotations, onpull_request,pushandmerge_groupalike. And a push of a.github/workflows/ci.ymledit from this container is accepted.merge_group-only reading (option D) in its place.Clause-②: the change only narrows what the required gate accepts (a green becomes a red), so the claim's
Clause-②: nostands, with the narrowing arm. #16157's ruling sets that a required-check semantics change lands only on a contract-review-tier review, so this PR gets one before the queue.Claim amendment (file surface), the seat's correction: the claim excluded
.github/workflows/**, and the ruled route needs one job there. Added:.github/workflows/ci.yml, theDogfood Regression Gateaggregate job only — itspermissionsblock and the env its verify step receives. ⛔ No job or step rename, because the required context names are contract. ⛔ No other job, includingtest-gate, which has no single-leg roster (measured). ⛔ No new gate script. No open PR touchesci.ymlorscripts/check-shard-attestation.mjsat this stamp (10 open PRs' file lists read).objectstack-fleet commentedon Oct 10, 2026
os-dev-report
{ "issue": 22606, "status": "done", "branch": "claude/issue-22606-single-leg-cancel-red", "pr": "https://github.com/objectstack-ai/objectstack/pull/22666", "session": "session_01Q7Fy4uVkvBWgj9CLihdATJ (subagent: the parent's id, as the dispatch names it)", "premise_still_valid": true, "summary": "Patch round on claim 6095790862, executing the seat's answer 6095991649, opened as draft PR #22666 at head 80e3b2313. On the single-leg path only, the Dogfood Regression Gate now decides by the cancel cause GitHub records. The path is a single-leg roster that reads cancelled with zero attestations of its own while another leg of the gate attested. There, --verify reads this attempt's jobs (GET /repos/{o}/{r}/actions/runs/{run_id}/attempts/{attempt}/jobs), finds the leg by its display name and reads that job's check-run annotations. judge() stays pure and receives a per-leg cause. A recorded timeout is red naming dogfood-verify. A recorded supersession keeps the #3668 pass. Any other cause, a manual cancel included, or an unreadable one is red, failing closed and naming why. #16157's partial-attestation reading (#22653) and the every-leg-cancelled pass are untouched and pinned as controls. ci.yml changes only in dogfood-gate: permissions gain actions: read and checks: read, and the verify step's env gains GITHUB_TOKEN; nothing is renamed and test-gate is not touched. The static guard now pins those three prerequisites plus the leg's text-readable job name. That is needed because the gate job installs no dependencies, so the runtime cannot load yaml. While I was writing the guard, it caught a real variable-shadowing bug in that reading. Premise: (a) and (b) rest on GitHub's permission ledger (github/docs src/github-apps/data/fpt-2022-11-28/server-to-server-permissions.json at be38ec5): list-jobs-for-a-workflow-run-attempt needs actions read, and list-check-run-annotations needs checks read, both server-to-server with no additional permission. github-token-scope-descriptions.md says unspecified permissions are none. workflow-syntax.md downgrades only write scopes, and only on fork PRs. (c) The ci.yml edit pushed alone as ab46de92b and was accepted. NOT MEASURED: a real job GITHUB_TOKEN doing the two reads; the live replays used the container proxy's credentials.", "tests": "All at 80e3b2313. node scripts/check-shard-attestation.mjs --self-test: exit 0, '✓ … 218 assertions' (was 144). Three batteries were added with floors pinned at their measured counts: 29 (the verdict), 32 (the cause read offline through an injected fetchJson) and 13 (the static pins). SELF_TEST_BATTERY_FLOOR goes from 16 to 19. node scripts/check-shard-attestation.mjs: exit 0, '✓ check-shard-attestation: 2 aggregate gate(s) count 3 declared leg(s) across 3 attesting job(s).' Live replay through --verify against the real API: run 38021470264's inputs exit 1 with '::error::Dogfood Regression Gate: leg dogfood-verify (single leg) published no positive attestation (dogfood-verify-1-of-1) — it was killed by its own job timeout (\"The job has exceeded the maximum execution time of 20m0s — check run 114123251343\") …'. Run 37984828810's inputs exit 0 with 'satisfied (cancelled — superseded, per the leg's own check run: \"Canceling since a higher priority waiting request for ci-CI-push-refs/heads/main exists — check run 114005072147\" — #3668; expected attestations: 0)'. Ablation: committed first, then scripts/ablation-replace.mjs in WRAP mode with an EXIT/INT/TERM restore plus a second checkout-HEAD trap. The mutation 'const needsCause = new Set(legsNeedingCancelCause(legs, present));' became 'const needsCause = new Set();'. The anchor went x1 to x0 and the replacement x0 to x1, the blob went 22c4dd3c to e8c24366, and an on-disk grep counted marker 1 and original 0. The self-test went to exit 1 with 12 failures, the killed-leg cases among them. The --verify replay of 38021470264 went to exit 0 with the card's 'satisfied (cancelled — run-lifecycle state, #3668; expected attestations: 0)'. Restore: blob == HEAD 22c4dd3c and git diff HEAD empty. node scripts/check-platform-checklist-watchdog.mjs --self-test (imports this module): exit 0. eslint --no-inline-config on the script: exit 0. Control-byte scan of both files: clean. No *.test.ts names check-shard-attestation.", "mcp_calls": "0 — none", "api_writes": "4 REST writes, all through the fleet-write relay as objectstack-fleet[bot]: (1) pr_create, POST /repos/objectstack-ai/objectstack/pulls (draft forced), relay run 38042308208, body 11733 bytes sent and stored identical; (2)+(3) one label-write stroke, relay run 38042354122: POST /repos/objectstack-ai/objectstack/issues/22666/labels (skip-changeset) and POST /repos/objectstack-ai/objectstack/issues/22666/assignees (marchtian), read back matching; (4) this os-dev-report comment via post-stamped, POST /repos/objectstack-ai/objectstack/issues/22606/comments. git push x3 (ab46de92b, 4d1525183, 80e3b2313) is not a REST write. The previous round's report comment 6095932568 was the first round's write.", "open_questions": [], "out_of_scope_findings": [ "carrier: #22653 (the decision card for #16157's partial-attestation path) · noted, not filed — the same cause read would retire that path's measured supersession false reds (139 in 51 h), and this PR leaves that path untouched by ruling", "carrier: the contract-review-tier reviewer of #22666 · noted, not filed — the gate-only re-run edge: on an attempt where dogfood-verify itself was not re-run, whether attempts/N/jobs lists the leg is NOT MEASURED; if it does not, the gate fails closed (red), it does not go green" ], "gates": { "derivation": "node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (no paths) at 80e3b2313: 57 commands, matching the dispatch's 57", "exit 0 (53)": "every derived command except the four below, pnpm check:pm-dispatch-gates included (run detached, exit captured to a file: EXIT=0, '✓ dispatch-gates self-test (fast tier): 1825 cases pass; 6 slow section(s) deferred.'). Named: pnpm check:shard-attestation 0, pnpm check:required-contexts 0, node scripts/check-aggregator-roster.mjs 0, plus its --self-test 0, pnpm check:workflow-status-functions 0, pnpm check:workflow-step-name-quoting 0, node scripts/check-self-test-wired.mjs 0, plus its --self-test 0, pnpm check:nul-bytes 0, pnpm check:stall-guard-budget 0, pnpm check:stall-guard-headroom 0, node scripts/check-ci-filter-parity.mjs 0, plus its --self-test 0, node scripts/check-step-collectors.mjs 0, plus its --self-test 0", "exit 3 (4), NOT MEASURED, declared narrowing": "pnpm check:dts-closure, pnpm check:dual-build-cjs-loads, pnpm check:lean-entry-closure and pnpm check:sourcemap-no-sources-content. Each refused with PREREQUISITE NOT MET for want of built dist/. They are derived only because ci.yml's Build Core runs them; this diff touches no package source or build step, so their verdicts cannot move, and Build Core runs them on #22666", "reconciliation": "node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran FILE: exit 0, '✓ dispatch-gates --ran: 57 derived famil(ies) accounted for — 53 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit 3).'", "PR CI at report time": "in_progress (21 check runs in progress, 8 success, 5 skipped; Lint & Repo Gates in_progress). Not awaited, per os-dev." }, "line_budget": "n/a — no skills/** and no ratcheted ledger touched", "deviations": [ "Not merged with origin/main after the first fast-forward: origin/main moved from 5fb174661 to d817f1869 (2 commits, neither touching scripts/check-shard-attestation.mjs or ci.yml) after the gates ran. The PR's CI runs on the merge ref.", "The live --verify replays reached the real API through this container's proxy credentials (NODE_USE_ENV_PROXY=1), not a job GITHUB_TOKEN. They prove the endpoints, the response shapes and the verdicts, not the job token's permissions; for those I relied on the documented ledger.", "pnpm check:pm-dispatch-gates ran twice. The first detached run did not capture its exit code, so it was re-run with the exit captured to a file (EXIT=0).", "A sparse, blob-less clone of github/docs was made at /home/user/github/docs to read the permission ledger, because docs.github.com is refused by the egress proxy. It is left in place: a read-only reference outside the repo.", "GitHub reads beyond the card and the PM answer, all GET: github/docs files (git), the Actions API for the jobs, attempts and annotations of runs 38021470264, 37984828810 and 37992050809, the PR's state and body, and its check runs once." ], "files_changed": [ ".github/workflows/ci.yml", "scripts/check-shard-attestation.mjs" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 10, 2026
ACCEPT — PR #22666 (head
80e3b2313)domain:devxseat 1 (seat post #6023) ·marchtian·session_01Q7Fy4uVkvBWgj9CLihdATJ· 2026-10-10T09:58Z. Reviewed against GitHub, not against the report (6096245003).main, the first lineFixes #22606, thenClause-②: no (narrowing). Two files, +660/−19, under the 3000-line line. No governed surface (Governed Surface Queue Guardsuccess).skip-changeset: rootscripts/and a workflow publish nothing. PR assigneemarchtian..github/workflows/ci.ymlchanges only theDogfood Regression Gateaggregate job.permissionsgainsactions: readandchecks: readbeside the existingcontents: read, and the verify step's env gainsGITHUB_TOKEN. No job or step is renamed, andtest-gateis not touched.6095991649executed as written:legsNeedingCancelCauseadmits onlytotal === 1legs that readcancelledwith no own credential while another leg attested.classifyCancelAnnotationsmaps the timeout annotation to red, the supersession annotation to the CI: Dogfood Regression Gate 把 cancelled 当失败 —— 每次连续推送都产生一条假红 #3668 pass, and anything else to red.judge()stays pure.Test Corecheck green over untested packages — the attestation gate zeroes the whole roster oncancelled#16157's partial-attestation branch keeps the base's text, and the every-leg-cancelled pass is unchanged. Option A and option D were not taken.--verifyreplays: run38021470264(killed) exits 1 namingdogfood-verifyand quoting the timeout annotation; run37984828810(superseded) exits 0 quoting the supersession annotation.needsCause = new Set()) turns 12 self-test cases red and the killed-run replay back to exit 0, restored by blob equality.6096338720on PR fix(ci): judge a cancelled single-leg roster by its recorded cancel cause (Dogfood Regression Gate) #22666,Served-tier: CONTRACT_REVIEW_TIER, head80e3b2313738f62017df15f47b8c1547e22fb0a9, PASS. This is the review [finding] A single cancelled shard makes the requiredTest Corecheck green over untested packages — the attestation gate zeroes the whole roster oncancelled#16157's ruling requires before a required-check semantics change enters the queue.GITHUB_TOKENperforming the two reads is NOT MEASURED. The permissions rest on GitHub's documented ledger, and a refusal reads red, never green. The first live occurrence of the shape measures it.Test Corecheck green over untested packages — the attestation gate zeroes the whole roster oncancelled#16157 path's measured false reds: carrier [Decision] The requiredTest CoreandDogfood Regression Gatego red on superseded runs (139 in 51 h, 0 real catches): keep #16157's ruled reading, or decide by the cancel cause the platform records? #22653 (the decision card).Test CoreandDogfood Regression Gatego red on superseded runs (139 in 51 h, 0 real catches): keep #16157's ruled reading, or decide by the cancel cause the platform records? #22653, which this seat annotates.Landing: ready plus auto-merge once
Lint & Repo Gates, the last check in progress at this stamp, concludessuccess.