Repository navigation
tooling(objectui-readiness): make the objectui tree merge-ready in its own repo before cutover (objectstack#25685) - #13472
Conversation
…to 19.3.0 (objectstack#25685 item 1) Every manifest that pins `react` / `react-dom` moves 19.2.8 -> 19.3.0 and every `@types/react` / `@types/react-dom` pin moves to 19.3.0, matching the root `pnpm.overrides`. objectstack's `@objectstack/client-react` requires react `^19.3.0`, and a second `@types/react` copy broke `@object-ui/plugin-view`'s declaration build in the merged `ui/` tree. The CLI scaffold (`REACT_RANGE` and the shared dev-dependency map) quotes the same pins, as its anchor test requires. Lockfile regenerated with `pnpm install --no-frozen-lockfile`; it also carries the single-zod-range resolution that item 2 declares in the manifests. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
…ge that lists it (objectstack#25685 item 2) `@object-ui/types`, `components`, `app-shell`, `test-support` and `plugin-timeline` declared three different zod ranges (`^4.4.3`, `^4.6.1`); in the merged `ui/` tree that resolved to two zod copies and the `z.ZodType` identity split between them. All five now declare `^4.6.5`, the range objectstack's own packages use, so the lockfile holds one zod 4.x for the workspace (commit 1's regenerated lockfile already carries that resolution). Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
… `.git` or `pnpm-workspace.yaml` (objectstack#25685 item 3) In the merged tree `ui/` has no `.git` and no `pnpm-workspace.yaml` of its own, so every test and script that located the repo root by walking up to one of those markers (or by `git rev-parse --show-toplevel`) would resolve the OBJECTSTACK root instead. `scripts/ui-root.mjs` exports `UI_ROOT` / `uiRoot()`, derived from the helper's own location and nothing else. Migrated: fifteen `repoRoot()` walkers, the sdui-parser census IIFE, four `pnpm-workspace.yaml` existence assertions, and four scripts that shelled out to `git rev-parse --show-toplevel`. `check-new-cross-file-line-citations.mjs` now diffs `--relative` and reads blobs as `rev:./path`, so it keeps working when the git toplevel is a parent of the ui root. Two instruments keep it that way: `scripts/check-ui-root-lookups.mjs` (`pnpm check:ui-root-lookups`, with `--self-test`) scans `scripts/`, `packages/` and `apps/` with the TypeScript AST for marker probes, `--show-toplevel` / `--git-common-dir` and `find-up`, against a ledger allowlist of the four CLI product predicates that legitimately probe the USER's cwd; and `check-test-path-roots.mjs` now classifies `uiRoot()` / `UI_ROOT` as the self root. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
…h-heap.mjs` (objectstack#25685 item 4) `@object-ui/app-shell` and `@object-ui/console` type-check against the whole objectstack tree once merged, and both OOM at Node's default old-space limit there. `scripts/with-heap.mjs CMD...` re-runs its arguments with `--max-old-space-size=4096` appended to NODE_OPTIONS (an old-space size the caller already set wins), propagates the child's exit code, and is what the two packages' `build` and `type-check` scripts now run `tsc` through — a cross-platform spelling instead of an inline `NODE_OPTIONS=...` prefix. Measured in this tree with `tsc --noEmit --extendedDiagnostics`: app-shell 2 234 110K, console 2 355 117K of heap. The turbo `build` inputs guard derives each package's build program from its script; it now understands the wrapper (recorded as part of the program AND looked through, so the wrapped `tsc` still contributes its tsconfig chain), and `turbo.json` lists `$TURBO_ROOT$/scripts/with-heap.mjs` as a `build` input. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
…workspace layout (objectstack#25685 item 5) `apps/console/vite.config.ts` recognised `@objectstack/*` modules for its vendor / spec / lazy-linter chunk rules only by their `node_modules` and pnpm-store path spellings. In the merged tree those packages are workspace siblings resolved from `<root>/packages/<name>/dist/...`, so every rule would have silently missed them. `scripts/vite-objectstack-workspace.ts` exports `frameworkPackagesDir(consoleDir)` (`../../../packages` from `ui/apps/console`) and `workspaceChunkTests(dir)`, which widens each of the three tests with an anchored, escaped `<dir>/` alternative (vendor excludes `lint/`, which stays lazy). The baseline spellings are kept, so the standalone layout is unchanged. Ported from spike 3efb112efb with the unit test it lacked: a standalone `node_modules/@objectstack/spec/...` id stays matched, `<root>/packages/spec/dist/x.mjs` is matched by spec and vendor, `<root>/packages/lint/...` is excluded from vendor and matched by lint, and a sibling `packages-other/` is not matched. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
…floor readers `workspace:` ranges (objectstack#25685 item 6) Two small pre-conditions for the merged tree. The root `typecheck` script is an alias of `type-check` (`turbo run type-check`), the spelling objectstack's fleet tooling invokes. And the three readers of `@objectstack/spec` RANGES — `scripts/check-spec-range-floors.mjs`, `scripts/objectstack-floor.mjs` and the `declaredSpecFloor-9012` test — understand the `workspace:` protocol: `workspace:*` / `^` / `~` / bare mean "the workspace package's own version", read from the installed `@objectstack/spec/package.json` (`workspaceSpecVersion`, `installedVersion`) and passed into `minVersionOf` / `effectiveFloor` / `planRanges` as `workspaceVersion`; `workspace:^18.1.0` reads its range tail. A `workspace:` range met without that version throws rather than silently passing, and the gate's self-tests cover both shapes. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…rivate regex (objectstack#25685 item 3) The `uiRoot()` test strips comments from `scripts/ui-root.mjs` before asserting what the helper spells and does not spell. It did so with its own `/\/\*[\s\S]*?\*\//` + `//`-to-end-of-line pair, which the `check-hand-rolled-comment-mask` gate rightly refuses: that is the naive-regex family the tree retired, and a `//` inside a string would open a phantom comment. The test reports neither a line nor an offset, so it now calls `stripComments` from `scripts/js-comment-mask.mjs`, the one answer to "is this span a comment". Verified locally: the gate test and `ui-root.test.ts` (26 tests) pass. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
… not a root wrapper script (objectstack#25685 item 4) `scripts/with-heap.mjs` was a file OUTSIDE the two packages whose build runs it, and this tree's gates chain from that fact to a governed surface: `turbo-build-inputs.test.ts` requires every out-of-package file a build program reads to be a `$TURBO_ROOT$` input of `build`, and `docs-build-trigger.test.ts` requires every such input to be in the docs job's pathspec in `ci.yml` -- a `.github/workflows/**` edit the maintainer must approve. Shard 15 went red on the second gate. A heap ceiling is not a build input: the spelling `packages/spec` in objectstack uses, `NODE_OPTIONS=--max-old-space-size=4096 tsc` inside the package script, needs no file, no turbo input and no workflow line, so app-shell and the console carry it that way. `build-program.ts` skips the leading `NAME=value` words of a command before classifying the tool, so the two wrapped builds are still tsc runs in the inputs sweep; the wrapper, its test and its turbo.json line are gone. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
…e monorepo packages dir exists (objectstack#25685 item 5) `vite-objectstack-spec-dist.test.ts` pins the `vendor-objectstack` test's literal as one of objectui#4854's four flagged surfaces, and shard 7 went red because the workspace alternative was prepended unconditionally: standalone it matched nothing, but the literal had moved. `frameworkPackagesDir()` now returns `null` when `<console>/../../../packages` is not a directory, and `workspaceChunkTests(null)` returns `BASELINE_CHUNK_TESTS`, the baseline literals byte for byte -- so standalone the config is unchanged and the pin holds, and under `ui/` the directory exists and the arm is added. The helper's own test pins the literal equality, a real monorepo-shaped temp tree, and that a FILE named `packages` is not the directory. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
…e cwd, narrowed to the objectui tree (objectstack#25685 item 3) The gate's self-test drives it against a scratch repository under `node_modules/`, so its subject is the repository at the cwd; rooting it on `uiRoot()` alone made `git merge-base` run in the objectui checkout against a scratch commit (shard 12: "no merge base"). `gateRoot()` reads the toplevel of the cwd's repository and narrows to `uiRoot()` only when the objectui tree lies inside it: standalone the two coincide, under the objectstack monorepo the narrowing is what `--relative` and `rev:./path` rest on, and in the scratch repository the toplevel is read. The one `--show-toplevel` this adds is on the `check-ui-root-lookups` allowlist with that reason. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
…s the module (objectstack#25685 item 3) `check-lint-rule-coverage` reported `scripts/ui-root.d.mts` as a file no ESLint config reaches and no ledger row declares (shard 13). The twin was never needed: `tsconfig.scripts.json` reads `.mjs` with `allowJs`, so the JSDoc on `ui-root.mjs` is its typing, exactly as for every other `.mjs` helper the script tests import. The test now pins the export surface and the twin's absence. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
…ave no allowJs — and ledger it for the lint census (objectstack#25685 item 3) 2195392 deleted the declaration twin because `tsconfig.scripts.json` reads `.mjs` with `allowJs`. The PACKAGE tsconfigs do not: `@object-ui/data-objectstack`'s `type-check` failed with TS7016 on `import { uiRoot } from '../../../scripts/ui-root.mjs'` in `readme-filter-operator-table.test.ts`, and every migrated package test imports the helper the same way. So the twin is back, with its pin test, and `check-lint-rule-coverage`'s predicate-2 ledger (`UNREACHED_GROUPS`, exact paths only) carries a row for it: two `export declare` lines no ESLint config reaches, declared rather than repaired because reaching a `.d.mts` means widening a rule-bearing `files` glob to `.mts`, the rule-strength decision objectui#8337 kept out of this gate. The gate's own test pins the unreached population as these two files. Clause-②: no Metadata-protocol: none Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
维护者速读改了什么 —— 这是 objectui 并入 objectstack 为什么改 —— 导入 风险与代价(含回滚) —— 超过 3000 行人工审核线的主因是 席位意见 —— 建议批准。无法拆到 3000 行以下:锁文件是整体文件,拆开 react/zod 两项只会产生两个各自超线的锁文件 diff。路径面未命中任何受管面( 你要做的(一个动作) —— 在本 PR 上留一条 APPROVED review(os-zhuang / hotlong 任一),之后由本席翻 ready、挂 auto-merge 走合并队列;或直接合并也可。 席位核对
ACCEPT for objectstack#25685 points here. |
Fixes objectstack-ai/objectstack#25685
Part of objectstack-ai/objectstack#25677 (sub-issue 2/6).
Clause-②: no
Metadata-protocol: none
One draft PR for the whole card, one commit per scope item in card order. Branch
claude/project-thread-dwhq6r, basemainat a3c0da9 (chore: release packages, #13289). Nothing under.github/,AGENTS.md,.changeset/config.jsonor any other governed surface is touched; the objectui tree is prepared in its own repo so theui/import (ruling D1 / A+) merges without a follow-up fix-up commit.What changed, per item
1. One react line (commit 8474f4d)
package.jsondevDependencies andpnpm.overrides, everypackages/*,apps/console,apps/site, the three examples):react/react-dom19.2.8 to 19.3.0,@types/react19.2.18 to 19.3.0,@types/react-dom19.2.4 to 19.3.0.packages/cli/src/utils/scaffold-dependencies.ts:REACT_RANGE = '19.3.0'and the@types/react*entries of the shared dev-dependency map, which the CLI anchor test compares to the root manifest.pnpm-lock.yamlregenerated withpnpm install --no-frozen-lockfile(1337 lines added / 1337 removed). It also carries item 2's single-zod resolution, because one install produced both..changeset/25685-one-react-line.md: patch for the 30 published packages whose manifests moved.Before:
grep -c '"react": "19.2.8"'over the workspace manifests = 33; after = 0, andpnpm ls react --depth 0across the workspace resolves onereact@19.3.0.2. One zod range (commit 1d6a038)
packages/types,components,app-shell,test-support,plugin-timeline:"zod": "^4.6.5"(was^4.4.3x3 and^4.6.1x2)..changeset/25685-one-zod-range.mdfor the four published packages.Before: three distinct declared ranges; after: one, and the lockfile holds a single
zod@4.6.7for the workspace (the unrelatedzod@3.25.76is a transitive dependency of a third-party tool and is unchanged).3.
uiRoot()instead of.git/pnpm-workspace.yamllookups (commit 5cc5354)scripts/ui-root.mjs(UI_ROOT,uiRoot(), derived from the helper's own location; node builtins only) and its declaration twinscripts/ui-root.d.mts: package tsconfigs have noallowJs, so without the twin every migrated package test's import is TS7016 (2195392 removed it, the Type Check job proved it needed, ae7fcc5 restored it).check-lint-rule-coveragereports a.d.mtsas a file no ESLint config reaches, so its predicate-2 ledger (UNREACHED_GROUPS, exact paths) carries a row for it, owned by this PR; the gate's own test pins the unreached population asscripts/ui-root.d.mts+vitest.config.mts.repoRoot()walkers in package tests (types x7, components, plugin-calendar x2, plugin-gantt, app-shell x2, data-objectstack, core), the sdui-parser census IIFE, fourexistsSync(join(root, 'pnpm-workspace.yaml'))sanity assertions (nowexpect(root).toBe(uiRoot())), and four scripts that shelled out togit rev-parse --show-toplevel(cross-file-line-citation-census.mjs,dollar-dialect-alias-census.mjs,check-new-cross-file-line-citations.mjs,check-cross-repo-closer-outcome.mjs).check-new-cross-file-line-citations.mjsnow diffs with--relativeand reads blobs asrev:./path, so it keeps working when the git toplevel is a parent of the ui root; its root isgateRoot()(7537206): the repository at the cwd via--show-toplevel— its self-test drives the gate against a scratch repository — narrowed touiRoot()when the objectui tree lies inside it.scripts/check-ui-root-lookups.mjs(pnpm check:ui-root-lookups;--list,--json,--self-testwith 13 cases): a TypeScript-AST scan ofscripts/,packages/,apps/for marker probes (existsSync/statSync/lstatSync/accessSyncon.gitorpnpm-workspace.yaml, directly, via a const binding or a template literal),--show-toplevel/--git-common-dirliterals, andfind-up. Allowlist is a ledger (a stale entry is red) with five entries:scripts/objectstack-pin.mjs(deleted at cutover),scripts/check-new-cross-file-line-citations.mjs(its subject is the repository at the cwd, above) and three CLI product predicates that probe the USER's cwd (app-generator.ts,workspace-vite.ts,app-generator.test.ts).scripts/check-test-path-roots.mjsclassifiesuiRoot()/UI_ROOTas the self root (two new self-test cases).Before: on
mainthe fifteen walkers and four shell-outs resolved the root through.git/pnpm-workspace.yaml/git rev-parse, andcheck-test-path-rootsreported 1264 self / 590 unclassified roots. After:check-ui-root-lookups: OK (7796 files scanned, 55 parsed, 6 probes all on the allowlist, 5 allowlist entries live);check-test-path-roots: OK, 1264 self / 579 unclassified. The card's crude grep (A4) re-derived to 55 unique files onmain(the card quoted 71); 20 package test files and 4 scripts were migrated, and the residue is comments,readFileSyncDATA reads of the workspace globs, fixture writes, two'.git'directory skip-list entries and the allowlisted CLI predicates — the gate, not the grep, is the instrument that fails when a new lookup lands.4. tsc heap for app-shell and console (commits 02eaff5, c464a4a)
packages/app-shell/package.jsonandapps/console/package.json: thetscofbuildandtype-checkruns asNODE_OPTIONS=--max-old-space-size=4096 tsc ...— the spelling objectstack'spackages/specuses for the same purpose.scripts/__tests__/helpers/build-program.ts:stripEnvAssignments()skips the leadingNAME=valuewords of a command before classifying the tool, so the two builds are still tsc runs in theturbo-build-inputssweep and contribute their tsconfig chain.scripts/with-heap.mjs(02eaff5) is a file outside the two packages, soturbo-build-inputs.test.tsrequires it as a$TURBO_ROOT$input ofbuild, anddocs-build-trigger.test.tsthen requires every such input in the docs job's pathspec inci.yml— a.github/workflows/**edit the maintainer must approve. Shard 15 went red on the second gate; c464a4a removes the wrapper, its test and its turbo.json line. A heap ceiling is not a build input.Measured (A3) with
tsc --noEmit --extendedDiagnosticsin this tree: app-shellMemory used: 2234110K(3915 files, 50.7 s), consoleMemory used: 2355117K(4122 files, 25.4 s). Both exceed what the default old-space limit left on the merged-tree runner in the spike measurement; 4096 MB has headroom.5. Vite chunk tests derived from the workspace layout (commit 5c76fe3)
scripts/vite-objectstack-workspace.ts:candidateFrameworkPackagesDir(consoleDir)(../../../packagesfromui/apps/console),frameworkPackagesDir(consoleDir)(that directory when it exists, elsenull) andworkspaceChunkTests(dir | null)returning{ vendor, spec, lint }regexes that keep the baselinenode_modules/ pnpm-store spellings and add an anchored, escapeddir/alternative (vendor excludeslint/, which must stay lazy). Withnull— standalone — it returnsBASELINE_CHUNK_TESTS, the baseline literals byte for byte (dde5e6d):vite-objectstack-spec-dist.test.tspins the vendor literal as one of objectui#4854's flagged surfaces, and an unconditional arm had moved it (shard 7).apps/console/vite.config.tsuses them forVENDOR_OBJECTSTACK_TEST,SPEC_MODULE_TESTand the lazy-linter assertion.scripts/__tests__/vite-objectstack-workspace.test.ts: standalone the three tests are the baseline literals; anode_modules/@objectstack/spec/...id is matched in both layouts;<monorepo>/packages/spec/dist/x.mjsis matched by spec and vendor;<monorepo>/packages/lint/...is excluded from vendor and matched by lint; a sibling directory, a FILE namedpackagesand objectui's ownui/packages/*are not matched.scripts/vite-objectstack-client-dist.tsjudged and left alone: its chunk test has nonode_modulesassumption, andpackageResolvesFromwalksnode_modules/name, which workspace links satisfy.6.
pnpm typecheckalias andworkspace:spec ranges (commit 11bc209)package.json:"typecheck": "turbo run type-check".scripts/check-spec-range-floors.mjs:WORKSPACE_PROTOCOL;minVersionOf(range, { workspaceVersion })readsworkspace:*/^/~/ bare as the workspace package's own version andworkspace:^18.1.0as its range tail;workspaceSpecVersion(root)reads the installed@objectstack/spec/package.json; aworkspace:range met without that version throws instead of passing.scripts/objectstack-floor.mjs:installedVersion,floorOfRange,planRanges(..., { workspaceVersionOf }).packages/core/src/utils/__tests__/normalize-list-view.declaredSpecFloor-9012.test.ts:floorOfreads aworkspace:range as the installed spec's own version (the oldworkspace:* is not a floorassertion replaced by that test).scripts/__tests__/check-spec-range-floors.test.tsandscripts/__tests__/objectstack-floor.test.ts.Other readers of
@objectstack/specranges that were NOT changed (they do not fail onworkspace:today):scripts/check-changeset-no-major.mjs(majorOfRange) andscripts/sync-quick-reference-release.mjs.Verification (local, this worktree)
Install:
pnpm install --no-frozen-lockfileagainst a stand-inOBJECTSTACK_ROOT(sibling objectstack checkout at 3efb112efb; pin manifests and sibling manifests have identical dependency names and exports, all 18.1.0, so.objectstack-pinand thefile:lockfile snapshots are unchanged). react / react-dom / @types 19.3.0 resolved.Under the shared verify lock (
--concurrency=2, 4096 MB heap):turbo run buildfor the dependency closure of console, cli and app-shell: 34 tasks, 34 successful.pnpm --filter @object-ui/app-shell type-check,pnpm --filter @object-ui/console build(vite build + sdui manifest + plugin),pnpm --filter @object-ui/cli build,type-check,test: all exit 0.declaredSpecFloor-9012, cliapp-generator,console-vite-alias-closure-4925,doc-version-claims): 24 passed, 325 tests.Unlocked (the dev's run, before the five red shards below):
pnpm type-check:scriptsexit 0;scripts/__tests__suites naming an edited script (ui-root,with-heap,check-ui-root-lookups,check-test-path-roots,vite-objectstack-workspace,objectstack-floor,check-spec-range-floors,react-peer-range-norm-3741,quick-reference-commands-4149,turbo-type-check-inputs,turbo-build-inputs,turbo-test-inputs,turbo-lint-inputs,scripts-type-check): all green. Gates exit 0:check:lockfile-integrity,check:lockfile-dedupe,check:phantom-deps,check:unused-deps,check:installed-pin-claims,check:test-path-roots,check:ui-root-lookups,check:entry-guard,check:pre-install-import-graph,check:control-bytes,type-check:coverage,check:new-line-citations,check-changeset-presence,check-changeset-no-major,check-changeset-fixed.eslintover all 41 changed source files: 0 errors (4 pre-existingno-explicit-anywarnings on lines this PR did not touch).pnpm check:spec-floorsafter the build: exit 1 with twofloor-too-lowfindings (@object-ui/authMEMBERSHIP_ROLE_EXTERNAL,@object-ui/typesnavItemVisibleDataNeedsDataSourceagainst the FETCHED@objectstack/spec@18.0.0-next.x). Identical verdict with the unmodified gate script frommainon the same dists, and both symbols are referenced bymain's source, so this is pre-existing and not introduced here; CI'sspec-range-floors.ymlruns the gate with--cross-check, which is the measurement that counts.NOT MEASURED locally (CI's): the full
turbo run test,lintandtype-checkacross the workspace,check:published-dist, performance budgets, the react 19.3.0 runtime behaviour beyond building and the touched test files.Epic PM follow-up (commits 6f3d9d5, c464a4a, dde5e6d, 7537206, 2195392, ae7fcc5)
The first CI run on 11bc209 had five red shards, all in
scripts/__tests__:check-hand-rolled-comment-mask(theuiRoot()test stripped comments with its own regex),vite-objectstack-spec-dist(vendor literal moved),check-new-cross-file-line-citations(gate rooted off its scratch repository),check-lint-rule-coverage(ui-root.d.mtsunreached),docs-build-trigger(new turbo input not in the governed docs pathspec). The second run's Type Check job then failed on@object-ui/data-objectstack(TS7016, the twin deleted by 2195392 was needed); ae7fcc5 restores it with a ledger row. Fixed as described in items 3–5; verified locally afterpnpm run setup(the pin built):vitest run scripts/__tests__194 files passed / 2 skipped,vite-objectstack-spec-dist.test.ts84 passed,check-lint-rule-coverage+ui-roottests green with the twin,pnpm type-check:scriptsexit 0,turbo run type-check --filter=@object-ui/data-objectstack --filter=@object-ui/types --filter=@object-ui/core6/6 tasks,check:ui-root-lookupsOK.Acceptance notes
pnpm installregenerates the whole file); commit 2 holds the manifest hunks and the changeset.NODE_OPTIONS=prefix rather than the card's cross-platform wrapper: a root wrapper is a build input, and a new build input must be in the governed docs pathspec (item 4). The flag changes the heap, not the program, so turbo's cache verdicts are unaffected.pnpm-workspace.yamlglobs inscripts/objectstack-pin.mjs,release-github-releases.mjsand the workspace-reading tests;'.git'in two directory skip lists) is deliberate: those are not root lookups. Thepnpm-workspace.yamlDATA readers will need a path onceui/has no workspace file of its own; that belongs to the carrier sub-issue, and is listed in the report.--write-manifestswas not passed.Generated by Claude Code