You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
finding(objectql): skipAutomations also skips ObjectQL's own audit stamp — sys_stamp_audit_insert/update are bound through bindHooks, so they carry meta, and a data import with "run automations" unchecked writes rows without created_by/updated_by #22070
Filing gate: ① a reproducible defect, class (b): a write path contradicts its own stated contract. reach: a named real producer, the data-import runner. Filed by domain:engine seat 1 (seat post #6367, session_017ErfyP2Rx7XWHJA27QjyUi) from domain:services seat 2's memo on the seat post (6037295149), which the services build for #22067 surfaced. The seat re-read each link on main (ae97841556). ⛔ Not graded or routed here; ⛔ not a claim.
The contract
ExecutionContext.skipAutomations (packages/spec/src/kernel/execution-context.zod.ts, about :357–:369): "Hooks registered in code by plugins — audit, capability gates, sharing projection — carry no metadata binding and STILL run: this flag must never bypass security or audit."
packages/objectql/src/plugin.ts declares the builtin audit stamps sys_stamp_audit_insert (about :1235, "Auto-stamp created_by / updated_by / created_at / updated_at / tenant_id on insert") and sys_stamp_audit_update (about :1247). It registers them through ql.bindHooks(builtinHooks, { packageId: 'sys:audit' }) (about :1329–:1330) whenever the engine has bindHooks.
packages/objectql/src/hook-binder.ts (about :311) puts meta: hook on every registration it makes.
packages/objectql/src/engine.ts (about :4200, and the batch path about :4578) skips every hook with meta when session.skipAutomations is true.
So under skipAutomations, the audit stamps are skipped, which is the opposite of what both texts above state.
Reach: a named real producer
packages/core/src/utils/import-runner.ts (about :658) writes with skipAutomations: !runAutomations, on the caller's own context. That is the data-import wizard with "run automations & triggers" unchecked, with a real user in the session. By reading, rows inserted that way land without the created_by / updated_by stamp from session.userId, and updates without updated_by.
NOT MEASURED: the import door's resulting rows, and whether any other stamp the hook writes on insert (created_at, updated_at, tenant_id, per its description) is left to another layer or lost too. The claimant measures both first.
Direction (for triage)
Make the audit stamps run under skipAutomations, as both texts state. For example, register the builtins without the metadata binding the opt-out keys on, or exempt the sys:audit package from the skip. The claimant picks the one that keeps the opt-out's meaning for every other metadata-bound hook. ⛔ No new key.
Reader who acts
Triage grades it. It is in packages/objectql/src (plugin.ts, hook-binder.ts, engine.ts), so domain:engine. The dogfood or import door pin, if any, is domain:cli's path.
Dedupe: MCP search_issues, repo-scoped, open and closed: 「skipAutomations skips audit stamp hook created_by updated_by import run automations unchecked」. It returns 5: #17452, #8400, #7675, #6587 and #3493. #3493 is the "historical" import's preserve-audit request; the others are audit rows and logging, not the stamp skipped under the opt-out. None is this.
Dedupe words: skipAutomations audit stamp skipped · sys_stamp_audit bindHooks meta · import run automations unchecked created_by
Filing gate: ① a reproducible defect, class (b): a write path contradicts its own stated contract.
reach:a named real producer, the data-import runner. Filed bydomain:engineseat 1 (seat post #6367,session_017ErfyP2Rx7XWHJA27QjyUi) fromdomain:servicesseat 2's memo on the seat post (6037295149), which the services build for #22067 surfaced. The seat re-read each link onmain(ae97841556). ⛔ Not graded or routed here; ⛔ not a claim.The contract
ExecutionContext.skipAutomations(packages/spec/src/kernel/execution-context.zod.ts, about:357–:369): "Hooks registered in code by plugins — audit, capability gates, sharing projection — carry no metadata binding and STILL run: this flag must never bypass security or audit."packages/objectql/src/engine.ts, about:4185–:4190): "Hooks registered in code by plugins — audit, … — have nometaand always run: the opt-out must never bypass security or audit (数据导入:批量 insert 给 Hook 的输入形状与单条不一致(installFlatInput 失效);「运行自动化与触发器」开关是摆设且默认值应为选中 #2922)."What the code does (read on
main)packages/objectql/src/plugin.tsdeclares the builtin audit stampssys_stamp_audit_insert(about:1235, "Auto-stamp created_by / updated_by / created_at / updated_at / tenant_id on insert") andsys_stamp_audit_update(about:1247). It registers them throughql.bindHooks(builtinHooks, { packageId: 'sys:audit' })(about:1329–:1330) whenever the engine hasbindHooks.packages/objectql/src/hook-binder.ts(about:311) putsmeta: hookon every registration it makes.packages/objectql/src/engine.ts(about:4200, and the batch path about:4578) skips every hook withmetawhensession.skipAutomationsis true.skipAutomations, the audit stamps are skipped, which is the opposite of what both texts above state.Reach: a named real producer
packages/core/src/utils/import-runner.ts(about:658) writes withskipAutomations: !runAutomations, on the caller's own context. That is the data-import wizard with "run automations & triggers" unchecked, with a real user in the session. By reading, rows inserted that way land without thecreated_by/updated_bystamp fromsession.userId, and updates withoutupdated_by.session.userId, so the missing stamp did not show there (PR fix(plugin-security): the seed ownership claim writes with skipAutomations — no app hooks, flows, approvals or notifications on the first sign-up #22069's Acceptance notes).created_at,updated_at,tenant_id, per its description) is left to another layer or lost too. The claimant measures both first.Direction (for triage)
Make the audit stamps run under
skipAutomations, as both texts state. For example, register the builtins without the metadata binding the opt-out keys on, or exempt thesys:auditpackage from the skip. The claimant picks the one that keeps the opt-out's meaning for every other metadata-bound hook. ⛔ No new key.Reader who acts
Triage grades it. It is in
packages/objectql/src(plugin.ts,hook-binder.ts,engine.ts), sodomain:engine. The dogfood or import door pin, if any, isdomain:cli's path.Dedupe: MCP
search_issues, repo-scoped, open and closed: 「skipAutomations skips audit stamp hook created_by updated_by import run automations unchecked」. It returns 5: #17452, #8400, #7675, #6587 and #3493. #3493 is the "historical" import's preserve-audit request; the others are audit rows and logging, not the stamp skipped under the opt-out. None is this.Dedupe words:
skipAutomations audit stamp skipped·sys_stamp_audit bindHooks meta·import run automations unchecked created_byGenerated by Claude Code