Skip to content

test(spec): the second data/ file group's test titles state each cited decision in words instead of a tracker number (stage 16) - #21831

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-20749-test-strings-g
Oct 5, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-20749-test-strings-g

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20749
Clause-②: no

Stage 16 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 second name-ordered file group directly under packages/spec/src/data/: the 20 test files from default-value-shape.test.ts to filter-comparand-shape.test.ts. They carried 94 messages and 100 tracker ids, citing 59 records plus one decision-batch number. 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 (a3ffc4512d)

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 15 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.

Both instruments read 1231 messages / 1304 ids in 262 files, the seat's reading at a3ffc4512d (stage 15's head).

directory files messages / ids titles other
ui/ 81 393 / 416 375 / 398 18 / 18
data/ (this PR: the second 20 files) 75 374 / 399 353 / 376 21 / 23
api/ 40 189 / 201 181 / 193 8 / 8
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 262 1231 / 1304 1154 / 1224 77 / 80

The group reads 94 messages / 100 ids in 20 files, the seat's figures, file for file:

file (under data/) messages / ids titles other
default-value-shape.test.ts 6 / 6 6 / 6 0
default-value-tokens.test.ts 1 / 1 1 / 1 0
document.test.ts 2 / 2 2 / 2 0
driver-nosql.test.ts 1 / 1 1 / 1 0
driver.test.ts 5 / 5 5 / 5 0
esignature-deadline-keys-retirement.test.ts 4 / 4 4 / 4 0
external-lookup-retirement.test.ts 3 / 3 1 / 1 2 / 2
feed.test.ts 1 / 1 1 / 1 0
field-autonumber-default-format.test.ts 1 / 1 1 / 1 0
field-autonumber-default-unique.test.ts 2 / 2 2 / 2 0
field-autonumber-readonly.test.ts 2 / 3 2 / 3 0
field-currency-scale-refused.test.ts 3 / 3 3 / 3 0
field-default-value.test.ts 4 / 4 1 / 1 3 / 3
field-rows-option-description.test.ts 4 / 4 4 / 4 0
field-value.test.ts 5 / 5 5 / 5 0
field.test.ts 32 / 36 32 / 36 0
filter-array-declaration.test.ts 2 / 2 1 / 1 1 / 1
filter-ascii-fold.test.ts 1 / 1 1 / 1 0
filter-boolean-comparand-declared-type.test.ts 11 / 11 11 / 11 0
filter-comparand-shape.test.ts 4 / 5 4 / 5 0
20 files 94 / 100 88 / 94 6 / 6
  • Controls. Lit, a title: data/filter-comparand-type.test.ts, outside the group, reads 9 / 10 at the head as at the base. Lit, "other" strings: the twin expect messages in system/message-queue-retirement.test.ts (:87, :127) still read at the head. Dark: data/filter-array-declaration.test.ts reads 0 / 0 at the head while 9 of its comment lines still carry a number. Planted in a scratch copy of the head data/filter-ascii-fold.test.ts: an id put into a title reads 1 / 1, and an id put into a comment reads 0.
  • A wider pattern (any # plus digits) reads the same totals in 19 of the 20 files. In field.test.ts it reads four more, at both base and head: the hex colours #00FF00 / #00AA00 in option fixtures (:859, :1461, :1476, :1484), which are not tracker ids.
  • At the head: 1137 messages / 1204 ids in 242 files. The 20 files read 0 / 0 on the gate pattern, 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 15's re-cut named this group at exactly 100, and this census reads 100, so the rule needed no re-cut.

Named for the next stages (re-cut from the head census, 1137 / 1204; data/ 280 / 299 left, the same cut stage 15 named):

  • data/ in three more stages, name-ordered:
    1. filter-comparand-type.test.ts to filter-view-operator-parity.test.ts: 20 files, 95 messages / 99 ids;
    2. filter.test.ts to object.test.ts: 17 files, 103 / 114. object.test.ts alone carries 42, so no cut lands nearer the bound;
    3. query-transport.test.ts to validation.test.ts (11 files, 34 / 34) with data/driver/ (7 files, 48 / 52): 86 ids.
  • ui/ 416, 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

31 literals (36 ids) now state a decision in words. 2 literals (2 ids) get their subject back in words where the number stood in for it. 61 literals (62 ids) drop a number the title already explains.

Every cited record was read with its comments through REST: 56 answer 200, the four objectui records among them. #8656, #12868 and #16867 answer 404, and their decisions were read from what landed: 94f7ef8 (a Field.time builder that produces the literal shape an author could already write), c459da6bc (the form-view option shape is the object-field option shape minus default) and 0ee32ed (the flat notNull spellings prescribe storage.notNull, not required), each with its CHANGELOG entry.

record(s) literal (under data/) now reads
#4560 default-value-tokens.test.ts:15 "defaultValue runtime tokens — one vocabulary the engine and the DDL both read". The token set moved to one source that the engine's default stamping and the SQL driver's column defaults both read, so a runtime token is never written as a literal column DEFAULT.
#14477 (2) document.test.ts:238, :255 "… a retiredKey() tombstone, since nothing ever read it (ADR-0049)". The pair had no reader and no roadmap, so it retired with the other deadline families.
#4484 driver.test.ts:112 "the streaming prescription names the removed findStream and the paged-find fix". findStream had no caller and was retired; the streaming bit described it.
#14478 driver.test.ts:399 "DriverOptions.timeout → DriverOptions.timeoutMs: the key carries its unit".
#18063 driver.test.ts:428 "driverSupportsTransactions — a driver that cannot honour transactions says so". Decision batch 148, item 3, letter B: a transport may declare that it has no transactions, and the engine refuses transactional use loudly.
#8075 (2) external-lookup-retirement.test.ts:89, :130 Two declared expect messages: "… must have zero holders after the external-lookup retirement" and "… being undone — the family had no consumer and accepted inline credentials". The measurement found no door reaching either schema, and both carried inline secrets, so both families were removed whole.
#11807 feed.test.ts:22 "SYS_ACTIVITY_BUILTIN_TYPES — the built-in activity types, published by the spec". Ruling A.
#5628, #5503 field-autonumber-readonly.test.ts:82 "RUNTIME_OWNED_FIELD_TYPES is the protocol vocabulary — the types whose value the runtime owns". The engine strips a client's autonumber value, and the builder declares the field read-only.
#13388 field-default-value.test.ts:98 A declared case label: "(postal_code, as the showcase seed once wrote it)". The seed's key was corrected to postalCode.
#16077 (2) field-default-value.test.ts:116, :123 Two declared case labels: "… (the rename is named over the missing-member error that sorts ahead)" and "… (the rename is named over the type error)". The literal gate prefers the rename over a positional member error.
objectui#6140 field-rows-option-description.test.ts:52 "FieldSchema accepts rows on the multiline editor types — declared because the editor widget reads it". Option A: validation and the running widget agree.
objectui#6153 field-rows-option-description.test.ts:162 "SelectOptionSchema accepts description — declared because the lookup widget reads it", the inherited ruling for a consumed key.
#12868 field-rows-option-description.test.ts:192 "… by construction (that face is the option shape minus default)".
#8163 field.test.ts:197 "FieldSchema — field-level currency key guidance, naming currencyConfig.defaultCurrency". The refusal gained a prescription; nothing it accepts moved.
#9784, #4447 field.test.ts:997 "keeps non-reference types ACCEPTING the key (installed-base artifact shape) — materialization moved to the reference-types block below". deleteBehavior materializes only on reference types. #4447 is dropped: "installed-base artifact shape" already says why the key must stay legal.
#8793 field.test.ts:1174 "relatedListFilter is judged by the schema door that refuses a bare date preset as a comparand", the ruled half that refuses the preset vocabulary as a bare temporal comparand at publish time.
#8656 field.test.ts:1434 "should create time field — the same literal shape an author could already write".
#11437, objectui#4015 field.test.ts:2105 "FieldSchema — authored radio + multiple: true is REFUSED (ruled: at the entrance, never rendered as checkboxes)". Option C; option A was not taken.
#17469 field.test.ts:2191 "FieldSchema — authored multiple: true on a NON-MULTI-CAPABLE type is REFUSED (ruled: one definition of multi-value, the radio rule generalised)". Option 1′ of decision batch 128, item 5. That batch number went with the id.
#9019, objectui#4676 field.test.ts:2320 "FieldSchema — placeholder is a DECLARED key (ruled: the renderers already apply it)". Option C: the producer moves.
#8993 field.test.ts:2393 "FieldSchema — maskingRule is a DECLARED key (ruled: partial masking, enforced at runtime)". Option A: partial masking as a runtime-first capability, declared only with its enforcement.
#11339 field.test.ts:2476 "Polymorphic pointer pair — referenceVia names the sibling column that holds the object (ADR-0052 §5)", the declared pointer-pair carrier.
#5158 filter-array-declaration.test.ts:142 A declared expect message: "… — the array form is input-only sugar, lowered before any driver sees it". Ruling C: one lowering seam.
#5286 filter-array-declaration.test.ts:233 "FilterArray type-level declaration (type-checked since the test layer got its own tsc program — see above)".
#4706 filter-ascii-fold.test.ts:32 "leaves non-ASCII letters ALONE — the case-insensitive operators fold ASCII only", the record's first question, answered A.
#21333 filter-boolean-comparand-declared-type.test.ts:138 "booleanComparandDoorVerdict — an accepted spelling narrows to its boolean, any other is refused".
#5423 (2) filter-comparand-shape.test.ts:779, :1068 "the whole refusal fits under the 500-char client bound the REST layer truncates at". The REST layer truncates a long 4xx message rather than replacing it.

Subject restored (2 ids): #16077 at default-value-shape.test.ts:172 ("the rename preference is a NO-OP for a class that cannot emit unrecognized_keys"; without its number the title would have read as if checkLiteralDefaultValue itself were the no-op) and #21382 at filter-boolean-comparand-declared-type.test.ts:195 ("the accepted set is unchanged — the non-string widening adds refusals only").

Dropped only (62 ids): #2004, #3855 (2), #4001 (3), #4455, #4634 (2), #5628, #5869, #6555, #7127 (3), #7768, #8075, #8321 (2), #8371, #9228, #9689 (4), #9784, #11566, #11949, #13053, #13671, #13802, #13894, #14168, #14477 (4), #15680, #16077 (3), #16867, #18972, #19629 (3), #19992 (5), #20740, #21333 (5), #21382 (4), #21448.

Readers

  • Test-name filters: none. A tracked-tree search for --testNamePattern and vitest … -t finds only the option name in packages/qa/vitest-filter-preflight/src/project-cli-override-preflight.ts:212, which filters nothing.
  • Snapshots: none. No .snap file or __snapshots__ directory is tracked under packages/spec.
  • Projects: none of the 20 files is listed in packages/spec/vitest.repo-tests.json; all 20 run in the local project.
  • By substring: every old literal, plus a window around each id (287 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 33 needle hits fall on 18 lines:
    • same-text strings in this card's later stages: data/driver/memory.test.ts:548 and data/driver/turso.test.ts:172 (the last data/ group), ui/dashboard.test.ts:717 ("carries its unit"); system/message-queue-retirement.test.ts:87 and :127, the twin expect messages of the two external-lookup-retirement.test.ts strings; system/translation.test.ts:767 ("unknown-key strictness"); ui/action.test.ts:1245 ("alias is REMOVED");
    • sibling titles in other lanes: objectql engine-aggregate-flag-comparand-refusal.test.ts:187, service-analytics where-boolean-flag-refusal.test.ts:197 and where-empty-operator.test.ts:130 (all [#21448] a LIST …);
    • comments and CHANGELOG: field.zod.ts:2264, driver-sql sql-driver.ts:20176, cli generate.ts:30, filter-comparand-shape.ts:735 and :802, filter-comparand-type.ts:116 and :228, and one packages/spec/CHANGELOG.md entry. None reads a test title.
  • Same-text titles named in stage 14's and 15's ACCEPTs: driver-nosql.test.ts:375 ((#15680)) is the one in this group, rewritten as above.

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. The declared lines are external-lookup-retirement.test.ts:89 and :130, field-default-value.test.ts:98, :116 and :123, and filter-array-declaration.test.ts:142.
  • Result: 20 of 20 files SAME on all three legs, with the per-file counts predicted in writing before the run.
  • Totals: 94 changed literals, 88 titles and 6 declared. The diff's + and - lines are exactly the 94 planned lines, and every file keeps its line count.
  • Controls (10 of 10 as predicted, on scratch copies, each anchor hit once): 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; a declared string given a new id VIOLATION; an undeclared expect message changed VIOLATION; a title re-split into a + chain DIFF.

Test counts: the 20 files were run at the base, in a separate base worktree, and at the head, with --project local --project repo. Both sides read 766 tests (765 passed, 1 todo), with the same count and status sequence per file in 20 of 20. 503 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 six commits past the base (088428fb42). None of them touches any of the 20 files, so main was not merged. Two of them touch packages/spec source (ui/report.form.ts and data/object.zod.ts); this diff changes only test-title text, so it cannot combine with them into a joint failure, and the merge queue re-runs the suite on the merged generation.

Changeset: skip-changeset

Measured, not assumed:

  • npm pack --dry-run of @objectstack/spec lists 2068 files. 0 of the 20 touched files are in it, and no *.test.ts at all. The controls src/data/field.zod.ts, src/data/filter.zod.ts and dist/data/index.js are in it.
  • In the built dist/, five new phrases and four old literals each read in 0 files. The control Unrecognized key(s) on reads in 42.

So this PR publishes nothing, and no changeset is added.

Verification (at 95baf08ba9)

  • pnpm turbo run build over all packages: 71 / 71.
  • @objectstack/spec:
    • vitest run --project local: 615 files, 18360 passed, 1 todo.
    • typecheck exit 0, including check:test-typecheck (52 files / 246 errors / 135 pinned signatures held). Its program holds all 20 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 15, and all 79 exit 0. --ran reconciles: 79 derived, 79 run, 0 NOT-MEASURED, 0 UNRUN, every family with its exit code recorded.
    • The derivation printed STALE TREE: main moved past the base during verification and scripts/engine-double-contract.pinned.json changed there. check:engine-double-contract exits 0 on this tree, this diff touches no engine double, and the queue re-runs the family on the merged generation.
    • 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.
  • ESLint, a proven narrowing: --no-inline-config over the 20 files reads 0 errors and 0 warnings. The population comes from ESLint's own config: 20 configured, 0 ignored. No file sets parserOptions.project or projectService, so no untouched file's verdict can move.
  • check-governed-merges --test: NOT governed, 188 changed lines.

Acceptance notes

  • No needle in this group. Every id was a title or a declared string; 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: 46 lines in packages/spec/src (14 in later data/ groups, 9 in system/, 23 in ui/). Among them, ui/view.test.ts:1893 ("leaves the malformed-declaration refusals (spec: Field.scale accepts meaningless declarations (2.5, -1) — now that scale is enforced, malformed declarations should be refused at authoring time #8321/spec/ui: FormField minLength/maxLength (and the number-constraint quartet) still carry the pre-#11566 shape — z.number().optional(), no integer/positivity validation #12174) reading exactly as before") and ui/action-param-default-value.test.ts:154 (#16077 carries the rename …) are near-twins of titles rewritten here.
  • Same-id test titles in other packages are their lanes' test-string shares. A search of describe / it / test lines outside packages/spec finds 111 lines in 15 packages citing ids this PR handled: objectql 47 (22 files), driver-sql 18 (13), rest 15 (12), driver-mongodb 6 (3), lint 5 (4), plugin-security 5 (2), cli 3 (2), core 2, driver-memory 2, metadata-protocol 2, service-analytics 2, and one each in driver-turso, plugin-audit, qa/dogfood and service-automation.
  • Two spec test files outside src/ carry same-id titles: packages/spec/scripts/check-generated-ledger.test.ts:100 and packages/spec/scripts/file-description.test.ts:66. They are outside class (e) as ruled ("the test strings shipped under src/").
  • Code comments still carry ids in these files and their sources, for example the header of filter-boolean-comparand-declared-type.test.ts, the block above filter-array-declaration.test.ts:233, and the field.zod.ts docblocks naming the shadowing mechanism. Comments are not this card's share, and none is touched here.

Generated by Claude Code

…d decision in words instead of a tracker number (stage 16)

Twenty test files directly under packages/spec/src/data/, from
default-value-shape.test.ts through filter-comparand-shape.test.ts: every
test title and declared test string that carried a tracker id now states
the cited decision in words, or drops the number where the title already
says it. Text only: no assertion, identifier, comment or non-test file
moves.

Claude-Session: https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

github-actions Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 08adfeade897e4115ab11c588a8de0d4d591b57c → packageMentionDocs.

@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 5, 2026
@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 5, 2026 07:35
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 5, 2026 07:35
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 5, 2026
Merged via the queue into main with commit 2799155 Oct 5, 2026
41 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20749-test-strings-g branch October 5, 2026 08:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

protocol:data size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants