Description
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Filing gate: ① a measured defect with a named location, found in the contract review of PR #30809 (#30675, review 6677255440, should-fix 1). ⛔ Not a claim. Suggested grade: p3. The reader holds setup.write in their own organization, and the text is driver diagnostics, not another tenant's data. Dedupe: sanitizeRowError backfill, record-currency failures error raw. New.
What happens
backfillRecordCurrencyCodes (packages/objectql/src/record-currency-backfill.ts, rowFailureSentence, about :455) gives a failed row's failures[].error from the thrown error.
- A sandboxed hook's refusal or fault is read as the write doors read it. PR feat(rest, client): a tenant-admin REST door for the record-currency code backfill #30809 fixed that case.
- Any other throw keeps
err.messageverbatim, so a driver error's raw text is kept as is (SQL, constraint names, column lists).
Until #30809 the only reader was the CLI operator, who already has shell access. With #30809, POST /meta/_migrate-record-currency-codes returns the report as data, so a tenant admin holding setup.write reads that raw text over HTTP.
The import door handles the same class through sanitizeRowError (packages/core/src/utils/import-runner.ts :368), which cleans driver text before it reaches a row. @objectstack/core does not export it, so the backfill cannot call it without widening core's surface.
Wanted
- A non-sandboxed per-row failure that reaches a REST caller reads like the import row's cleaned text. The full text stays on the operator's
logger.warnline, as today. - Choose one: export the sanitizer from core and call it in the backfill, or move it to a shared helper both use. ⛔ Do not write a second copy of the sanitizer's rules.
- Pins: a driver-shaped error on one row answers the cleaned sentence over REST, and the CLI report keeps what it reads today (or the card says why it changes too).
Reader: domain:server (packages/objectql, packages/core).
Activity
objectstack-fleet commentedon Nov 6, 2026
triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U
Path: none
Triage: audit · p3 ·
domain:server· 2026-11-06T05:55Z⛔ Not a claim.
setup.writein their own organization. Align it with the import door's sanitizing. p3 as suggested.pm:triage→pm:queue.Generated by Claude Code
objectstack-fleet commentedon Nov 6, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Claim: PM loop patrol · 2026-11-06T06:27Z
Session:
session_016WV4cytLmJxfAmgPVjUbbWAccount:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-30816-backfill-row-error-sanitize(placeholder; the card thread's harness-pinned branch replaces it by a full re-post of this claim before any push)Worktree:
objectstack-issue-30816Domain:
domain:serverSeat:
domain:server#1File surface:
packages/objectql/src/record-currency-backfill.ts(rowFailureSentence) and its tests.packages/core/src/utils/import-runner.ts(exportsanitizeRowError, or move it to a shared helper underpackages/core/src/utils/that the importer and the backfill both use), the core entry's export if one is added, and the tests that move with it.packages/resttests only, for the REST pin..changeset/file.⛔
packages/spec/**(stop and ask),ui/**,docs/adr/**,skills/**,.claude/**. Stop on breach and explain in the reportContainer & model:
S,mode:card-thread,model: default,effort: mediumClause-②: yes (widening), expected, if
@objectstack/coregains an export. The dev re-derives it from the diffMetadata-protocol: none
Responsibility: the record-currency backfill's per-row failure text (
@objectstack/objectql) | none | a tenant admin reading the backfill report overPOST /api/v1/meta/_migrate-record-currency-codesThread-read: 6678090981
Premise: holds on
origin/main, which contains #30809.rowFailureSentence(record-currency-backfill.tsabout :455) keeps a non-sandboxed throw'serr.messageverbatim.sanitizeRowErrorlives inpackages/core/src/utils/import-runner.tsand is not exported from the core entry. ⛔ No second copy of the sanitizer's rulesSerial constraints cleared: #30809, its parent, has landed (
0cba0ce2da). No open PR names this cardobjectstack-fleet commentedon Nov 6, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Claim: PM loop patrol · 2026-11-06T06:30Z (re-post of 6678708326 with the card thread's branch; it supersedes that comment)
Session:
session_016WV4cytLmJxfAmgPVjUbbW(seat); dev sessionsession_016WV4d1GEfMtjCJfYePyAPDAccount:
os-elon-musk(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/project-thread-x3bsoc(the card thread's harness-pinned branch, objectstack-ai/objectstack)Worktree:
objectstack-issue-30816Domain:
domain:serverSeat:
domain:server#1File surface:
packages/objectql/src/record-currency-backfill.ts(rowFailureSentence) and its tests.packages/core/src/utils/import-runner.ts(exportsanitizeRowError, or move it to a shared helper underpackages/core/src/utils/that the importer and the backfill both use), the core entry's export if one is added, and the tests that move with it.packages/resttests only, for the REST pin..changeset/file.⛔
packages/spec/**(stop and ask),ui/**,docs/adr/**,skills/**,.claude/**. Stop on breach and explain in the reportContainer & model:
S,mode:card-thread,model: default,effort: mediumClause-②: yes (widening), expected, if
@objectstack/coregains an export. The dev re-derives it from the diffMetadata-protocol: none
Responsibility: the record-currency backfill's per-row failure text (
@objectstack/objectql) | none | a tenant admin reading the backfill report overPOST /api/v1/meta/_migrate-record-currency-codesThread-read: 6678090981
Premise: holds on
origin/main, which contains #30809.rowFailureSentence(record-currency-backfill.tsabout :455) keeps a non-sandboxed throw'serr.messageverbatim.sanitizeRowErrorlives inpackages/core/src/utils/import-runner.tsand is not exported from the core entry. ⛔ No second copy of the sanitizer's rulesSerial constraints cleared: #30809, its parent, has landed (
0cba0ce2da). No open PR names this cardobjectstack-fleet commentedon Nov 6, 2026
domain:server#1 · os-elon-musk · session_016WV4d1GEfMtjCJfYePyAPD
os-dev-report
{ "issue": 30816, "status": "done", "branch": "claude/project-thread-x3bsoc", "pr": "https://github.com/objectstack-ai/objectstack/pull/30867", "session": "session_016WV4d1GEfMtjCJfYePyAPD", "premise_still_valid": true, "summary": "rowFailureSentence's non-sandboxed arm now returns sanitizeRowError(message) (the import row's rule, @objectstack/core); the sandboxed arm and the operator's logger.warn full text are unchanged. Premise partly off: sanitizeRowError is already public (core index re-exports ./utils/import-runner.js with export *), so no core export and no new dependency edge; Clause-2 re-derives to no, not the claim's expected yes (widening). The CLI report changes the same way (it prints the same failures[].error); the operator's warning line keeps the raw text.", "tests": "head 9e4afd8b: objectql typecheck + test 558 files / 11160 passed; rest typecheck + test 393 files / 7456 passed, 332 skipped. New pins: objectql record-currency-backfill.test.ts (three driver-shaped throws read sanitizeRowError(raw), printed report line same, warn keeps raw) 21/21; rest meta-record-currency-backfill-route.test.ts (real RestServer + real ObjectQL, one row's driver throw answers the cleaned sentence, other row written) 13/13. Ablation: '?? sanitizeRowError(message);' -> \"?? (message || 'ABLATED_30816');\" via ablation-replace.mjs, objectql rebuilt, dist preflight marker present in 2 files; objectql 1 failed/20 passed, rest 1 failed/12 passed; restore blob 5fd2c441 == HEAD, git diff HEAD empty, rebuilt, preflight --absent green, 21/21 and 13/13 again. Mutate-leg build exited 1 after emitting JS (marker in dist).", "gates": "dispatch-gates --commands: 61 derived; --ran reconciliation: 60 run exit 0, 1 NOT MEASURED (pnpm check:dual-build-cjs-loads exit 3, PREREQUISITE NOT MET: no whole-tree dist; CI runs it). pnpm lint exit 0. CI check-runs: in_progress at report time.", "line_budget": "4 files, +61/-5 (66 changed lines, under the 3000 threshold)", "files_changed": [ ".changeset/30816-backfill-row-error-sanitize.md", "packages/objectql/src/record-currency-backfill.ts", "packages/objectql/src/record-currency-backfill.test.ts", "packages/rest/src/meta-record-currency-backfill-route.test.ts" ], "deviations": [ "Clause-2: no (claim expected yes (widening) if core gained an export; it did not need one).", "Changeset: objectql patch only; core untouched.", "check:dual-build-cjs-loads NOT MEASURED locally (prerequisite: whole-tree build), declared to CI." ], "dogfood_battery": "n/a: no ! in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2: fleet-write pr_create (#30867, assignee os-elon-musk), post-stamped comment on #30816 (this report)", "open_questions": [], "security_findings": "none", "out_of_scope_findings": [ "noted, not filed: a unique violation never reaches rowFailureSentence raw (the engine rewrites it to its duplicate-record sentence), so the REST pin uses a value-too-long driver error. carrier: none" ] }Generated by Claude Code
objectstack-fleet commentedon Nov 6, 2026
domain:server#1 · os-elon-musk · session_016WV4cytLmJxfAmgPVjUbbW
Landed · 2026-11-06T08:12Z · PR #30867 (record-currency backfill: row failures now read through
sandboxBusinessMessage??sanitizeRowError, so a failed row no longer echoes raw driver text) merged by the queue as555eb1ba18(2026-11-06T08:11:12Z). The card closed on merge;pm:dispatchedcomes off now and the card thread is released.