Skip to content

plugin-audit 的 5 个 hook 全部无 object 注册 ⇒ 引擎「按对象」需求门(#5284 单 id / #5038 批量)在 audit 启用时恒真 #5860

Description

@os-zhuang

Blocked-by: #5928

#5846(b) 半边拆出(由分诊座位按域路由拆分:#5846 的 (a) 半落 objectql 引擎时序 ⇒ domain:engine-core,(b) 半落 plugin-audit 注册面 ⇒ domain:identity;#5846 正文自陈两条后果「互相独立」,故平级拆分而非父子)。

状态注记(identity 车道 PM,2026-08-06 12:1xZ):第 5 轮派发后 dev 实测证明本单在 plugin-audit 文件面内无法落地 —— 注册契约只能表达允许列表,SKIP_OBJECTS 是开放全集上的拒绝列表(细节与探针数据见 dev 阻塞报告评论)。所需引擎侧契约已提为 #5928(engine-core);其落地后本单收敛为「5 个注册带上排除面」。另:验收判据的 delete 侧#5929(内建 sys_fetch_previous_deleteobject:'*' 注册,门恒真)独立作废,本单验收以 update 侧为准。

事实(已按 #5846origin/main 逐处核对)

packages/plugins/plugin-audit/src/audit-writers.ts:

  • captureBefore 注册在 beforeUpdate / beforeDelete,object 选项 ⇒ 全局;
  • writeAuditafterInsert / afterUpdate / afterDelete 三个注册同样不带 object

hasHooksFortriggerHooks 的语义,把「无 object 的注册」正确地当作命中每个对象。于是只要 plugin-audit 启用:

关键点:平台其实已经知道答案,只是没表达在注册面上

writeAudit 自身是在 handler 里SKIP_OBJECTS 过滤的 —— 也就是说「哪些对象要审计」这件事平台已经知道,只是这个知识停在 handler 内部,注册面上看不见,所以任何按注册面计算的需求门都只能保守地判「全命中」。

完成范围

把该知识表达到注册面上,二选一(接手方按代码判,本单不预设):

  1. 注册时给出 object 列表(由 SKIP_OBJECTS 的补集导出),或
  2. 提供一个「本对象是否被审计」的谓词供门查询。

验收判据:装了 plugin-audit 的 kernel 上,对一个SKIP_OBJECTS的对象做单 id update(),#5284 的按对象门应判不需要前置行(当前判需要)。

#5846 (a) 半边的关系

(a)(引擎 update 侧对齐 #5272 的 delete 时序、让 before 阶段两个消费者共用一次读)与本单互相独立:(a) 消掉「同一行读 3 次」里的两次引擎读,本单消掉「按对象门恒真」。两者都做才既省读又让门真正生效;只做一个也各自成立。

⚠️ 落点不同、车道不同:(a) 在 packages/objectql(domain:engine-core),本单在 packages/plugins/plugin-audit(domain:identity)。⛔ 不要合成一个 PR —— 那会跨两个车道的文件面。

Refs:#5846(来源)、#5284#5038#5272#5574#5928(阻塞项)#5929(delete 侧判据作废方)

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions