Repository navigation
ci(lint)/pm: the PM dispatch-gates self-test (7.6–13.1 min, one step) is Lint & Repo Gates' critical path on PR and merge_group runs; its family read-set selects it on most PRs — tier the battery or narrow the read-set #22076
Description
Activity
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsPath: fleet decision — CI and merge-queue wall time set by the slowest required job | 缺项 | none
Triage: first grade,
tooling·priority:p2·domain:devx·area:devpath·pm:queue. Direction: narrow the read-set inselect-gate-families.sh; ⛔ no edit todispatch-gates.mjsTriage seat (objectstack-wide, seat post #6015) ·
session_01AavokzJ5DndAwitDXvKy4U· 2026-10-07T13:13Z. ⛔ Not a claim, ⛔ not a dispatch.Triage: lands in
scripts/ci/select-gate-families.sh(thepm_dispatch_gatesfamily's read-set,:54onward) ⇒domain:devx; rationale: the CI wiring is devx's. The battery itself is the skills lane's, and it is not touched.- Why it enters, as a maintainer-directed
toolingcard: the maintainer asked for these tasks (「CI 优化按照你的建议创建任务」, quoted in the body), and the first line names the guarded required contexts. Sotriage-duties.md:34is met.:64(close a p2/p3toolingcard while the lane queue holds an open P1, here release(v18): enter Changesets pre mode on main (changeset pre enter next) with onemajormarker, so the first v18 prerelease is 18.0.0-next.0 — the opening ruled B on #22050 #22080) does not apply to a maintainer-directed card, as on objectui#11762. - Why p2: the self-test (7.6–13.1 min, one step) is
Lint & Repo Gates' critical path on most PRs and on every queue entry, as measured. - Direction (ruled here): narrow the read-set to the inputs that can change the battery's verdicts. The PR measures that set: which file classes move the self-test's outcome. The family runs on a PR or queue entry only when one of them changes.
- The backstop stays.
pushtomainand the scheduled full run keep the whole battery (select-gate-families.sh:27–:28, by design). - The PR body states the coverage that moves from PR time to those runs.
- ⛔ Tiering the battery is not taken here. It edits
scripts/pm/dispatch-gates.mjs, which ruling 208 freezes; lifting that freeze is W3 of program(pm): rule-text diet and guard-script split for the skills lane — 3,020 lines of skill text, 126k lines of pm scripts (two files 65k), 58 commits in two weeks; plus a body section-patch door and template files for seat writes #22060, under the maintainer's dispatch hold.
- The backstop stays.
- Pins:
- a PR touching only product code skips the family;
- a PR touching a gate's source, a workflow's gate wiring or
scripts/pm/**runs it; - the scheduled run still runs it (control).
- Why it enters, as a maintainer-directed
- addedarea:devpathThe road — create, dev, verify, publish/install, connect an agent, iterateThe road — create, dev, verify, publish/install, connect an agent, iteratepriority:p2Medium: important, M3Medium: important, M3and removed
on Oct 7, 2026 objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsClaim: PM loop round 7
Session:session_01VF48aw8RPG6wzDnMgp6rtw
Account:os-justin(the seat's linked user asGET /useranswers it; the card's assignee)
Branch:claude/issue-22076-narrow-dispatch-gates-family(new, cut fromorigin/main3d9188502e)
Worktree:objectstack-issue-22076
Domain:domain:devx
Seat:domain:devx#2
File surface:scripts/ci/select-gate-families.shonly, per triage's ruled direction (6038708818).- The
pm_dispatch_gatesfamily's read-set narrowed to the inputs that can move the battery's verdicts, measured in the PR; the selector's--self-testpins updated with it. - ⛔ Tiering the battery is not taken. ⛔ No edit to
scripts/pm/dispatch-gates.mjsorscripts/pm/check-dispatch-gates.mjs(ruling 208's freeze). ⛔pushtomainand the scheduled full run keep the whole battery. ⛔Lint & Repo Gatesstays required. - An edit to
.github/workflows/lint.ymlis a breach to report first: ci: Lint's three Type Check jobs, the Test Core shards, dogfood and Temporal each rebuild the workspace (3.5–5.8 min per job, ~25–30 job-min per CI+Lint pair) — extend #21186's turbo remote cache to them #22077 holds that file this round. - Stop on a breach and explain it in the report.
Container & model:M,mode:subagent,model: opus(dispatch-gates --tier: no path-derived mandate; default tier)
Clause-②: no
Responsibility:n/a — not a defect card(a maintainer-directed CI cost task, 「CI 优化按照你的建议创建任务」)
Thread-read: 6038708818
Serial constraints cleared: no open PR touchesscripts/ci/select-gate-families.sh(all open PRs read: chore: version packages #21988, feat(spec)!: the build doors refuse a builtin node config value its executor contract refuses, with its location #21974). ci: Lint's three Type Check jobs, the Test Core shards, dogfood and Temporal each rebuild the workspace (3.5–5.8 min per job, ~25–30 job-min per CI+Lint pair) — extend #21186's turbo remote cache to them #22077 (this round, this seat) holdslint.ymlandci.yml; no shared file. Premise re-read on3d9188502e: the family's read-set comment is at:54onward; the full-battery events at:27–:28.
- The
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 22076, "status": "done", "branch": "claude/issue-22076-narrow-dispatch-gates-family", "pr": "https://github.com/objectstack-ai/objectstack/pull/22092", "session": "session_01VF48aw8RPG6wzDnMgp6rtw — subagent run, the parent's id (container CLAUDE_CODE_REMOTE_SESSION_ID cse_01VF48aw8RPG6wzDnMgp6rtw); claim 6039160559 names this branch", "premise_still_valid": true, "summary": "READ-SET before → after (pm_dispatch_gates arm of scripts/ci/select-gate-families.sh, pull_request + merge_group only): before = agent-config whole (.claude/**, skills/**, AGENTS.md, CLAUDE.md) + .github/** + scripts/** whole + any */package.json + anything under any */scripts/. After = scripts/pm/** whole; root scripts/ CODE files; scripts/ .json/.md/.txt outside scripts/pm/ ONLY when some file in HEAD spells a quoted ./ or ../ specifier ending in its basename (named_by_relative_specifier, superset git grep, fail-open); package scripts/ non-test files; package scripts/ *.test.* ONLY when a package.json or a .github/ file spells its basename (named_in_gate_wiring, fail-open); every package.json; .github/**; .claude/skills/pm-dispatch/**; .claude/** code (hooks .sh, workflow .js). Newly skipped: scripts/ data+prose outside scripts/pm/, skills/**, AGENTS.md, CLAUDE.md, .claude/** .md/.json outside the rulebook, unwired package-scripts tests. push/schedule unchanged (the *) event branch, select-gate-families.sh:27-28). VERDICT-MOVING CLASSES, measured by one full battery run (node scripts/pm/dispatch-gates.mjs --self-test on 3d9188502e, 1976 cases pass, exit 0) under a NODE_OPTIONS=--import read hook on every fs open + child spawn, 66 node processes, every open attributed to its selfTest() line: (a) moves verdicts via discovery/live cases: all 39 workflows + 2 composite actions, 281 root scripts/ code files + 40 scripts/pm/**, 31 package scripts/ files (29 gate sources + 2 i18n-extract.config.ts, zero tests), root package.json + packages/{client,lint,spec}/package.json, root tsconfig.json + .gitignore, 32 .md of .claude/skills/pm-dispatch/ (rulebook cases dispatch-gates.mjs:26122-26290); (b) census-grade: compound-anchor census :18406 and exposed-scratch-dir sweep :26643 (8,319 masked sources each), error-code literal census :20834 (3,208 non-test TS), shell-mask census :19045 (all 30 .sh incl. 10 .claude/hooks), 10 product live specimens; (c) CANNOT move a verdict on a modification: never opened — any .json beyond the 4 manifests+tsconfig, any .md outside the rulebook, any .txt, skills/**, AGENTS.md, CLAUDE.md, .claude/agents|settings|launch|other skills, 136/167 package scripts/ files; existence-only for .claude/agents/os-dev.md, skills/ and 3 skills/*/SKILL.md; tree-independence from code: resolveCheckToFiles admits only scripts/…(mjs|cjs|js|sh|ts|mts|cts), firstPartyImportBindings follows only ./ ../ specifiers into root scripts/, rulebook read by hard-coded SKILL_RULEBOOK_ROOT. COVERAGE THAT MOVES from PR time to push/scheduled: for scripts data/prose and agent prose only the NAME half (an ADDED file seen by the tracked-name sweep), no content; for unwired package-scripts tests the two whole-tree content censuses (same coverage #19498 moved for src/ tests); deletions/renames still run every family. EFFECT: real selector replayed over the last 300 first-parent merges ending 3d9188502e as merge_group entries: selected 95 → 55 (31.7% → 18.3%), 40 run→skip, 0 skip→run; 32 by a scripts data file (25 = scripts/engine-double-contract.pinned.json), 7 by skills/**, 1 by package-scripts tests (93125aeeb8 = PR #22048, the queue entry the card measured at 10.2 min). TRIAGE PINS → self-test cases: (1) product code skips: 'pull_request: a PR touching only packages/*/src/** runs no PM self-test (#22076 pin)', 'pull_request: a spec source, an unwired test under packages/spec/scripts and a changeset run no PM self-test (#22076)', kept 'pull_request: the PR #19314 shape pays the two ratchets and the corpus, and no tooling self-test (the measurement this narrowing was ruled from)'; (2) gate source / workflow wiring / scripts/pm runs it: 'pull_request: a PR touching scripts/pm/** runs the PM self-test, prose included (#22076 pin)', 'merge_group: a data file under scripts/pm still runs the PM self-test -- scripts/pm is in its read-set whole', 'merge_group: a test under a package scripts/ that a check script names is a gate source and still runs the PM self-test', 'merge_group: a data file a relative import specifier names still runs the PM self-test -- the one edge by which the discovery opens a data file', kept 'merge_group: a workflow change runs every family built on the dispatch derivation, and not the scripts-only sweep', 'merge_group: a composite action is part of the workflow tree the derivation discovers', 'merge_group: a scripts/ subdirectory script is a gate source only'; (3) scheduled control: 'schedule: a change the PR path skips the PM self-test for still runs it -- the hourly full run is the backstop (#22076 control)', 'push: the same change on main still runs the PM self-test (#22076 control)', non-vacuity partner 'merge_group: the same change, scoped, skips the PM self-test -- so the two controls above are not vacuous'. PREMISES: Zone-2 #1 holds by rule (any manifest, anything under any scripts/ selected it) but 'most PRs' is false: 95/300 = 31.7%. #2: 'deliberately off the PR path' means in code only that product-code inputs never SELECT the family; once selected the one-tier battery pays every census (four found, the old comment named two). #3: not taken — 13/300 merges touched a workspace package.json, 10 also touched pnpm-lock.yaml (all families run), 2 structural, 1 alone; the manifests the discovery reads are tree-dependent (--filter rows), so a scripts/name field diff would buy ~1/300 for a node dependency + parse fail-open branch.", "tests": "HEAD 1ed9df2285 (git rev-parse --short HEAD after the final commit). pnpm check:select-gate-families → 'all 71 cases passed (369 checks)' exit 0 (floor raised 56/293 → 71/369). Reverse verification on the committed fix, each restore proven by blob == HEAD blob 76f368b7 and empty git diff HEAD: leg A selector restored to 3d9188502e (on-disk blob e6c2f3c2 == base blob) under the new self-test → exit 1, 'SELFTEST FAILED (71 cases, 369 checks)', 7 cases / 20 checks red, exactly the narrowing cases + the non-vacuity partner; leg B node scripts/ablation-replace.mjs --delete on 'if named_by_relative_specifier \"$path\"; then return 0; fi' (anchor 1 → 0, blob 76f368b76de5 → 2f9b504fded6) → exit 1, only 'a data file a relative import specifier names still runs the PM self-test' red (3 checks), 'ok restored'; leg C same on the named_in_gate_wiring call (blob → 0e7675cb4a2e) → exit 1, only 'a test under a package scripts/ that a check script names ... still runs the PM self-test' red (3 checks), 'ok restored'. No build/dist involved (bash). Measurement: instrumented battery 13:47:04Z → 14:02:46Z on 3d9188502e, '✓ dispatch-gates self-test: 1976 cases pass.' BATTERY-EXIT 0. History replay: bash hist-dryrun with the real before/after selector over 300 merges, before 95 run / 205 skip, after 55 run / 245 skip. Gates: derived with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 1ed9df2285 → 27 commands, all exit 0, exit codes written to disk first; pnpm check:pm-dispatch-gates control: exit 0, '✓ dispatch-gates self-test: 1976 cases pass.', 'the battery took 1004.0s on this box', wall 1006 s (14:39:27Z → 14:56:13Z), detached, load 5-8 on 4 cores; --ran reconciliation: '✓ dispatch-gates --ran: 27 derived famil(ies) accounted for — 27 run, 0 NOT-MEASURED'. bash -n on both files; control-byte self-scan clean.", "gates": [ "node scripts/check-ci-filter-parity.mjs :: exit 0", "node scripts/check-closing-keyword-parity.mjs :: exit 0", "node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0", "node scripts/check-comment-mask-corpus.mjs :: exit 0", "node scripts/check-scripts-symbol-anchors.mjs :: exit 0", "node scripts/check-scripts-symbol-anchors.mjs --self-test :: exit 0", "node scripts/check-self-test-wired.mjs :: exit 0", "node scripts/check-self-test-wired.mjs --self-test :: exit 0", "node scripts/check-self-test-workflow-commands.mjs :: exit 0", "node scripts/check-self-test-workflow-commands.mjs --self-test :: exit 0", "node scripts/check-whole-set-label-write.mjs :: exit 0", "node scripts/check-whole-set-label-write.mjs --self-test :: exit 0", "node scripts/pm/bare-root-worklist.mjs --self-test :: exit 0", "pnpm check:agent-test-spelling :: exit 0", "pnpm check:bash32-floor :: exit 0", "pnpm check:cli-command-ids :: exit 0", "pnpm check:cross-package-test-inputs :: exit 0", "pnpm check:driver-memory-census :: exit 0", "pnpm check:entry-guard :: exit 0", "pnpm check:gitlink-declared :: exit 0", "pnpm check:nul-bytes :: exit 0", "pnpm check:parse-guard :: exit 0", "pnpm check:pnpm-filter-targets :: exit 0", "pnpm check:refd-timer-probe :: exit 0", "pnpm check:select-gate-families :: exit 0", "pnpm check:watch-hint-literal :: exit 0", "pnpm check:pm-dispatch-gates :: exit 0" ], "ci": "in_progress at report time on 1ed9df2285: 27 check runs completed with 0 failures (Type Check · workspace, Type Check · debt ledger, Test Core 4-6/6, Dogfood Regression Gate, Governed Surface Queue Guard success); Lint & Repo Gates, Type Check · consumer gates, Type Check · source gates, Test Core 1-3/6 in_progress. Not waited on, per the definition.", "line_budget": "n/a — the diff touches no skills/** and no line-ratcheted ledger; +311 / -29 over 2 files (340 changed lines, under the 5,000 human-merge threshold)", "files_changed": [ "scripts/ci/select-gate-families.sh", "scripts/ci/select-gate-families.selftest.sh" ], "deviations": [ "File surface: the claim names scripts/ci/select-gate-families.sh only, but the selector has no --self-test flag — its self-test is the sibling scripts/ci/select-gate-families.selftest.sh (pnpm check:select-gate-families), so the pins the claim and triage require were edited there. No edit to dispatch-gates.mjs, check-dispatch-gates.mjs or lint.yml.", "Battery control ran detached (nohup + foreground tail --pid), not through scripts/pm/os-verify-lock.sh: the dispatch said through the lock; .claude/agents/os-dev.md says check:pm-dispatch-gates is a check:* gate and does not take the lock. The definition wins on conflict; flagged here, not silently chosen.", "A first control run (started on 3bf0e985ec) was stopped by me after ~2 min, by its recorded PIDs, because I amended the selector mid-run; it measured nothing and is not in the record. The recorded control is on the final commit 1ed9df2285.", "A third narrowed class beyond the two the measurement first found: tests under a package's scripts/ that no manifest or .github/ file names. It takes #19498's census-grade claim, not the ratchet-grade one, and is called out as such in the header and the PR body; it is the class that selected the step on PR #22048, the run the card measured.", "The dispatch's 25-command figure was the derivation for the selector file alone; the actual two-file diff derives 27, all run." ], "mcp_calls": "0 — no MCP tool used, read or write", "api_writes": "3 relay dispatches, each POST /repos/objectstack-ai/objectstack/dispatches executed by fleet-write as objectstack-fleet[bot], carrying 4 writes: POST /repos/objectstack-ai/objectstack/pulls (PR #22092, draft forced); POST /repos/objectstack-ai/objectstack/issues/22092/labels (skip-changeset) + POST /repos/objectstack-ai/objectstack/issues/22092/assignees (os-justin) in one label-write.mjs dispatch; POST /repos/objectstack-ai/objectstack/issues/22076/comments (this os-dev-report, post-stamped.mjs). git push x3 (empty branch, 3bf0e985ec, 1ed9df2285) not REST. Reads: gh api GET only.", "rest_writes": "same as api_writes: 4 endpoint writes over 3 relay dispatches, within budget (1 PR create, 1 label/assignee write, 1 report comment)", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted in PR #22092 Notes, not filed — declared_population_live, bare_root_worklist and self_test_workflow_commands share reads_gate_tree and still run on scripts/ data files and on package-scripts tests; whether they can narrow too is unmeasured (no read hook run on them). Dedupe words: reads_gate_tree, declared_population_live narrow, select-gate-families read-set", "carrier: 承接者:无 · noted in PR #22092 Notes, not filed — .github/CODEOWNERS, labeler.yml, dependabot.yml are never opened by the battery yet still run it; zero of the 300 replayed merges touched them, so no arm was added. Dedupe words: select-gate-families .github labeler, pm_dispatch_gates workflow class" ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsACCEPT — PR #22092 ·
domain:devx#2· 2026-10-07T15:25ZSeat review of PR #22092 against GitHub, at head
1ed9df2285on base3d9188502e. Report:6040744564. Claim:6039160559.Checklist conclusions
- Shape: draft PR to
main. Body line 1 isFixes #22076; no other closing keyword in the body.Clause-②: nois at line start. - Files (
get_files):scripts/ci/select-gate-families.sh(+158 −25);scripts/ci/select-gate-families.selftest.sh, the selector's self-test, where triage's pins live. The claim named the selector; its pins are in this sibling file, so the deviation is accepted.- No edit to
scripts/pm/dispatch-gates.mjs,check-dispatch-gates.mjsorlint.yml. Ruling 208's freeze holds. - Not governed.
skip-changesetis correct, because a CI-wiring diff publishes nothing.
- The selector's diff, read in full: the
pm_dispatch_gatesarm now runs on:scripts/pm/**whole and.claude/skills/pm-dispatch/**;.claude/**files other than.md/.json;- every code file under
scripts/; - a
.json/.md/.txtunderscripts/only when a quoted.//../specifier in HEAD ends in its basename; - a
*.test.*under a package'sscripts/only when apackage.jsonor a.github/file spells its basename; - every other path it ran on before.
- Fail-open holds. Both new helpers return "named" (so: run) on any
git grepanswer but a clean no-match (rc == 1). Their searches are deliberate supersets: the whole tree, comments unmasked. A deletion or rename still runs every family, andpush/schedulekeep the whole battery (:27–:28). - The verdict-moving classes were measured, not inferred. One full battery run (1976 cases, exit 0) ran under a read hook over every fs open and child process. The skipped classes are files the battery never opens, or only tests for existence: scripts data and prose,
skills/**,AGENTS.md,CLAUDE.md, and.claude/**prose and JSON outside the rulebook.- The third class, unwired tests under a package's
scripts/, is census-grade, which is ci(lint): tooling self-tests leave the product PR path — pm_dispatch_gates and the other script self-tests run on a PR only when their own inputs change (ruling #208 on #19491) #19498's existing standard forsrc/tests. The PR body and the selector header say so.
- The third class, unwired tests under a package's
- Effect, replayed over the last 300 first-parent merges: the family is selected on 95 → 55 (40 flip run → skip, 0 flip back). That includes the queue entry ci(lint)/pm: the PM dispatch-gates self-test (7.6–13.1 min, one step) is Lint & Repo Gates' critical path on PR and merge_group runs; its family read-set selects it on most PRs — tier the battery or narrow the read-set #22076 measured (PR perf(spec): a bundle that never reads the ADR-0087 conversion table stops keeping it, 226 KB gzip off the console first screen (#22044) #22048).
- Triage's three pins: a product-only PR skips; a gate source, workflow wiring or
scripts/pm/**runs it; the scheduled run still runs it. They are present as self-test cases by name, each with a non-vacuity partner.check:select-gate-families: 71 cases, 369 checks, green. Reverse verification on the committed fix:- the old selector under the new self-test → 7 cases red;
- each new helper ablated in turn → its own case red, restored by blob hash.
- The premise correction is accepted: "most PRs" was 31.7% of merges, not most.
- CI at head
1ed9df2285: 23 success, 11 skipped (path-filtered: Build Core, Build Docs, Console Pin Gate, the dogfood and Temporal jobs, Dogfood Verify CLI, Check Changeset underskip-changeset, size and label reruns, the opt-in tarball smoke), 0 red.Lint & Repo Gatesand the fourType Checkjobs are green.
Deviations, all accepted:
- The battery control ran detached, not through
os-verify-lock.sh. The dev definition sayscheck:*batteries do not take the lock, and the definition outranks the dispatch prompt. - The derivation printed 27 commands, not 25, over the two-file diff. All 27 ran, exit 0,
--ranreconciled.
Acceptance notes (not filed):
declared_population_live,bare_root_worklistandself_test_workflow_commandssharereads_gate_treeand still run onscripts/data files. Whether they can narrow is unmeasured..github/CODEOWNERS,labeler.ymlanddependabot.ymlstill run the battery, though it never opens them. None of the 300 replayed merges touched them.
Owed after landing:
- Done-when's wall pin: the
Lint & Repo Gateswall under 18 minutes on a product-only PR. - The
merge_groupcritical-path reading.
Both are read from the first such runs after the merge and recorded in the landing record.
- Shape: draft PR to
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 22076, "addendum": "patch round: merge origin/main for a fresh CI run (run 37641184309 concluded failure during the Actions incident without creating the required Test Core aggregate)", "status": "done", "branch": "claude/issue-22076-narrow-dispatch-gates-family", "pr": "https://github.com/objectstack-ai/objectstack/pull/22092", "session": "session_01VF48aw8RPG6wzDnMgp6rtw — subagent run, the parent's id", "head": "df8e26e3fb (was 1ed9df2285)", "summary": "I recreated worktree objectstack-issue-22076 at 1ed9df2285 and merged origin/main (bafb58bb08, which carries b04a5295f7 #22086 and bafb58bb08 #22089) as merge commit df8e26e3fb: no rebase, no force. The merge applied with no conflicts. Its changes are .changeset/22071-runtime-assets-boot-warning.md, .github/workflows/ci.yml, .github/workflows/lint.yml and four packages/cli files. git diff --quiet 1ed9df2285 HEAD on scripts/ci/select-gate-families.sh and its self-test exits 0, so both files are byte-unchanged. The self-test's YAML half re-reads the merged lint.yml and passes. I pushed df8e26e3fb as a fast-forward (1ed9df2285..df8e26e3fb). I did not touch the PR's draft, ready or auto-merge state, its labels or its body.", "tests": "Exit codes written to disk before reading, on HEAD df8e26e3fb: 'bash -n scripts/ci/select-gate-families.sh :: exit 0'; 'bash -n scripts/ci/select-gate-families.selftest.sh :: exit 0'; 'pnpm check:select-gate-families :: exit 0' → 'all 71 cases passed (369 checks)', 0 FAIL lines. The pre-push check:commit-card-trailers is green on the merge commit. CI on df8e26e3fb was not waited on (per the definition).", "mcp_calls": "0", "api_writes": "1 relay dispatch (POST /repos/objectstack-ai/objectstack/dispatches → POST /repos/objectstack-ai/objectstack/issues/22076/comments, this addendum via post-stamped.mjs). git push x1 (1ed9df2285..df8e26e3fb) is not REST.", "deviations": [ "The first git fetch printed 'cannot lock ref refs/remotes/origin/main: is at bafb58bb08 but expected b04a5295f7'. A sibling's concurrent fetch moved the shared ref. I merged after confirming origin/main = bafb58bb08, and 3d9188502e..origin/main listed exactly the two named commits." ], "open_questions": [], "out_of_scope_findings": [] }
Generated by Claude Code
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsLanded — PR #22092 →
dfa427bc67·domain:devx#2· 2026-10-07T17:50Z- Merged through the merge queue at 2026-10-07T17:49:48Z. The squash commit
dfa427bc67is onmain. - Verified on
mainby blob identity, both files equal to the PR headdf8e26e3fb:scripts/ci/select-gate-families.sh=76f368b76d;scripts/ci/select-gate-families.selftest.sh=7422005c5f.
- The card closed
completedonFixes #22076.pm:dispatchedis removed in this act. - The queue-time patch round: during GitHub's Actions incident the first CI run (
37641184309) never created the requiredTest Coreaggregate. A merge ofmain(df8e26e3fb, addendum6041719019) re-ran it green. The selector files were byte-unchanged.
The queue entry's own reading (Lint
37658565268):- This diff touches
scripts/ci/, so the family ran here, as designed:PM dispatch-gates self-test765 s, insideLint & Repo Gates26m44s. - With ci: Lint's three Type Check jobs, the Test Core shards, dogfood and Temporal each rebuild the workspace (3.5–5.8 min per job, ~25–30 job-min per CI+Lint pair) — extend #21186's turbo remote cache to them #22077 landed, the four
Type Checklanes took 1–3.5 min. SoLint & Repo Gatesis now the only long job in the Lint workflow, which is where this card's narrowing pays.
Still owed (the card's wall pin): the first product-only PR or queue entry after this merge. Its
Lint & Repo Gatesshould run no PM self-test, with a wall under 18 minutes. That gets read and recorded here with its run id.- Merged through the merge queue at 2026-10-07T17:49:48Z. The squash commit
objectstack-fleet commented
on Oct 7, 2026 ContributorAuthorMore actionsPost-landing reading — #22076's wall pin ·
domain:devx#2· 2026-10-07T18:29ZThis is the reading owed by the landing record
6043608279, taken from the first runs afterdfa427bc67. In every run below, thePM dispatch-gates self-teststep readsskipped.The pin: a product-only change. In each of these runs the self-test is skipped and the
Lint & Repo Gateswall is under 18 minutes.Run Event Change Lint & Repo Gateswall37658572315merge_group#22091 → c28f317ec6:packages/core/src/**,packages/objectql/src/**, a dogfood test, a changeset11.5 min 37658574914merge_group#22097 → 4935c66bc917.0 min 37662099940merge_group#22109 → ace0a5385211.8 min 37662182396pull_request#22108: packages/cli/src/**,packages/cli/test,content/docs, a changeset16.7 min Before and after, on the same kind of queue entry
- Before (the card's baseline,
37570577129, the queue entry for perf(spec): a bundle that never reads the ADR-0087 conversion table stops keeping it, 226 KB gzip off the console first screen (#22044) #22048):- the
Lint & Type Checkwall was 25.3 min; - the self-test alone took 10.2 min;
- the sibling
CIrun took 37.1 min.
- the
- After (feat(core): one by-name read of the security catalog (ADR-0131 C2, stage S1) #22091's queue entry, head
c28f317ec6):- the
Lint & Type Checkwall is 11.6 min.Lint & Repo Gates(11.5) is still that workflow's longest job, ahead ofType Check · workspace(6.8). - The queue entry's critical path is now
CI(31.6 min). Within it,Test Core (1/6)takes 30.2 min, against 8.1–13.8 min for the other five shards. That imbalance belongs to the shard-timings work in finding(ci): the shard-timings dataset rests on ONE scheduled run, and records @objectstack/spec at 1134.86 s against 1573–1651 s executed — #16468's 25%-headroom ceilings built on it would red every PR that runs spec #22014, not to this card.
- the
One run outside the pin, recorded so it is not mistaken for a regression
37662943138is apull_requestrun for feat(platform-objects,service-automation,service-realtime)!: seven deployment-level tables lose their injected organization column, and reads need manage_platform_settings (ADR-0131 D7) #22107, which also touchesscripts/platform-object-tenancy-census.json.- The self-test was correctly skipped: the file is scripts data, and no relative specifier names it.
- Its
Lint & Repo Gateswall was 19.3 min, but no step took more than 2.7 min: 194 successful steps summed to 19.3 min, against 189 summing to 11.4 min in37658572315. - The extra minutes are spread across steps, not in this family. A change that touches scripts data still selects the census families that read it.
Done-when's wall pin is met. Nothing further is owed on this card.
- Before (the card's baseline,
- added a commit that references this issue
on Oct 9, 2026
Filing gate: ③ a maintainer-directed task — the maintainer, after this seat's CI assessment in this session, verbatim: 「CI 优化按照你的建议创建任务」 — carrying ① a measured defect with a named fix site: the
PM dispatch-gates self-teststep takes 7.6–13.1 minutes whenever it runs and alone makesLint & Repo Gatesthe critical path ofLint & Type Checkonpull_requestandmerge_groupruns; its gate-family read-set is the tool's own inputs (every workflow file, everycheck:*script through the root and packagepackage.jsons, all ofscripts/**andpackages/*/scripts/**,.claude/**,skills/**,AGENTS.md,CLAUDE.md), so most PRs select it. Filed bydomain:skillsseat 2 (seat post #19287,session_0181E4ZeZmWyknawnauxD2CE). ⛔ Not a claim. Thetoolingentry rule (triage-duties.md:34) is met by the maintainer's instruction quoted here; the guarded surface is the required contextLint & Repo Gates.Reader: triage first-touch → the battery is PM tooling (
domain:skills); its CI wiring (scripts/ci/select-gate-families.sh,lint.yml) isdomain:devx. The seat proposesdomain:skillswith the wiring touched minimally; triage routes.Dedupe: page-looped REST listings, closed included (union 1,266 as on the sibling cards) grepped for
dispatch-gates.*(self-test|lint|critical)|pm-dispatch-gates→ 11 hits. The nearest: #16496 (closed: Lint & Repo Gates is the merge-group critical path after #16453; run each gate family only on the paths it reads — the origin ofselect-gate-families.sh), #16769 (closed: pins for the families' key sets), #18201 (closed:pnpm check:pm-dispatch-gatescannot complete inside the container's 10-minute cap), #21719 (closed: the battery holds the shared verify lock about 20 minutes), #8162 (the original unconditional rationale cited atlint.yml:985). None tiers the battery or re-measures what its read-set costs the PR path; W3 on #22060 (on hold) is the long-horizon split of the frozen file, not this card.What is measured
Lint & Type Checkpull_requestrun 37567293525 (branchclaude/issue-22044-…): wall 26.4 min;Lint & Repo Gates26.4 min is the critical path; its longest step isPM dispatch-gates self-test10.9 min, then the engine query-options erasure ratchet 2.1 and ESLint 1.3.merge_grouprun 37570577129 (queue entry for perf(spec): a bundle that never reads the ADR-0087 conversion table stops keeping it, 226 KB gzip off the console first screen (#22044) #22048): wall 25.3 min;Lint & Repo Gates25.3 min; the self-test 10.2 min.select-gate-families.sh:27-28).pull_requestrun 37572678684 (branchclaude/issue-22047-…) skipped it: Lint wall 17.5 min, andType Check · workspace(17.4 min) became the critical path. So without this step the Lint wall is about 17 minutes.scripts/ci/select-gate-families.sh:54-74): the tool discovers every workflow file, resolves everycheck:*script through the root and packagepackage.jsons, reads each gate's source for watch hints (ALL ofscripts/**and everypackages/*/scripts/**), and reads.claude/**,skills/**,AGENTS.md,CLAUDE.md. A PR that touches any package manifest or any script selects the 8–13-minute step; the tree-wide content censuses the battery also performs are already declared "deliberately off the PR path" in that comment, yet they run whenever the family is selected, because the battery has one tier.scripts/pm/dispatch-gates.mjs, which is frozen under ruling 208 (R6); the wrapper isscripts/pm/check-dispatch-gates.mjs.Done when
pull_requestandmerge_groupwhen the family is selected; a slow tier — the tree-wide censuses (compound-anchor census, exposed-scratch-dir sweep, tracked-name reachability) — runs onpushtomainand the scheduled full run only, where a red files a card as the hourly full run already does (ci: push runs on main use the affected set; an hourly scheduled run keeps the full list and files a card on red (maintainer-directed) #16467). Implemented in the wrapper and the family selector if the frozen file needs no edit; if it needs one flag, the PR names that flag and quotes the maintainer's unfreeze for exactly it.select-gate-families.sh --self-testpins ([finding] nothing pinsselect-gate-families's key sets to the gates' LIVE read-sets — the dispatch-gates self-test grew a.shcontent census the day the selector shipped, and the selector has no*.sharm #16769) are updated with it.packages/*/src/**,Lint & Repo Gatesruns no PM self-test and its wall is under 18 minutes; the merge_group run's critical path after the change is measured in the PR body with run ids.Lint & Repo Gatesstays a required context; ⛔ no edit todispatch-gates.mjsbeyond the one flag, if any, and only with the quoted unfreeze.Generated by Claude Code