Skip to content

docs(objectql): audit the three unverified delete-phase hook bullets — all correct, and the audit recorded (#7933) - #8085

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-7933-preimage-bullet-audit
Aug 12, 2026
Merged

docs(objectql): audit the three unverified delete-phase hook bullets — all correct, and the audit recorded (#7933)#8085
os-zhuang merged 2 commits into
mainfrom
claude/issue-7933-preimage-bullet-audit

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

Fixes#7933

Audits the three never-verified entries of the delete-phase hook bullet list in packages/objectql/src/engine.tsplugin-auth, plugin-sharing, service-storage — against each package's actual current hook registrations.

All three are correct as written, on both halves (hook name and which gate term they hold). No bullet's substance changed. The diff is 13 comment lines recording the audit.

Verdict per bullet

1. plugin-auth identity-write-guard beforeDelete — CORRECT (term 1 only).
packages/plugins/plugin-auth/src/identity-write-guard.ts:199, bound by registerIdentityWriteGuard:
engine.registerHook('beforeDelete', rejectWrite('delete'), { priority: 10, packageId }) — no object key, so global. The handler opens by returning unless isManaged(ctx.object), as the bullet claims. The package registers no afterDelete at all, so "term 1 only" is right.

2. plugin-sharing record-share-cascade before+afterDelete — CORRECT (terms 1 and 2).
packages/plugins/plugin-sharing/src/record-share-cascade.ts:320 and :331, bound by bindRecordShareCascade, both registered with opts = { packageId: RECORD_SHARE_CASCADE_PACKAGE, priority: 190 } — no object key. Both handlers open with const t = targets(objectName); if (!t.shares && !t.links) return;, matching the bullet's named filter.

3. service-storage file-reference-lifecycle before+afterDelete — CORRECT (terms 1 and 2).
packages/services/service-storage/src/file-reference-lifecycle.ts:782 and :801, bound by installFileReferenceHooks, both { packageId: PACKAGE_ID } — no object key. Both handlers open with if (activeFileFields(engine, object).length === 0) return;, matching the bullet's named filter.

None of the three modules has moved or been retired.

The "global" premise, checked rather than assumed

The paragraph above the list asserts every listed hook registers with noobject. Verified from both ends:

  • hookMatchesObject (engine.ts:1026) treats an absent entry.object as global, so an object-less registration makes hasHooksFor true for every object.
  • Every other delete-phase registration in packages/plugins and packages/services is object-scoped: last-admin-guard (four, on sys_user / sys_member / sys_user_permission_set / sys_permission_set), rule-hooks (object: objectName), primary-bu-projection and bu-tree-recompute, attachment-lifecycle and attachment-access-hooks (sys_attachment), comment-access-hooks (sys_comment), and metadata-driven record-change triggers (object: binding.object).

So the list's population — the global delete-phase registrants — is complete, not merely accurate. plugin-sharing says the same thing independently at sharing-plugin.ts:513: "Not bound per object: the posture is judged per delete from live metadata".

The gate itself was retired mid-flight

PR #7989 (issue #7867) landed during this work and retired the three-term wantsPreImage gate: the const wantsPreImage = expression is gone from main, and only the prose mention survives inside its own RETIRED banner. That PR deliberately kept this bullet list, because its retirement rationale leans on it:

On any kernel loading the global registrants enumerated above, term 1 or 2 was already true for every object, so this skipped nothing there anyway.

That makes the audit worth more rather than less: the sentence the retirement stands on is exactly the claim these three bullets encode, and it had never been checked. origin/main is merged in here, its RETIRED banner preserved verbatim, and the audit note reframed to sit beneath it and say what it now supports.

Verification

  • Gates on the merged state: check:adr-anchors, check:durability-log-level, check:engine-double-contract, check:stack-collection-maps, check:nul-bytes — all pass
  • node scripts/check-engine-split-ratio.mjs — report-only metric, ran clean
  • pnpm --filter @objectstack/objectql typecheck — clean
  • pnpm --filter @objectstack/objectql test — 190 files / 3376 tests passed
  • ESLint on engine.ts — clean

A first typecheck run reported TS7006 in registry.ts — a file this PR does not touch. It was a stale-dist false red: the merge brought in checkManagedApiMethodAffordances (from #7851) while the built closure predated it. Rebuilding with pnpm --filter '@objectstack/objectql^...' build cleared it. main is not broken.

Comments-only diff, no test file touched, so neither repo-wide ratchet moves — this carries the skip-changeset label rather than a changeset, since an empty-frontmatter one would be rejected by check-empty-changeset.mjs.


Generated by Claude Code

…auth, plugin-sharing and service-storage (#7933)
The three entries #7707 left unverified in engine.ts's `wantsPreImage`
bullet list have been read against the functions that bind them
(`registerIdentityWriteGuard`, `bindRecordShareCascade`,
`installFileReferenceHooks`). All three match what the list claims:
same events, same object-less registration, same in-handler filter.
No bullet's substance changed — the audit is recorded because "never
checked" and "checked and correct" read identically in prose, which is
what produced #7933 in the first place.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014C8pAprWdmtecFsEprZax4
…image-bullet-audit
# Conflicts:
#	packages/objectql/src/engine.ts
@vercel

vercelBot commented Aug 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
objectstackIgnoredIgnoredAug 12, 2026 2:56pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/objectql.

15 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/metadata-lifecycle.mdx(via @objectstack/objectql)
  • content/docs/data-modeling/formulas.mdx(via packages/objectql)
  • content/docs/deployment/migration-from-objectql.mdx(via @objectstack/objectql)
  • content/docs/deployment/vercel.mdx(via @objectstack/objectql)
  • content/docs/kernel/contracts/data-engine.mdx(via @objectstack/objectql)
  • content/docs/kernel/runtime-services/examples.mdx(via packages/objectql)
  • content/docs/kernel/services-checklist.mdx(via @objectstack/objectql)
  • content/docs/kernel/services.mdx(via @objectstack/objectql)
  • content/docs/permissions/authentication.mdx(via @objectstack/objectql)
  • content/docs/permissions/system-context.mdx(via packages/objectql)
  • content/docs/plugins/index.mdx(via @objectstack/objectql)
  • content/docs/plugins/packages.mdx(via @objectstack/objectql)
  • content/docs/protocol/kernel/index.mdx(via @objectstack/objectql)
  • content/docs/protocol/objectql/query-syntax.mdx(via packages/objectql)
  • content/docs/protocol/objectql/state-machine.mdx(via @objectstack/objectql)

1 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx(via @objectstack/objectql)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 12, 2026
@os-zhuang
os-zhuang marked this pull request as ready for review August 12, 2026 15:20
@os-zhuang
os-zhuang added this pull request to the merge queueAug 12, 2026
Merged via the queue into main with commit 9e45153Aug 12, 2026
29 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-7933-preimage-bullet-audit branch August 12, 2026 15:34
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants

@os-zhuang@claude