Skip to content

tooling(ui-wiring): four objectstack gates read the merged tree right once ui/ exists, inert today (#25697 PR A2) - #25738

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-i7mwht
Oct 25, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/project-thread-i7mwht

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Part of #25697 (PR A2; the card stays open for PR B, the pin-gate retirement in the cutover window).
Part of objectstack#25677.

Clause-②: no
Metadata-protocol: none

What this is

The second inert objectstack-side patch of the ui/ CI wiring (PR A was #25710). On today's tree, with no ui/ directory, every changed script and the root build give byte-identical results (measured below). The change only matters once objectui's tree sits under ui/. On the verification PR #25718 (runs 1–5) four gates stayed red in the merged layout because of objectstack's own tooling. This PR repairs those four. Every exclusion is by path (a workspace member whose directory is ui or under it), never by the @object-ui/ scope. The ui root package is named object-ui-monorepo, so a scope filter would have missed it.

# Gate Red on the merged tree Change
1 Test Core partitioner, scripts/partition-test-shards.mjs turbo ls lists 47 ui/ members (46 @object-ui/* plus the ui root at path ui), and every shard received some. Shard 1 got the ui root alone (18783 s estimated, max/mean 2.17x). Under OS_SKIP_DTS that means TS7016, and run 4 spent 38 min running the ui root's whole-suite test. planRun() drops items whose path is under ui/ before weighing. This is the one path main() runs. The drop happens only when such items exist, and only then does it print one stderr line (ui/ tree: N member(s) not partitioned here -- Test UI runs them). Test UI keeps its own matrix.
2 Root build (package.json) turbo run build --filter=!@objectstack/docs includes @object-ui/site#build (next build), which objectui's own root build excluded. Adds --filter=!./ui*/apps/site. Turbo's path form, with a glob. Why it is spelled this way is under Acceptance notes.
3 scripts/check-type-check-coverage.mjs (Type Check · source gates, and the debt ledger lane through --re-measure) JSON.parse throws on ui/tsconfig.json, which is JSONC with block comments. tsc accepts it. Three more ui configs (ui/apps/console/tsconfig.json, ui/apps/console/tsconfig.node.json, ui/packages/runner/tsconfig.json) have the same shape. JSONC reader, not the exclusion fallback. A new parseTsconfigText() uses TypeScript's own parseConfigFileTextToJson and replaces all three tsconfig reads in the file (readTsconfig, tsconfigChainFacts, measureTestDebt). The reason is that what tsc compiles is what this gate claims to describe, and the fix also protects objectstack's own future tsconfigs. The refusals are kept. A syntax error, a merge-conflict marker, a non-object root and an empty or comment-only document are still refused (readTsconfig still throws, so the exit-code pin still sees it).
4 scripts/check-published-readme-exports.mjs (Type Check · consumer gates) Exit 3 (PREREQUISITE NOT MET). The @object-ui/* built type entries are not in the closure this lane builds, so no objectstack README was judged. run() drops members under ui/, and the documents they publish, from the population (outsideUiTree()). The scan now covers the members outside ui/. Objectui judges its own README claims with ui/scripts/check-readme-exports.mjs (see Acceptance notes for where that runs today).

Rulings followed: path, not scope. Nothing under .github/workflows/**. The dispatch-gates maxBuffer item is not redone (#25732).

Verification record

Measured on base origin/main f3fea0a with the fix commit 0263a19. The head 898990e then merges origin/main 4cc17db. Those 4 commits touch none of the four files, and the derived command list is identical after the merge. The scoped re-check on the head was the three touched self-tests plus pnpm check:type-check-coverage, check-ci-filter-parity and check:turbo-task-graph, all exit 0. Verification tree: #25718 head cfa1676afc with this diff applied (git diff f3fea0a..HEAD | git apply), after pnpm install --frozen-lockfile. Exit codes were captured before any pipe.

Inert on main (no ui/):

  • Partitioner. turbo ls --output=json on the full list, then --shard N/6 --exclude @objectstack/dogfood for N = 1..6, base script against new script. stdout and stderr are byte-identical on all six shards (exit 0/0; 12/13/14/14/21/11 items).
  • Root build. turbo run build --filter=!@objectstack/docs --dry=json before, and pnpm build --dry=json after. Both give the same 83 task ids, and the task hashes are the same too, compared with the filter passed by hand. With !./ui/apps/site or !@object-ui/site instead, turbo exits 1 on this tree (see notes).
  • node scripts/check-type-check-coverage.mjs, base against new: exit 0/0, byte-identical output.
  • node scripts/check-published-readme-exports.mjs on a built closure, base against new: exit 0/0, byte-identical output. Both report 105 documents, 84 members and 225/225 own-scope specifiers.

Effect on the verification tree (cfa1676afc + this diff):

Reproduction Before After
partitioner, 6 shards 47 ui/ items placed (shard 1 = object-ui-monorepo) 0 ui/ items. All 83 non-ui members placed exactly once. Max/mean 1.00x, and the CLI is sliced x3 as on main.
node scripts/check-type-check-coverage.mjs exit 1, uncaught Error: ui/tsconfig.json is not parseable reads ui/tsconfig.json. Exit 1 with 489 findings, all of them on ui/ members (see notes).
node scripts/check-published-readme-exports.mjs (objectstack closure built: turbo run build --filter='./packages/*' --filter='./packages/*/*', the lane's step) exit 3, 33 @object-ui/* entries unbuilt exit 0, a verdict. 105 documents, 84 members, 225/225 own-scope specifiers, 366 symbols checked.
turbo run build dry-run of the root filter 130 tasks incl. @object-ui/site#build 129 tasks. The only one removed is @object-ui/site#build.

Self-tests with the ui/ case (each one green on main and on the verification tree):

  • node scripts/partition-test-shards.mjs --self-test, exit 0. New battery "the ui/ tree is Test UI's, not Test Core's" (6 cases). It runs planRun() on a merged document with the ui root at path ui, an @object-ui member, and a member given an absolute path. None reaches a bin. The bins equal the split of the same document without them. A package at packages/ui is kept, and an entry with no path is kept so that weighItems() refuses it. The roster floor goes from 14 to 15.
  • node scripts/check-type-check-coverage.mjs --self-test, exit 0. New battery "JSONC tsconfig reader" (8 cases). Four shapes tsc accepts are read: a block comment between keys (objectui's root config), trailing commas, a whole-line comment, and a // inside a string. Four shapes stay refused: a truncated file, a merge-conflict marker, a non-object root, and a comment-only file. The roster floor goes from 65 to 66.
  • node scripts/check-published-readme-exports.mjs --self-test, exit 0. New battery "THE ui/ TREE IS OUT OF THIS POPULATION, BY PATH" (5 cases). It runs the production run() on a scratch workspace. An unbuilt member under ui/ gives exit 0 and is not named in the output. The control puts the same unbuilt member outside ui/, which still gives exit 3 and names it. The roster floor goes from 26 to 27.

Derived gates. node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derives 46 commands. All 46 exit 0 on the head, including check:type-check-coverage, check:type-check-debt, check:published-readme-exports, check:pm-dispatch-gates (fast tier), check:parse-guard, check:entry-guard, check:ci-filter-parity and check:turbo-task-graph. Reconciled with --ran (each line command :: exit N): 46 derived, 46 run, 0 NOT-MEASURED (a DERIVED zero). pnpm exec eslint --no-inline-config on the three scripts: exit 0.

node scripts/pm/check-governed-merges.mjs --branch HEAD: NOT governed, 344 changed lines.

No changeset: the root package is private and scripts/** ships in no package's files[]. The PR carries skip-changeset.

Acceptance notes (for the cutover card)

  1. The coverage gate is still red on the merged tree, now with findings instead of a crash. With the JSONC reader it reads every ui config and judges the 47 ui members: 489 findings, 0 of them outside ui/. They break down as 47 "no typecheck script and no ledger entry" (objectui spells the script type-check), 392 @ts-expect-error pins in files no typecheck program compiles (a consequence of the first class), 40 hidden test layers and 10 unread source directories. So Type Check · source gates and Type Check · debt ledger go from exit 1 by an uncaught throw to exit 1 with a verdict. Turning them green is a coverage-semantics decision for the cutover. One option is to give ui packages the typecheck spelling or ledger rows. The other is the path exclusion this PR did not take. Either is a follow-up for the cutover card, not part of this patch.
  2. The order says objectui's README gate runs in the Type Check UI job. Measured, it does not. pnpm check:readme-exports is in objectui's repo-gates.yml (README Export Check), which the roster routes to sub-issue 4. In the merged tree, ui/ README export claims are checked by neither gate until that workflow is ported, or until Type Check UI gains the step.
  3. Why the root build filter is a glob. On a tree without ui/, turbo 2.11.5 exits 1 on --filter=!./ui/apps/site ("Directory … specified in filter does not exist"), on !./ui/apps/[s]ite, and on !@object-ui/site ("No package found with name"). !./ui*/apps/site is accepted because turbo walks the glob from the repo root. Measured: it removes exactly @object-ui/site#build on the verification tree and nothing on main. Once ui/ exists the spelling can be tightened to !./ui/apps/site. That is optional.
  4. The ui root's own test script (objectui's whole-suite vitest run) is untouched here. Its drop stays on the cutover adaptation bill. After this PR, Test Core never schedules it.
  5. The root build dry-run on the verification tree still lists object-ui-monorepo#build with command NONEXISTENT, because the adaptation commit already dropped the script. Turbo skips it. Nothing to do.
  6. The readme gate refused 33 unbuilt @object-ui entries locally against 19 in run 4's lane. The lane builds part of the ui closure through its dependency edges. Both refuse without this diff. With it, the local run exits 0. The lane's own reading comes from this PR's CI and from the next verification run.

Generated by Claude Code

…/ is imported

With objectui's tree under ui/, four objectstack-side tools stay red for
reasons of their own, measured on the verification branch. Each change gives
byte-identical results on a tree with no ui/ directory.

- partition-test-shards: members whose path is ui or under it are dropped
  from the Test Core document (Test UI runs them), by path rather than by
  scope so the ui root package is caught too.
- root build: excludes the docs site under ui/apps/site with a path glob
  turbo accepts while ui/ does not exist.
- check-type-check-coverage: tsconfig files are read with TypeScript's own
  JSONC parser (block comments, trailing commas), refusals kept.
- check-published-readme-exports: the ui/ tree's members and documents are
  out of this gate's population, by path.

Claude-Session: https://claude.ai/code/session_01Y9KdeUcccMQ3ReF85Xyf5o
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Dispatch seat record. ACCEPTed as PR A2 on card #25697 (card stays open for PR B in the cutover window). check-governed-merges --pr objectstack-ai/objectstack#25738 on the final file list: NOT governed (0 of 4 paths in the register; 7 surfaces govern objectstack), 344 changed lines (+324/−20) under the 3000-line human-merge threshold. CI: 50/50 check runs completed on head 898990ec, none failed (the skipped ones are the ui/**-filtered UI lanes and opt-in jobs). Flipping ready and arming auto-merge (ordinary queue landing). No reviewer requested; this lands on the dispatch seat's verdict.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 25, 2026 03:50
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 25, 2026 03:50
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 25, 2026
Merged via the queue into main with commit c61f75d Oct 25, 2026
51 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/project-thread-i7mwht branch October 25, 2026 04:27
os-tesla pushed a commit that referenced this pull request Oct 25, 2026
…1, WIP)

main moved .objectui-sha (#25735) and the root build script (#25738); the pin stays
deleted and the build keeps main's site exclusion.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149BHSXfCdQywGaLdpRAtWe
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants