Skip to content

plugin-audit: sys_upload_session 同样声明 lifecycle.class: 'transient' 却不在 SKIP_OBJECTS —— 分块上传每传一块写一组 audit_log + activity 行 #5202

Description

@os-zhuang

在 #5193(把 sys_job_queue 加进 plugin-audit 的 SKIP_OBJECTS)里,按派发要求核了一遍「还有哪些表同样漏在豁免外」。未在 #5193 的 PR(#5201)里修(越界,一事一议)。

事实(均对 origin/main 核过)

把「声明了 lifecycle.class 为 telemetry / transient / event 的对象」与 packages/plugins/plugin-audit/src/audit-writers.ts 的 SKIP_OBJECTS 第 (2) 组对一遍,只剩两张表在豁免外:

对象 lifecycle.class 在 SKIP_OBJECTS? 判断
sys_upload_session(packages/services/service-storage/src/objects/system-upload-session.object.ts:132) transient ❌ 本单
sys_file(.../system-file.object.ts:179) transient ❌ 不算漏 —— 其自身注释即写 “sys_file rows are mostly permanent business truth”,transient 只为收墓碑行/未完成上传;审计有合规价值

sys_upload_session 的对象注释说的是另一回事:「an upload session is ephemeral state, never business truth」(ADR-0057 / #2970 item 4)—— 与 sys_job_queue 同类。

写入面(packages/services/service-storage/src/metadata-store.ts):

  • createSession() → engine.insert(sys_upload_session, full)(:146);
  • updateSession() → engine.update(sys_upload_session, merged, …)(:178)—— 分块上传每传一块调一次,而且写的是 merged 全量记录,含 parts 这个随块数增长的 JSON blob,所以每行 audit 的 old_value/new_value diff 也跟着变大;
  • deleteSession() → engine.delete(…)(:190),外加 LifecycleService 的 TTL/retention reaper(ttl:expires_at + 1d;retention:7d,onlyWhen status 属于 completed/failed/expired)。

审计钩子全对象注册、无系统上下文豁免(audit-writers.ts:651-653,把关的只有 :423 / :461 两处 SKIP_OBJECTS.has),所以一次 N 块的上传 = 1 + N 次写 → 2 × (1 + N) 行 sys_audit_log + sys_activity,外加每次 beforeUpdate 的 captureBefore 快照读(:422)。

与 #5193 的差别(为什么单独立单而不是并进去)

  • 严重度低一档:上传频率远低于队列消息,plugin-email: 邮件投递接入持久化队列 —— send 走 email.send.async / sys_job_queue(重试+DLQ),可配置开关 #5160 那种「每封邮件都过」的常驻放大器在这里没有;
  • 治理声明也弱一档:sys_job_queue 有 managedBy = engine-owned + enable.apiMethods = get/list(用户根本写不了),sys_upload_session 两者都没有 —— 它只是事实上由 StorageMetadataStore 独占写入。要不要顺带补上治理声明,是这张表自己的问题,不该塞进审计豁免这单;
  • 目标表 sys_audit_log / sys_activity 本身有 retention/rotation,所以后果是噪声与写放大,不是无界增长。严重度请 PM 判。

建议修法

与 #5193 完全同形:把 sys_upload_session 加进 SKIP_OBJECTS 第 (2) 组,注释注明其 lifecycle.class = transient 与「never business truth」的自述。等 #5201 落地后做,避免同一处清单的行冲突。

顺带(#5193 正文已提出,这里只做交叉引用)

这份名单是手写的,与对象上的 lifecycle.class 没有任何机械关联 —— 本单就是这个耦合缺失的第二个实例(第一个是 #5193)。是否改成按注册表里的 lifecycle.class 判定(或加一道对账门禁:声明了 telemetry/transient/event 却不在豁免组的表必须显式登记豁免理由),值得单独定夺,不在本单范围内。

Found-during: #5193 / PR #5201
Related: #5193(同类,sys_job_queue)

Activity

  1. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    分诊(PM 循环,#5193 派生):auto-queue —— pm:queue + domain:identity。同形于 #5193(具名位置、修法同形、ADR-0057 决策 5 的 restore-invariant),不需要维护者拍板。串行在 PR #5201 之后(同一张 SKIP_OBJECTS 手写清单,同批必撞行),#5201 合入即可派。「SKIP_OBJECTS 与 lifecycle.class 无机械关联」的横切问题保持独立,不挂本单。


    Generated by Claude Code

  2. self-assigned this
    on Aug 4, 2026
  3. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    认领:PM 循环第 8 轮
    会话:session_017MCKJaEomEqg4tvz4SzdNd
    分支:claude/issue-5202-audit-skip-upload-session
    Worktree:objectstack-issue-5202
    域:domain:identity
    文件面:packages/plugins/plugin-audit/src/(越界即停,报告说明)

    串行条件已满足:PR #5201 已合入 main,SKIP_OBJECTS 清单上的行冲突风险解除。与在飞的 #5195 接手(objectql/service-queue)、#5177 接手(plugin-email/platform-objects)不同包,并批安全。


    Generated by Claude Code

  4. os-zhuang commented on Aug 4, 2026

    @os-zhuang
    ContributorAuthor

    复核结论:ACCEPT —— PR #5215,转 ready 并入合并队列。head 上 23 个 check run 全部 success/skipped。

    与 #5201 同形的一行清单 + 注释;五个新用例含逐位对得上放大倍数的突变检查(删行后 8 块上传 = 2×11 行、3 块 abort = 2×6 行、5 次快照读,与 issue 预测完全一致),以及对 sys_file 的刻意不豁免用例——把「为什么不豁免」也钉进了测试,防止未来有人顺手扩面。

    衍生 #5216(StorageMetadataStore 把全部 8 个 engine 调用包在无日志的 catch { /* ignore */ } 里,createFile 失败即静默丢 sys_file 业务真相而 API 返回 200)已入队分诊,见该单评论。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions