Repository navigation
Commit 769ac80
tooling(ui-wiring): inert workspace, turbo and CI wiring for the ui/ tree (objectstack#25697 PR A) (#25710)
Part of #25697 (PR A of two; PR B, which retires the two-repo pin gates,
is drafted later and merges in the cutover window). Part of #25677.
## What
The objectstack side of importing objectui under `ui/`, landed
**inert**: until `ui/package.json` exists, nothing in this PR changes
what pnpm installs, what turbo builds, or what CI runs.
1. **Workspace.** `pnpm-workspace.yaml` adds `ui`, `ui/packages/*`,
`ui/apps/*`, `ui/examples/*`. objectui declares no
`onlyBuiltDependencies`, so the union with ours is our list unchanged.
objectui's overrides and its `@radix-ui/react-focus-scope` patch arrive
with the import, not here.
2. **Root turbo.** `turbo.json` adds `type-check`, `lint`, `test:dist`,
`test:watch` with objectui's inputs, outputs, dependsOn and cache
settings. Its repo-root inputs are re-rooted under `$TURBO_ROOT$/ui/`.
Two things are not carried over:
- the `//#lint:root` and `//#type-check:e2e` dependsOn edges. Turbo
refuses a whole run over a package-named dependsOn whose package does
not exist yet, so those two programs are steps in the ui jobs instead.
- its `globalDependencies` (pin plumbing).
3. **CI jobs** in `ci.yml`, ported from objectui's `ci.yml` and
`lint.yml`:
- `Type Check UI`
- `Test UI (n/16)`
- `Lint UI`
- `Build & E2E UI`
The `filter` job gains three outputs: `ui` (`ui/**` plus the root files
the jobs build from), `ui_consumers` (the seven packages objectui
installs: spec, client, core, formula, lint, sdui-parser, types) and
`ui_tree` (whether `ui/package.json` exists, set by a step with no
`if:`). Every job's `if:` follows THE FILTER CONTRACT: `!cancelled() &&
needs.filter.outputs.ui_tree != 'false' && PATH_OUTPUTS != 'false'`.
With `ui/` absent, every job is **skipped** on every event. None of them
is a required context or an aggregator member.
4. **A spec change compiles the Console.** `Type Check UI` and `Build &
E2E UI` also run on `ui_consumers`. On pull_request and merge_group,
Type Check UI uses turbo `--filter=...[base]`, so a spec change selects
every ui package that depends on spec.
5. **Roster audit** of objectui's 28 workflows: see the table below.
### Gates that had to learn about a tree that has not arrived yet
Several repo gates treat "config describes something absent" as a
defect. That reading is correct except for a tree that is about to be
imported. Each gate below now declares the ui roots, and each hold is
narrow:
- `check-turbo-task-graph`: the generic keys `type-check`, `lint` and
`test:dist` have no holder until the import.
`GENERIC_TASKS_AWAITING_UI_IMPORT` holds them only while
`ui/package.json` is absent. A held key that turbo.json does not declare
is itself a finding. 7 new self-test cases.
- `check-cross-package-test-inputs`: `ui` is a `$TURBO_ROOT$` segment
that git does not track yet. `TOP_LEVEL_DIRECTORIES_AWAITING_IMPORT`
excuses it only while it is untracked. Once tracked, it owes a
recognised or pending entry.
- `check-published-files`, `check-test-source-alias`,
`check-undeclared-dep-imports`, `check-llms-txt`: each holds a hand copy
of the workspace globs, and each now declares the four ui roots.
`check-undeclared-dep-imports` also learned the bare `DIR` workspace
entry; before, it made the whole sweep fatal. 2 new cases.
- `check-expected-skips`: the four `* UI` names are declared as
by-design skips.
### Why objectui commands are spelled `pnpm --dir ui run ALIAS`
This repo's workflow gates (`check-self-test-wired`, the dispatch-gates
derivation and others) key `scripts/NAME` and `pnpm ALIAS` against
**this** repo's root, and none of them reads `working-directory`. Under
`working-directory: ui`, objectui's `scripts/check-entry-guard.mjs` was
credited to objectstack's file of the same name.
`scripts/check-lint-coverage.mjs`, which only objectui has, read as a
missing script.
### Test UI shard count
N = 16, chosen the way `scripts/partition-test-shards.mjs` chooses Test
Core's N: max/mean ≤ 1.3, from ui/scripts/test-shard-timings.json (4979
files, 325.7 summed minutes).
- By package, `@object-ui/app-shell` alone is 104.2 minutes, so the
bound admits at most 4 legs.
- By file, objectui's own LPT sequencer gives max/mean = 1.000 at any N,
so the job timeout sets N. 16 legs carry 20.4 summed minutes each.
The suite must run with cwd = `ui/`, because the dataset keys are
relative to the vitest root.
## Verification (local, on `issue-25697` at 597471c)
| Check | Command | Result |
|---|---|---|
| Lockfile byte-identical | `pnpm install --frozen-lockfile
--prefer-offline && git diff --exit-code pnpm-lock.yaml` | exit 0 / exit
0 (also with `--lockfile-only`) |
| Workspace unchanged | `pnpm -r ls --depth -1` with the base workspace
file vs the new one | identical (84 members + root) |
| Same build tasks | `turbo run build --dry=json`, before vs after | 84
= 84 taskIds. Hashes were identical with the turbo/workspace commit
alone. At head, 78 hashes move only because
`packages/spec/scripts/check-llms-txt.ts` is an input of
`@objectstack/spec#build`. |
| New tasks on today's tree | `turbo run type-check / lint / test:dist /
test:watch --dry=json` | before: exit 1 "Could not find task"; after:
exit 0. No root script and no CI step invokes them while `ui/` is
absent. |
| Workflow syntax | `actionlint 1.7.7 -shellcheck=
.github/workflows/ci.yml` (shellcheck not installed) | exit 0, before
and after |
| Derived gate families | `node scripts/pm/dispatch-gates.mjs --repo
objectstack-ai/objectstack --commands`, run in full, plus `pnpm
check:pm-dispatch-gates` | 121 commands, all exit 0. `--ran`
reconciliation: 118 derived, 118 run, 0 NOT-MEASURED, 0 UNRUN (all with
recorded exit codes). |
| Ledger ratchet | `pnpm check:type-check-debt` (under
`scripts/pm/os-verify-lock.sh`) | VERDICT command-exit 0 |
| Lint on changed scripts | `eslint --no-inline-config` on the 7 changed
scripts | exit 0 |
**Throwaway import (local, never pushed, deleted afterwards).** Built
from this branch plus the #25678 spike's adapted `ui/` tree, overrides
and patch, then a lockfile recompute. Results:
- `pnpm install`: 48 s.
- `pnpm -r ls --depth -1` lists 45 `@object-ui/*` packages plus
`object-ui-monorepo`.
- `turbo run type-check --filter='./ui/packages/types' --dry=json`
resolves `@objectstack/spec#build → @object-ui/types#type-check`.
- The full-scope filters select 46 ui type-check tasks. They select no
`@objectstack/*` type-check and not the `ui` root (which would recurse).
- A probe edit in `packages/spec/src` selects 44 ui packages under the
affected filter.
- `pnpm --dir ui run type-check:coverage`, `lint:coverage`,
`check:phantom-deps` and `check:entry-guard --self-test` all exit 0.
**Not verified here, owed by the CI runs on #25697** (a `DO NOT MERGE`
branch = this head + the subtree import):
- every new job running green with `ui/` present;
- the spec counter-probe turning `Type Check UI` red on a `ui/` file;
- cold and turbo-warm minutes for Type Check UI and Build & E2E UI
against today's ~13 min hourly Spec Shape Gate;
- the live required-set sweep (`check-required-contexts
--verify-required-set`), which cannot run from a dev seat. The new names
are not in `REQUIRED_CONTEXTS`.
## Acceptance notes: what the import commit will turn red (measured on
the throwaway tree)
None of these is reachable while `ui/` is absent. Each needs a decision
in the cutover PR (sub-issue 5) or in sub-issue 2:
- `check-turbo-task-graph` and `check-workspace-manifest-cycles`
self-tests: their `DECLARED_WATCH_HINTS` do not cover
`ui/**/package.json`. They cannot declare it today, because both also
red on a pattern that covers zero manifests.
- `check-published-files` self-test: `EXPORTS_CENSUS_FLOOR` (50) must
rise. The live publishable count goes 73 → 112.
- `check-undeclared-dep-imports`: 9 findings. `@object-ui/console`
imports `@objectstack/spec` and `@objectstack/client` but declares them
only as devDependencies.
- `check-type-check-coverage`: it cannot parse `ui/tsconfig.json`, which
is JSONC.
- `check-cross-package-test-inputs` self-test: the tracked `ui/` segment
must be recognised or pending, as designed.
- Not measured, but likely: the root `pnpm build` (`turbo run build`)
would include `object-ui-monorepo#build`, which is itself `turbo run
build`, and the root `pnpm lint` (`eslint .`) would sweep `ui/`.
## Roster audit (item 5)
| objectui workflow | Disposition |
|---|---|
| `ci.yml`: Type Check · Test (shard n/16) · Build & E2E | **ported in
PR A** → Type Check UI · Test UI (n/16) · Build & E2E UI |
| `ci.yml`: Test (dist pins) · coverage lane · Build Docs | kept,
follow-up port |
| `ci.yml`: Test (aggregate) | dropped until the cutover required set |
| `ci.yml`: Changeset Fixed Group Check | → sub-issue 4 |
| `lint.yml` | **ported in PR A** → Lint UI (closer-contract step →
sub-issue 4) |
| `live-e2e`, `lockfile-dedupe`, `lockfile-integrity`,
`node-esm-load-gate`, `performance-budget`, `published-dist-gate`,
`shadcn-check` | kept, follow-up port |
| `spec-range-floors` | dropped (`workspace:^` makes the floor the
workspace version) |
| `governed-surface-guard`, `half-state-patrol`, `hook-selftests`,
`labeler`, `required-check-set-patrol` | covered by an objectstack
workflow → sub-issue 4 |
| `board-snapshot`, `changelog`, `changeset-guard`,
`changeset-presence`, `changeset-release`, `check-links`,
`cross-repo-issue-closer`, `dependabot-auto-merge`, `docs-deploy`,
`line-citation-gate`, `merge-queue-head-patrol`, `repo-gates`,
`test-shard-timings-refresh` | → sub-issue 4 |
The full table, one line per workflow with notes, goes on #25697 as a
comment (the seat posts it).
## 维护者速读
**改了什么** —— objectstack 这一侧为导入 objectui(`ui/` 子目录)预先铺线,全部**惰性**:在
`ui/package.json` 出现之前,pnpm 装什么、turbo 建什么、CI 跑什么,一个字节都不变。具体是 workspace
四条 `ui` 通配、根 turbo
四个任务名(`type-check`/`lint`/`test:dist`/`test:watch`)、`ci.yml` 四个新
job(Type Check UI / Test UI 16 片 / Lint UI / Build & E2E UI,都挂在"`ui/`
树存在"这一个开关上,不存在就 skipped,且都不是必查项),以及 7 个仓内门禁学会这四个还不存在的根目录。附 objectui 28 个
workflow 的去向表。
**为什么改** —— 让后面那个 2.59 M 行的导入提交只做一件事:`git subtree add`。接线先行、并且先在今天的树上过一轮
CI,导入那天就不用边导入边改 CI。spec 一改就编译 Console(Type Check UI 对 `ui_consumers`
也触发)是把"objectui 被 spec 改坏"从发版后发现提前到 PR 上发现。
**风险与代价(含回滚)** —— 对现有流水线零影响的证据:锁文件逐字节不变(`--frozen-lockfile` 过)、`turbo
run build --dry=json` 前后同为 84 个任务、121 条派生门禁全部 exit 0、actionlint 过。代价是
`ci.yml` 多了 624 行当前全部 skipped 的 job;导入后每个碰 `ui/` 的 PR 多跑 16 个测试 runner(与
objectui 今天一样)。回滚 = revert 一个 squash 提交,无发布、无数据副作用。未在本地量到的只有导入后 Type
Check UI / Build & E2E UI 的冷热分钟数,靠下一步的 DO NOT MERGE 验证分支量。
**席位意见** —— 建议批准。这是子单 3 的 PR A;PR B(退役两仓 pin 门禁)单独起草、只在切换窗口合。
**你要做的(一个动作)** —— 在本 PR 上留一条 APPROVED review;之后由派发席翻 ready、挂 auto-merge
走合并队列。
## Landing
Tier H: `.github/workflows/**`. Draft until an APPROVED review from
`GOVERNED_APPROVERS` is on record; then the dispatch seat lands it
through the merge queue (maintainer ruling C). No seat flips it ready
before that.
No changeset: the diff touches workflows, root config, `scripts/**` and
`packages/spec/scripts/**` (not in spec's `files[]`), so nothing
published changes.
Changed lines: 964 (931 additions, 33 deletions), under the human-merge
threshold.
Clause-②: no
Metadata-protocol: none
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01RSDL3SFtJaKzcymvCD8RsU
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent f6ba134 commit 769ac80
12 files changed
Lines changed: 1019 additions & 35 deletions
File tree
- .github/workflows
- packages/spec/scripts
- scripts
- pm
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
313 | 313 | | |
314 | 314 | | |
315 | 315 | | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
316 | 324 | | |
317 | 325 | | |
318 | 326 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
227 | 227 | | |
228 | 228 | | |
229 | 229 | | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
230 | 234 | | |
231 | 235 | | |
232 | 236 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
13 | 26 | | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
14 | 30 | | |
15 | 31 | | |
16 | 32 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
426 | 426 | | |
427 | 427 | | |
428 | 428 | | |
429 | | - | |
| 429 | + | |
430 | 430 | | |
431 | 431 | | |
432 | 432 | | |
| |||
1435 | 1435 | | |
1436 | 1436 | | |
1437 | 1437 | | |
| 1438 | + | |
| 1439 | + | |
| 1440 | + | |
| 1441 | + | |
| 1442 | + | |
| 1443 | + | |
| 1444 | + | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
1438 | 1454 | | |
1439 | 1455 | | |
1440 | 1456 | | |
| |||
4353 | 4369 | | |
4354 | 4370 | | |
4355 | 4371 | | |
4356 | | - | |
| 4372 | + | |
| 4373 | + | |
| 4374 | + | |
| 4375 | + | |
| 4376 | + | |
| 4377 | + | |
| 4378 | + | |
| 4379 | + | |
| 4380 | + | |
| 4381 | + | |
| 4382 | + | |
| 4383 | + | |
| 4384 | + | |
| 4385 | + | |
| 4386 | + | |
| 4387 | + | |
| 4388 | + | |
| 4389 | + | |
| 4390 | + | |
| 4391 | + | |
| 4392 | + | |
4357 | 4393 | | |
4358 | 4394 | | |
4359 | 4395 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
288 | 288 | | |
289 | 289 | | |
290 | 290 | | |
291 | | - | |
| 291 | + | |
| 292 | + | |
292 | 293 | | |
293 | 294 | | |
294 | 295 | | |
| |||
493 | 494 | | |
494 | 495 | | |
495 | 496 | | |
496 | | - | |
| 497 | + | |
497 | 498 | | |
498 | 499 | | |
| 500 | + | |
499 | 501 | | |
500 | 502 | | |
501 | 503 | | |
| 504 | + | |
| 505 | + | |
| 506 | + | |
| 507 | + | |
| 508 | + | |
| 509 | + | |
| 510 | + | |
| 511 | + | |
| 512 | + | |
| 513 | + | |
| 514 | + | |
| 515 | + | |
| 516 | + | |
| 517 | + | |
| 518 | + | |
| 519 | + | |
| 520 | + | |
| 521 | + | |
| 522 | + | |
| 523 | + | |
| 524 | + | |
| 525 | + | |
| 526 | + | |
| 527 | + | |
| 528 | + | |
| 529 | + | |
| 530 | + | |
| 531 | + | |
| 532 | + | |
| 533 | + | |
| 534 | + | |
| 535 | + | |
| 536 | + | |
502 | 537 | | |
503 | 538 | | |
504 | 539 | | |
| |||
6145 | 6180 | | |
6146 | 6181 | | |
6147 | 6182 | | |
| 6183 | + | |
6148 | 6184 | | |
6149 | 6185 | | |
| 6186 | + | |
| 6187 | + | |
| 6188 | + | |
| 6189 | + | |
| 6190 | + | |
| 6191 | + | |
| 6192 | + | |
| 6193 | + | |
| 6194 | + | |
| 6195 | + | |
| 6196 | + | |
| 6197 | + | |
| 6198 | + | |
| 6199 | + | |
| 6200 | + | |
| 6201 | + | |
| 6202 | + | |
| 6203 | + | |
| 6204 | + | |
| 6205 | + | |
| 6206 | + | |
| 6207 | + | |
| 6208 | + | |
| 6209 | + | |
| 6210 | + | |
| 6211 | + | |
| 6212 | + | |
| 6213 | + | |
| 6214 | + | |
| 6215 | + | |
| 6216 | + | |
| 6217 | + | |
| 6218 | + | |
| 6219 | + | |
| 6220 | + | |
| 6221 | + | |
| 6222 | + | |
| 6223 | + | |
| 6224 | + | |
| 6225 | + | |
| 6226 | + | |
6150 | 6227 | | |
6151 | 6228 | | |
6152 | 6229 | | |
| |||
6516 | 6593 | | |
6517 | 6594 | | |
6518 | 6595 | | |
| 6596 | + | |
6519 | 6597 | | |
6520 | 6598 | | |
6521 | 6599 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
458 | 458 | | |
459 | 459 | | |
460 | 460 | | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
461 | 468 | | |
462 | 469 | | |
463 | 470 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
633 | 633 | | |
634 | 634 | | |
635 | 635 | | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
636 | 641 | | |
637 | 642 | | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
| 646 | + | |
| 647 | + | |
| 648 | + | |
| 649 | + | |
| 650 | + | |
638 | 651 | | |
639 | 652 | | |
640 | 653 | | |
| |||
650 | 663 | | |
651 | 664 | | |
652 | 665 | | |
| 666 | + | |
653 | 667 | | |
654 | 668 | | |
655 | 669 | | |
656 | | - | |
657 | | - | |
658 | | - | |
659 | | - | |
660 | | - | |
661 | | - | |
662 | | - | |
663 | | - | |
664 | | - | |
665 | | - | |
666 | | - | |
667 | | - | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
668 | 681 | | |
| 682 | + | |
| 683 | + | |
669 | 684 | | |
670 | 685 | | |
671 | 686 | | |
| |||
3322 | 3337 | | |
3323 | 3338 | | |
3324 | 3339 | | |
3325 | | - | |
| 3340 | + | |
3326 | 3341 | | |
3327 | 3342 | | |
3328 | 3343 | | |
| |||
3346 | 3361 | | |
3347 | 3362 | | |
3348 | 3363 | | |
3349 | | - | |
| 3364 | + | |
| 3365 | + | |
| 3366 | + | |
| 3367 | + | |
| 3368 | + | |
| 3369 | + | |
3350 | 3370 | | |
3351 | 3371 | | |
3352 | 3372 | | |
| |||
0 commit comments