Skip to content

test(spec): the first system/ file group's test titles state each cited decision in words instead of a tracker number (stage 26) - #21987

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

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

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20749
Clause-②: no

Stage 26 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 first name-ordered system/ group: the 18 id-bearing test files under packages/spec/src/system/ from auth-config.test.ts to metadata-form-declared-rows.pin.test.ts, with constants/system-names.test.ts in its path position. Those files carried 91 messages and 97 tracker ids, citing 54 records. All 97 now either state what their record decided, in words (form D), or are dropped where the title already says it. No needle sits in this group. Text only: no assertion, identifier, test count or code comment changes, and no file is renamed.

Census at the base (dcf3eb494a)

Instruments: census10.cjs (md5 9d08602ab972b4b8643c90d64d40fa41), census.cjs (md5 6e42a45a926d375013c32d62f16a296e), census-wide.cjs (md5 c98410a19529c439adb0afbfb00026a2) and dirtable.cjs (md5 dda605c54745b4a60cc14c9a686e4eff), byte-identical to the copies stages 10 to 25 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 worktree was cut from origin/main at dcf3eb494a, the claim's base and stage 25's landing. Both instruments read 282 messages / 297 ids in 71 files, the seat's reading and stage 25's head reading.

directory files messages / ids titles other
system/ (this PR: 18 of its 34 files) 34 154 / 167 128 / 138 26 / 29
(files directly in src/) 30 118 / 120 117 / 119 1 / 1
ui/ 5 7 / 7 0 7 / 7
ai/ 1 2 / 2 0 2 / 2
contracts/ 1 1 / 1 0 1 / 1
total 71 282 / 297 245 / 257 37 / 40

The group reads 91 messages / 97 ids in 18 files, the seat's figures file for file:

file (under system/) messages / ids titles other
auth-config.test.ts 2 / 2 2 / 2 0
book.test.ts 2 / 2 2 / 2 0
cache.test.ts 1 / 1 1 / 1 0
collaboration.test.ts 1 / 1 1 / 1 0
compliance-families-retirement.test.ts 7 / 7 4 / 4 3 / 3
constants/system-names.test.ts 1 / 1 1 / 1 0
core-service-provider.test.ts 1 / 1 1 / 1 0
data-migration-flag-column-move.pin.test.ts 2 / 3 2 / 3 0
disaster-recovery.test.ts 1 / 1 1 / 1 0
email-config.test.ts 2 / 2 2 / 2 0
email-template-floor-locale-parity.pin.test.ts 1 / 1 1 / 1 0
environment-artifact.test.ts 5 / 5 5 / 5 0
http-server.test.ts 2 / 2 2 / 2 0
i18n-resolver.test.ts 53 / 56 50 / 53 3 / 3
job.test.ts 4 / 4 4 / 4 0
logging.test.ts 1 / 3 1 / 3 0
message-queue-retirement.test.ts 3 / 3 1 / 1 2 / 2
metadata-form-declared-rows.pin.test.ts 2 / 2 2 / 2 0
18 files 91 / 97 83 / 89 8 / 8

Ten more test files sit in the same name range and carry no id (constants/platform-object-names, constants/platform-tool-names, core-services, deploy-bundle, doc, encryption, i18n-resolver.nav-label-identity, i18n-resolver.object-list-views, job-pull-organization, license). The eight "other" strings are expect failure messages, rewritten and declared to the text-only tool: compliance-families-retirement.test.ts:159 (a template literal), :210 and :494; message-queue-retirement.test.ts:87 (a template literal) and :127; i18n-resolver.test.ts:3288 (the second leaf of a + chain), :3299 and :3303.

  • Controls. Lit: system/metrics.test.ts (4 / 5) and system/translation.test.ts (12 / 12), outside the group, read the same at the base and at the head. Dark: i18n-resolver.test.ts reads 0 at the head while 47 of its lines still carry # plus digits: 45 comment lines and the two (batch #58) titles below. Planted in a scratch tree: an id put into the rewritten i18n-resolver.test.ts "per-component copy" title reads 1 / 1 (title:describe), and an id put into a job.test.ts comment reads 0.
  • A wider pattern (any # plus digits) reads the same as the gate pattern in 17 of the 18 files at the base. In i18n-resolver.test.ts it reads two more: :1744 and :1757 end in "(batch Query Protocol: Add comprehensive test coverage and documentation for aggregations, joins, and window functions #58)", a two-digit decision-batch label that the gate's three-to-five-digit pattern does not count. Neither literal carries a counted id, so both stay, in the form earlier stages kept batch labels (stage 21's 批 17, stage 22's 批 14 / batch 13). At the head the wider pattern reads 0 in 17 files and those 2 in i18n-resolver.test.ts.
  • At the head: 191 messages / 200 ids in 53 files. The 18 files read 0 / 0, system/ reads 63 / 70 in 16 files, and no other file moved.

How the area was chosen

system/ is taken in path-ordered file groups near the ~100-id bound, the rule stages 20 to 25 used, with constants/system-names.test.ts sorting at constants/. Stage 25's cut named this group at 97 ids, and this census reads 97, so no re-cut was needed. i18n-resolver.test.ts (56 ids; #21948 landed into it at bab76850cd, and its titles were read at this base) fits one PR and one text-only proof, so it is not split.

Named for the next stages (cut from the head census, 191 / 200):

  • the second system/ group: metadata-form-zod-reconciliation.test.ts through worker.test.ts, 16 files, 63 messages / 70 ids (45 / 49 titles, 18 / 21 other). Its first file alone carries 21 / 24, 17 of them "other" strings (its ledger why entries).
  • The files directly in src/, 120, one stage.
  • The needles: one stage, with an at-tier review. The four colour literals stay, as stage 21 decided.

What each id became

  • 23 literals (25 ids) now state a decision in words.
  • 11 literals (12 ids) get their subject back in words, where the number stood for a thing.
  • 57 literals (60 ids) drop a number the title already explains.

Every cited record was fetched with all its comments through REST, and its decision was read from its ruling, ACCEPT and landing comments: a keyword digest of every record, and full reads wherever the new words carry a decision. 54 records are cited: 51 answer 200 (#15514 is a PR, merged as bf1054a4c0) and 3 answer 404. The three that answer 404 were read from what landed, through the commits endpoint (this checkout is shallow), each found through its CHANGELOG entry or the file's own commit anchor:

The same-id title stage 25 listed: book.test.ts:413 "ResolvedBookSchema is the book-tree response contract (#12038)". Its body parses the real resolveBookTree() output, accepts the honest-empty tree and pins each Zod schema type-identical to its interface: a describe-only transcription, which the five-part ruling's implementation plan names (5434804846). None of 1C · 2C · 3A · 4A · 5A is pinned, so no letter is named; the title already says the decision, and only the number goes.

"ruled:" appears in two titles, each on a record that carries a ruling:

Stated in words (23 literals):

record literal (under system/) now reads the decision
#11739 auth-config.test.ts:423 "AudienceConfigSchema — one closed audience posture, invite_only when undeclared" One declared posture, a closed vocabulary (invite_only / email_domain / open), invite_only when undeclared, as the body records it ruled.
#15679 (#14478 ruling B) cache.test.ts:336, collaboration.test.ts:1005, disaster-recovery.test.ts:235 "… carry their unit in the key name" / "… carries its unit in the key name" The system/ duration keys carry their unit in the key name, stage 25's #15677 reading.
#15513 compliance-families-retirement.test.ts:210, :494 (expect messages) "… being undone — the three families were retired whole, none roadmapped" Maintainer ruling A (5548577921): the three compliance-shaped families are retired whole; none is roadmapped.
#15989 Q1, via #16185 data-migration-flag-column-move.pin.test.ts:72 "columns_moved_at — absence is the contract (ruled: one nullable datetime on the flag row)" Above.
#16185 constraint 2 data-migration-flag-column-move.pin.test.ts:126 "the ONE arbiter is unchanged by the new member — read beside it, never inside it" isDataMigrationFlagVerified is not touched; the new field is read in addition to the arbiter, never inside it.
#19184 job.test.ts:881 "JobSchema's own @example — copied verbatim, it parses" The example stops opening with the retired id, so a verbatim copy is accepted.
#8075 message-queue-retirement.test.ts:127 (expect message) "… being undone — the family had no consumer and carried an inline credential" Fork (b): exported but unconsumed, the credential-bearing shape is retired whole.
#16772 i18n-resolver.test.ts:1207 "translateDashboard — global filters, addressable from a bundle" Finding B: dashboards.NAME.globalFilters becomes a bundle group.
#6080 :1573 "per-component copy, keyed by component id" Page component copy gets a bundle address by component id.
#13218 (404) :2215 "walkAddressedPageComponents — the one addressed-component walk, shared by the resolver and the CLI extractor" What landed in c45d8e6b4e.
#5377 :2652 "resolveTabLabel — filter-preset tab labels, keyed under _tabs" Tab labels get the objects.OBJECT._tabs.TAB.label key and a resolver.
#3370 :3049 "translateObject inline actions — served with their _actions translations" Declared action labels are translated, not served as English literals.
#3833, #3847 :3131 "resolveObjectFieldLabels — the declared rich entries, read from the nested translation shape" #3833: the nested shape, never the retired flat dialect; #3847: the rich label / help / options entries the response declares.
#7679 :3308 "normalizeSupportedLocales — the declared supportedLocales narrow the advertised set" /i18n/locales reports the app's declared locales, not every loaded bundle.
#11287 :3732, :4134 "translateFlow — screen-flow copy from the flows bundle group" / "resolveFlowScreenTitle — a screen title from the flows bundle group" The resolver half that reads TranslationData.flows.
#3786 :4726 "… the REST boundary follows — one derived list, no hand-kept copy" Derive from the one source instead of hand-copying a "keep in sync" list.
#14882 :4853 "a declared fallback chain, not a literal en, at the resolver" The chain honours the declared fallbackLocale, not a hard-wired ['en'].
#15711 :4944 "… for a default-locale request (ruled: the authored label is the default-locale text)" Above.
#16458 :5011 "resolveMetadataFormSchemaTitles — bundle labels overlaid as JSON Schema titles, repeater rows included" Item-level property names get a translated title through the array's items.

Subject back in words (11 literals):

Dropped where already stated (57 literals, 60 ids). A number goes only where the title already says its decision. Examples: [#15513] x2 and [#8075] retirement describes and [#4740]; the four other [#15711] prefixes, once the ruling is stated in the first; the tails (#18124), (#4667) x2, (#12038), (#4611), (#4451), (#5307), (#14865), (#4938), (#5295), (#16292), (#19085), (#20439), (#4854), (#21257), (#10926), (#12961), (#5775), (#20940) x3, (#16772) x4, (#5377) x2, (#5728) x2, (#3847) x2, (#7634) x4 (one title and three expect messages), (#8284), (#11745), (#14253) x6; the objectstack#14972 tail with its repository qualifier; the ADR-bearing tails (#4740, ADR-0049), (#20680, ADR-0029 D9.2a), (#20731, ADR-0029 D9.2a), (#14478, ADR-0087 …), which keep their ADR; pre-#4740 before "v0 artifact"; and (#17782, #15939, #14478) on "logging duration keys → *Ms", whose title shows the rename. The two 404 numbers among them (#10926, #12961) go only where the title already states what landed.

No file is renamed.

Readers

  • Needles: none. The eight declared strings are assertion failure messages (the second argument of expect), none is an expected value. The three .pin.test.ts files read source text, and none reads an id: data-migration-flag-column-move.pin.test.ts reads isDataMigrationFlagVerified's body for verified_at, blocking and the absence of columns_moved_at; email-template-floor-locale-parity.pin.test.ts reads DEFAULT_TEMPLATE_LOCALE and "must stay equal"; metadata-form-declared-rows.pin.test.ts reads registered form rows. job.test.ts's @example pin reads the anchor "@example Metadata Sync Job (Cron)". No title or message in the group is matched against a source docblock or another file's text.
  • Test-name filters: none. No tracked script, workflow or package config passes -t / --testNamePattern to vitest; the one vitest -t hit is a README example under packages/qa/dogfood filtering its own fixture.
  • Snapshots: none. No __snapshots__ directory is tracked under packages/spec, and none of the 18 files calls a snapshot matcher.
  • Projects: compliance-families-retirement.test.ts and email-template-floor-locale-parity.pin.test.ts are in the repo project (packages/spec/vitest.repo-tests.json); the other 16 run in local. The base-versus-head run below takes both projects.
  • By substring: every old literal, its id-bearing fragment and a window around each id (272 needles) was searched with git grep at the base, across the tracked tree outside its own file. No gate, doc, filter, snapshot, QA checklist entry or scripts/check-*.mjs self-test reads one. The 12 hits are sibling test titles: the three (#15679) titles in this group hit each other (all rewritten here) and the five (#15679) titles of the second system/ group (metrics, object-storage, registry-config, tracing, worker), which go with that stage.

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 the eight expect-message lines named above.
  • Result: 18 of 18 files SAME on all three legs, with the per-file counts predicted in writing before any edit.
  • Totals: 91 changed string leaves in 91 literals: 83 titles and 8 declared. The diff's + and - lines are exactly the 91 planned lines as multisets, and every file keeps its line count.
  • Controls (14 of 14 as predicted on the first run, 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; an it.each row given an id VIOLATION; an undeclared expect message changed VIOLATION; a title re-split into a + chain DIFF; a declared expect message reverted to base SAME; a declared template expect message given a new id VIOLATION; a declared +-chain leaf given a new id VIOLATION; a template-literal title given a new id VIOLATION.
  • Templates and tables: no .each title and no $name placeholder changes. The two template literals change only their text after the ${…} span.

Test counts: the 18 files were run at the base, before the edit, and at the head, in the same worktree, with --project local --project repo. Both sides read 783 tests in 18 files, all passed, with the same count and status sequence per file in 18 of 18. 354 full test names change, and each changed name equals the base name with the planned replacements applied: 0 mismatches. No full name repeats on either side. No head name carries a gate-pattern id (354 base names did); two head names carry the kept "(batch #58)". No source escape sits in a planned anchor, so the comparison tool met none.

Changeset: skip-changeset

Measured, not assumed:

  • npm pack --dry-run of @objectstack/spec lists 2068 files. 0 of the 18 touched files are in it, and no *.test.ts at all (files[] ships src/**/*.zod.ts, not tests). The controls src/system/job.zod.ts, src/system/translation.zod.ts and dist/index.mjs are in it.
  • In the built dist/, two new phrases and an old one each read in 0 files. The control Unrecognized key reads in 42.

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

Verification (at ed2bc649f3)

  • pnpm turbo run build over all packages: 71 / 71, through the shared verify lock (turbo exit 0, recorded to a file; VERDICT batch-last-exit 0).
  • @objectstack/spec:
    • vitest run --project local: 619 files, 18485 passed, 1 todo.
    • typecheck: exit 0, including check:test-typecheck (52 files / 246 errors / 135 pinned signatures held). Its program holds all 18 group files, counted by path with tsc --listFilesOnly -p tsconfig.test.json.
    • check:generated: all 15 generated artifacts up to date, against the dist/ the build above wrote.
  • Gates: dispatch-gates --commands derived 79 families, the same 79 as stage 25. All 79 exit 0. --ran reconciles: 79 derived, 79 run, 0 NOT-MEASURED, 0 UNRUN, every family with its exit code recorded. The same 79 derive from origin/main 4e4e881427 with this diff applied. The five roster families marked as sharing a directory with this diff (check:meta-url-spelling, check:spec-changes, check:authz-resolver, check:error-code-casing, check:filter-alias-parity) each exit 0.
  • ESLint, a proven narrowing: --no-inline-config over the 18 files reads 0 errors and 0 warnings. The population comes from ESLint's own config: 18 configured, 0 ignored. No file sets parserOptions.project or projectService, so no untouched file's verdict can move.
  • check-governed-merges --test: NOT governed, 182 changed lines (+91 / -91).
  • A control-byte scan over the 18 changed files finds none.

main since the base

Re-fetched just before this PR opened, origin/main was three commits past the base (4e4e881427: #21976, #21977, #21352). They touch 490 files, none of the 18 and none under packages/spec/src/system/, so main was not merged. The census of 4e4e881427 with this diff applied reads 191 / 200, file for file the same as the head. git merge-tree onto 4e4e881427 is clean, and none of the 5 open PRs touches any of the 18 files.

Acceptance notes


Generated by Claude Code

…ed decision in words instead of a tracker number (stage 26)

Stage 26 of the spec lane's share of the runtime-string burn-down: the
test strings shipped under packages/spec/src, the first name-ordered
system/ group (auth-config.test.ts through
metadata-form-declared-rows.pin.test.ts, with
constants/system-names.test.ts in its path position).

91 literals in 18 files (83 test titles and 8 declared expect messages)
lose 97 tracker ids: 23 literals now state the cited decision in words,
11 get their subject back in words, and 57 drop a number the title
already explains. No needle sits in this group.

Text only: one line per literal, no assertion, identifier, test count,
code comment or file name changes.

Claude-Session: https://claude.ai/code/session_01T9u38rswFp5Rw8DswRUReJ
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 6, 2026
@github-actions

github-actions Bot commented Oct 6, 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 4e4e881427a8b8b57696ad5bdb12792f2dac6556 → packageMentionDocs.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 6, 2026 12:36
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 6, 2026 12:36
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 6, 2026
Merged via the queue into main with commit aa09db5 Oct 6, 2026
41 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20749-test-strings-q branch October 6, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

protocol:system 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