Repository navigation
test(spec): correct the row-update positive control's data-API path - #17581
Conversation
`action-row-update.test.ts`'s positive control spelled
`/api/v1/sys_api_key/{id}` — the pre-fix data-API path, missing the
`/data` segment, with a `{id}` placeholder that is `newTabUrl`'s
convention and is not substituted into `target`. The shipped door is
`PATCH {apiBase}/data/:object/:id` (`getApiBasePath()` + `crud.dataPrefix`,
default `/data`), and the twin docblock on `method` was corrected to
`/api/v1/data/sys_api_key/${ctx.recordId}`.
`target` is `z.string().optional()`, so the value carries no assertion
weight and nothing ever reddened. The cost is that the *positive control*
— the line a reader copies to learn the correct shape — taught the wrong
path with the authority of a passing test, and was the last live site in
`packages/**` spelling it.
Fixture string only. The schema is untouched: validating data-API paths
would be a new refusal on a published schema.
Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MkQhmuuJAVDjmeWNixwDDH
📓 Docs Drift CheckNothing 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): |
|
Seat acceptance — content reviewed, ①②③ read; ④ outstanding.
The diff is one line: ⭐ The round declined the card's alternative, and declined it for the right kind of reason. The card offered a second option — replace the path with something obviously illustrative so it can never be mistaken for a worked example — and the earlier triage comment noted it scores better on the anti-AI-error axis. The order allowed it only on a measurement showing option 1 to be actively misleading. The round measured and found the opposite: after this fix no source file under ⭐ The ablation this card actually owed was run, and it is the interesting half. The card's premise is that
⛔ Nothing is enqueued and no auto-merge is armed until ④ is green. Generated by Claude Code |
Fixes #15099
Clause-②: no — re-derived from what this ships, not inherited. The diff is one string literal inside a
.test.ts. No accept set moves (targetisz.string().optional()andActionSchemais untouched), no authorable key is added or removed, no closed-set member, no published export, no registry entry. C5 widening tells: none.What changed
One line —
packages/spec/src/ui/action-row-update.test.ts:156, the positive control of the row-level declarative-write suite:Two things were wrong with the old spelling, and both are corrected:
/datasegment. The shipped data door isPATCH {apiBase}/data/:object/:id—getApiBasePath()composed withcrud.dataPrefix, whose default is/data(packages/spec/src/api/rest-server.zod.ts:312). The fixture omitted it.targetdocuments${param.X}/${ctx.X}interpolation (action.zod.ts:985-1003); a bare{id}isnewTabUrl's convention and is never substituted here — themethoddocblock says so in as many words.The new value is byte-identical in shape to the corrected twin at
packages/spec/src/ui/action.zod.ts:1403, which PR #15098 landed.Direction
Taken from the newest triage comment, quoted rather than paraphrased:
The card's alternative — replace the value with something obviously illustrative — was not taken. That option was licensed only on a measurement that correcting the spelling is actively misleading, and the measurement says the opposite: after this change the fixture agrees byte-for-byte with its twin docblock at
action.zod.ts:1403, and no source file underpackages/**spells the pre-fix shape any more — the sole surviving occurrence is theCHANGELOG.mdhistorical record. A reader greppingsys_api_keyfor a worked example now finds one answer instead of two.Premise, falsified on this branch's own merge base (
f721ef0ff2)Readings taken on the source tree at the merge base, before any build. Occurrence counts, not line counts —
grep -o ... | wc -l, becausegrep -ccounts lines and would have made these readings void./api/v1/sys_api_keyacrosspackages/**before the fixaction-row-update.test.ts:156andpackages/spec/CHANGELOG.md:8775/api/v1/data/sys_api_keysys_api_keyoccurrences inside the edited filetarget's schemaz.string().optional()— no path validationpackages/spec/CHANGELOG.md:8775is a historical record and is not rewritten. It is the only place the old spelling survives, and a changelog is true about the past.The ablation this card owed: the fixture is INERT to the assertion
Three legs, same command, same file, same suite. Every mutation and every restore proven by state —
git hash-objectagainst the HEAD blob and an emptygit diff HEAD— never by an exit code. The mutating script carriedtrap restore EXIT INT TERMwith an absolute path, and each mutation was confirmed on disk by an anchoredgrep -cof both the injected and the removed text before the run.Leg 1 paired with leg 2 is the proof: an absurd path leaves 31/31 green, while breaking a value the same test actually asserts reddens exactly that test. Nothing pins the path string, so the card's premise stands and this is a commit rather than a report. It is also why this sat unnoticed: a positive control teaches with the authority of a passing test, and this one could never have failed.
Both legs restored; the working tree is clean and no ablation artifact is committed.
Changeset: measured, not asserted —
skip-changesetThe card argued the fixture does not publish. Measured on the built package rather than inferred from the glob:
npm pack --dry-run --jsonon a freshly built@objectstack/specenumerates 2011 files.src/ui/action-row-update.test.tsis absent; so is every other.test.ts(0 of 2011).src/ui/action.zod.tsis present ⇒ the absence above is a reading, not an empty corpus.the api and script forms are untouched) scores 0 occurrences across all 2011 published files, while a control token from published source (Supports ${param.X} and ${ctx.X} interpolation) scores 61 on the same corpus. No generated artifact —json-schema,api-surface,spec-changes.json,llms.txt,prompts,liveness,dist— re-authors the test file's content.CHANGELOG.md, the historical record this PR deliberately does not touch.Nothing already published moves ⇒ no changeset.
Verification
Run on the final commit
2b266a8ced.pnpm --filter @objectstack/spec exec vitest run --project local src/ui/action-row-update.test.tspnpm --filter @objectstack/spec testpnpm --filter @objectstack/spec typechecktsc --noEmit,check:scripts-typecheck,check:test-typecheck)tsc -p tsconfig.test.json --listFilesnames it 1x (control: 126src/ui/files in the same program) — so the typecheck above is not silently excluding itpnpm exec turbo run build --filter=@objectstack/spec --filter=@objectstack/formula --filter=@objectstack/lintpnpm lint(repo-wide,eslint . --no-inline-config)pnpm check:nul-bytesscripts/pm/dispatch-gates.mjs --commands)--ranreconciles 71 run green, 5 NOT MEASURED, 0 unrunThe dependency-closure build (
@objectstack/spec^...) is empty —packages/spechas no workspace dependencies — so that leg is vacuous here and the package was built directly instead.Declared to CI, NOT MEASURED locally (exit 3,
PREREQUISITE NOT MET, each needs the whole repo built):check:dts-closure,check:dual-build-cjs-loads,check:lean-entry-closure,check:sourcemap-no-sources-content,check:type-check-debt. Six further gates first read as non-zero for the same reason and are green after the build:check:api-surface,check:browser-reachable-entries,check:dual-source-exports,check:entry-nameability,check:exported-any,check:doc-formula-expressions. None is recorded as a red.验收备注
Fences held.
ActionSchemais untouched;packages/spec/CHANGELOG.mdis untouched; the three sibling rounds' surfaces (zod-issues-to-fields.ts,search-fields.ts,contracts/**) are untouched. The live fence on this file was checked directly: the edit is thetargetliteral in a.successpositive control, not a union-branch author-visible message pin — the message-pinning assertions elsewhere in the file are unchanged.No out-of-scope findings were filed. One observation, noted and deliberately not filed:
recordIdParam: 'id'sits beside the correctedtargetin the same fixture and is equally inert to the assertion, but it is a separate key with its own meaning rather than part of the path, so correcting it was outside the licensed diff and there is no evidence it is wrong. Carrier if it ever matters: whichever PR next revisits this fixture — currently none.Generated by Claude Code