Repository navigation
Commit 2e5746d
test(spec): state the registered-type closure rule instead of pinning closed/total counts (#26509)
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} -->
_Requested by **Yibo Wang** · [project
thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwB5sm8QBuDxvf14zMDnQes6X)_
Fixes #26437
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:`metadata-type-schemas.test.ts` 末尾两个手写计数(closed 27 / types
28)换成规则断言:从注册表算出「未闭合的类型集合」,必须恰好等于文件里具名的例外表 `STILL_STRIP`(今天只有
`view`)。计数的递增记录挪到文件头作为历史。
- 为什么改:每加一种元数据类型就得手改这两个数,改数不证明任何事;规则断言只在真正违约时变红,并直接点名违约的类型。
- 风险与回滚:只改一个测试文件,不发布任何东西;回滚就是 revert 这一个提交。
- 先看:`packages/spec/src/kernel/metadata-type-schemas.test.ts` 的 `the
open set, computed from the registry, IS STILL_STRIP` 用例(文件末尾),再看文件头新加的
History 节。
- 两分钟验证:`pnpm --filter @objectstack/spec exec vitest run
src/kernel/metadata-type-schemas.test.ts`,预期 134/134 通过。
- 需要你做的:无,席位落地。
## What changes
`packages/spec/src/kernel/metadata-type-schemas.test.ts` only.
- The closure `describe` ended in `expect(closed.length).toBe(27)` and
`expect(types.length).toBe(28)`, bumped by hand on every new metadata
kind. That test is replaced by the rule the counts stood in for: the
registered types whose top-level schema posture is not `strict`,
computed from `listMetadataTypeSchemaTypes()` with the file's own
`topLevelPosture` walker, must equal `STILL_STRIP` (today `['view']`).
`types.length > 0` is kept.
- The bump log (25 → 24 `validation`, 24 → 25 `api`, 25 → 26
`capability`, `api` closing, 26 → 27 `picklist`, 27 → 28 `sharing_rule`)
moves to a `## History` section in the file header.
- Two pieces of prose that still referred to the count are updated: the
STILL_STRIP reverse-pin message no longer says "and update the count",
and the `view` note no longer says "24 of 25 are closed".
## Why
Part of #26431 (retire the transcription pins). A hand-typed total is a
transcription of the registry, not a check on it: adding a closed kind
turned the suite red for no defect, and the fix was always to type the
new number. The rule form fails only on a real breach (a new open kind,
or an exception that closed) and names the offending types in the diff.
## Tests
Run at head `120bfb17`.
- `pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2
src/kernel/metadata-type-schemas.test.ts` under the verify lock: `Test
Files 1 passed (1)`, `Tests 134 passed (134)`, `VERDICT command-exit 0`.
- `pnpm --filter @objectstack/spec build && pnpm --filter
@objectstack/spec typecheck`: `VERDICT command-exit 0`;
`check:test-typecheck: OK` (test layer compiles under
`tsconfig.test.json`, debt ledger held).
<details><summary>Ablation: one closed type made non-strict reds the new
assertion</summary>
Via `scripts/ablation-replace.mjs` on
`packages/spec/src/data/picklist.zod.ts`, anchor `export const
PicklistSchema = lazySchema(() => strictObject({` replaced with
`z.object({` (anchor x1 → x0, replacement x0 → x1, blob `56447b6a03a5` →
`9ee381dbfaaf`). The test imports the registry by relative `src` path,
so no build sits between the mutation and the run.
```
FAIL registered-type closure is derived, not tallied > the open set, computed from the registry, IS `STILL_STRIP` — no count to bump
AssertionError: the registered types whose schema is not closed must be exactly STILL_STRIP: expected [ 'picklist', 'view' ] to deeply equal [ 'view' ]
Tests 4 failed | 130 passed (134)
```
The other three reds are the pre-existing per-type pins on `picklist`
(REJECTS unknown keys, and the two envelope pins, since `strictObject`
is what spreads the envelope fields). Restore: blob after restore
`56447b6a03a5` == HEAD, `git diff HEAD` empty.
</details>
## Acceptance notes
- Adding a closed metadata kind changes no test: the new assertion
derives both sides from the registry and the named list; nothing counts.
- `git grep -n 'closed.length).toBe(' packages/spec` returns 0 hits
(exit 1).
- No changeset: the diff is a test file, outside every `files[]` entry
`@objectstack/spec` publishes (`src/**/*.zod.ts`, `dist`, …). Built
`dist` has zero hits for the new test's text; positive control
`listMetadataTypeSchemaTypes` hits `dist/browser/kernel/index.js`.
Labelled `skip-changeset`.
## Verification
<details><summary>Derived local gates: 73 derived, 69 run green, 4 not
measured, 0 red</summary>
`node scripts/pm/dispatch-gates.mjs --commands` at `120bfb17` derived 73
families for the one changed path. All 73 were run with exit codes
recorded; `dispatch-gates --ran` reconciles: `73 derived famil(ies)
accounted for — 69 run, 4 NOT-MEASURED (4 DERIVED from a recorded exit
3)`.
NOT MEASURED (exit 3, prerequisite refusal, owned by CI):
- `node scripts/check-plugin-teardown-shape.mjs --self-test`, reason:
shallow clone cannot reach its pinned positive-control commit.
- `pnpm --filter @objectstack/lint run check:doc-formula-expressions`,
reason: `@objectstack/formula` and `@objectstack/lint` not built in this
worktree.
- `pnpm check:dual-build-cjs-loads`, reason: reads built output of
packages this diff does not touch (no `dist/`).
- `pnpm check:lean-entry-closure`, reason: `@objectstack/objectql` not
built.
`node scripts/check-nul-bytes.mjs`: exit 0. Repo-wide scans (`pnpm
lint`) and the full test farm are CI's.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (CI's run is the
reading.)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset. (Publishes
nothing; `skip-changeset`.)
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (Test file only; no artifact reads it.)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
Dispatched by spec seat 1 (`session_01WGufzfhobWEgUUrjz4rrbh`);
implemented in card thread `session_01WGufzgtamNuTZbD2fSuQ3Y`.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01WGufzgtamNuTZbD2fSuQ3Y
---
_Generated by [Claude
Code](https://claude.ai/code/session_01WGufzgtamNuTZbD2fSuQ3Y)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent d2ca707 commit 2e5746d
1 file changed
Lines changed: 53 additions & 45 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 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 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
56 | 95 | | |
57 | 96 | | |
58 | 97 | | |
| |||
483 | 522 | | |
484 | 523 | | |
485 | 524 | | |
486 | | - | |
487 | | - | |
| 525 | + | |
| 526 | + | |
488 | 527 | | |
489 | 528 | | |
490 | 529 | | |
| |||
609 | 648 | | |
610 | 649 | | |
611 | 650 | | |
612 | | - | |
| 651 | + | |
613 | 652 | | |
614 | 653 | | |
615 | 654 | | |
616 | | - | |
617 | | - | |
618 | | - | |
619 | | - | |
620 | | - | |
621 | | - | |
622 | | - | |
623 | | - | |
624 | | - | |
625 | | - | |
626 | | - | |
627 | | - | |
628 | | - | |
629 | | - | |
630 | | - | |
631 | | - | |
632 | | - | |
633 | | - | |
634 | | - | |
635 | | - | |
636 | | - | |
637 | | - | |
638 | | - | |
639 | | - | |
640 | | - | |
641 | | - | |
642 | | - | |
643 | | - | |
644 | | - | |
645 | | - | |
646 | | - | |
647 | | - | |
648 | | - | |
649 | | - | |
650 | | - | |
651 | | - | |
652 | | - | |
653 | | - | |
654 | | - | |
655 | | - | |
656 | | - | |
657 | | - | |
| 655 | + | |
| 656 | + | |
| 657 | + | |
| 658 | + | |
| 659 | + | |
| 660 | + | |
| 661 | + | |
| 662 | + | |
| 663 | + | |
| 664 | + | |
| 665 | + | |
658 | 666 | | |
659 | 667 | | |
0 commit comments