You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 124533b
Browse filesBrowse the repository at this point in the historyBrowse files
test(spec): the fourth data/ file group's test titles state each cited decision in words instead of a tracker number (stage 18) (#21870)
Part of #20749
Clause-②: no
Stage 18 of this card: the next area of class (e), the test strings
shipped under `packages/spec/src`, as ruled in `5902360492` on #20513.
This stage takes the fourth name-ordered file group directly under
`packages/spec/src/data/`: the 17 test files that carry an id from
`filter.test.ts` to `object.test.ts`. They carried 103 messages and 114
tracker ids, citing 81 records. Every one of those ids now either states
what its record decided, in words (form D), or is dropped where the
title already says it. Text only: no assertion, identifier, test count
or code comment changes.
## Census at the base (`c9be1f179d`)
Instruments: `census10.cjs` (md5 `9d08602ab972b4b8643c90d64d40fa41`),
`census.cjs` (md5 `6e42a45a926d375013c32d62f16a296e`), `census-wide.cjs`
(md5 `c98410a19529c439adb0afbfb00026a2`) and `dirtable.cjs` (md5
`dda605c54745b4a60cc14c9a686e4eff`). They are byte-identical to the
copies stages 10 to 17 used. A literal counts as a test title when its
folded message is argument 0 of a `describe` / `it` / `test` call,
`.each` / `.skip` / `.only` chains included. Everything else is an
"other" string.
The base is `c9be1f179d`, one commit past the claim's `969ffba25e`. That
commit (#21857) touches only `plugin-security`, so the test census is
the same. Both instruments read **1045 messages / 1108 ids in 225
files**, the seat's reading and stage 17's head reading.
| directory | files | messages / ids | titles | other |
|:--|--:|--:|--:|--:|
| `ui/` | 84 | 396 / 419 | 378 / 401 | 18 / 18 |
| `api/` | 40 | 189 / 201 | 181 / 193 | 8 / 8 |
| `data/` (this PR: the fourth group) | 35 | 185 / 200 | 184 / 199 | 1 /
1 |
| `system/` | 34 | 154 / 165 | 128 / 138 | 26 / 27 |
| (files directly in `src/`) | 30 | 118 / 120 | 117 / 119 | 1 / 1 |
| `ai/` | 1 | 2 / 2 | 0 | 2 / 2 |
| `contracts/` | 1 | 1 / 1 | 0 | 1 / 1 |
| **total** | **225** | **1045 / 1108** | **988 / 1050** | **57 / 58** |
The group reads **103 messages / 114 ids in 17 files**, the seat's
figures, file for file. Every one of them is a test title:
| file (under `data/`) | messages / ids | titles | other |
|:--|--:|--:|--:|
| `filter.test.ts` | 18 / 19 | 18 / 19 | 0 |
| `form-delete-behavior-options.test.ts` | 1 / 1 | 1 / 1 | 0 |
| `form-return-type-options.test.ts` | 1 / 1 | 1 / 1 | 0 |
| `hook-body.test.ts` | 4 / 4 | 4 / 4 | 0 |
| `hook.test.ts` | 10 / 10 | 10 / 10 | 0 |
| `import-coercion.test.ts` | 2 / 2 | 2 / 2 | 0 |
| `import-mapping-target.test.ts` | 2 / 2 | 2 / 2 | 0 |
| `injected-system-column-provenance.test.ts` | 2 / 2 | 2 / 2 | 0 |
| `injected-system-columns.test.ts` | 1 / 1 | 1 / 1 | 0 |
| `inline-grid-column-currency-scale-refused.test.ts` | 5 / 5 | 5 / 5 |
0 |
| `inline-related-columns.test.ts` | 3 / 3 | 3 / 3 | 0 |
| `managed-api-affordance.test.ts` | 2 / 2 | 2 / 2 | 0 |
| `masked-field-types.test.ts` | 1 / 1 | 1 / 1 | 0 |
| `numeric-column-representation.test.ts` | 1 / 1 | 1 / 1 | 0 |
| `object-image-field.test.ts` | 1 / 1 | 1 / 1 | 0 |
| `object-strictness-batch20.test.ts` | 13 / 17 | 13 / 17 | 0 |
| `object.test.ts` | 36 / 42 | 36 / 42 | 0 |
| **17 files** | **103 / 114** | **103 / 114** | **0** |
Five more test files sit in the same name range and carry no id:
`hook-api`, `hook-body-stored-metadata-target`, `inline-grid-columns`,
`mapping-connector-source` and `mapping`. They are not touched.
- **Controls.** Lit, a title and an "other" string:
`data/query.test.ts`, outside the group, reads 11 / 11 at the head as at
the base, its "other" string at `:202` included. Dark:
`data/import-mapping-target.test.ts` reads 0 / 0 at the head while 2 of
its comment lines still carry a number. Planted in scratch copies of
head files: an id put into a `hook-body.test.ts` title reads 1 / 1, and
an id put into a `masked-field-types.test.ts` comment reads 0.
- **A wider pattern** (any `#` plus digits) reads the same totals as the
gate pattern in 16 of the 17 files at the base. `object.test.ts` reads
one more, at `:857`, which is the colour value `'#00FF00'` and not a
tracker id. At the head the wider pattern reads 0 in 16 files and that
same colour in `object.test.ts`.
- **At the head:** 942 messages / 994 ids in 208 files. The 17 files
read 0 / 0, and no other file moved.
## How the area was chosen
`data/` has no subdirectory to split by, so its stages take name-ordered
file groups near the ~100-id bound. Stage 17's re-cut named this group
at 114, with `object.test.ts` alone carrying 42, and this census reads
114, so the rule needed no re-cut.
**Named for the next stages** (re-cut from the head census, 942 / 994;
`data/` 82 / 86 left, in 18 files):
- `data/`, one more stage: `query-transport.test.ts` to
`validation.test.ts` (11 files, 34 / 34) with `data/driver/` (7 files,
48 / 52): 82 messages / 86 ids.
- `ui/` 419, about four stages. `api/` 201, two. `system/` 165, two. The
files directly in `src/`, 120, one.
- The three docblock needles (`ai/build-progress.test.ts:236`, `:237`,
`contracts/approval-service.test.ts:274`), one stage with their
docblocks.
## What each id became
34 literals (41 ids) now state a decision in words. 69 literals (73 ids)
drop a number the title already explains.
Every cited record was read with its comments through REST. 73 answer
200; `framework#2536` is counted there, because the repository was
renamed `framework` → `objectstack` (`apps/docs/lib/layout.shared.tsx`
records the rename). The old name answers 403 from this session, and the
same number under the current name is the compactLayout retirement that
the title names. Eight answer 404, and each decision was read from what
landed, by REST GET of the landing commit and its CHANGELOG entry: #6571
(`2f3e79351e`), #10165 (`8012960508`), #10347 (`530c1df653`), #10527
(`5649efbf93`), #11195 (`b372318836`), #11408 (`f11fc61c51`), #13644
(`34ce8e7dbe`) and #18012 (`176b03582e`).
| record(s) | literal (under `data/`) | now reads |
|:--|:--|:--|
| #5685 | `filter.test.ts:77` | "string comparands — the ordering slots
take a string, which is what the date macros emit". `string` joined the
four ordering slots because the platform's own date-macro resolver
produces only strings. |
| #14080 | `filter.test.ts:166` | "null comparand — refused in the four
ordering slots, like a null list member". Ruled A: refused at the same
entrance, in the same shape, as the null `$in` member. |
| #6571 (404) | `filter.test.ts:364` | "string endpoints — `$between`
takes the ISO and clock strings the platform produces". The sibling half
of #5685, from `2f3e79351e`. |
| #7711 (2) | `filter.test.ts:549` | "the whole-filter face refuses
these field conditions too — green while the group branch was a
non-strict catch-all". The group branch became `.strict()`, so a refused
member has nowhere to land. |
| #5222 | `filter.test.ts:576` | "leaves the four ORDERING slots taking
a reference — a column-to-column comparison, and the prescribed
alternative". `$field` compiles to a same-table column comparison on SQL
push-down. |
| #5322 | `filter.test.ts:1541` | "leaves the empty-combinator
identities accepted — each reduces to its boolean unit". Ruled:
`{$and:[]}` is every row, `{$or:[]}` none, `{$not:{}}` none. |
| #14104 | `filter.test.ts:1851` | "FieldReferenceSchema.addDays — a
whole-day offset on a reference, an integer or another column". Ruled A:
an offset on the field reference. |
| #16923 | `filter.test.ts:1998` | "filter.zod.ts docblock @examples — a
`$field` comparand names a column of the same row". The relation-path
example was the wrong half; the same-table prose was right. |
| #14010 | `hook.test.ts:352` | "runAs — a hook may run as `system` or
`user`, and inherits by default". Ruled: `runAs: 'system' \| 'user' \|
'inherit'`, default `'inherit'`. |
| #13644 (404) | `hook.test.ts:529` | "Referential-Cleanup Marker —
declared, and true only on a reference-cleanup write by the engine".
Adopted by maintainer ruling, from `34ce8e7dbe`. |
| #4269 | `hook.test.ts:924` | "defineHook — the authoring factory, so a
hook is validated where it is written". The `defineDatasource` pattern:
the convention-scan path got a parse at authoring time. |
| #3493 | `hook.test.ts:1148` | "PRESERVES `preserveAudit` through a
parse (the opt-in a historical import uses to keep its audit stamps)". |
| #5945 | `hook.test.ts:1286` | "HookContext.api typing — the minimum
scoped context the docs teach: `object()` and `transaction()`". Ruled
option C. |
| #4173 (2) | `import-coercion.test.ts:23`, `:48` | "import boolean
tokens — one table for the server coercion and the Import Wizard
preview" and "import reference types — exported from spec, not copied at
each consumer". |
| #8116 | `injected-system-column-provenance.test.ts:53` | "provenance
derivation at its spec home — where the author-time linter can reach
it". Ruled option 1: the derivation moved into the contract package,
which the linter may import. |
| #5378 | `injected-system-columns.test.ts:17` |
"resolveInjectedSystemColumns — the injected columns, so author-time
validation resolves them too". |
| #20045 | `inline-grid-column-currency-scale-refused.test.ts:172` |
"SHAPE PARITY with the currency FIELD refusal (its ruled text carried,
not reworded)". "ruling B" is the ruling that retired `scale` on a
currency field; the letter went with the id. |
| #7521 | `managed-api-affordance.test.ts:57` | "is the exact shape the
boot only warned about, now named at authoring time (sys_environment /
sys_package)". Ruled: an authoring-time check, with boot left at warn
and strip. |
| #16318 | `numeric-column-representation.test.ts:24` | "the numeric
physical-representation table — one table the driver and the migration
generators both read". Ruled C: one table in `packages/spec`, both
producers read it. |
| #4001 (2) | `object-strictness-batch20.test.ts:93`, `:229` | "批 20,
unknown keys refused — …", as stage 15 wrote "batch D, unknown keys
refused". `:132` already says it and keeps only "批 20". |
| #1535, #4519, #4522 | `object-strictness-batch20.test.ts:124` | "the
root itself was already closed, on parse as well as create() — this
batch is the level BELOW it". |
| #5014 | `object-strictness-batch20.test.ts:187` | "⚠️ `systemFields`
is the batch's ONE union flattened to a bare `Invalid input` — …". |
| #5677, #6365 | `object-strictness-batch20.test.ts:380` | "… — since
the unit anchor is injected, the property governs
`owning_business_unit_id` too". #6365 is dropped: the title already
states its correction. |
| #11195 (404) | `object-strictness-batch20.test.ts:422` | "the two
`userActions` vocabularies stay disjoint, the three adopted view keys
included — …". `b372318836` adopted `group` / `hideFields` / `rowColor`
onto the view block. |
| #4001, objectui#4772 | `object-strictness-batch20.test.ts:528` | "批 20
— `IndexSchema` is closed (the held 14th site, once the console index
editor converged on it)". |
| #10527 (404) | `object.test.ts:188` | "retention + ttl + archive
triple — refused unless the ttl restates the age bound". From
`5649efbf93`. |
| #10347 (404) | `object.test.ts:192` | "still accepts the ttl + archive
pair, whose ttl cutoff picks the rows to archive (no retention)". From
`530c1df653`. |
| #2834 | `object.test.ts:264` | "accepts retention.onlyWhen with scalar
and $in predicates (mixed tables, where only terminal rows age out)". |
| #10165 (404) | `object.test.ts:289` | "accepts ttl.onlyWhen with the
canonical null predicate — so rows whose value is absent are spared".
From `8012960508`. |
| #3175 | `object.test.ts:1101` | "ownership record-model field —
declared, so the opt-out the registry reads can be authored". |
| #11408 (404), #10144 | `object.test.ts:1713` | "ObjectSchema editMode
(declared by maintainer ruling: the renderer reads it, so the spec
declares it)". From `f11fc61c51`, in #10144's declare-or-rule-out
family. |
| #14935, #14637 | `object.test.ts:2135` | "isPublicSharingEnabled — the
one canonical standing share-link policy predicate". The runtime mirror
was retired. |
**Dropped where already stated** (69 literals, 73 ids). A number goes
only where the title already says its decision, for example "$field
members are refused (#7596)", the four `crypto.hash` titles in
`hook-body.test.ts` (#4391), the `#20045 —` prefix on the four other
describes of the currency-scale file, and twenty-nine `object.test.ts`
titles such as "managedBy: retiring the overloaded `system` bucket
(#3355)". `(ADR-0049)`, `(ADR-0066)`, `(ADR-0100)` and `(ADR-0087 …)`
stay: they cite decision records by number, not tracker ids.
**Three judgements, each declared:**
- `filter.test.ts:298` keeps "ruled 2026-08-31" and drops only
`(#13357)`. The sibling title at `:656` names "the 2026-08-31 ruling",
so the date stays as its anchor.
- The `批 20` label stays on the four batch-20 describes, because the
file's own name and header carry it. Only `#4001` and `objectui#4772`
went.
- `object-strictness-batch20.test.ts:563` drops "(#5114 class)": the
title already says what is pinned, that the tombstones keep their
prescription through the strict close.
## Readers
- **Test-name filters:** none. No tracked script, workflow or config
passes `-t` / `--testNamePattern`.
- **Snapshots:** none. No `__snapshots__` directory is tracked under
`packages/spec`.
- **Projects:** none of the 17 files is listed in
`packages/spec/vitest.repo-tests.json`; all 17 run in the `local`
project.
- **By substring:** every old literal, plus a window around each id (311
needles), was searched across the tracked tree outside its own file. No
gate, doc, filter, snapshot or `scripts/check-*.mjs` self-test reads
one. The 8 needle hits fall on 7 lines:
- a code comment in `object.zod.ts:2532`;
- two release-owned CHANGELOG lines;
- a sibling title in this card's `system/` stage
(`system/job.test.ts:471`);
- sibling titles in `cli` (`extract-hook-body.test.ts:179`),
`driver-sql` (`sql-driver-16318-numeric-representation.test.ts:64`) and
`objectql` (`engine.test.ts:831`).
None reads a spec test title.
- **The files by name:** 96 references to these file names outside
CHANGELOGs. The gate ledgers among them (`test-typecheck-debt.json`,
`engine-double-contract.pinned.json`,
`objectql-double-limit.baseline.json`) key on the file and on error
signatures, not on a title, and each gate exits 0 at the head.
`scripts/check-org-identifier.mjs` counts `session: { … tenantId … }`
literals in `hook.test.ts`, which this PR does not touch. ADR-0129
quotes "name-as-identity", a title this PR does not change.
## Text-only proof
Stage 10's scratch tool (`textonly10.cjs`, md5
`d5e4801dbb4329ab1984da91e92fc47c`) compares base and head file by file
on three legs:
1. **Skeleton:** the full AST, with string pieces masked. It must be
identical.
2. **Comments:** every comment, byte-equal.
3. **Strings:** each changed string leaf must sit in a test-call title
position or on a declared line, must carry a tracker id before, and must
carry no `#` plus digits after. This stage declares no line: every
changed leaf is a title.
- **Result:** 17 of 17 files SAME on all three legs, with the per-file
counts predicted in writing before the run.
- **Totals:** 103 changed string leaves in 103 literals, all titles. The
diff's `+` and `-` lines are exactly the 103 planned lines, and every
file keeps its line count.
- **Controls (10 of 10 as predicted, on scratch copies, each anchor hit
once in the reported run):** identifier rename DIFF; numeric literal
DIFF; comment edit COMMENT DIFF; a non-title string given an id
VIOLATION; a rewritten title given a new id VIOLATION; a title that was
id-free at base edited VIOLATION; one title reverted to base SAME; an
`it.each` row name given an id VIOLATION; an undeclared `expect` message
changed VIOLATION; a title re-split into a `+` chain DIFF. The non-title
control's first anchor matched nothing (0 hits, so nothing ran). Its
anchor was corrected and all ten were run again.
**Test counts:** the 17 files were run at the base, in a separate base
worktree, and at the head, with `--project local --project repo`. Both
sides read 670 tests, all passed, with the same count and status
sequence per file in 17 of 17. 378 full test names change, and each
equals the base name with the planned replacements applied (0
mismatches). No full name repeats on either side.
## `main` since the base
Re-fetched just before this PR opened, `origin/main` was two commits
past the base (`9f9510f25e`: #21858, #21862). Neither touches any of the
17 files; the one `packages/spec` path among them is
`api/error-code-ledger.zod.ts`. So `main` was not merged. `git
merge-tree` onto `9f9510f25e` is clean. No open PR touches the 17 files.
## Changeset: `skip-changeset`
Measured, not assumed:
- `npm pack --dry-run` of `@objectstack/spec` lists 2068 files. 0 of the
17 touched files are in it, and no `*.test.ts` at all. The controls
`src/data/filter.zod.ts` and `dist/index.mjs` are in it.
- In the built `dist/`, a new phrase and an old literal each read in 0
files. The control `Unrecognized key` reads in 42.
So this PR publishes nothing, and no changeset is added.
## Verification (at `21f39afe57`)
- `pnpm turbo run build` over all packages: 71 / 71.
- `@objectstack/spec`:
- `vitest run --project local`: 615 files, 18387 passed, 1 todo.
- `typecheck` exit 0, including `check:test-typecheck` (52 files / 246
errors / 135 pinned signatures held). Its program holds all 17 touched
files, counted with `tsc --listFilesOnly -p tsconfig.test.json`.
- `check:generated`: all 15 generated artifacts up to date.
- **Gates:** `dispatch-gates --commands` derived 79 families, the same
set as stages 13 to 17, and all 79 exit 0. `--ran` reconciles: 79
derived, 79 run, 0 NOT-MEASURED, 0 UNRUN, every family with its exit
code recorded.
- The five roster families whose rosters sit under a touched directory
were also run, and each exits 0: `check:meta-url-spelling`,
`check:spec-changes`, `check:authz-resolver`, `check:error-code-casing`
and `check:filter-alias-parity`.
- The derivation printed `STALE TREE`:
`scripts/engine-double-contract.pinned.json` moved on `main` after the
base. This diff adds and changes no engine double,
`check:engine-double-contract` exits 0 on this tree, and the queue
re-runs it on the merged generation.
- **ESLint, a proven narrowing:** `--no-inline-config` over the 17 files
reads 0 errors and 0 warnings. The population comes from ESLint's own
config: 17 configured, 0 ignored. No file sets `parserOptions.project`
or `projectService`, so no untouched file's verdict can move.
- `check-governed-merges --test`: NOT governed, 206 changed lines.
## Acceptance notes
- **No needle in this group.** Every id was a test title; no expected
value of an assertion over a source docblock was found. The three known
needles are untouched.
- **Same-id test titles in this card's later stages** go with those
stages: 38 lines in `packages/spec/src`, 9 in `system/` (for example
`system/job.test.ts:471`, the `job.timeout` twin of `hook.test.ts:1382`)
and 29 in `ui/` (for example the `#4001 批 15` / `批 16` / `批 18` / `批 19`
describes and `ui/view-filter-rule-wire-id.test.ts`'s four `#5114`
describes).
- **Same-id test titles in other packages** are their lanes' test-string
shares. A search of `describe` / `it` / `test` lines outside
`packages/spec/src` finds 140 lines citing ids this PR handled:
`objectql` 23 (13 files), `service-analytics` 18 (8), `lint` 17 (9),
`driver-sql` 11 (7), `cli` 10 (4), `runtime` 10 (7), `platform-objects`
5, `plugin-audit` 5, `plugin-security` 5, and fewer in 16 more places,
among them two `packages/spec/scripts/*.test.ts` titles (outside `src/`)
and one title each in `examples/app-crm` and `examples/app-showcase`.
- **Code comments still carry ids** in these files and their sources,
for example the `// [#20150]` block at
`import-mapping-target.test.ts:17`, the `#4001 批 20` header of
`object-strictness-batch20.test.ts` and `object.zod.ts:2532`. Comments
are not this card's share, and none is touched here.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ)_
Co-authored-by: Claude <noreply@anthropic.com>
0 commit comments