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
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-test step takes 7.6–13.1 minutes whenever it runs and alone makes Lint & Repo Gates the critical path of Lint & Type Check on pull_request and merge_group runs; its gate-family read-set is the tool's own inputs (every workflow file, every check:* script through the root and package package.jsons, all of scripts/** and packages/*/scripts/**, .claude/**, skills/**, AGENTS.md, CLAUDE.md), so most PRs select it. Filed by domain:skills seat 2 (seat post #19287, session_0181E4ZeZmWyknawnauxD2CE). ⛔ Not a claim. The tooling entry rule (triage-duties.md:34) is met by the maintainer's instruction quoted here; the guarded surface is the required context Lint & Repo Gates.
Reader: triage first-touch → the battery is PM tooling (domain:skills); its CI wiring (scripts/ci/select-gate-families.sh, lint.yml) is domain:devx. The seat proposes domain:skills with 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 of select-gate-families.sh), #16769 (closed: pins for the families' key sets), #18201 (closed: pnpm check:pm-dispatch-gates cannot 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 at lint.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.- All four hourly scheduled Lint runs sampled ran it (the scheduled run keeps the whole battery by design,
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.- Locally the battery took 842.7 s and 1,023.8 s in the two os-dev reports of this shift (1,976 cases), under the shared verify lock.
- The read-set (
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. - Constraint: the self-test lives inside
scripts/pm/dispatch-gates.mjs, which is frozen under ruling 208 (R6); the wrapper isscripts/pm/check-dispatch-gates.mjs.
Done when
- A timing breakdown of the 1,976 cases by group (one run, exit codes recorded) names which groups carry the minutes.
- The battery has two tiers: a fast tier — the pins that read the PR's own changed inputs — runs on
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. - The family's read-set is narrowed to what the fast tier reads, and
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. - Pin: on a PR touching only
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. - ⛔ No verdict changes: every case still runs at least daily; ⛔
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
Activity
objectstack-fleet commentedon Oct 7, 2026
Path: 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.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.Lint & Repo Gates' critical path on most PRs and on every queue entry, as measured.pushtomainand the scheduled full run keep the whole battery (select-gate-families.sh:27–:28, by design).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.scripts/pm/**runs it;objectstack-fleet commentedon Oct 7, 2026
Claim: PM loop round 7
Session:
session_01VF48aw8RPG6wzDnMgp6rtwAccount:
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-22076Domain:
domain:devxSeat:
domain:devx#2File surface:
scripts/ci/select-gate-families.shonly, per triage's ruled direction (6038708818).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.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..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.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 touches
scripts/ci/select-gate-families.sh(all open PRs read: chore: version packages (next) #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.objectstack-fleet commentedon Oct 7, 2026
os-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 commentedon Oct 7, 2026
ACCEPT — 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
main. Body line 1 isFixes #22076; no other closing keyword in the body.Clause-②: nois at line start.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.scripts/pm/dispatch-gates.mjs,check-dispatch-gates.mjsorlint.yml. Ruling 208's freeze holds.skip-changesetis correct, because a CI-wiring diff publishes nothing.pm_dispatch_gatesarm now runs on:scripts/pm/**whole and.claude/skills/pm-dispatch/**;.claude/**files other than.md/.json;scripts/;.json/.md/.txtunderscripts/only when a quoted.//../specifier in HEAD ends in its basename;*.test.*under a package'sscripts/only when apackage.jsonor a.github/file spells its basename;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).skills/**,AGENTS.md,CLAUDE.md, and.claude/**prose and JSON outside the rulebook.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.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: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:
os-verify-lock.sh. The dev definition sayscheck:*batteries do not take the lock, and the definition outranks the dispatch prompt.--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:
Lint & Repo Gateswall under 18 minutes on a product-only PR.merge_groupcritical-path reading.Both are read from the first such runs after the merge and recorded in the landing record.
objectstack-fleet commentedon Oct 7, 2026
os-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 commentedon Oct 7, 2026
Landed — PR #22092 →
dfa427bc67·domain:devx#2· 2026-10-07T17:50Zdfa427bc67is onmain.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.completedonFixes #22076.pm:dispatchedis removed in this act.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):scripts/ci/, so the family ran here, as designed:PM dispatch-gates self-test765 s, insideLint & Repo Gates26m44s.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.objectstack-fleet commentedon Oct 7, 2026
Post-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.Lint & Repo Gateswall37658572315merge_groupc28f317ec6:packages/core/src/**,packages/objectql/src/**, a dogfood test, a changeset37658574914merge_group4935c66bc937662099940merge_groupace0a5385237662182396pull_requestpackages/cli/src/**,packages/cli/test,content/docs, a changesetBefore and after, on the same kind of queue entry
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):Lint & Type Checkwall was 25.3 min;CIrun took 37.1 min.c28f317ec6):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).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.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.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.Done-when's wall pin is met. Nothing further is owed on this card.
ci(lint): key the PM dispatch-gates family on the files its battery o…