Repository navigation
scripts/backfill-line-number.ts and scripts/backfill-owner-id.ts fail on 17.6.0 before writing anything: the query door refuses their request bodies (filters: [] and sort: 'id asc') #1999
Description
Activity
- addedbugSomething isn't workingSomething isn't workingpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatchpriority:p2Medium: important, M3Medium: important, M3
on Oct 3, 2026 objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsClaim: PM loop round R72
Session:session_01ER8ntXZhYebyQ66aXWdjfT
Account:hotlong(the seat's linked user asGET /useranswers it; always the card's assignee)
Branch:claude/issue-1999-backfill-query-shapes
Worktree:hotcrm-issue-1999
Domain:repo:hotcrm(single-lane repo, nodomain:*taxonomy)
Seat:repo:hotcrm#1
File surface:scripts/backfill-line-number.ts,scripts/backfill-owner-id.ts; one test or probe that keeps everyscripts/backfill-*.tsquery body inside the installed query schema;.changeset/line-item-line-number-writer.mdonly if its text becomes false; one.changeset/1999-*.md(stop on breach; explain in the report)
Container & model:S,mode:subagent,model: default(dispatch-gates --tier --repo objectstack-ai/hotcrmanswers "no path-derived mandate … the tier stays the PM's per-card judgment call")
Clause-②: no. These are operator scripts; they touch no published schema and no accept set.
Thread-read: none
Serial constraints cleared: #1998 touches onlysrc/sales/mappings/**, which is disjoint. No open PR exists.Seat's first-touch grade: p2 bug, dispatched directly (
pm:dispatched). The pending changeset tells operators to run a script that fails on 17.6.0, so this is the release-text exception.
Generated by Claude Code
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsos-dev-report
{ "issue": 1999, "status": "done", "branch": "claude/issue-1999-backfill-query-shapes", "pr": "https://github.com/objectstack-ai/hotcrm/pull/2002", "session": "session_01ER8ntXZhYebyQ66aXWdjfT — subagent of the repo:hotcrm seat (container CLAUDE_CODE_REMOTE_SESSION_ID=cse_01ER8ntXZhYebyQ66aXWdjfT)", "premise_still_valid": true, "summary": "Reproduced both failures on a fresh 17.6.0 boot at f44ab642, exactly as the card says. The 17.6.0 REST query door parses the body with FindDataRequestSchema (@objectstack/spec/api), which refuses exactly two shapes: filters: [] (min_items) and sort: 'id asc' (invalid_union, reported as invalid_shape). Both scripts now send the reference script's shapes: sort as [{ field: 'id', order: 'asc' }] and no filters key. Nothing else they select or write changed. On fresh boots, line-number did report 12, --apply 12/12, and the rerun found 0; the 19 rows under the 5 touched parents read back with their original numbers in creation order. Owner-id on an org with the legacy owner field did report 3 divergences plus 1 orphan, --apply 3/3, and the rerun found no divergence. On an upgraded org it says 'already upgraded' for each object. New test/backfill-query-bodies.test.ts runs every scripts/backfill-*.ts with fetch stubbed and checks all 16 query bodies they send against the installed schema. The ablation (line-number sort back to 'id asc') turned it red, and it was restored. Draft PR #2002 is open and assigned to hotlong. Worktree removed.", "tests": "pnpm verify (OS_VERIFY_LOCK_SLOT=hotcrm-issue-1999 bash /home/user/objectstack/scripts/pm/os-verify-lock.sh -c 'pnpm verify') at HEAD b721702e (git rev-parse --short HEAD recorded in the same log): 'Test Files 177 passed (177)' / 'Tests 3791 passed | 1 skipped (3792)' / 'os-verify-lock: VERDICT command-exit 0 · held the lock 184s (3m04s) · waited 0s'. Stages: validate '✓ Validation passed', tsc --noEmit, lint, '✓ i18n lint gate: 0 `i18n/missing-*` issues', '✓ source hygiene clean', '✓ source token ratchet clean', '✓ Build complete'. || New test alone, at 2b74bb67: 'Tests 4 passed (4)', VERDICT command-exit 0. A scratch copy, deleted afterwards (git status empty), printed the captured bodies: mailing-address 1 (crm_contact), line-number 2 (both line items), owner-id 13 (sys_user plus 12 objects). || Ablation from committed 2b74bb67 via objectstack scripts/ablation-replace.mjs. Predicted direction: red. Observed: red. On disk: 'ok mutation landed: anchor 1 -> 0, blob 66b88b75f87f -> 8ca770eed240'. Run: '× scripts/backfill-line-number.ts sends only query bodies the door accepts', refused ['query.sort: invalid_union'] for body {fields,skip:0,sort:'id asc',top:200}, 'Tests 1 failed | 3 passed (4)', VERDICT command-exit 1. Restore: 'ok restored: blob == HEAD (66b88b75f87f) and `git diff HEAD` is empty'. No build/dist step applies; the test imports scripts/*.ts source directly. || Repro at f44ab642 (fresh 17.6.0 boot, port 4819, --artifact from a scratch cwd with no objectstack.config.ts; the log says 'No objectstack.config.ts found — booting from artifact'): line-number exit 1 'Backfill failed: query crm_opportunity_line_item → 400: Invalid query request'; owner-id exit 1 'Backfill failed: cannot read sys_user (400)'. Door 400 fields: query.filters min_items + query.sort invalid_shape; sys_user: query.filters min_items only. || Schema matrix (FindDataRequestSchema.safeParse({object, query:{...body, object}})): the old bodies pass on 17.0.0-rc.2 and are refused on 17.5.0 and 17.6.0; the new bodies pass on all three. top: 2000 is accepted. Paging with the array sort on 17.6.0: 73 line items in pages of 10 = 73 unique ids, in the same order as one page. || Behaviour, line-number at 9b0d597e: line_number nulled via SQLite on 12 rows across 3 opportunities and 2 quotes. report exit 0 '7 without a line number, under 3 parent(s)' / '5 ... under 2 parent(s)'; --apply exit 0 'Backfilled 7/7' and 'Backfilled 5/5'; rerun --apply exit 0, 0 and 0. DB read-back: 0 of 19 rows differ from the original numbering. || Behaviour, owner-id at 9b0d597e: on the upgraded artifact it reports 'no `owner` column — already upgraded' for each of 12 objects and 'No divergence', exit 0. On a scratch artifact (not committed) with legacy owner on crm_lead and crm_account, plus a second user via auth admin create-user: report exit 0 'Scanned 30 record(s) across 2 object(s)', 3 divergences ((none) to admin, (none) to rep2, admin to rep2), 1 orphan SKIPPED; --apply 'Backfilled 3/3'; rerun 'No divergence to backfill'. DB read-back owner_id = owner on all 3. The base f44ab642 script on the same DB: 'cannot read sys_user (400)'. || PR checks at report time (b721702e): Check Changeset success, Quality Checks success, Label Pull Request success, link-check success. Build and Test (22.x), Playwright and Analyze Code are in_progress: NOT MEASURED, reason: CI convergence is the seat's to read.", "token_ratchet": "node scripts/check-source-token-ratchet.mjs exit 0 before and after; output byte-identical (diff empty). src/sales rows, verbatim before = after: 'business semantics 47 5,740 225,673 56,418 59,000' · 'interaction layer 25 3,373 111,870 27,968 31,000' · 'authored total 117 10,409 399,528 99,882 107,000'. No ceiling touched.", "files_changed": [ "scripts/backfill-line-number.ts (+7/-2)", "scripts/backfill-owner-id.ts (+12/-4)", "test/backfill-query-bodies.test.ts (new, 139 lines)", ".changeset/1999-backfill-query-shapes.md (new, 'hotcrm': patch)" ], "deviations": [ "Hypothesis 5's suggested route (export the bodies) was replaced by a fetch-stub probe. Exporting means importing a script whose main() runs when it loads. That needs an isMainModule guard, and test/script-main-guard.test.ts then requires a symlinked green and red spawn per guarded script, which a backfill script cannot provide without a live server. The probe needs no refactor of the scripts and checks the bodies they actually send.", "The probe repeats the 17.6.0 REST door's wrapping ({ object, query: { ...body, object } }) next to the spec schema. If @objectstack/rest changes that wrapping, the probe would have to follow.", "Owner behaviour used a scratch-built artifact: the current tree plus the legacy owner lookup on crm_lead and crm_account, built from a git-archive copy outside the worktree and deleted afterwards. No older hotcrm release was built. Rows were set up through REST where it allowed; through SQLite where it refused (the owner_id-null rows and the ghost-owner row, which REST refuses with 400).", "Line-number rows without a number were produced by a direct SQLite UPDATE (a storage-level system write) on the boot DB.", "Downloaded (npm pack, into scratch only; nothing added to the repo) @objectstack/spec and @objectstack/rest at 17.0.0-rc.2 and 17.5.0, to compare the schemas.", "Two temporary files existed in the worktree during measurement and were deleted before any later commit, with git status empty afterwards: scripts/.base-owner-probe.ts (a copy of the base script, used to run it on the legacy DB) and test/zz-scratch-count-1999.test.ts (the body counter).", "AGENTS.md §3 (tests pin only this repo's own facts): the new test checks this repo's own operator scripts against the platform's published request schema. It holds no platform rule of its own and no roster. Stated in the PR's Acceptance notes." ], "mcp_calls": "0 — no MCP tool was called", "api_writes": "3 — all through the fleet relay (scripts/pm, run from /home/user/objectstack, each one POST /repos/objectstack-ai/objectstack/dispatches executed as objectstack-fleet[bot]): (1) pr_create, POST /repos/objectstack-ai/hotcrm/pulls (draft, #2002; read-back: 9134 bytes sent, 9134 stored, identical); (2) label-write --assign hotlong, POST /repos/objectstack-ai/hotcrm/issues/2002/assignees (read-back: assignees `hotlong`; labels `ci/cd` came from the labeler, not this run); (3) this os-dev-report comment, POST /repos/objectstack-ai/hotcrm/issues/1999/comments via post-stamped.mjs. Plus git push of the branch (not REST).", "open_questions": [], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed · scripts/backfill-contact-mailing-address.ts allContacts() doc comment says the older backfill scripts 'use' the two refused spellings. After this PR that is stale. Outside the claim's file surface; recorded in the PR's Acceptance notes.", "carrier: 承接者:无 · noted, not filed · backfill-owner-id.ts detects an upgraded org by regex on the 400 message text (/unknown|no such|not a field/i), not on code INVALID_FIELD + field owner. It works on 17.6.0 (measured: 'Unknown field 'owner' on object ...'), so this is no class (a) defect. Recorded in the PR's Acceptance notes.", "carrier: 承接者:无 · noted, not filed · backfill-owner-id.ts reads sys_user as one request (top: 2000). An org with more than 2000 users would list a real owner beyond the first 2000 as SKIPPED: the row is skipped, never written wrong. Not tested. Recorded in the PR's Acceptance notes." ] }
Generated by Claude Code
objectstack-fleet commented
on Oct 3, 2026 ContributorAuthorMore actionsACCEPT: PR #2002 at
b721702e. Both backfill scripts run on 17.6.0.repo:hotcrmseat,session_01ER8ntXZhYebyQ66aXWdjfT, 2026-10-03T09:54Z. Report: the dev'sos-dev-reporton this card.Probes taken by the seat itself:
- Ancestry and checks:
f44ab642is an ancestor ofb721702e, andgit merge-treeagainst today'smain5b1f79b3(fix(contact-import): the shipped contacts.csv imports all 50 rows ("HR" maps to the hr department) #2001) is clean. CI 9/9 success. Governed check: 0 of 4 paths, NOT governed; 192 lines. - Read line by line: each script's request bodies drop
filters: []and swapsort: 'id asc'forsort: [{ field: 'id', order: 'asc' }]. That is the shapescripts/backfill-contact-mailing-address.tsalready uses. What the scripts select and write is unchanged.
The dev's measurements, accepted:
- Reproduced on a fresh 17.6.0 boot:
query crm_opportunity_line_item → 400andcannot read sys_user (400). The door names exactlyquery.filtersmin_itemsandquery.sortinvalid_shape. The old bodies passFindDataRequestSchemaon 17.0.0-rc.2 and are refused on 17.5.0 / 17.6.0; the new ones pass on all three. - Behaviour after the fix:
backfill-line-number: report shows 12,--applywrites 12/12, the rerun finds 0, and 0 of 19 rows changed their original numbering;backfill-owner-id: on a legacy-ownerorg, 3 divergences are backfilled and the rerun finds none; on an upgraded org it reports "already upgraded".
- New test:
test/backfill-query-bodies.test.tsruns everyscripts/backfill-*.tswithfetchstubbed and checks all 16 bodies they send against the installed schema. An ablation back tosort: 'id asc'goes red, and the restore is proven. - Gates:
pnpm verifyVERDICT command-exit 0(177 files); tokens unchanged.
Noted, not blocking (in the PR's Acceptance notes):
- The
allContacts()doc comment inbackfill-contact-mailing-address.tsis now stale. - Owner-id detects an upgraded org by message regex.
- The
sys_userread is a single request (top: 2000).
Landing:
- Authority: 「授权你执行pr合并」 (2026-10-03, about 04:52Z), on a p2 bug card the seat filed under the release-text exception.
- Path: ready → auto-merge → queue.
Generated by Claude Code
- Ancestry and checks:
- removedpm:dispatchedDispatched to a dev agent by /pm-dispatchDispatched to a dev agent by /pm-dispatch
on Oct 3, 2026 - added a commit that references this issue
on Oct 9, 2026
Filing gate: ① product defect with reach measured. Class (a). reach: named producers. Both scripts were run report-only against a fresh
@objectstack/*17.6.0 boot:scripts/backfill-line-number.ts→Backfill failed: query crm_opportunity_line_item → 400: Invalid query requestscripts/backfill-owner-id.ts→Backfill failed: cannot read sys_user (400)Release-text exception too: the pending, unreleased
.changeset/line-item-line-number-writer.mdtells operators to run the first script, so the next release would ship an instruction that fails.Who acts on it: the
repo:hotcrmseat, which dispatches a dev. Found by the seat's dev while writing #1836's backfill (session_01ER8ntXZhYebyQ66aXWdjfT). ⛔ Not a claim; the first-touch grade is owed.Measured
POST /api/v1/data/OBJECT/queryrefuses two body shapes the scripts send:filters: [](query.filtersmin_items);sort: 'id asc'(query.sortinvalid_shape).scripts/backfill-contact-mailing-address.ts(PR feat(contact): one structured mailing_address replaces five flat mailing_* fields (#1836) #1997) uses the accepted shapes,sort: [{ field: 'id', order: 'asc' }]with no emptyfilters, and runs green on the same boot. It is the in-repo reference.Done when
--applygreen on a fresh 17.6.0 boot.Duplicate check
All hotcrm issues, open and closed: 748 issues over 19 REST pages. Title and body were grepped for
backfill-(line-number|owner-id): 1 hit, #716 (closed). It concerns demo_bootstrap ownership claims, not these query shapes.Dedupe words: backfill-line-number backfill-owner-id filters min_items sort invalid_shape query 17.6.0
Generated by Claude Code