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(ui-merge): every merge-queue entry runs all four ui lanes because the ui filter output falls back to 'true' on merge_group — decide the ui lanes from the diff against merge_group.base_sha, as Test Core already does (parent #25677) #25867
Filing gate ③ (maintainer-directed) + ④: aftercare of the ui/ merge (#25752), part of #25677. Touches .github/workflows/ci.yml = Tier H: GOVERNED_APPROVERS review, the PR stops at draft.
Maintainer, 2026-10-26 01:45Z, in the project thread that measured post-merge CI speed: 「创建issue」 (asked after reading the ranked fix list; this is item 1).
谁付代价(业务筛): every PR that lands goes through the merge queue. Since the merge, a queue entry that changes only docs, scripts or a core package still runs Test UI (16 shards), Type Check UI, Build & E2E UI and Lint UI. Small entries used to finish in 4–10 min; now their floor is ~16–18 min, and each entry pays ~220 extra runner-minutes. With up to 8 card threads landing in parallel, this is the main post-merge slowdown the fleet feels.
Measured
Pre-merge merge_group CI runs (2026-10-25, list of 40): small entries 4.0–9.8 min (e.g. 40181079769 4.0, 40195098891 4.9, 40198037200 5.1), core entries 26–30 min.
Cause, ci.ymlfilter job: dorny/paths-filter runs only on pull_request / push (if: github.event_name == 'pull_request' || github.event_name == 'push'), and the outputs ui / ui_consumers fall back to 'true' (ui: ${{ steps.changes.outputs.ui || 'true' }}). Test Core does not have this problem: scripts/ci/select-shard-packages.sh already scopes merge_group runs with turbo ls --affected against merge_group.base_sha.
Wanted
On merge_group, compute the ui and ui_consumers outputs from git diff --name-only <merge_group.base_sha>...HEAD, using the same globs the pull_request filter uses. Fail open: if the base cannot be fetched or the diff fails, the output stays 'true'.
push / schedule / workflow_dispatch keep the full battery (maintainer ruling 2026-10-25 Q6-b: push-to-main runs stay).
The workflow's gate rosters follow (check-ci-filter-parity, check-expected-skips, check-step-collectors); each --self-test exits 0.
Acceptance
A queue entry that changes no ui/** file and no ui_consumers path shows the four ui lanes as skipped, and the required contexts (Lint UI, Build & E2E UI, and later Type Check UI) still report success. Skipped counts as passing for a required check, so name the run that shows this.
A queue entry touching ui/** still runs all four lanes.
On the card: queue CI wall time for one small entry before and after.
Expected saving: ~220 runner-min per non-ui queue entry; small entries back to 5–10 min. Size: S. Clause-②: no. Metadata-protocol: none.
Dedupe
search_issues 2026-10-26 01:50Z 「merge_group merge queue runs all ui jobs paths filter ui output true」: 5 hits, all closed and unrelated (#19036, #16574, #11621, #9283, #4897). New.
Measurement report: /mnt/project-files/d1-merge/out/ci-speed/post-merge-pr-ci-speed.md (project thread "Keep PR CI fast after the merge").
Claim: epic #25677 round 8 (post-cutover CI speed cards; Tesla 2026-10-26 01:45Z 「创建issue」) 2026-10-26T01:55Z
Session: session_01RSDL3SFtJaKzcymvCD8RsU
Account: os-tesla
Branch: claude/project-thread-8dceid (the card thread's designated branch in objectstack-ai/objectstack — the thread can push only this branch, a measured platform exception to claude/issue-<n>-<slug>)
Worktree: objectstack-issue-25867
Domain: domain:devx
Seat: epic:#25677
Scope: the whole card — ci.ymlfilter job computes ui / ui_consumers on merge_group from git diff --name-only <merge_group.base_sha>...HEAD with the pull_request globs, fail-open to 'true'; push/schedule/workflow_dispatch keep the full battery (Q6-b); the gate rosters follow with --self-test 0; Tier H (draft, os-zhuang + hotlong), skip-changeset
Why now: every queue entry pays ~220 runner-min and a 16–18 min floor for four ui lanes it does not need; with 6 card threads landing tonight this is the queue's pace
Container & model: S, mode:thread (thread session session_01Suqt7vsGh5kE2NhDZyqeh6; order: this card's body, FRAME.md applies), model: opus, effort: xhigh
Clause-②: no
Metadata-protocol: none
Responsibility: n/a — epic step
Thread-read: none
Serial constraints cleared: #25868 edits only the test-ui job of the same file (branch claude/project-thread-n0iri6); the #25853 seat's Type Check UI row PR edits scripts/check-required-contexts.mjs and the two statesTheSet surfaces, not ci.yml; #25869 is held until this and #25868 land. Rebase over whichever lands first; ⛔ do not change any lane's if: beyond the filter outputs this card names
{
"issue": 25867,
"status": "done",
"branch": "claude/project-thread-8dceid",
"pr": "https://github.com/objectstack-ai/objectstack/pull/25881",
"session": "session_01Suqt7vsGh5kE2NhDZyqeh6",
"premise_still_valid": true,
"summary": "ci.yml filter job: the dorny/paths-filter step's allow-list gains merge_group (the pinned v4.0.3 reads merge_group.base_sha/head_sha from the payload and diffs base..head), continue-on-error on that event so a failed diff fails open to 'true'. ui and ui_consumers read the queue diff; docs/core/crosspkg are guarded with github.event_name != 'merge_group' and stay 'true' on queue builds; schedule/dispatch unchanged. check-expected-skips header + ui roster reasons and the dispatch-gates marker census (133 -> 137) follow.",
"tests": "Replayed the pinned action dist/index.js with synthetic merge_group payloads and this branch's filter block: non-ui entry abebc4e1 -> ui=false ui_consumers=false; spec+lint b00fc55c -> ui=false ui_consumers=true; ui/ entry 12105449 -> ui=true; 3-commit group 3fca5996..c475b45b -> ui=true; depth-1 checkout with base absent -> action fetched base by sha and diffed; unfetchable base -> action exit 1 with no outputs (fail-open via continue-on-error). Live queue evidence owed after landing (this PR's own entry changes ci.yml, which is in the ui filter, so it runs all four ui lanes).",
"gates": "be2cff5e: dispatch-gates --commands derives 67; all 67 exit 0 (incl. check:pm-dispatch-gates fast tier 1917/1917, check-ci-filter-parity + --self-test, check:pm-expected-skips, check-step-collectors + --self-test, check:type-check-debt); --ran: 67 derived, 67 run, 0 NOT-MEASURED (derived zero). Earlier head 5aa9fcb3: check:pm-dispatch-gates 1 of 1917 red (marker census pinned check-expected-skips.mjs:133), fixed in be2cff5e. PR check-runs: in_progress at report time.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"files_changed": [
".github/workflows/ci.yml",
"scripts/pm/check-expected-skips.mjs",
"scripts/pm/dispatch-gates.self-test.mjs"
],
"line_budget": "+70 / -37",
"deviations": [
"Route: the card says git diff --name-only with the pull_request globs; the step runs dorny/paths-filter itself on merge_group instead, so the globs are the same block by construction and check-ci-filter-parity's one-step rule holds.",
"Third file outside the card's named rosters: dispatch-gates.self-test.mjs marker-census row moved 133 -> 137 because the check-expected-skips header grew four lines."
],
"mcp_calls": "4 — issue_read get, issue_read get_comments, list_pull_requests, pull_request_read get (all reads, no write tool)",
"api_writes": "2 — relay pr_create (fleet-write run 40259928648; relay's governed-review follow-up requested os-zhuang + hotlong), this report comment via post-stamped",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none · noted, not filed — docs/core/crosspkg could read the queue diff the same way (Build Core / Build Docs would skip on queue entries outside their paths); left at 'true' per the filter's 'queue build is the last validation before main' reasoning"
]
}
Live queue evidence for #25881 (merged 03:27Z), read 2026-10-26T05:25Z.
Non-ui entry: #25929 (fix(service-automation), 3 files: packages/services/service-automation/src/** + a changeset). Merge-group run 40271496679, base dd5e3554f0:
job
conclusion
window
filter
success
04:55:07–04:55:34
Test UI (pre-expansion name, all 16 shards)
skipped
04:55:34
Type Check UI
skipped
04:55:34
Build & E2E UI
skipped
04:55:34
Lint UI
skipped
04:55:34
Build Core / Build Docs
success
until 05:01:26 / 05:00:41
Test Core (8 shards + aggregate)
success
until 05:15:39 (long pole: 4/8, 19.5 min)
The entry landed on main as de2b7e02 with Lint UI and Build & E2E UI (required) reported as skipped, so the queue accepted skipped as passing.
Spec entry: #25830 (spec,plugin-auth,runtime,cli). Run 40264874688 took the ui_consumers path, as designed:
Test UI and Lint UI were skipped.
Type Check UI (03:36:39–03:48:37) and Build & E2E UI (03:36:39–03:43:43) ran.
After, on 40271496679, the ui lanes took 0 runner-min and occupied 0 runner slots.
Wall clock: 40271496679 ran 20.6 min (04:55:05 to 05:15:39). For an entry that touches a core package, Test Core 4/8 is the critical path either way, so the ui skip does not shorten it; the saving there is runner-minutes and slots.
Pending: a docs- or scripts-only entry, where the ui lanes used to set the ~16–18 min floor, has not entered the queue since the merge. When one does, its wall clock is the remaining before/after number on this card.
Activity
objectstack-fleet commentedon Oct 26, 2026
Claim: epic #25677 round 8 (post-cutover CI speed cards; Tesla 2026-10-26 01:45Z 「创建issue」) 2026-10-26T01:55Z
Session:
session_01RSDL3SFtJaKzcymvCD8RsUAccount:
os-teslaBranch:
claude/project-thread-8dceid(the card thread's designated branch in objectstack-ai/objectstack — the thread can push only this branch, a measured platform exception toclaude/issue-<n>-<slug>)Worktree:
objectstack-issue-25867Domain:
domain:devxSeat:
epic:#25677Scope: the whole card —
ci.ymlfilterjob computesui/ui_consumersonmerge_groupfromgit diff --name-only <merge_group.base_sha>...HEADwith thepull_requestglobs, fail-open to'true'; push/schedule/workflow_dispatch keep the full battery (Q6-b); the gate rosters follow with--self-test0; Tier H (draft, os-zhuang + hotlong),skip-changesetWhy now: every queue entry pays ~220 runner-min and a 16–18 min floor for four ui lanes it does not need; with 6 card threads landing tonight this is the queue's pace
Container & model: S,
mode:thread(thread sessionsession_01Suqt7vsGh5kE2NhDZyqeh6; order: this card's body, FRAME.md applies),model: opus,effort: xhighClause-②: no
Metadata-protocol: none
Responsibility: n/a — epic step
Thread-read: none
Serial constraints cleared: #25868 edits only the
test-uijob of the same file (branchclaude/project-thread-n0iri6); the #25853 seat's Type Check UI row PR editsscripts/check-required-contexts.mjsand the two statesTheSet surfaces, notci.yml; #25869 is held until this and #25868 land. Rebase over whichever lands first; ⛔ do not change any lane'sif:beyond the filter outputs this card namesobjectstack-fleet commentedon Oct 26, 2026
os-dev-report
{ "issue": 25867, "status": "done", "branch": "claude/project-thread-8dceid", "pr": "https://github.com/objectstack-ai/objectstack/pull/25881", "session": "session_01Suqt7vsGh5kE2NhDZyqeh6", "premise_still_valid": true, "summary": "ci.yml filter job: the dorny/paths-filter step's allow-list gains merge_group (the pinned v4.0.3 reads merge_group.base_sha/head_sha from the payload and diffs base..head), continue-on-error on that event so a failed diff fails open to 'true'. ui and ui_consumers read the queue diff; docs/core/crosspkg are guarded with github.event_name != 'merge_group' and stay 'true' on queue builds; schedule/dispatch unchanged. check-expected-skips header + ui roster reasons and the dispatch-gates marker census (133 -> 137) follow.", "tests": "Replayed the pinned action dist/index.js with synthetic merge_group payloads and this branch's filter block: non-ui entry abebc4e1 -> ui=false ui_consumers=false; spec+lint b00fc55c -> ui=false ui_consumers=true; ui/ entry 12105449 -> ui=true; 3-commit group 3fca5996..c475b45b -> ui=true; depth-1 checkout with base absent -> action fetched base by sha and diffed; unfetchable base -> action exit 1 with no outputs (fail-open via continue-on-error). Live queue evidence owed after landing (this PR's own entry changes ci.yml, which is in the ui filter, so it runs all four ui lanes).", "gates": "be2cff5e: dispatch-gates --commands derives 67; all 67 exit 0 (incl. check:pm-dispatch-gates fast tier 1917/1917, check-ci-filter-parity + --self-test, check:pm-expected-skips, check-step-collectors + --self-test, check:type-check-debt); --ran: 67 derived, 67 run, 0 NOT-MEASURED (derived zero). Earlier head 5aa9fcb3: check:pm-dispatch-gates 1 of 1917 red (marker census pinned check-expected-skips.mjs:133), fixed in be2cff5e. PR check-runs: in_progress at report time.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "files_changed": [ ".github/workflows/ci.yml", "scripts/pm/check-expected-skips.mjs", "scripts/pm/dispatch-gates.self-test.mjs" ], "line_budget": "+70 / -37", "deviations": [ "Route: the card says git diff --name-only with the pull_request globs; the step runs dorny/paths-filter itself on merge_group instead, so the globs are the same block by construction and check-ci-filter-parity's one-step rule holds.", "Third file outside the card's named rosters: dispatch-gates.self-test.mjs marker-census row moved 133 -> 137 because the check-expected-skips header grew four lines." ], "mcp_calls": "4 — issue_read get, issue_read get_comments, list_pull_requests, pull_request_read get (all reads, no write tool)", "api_writes": "2 — relay pr_create (fleet-write run 40259928648; relay's governed-review follow-up requested os-zhuang + hotlong), this report comment via post-stamped", "open_questions": [], "out_of_scope_findings": [ "carrier: none · noted, not filed — docs/core/crosspkg could read the queue diff the same way (Build Core / Build Docs would skip on queue entries outside their paths); left at 'true' per the filter's 'queue build is the last validation before main' reasoning" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 26, 2026
Live queue evidence for #25881 (merged 03:27Z), read 2026-10-26T05:25Z.
Non-ui entry: #25929 (
fix(service-automation), 3 files:packages/services/service-automation/src/**+ a changeset). Merge-group run 40271496679, basedd5e3554f0:The entry landed on
mainasde2b7e02withLint UIandBuild & E2E UI(required) reported as skipped, so the queue accepted skipped as passing.Spec entry: #25830 (
spec,plugin-auth,runtime,cli). Run 40264874688 took theui_consumerspath, as designed:f00e8d5c.Before vs after (ui lanes per queue entry):
Wall clock: 40271496679 ran 20.6 min (04:55:05 to 05:15:39). For an entry that touches a core package, Test Core 4/8 is the critical path either way, so the ui skip does not shorten it; the saving there is runner-minutes and slots.
Pending: a docs- or scripts-only entry, where the ui lanes used to set the ~16–18 min floor, has not entered the queue since the merge. When one does, its wall clock is the remaining before/after number on this card.
Generated by Claude Code