Skip to content

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

Closed

Description

@objectstack-fleet

Filing gate: ③ a maintainer-directed task — the maintainer, after this seat's CI assessment in this session, verbatim: 「CI 优化按照你的建议创建任务」 — carrying ① a measured cost with a named fix site: each CI and Lint run rebuilds the workspace in several jobs that share nothing (the three Type Check jobs, the Test Core shards' closures, the dogfood shards, Temporal, Build Core), 3.5–5.8 minutes per job, about 25–30 job-minutes per CI+Lint pair, while the turbo remote cache #21186 wired is read by ci.yml's Build Core only. 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 surfaces are the required contexts TypeScript Type Check, Test Core, Dogfood Regression Gate and Temporal Conformance.
Reader: triage first-touch → domain:devx (CI wiring; #21186 was routed domain:spec — triage decides); the owning seat dispatches it.
Dedupe: page-looped REST listings, closed included (union 1,266 as on the sibling cards) grepped for build once|share.*dist|remote cache|turbo.*(cache|remote)|duplicate.*build|rebuild → 5 hits: #21186 (closed 2026-10-05: wire the Vercel turbo remote cache — team object-stack — into ci.yml; trusted events write, PRs read, signed), #21193 (closed: build hashes omit five root inputs the builds read), #11264 and #19086 (closed: two cache-served-dist pitfalls, kept below as pins), #19541 (unrelated). None extends the cache beyond Build Core.

What is measured

  • lint.yml passes no TURBO_TOKEN / TURBO_TEAM / TURBO_REMOTE_CACHE_SIGNATURE_KEY (grep: 0 lines), so its three builds cannot hit the remote cache; ci.yml passes them only in the Build Core job (the block at about :2185-2219, "Turbo remote cache (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)").
  • Jobs API, step timestamps, pull_request runs 37567293616 (CI) and 37567293525 (Lint), same commit:
    • Type Check · workspace: build 3.5 min, then typecheck 6.2; Type Check · consumer gates: build 3.5; Type Check · debt ledger: build 4.5.
    • Build Core: build packages 6.2 min.
    • Dogfood shards 2/3, 1/3, 3/3: build dogfood deps 5.4 / 5.2 / 3.8 min; Temporal: build driver-sql deps 1.7 and more.
    • Nothing is passed between jobs as an artifact; every heavy job repeats checkout + setup-pnpm + pnpm install --frozen-lockfile (install itself is cheap, 0.07–0.18 min).
  • Per CI+Lint pair that is roughly 25–30 job-minutes of repeated build; the queue re-runs the same set per entry (about 235 job-minutes per queue build).
  • Setup-side caches today: pnpm store via actions/cache keyed on the lockfile; turbo LOCAL cache via actions/cache keyed per job + shard + ref + sha (a new entry per run; restore-keys fall back to main); the remote cache only in Build Core.

Done when


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    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. Scope: extend #21186's turbo remote cache, under #21186's own rules, to the jobs that rebuild the workspace

    Triage seat (objectstack-wide, seat post #6015) · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-07T13:14Z. ⛔ Not a claim, ⛔ not a dispatch.

    Triage: lands in .github/workflows/lint.yml (the three Type Check jobs, which pass no TURBO_* today: grep -cE "TURBO_TOKEN|TURBO_TEAM" prints 0) and .github/workflows/ci.yml (the Test Core, dogfood and Temporal build steps; the remote-cache block exists only in Build Core, about :2206–:2219) ⇒ domain:devx; rationale: CI wiring.

  2. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 7
    Session: session_01VF48aw8RPG6wzDnMgp6rtw
    Account: os-justin (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-22077-turbo-remote-cache-jobs (new, cut from origin/main 3d9188502e)
    Worktree: objectstack-issue-22077
    Domain: domain:devx
    Seat: domain:devx#2
    File surface: .github/workflows/lint.yml and .github/workflows/ci.yml only, as triage scoped it (6038738054).

  3. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
     "issue": 22077,
     "status": "done",
     "branch": "claude/issue-22077-turbo-remote-cache-jobs",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/22086",
     "session": "session_01VF48aw8RPG6wzDnMgp6rtw",
     "premise_still_valid": true,
     "summary": "WIRED (11 steps, each given Build Core's four env lines byte-identical: TURBO_CACHE (local:rw,remote:rw on merge_group and on push/workflow_dispatch to refs/heads/main, else local:rw,remote:r), TURBO_TOKEN (only when TURBO_REMOTE_CACHE_SIGNATURE_KEY is non-empty), TURBO_TEAM (vars), TURBO_REMOTE_CACHE_SIGNATURE_KEY (secret); step level only, no job-level TURBO_*): lint.yml Type Check · workspace `Build workspace packages`; Type Check · debt ledger `Build workspace packages` + `Build the ledgered packages' dependencies`; Type Check · consumer gates `Build workspace packages` + `Build the nested packages the consumer gates resolve through`; ci.yml dogfood shards `Build the dogfood package's dependency closure`; Temporal Conformance `Build driver-sql and its dependencies`, `Build the non-SQL temporal backends`, `Build metadata-protocol and its dependencies`, `Build runtime and its dependencies`; Test Core shards: NEW guarded step `Build this shard's dependency closure` (turbo run build --filter=PKG^... per shard item; empty FILTERS exits before turbo). Zone-2 premise 4 was half-false for Test Core: its existing build step (`Build the sliced package's dependency closure`) runs zero iterations since #21487 and the closure was built inside `Run this shard's tests` (merge_group 37623284168, Test Core 3/6: Cached 1 cached, 72 total, Time 11m43.373s), whose run must stay off the remote, so the closure moved into a new build step that carries the block and the test step replays it. Build Core's #21186 comment now states the extended scope and a PINS paragraph every carrier points back to. ROUTE: remote cache (not the dist upload-artifact fallback) because nothing in it failed: every carrier plan is a subset of Build Core's plan with identical task hashes and globalCacheInputs (dry-run on 3d9188502e, turbo 2.11.5: workspace 70/70, nested 77/77, dogfood 66/66, Temporal 8/18/14/31 all, Test Core shards 60/62/63/62/32/62 all), the PR run printed `Remote caching enabled` with no signature error, and Zone-2 premise 3 holds unchanged (#21186's expression: fork PR gets no secrets, TURBO_TOKEN evaluates to empty, turbo reports Remote caching disabled). BEFORE/AFTER (step seconds, jobs API): baseline main push at base 3d9188502e CI 37627942232 / Lint 37627942309 -> this PR pull_request CI 37635720375 / Lint 37635720510: TC workspace build 297 -> 1; debt build 335 -> 1, ledgered 31 -> 1; consumers build 330 -> 1, nested 30 -> 1; dogfood 1/3,2/3,3/3 200,336,201 -> 1,2,1; Temporal driver-sql/non-SQL/metadata-protocol/runtime 1,35,0,79 -> 3,3,1,3; Build Core 6 -> 7 (unchanged wiring); Test Core new step 1/6 1 s, 2-6/6 0 s (no packages on those shards for this PR); the 1/6 test step read 127 s here against 1181 s on main, but the affected sets differ, so that pair is not a before/after. ⚠ That main-vs-PR delta is mostly the local actions/cache seed (this PR restored the exact-tree seed the base push saved). The ATTRIBUTABLE reading is a same-base PR control, Lint 37632788013 (PR #22080, no remote, same typecheck seed): debt `Build the ledgered packages' dependencies` control `Remote caching disabled` / `Cached: 66 cached, 71 total` / `Time: 29.447s` vs this PR `Remote caching enabled` / `Tasks: 71 successful, 71 total` / `Cached: 71 cached, 71 total` / `Time: 527ms >>> FULL TURBO`; consumers nested build control `Cached: 66 cached, 71 total` / `Time: 29.819s` vs this PR `Cached: 71 cached, 71 total` / `Time: 558ms >>> FULL TURBO`. The 5 tasks the control executed (embedder-openai, studio, knowledge-ragflow, service-cluster-redis, organizations #build; hashes 9842d0cdd5169661, cc07959070308ace, 5a7a3cca239dd8c9, f463e9af7a1446c5, 6466cb05555f16f7) equal my local dry-run hashes at 3d9188502e and lie outside the workspace-build plan the typecheck seed is saved from, so on this PR the REMOTE served them. Other after lines read: Temporal runtime `Remote caching enabled` / `Cached: 30 cached, 30 total` / `Time: 3.04s >>> FULL TURBO`; metadata-protocol `Cached: 13 cached, 13 total` / 223ms FULL TURBO; debt first build `Cached: 67 cached, 67 total` / 766ms FULL TURBO; Test Core 1/6 new step `Cached: 6 cached, 6 total` / 546ms FULL TURBO, and its test step `Remote caching disabled` / `Cached: 6 cached, 7 total` / `Time: 2m6.47s` (the test run reads no remote, by design, and replays the closure). MERGE-QUEUE reading: pending, the seat takes it from this PR's own queue entry at landing (baseline merge_group CI 37623284168 / Lint 37623284080: TC builds 323/340/342 s, dogfood 322/340/287 s, Temporal 95/47/1/91 s). PINS: #19086 checked by a YAML audit of the final tree (12 TURBO_TOKEN carriers incl. Build Core, all byte-identical env, all `turbo run build`/`pnpm build` only, 0 job-level TURBO_*), every carrier dry-run plan 100% #build tasks, 0 workflow invocations of turbo gen:* (gen:schema and gen:skill-refs are cacheable turbo tasks), 0 gen:/--fix/--write steps in the wired jobs, and the typecheck step's ^build closure is inside the wired build plan (66/66, 0 extra) so it replays locally off the remote. #21193 checked by re-running its probe on 3d9188502e (append one line, re-derive the 72-task Build Core plan, restore from HEAD, blob-hash proof, trap restore): the 17 declared root inputs move 72/72, 71/72 or 6/72 exactly as #21193 recorded; controls root tsup.config.ts 72/72, scripts/check-turbo-task-graph.mjs 0, ci.yml 0, lint.yml 0 (this diff moves no build hash); and a static import-closure audit of every root script a build command or tsup config names (plus spec's generators, 450 files, 10 root scripts) found every root file inside the declared $TURBO_ROOT$ inputs. Both pins are written into Build Core's comment; no gate added, turbo.json and scripts untouched.",
     "tests": "LOCAL GATES at cbb948b926 (final head): `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` derived 52 commands; each run with its exit code written to disk first; all 52 exit 0. `dispatch-gates --ran` with `cmd :: exit N` rows: `52 derived famil(ies) accounted for — 52 run, 0 NOT-MEASURED (a DERIVED zero — all 52 recorded an exit code and none of them is 3)`. Verdict excerpts: check:stall-guard-budget `OK (39 workflow file(s), 65 job(s), 734 step(s), 11 guard-wrapped step(s); every effective cap clears its job budget by at least one stall window)` and the new step judged `window 10m · cap 20m · budget 45m · slack 25m`; check:workflow-step-name-quoting OK (742 step names); check:required-contexts green; check:pnpm-filter-targets `155/209 --filter occurrence(s) ... resolve`; check-ci-filter-parity, check-self-test-workflow-commands, check-step-collectors, check:pm-expected-skips exit 0; check:pm-dispatch-gates `dispatch-gates self-test: 1976 cases pass` (battery 1091.4s). Build-dependent five after a locked build (os-verify-lock `VERDICT command-exit 0`, 72 tasks, 13m04s held): check:dts-closure `170/170 declared declaration file(s) present across 72 package(s)`, check:sourcemap-no-sources-content `540 map(s), none embed source text`, check:lean-entry-closure `Admitted set held exactly (15 packages)`, check:dual-build-cjs-loads exit 0, check:type-check-debt `OK — 1 ledger entr(ies) re-measured ... none above its recorded number`. PROBES: dry-run hash identity (above), Test Core plan equality per shard (test plan build tasks == new-step plan, identical hashes, 0 extra; only cli#build on 1/6 stays in the test step because cli#test dependsOn build), #21193 root-input probe (above; git diff HEAD empty after, blob hashes verified per file). Empty-filter behaviour measured: `turbo run build --filter=@objectstack/spec^...` -> `No tasks were executed`, exit 0. YAML carrier audit: carriers=12 bad=0. CI on cbb948b926 at report time: CI run 37635720375 success; Lint run 37635720510 in_progress (31 checks success, 4 skipped, 1 in_progress: Lint & Repo Gates; TypeScript Type Check success). No ablation: no test or gate was added.",
     "mcp_calls": "10 — mcp__github__get_job_logs x10, read-only (job ids 112798774184, 112841509356 x2, 112841509140, 112841291243, 112831153225, 112841291174, 112831153344, 112841509669, 112841290802). gh/curl job-log downloads are refused by the egress policy (403 CONNECT to productionresultssa15.blob.core.windows.net and results-receiver.actions.githubusercontent.com), and the MCP tool returns only each log's last 5000 lines. No MCP write tool.",
     "api_writes": "3 — each a POST /repos/objectstack-ai/objectstack/dispatches through the scripts/pm fleet-write relay (objectstack-fleet[bot]): (1) pr_create #22086 draft (relay run 37635655819, read-back 8954 bytes identical); (2) label-write.mjs: labels_add skip-changeset + assign os-justin on #22086 (relay run 37635776942, read-back MATCHES; ci/cd and size/m were already there from the labeler); (3) this os-dev-report comment via post-stamped.mjs. Plus 2 git pushes (empty-branch probe, then cbb948b926), which are not REST writes.",
     "open_questions": [],
     "out_of_scope_findings": [
      "carrier: 承接者:无 · noted, not filed — `Dogfood Verify CLI` and `Console Pin Gate` also run turbo builds but are not named by the card, so they stay unwired; recorded in the PR's Acceptance notes"
     ],
     "gates": "52/52 exit 0 at cbb948b926 (dispatch-gates --ran: 52 derived, 52 run, 0 NOT-MEASURED, derived zero). CI: CI 37635720375 success, Lint 37635720510 in_progress at report time.",
     "line_budget": "n/a — no skills/** or line-ratcheted ledger touched; diff +167/-4 over 2 files (171 changed lines, under the 5000 human-merge threshold).",
     "deviations": [
      "Test Core: instead of only adding env lines to the existing (idle) slice-build step, a new guarded step `Build this shard's dependency closure` was added before it, because the closure was built inside the test step's turbo run, which must not read the remote. Within the ruled file surface; no job, required context or gate changed.",
      "PR body: the ruling asks for the after-readings in the PR body, but the os-dev definition writes the body once at creation and never PATCHes it. The PR's own run only exists after creation, so the after table and turbo lines are in this report. Suggested body amendment for the seat: append the after numbers, the same-base control (Lint 37632788013 vs 37635720510) and the turbo lines from `summary` under the body's `## Measurement (before / after)`, replacing the sentence that says they are posted in the os-dev-report.",
      "Measurement: turbo summary lines are NOT MEASURED for dogfood 1-3/3, the workspace lane's build step, and Temporal's driver-sql and non-SQL steps. Reason: those lines fall outside the last 5000 lines that MCP get_job_logs returns, and the full-log blob is denied by the egress policy. Step seconds for all of them come from the jobs API.",
      "check:type-check-debt was run with NODE_OPTIONS=--max-old-space-size=6144, the gate's pinned CI heap ceiling (its stale arm refuses otherwise), not 4096.",
      "check:pm-dispatch-gates: the first run was cut by my wrapper's 900 s timeout (exit 124, read as NOT MEASURED, not as red); it was re-run detached to completion: exit 0, battery 1091.4 s.",
      "The commit carries the model-free trailer pair from AGENTS.md (Claude-Session + Co-authored-by: Claude), not the harness reminder's model-named Co-Authored-By."
     ],
     "files_changed": [
      ".github/workflows/ci.yml (+122 -4)",
      ".github/workflows/lint.yml (+45 -0)"
     ],
     "dedupe_words": [
      "turbo remote cache",
      "TURBO_TOKEN lint.yml",
      "Test Core closure build",
      "remote:r PR read"
     ]
    }

    Generated by Claude Code

  4. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    ACCEPT — PR #22086 · domain:devx#2 · 2026-10-07T14:48Z

    Seat review of PR #22086 against GitHub, at head cbb948b926 on base 3d9188502e. Report: 6040381091. Claim: 6039143160.

    Checklist conclusions

    Deviations, all accepted:

    • The after-readings were in the report, not the PR body, because the dev writes the body once. The seat appended them to the PR body's ## Measurement section (relay run 37639459042, read back byte-identical).
    • Turbo's lines for the dogfood, workspace, driver-sql and non-SQL steps are NOT MEASURED. The log read path returns only the last 5000 lines. Their step seconds come from the jobs API.
    • mcp_calls: 10 read-only get_job_logs; no write tool.

    Acceptance notes: Dogfood Verify CLI and Console Pin Gate also run turbo builds. The card does not name them, so they stay unwired. Recorded, not filed: no measured cost is attached.

    Landing: pr_ready + automerge_enable through the relay now. The merge-queue reading, the before/after from this PR's own merge_group run, is owed in the landing record.

  5. objectstack-fleet commented on Oct 7, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — PR #22086 → b04a5295f7 · domain:devx#2 · 2026-10-07T15:49Z

    • Merged through the merge queue at 2026-10-07T15:30:16Z. The squash commit b04a5295f7 is on main; its parent is 3d9188502e.
    • Verified on main by blob identity:
      • .github/workflows/ci.yml = 0d2576cbf2;
      • .github/workflows/lint.yml = deb5d9ea8e;
      • both equal to the PR head cbb948b926.
    • The card closed completed on Fixes #22077. pm:dispatched is removed in this act.

    The merge-queue reading the ACCEPT left owed (build-step seconds, jobs API). Before: the queue entry for the same base tree (CI 37623284168 / Lint 37623284080). After: this PR's own queue entry (CI 37640052871 / Lint 37640052789).

    step before after
    Type Check · workspace Build workspace packages 323 s 1 s
    Type Check · debt ledger: build, then ledgered build 340 s, then 32 s 2 s, then 0 s
    Type Check · consumer gates: build, then nested build 342 s, then 31 s 2 s, then 1 s
    dogfood 1/3, 2/3, 3/3 closure build 322, 340, 287 s 1, 1, 1 s
    Temporal: driver-sql, non-SQL, metadata-protocol, runtime 95, 47, 1, 91 s 3, 2, 1, 3 s
    Build Core Build packages (excluding docs) 193 s 6 s
    Test Core new Build this shard's dependency closure, shards 1–6 — 1, 0, 0, 0, 0, 0 s

    How to read it: this queue entry's tree carries no build-hash change (the diff is workflow-only), so every build task was already in the remote, written by the main push at 3d9188502e. That makes this the best case. The steady-state figure is the next queue entry whose diff does move hashes.

  6. added a commit that references this issue on Oct 9, 2026
    b04a529
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:devxpriority:p2Medium: important, M3tooling

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions