Skip to content

A sys_audit_log write refused by the system-write organization rule is swallowed by plugin-audit's best-effort catch, so the audit row about a defective record is LOST silently — surfaced by #13636's admission #14927

Description

@os-musk

Filed unassigned and ungraded by the domain:engine execution seat, carrying an open question #13636's dev raised and deliberately did not implement. ⛔ domain:*, priority and type are triage's. The fix面 is plugin-audit, which is the domain:services lane — ⛔ never repaired from this lane.

Filed as a card, not left in a dispatch report, because a cross-seat request that lives only in a report is invisible to that lane's candidate query, sweep and ageing alarms.

How it surfaced

PR #14923 (#13636) admits sys_audit_log into the #8844 derive-or-refuse machinery under the new conditional verdict. Admission makes the object stricter, which is the ruled intent. Its writers now declare their legitimately org-less cases explicitly.

One population is deliberately left undeclared, and that is correct on the merits: case 2 of audit-writers.ts's own enumeration — an audit row whose subject has an organization column whose value is NULL, written under a system context on a walled install. It is left to refuse because at that call site it is indistinguishable from the missing-stamp defect; #9516 was exactly that bug, on those exact lines.

The consequence, which is the actual subject of this card

That refusal (SystemWriteOrganizationRequiredError) lands inside plugin-audit's best-effort swallow-and-report catch.

⇒ ⭐ The outcome is a lost audit row, not a visible failure — and the row that is lost is precisely the audit record about a defective row. The control gets sharper and the evidence disappears at the same moment.

⚠️ Not speculative: reachable today on any walled install holding a record whose organization column is NULL.

Three directions, as the dev costed them

四棱分析(维护者裁决用)

  • 实际业务需求 —— ⭐ 拉动是实测的:case 2 在任何 walled 安装上、只要存在 organization 列为 NULL 的记录就可达,不是构造出来的边角。丢的还偏偏是关于那条缺陷记录的审计行,即最该留下的那一条。
  • 项目长远合理性 —— ⭐ A 与 B 是在同两个好处之间对换:A 保住控制的锐度、静默丢行;B 保住行、致盲控制。C 拒绝承认这个交换是被迫的 —— A 的损失并非由拒绝造成,而是由拒绝不可见造成,而 plugin-audit 早已持有让这类丢失变响的通道。
  • 防 AI 写代码犯错 —— ⭐ 本棱指向 C:C 让申报词表保持封闭,任何未来的写入方都无法伸手拿一个 case-2 理由去安抚一条它没读懂的拒绝。B 恰恰相反 —— 它新开一个最容易被误用的申报理由。
  • 创业阶段不扩散需求 —— C 不新增能力、不新增面,只是在一条已经在上报的路径上改日志级别/通道。B 才是扩大接受集。

⚠️ 四棱同向指向 C,但 C 改的是 p1 security 路径上的失败上报行为,⇒ 仍应走独立评审卡,⛔ 不适合作为 #13636 的搭车修改 —— 这也正是该 dev ⛔ 未实施的理由。

Re-check

git grep -n "DURABILITY_CRITICAL_CALLEES" origin/main
git grep -n "persistAuditTrailRow" origin/main -- packages/plugins/plugin-audit/src
git show origin/main:packages/plugins/plugin-audit/src/audit-writers.ts | grep -n "organization"

Dedup — declared WEAK

⚠️ search_issues free-text is recorded in #14743 as returning 0 for terms present in open issue titles with incomplete_results: false, so ⛔ a zero from it supports no negative. Whoever grades this should re-run with a keyword pass.

Refs: #13636 / PR #14923 (where it surfaced) · #13491 (execution point 3) · #9516 (the missing-stamp bug on these exact lines) · #8844 (the derive-or-refuse machinery).

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions