Repository navigation
Commit 0e205fe
test(ui/scripts): the inputs guards and the lychee pins read the configs that run; ui/lychee.toml is deleted, ui/turbo.objectui.json stays (#27281)
Part of #26080
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:实测确认 `ui/turbo.objectui.json` 和 `ui/lychee.toml`
没有任何真实运行会读(turbo 只解析根 `turbo.json`,`check-links.yml` 只读根
`lychee.toml`)。三组守卫原本对着这两份死配置断言,现在改读真正生效的根配置:`type-check` 输入守卫、包级 `lint`
输入守卫、lychee「不许有 remap」守卫。断言一条没删,也没放宽。另把 lychee 的站内路由守卫改为读
check-links.yml 的 lychee 参数(只读不改 workflow),`ui/lychee.toml` 已无读者,删除。
- **为什么改**:守卫对着死文件断言,根配置漂了也照样是绿的。改完之后,从根 `turbo.json` 删掉一条 ui 输入,立刻红 38
条。
- **风险与回滚**:只改 `ui/scripts/__tests__` 下的 4 个测试文件与 1
份死配置,不动运行时、构建配置、workflow,也不动任何发布包;回滚 = revert。`ui/lychee.toml`
已删;`ui/turbo.objectui.json` 这次**不删**:用根配置去跑旧断言会红 147
条,其中不少属性在根配置里根本没有对应项。按裁决不许放宽,这些守卫只能继续读旧文件,具体列在 Acceptance notes,要你来定。
- **先看**:1) `ui/scripts/__tests__/helpers/turbo-inputs.ts`(新增
`liveTurboConfig` / `parkedTurboConfig`,默认值仍是旧文件);2)
`ui/scripts/__tests__/check-links-workflow.test.ts` 的
`liveLycheeConfigPath`;3) Acceptance notes 第一条:根 `build` 任务没有哈希 ui 的根脚本。
- **两分钟验证**:`pnpm --dir ui exec vitest run
scripts/__tests__/turbo-type-check-inputs.test.ts
scripts/__tests__/turbo-lint-inputs.test.ts
scripts/__tests__/check-links-workflow.test.ts`,预期 3 个文件全绿;在根
`turbo.json` 的 `type-check.inputs` 里删掉
`"$TURBO_ROOT$/ui/tsconfig.json",` 再跑,预期 type-check 守卫红。
- **需要你做的**:无,席位落地(根 turbo.json 的 ui 输入缺口由席位另立卡 #27283)。
## What changes
Slice 2 of ruling A, item (3): `ui/turbo.objectui.json` and
`ui/lychee.toml`.
**Measured: no real run on `main` reads either file** (readings below).
Every `turbo` invocation, whether in workflows, the root `package.json`
scripts, or turbo's own config resolution, resolves the root
`turbo.json` plus the package-level `ui/apps/console/turbo.json`. Turbo
has no flag here that names another root config, and none is passed.
`check-links.yml` passes `--config lychee.toml` from the repository
root, and no workflow reads `ui/lychee.toml`. So both files are dead
config, read only by tests.
**The retarget.** The live counterpart of the parked turbo config is
`uiScopedTurboConfig()` (`ui/scripts/workspace-root.mjs`): the root
`turbo.json`, narrowed to the `ui/` subset. It is the same reader the
production `select-type-check-scope.mjs` already uses. Swapping the
parked file's content for that live config (probe below) sorts each
guard into one of two groups.
| Reader | Live counterpart holds? | This PR |
|---|---|---|
| `turbo-type-check-inputs.test.ts` (via `helpers/turbo-inputs.ts`) |
yes, all cases | reads `liveTurboConfig()` |
| `turbo-lint-inputs.test.ts`, the package `lint` describe | yes | reads
`liveTurboConfig()` |
| `turbo-lint-inputs.test.ts`, the `//#lint:root` describe | no (5 red)
| unchanged, parked |
| `turbo-build-inputs.test.ts` | no (38 red) | unchanged, parked |
| `turbo-test-inputs.test.ts` | no (41 red) | unchanged, parked |
| `turbo-task-guard-coverage.test.ts` | no (55 red) | unchanged, parked
|
| `check-dist-completeness.test.ts` (build-input case) | no (1 red) |
unchanged, parked |
| `e2e-type-check.test.ts` (wiring cases) | no (4 red) | unchanged,
parked |
| `select-type-check-scope.test.ts` | no (2 red) | unchanged, parked |
| `turbo-build-outputs-cover-published-entries.test.ts` | no (1 red) |
unchanged, parked |
| `workspace-root.test.ts` (`uiTurboConfigPath` itself) | n/a, pins the
resolver | unchanged |
| `check-links-workflow.test.ts`, "carries no remap" | yes (root file
has no `remap`) | reads the root `lychee.toml` |
| `check-links-workflow.test.ts`, site-route pin | yes: restated against
`check-links.yml` `LYCHEE_ARGS` (`--config lychee.toml`, absolute
`--root-dir` over the docs tree, `--fallback-extensions mdx,md`) | reads
the workflow argv |
`ui/lychee.toml` has no reader left and is deleted.
`helpers/turbo-inputs.ts` now exports `liveTurboConfig()` and
`parkedTurboConfig()`. `taskInputs` / `rootAnchoredInputs` take the
config as an optional second argument, defaulting to the parked copy, so
every guard not listed as retargeted reads exactly what it read before.
**`ui/turbo.objectui.json` is not deleted.** Readers whose property has
no live counterpart still need them, and the ruling forbids loosening
those guards. See Acceptance notes.
**Item (2), checked:** `ui/docs/adr`'s index prefix is settled on
`main`. PR #26503 merged as `79cd9ef8` (`git merge-base --is-ancestor
79cd9ef HEAD` → exit 0, a self-proving leg). `docs/adr/README.md:11`
and `:215` list the ObjectUI registry under the `ui-` prefix, with files
untouched, and `scripts/adr-index.mjs` generates it. No edit is needed,
and none is made. A pointer would land in `ui/docs/adr/**` (governed)
and buys nothing.
## Tests
- `pnpm --dir ui exec vitest run --maxWorkers=2 scripts/` on head
`88bd2bb7` (lock VERDICT command-exit 0): **Test Files 174 passed | 2
skipped (176), Tests 5003 passed | 2 skipped (5005)**.
- The 11 reader files, before and after the change: **11 passed, 338
tests**, both times. That is the same count, so no case was dropped.
- `pnpm --dir ui run type-check:scripts`: exit 0.
- **Teeth.** Each mutation was made on disk and verified, then restored.
The restore was proven by `git hash-object` = the HEAD blob, plus an
empty `git status --porcelain`.
- `node scripts/ablation-replace.mjs --file turbo.json --anchor
'"$TURBO_ROOT$/ui/tsconfig.json",' --delete` (anchor 1 → 0, blob
`6d3dece1ae49` → `5b5820c9f5f8`). Result:
`turbo-type-check-inputs.test.ts` **38 failed** (one per `@object-ui/*`
package). Before this PR, the same root edit could not reach that guard:
it read only the parked copy.
- Appending `remap = [...]` to the root `lychee.toml` (`grep -c
'^remap'` 0 → 1). Result: "carries no remap pretending to resolve
fumadocs routes" **failed**.
- Deleting `--root-dir`, then `--fallback-extensions`, from the on-disk
`check-links.yml` (`ablation-replace`, blob `fd75bd9ccaee` restored by
hash, never committed) turns the site-route pin red with its own message
each time.
## Acceptance notes
1. **Open question: the live root `build` and `test` tasks do not hash
the ui tree's root files.**
- The parked copy declares `$TURBO_ROOT$/tsconfig.json`,
`scripts/vite-*.ts`, `scripts/build-plugin-stylesheet.mjs`,
`scripts/check-dist-completeness.mjs`, `scripts/invoked-as.mjs` and
`scripts/vitest-invocation-guard.mjs` for `build`, plus the vitest
config and setup set for `test`.
- The root `turbo.json` carries none of them under `ui/`. Measured:
`pnpm exec turbo run build --filter=@object-ui/components --dry=json` →
the task's root-anchored inputs are exactly
`scripts/check-dts-emitted.mjs`, `scripts/invoked-as.mjs` and
`scripts/tsup-drop-sources-content.mjs`. Meanwhile
`ui/packages/components/vite.config.ts:14-15` imports
`ui/scripts/vite-dts-*.ts`, and its `tsconfig.json` extends
`ui/tsconfig.json`.
- So an edit to either file replays a cached `@object-ui/*` build in any
`turbo run build` that includes ui packages (root `pnpm build`).
- The guards that would catch this (`turbo-build-inputs`,
`turbo-test-inputs`, `check-dist-completeness`'s build-input case) stay
green because they read the dead copy.
- Options:
- **A**: port the ui entries into the root `build` / `test` inputs.
Every `@objectstack/*` package then also hashes them, so this edits the
real cache keys. Then retarget those guards and delete the parked file.
- **B**: give the ui packages package-level `turbo.json` files that
extend the root.
- **C**: keep the status quo.
- Recommendation: **A**, because it closes the stale-replay path and
makes the parked file deletable. It is a root `turbo.json` behaviour
change, so it is its own card, not this slice. Seat: #27283 carries the
root turbo.json ui-input gap, with these guards riding it.
2. **Open question: the properties that have no live counterpart by
construction.**
- `//#lint:root` and `//#type-check:e2e` are root tasks of objectui's
own manifest. In the root config, `//` is the objectstack root package,
so they cannot exist there. CI runs them as plain steps (`pnpm --dir ui
run type-check:e2e`, ci.yml's ported-jobs header).
- The guards pinning them (`turbo-lint-inputs` `//#lint:root` describe,
`e2e-type-check` wiring, `select-type-check-scope`'s root-task case,
part of `turbo-task-guard-coverage`) can only ever read the parked copy.
- Recommendation: a follow-up rules each guard either retired with a
named duplicate (per the deletion rule) or rewritten against the CI step
that runs the task. Until then the parked file stays. Seat: #27283
carries this too.
3. **Resolved in this PR (seat answer A):** the site-route pin is
restated against the live argv, and `ui/lychee.toml` is deleted.
4. `select-type-check-scope.test.ts` drives the selector with the parked
config, while the selector in production
(`select-type-check-scope.mjs:324`) reads `uiScopedTurboConfig`. Against
the live config, two cases go red: e2e files no longer widen, because
`//#type-check:e2e` does not exist there. The test stays as is (point
2).
5. `turbo-build-outputs-cover-published-entries`:
`ui/apps/console/turbo.json` restates the parked `build.outputs`, not
the root's (it lacks `json-schema/**` and `!.next/cache/**`). The "no
package configuration narrows the root outputs" case is the one red
against live. It is noted only: console emits neither path.
## Verification
<details><summary>Reading 1: no turbo invocation names the parked
file</summary>
```
$ git grep -n -i 'root-turbo-json\|ROOT_TURBO_JSON\|turbo.objectui' -- . ':!ui/CHANGELOG.md' | grep -v '^ui/scripts/__tests__\|^ui/scripts/workspace-root'
(no hits; the only hits outside those two paths are vscode-extension `*.objectui.json` schema-file globs, a different thing)
$ find . -name turbo.json -not -path '*/node_modules/*'
./turbo.json
./ui/apps/console/turbo.json # "extends": ["//"]
$ grep -n 'turbo' package.json # root scripts: build, spec:rebuild, test, test:smoke, typecheck, clean, console:build -- all plain `turbo run`
$ grep -n '"turbo \|turbo run' ui/package.json
(no hits)
$ grep -n 'turbo run' .github/workflows/*.yml # every one runs from the repo root, e.g. ci.yml:3314, :3486, :3576, :3584
$ ls ui/.github
ls: cannot access 'ui/.github': No such file or directory
```
</details>
<details><summary>Reading 2: no workflow reads ui/lychee.toml</summary>
```
$ git grep -n 'lychee' -- ':!ui/CHANGELOG.md' | grep -v '^content/docs/releases' | grep -v '^.github/workflows/check-links.yml'
ui/lychee.toml ... (its own text)
ui/scripts/__tests__/check-links-workflow.test.ts ...
scripts/check-adr-links.mjs / scripts/check-doc-anchors.mjs (prose naming the ROOT lychee.toml)
$ sed -n 120,126p .github/workflows/check-links.yml
--root-dir ${{ github.workspace }}/content
--fallback-extensions mdx,md
--config lychee.toml
```
</details>
<details><summary>Reading 3: probe, the live config substituted for the
parked one (base 4d3a077, restored by hash)</summary>
```
parked tasks: build test test:dist test:watch lint //#lint:root type-check //#type-check:e2e clean dev
DIFF build.inputs: onlyParked=["$TURBO_ROOT$/tsconfig.json","$TURBO_ROOT$/scripts/vite-*.ts","$TURBO_ROOT$/scripts/build-plugin-stylesheet.mjs","$TURBO_ROOT$/scripts/check-dist-completeness.mjs","$TURBO_ROOT$/scripts/invoked-as.mjs","$TURBO_ROOT$/scripts/vitest-invocation-guard.mjs"]
DIFF test.inputs: onlyParked=["src/**", ..., "$TURBO_ROOT$/vitest.config.mts", "$TURBO_ROOT$/vitest.setup.*", ...]
MISSING in live: //#lint:root
MISSING in live: //#type-check:e2e
$ vitest run (the 11 reader files) with ui/turbo.objectui.json := JSON of uiScopedTurboConfig()
Test Files 8 failed | 3 passed (11)
Tests 147 failed | 294 passed (441)
per file: turbo-task-guard-coverage 55 · turbo-test-inputs 41 · turbo-build-inputs 38 · turbo-lint-inputs 5 (all in the //#lint:root describe) · e2e-type-check 4 · select-type-check-scope 2 · check-dist-completeness 1 · turbo-build-outputs-cover-published-entries 1
green: turbo-type-check-inputs, workspace-root, check-links-workflow
```
</details>
<details><summary>Reading 4: derived gates on head 88bd2bb</summary>
```
$ node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack # 18 families, change set vs merge base 1287b2f
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
pnpm --dir ui exec vitest run scripts/ :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:published-files :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
$ node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran ran.txt
✓ dispatch-gates --ran: 18 derived famil(ies) accounted for — 18 run, 0 NOT-MEASURED (a DERIVED zero — all 18 recorded an exit code and none of them is 3).
```
</details>
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01QSeKYmTYfaPbLQD4BJfomW
---
_Generated by [Claude
Code](https://claude.ai/code/session_01QSeKYmTYfaPbLQD4BJfomW)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 79ed6f7 commit 0e205fe
5 files changed
Lines changed: 99 additions & 148 deletions
File tree
- ui
- scripts/__tests__
- helpers
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2 | 2 | | |
3 | 3 | | |
4 | 4 | | |
| 5 | + | |
5 | 6 | | |
6 | 7 | | |
7 | 8 | | |
| |||
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
35 | 40 | | |
36 | 41 | | |
37 | 42 | | |
| |||
51 | 56 | | |
52 | 57 | | |
53 | 58 | | |
54 | | - | |
55 | | - | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
56 | 89 | | |
57 | 90 | | |
58 | 91 | | |
| |||
209 | 242 | | |
210 | 243 | | |
211 | 244 | | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
223 | 269 | | |
224 | 270 | | |
225 | 271 | | |
226 | 272 | | |
227 | 273 | | |
228 | 274 | | |
229 | 275 | | |
230 | | - | |
| 276 | + | |
231 | 277 | | |
232 | 278 | | |
233 | 279 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
| 24 | + | |
25 | 25 | | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
29 | 45 | | |
30 | 46 | | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
36 | 51 | | |
37 | | - | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
38 | 55 | | |
39 | 56 | | |
40 | 57 | | |
| |||
106 | 123 | | |
107 | 124 | | |
108 | 125 | | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
| 126 | + | |
113 | 127 | | |
114 | 128 | | |
115 | 129 | | |
| |||
124 | 138 | | |
125 | 139 | | |
126 | 140 | | |
127 | | - | |
128 | | - | |
| 141 | + | |
| 142 | + | |
129 | 143 | | |
130 | 144 | | |
131 | 145 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
14 | 15 | | |
15 | 16 | | |
| |||
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
91 | | - | |
| 92 | + | |
92 | 93 | | |
93 | 94 | | |
94 | 95 | | |
| |||
167 | 168 | | |
168 | 169 | | |
169 | 170 | | |
170 | | - | |
| 171 | + | |
171 | 172 | | |
172 | 173 | | |
173 | 174 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
| 7 | + | |
7 | 8 | | |
8 | 9 | | |
9 | 10 | | |
| |||
131 | 132 | | |
132 | 133 | | |
133 | 134 | | |
134 | | - | |
| 135 | + | |
135 | 136 | | |
136 | 137 | | |
137 | 138 | | |
| |||
0 commit comments