Skip to content

feat(pm): dispatch-gates derives the ui/scripts/__tests__ suite for diffs under ui source, ui apps, skills/objectui and ui/scripts - #26383

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-hc6m69
Oct 27, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-hc6m69

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Elon · project thread

What

scripts/pm/dispatch-gates.mjs now derives pnpm --dir ui exec vitest run scripts/ (the whole ui/scripts/__tests__ suite) for any diff touching one of the card's four roots: ui/packages/**/src, ui/apps/**, skills/objectui/** or ui/scripts/**. Before this, those 180 files (178 that run, 2 skipped) ran only in CI's 16 Test UI shards and no derived family named them.

How (the tool's own convention, no parallel mechanism)

  • A change-kind row. A new row in CHANGE_KIND_ROWS (scripts/pm/dispatch-gates.data.mjs) with predicate ui-scripts-suite-input, bound in CHANGE_KIND_PREDICATES. The roots are data (UI_SCRIPTS_SUITE_ROOTS). They are matched in CI's own paths: language through the existing triggerListCovers, so a directory surface counts the way it counts for a workflow trigger.
  • Bound to the CI job it stands in for. Every other gate in that table resolves by name against a discovered check:* family. This suite has no such family: the only step that runs it is Test UI's vitest line, which carries a shard and the affected-test selector's filter list, and .github/** is out of scope here. So the gate declares ciJob: 'Test UI' and ciRunner: 'pnpm --dir ui exec vitest run'.
    • ciJobRunsRunner resolves the gate against the same workflowEntries the discovery reads. If the job is renamed or the runner is respelled, the gate renders STALE, which is the same rot report a renamed family gets.
    • bindChangeKindRows refuses a half-declared binding at load.
    • The census guard in the self-test reds when the live workflows stop running it.
  • It reaches every output. Through kindGroups the gate is in --commands, --json, the human convention block, the --residue kind list and --ran (commandsFor → runReconciliation). Nothing moves in the family partition: the residue still places 326 of 326.
  • The why names its prerequisite. The suite needs the seven @objectstack packages Test UI builds first. Unbuilt, 16 files go red on a missing dist import (measured below). So the line prints the job's own turbo build command.

Measured first

All measured on a 4-vCPU cloud container at base 6390fe52.

Reading Result
Suite, packages unbuilt 16 files failed / 162 passed, 231 s (missing @objectstack/spec dist and similar)
Seven packages built (job's turbo command) 274 s cold
Suite, built — run 1 178 passed, 2 skipped, 284 s
Suite, built — run 2 178 passed, 2 skipped, 286 s

Vitest reports ~270 s of the run as module import.

Reach of the 180 files, from a static scan of each file plus the helpers it imports relatively. This is a source scan, not a runtime trace.

Root Files that read it (file + helpers) File alone
ui/packages/**/src 165 128
ui/apps/** 141 66
skills/objectui/** 16 8
ui/scripts/** 170 140

Decision: the whole suite, not an affected subset. On this container it is about five minutes, not the card's "about a minute". It still replaces a ~25-minute CI round trip. A subset map would have to model what each file reads off the tree: 165 of the 180 read package source and 141 the apps. That map is exactly the second list that goes stale, and it would save minutes, not a round trip. The deletion criterion and the stated blind spot sit with the row's docblock.

Self-test pins (fast tier, in-process)

  • A diff under each of the four roots derives the suite, both in the rendered convention block (anchored on the delimiter) and in the runnable union.
  • packages/core/src/x.ts, ui/packages/core/package.json, skills/objectstack/SKILL.md and scripts/pm/dispatch-gates.mjs derive neither.
  • A run record that carries every derived command except the suite is not ok, and names the suite unrun. The control with it is ok.
  • An unresolved binding renders STALE, naming the job and the runner.
  • ciJobRunsRunner resolves on a fixture job, fails on a renamed job and on a respelled runner, and resolves against the live workflows.
  • A half-declared binding refuses at load.
  • One existing pin moved. The inherited-population marker line census reads dispatch-gates.mjs:738 instead of :736, because the data import and its re-export each gained one name. It carries a comment like its neighbours.

node scripts/pm/dispatch-gates.mjs --self-test --fast, detached: 1935 cases pass. The full battery result is in the gate run below.

End to end on PR #26274 head 1ef5c48

The head is reachable. Merge base 2409c9c8, 57 changed files.

  • --commands over those 57 files: 66 commands. Against the base tool (same tree, 6390fe52) the only difference is the added line pnpm --dir ui exec vitest run scripts/.
  • I ran that command in a worktree at 1ef5c482, after the seven-package build: 4 files failed, 174 passed. It reproduces all three reds the card measured:
    • check-skill-examples.test.ts: json: 69 marked, floor 70 (the MARKED_FLOOR).
    • turbo-build-inputs.test.ts: @object-ui/console's build reads packages/sdui-parser/src/retired-visibility-dialects.ts, which turbo's build inputs do not declare.
    • check-doc-expression-carriage.test.ts: 10 failures on the carriage fixtures.
    • The fourth, check-hand-rolled-comment-mask.test.ts › exits 0 as a process, was a 15 s timeout while the dispatch-gates self-test ran on the same 4 cores. It passed in both clean runs on main. I read it as container load, not that head's.

No narrowing

--commands from this branch vs main's tool on the same tree, sorted and diffed:

Paths main this branch Difference
packages/core/src/index.ts 49 49 none
scripts/pm/dispatch-gates.mjs 30 30 none
ui/scripts/check-skill-examples.mjs 12 13 + the suite
skills/objectui/SKILL.md 34 35 + the suite
ui/apps/console/package.json + a spec file 85 86 + the suite
#26274's 57 files 65 66 + the suite

No line was removed in any set.

Local gates for this diff

node scripts/pm/dispatch-gates.mjs --commands (no paths, from git, merge base 6390fe52) derives 30 families for this diff. All 30 ran, each recorded as CMD :: exit N, and all 30 exited 0. pnpm check:pm-dispatch-gates is the fast tier, 1935 cases in 377 s.

node scripts/pm/dispatch-gates.mjs --ran ran.list reports: 30 derived famil(ies) accounted for — 30 run, 0 NOT-MEASURED (a DERIVED zero), exit 0.

The slow tier (--self-test without --fast) runs on main's push and schedule only. Its local reading is reported on the card.

Out of scope, noted for the seat

  • dispatch-gates.mjs's pnpm recognizer reads pnpm [--filter X] [run] check:*, never pnpm --dir ui run check:*. So the 38 distinct check:* scripts that Lint UI / Build & E2E UI invoke that way in ci.yml are discovered as no family at all.
  • Those jobs' if: is ui_tree != 'false' && ui != 'false', which jobIfReading refuses as an intersection. So they appear in neither the job-filtered tail nor the always-runs tail.
  • That is a reproducible under-derivation for every ui card, and it is not fixed here. It needs its own card (recognizer + &&-of-filter-outputs reading).

Governance

Clause-②: no
Metadata-protocol: none

Fixes #26318

🤖 Generated with Claude Code

https://claude.ai/code/session_01AYg1gtz1tWt66GpPnTo1QF


Generated by Claude Code

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对

Verdict: ACCEPT at head aab0e515b0b30aee4f3cef645d501e476edcd93e. This is not governed: check-governed-merges --pr 26383 reports 0 of 3 paths on the register, and the size is +217/−6. Ordinary queue landing applies, and the seat flips it now.

Contract review: not triggered. The diff is private root scripts only (scripts/pm/dispatch-gates{,.data,.self-test}.mjs): no packages/spec/src/** and no governed rule text.

The data module's own rule is met. dispatch-gates.data.mjs says a new change-kind row is added "still only on the maintainer's words", and this row came from a seat-filed card. The seat put that question to the maintainer, and he answered 「同意合并」 in the card thread at 2026-10-27 03:58Z.

Against the card and the dispatch order (read line by line)

  • One CHANGE_KIND_ROWS row, ui-scripts-suite-input, covers the card's four roots (UI_SCRIPTS_SUITE_ROOTS). They are matched in CI's own paths: language through triggerListCovers, so no second glob dialect is added.
  • The gate names the whole suite, never a subset map. The dev measured it at 284 s and 286 s on 4 vCPU, not the card's "about a minute". The PR records the cost of that measurement and of the build prerequisite in the row's why.
  • ciJobRunsRunner binds the row to the live Test UI job's pnpm --dir ui exec vitest run step. If that job is renamed or retired, the row renders STALE instead of outliving it. bindChangeKindRows refuses a half-declared binding at load.
  • No narrowing: every existing family's derivation is unchanged; the dev checked this over six path sets.
  • The dev's reading: 30 derived gates exit 0; --ran 30/30; the full --self-test passes (2200 cases); PR feat(types,react,sdui-parser)!: retire the node-level visibleOn / hiddenOn / disabledOn spellings #26274 head 1ef5c48 reproduces all three of the card's reds.

Gates at head aab0e51

  • 33 success, 17 skipped, 0 failing.

Out of scope, carried in the seat's handoff, not filed here: dispatch-gates never discovers the 38 pnpm --dir ui run check:* gates of Lint UI and Build & E2E UI. Their ui_tree && ui condition is refused as an intersection, so every ui card under-derives them.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 27, 2026 04:00
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 27, 2026 04:00
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 27, 2026
Merged via the queue into main with commit 55f845a Oct 27, 2026
51 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-hc6m69 branch October 27, 2026 04:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants