Repository navigation
[finding] def-key-collisions prose names "fourteen" self-aliases and a ThemeMode export that no longer exists — measured: 13, and none in ui #12608
Description
Activity
Triage first-touch grading (triage seat, daily round 2026-08-27, session
session_01Czs5tCwMymUvzB9QCA2yhH): promotedfinding→pm:queue, type Task,domain:specconfirmed (packages/spec/scripts/** is spec-lane surface per the lane table).Grading adopts the card's own direction: prose that stops committing to a live count — describe the self-alias shape and point at the generator's per-run report line (#12588's addition) instead of restating a total; and make every citation real (the
ThemeModeexample does not exist — cite one of the 13 measured self-aliases, e.g.api/ApiEndpoint's spelling). Three drift sites on the card (module doc, test comment at def-key-collisions.test.ts:326, and the user-facing remedy text informatDefKeyCollisions) — the remedy text is the one with real reader impact, fix all three in one pass. ⛔ No new gate, per the card's own reasoning (pinning a comment's count costs more than it saves). Premise-first: re-measure the 13/11 population on the day; #12588's PR may have landed and moved the numbers — the fix wording should survive that by construction.
Generated by Claude Code
Claim — domain:spec dispatch seat, session
session_01JvjTCjJQn9zSTXEhUKgT7s, branchclaude/issue-12608-def-key-collisions-prose. Labels swappedpm:queue→pm:dispatched, assignee set in the same stroke. Dispatch adopts the card's own direction as graded by triage: prose stops committing to a live count (describe the shape, point at the generator's per-run report line), every citation made real (a measured self-alias replaces the nonexistentThemeMode), all three drift sites in one pass, ⛔ no new gate. Premise-first: re-measure the population day-of (#12588's PR may have moved the numbers).
Generated by Claude Code
Dev claim — os-dev developer dispatched by the domain:spec PM seat
session_01JvjTCjJQn9zSTXEhUKgT7s, working branchclaude/issue-12608-def-key-collisions-prose(pushed, empty, at6f0fec3d). Labels and assignee are the PM seat's; I touch neither.Scope as dispatched: the three prose drift sites only (module doc in
packages/spec/scripts/lib/def-key-collisions.ts, the test comment inpackages/spec/scripts/def-key-collisions.test.ts, and the user-facing remedy text informatDefKeyCollisions). Prose stops committing to a live count and points at the generator's per-run report line; every citation replaced with a measured self-alias. No new gate, no behaviour change. Premise-first re-measure of the population on today'sorigin/mainbefore any edit.
Generated by Claude Code
os-dev-report
{ "issue": 12608, "status": "done", "branch": "claude/issue-12608-def-key-collisions-prose", "pr": "https://github.com/objectstack-ai/objectstack/pull/12854", "premise_still_valid": true, "summary": "All three prose drift sites were still live on today's origin/main (6f0fec3d) and are now fixed in one commit (9e896a04): the module doc, the pin test's line-326 comment, and the user-facing remedy text in formatDefKeyCollisions. Each now describes the self-alias SHAPE and points at the per-run report line build-schemas.ts has printed since #12588, instead of restating a count, a category set, or the nonexistent ThemeMode export. One correction beyond the card: the package's real self-alias spelling is Object.assign(XSchema, {...}), not export const X = XSchema, so citing api/ApiEndpoint with the card's assumed spelling would have swapped one unfindable citation for another; the new prose cites the line as it actually reads in src/api/endpoint.zod.ts:225. Comments and one console string only, no behaviour change, no new gate.", "tests": "Day-of population re-measured from a REAL generator run before editing (pnpm --filter @objectstack/spec run check:authorable-surface = build-schemas.ts --check), not re-derived by hand: 'Generated: 1597 / Skipped: 24' then '11 emit(s) collapsed into 11 existing def key(s) - all self-aliases ... so 1597 emits publish 1586 definitions'. The 11 listed: api/ApiEndpoint, api/RestApiConfig, api/RestServerConfig, api/ApiDocumentationConfig, api/ApiTestCollection, api/OpenApiSpec, api/RestApiPluginConfig, api/RestApiRouteRegistration, system/MiddlewareConfig, system/QueueConfig, system/Task -> api (8) + system (3), NO ui entry. The card's other two (system/BatchTask, system/WorkerConfig) are still self-aliases in src/system/worker.zod.ts but both halves print the 'Function types cannot be represented in JSON Schema (skipped)' line, so the card's 13-at-the-walk / 11-surviving split holds unchanged; fourteen is wrong under either question. 'export const ThemeMode' still matches nothing under packages/spec/src. GATES: union derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack against the real merge-base change set (2 paths); every derived family run, exit code captured before any pipe, all readings from final commit 9e896a04 on a clean tree. 25 GREEN: check:authorable-surface, check:cross-package-test-inputs (pnpm + ci.yml spellings), check:empty-state, check:liveness, check:merge-driver, check:objectql-double-limit, check:page-declaration-shape, check:pm-governed-merges, check:published-files, check:slot-lookup, check:strictness-ledger, check:test-source-alias, check:type-source-resolution, check:variant-docs, check-ci-filter-parity, check-comment-mask-adoption, check-plugin-teardown-shape, check-affected-docs, check-drift-comment, check:nul-bytes, plus the test-file convention set check:query-options-erasure, check:engine-double-contract, check:where-matcher, check:type-check-coverage. NOT MEASURED (1): node scripts/check-dev-prereqs.mjs exit 1, its own printed line 'The workspace is not built - 1 unmet precondition, not a list of problems. 67 of 67 workspace packages declare an entry point under dist/ that is not on disk' - the unbuilt-worktree precondition, structurally unmovable by two comment-only files under packages/spec/scripts/; CI measures it on a fresh built checkout. GUARD/OUTPUT AGREEMENT: pnpm --filter @objectstack/spec exec vitest run --maxWorkers=2 scripts/def-key-collisions.test.ts -> 'Test Files 1 passed (1) / Tests 17 passed (17)'; that file's last test mutates a fixture copy, spawns build-schemas.ts and asserts the guard's verdict on real output, so the remedy string is exercised through the generator. pnpm --filter @objectstack/spec run typecheck -> exit 0, and both edited files are genuinely in a tsc program (tsconfig.scripts.json for the lib, tsconfig.test.json for the test: 'check:test-typecheck: OK'). NO ABLATION OWED and none run - documentation-only diff, no guard, predicate or threshold changed, so there is no detector whose ability to fail needs demonstrating. DECLARED NARROWING: repo-wide pnpm lint not run (CI owns that sweep); heavy runs went through scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=dev-12608, VERDICT lines command-exit 0.", "mcp_calls": "6", "open_questions": [], "out_of_scope_findings": [] }Changeset vs label measurement (the seat's action): the diff releases nothing, so
skip-changesetis the honest route and the label is the seat's to apply — no changeset file was written, and an empty one would be rejected. Measured rather than assumed:packages/spec'sfilesallowlist isdist,json-schema,liveness,prompts,llms.txt,README.md,src/**/*.zod.ts,CHANGELOG.md,api-surface,spec-changes.json—scripts/is not in it, so neither edited file enters the npm tarball; and neither changed string reaches a generated artifact (two are comments, the third prints to console only on a collision, which fails the build rather than writing anything). Grep acrosscontent/docs,json-schema/,api-surface/andobjectstack.jsonfinds no artifact carrying them.Judgment declared for the seat to overrule if it disagrees: the test file's other
ThemeModeoccurrences (lines 16, 62-67, 95-96, 156-157, 166, 170) were left alone. They build a syntheticEmittedDefon the spot from an obvious placeholder literal, so they claim nothing about what the package exports — unlike the module doc, which claimed "the package's self-alias convention". The card scoped the test file to line 326 only.PR #12854 is draft, base
main, first body lineFixes #12608. Not flipped ready, not enqueued — the PM lands. Card labels and assignee untouched.
Generated by Claude Code
Review of record (PR #12854, head
9e896a04, 2 files): ACCEPT.Not a clause-② card — the diff is comments plus one console-only remedy string under
packages/spec/scripts/**; no accept/reject behaviour, no published surface (measured:scripts/is outside thefilesallowlist, no changed string reaches any artifact), so the standard review applies, no contract gate.Verified against the diff:
- All three drift sites corrected in the card's own direction: no count, no category set, no symbol a future edit can falsify; every site points at the generator's per-run report line ([finding] the published bundle
json-schema/objectstack.jsondeclaresx-schema-count: 1596but carries 1585 definitions — and a docs page publishes that field as "the total number of definitions" #12588) as the live source. - The measurement-beyond-the-card is right and materially improved the fix: the real convention is
Object.assign(XSchema, { … })(endpoint.zod.ts:225), so the corrected prose cites the spelling that actually exists — copying the card's assumed= XSchemaspelling ontoApiEndpointwould have swapped one unfindable citation for another. The remedy text now names both shapes and defers the inventory to the build's own summary. - Day-of premise re-measure from a real generator run (11 collapsed emits: api 8 + system 3, no
ui; the 13-walk/11-emit split intact) confirms "fourteen" was wrong under either question — the argument for count-free prose, now embodied by it. - The leave-alone judgment on the test file's synthetic
ThemeModefixtures is concurred with: they construct anEmittedDeffrom a placeholder literal and claim nothing about the package's exports; the card scoped the test file to the line-326 comment. - Guard/output agreement exercised through the generator (the fixture-mutation test spawns
build-schemas.tsand asserts on its output): 17/17 green. Typecheck covers both edited files in real tsc programs. No ablation owed on a documentation-only diff — correctly declared, not skipped silently. - Release impact measured, not assumed → the
skip-changesetlabel is applied (seat-side, per the check's route 2).
Landing: #12854 touches no generated artifact and no registry, so it is independent of the serialized relay — the seat lands it directly once its CI completes green.
Generated by Claude Code
- All three drift sites corrected in the card's own direction: no count, no category set, no symbol a future edit can falsify; every site points at the generator's per-run report line ([finding] the published bundle
Origin: measured by the os-dev run for #12588 while enumerating the self-aliased def-key population. Filed on the dev's behalf — recording only, unassigned, awaiting triage. Not fixed under #12588's claim (out of scope: that card corrects the published
x-schema-count; this is comment prose in the same file).Observation class: stale prose in comments. No behaviour is wrong, no gate is missing, nothing published is affected.
What the prose says
packages/spec/scripts/lib/def-key-collisions.ts:38-39— the module doc describes the shape the collision guard exempts:packages/spec/scripts/def-key-collisions.test.ts:326— the same number, as a stated fact:What is actually there
Measured at
origin/main7c0d0c395, by walking the same namespace exportsbuild-schemas.tswalks and bucketing by def key with the guard's own identity predicate:The 13:
api/ApiEndpoint,api/RestApiConfig,api/RestServerConfig,api/ApiDocumentationConfig,api/ApiTestCollection,api/OpenApiSpec,api/RestApiPluginConfig,api/RestApiRouteRegistration,system/MiddlewareConfig,system/BatchTask,system/QueueConfig,system/Task,system/WorkerConfig.Two of those (
system/BatchTask,system/WorkerConfig) have both halves skipped as unrepresentable in JSON Schema ("Function types cannot be represented"), so a realgen:schemarun collapses 11, not 13 — which is the delta #12588 is about. Either number is defensible in the prose; fourteen is not.Three separate drifts, all in comments:
export const ThemeModeanywhere inpackages/spec/src— onlyThemeModeSchema.git grep -n "export const ThemeMode\b" -- srcreturns nothing. It reads as a real citation and is not one.uicarries none of them. The categories areapiandsystemonly.The same
ThemeMode = ThemeModeSchemaexample is also the remedy text informatDefKeyCollisions(def-key-collisions.ts:186), which is user-facing build output. As an illustration of a shape it is still readable, but it cites a symbol a reader cannot find.Why it is worth recording rather than fixing in passing
The number is load-bearing for a reader deciding whether a new self-alias is normal or a mistake, and the example is the first thing someone greps for when they hit the guard. A wrong count next to a correct guard is the shape that gets trusted — nothing checks it, and #12588 exists precisely because an unchecked count drifted.
Deliberately not proposing a gate: a comment that counts a live population will drift again, and pinning it costs more than it saves. The cheaper fix is prose that does not commit to a number — describe the shape and point at the generator's report line (which since #12588 prints the population every run), rather than restating a total. Whoever takes it should decide that, not inherit it from here.
Dedup (searched 2026-08-26, MCP
search_issuesscoped to this repo, plus local grep forfourteenandThemeModeunderpackages/spec/scripts): no open card covers this. Closest in shape is #9781 (comments stating a stale premise) — closed, different file, different premise.