Repository navigation
tooling(ui-wiring): objectstack-side inert wiring for the ui/ workspace — workspace globs, root turbo tasks, path-filtered ui test/typecheck/lint/E2E jobs, spec change compiles the Console; pin gates retire at cutover (parent #25677, 3/6) #25697
Description
Filing gate ④: sub-issue 3/6 of the epic #25677 (pm:epic; epic PM session_01RSDL3SFtJaKzcymvCD8RsU). Part of #25677. ⛔ Not a claim.
Blocked-by: none for PR A — nothing in it needs a change from #25685, everything it adds is inert while ui/ is absent, and it is verified against a throwaway import (below). PR B is drafted here but merges only in the cutover window (sub-issue 5), right after the subtree PR.
Who does it, where it lands: the epic PM dispatches it (os-dev, objectstack checkout). Two PRs to objectstack-ai/objectstack main. Both touch .github/workflows/**, so both are Tier H: draft until CI is green, the maintainer approves and merges, the seat never enqueues them. Why two PRs: PR A can land weeks before cutover and is exercised on every PR without effect; PR B deletes the two-repo pin gates and is only correct from the moment ui/ exists, so it is drafted now and merged in the freeze window.
维护者速读
子卡 1 的 spike 证明,ui/ 接进来后 objectstack 这边要做的只有三类事:pnpm workspace 认得 ui/ 下的包、根 turbo.json 认得 objectui 的任务名、CI 给 ui 开按 ui/** 路径过滤的测试/类型检查/lint/Playwright 作业,并在 spec 改动的 PR 里直接编译 Console(这正是今天 Spec Shape Gate 每小时对着 clone 做 13 分钟的事,合并后同一次 CI 顺手做掉)。这些都能在 ui/ 还不存在时先落 main:目录不在,通配匹配不到任何包,新作业全部跳过。切换日再合第二个 PR:删 Spec Shape Gate、Console Pin Gate、prerelease-pin-watch 和 .objectui-sha 过滤。两个 PR 都碰 .github/workflows/**,按 Tier H 由维护者批准、人工合并。
Scope
PR A — inert wiring, lands before cutover
- Workspace.
pnpm-workspace.yamladdsui,ui/packages/*,ui/apps/*,ui/examples/*topackages:and the union of objectui'sonlyBuiltDependencies. Verified 2026-10-24: pnpm 10.28 accepts globs that match nothing —pnpm installandpnpm -r lsare unchanged. NOT moved here: objectui'spnpm.overrides(security floors forqs,shell-quote,tmp,uuid, the react 19.3.0 line) and the@radix-ui/react-focus-scope@1.1.16patch — an unusedpatchedDependenciesentry fails install and an override rewrites today's lockfile. Those travel with the subtree in sub-issue 5; the spike'sec74d9ecfa/4f3149d015onclaude/project-thread-dwhq6rare the recipe. - Root turbo.
turbo.jsonabsorbs the four task names objectui's packages use and the root lacks —type-check,lint,test:dist,test:watch— with the inputs/outputs/dependsOn objectui'sturbo.jsondeclares for them (read it atui/turbo.objectui.jsonon the spike branch; the spike parked it because turbo 2.11 rejects a nestedturbo.jsonwithoutextends, finding 7). ItsglobalDependencies(.objectstack-sha, the shape-gate stamp, the stamp cache) are pin plumbing and are not ported. A task defined for a script no objectstack package has is inert; the dev provesturbo run build --dry=jsononmainlists the same tasks before and after. - CI jobs for
ui/**. Inci.yml: auioutput on thefilterjob (ui/**), and jobsTest UI (n/N)(objectui's vitest projects partitioned by package, N chosen from measured timings the wayscripts/partition-test-shards.mjsdoes for core — objectui runs 16 shards today),Type Check UI,Lint UI(or inlint.yml, wherever the existing split puts it) andBuild & E2E UI(Console build + Playwright, objectuici.yml'sBuild & E2Ejob ported; Node heap per tooling(objectui-readiness): make the objectui tree merge-ready in its own repo before cutover — one react line, one zod range, uiRoot() helper, tsc heap, workspace-aware Console chunk tests, typecheck alias (parent #25677, 2/6) #25685 item 4). Every new job is guarded by BOTH the filter output ANDhashFiles('ui/package.json') != '', because the filter's "everything changed" fallback on push (|| 'true', THE FILTER CONTRACTfilterjob 一旦失败,Test Core / Build Core / Dogfood 会全部 skipped 而分支保护判为通过 —— 隐式 success() 今天已第三次咬人 #4928) would otherwise start them on a tree withoutui/. None joins the required set until cutover (the ruleset is the maintainer's, sub-issue 5);required-set-patrolandcheck:shard-attestationmust keep passing with the new jobs skipped. - A spec change compiles the Console.
Type Check UIalso runs when any of the seven packages objectui installs changes (packages/spec,client,core,formula,lint,sdui-parser,types), so the compile Spec Shape Gate does hourly against a clone of objectuimainhappens in the PR that moves the shape, naming theui/file. The dev reports the measured cold and turbo-warm minutes against today's ~13 min hourly gate. - Roster audit. A table over objectui's 28 workflows — "ported in PR A / already covered by an objectstack workflow / dropped", one line each — posted on this card. Correctness gates (
ci,lint,live-e2e,performance-budget,published-dist-gate,node-esm-load-gate,shadcn-check,lockfile-dedupe,lockfile-integrity,spec-range-floors) are decided and, where kept, ported in this card; governance workflows (changeset-*,governed-surface-guard,half-state-patrol,merge-queue-head-patrol,required-check-set-patrol,board-snapshot,labeler,line-citation-gate,hook-selftests,repo-gates,test-shard-timings-refresh,cross-repo-issue-closer,dependabot-auto-merge,docs-deploy,check-links,changelog) go to sub-issue 4 with the table as its input.
PR B — retire the two-repo pin gates, drafted now, merged in the cutover window after the subtree PR
- Delete
.github/workflows/spec-shape-gate.ymlwithscripts/ci/spec-shape-gate.mjsandscripts/ci/spec-shape-retirements.json; delete theconsole-pinjob (Console Pin Gate) and theconsoleentries of thefilterjob; delete.github/workflows/prerelease-pin-watch.yml; dropSpec Shape GatefromRELEASE_GATE_WORKFLOWSinscripts/ci/scheduled-full-run.mjsand from anyrelease.yml/cut-rc.ymlread of it. The scripts those jobs call (build-console.sh,check-console-sha.mjs,check-console-injection.mjs,console-spec-probes.mjs,assert-console-spec-injection.mjs) stay until sub-issue 4 removes them with the pin field and thepackages/consolebuild switch; PR B only stops the workflows from being the thing that proves the pin.
Verification (the dev's, before each PR leaves draft)
- PR A on
mainas it is: a CI run whose job list equals today's plus the new jobs skipped (not failed, not required);pnpm install --frozen-lockfileleavespnpm-lock.yamlbyte-identical;turbo run build --dry=jsonlists the same tasks. - PR A with
ui/present: a throwaway draft PR from a branch = PR A's head +git subtree add --prefix=uiof objectuimain(sha fromgit ls-remote, the tooling(monorepo): 在试验分支上把 objectui 并入ui/workspace(subtree add、单 lockfile、turbo 构建图),交冲突清单、必改脚本清单与各类 PR 的 CI 时长读数 — 不落 main(父单 1/6) #25678 recipe) + the lockfile recompute, titledDO NOT MERGE — verification run for #<this card>, never enqueued, closed once the run is read. It must show every new job running and green, and a counter-probe: one commit that breaks apackages/spec/src/uishape objectui reads turnsType Check UIred naming theui/file, then is reverted. Link the runs on this card. - PR B on the same throwaway branch: green with the pin gates gone and nothing else red.
Done when
- PR A merged on
main(maintainer, Tier H) with the two runs linked here and the roster table posted. - PR B open as draft, green on the throwaway branch, marked
Blocked-by: sub-issue 5in its body and handed to the cutover card. - Spec Shape Gate's hourly run is unchanged until PR B merges — this card never weakens a gate before its replacement has run green.
Size: L (PR A is the bulk: ~5 jobs ported with their caches and shard plumbing). Clause-②: no. Metadata-protocol: none.
风险
- CI minutes:
Build & E2E UIandType Check UIadd the Console build to spec-touching PRs; the spike measured Console 2 m 01 s warm, 7 m 31 s with 72 deps cold. If the warm number does not hold under turbo remote cache, the dev reports it here before PR A leaves draft and the PM decides between path-narrowing and a nightly tier. - Required set drift: a skipped job that a later PR accidentally lists as required blocks every PR until cutover;
required-set-patrolcovers the ruleset side, the dev adds the new job names to its expectations only as "optional until cutover".
Dedupe
search_issues 2026-10-24 17:30Z, objectstack 「ui workspace CI shards Playwright path filter objectui monorepo wiring」 7 hits: this epic's own #25677 / #25678 / #25685; closed #24306, #23720, #22429 (build-console and pin bumps, the mechanism this card retires); #17250 (closed decision on where pure-objectui cards live). No card wires ui/ into this repo's CI. New.
Activity
objectstack-fleet commentedon Oct 24, 2026
Claim: epic #25677 round 3
Session:
session_01RSDL3SFtJaKzcymvCD8RsUAccount:
os-teslaBranch:
claude/project-thread-dwhq6r-25697for PR A and PR B (objectstack-ai/objectstack; mode:thread — the thread's designated branchclaude/project-thread-dwhq6rcarries the #25678 spike import that this card's PRs must not contain, so a second branch is requested from the maintainer at 17:35Z; until it is granted the work stays in a local worktree offorigin/mainand nothing is pushed). The throwaway verification run usesclaude/project-thread-dwhq6r-25697-verify, closed after the run.Worktree:
objectstack-issue-25697(fresh fromorigin/main; the spike checkout is read, never built on)Domain:
domain:devxSeat:
epic:#25677File surface:
pnpm-workspace.yaml(packages globs, onlyBuiltDependencies only — no overrides, no patches),turbo.json(four task names),.github/workflows/ci.ymlandlint.yml(newuifilter output and ui jobs; PR B deletesconsole-pinandspec-shape-gate.yml,prerelease-pin-watch.yml),scripts/ci/scheduled-full-run.mjs(PR B: RELEASE_GATE_WORKFLOWS),scripts/ci/spec-shape-gate.mjs+scripts/ci/spec-shape-retirements.json(PR B: deleted), the workflow self-tests underscripts/__tests__/andscripts/ci/__tests__/that pin job rosters; noAGENTS.md, nodocs/adr/**, no.changeset/config.json, norelease.ymlContainer & model: L,
mode:subagent,model: opus(default;dispatch-gates --tier --repo objectstack-ai/objectstackis run by the dev on its own paths before the PR —.github/workflows/**is Tier H, so both PRs stay draft until the maintainer approves and merges; the seat never enqueues them),effort: highClause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
Serial constraints cleared: objectstack open PRs on 2026-10-24 17:30Z — no open PR of this epic touches
ci.yml,turbo.jsonorpnpm-workspace.yaml; other open PRs on.github/workflows/**are serialized by the Governed Surface Queue Guard at enqueue, and the dev re-reads the open set on those three files before PR A leaves draft and rebases on anything that merged first. PR B is held (Blocked-by: sub-issue 5) and lands in the cutover window after the subtree PR.Generated by Claude Code
objectstack-fleet commentedon Oct 24, 2026
Item 5 — objectui workflow roster audit
Input: the 28 files in
ui/.github/workflows/on the #25678 spike branch (objectuimainat0984c77e1).Dispositions: ported in PR A · covered by objectstack workflow X · dropped · kept, follow-up port (a correctness gate this card keeps but PR A does not carry; ported once the throwaway import run can exercise it) · → sub-issue 4 (governance, with this table as its input).
board-snapshot.ymlboard-snapshot.yml; decide whether one board archive covers both.changelog.ymlchangeset-guard.ymlchangeset-presence.ymlpr-automation.ymlCheck Changesetis the root counterpart.changeset-release.ymlrelease.ymlpublishes; one release lane after the merge.check-links.ymlcheck-links.yml(lychee) exists; widen it toui/or keep objectui's.ci.ymlType Check UI...[base]; also runs on the seven consumedpackages/*(item 4).ci.ymlTest UI (n/16)uiRoot(). Timings reporter and upload wait for the refresh workflow (row 28).ci.ymlBuild & E2E UIvite buildand Playwright chromium; Node heap 4 GB; also runs on the seven consumedpackages/*.ci.ymlci.ymlpnpm test:dist(turbotest:diston@object-ui/components); the only caller of thetest:disttask PR A defines.ci.ymlci.ymlcoverage-nightly.yml; decide push-lane vs nightly tier.ci.yml@object-ui/site)Build Docsbuildsapps/docsonly.cross-repo-issue-closer.ymldependabot-auto-merge.ymldocs-deploy.ymldocs-deploy.ymldeploysapps/docs; objectui's site is a separate Vercel project.governed-surface-guard.ymlgoverned-surface-guard.yml→ sub-issue 4GOVERNED_SURFACES) must decide whichui/**paths are governed.half-state-patrol.ymlhalf-state-patrol.yml→ sub-issue 4hook-selftests.ymllint.yml(hook self-tests step over.claude/hooks) → sub-issue 4ui/.claude/hooks(8 hooks) is not swept by it; merge or retire them.labeler.ymlpr-automation.yml(Auto Label) → sub-issue 4line-citation-gate.ymllint.ymlLint UI(in ci.yml, beside thefilterjob it needs)//#lint:rootbecame its own step; the cross-repo closer contract step → sub-issue 4.live-e2e.ymllockfile-dedupe.ymlpnpm-lock.yaml; objectstack has no dedupe gate (validate-deps.ymlchecks frozen install and OSV only).lockfile-integrity.ymlmerge-queue-head-patrol.ymlmerge-queue-triage.ymlis the counterpart.node-esm-load-gate.yml@object-ui/*ESM load scan; nothing in objectstack covers@object-ui/*.performance-budget.ymlBuild & E2E UIto avoid a second Console build.published-dist-gate.ymlrepo-gates.ymlLint UIthere.required-check-set-patrol.ymlrequired-set-patrol.yml→ sub-issue 4* UInames join the required set only at cutover (sub-issue 5).shadcn-check.ymlspec-range-floors.ymlworkspace:^the floor is the workspace version by construction (spike finding 1); sub-issue 2 item 6 makes the scripts acceptworkspace:, sub-issue 4 deletes them.test-shard-timings-refresh.ymlshard-timings-refresh.ymlfor core; when ported, restore Test UI's timings reporter and upload.Count: 28 workflows. PR A ports
lint.ymland the three named jobs ofci.yml. 10 correctness items are kept for a follow-up port (row 7 ×3, rows 17, 18, 19, 21, 22, 23, 26).spec-range-floors.ymlis dropped, andci.yml'sTestaggregate waits for the cutover required set. 18 governance workflows go to sub-issue 4 (rows 1–6, 8–15, 20, 24, 25, 28); 5 of them are already covered by an objectstack workflow (rows 11–14, 25).PR A status and PM rulings on the dev's open questions
PR A (inert wiring) is built and verified locally: 4 commits, 10 files, +931/−33 —
pnpm-workspace.yamlui globs, 4 root turbo tasks,ci.ymljobsType Check UI/Test UI (n/16)/Lint UI/Build & E2E UIgated on aui_treefilter output (skipped, not failed, whileui/is absent; none required), and 7 gate scripts that mirror the workspace globs or hold untilui/package.jsonexists. Lockfile byte-identical under--frozen-lockfile;turbo run build --dry=jsonsame 84 tasks; all 121 derived gate commands exit 0; actionlint exit 0. A throwaway import of the spike'sui/tree installs in 48 s with 45@object-ui/*members and the spec→ui type-check selection works (44 ui packages selected by a spec edit).The branch is not pushed yet: this thread's objectstack branch carries the sub-issue 1 spike subtree, so the PM asked the maintainer for a second branch name for this card. The draft PR opens as soon as that is granted;
.github/workflows/**makes it Tier H, so it waits for a human approval in any case.Rulings (PM, so the dev's report is closed):
ui/arrives.actions/cacheonly for now.Test UIruns onuichanges only (option A); spec changes reachType Check UIandBuild & E2E UI. Revisit after the first measured runs.skip-changeseton the PR (nothing published changes).Note for the cutover script: objectui
origin/mainfetched locally as a3c0da9 while the spike tree is 0984c77; the import must take the sha fromgit ls-remote, not a local checkout.objectstack-fleet commentedon Oct 24, 2026
PR A opened as a draft: #25710 (branch
claude/project-thread-dwhq6r-25697, head 597471c, +931/−33,skip-changeset). Tier H (.github/workflows/**): waits for one APPROVED review from GOVERNED_APPROVERS, then the dispatch seat lands it through the queue. Its body carries the 维护者速读 and the acceptance notes for the cutover card; the full roster table is the comment above.Next on this card: the throwaway
DO NOT MERGEverification branch (this head + the subtree import) to measure the four UI jobs withui/present and run the spec counter-probe; then PR B (retire the two-repo pin gates), drafted for the cutover window.objectstack-fleet commentedon Oct 24, 2026
Verification branch up: #25718 (
DO NOT MERGE, draft,needs-user-decision+skip-changeset, never enqueued; branchclaude/project-thread-dwhq6r-25697-verify= PR A head + objectuimain@cd70b7818das theui/subtree + the spike adaptations + PR A's7ca50a8a7b). Its body lists the 17 gates the import commit turns red on this tree (the cutover card's bill) and the counter-probe to push after the first run is read.PR A itself: #25710 was approved by os-zhuang and auto-merge armed; two workspace-glob gates CI caught (
check:dispatcher-error-vocabulary,check:duration-unit-keys) were fixed in7ca50a8a7b(comment 6391016137); it merges through the queue when green.New finding for the cutover bill, from the verify tree:
check:duration-unit-keyswalksui/**/srconceui/exists and reports 9 ms-described keys without a unit in the name, all inui/packages/types/src/zod(autoPlay, autoResponseDelay, timeout, delay, duration, delayDuration, openDelay, closeDelay, refreshInterval). Those are published prop names, so the answer is a declared exemption or a scope decision, not a rename — sub-issue 5 decides with the maintainer.objectstack-fleet commentedon Oct 25, 2026
Verification run 1 of #25718 read — summary with the measured causes and the owner of each red is on the PR (the comment titled "Run 1 read"). In one line: the four UI jobs ran, Lint UI is green cold in 12 min, and every other red traces to (1) objectui readers of
pnpm-workspace.yaml/turbo.json/pnpm-lock.yaml/ root overrides at the objectui root → new sub-issue 2b #25723 (dispatched); (2) the ui root's turbo-recursive scripts nesting a second turbo run inside rootturbo run build→ cutover adaptation (verify commit 1a76fa5 previews it, run 2 in flight); (3) objectstack-side inert follow-ups for PR A2 on this card: Test Core partitioner excludes members underui/;dispatch-gates.mjsrunGitbuffer; (4) the already-listed cutover bill (fixed group → 4a, lint-lane gates,QUICK_REFERENCE.md). Dom/unit failures not attributed to a reader are measured again on run 3.Cutover bill additions for the adaptation commit (sub-issue 5), carried here until that card is filed:
ui/package.json: dropbuild,build:all,lint,type-check,typecheck,test:dist,site:build(allturbo run …).ui/QUICK_REFERENCE.md"Current Release" block statesworkspace:^.ui/turbo.jsonparked asui/turbo.objectui.json(a nested turbo.json mustextendsthe root); readers → tooling(objectui-readiness 2): scripts, tests and e2e specs that read pnpm-workspace.yaml, turbo.json, pnpm-lock.yaml or root overrides at the objectui root resolve the workspace root upward (parent #25677, 2b/6) #25723.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
PR A (#25710) is on
mainas 769ac80 (merged 2026-10-25 00:58Z, approved by os-zhuang). Inert whileui/is absent:ui/*workspace glob, the four ui turbo task names, the ui CI jobs behindui_tree, the spec→Console typecheck edge, the roster table. Parent #25677 item 3 text updated (PR B still pending — cutover window).Next on this card, in order:
.objectstack-shae649c2d vs main, TS1360 in TranslationPreview on run 2).claude/project-thread-dwhq6r-25697restarted from main): Test Core partitioner excludes workspace members underui/(run 1: shards 2–6 enumerated@object-ui/*and failed under OS_SKIP_DTS);scripts/pm/dispatch-gates.mjsrunGitmaxBuffer (ENOBUFS on the imported tree); rootbuildtask excludes@object-ui/site(next build) or it gets its own job. Filed as a PR on this card once run 3 is read.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Verify run 3 read (#25718, head 1cade69, objectui#25723's patch on top) — pointer. Build & E2E UI is green for the first time (7:33); Type Check UI passes 15 ui gates and stops at
check:icon-record-names; Test UI's reader class is gone. Summary: #25718 (comment).New cutover-bill item — dependency resolution. The verify branch's lockfile was recomputed from ranges (not carried from objectui's lock), and the git-root
pnpm-workspace.yamloverrides (48) now governui/*. Against objectuimain's lockfile, 138 importer×dependency rows moved across 69 packages; the remaining Test UI reds (radix Select/Tooltip minors) and the lucide name drift come from this, and the root overridereact-router@<8.3.0 → ^8.3.0puts react-router 8.5.0 under objectui's react-router-dom 7.18. Sub-issue 5a filed: the import splices objectui's resolutions into the merged lockfile and scopes the overrides that would rewrite a line objectui owns.Resolution diff, objectui lock → merged lock (ui importers only)
vite@vitejs/plugin-reactlucide-reactvite-plugin-dtsvitest@types/nodepostcssreact-router-domautoprefixer@testing-library/react@testing-library/user-event@vitest/uichalkhappy-domreact-i18nextreact-map-gl@ai-sdk/react@changesets/cli@playwright/test@radix-ui/react-alert-dialog@radix-ui/react-aspect-ratio@radix-ui/react-avatar@radix-ui/react-checkbox@radix-ui/react-context-menu@radix-ui/react-dropdown-menu@radix-ui/react-hover-card@radix-ui/react-label@radix-ui/react-menubar@radix-ui/react-progress@radix-ui/react-radio-group@radix-ui/react-select@radix-ui/react-separator@radix-ui/react-slider@radix-ui/react-switch@radix-ui/react-toggle@radix-ui/react-toggle-group@radix-ui/react-tooltip@sentry/react@tanstack/react-virtual@types/vscode@vitest/coverage-v8aiaxe-corebetter-authconcurrentlyeslinteslint-plugin-react-refreshexpressexpress-rate-limitfs-extraglobalsi18nextinput-otpjs-yamlmaplibre-glmotionplaywrightreact-day-pickerreact-grid-layoutreact-hook-formreact-resizable-panelsshadcnstreamdowntsxturbotypedoc-plugin-markdowntypescript-eslintwait-onyamlStill open on this card: run 4 (d17ed5e, lucide names regenerated) for the Type Check UI tsc step and the full spec-drift list → sub-issue 2c (objectui catches up to objectstack main); then the counter-probe and closing #25718.
Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Claim: epic #25677 round 6 — PR A2 of this card (card threads; Tesla 2026-10-25 「你应该使用 pm-dispatch 技能派发」「并发可以到6」). Supersedes the epic PM's own
claude/project-thread-dwhq6r-25697branch for PR A2; PR B (pin-gate retirement, cutover window) and the verification branchclaude/project-thread-dwhq6r-25697-verify(#25718) stay with the epic PM.Session:
session_01RSDL3SFtJaKzcymvCD8RsUAccount:
os-teslaBranch:
claude/project-thread-i7mwht(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-25697Domain:
domain:devxSeat:
epic:#25677File surface (PR A2, inert while
ui/is absent):scripts/partition-test-shards.mjs(+ its tests), rootpackage.jsonbuildscript and/orturbo.jsonfilter,scripts/check-type-check-coverage.mjs,scripts/check-published-readme-exports.mjs(+ their self-tests); ⛔ nothing under.github/workflows/**(Tier H) — a fix that needs a workflow change is reported, not made. The dispatch-gatesmaxBufferitem is already in #25732.Container & model: M,
mode:thread(thread sessionsession_01Y9KdeUcccMQ3ReF85Xyf5o; order:/mnt/project-files/d1-merge/dispatch/3-25697-pr-a2-objectstack-inert-gates.mdin the project, FRAME.md applies),model: opus,effort: high(coordinator default)Clause-②: no
Metadata-protocol: none
Responsibility: n/a — not a defect card
Thread-read: none
PR body:
Part of #25697(this card stays open for PR B),Part of objectstack#25677; ⛔ noFixes.Serial constraints: none — PR A #25710 is on
main; #25732 (4b PR 1,scripts/pm/**) touches none of these files.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
os-dev-report
{ "issue": 25697, "status": "done", "branch": "claude/project-thread-i7mwht", "pr": "https://github.com/objectstack-ai/objectstack/pull/25738", "session": "session_01Y9KdeUcccMQ3ReF85Xyf5o", "premise_still_valid": true, "summary": "PR A2 (inert): the Test Core partitioner drops workspace members under ui/ by path (the ui root included); the root build excludes ./ui*/apps/site; check-type-check-coverage reads tsconfigs with TypeScript's JSONC parser (refusals kept); check-published-readme-exports scopes its population to members outside ui/. Byte-identical on main; on the verify head cfa1676afc the four reproductions move as the order asked, with the coverage gate now giving 489 ui-only findings instead of a crash (cutover decision, acceptance note 1).", "tests": "head 898990ec: partition-test-shards --self-test exit 0 (new battery 6 cases), check-type-check-coverage --self-test exit 0 (new battery 8), check-published-readme-exports --self-test exit 0 (new battery 5, with control); same three green on the verify tree with the diff applied. Inert: partitioner stdout+stderr byte-identical on 6 shards of main's turbo ls; root build dry-run 83 = 83 task ids; coverage and readme-exports output byte-identical base vs new on main. Effect (verify tree): 47 -> 0 ui shard items; coverage throw -> reads ui/tsconfig.json (exit 1, 489 findings all under ui/); readme-exports exit 3 -> 0 on the lane's built closure; dry-run 130 -> 129 tasks, only @object-ui/site#build removed. No ablation: scripts only.", "gates": "dispatch-gates --commands: 46 derived, all 46 exit 0 (record /mnt/project-files/d1-merge/out/3-25697-a2-gates-ran.txt); --ran reconcile: 46 run, 0 NOT-MEASURED (derived zero). check-governed-merges --branch HEAD: NOT governed, 344 lines. eslint on the three scripts exit 0. CI on #25738: in_progress at report time.", "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "1 relay stroke: pr_create (create + assignees + labels legs, run 40158788478); this report comment is the 2nd", "open_questions": [ { "question": "Coverage gate on the merged tree: 489 findings, all on ui/ members (47 lack a typecheck script because objectui spells it type-check). Which way at cutover?", "options": [ "A: ui packages gain typecheck scripts or ledger rows in the adaptation commit", "B: exclude members under ui/ by path from this gate too, as PR A2 did for the readme gate" ], "recommendation": "PM/maintainer call; A keeps the ratchet's coverage over ui/, B keeps cutover small" } ], "out_of_scope_findings": [ "class: measurement contradicting the order. objectui's check:readme-exports runs in its repo-gates.yml (governance roster, sub-issue 4), not in Type Check UI, so after cutover no gate judges ui/ README exports until that port. carrier: sub-issue 4 (#25712) or the cutover card. noted, not filed" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
ACCEPT PR A2 — dispatch seat. #25738 (head
898990ec, branchclaude/project-thread-i7mwht, +324/−20, 4 files) is accepted as PR A2 of this card. The card stays open: PR B (Spec Shape Gate / Console Pin Gate / prerelease-pin-watch retirement) lands in the cutover window, and the verification branch #25718 stays with the PM.Checked against the order (
/mnt/project-files/d1-merge/dispatch/3-25697-pr-a2-objectstack-inert-gates.md):uior under it), never by the@object-ui/scope; nothing under.github/workflows/**; the dispatch-gatesmaxBufferitem correctly left to tooling(pm): dispatch-gates git maxBuffer for the merged tree; register matchers proven on the nested ui/ rows (4b PR 1, inert) #25732.main, measured: partitioner stdout/stderr byte-identical on all 6 shards; root build dry-run the same 83 task ids and hashes;check-type-check-coverageandcheck-published-readme-exportsbyte-identical output. Effect on the verify treecfa1676afc+ diff:ui/items in Test Core 47 → 0 (max/mean 1.00x); coverage gate readsui/tsconfig.json(JSONC via TypeScript's own parser, refusals kept); README-exports gate exit 3 → 0 on the lane's built closure; dry-run drops exactly@object-ui/site#build.mainand on the verify tree; roster floors 14→15, 65→66, 26→27.--ran(0 NOT-MEASURED). eslint 0.ui/**-filtered UI lanes and opt-in jobs, as expected on a tree withoutui/). Test Core 1/6 took 9 min (run 5 on the verify branch took 29 min for the same shard carrying the ui root).check-governed-merges --pr objectstack-ai/objectstack#25738: NOT governed (0 of 4 paths hit the register), 344 changed lines ≤ 3000 — ordinary queue landing.Deviations, read and accepted:
--filter=!./ui*/apps/site(turbo 2.11.5 refuses!./ui/apps/siteand!@object-ui/siteon a tree withoutui/). Accepted; tightening to!./ui/apps/siteis on the cutover bill as optional.ui/(47 "notypecheckscript" because objectui spells ittype-check, the rest downstream of that). Accepted as out of this patch: a coverage-semantics decision, carried to child 5 (seat's proposed route: accepttype-checkas a second spelling for members underui/, then seed ledger rows for what remains; path exclusion only as the fallback).repo-gates.yml, not Type Check UI as the order said. The order was wrong; the correction goes to the 4b PR 2 bill (port README Export Check with its build prerequisite).@object-uientries vs 19 in run 4's lane: informational; the lane's reading comes from run 6.Bill notes:
/mnt/project-files/d1-merge/out/5-cutover-bill-notes.md.Landing: the seat flips the PR ready and arms auto-merge via the relay now. Follow-on: verify run 6 on #25718 after the objectui
mainrefresh (2c round 1 + 2d merged; 2e in flight) plus this patch, expecting Test Core 6/6 and the consumer-gates lane green, and the source-gates / debt-ledger lanes red with a verdict (deviation 2) until child 5.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Claim: PM loop round 2 (item 6, PR B — retire the two-repo pin gates; PR A #25710 is merged)
Session:
session_01H835wAyqCCeF7jiYq7XSxiAccount:
os-tesla(the seat's linked user; the card's assignee)Branch:
claude/project-thread-90y5m2Worktree:
objectstack-issue-25697Domain:
domain:devxSeat:
domain:devx#1File surface:
.github/workflows/spec-shape-gate.yml, .github/workflows/prerelease-pin-watch.yml, scripts/ci/spec-shape-gate.mjs, scripts/ci/spec-shape-retirements.json (deleted); .github/workflows/ci.yml (console-pin job + filter console entries); scripts/ci/scheduled-full-run.mjs (roster + its self-test cases); release.yml / cut-rc.yml reads of the gate; the ledgers, census gates and prose that name the deleted gates(stop on breach; explain in the report)Container & model:
M,mode:thread,model: opus (default judgment tier),effort: xhighClause-②: no
Metadata-protocol: none
Responsibility: n/a — epic step (#25752 step 5, PR 3 of 4 at the sitting)
Thread-read: none
Premise: holds — origin/main 52f3f51 carries all four files and the console-pin job; the console scripts and the pin field stay (#25712)
Serial constraints cleared: draft only, merged by the maintainer at the 2026-10-26 09:00Z sitting after the cutover PR and 4a #25745; never ready, never auto-merge; no
claude/project-thread-dwhq6r*branch is touchedResume-from: none
Dispatched by the epic seat (
session_01RSDL3SFtJaKzcymvCD8RsU) under the pm-dispatch frame; order:/mnt/project-files/d1-merge/dispatch/3B-25697-retire-pin-gates.md. Part of #25677.Generated by Claude Code
wip(docs): past tense for the retired pin gates in AGENTS.md, release…
objectstack-fleet commentedon Oct 25, 2026
Measurement: item 6 (PR B) census · 2026-10-25T16:10Z · branch
claude/project-thread-90y5m2, base52f3f518e1git grep -n -E 'spec-shape-gate|Spec Shape Gate|spec-shape-retirements|prerelease-pin-watch|Console Pin Gate|console-pin'over the tree at the base: 169 hits in 33 files. Every hit class and what PR B does with it:spec-shape-gate.yml(15),scripts/ci/spec-shape-gate.mjs(21),scripts/ci/spec-shape-retirements.json(1),prerelease-pin-watch.yml(6)ci.ymljob and filterci.yml(7)console-pinjob,consolefilter list and output deleted; the comments that pointed at them re-wordedscripts/ci/scheduled-full-run.mjs(19)Spec Shape Gaterow dropped fromRELEASE_GATE_WORKFLOWS(roster is nowCI+Lint & Type Check); its self-tests rewritten to the two-row roster with the same assertion shape; two dated diagnosis fixtures keptcheck-ci-filter-parity.mjs(5),check-expected-skips.mjs(5),dispatch-gates.self-test.mjs(20),dispatch-gates.mjs(7)consolesubject retired (battery floor 10 → 9); theConsole Pin Gateexpected-skip row removed and its recordings re-spelled; live-tree job-filter cases re-pointed atBuild Core; synthetic specimens kept; tense fixesscripts/check-prerelease-pin-watch.mjs(15),package.json(2)check:spec-shape-gateandcheck:prerelease-pinsaliases (deviation:check-self-test-wiredreds the orphan)AGENTS.md(2),docs/releases-maintenance.md(2)cut-rc.yml,docs-deploy.yml,lint.yml(2),release-coverage-patrol.yml,release.yml:1510,check-release-section-coverage.mjs(2),check-self-test-workflow-commands.mjs,check-vendor-version-stamps.mjs(2),check-required-contexts.mjsrelease.yml:1874/1917,cut-rc.yml:383,packages/console/README.md:54,check-console-injection.mjs(6)docs/audits/*(5),scripts/docs-audit/README.md,scripts/fixtures/merge-queue-triage/*.json(2),fleet-write/validate.mjsfixture,packages/spec/liveness/dashboard.json:146,pnpm-workspace.yaml:184, the #9533 tombstone incheck-required-contexts.mjsMeasurements that contradict the order:
GET /repos/objectstack-ai/objectstack/rules/branches/main(read 2026-10-25T15:50Z) requiresTypeScript Type Check,Test Core,Build Core,Lint & Repo Gates,Governed Surface Queue Guard; classic branch protection requiresTypeScript Type Check,Build Core,Test Core,Dogfood Regression Gate. No required context vanishes when PR B merges, and the sitting needs no ruleset step for it. (Console Pin Gateleft the registry with finding: required-context registry pins Build Docs and Console Pin Gate, absent from the maintainer's 2026-08-18 six-item required-set reading #9533 and appears in no reading of the required set;Spec Shape Gateis in neither reading today.)release.ymlorcut-rc.ymlstep readsSpec Shape Gatedirectly. Both reach it only throughscheduled-full-run.mjs --release-gate, so dropping the roster row is the whole change.prerelease-pin-watch.ymldoes not watch the objectui pin. It watches better-auth prerelease overrides inpnpm-workspace.yaml, and its watch list is already empty. Deleted as ordered.main. The order keepscheck-console-injection.mjs/console-spec-probes.mjsuntil 4a and deletesConsole Pin Gate, their only PR-time runner. Two live-tree cases of the dispatch-gates fast tier then red: the silent load-break paircheck:console-injection <- console-spec-probes.mjs, and thepull_request-only narrowing of the scheduled-only zero. That step is a member ofLint & Repo Gates. On a local merge ofmain+ 4a (4ac569dc00) + PR B the same fast tier passes 1917/1917, so the reds belong to the landing order (4a first), not to either PR. Neither case was weakened.package.json(both deletecheck:prerelease-pins) and one comment indispatch-gates.self-test.mjs. Resolve both by takingmain(4a); both conflicts are verified on the local merge above.release(ui-merge): one release lane for both scopes — @object-ui join…
ci(ui-merge): retire the two-repo pin gates — Spec Shape Gate, Consol…