Repository navigation
fix(objectql): the record-currency backfill cleans a driver's raw text out of a failed row, as the import door does - #30867
Conversation
…t out of a failed row A non-sandboxed row failure now reads sanitizeRowError's sentence, the import door's rule, in the report the REST door returns; the operator's log line keeps the whole text. Co-authored-by: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1GEfMtjCJfYePyAPD
📓 Docs Drift Check1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 21 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 05b46a2e773d5f9e8e9074a95c60971c86e46b1e && git checkout 05b46a2e773d5f9e8e9074a95c60971c86e46b1e
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 042efb7f12e935c913d1d6e323d2101827c78998 9e4afd8b1ac350539c472596a057ca754bfeeb91 && git checkout -B drift-repro 042efb7f12e935c913d1d6e323d2101827c78998 && git merge --no-ff 9e4afd8b1ac350539c472596a057ca754bfeeb91
node scripts/docs-audit/affected-docs.mjs --json 042efb7f12e935c913d1d6e323d2101827c78998 |
|
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW 席位核对 · ACCEPT · 2026-11-06T07:48Z · #30816Head-sha: 9e4afd8
|
Requested by Elon · project thread
domain:server#1 · os-elon-musk · session_016WV4d1GEfMtjCJfYePyAPD
Fixes #30816
Clause-②: no
Metadata-protocol: none
Claim: comment 6678760289 (branch
claude/project-thread-x3bsoc).维护者速读
POST /api/v1/meta/_migrate-record-currency-codes与os migrate record-currency-codes)报告里失败行的错误文字,非沙箱钩子的报错现在先经导入入口同一个清洗函数sanitizeRowError再返回。setup.write的租户管理员,数据库驱动的原始报错(SQL 语句、约束名、列名)会原样外露;导入入口早已清洗同类报错。packages/objectql/src/record-currency-backfill.ts(rowFailureSentence的最后一行)、packages/rest/src/meta-record-currency-backfill-route.test.ts(REST 钉)。pnpm --filter @objectstack/objectql exec vitest run src/record-currency-backfill.test.ts,预期 21/21 通过。What changes
rowFailureSentence(@objectstack/objectql): a row whose write threw anything other than a sandboxed hook's error now readssanitizeRowError(message), the import row's rule from@objectstack/core, instead of the raw message. The sandboxed arm (the door's withheld sentence for a crash, the hook's own sentence for a refusal) is unchanged. The operator'slogger.warnline still carries the whole text.sanitizeRowErroris already public (packages/core/src/index.tsre-exports./utils/import-runner.jswithexport *;@objectstack/resttests already import it from@objectstack/core), and@objectstack/objectqlalready depends on@objectstack/core. So the card's premise that core does not export it does not hold, andClause-②re-derives tonoinstead of the claim's expectedyes (widening). ⛔ No second copy of the sanitizer's rules.failures[].errorthroughformatRecordCurrencyBackfillReport. The operator loses nothing: the CLI routeslogger.warnto its warning line (stderr under--json), which keeps the raw driver text.Why
Since #30809 the backfill report is also the REST answer of
POST /meta/_migrate-record-currency-codes, read by a tenant admin holdingsetup.write. A driver's error kept its SQL statement, constraint name and column list verbatim in that answer, while the import door cleans the same class. Contract review 6677255440, should-fix 1.Tests
packages/objectql/src/record-currency-backfill.test.ts: three driver-shaped throws (anupdate ... - REASONstatement, a SQLite UNIQUE failure, aninsert ... - FOREIGN_KEY_REASONstatement) each readsanitizeRowError(raw)in the report and none of the driver's names; the printed report line reads the same sentence; the warning line keeps the raw text. The existing CONTROL (a plain message with no driver text) still reads as before.packages/rest/src/meta-record-currency-backfill-route.test.ts: on the realRestServerroute over a realObjectQLengine, the driver throws a driver-shaped error for one row of the caller's organization; the answer is 200, the other row is written, and the failed row carriessanitizeRowError(raw)with no SQL, column or placeholder text.rowFailureSentenceraw, because the engine already rewrites it into its own duplicate-record sentence. The REST pin therefore uses a value-too-long driver error.Ablation (restored, blob equal to HEAD, git diff HEAD empty)
?? sanitizeRowError(message);to?? (message || 'ABLATED_30816');viascripts/ablation-replace.mjs, objectql rebuilt,ablation-dist-preflightfound the marker in 2 built files (the REST suite reads objectql'sdist/).5fd2c441equals HEAD,git diff HEADempty, objectql rebuilt, preflight--absentgreen, both files green again (21/21, 13/13).Acceptance notes
sanitizeRowErrorkeeps the trailing reason of a... - REASONdriver message when the reason is not itself SQL, so a reason such asvalue too long for type character varying(3)is still shown. That is the import door's existing reading, applied here unchanged.Verification
All on head
9e4afd8b:pnpm --filter @objectstack/objectql typecheckandtest: 558 files, 11160 tests passed.pnpm --filter @objectstack/rest typecheckandtest: 393 files, 7456 passed, 332 skipped.node scripts/pm/dispatch-gates.mjs --commands: 61 families derived;--ranreconciliation: 60 run with exit 0, 1 NOT MEASURED (pnpm check:dual-build-cjs-loads, exit 3, PREREQUISITE NOT MET: the whole tree has nodist/; CI runs it on a full build).pnpm lint: exit 0.Human Minimum
packages/specholds no runtime logic. (not touched)pnpm lintpasses.main, one pull request.packages/spectouched: not touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code