Repository navigation
Description
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 3).
谁付代价(业务筛): the fleet's runner budget, and the wall clock of ui PRs. Every run that schedules the ui lanes repeats one build 20 times (Test UI ×16, Type Check UI, Lint UI, Build & E2E UI): turbo run build --filter=@objectstack/spec... --filter=@objectstack/client... … for the seven packages objectui consumes. When cardholders are running in parallel, this is ~40 runner-min per run, plus 1.6–2.5 min on the critical path of a ui-only PR.
Measured (run 40248884869, 2026-10-26)
- The step "Build the @objectstack packages objectui consumes" took 1.6–2.5 min in each of the 20 ui jobs.
- Turbo cache: Build & E2E UI had 13 hits and 20+ misses. Type Check UI's turbo run had 45 cached out of 104 tasks. The same task hashes (e.g.
98223300f02b7bf4,7454d81e14530f86) are a miss in one job and a hit in another: each job restores its ownactions/cachekey (turbo-<job>-<ref>-), falling back toturbo-build-core-. pull_requestruns get noTURBO_TOKEN(it is set only formerge_groupandrefs/heads/main), so PRs do not read the remote cache from ci: wire the Vercel turbo remote cache (team object-stack) into ci.yml — trusted events write, PRs read, signed — so cloud's pinned framework build can replay what this repo's main already built #21186 / 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.- Caveat: main's per-job caches were cold right after the cutover. Re-read the hit rate on a run from the same day before choosing.
Wanted
The seat measures two options and picks the cheaper one per run:
- (a) one
ui-depsjob builds the seven packages once and uploads theirdist/as an artifact, and the ui lanes download it; - (b)
pull_requestruns read the signed turbo remote cache, still with no write.
⛔ Do not change what the ui lanes test, or their if:.
Acceptance
- On the card: total ui-lane runner-min and Test UI shard wall time, before and after, on comparable PRs.
- The gate rosters follow; each
--self-testexits 0.
Expected saving: ~40 runner-min per ui-scheduling run, 1–2 min per ui lane. Size: S–M. Clause-②: no. Metadata-protocol: none.
Dedupe
search_issues 2026-10-26 01:50Z 「ui jobs build objectstack packages once artifact turbo remote cache pull_request」: 20 hits. The relevant ones are closed: #21186 (wire the remote cache) and #22077 (extend it to Lint / Test Core). Neither covers the ui lanes added at cutover. New.
Measurement report: /mnt/project-files/d1-merge/out/ci-speed/post-merge-pr-ci-speed.md.
Activity
objectstack-fleet commentedon Oct 26, 2026
Epic PM: two rows added from the 2d-1 census 2026-10-26T02:24Z ·
session_01RSDL3SFtJaKzcymvCD8RsUNot a claim; this card stays held until #25867 and #25868 land. Two follow-up rows from #25879 (4b 2d-1, the
ui/scripts/__tests__readers of the nestedui/.github/workflows/ci.yml) belong to this card because they are the same surface — the root* UIjobs' Turbo cache steps — and the seat that measures options (a) and (b) touches exactly those steps:type-check-uijob's Turbo cache save has none of the objectui#6577 / fix(ci): diff-scope the no-major changeset guard against the merge base (#7005) #7048 bounds: no split restore/save, notimeout-minuteson the save, nocontinue-on-error, nocache-hitguard, and a 40-minute job ceiling that leaves the verdict no room.ui/scripts/__tests__/turbo-cache-save-bound.test.ts(deleted by test(ui-merge): the ui gate-wiring pins read the root ci.yml that runs them; pins on jobs it did not port retire #25879 as a nested-workflow reader) pointed at the root job fails 5 of its 6 pins; only "save after the last command" holds. Wanted here: bound the four root ui jobs' saves the objectui way, then restore those six pins againsttype-check-uiby path (the helperui/scripts/__tests__/helpers/root-ci.tsfrom test(ui-merge): the ui gate-wiring pins read the root ci.yml that runs them; pins on jobs it did not port retire #25879)..github/workflows/ci.yml= Tier H, as this card already is.ui/scripts/report-turbo-cache.mjs(prune before save, restored-key notice) or the script retires;report-turbo-cache.test.tslost 7 nested-workflow cases in test(ui-merge): the ui gate-wiring pins read the root ci.yml that runs them; pins on jobs it did not port retire #25879 with a pointer here.Acceptance addition: the seat's before/after table also shows the save step's duration and that a save that exceeds its bound cannot red the job. Part of #25677.
objectstack-fleet commentedon Oct 26, 2026
Claim: epic #25677 round 8 (post-cutover CI speed card 3; Tesla 2026-10-26 01:45Z 「创建issue」; held until #25881 and #25882 landed, both merged 03:27Z) 2026-10-26T05:20Z
Session:
session_01RSDL3SFtJaKzcymvCD8RsUAccount:
os-teslaBranch:
claude/project-thread-kz44z5(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-25869Domain:
domain:devxSeat:
epic:#25677Scope: the whole card — build the seven
@objectstack/*packages the ui lanes consume once per run and hand their dists to the ui jobs instead of each job rebuilding them; plus row F1 of comment 6406837199 (bound the root ui jobs' cache saves the objectui way, F11's combined pnpm-store cache included), row F2 of the same comment, and F13 from #25940's body (derive and pin the rootlint-ui30 /build-e2e-ui45timeout-minutes); push/schedule keep the full battery (Q6-b); the gate rosters follow with--self-test0; Tier H (draft, os-zhuang + hotlong),skip-changesetWhy now: twenty ui jobs each rebuild the same seven packages (1.6–2.5 min apiece, mostly turbo cache misses on PRs); #25881 and #25882 cut the queue and PR shard counts, so this rebuild is now the largest fixed cost left per ui run
Container & model: M,
mode:thread(thread sessionsession_01XpG2CKzNjLujzcMmSxKCHy; 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: #25902 (#25880, open, Tier H) adds gate steps inside
lint-uiof the sameci.yml— ⛔ do not touch those steps; rebase over it when it lands. 4b 2d-3c (#25712, not yet opened) deletesui/.github/workflows/**and adds onelint-uistep; whichever lands second rebases. ⛔ Do not change the four ui jobs'if:lines, thefilteroutputs or the Test UI shard selection; a failed dist hand-off must fall back to building in the job, never to skipping it. Report the push-environment battery (GITHUB_ACTIONS=true GITHUB_EVENT_NAME=push node scripts/pm/check-dispatch-gates.mjs, 2182/0) before the PM flips readyobjectstack-fleet commentedon Oct 26, 2026
#25869 after-readings: the seven packages built once per run (#25963) · 2026-10-26T08:33Z ·
session_01XpG2CKzNjLujzcMmSxKCHy#25963 landed through the queue on os-zhuang's approval. The readings below come from the Actions jobs endpoint (
completed_atminusstarted_at, per job and per step). Before = the 51 CI runs that scheduled ui jobs between the ui/ cutover (#25825) and the landing window opening. After = the 19 completed CI runs since #25963 landed that ran Build UI Deps. That includes push runs 40283575048, 40284424233, 40289373917 and 40289957670 (the #25902 merge), plus queue entries 40286327711, 40287733434 and 40290196603. Two cancelled PR runs are left out.The seven-package build (the card's question)
Wall clock (Premise vs measured, point 1)
The ui jobs now start when Build UI Deps finishes:
The card's expected "1–2 min per ui lane" wall saving does not hold. The change saves runner-minutes and adds about a minute of wall clock per lane.
Per-job wall clock, whole job (n, median, max)
These populations are different PR mixes, so job medians compare loosely. The step readings above are the like-for-like comparison.
Lint UI with #25902's gates in the job (runs since its merge): n=4, at 259 s, 429 s, 433 s and 685 s (push 40289957670). The 685 s run exceeds the population the 30-minute ceiling was derived from (max 558 s). By objectui's rule (≥ 3× max and ≥ max + 15 min), 685 s gives 35. The 30 still leaves 2.6× headroom over the slowest run seen, but n=4 is too few to re-derive from. That re-derivation belongs to the #25880 seat (
ui/scripts/__tests__/turbo-cache-save-bound.test.tspins Lint UI at 30).Saves (rows F1/F11)
Every ui cache save is now a bounded, non-fatal
actions/cache/save(5 min). The turbo seed saves after the landing took 0–2 s (n=12). Build UI Deps did not save the pnpm store in this window, because every run hit its exact key. No save step ran into its bound.Premise vs measured, point 2
Option (b), a
pull_requestrun reading the remote cache, was not taken. Turbo reads with the same TURBO_TOKEN that writes, and Build Core's credential ruling (#21186) withholds it and the signing key from PR code. The PM ruled that the ruling stands. Queue andmainruns of Build UI Deps carry the remote-cache lines.Local evidence at the PR head (
cd0ae004)check:dual-build-cjs-loadswas first a PREREQUISITE NOT MET and passed after a fullpnpm build.--ranreports 0 unrun.main's known pre-install-import-graph row.Relay writes for this card: 2 (
pr_create, this comment). MCP calls: 0.