Repository navigation
docs(changeset): correct the objectql release note for the set-rooted predicate delete walk - #27288
Conversation
The pending objectql release note for the predicate delete walk listed a by-id delete's probe filters as unchanged, left out the count and hook change for a matched row another matched row cascades into and the change in which refusal is reported, and gave an example the old walk did not show. Correct those sentences; the level and both declaration lines stay. Claude-Session: https://claude.ai/code/session_01Utp6CXc5hequf76uJfzrdK Co-authored-by: Claude <noreply@anthropic.com>
…hed row cascades into A predicate delete walks its matched rows as one set, so a matched row that another matched row's cascade reaches is removed by the predicate's own id-set delete: the count includes it and its delete hooks fire once. The pending release note states this; the test holds it. Claude-Session: https://claude.ai/code/session_01Utp6CXc5hequf76uJfzrdK Co-authored-by: Claude <noreply@anthropic.com>
… and name the nested delete Claude-Session: https://claude.ai/code/session_01Utp6CXc5hequf76uJfzrdK Co-authored-by: Claude <noreply@anthropic.com>
📓 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): |
Contract reviewServed-tier: Face: the ① Derived judgmentsEach rewritten sentence, before → after, against the review's three findings:
The title, the ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS Generated by Claude Code |
席位核对 — ACCEPT ·
|
Requested by Bill · project thread
Fixes #27201
Clause-②: yes (widening) — unchanged from the landed changeset; the review 6466053903 found the line right and this card keeps it.
Metadata-protocol: none
维护者速读
@objectstack/objectql待发布说明.changeset/27004-predicate-delete-walk-as-set.md里三处与代码不符的说法,并加一条测试钉住其中一项行为。引擎代码一行未动。patch和两行声明保持不变。回滚即 revert 本 PR,说明退回旧的错误文本。.changeset/27004-predicate-delete-walk-as-set.md新增的三条要点和Clause-②:行里改过的例子;②packages/objectql/src/engine-cascade-delete-atomic.test.ts新增的一条用例。pnpm --filter @objectstack/objectql exec vitest run src/engine-cascade-delete-atomic.test.ts,预期 20 条全过。Check Changeset对只改现有 changeset 的 PR 按设计保持红(非必需检查,不打skip-changeset),改正的书面确认由席位写在本 PR 上。What changes
The pending changeset of #27073 (card #27004) becomes the
@objectstack/objectqlrelease note when Version Packages (#26517) lands. The post-landing contract review of #27073 (comment 6466053903) found the engine right and three statements of the note false. This PR corrects those statements and changes nothing else in the note: thepatchlevel, the title, theClause-②: yes (widening)andMetadata-protocol: nonedeclarations, and the Before, Now (one qualifier added) and Who-sees-it bullets stay.collectCascadeDeleteSetprobes the records found at one depth together, per object and relation, andrefuseRestrictsInsideOwnCascadeprobes together the members asking one relation. With two or more records this sends$in, one probe per 500 records, or on a multiple lookup the OR of each id's$contains(referenceProbeFilterOfSet). The root's own probe and each cascaded child's own walk still send that one record's filter: a batch of one isreferenceProbeFilter, and a child is deleted through its own by-iddelete(), which joins the set and walks one id.deleteMany. The set walk enters every matched id before the first nesteddelete(), so the cascade skips it. The count the predicate delete returns now includes that row, and itsbeforeDelete/afterDeletehooks fire once, from the per-row dispatch. Before, the cascade's nesteddelete()removed the row ahead ofdeleteMany, so the count left it out, and its hooks fired a second time from that nested delete. The new bullet also notes that a flow'sdelete_recordhands this count on as itsresult(crud-nodes.ts).restrictcheck for every matched root before the walk starts. So when two relations refuse different matched rows, it reports the first relation's refusal. Before, it reported the first matched row's refusal.Clause-②:line said the row-by-row walk refused a report and its manager (arestrictself-lookup, both matched) "or not, depending on which row it met first". It refused in either order, and the line now says so. TheClause-②: yes (widening)declaration at the start of the line is unchanged.The Now bullet's "
cascadedeletes (each child through its own delete, hooks and all)" now says "each child the predicate did not match". Without that qualifier it would contradict item 2.Tests
packages/objectql/src/engine-cascade-delete-atomic.test.ts: counts a matched row another matched row cascades into, and fires its delete hooks once (objectql: since #26930 a predicate delete walks every matched row one by one; 1,001 rows cost ~1.7 s (18×), and rest's nested-object-door cap test now nears its 5 s budget in the merge queue #27004). An object holds acascadelookup to itself, and parent and child are both matched. The test asserts the delete returns2, only the unmatched row is left, and each matched row gets exactly onebeforeDeleteand oneafterDelete. This is the optional pin the card offered.cascadeDeleteRelations(object, matchedIds, …)was swapped for the loop it replaced, one root per matched id, throughscripts/ablation-replace.mjs. The mutation landed (blob3dcaaed4af74→b887e2f85237) and was restored to HEAD (git diff HEADempty). Temporary probe cases were appended to the test file and removed afterwards; the file's blob equals HEAD.21restrictself-lookup, manager matched first2)DELETE_RESTRICTED2)DELETE_RESTRICTEDaa_guardrestricts p2,zz_guardrestricts p1aa_guardzz_guardThe new pin test fails on the mutation (
expected 1 to be 2) and passes on this tree.Acceptance notes
Check Changesetstays red, by design. This PR edits a pending changeset and adds none, so the job reds twice: its count of added changesets is 0, andcheck-empty-changeset.mjsrefuses a change to a changeset that exists on the merge base. This is that gate's DELIBERATE CORRECTION class. The route it prescribes: do not restore the note, do not applyskip-changeset, name the note and what changed under it on the PR, and get the correction confirmed there in writing. The note is.changeset/27004-predicate-delete-walk-as-set.md. What changed under it is the engine change fix(objectql): a predicate delete walks the rows it matches as one set, one probe per relation per 500 rows (#27004) #27073 already landed: this PR changes no code, and the note was wrong about that change from the start. The order for this edit is the card's triage ruling (6467217349), verbatim: "⛔ Edit the pending changeset text only. The engine code was judged right." The written confirmation on this PR is still owed.Check Changesetis not one of the ten required contexts.packages/objectql/src/engine.tsis byte-identical toorigin/main.Verification
All readings are from the worktree of this branch. Head is
cbc268d7unless a line says otherwise.Derived gate families: 59 derived, 59 run, 58 exit 0, 1 exit 1 (by design)
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 59 families atcbc268d7from 2 changed paths (+38/-3).--ranreconciliation reads:✓ dispatch-gates --ran: 59 derived famil(ies) accounted for — 59 run, 0 NOT-MEASURED.node scripts/check-empty-changeset.mjs --base origin/main(exit 1). It names.changeset/27004-predicate-delete-walk-as-set.mdas existing on the merge base and offers the DELIBERATE CORRECTION route. See Acceptance notes.00ca77b4, had three exit-3 readings:check-plugin-teardown-shape --self-test(a shallow clone; I fetched its pinned control commit),check:lean-entry-closure(needed objectqldist; I built it) andcheck:dual-build-cjs-loads(needed built packages). All three exit 0 in thecbc268d7run.@objectstack/objectql package runs
pnpm --filter '@objectstack/objectql^...' build: VERDICT command-exit 0.pnpm --filter @objectstack/objectql typecheck: VERDICT command-exit 0. Output:check:test-typecheck: OK … 39 file(s) / 233 error(s) / 64 pinned signature(s) held.pnpm --filter @objectstack/objectql testat00ca77b4:Test Files 477 passed (477),Tests 8900 passed (8900), VERDICT command-exit 0. The only commit after it (cbc268d7) changes two lines of the changeset, sopackages/objectqlis byte-identical.vitest run src/engine-cascade-delete-atomic.test.ts: 20 passed. Under the old-walk mutation, the new case fails withexpected 1 to be 2.Not run locally
pnpm lintover the whole repo: CI runs it. I ranpnpm exec eslint --no-inline-config packages/objectql/src/engine-cascade-delete-atomic.test.tson the one code file this PR touches: exit 0, no findings.test:repo: CI runs it, and the diff touches no file of that project.!, and theClause-②:line carries no(narrowing)arm.Generated by Claude Code