Skip to content

[finding] isSystem 写入的 owner_id 缺口有两处彼此独立的补偿、没有共享机制 —— 第三条系统写入路径两者都拿不到 #6896

Closed as not planned

Description

@os-project-manager

观察类记录,来自 #6782 的 isSystem 全仓普查(PR #6891)。今天没有用户能撞到:已知的两条系统写入路径各自都补上了。记录它是因为补偿方式是两套、互不知情,而缺口本身在中间件里。

事实

平台的 owner_id 写时 stamp 在安全中间件的 3.5 步(packages/plugins/plugin-security/src/security-plugin.ts:1466—1560:INSERT 时把空 owner_id 补成 acting user)。该中间件在 security-plugin.ts:825 因 context.isSystem 整体短路,所以任何 isSystem 写入都拿不到这个 stamp,行落库时 owner_id = NULL —— 默认的 owner_only_writes 策略会让它对自己的创建者不可见。

对此平台做了两处彼此独立的补偿:

  1. 自动化流程的数据节点,内联补。 packages/services/service-automation/src/runtime-identity.ts:279(stampSystemInsertOwner),由 packages/services/service-automation/src/builtin/crud-nodes.ts:309 调用。该调用点的注释自陈了原因:

    the ownership anchor has no such engine-side channel for system writes — the security middleware that stamps it short-circuits on isSystem — so the writer fills it here.

  2. 种子数据,启动期扫描补。 packages/plugins/plugin-security/src/claim-seed-ownership.ts:kernel:ready 之后扫出 owner_id 为 NULL 或 usr_system 的行,以 isSystem 更新认领。

两者解决同一个缺口,但没有共享的机制或契约:一个是写入时填充,一个是启动后修复,彼此不知道对方存在。

为什么记录

新增第四条系统写入路径时,两条补偿都不会自动覆盖它,而失败模式与 #4707 记录的完全同形 —— 元数据完整正确,行也写进去了,只有查库才能发现它没有 owner,因而对创建者不可见。普查确认目前只有上面两处补偿点。

可能的处置(不预设结论,留给分诊)

  • A:维持现状,只靠文档(PR docs(permissions): isSystem 行为全集权威表 —— 按普查而非回忆构建 (#6782) #6891 的权威表已点名这条,新增路径的作者若读到表就会知道要自己补)。
  • B:把 stamp 从安全中间件里提出来,做成不随 isSystem 短路的独立步骤(owner_id 本来就不是授权判定,是平台锚点)。
  • C:给系统写入提供一个共享的 helper / 契约,让第三条路径「不写就报错」而不是静默拿不到。

倾向 B 或 C,但这是已发布语义的改动,且 #4707 的裁决刚刚明确「不拆分 isSystem 概念」,所以不自作主张 —— 按 observation 记录,不挂 pm:queue。

参考:#4707(锚点单)、#6782 / PR #6891(权威表,含本条为「已知粗糙处」第 1 条)、hotcrm#622(诉求 1 的原始 app 侧 bug)。

Activity

  1. os-zhuang commented on Aug 9, 2026

    @os-zhuang
    Contributor

    Findings triage round: held (finding stays) — first grading (no prior disposition on this card).

    Premises re-verified on origin/main @ 3e8e669: the isSystem short-circuit is live at security-plugin.ts:825; both independent compensations are live — stampSystemInsertOwner (runtime-identity.ts:273, called from crud-nodes.ts:318) and the boot-time sweep (claim-seed-ownership.ts, present). Line anchors drifted slightly from the card (279→273, 309→318) but the mechanisms are byte-for-byte the ones described.

    Hold rationale: the card's own framing is correct — both known system-write paths are compensated, so no user hits this today; options B/C change published semantics, and the #4707 ruling ("don't split the isSystem concept") is recent, so promoting a mechanism-consolidation now would re-open a freshly settled design without a forcing event.

    Restart conditions: ① a third system-write path lands (the failure mode then becomes live — the PR adding it should be pointed at PR #6891's authoritative table); ② the maintainer revisits the #4707 anchor; ③ an owner-invisible-row report arrives from any app (that is the #4707-shaped symptom this card predicts).

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Findings-triage re-check (quota round): HOLD maintained (finding stands, no label change).

    Premise re-verified on origin/main @ 2c28df9: both independent compensations are still in place and still unaware of each other — the automation-side stamp stampSystemInsertOwner now at packages/services/service-automation/src/runtime-identity.ts:273 (was :279), called from builtin/crud-nodes.ts:318 (was :309) — line drifts recorded; and the security middleware's isSystem short-circuits remain (security-plugin.ts :781/:803/:901). No third system-write path has appeared, so nothing hits the gap today. Held: the record exists so a future system-write path lands on this card instead of rediscovering the NULL owner_id shape.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings triage: HOLD.

    Re-verified @ origin/main 8dd98bf: the isSystem short-circuit is live (now security-plugin.ts:794, if (context?.isSystem) return true; — drifted from the previously recorded :825), and both independent compensations remain in place and unaware of each other: the automation-side stamp stampSystemInsertOwner (packages/services/service-automation/src/runtime-identity.ts:273, called from builtin/crud-nodes.ts:318) and the boot-time sweep (packages/plugins/plugin-security/src/claim-seed-ownership.ts, present with its test). No shared mechanism has appeared, and no third system write path has been shown to hit the gap live. Observation stands: real structural duplication, nothing a user hits today.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  4. os-zhuang commented on Aug 11, 2026

    @os-zhuang
    Contributor

    Findings triage round, 2026-08-11 (maintainer-directed). Graded: hold — both known system-write paths carry their own compensation; the structural risk is the THIRD path that gets neither. Restart: any new system write path lands (converge the two compensations into a shared mechanism first, then build on it).


    Generated by Claude Code

  5. hotlong commented on Aug 12, 2026

    @hotlong
    Contributor

    Finding-grading round: closed, not planned.

    Premise still true (all three anchors live) but pull-less across five holds, and option A is already shipped: content/docs/permissions/system-context.mdx "Known rough edges" #1 states this gap verbatim and tells the author of a third system write path to stamp ownership — the record has a durable home outside this card. Options B/C are published-semantics changes cutting against the #4707 ruling; if ever wanted they need a fresh decision card with fresh evidence. Note: #7858 (d99ff1a) and #7865/#8115 are adjacent (phantom anchors on external objects) but do not absorb this (NULL owner on system writes) — closing on pull, not on overlap.


    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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions