Skip to content

[finding] the deliberate reference_to tolerance in plugin-security has no measured stored-metadata population — the prerequisite for ever narrowing it #13542

Closed as not planned

Description

@claude

Deferred by the maintainer ruling on #13250 (2026-08-30, verbatim 「同意」), which named it out of scope for that card in its own words: narrowing the security reader for real is a separate card, not a rider. Filed unassigned so the option is recorded rather than lost. ⛔ Nothing here is claimed to be broken today.

Where this stands

resolveCbpRelation in packages/plugins/plugin-security/src/security-plugin.ts deliberately still reads reference ?? reference_to ?? referenceTo, and PR #13541 made that tolerance loud rather than removing it. The in-file comment there records why, and it is not a style preference:

What would have to be measured before narrowing

The ruling's option C. None of this has been done, and this card exists to hold the question, not to answer it:

  1. Size the population. How many raw-registered / stored objects actually spell reference_to or referenceTo on the field that resolves a controlled_by_parent master relation? The repo-wide source sweep done for fix(security,verify): keep the security reference-alias read tolerant but LOUD, narrow verify with a named finding #13541 found the spelling only in tests, the spec's own alias tables and other readers' documentation — no example app or platform object uses it. That says nothing about metadata stored in a live deployment's database, which is the population that matters here.
  2. Decide the migration. If the population is non-empty, a sweep that rewrites the key has to land, and be verifiable, before any narrowing.
  3. Only then flip the reader, and delete the tolerance note along with it.

If step 1 measures zero across every reachable corpus, the narrowing becomes cheap and this card is small. If it does not, the outage cost above is the thing to weigh.

Related

#13250 (the ruling and both dispositions) · #13541 (the loud tolerance) · #11567 (reference is the only declared spelling)


Generated by Claude Code

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 30, 2026
  2. changed the title [-][finding] the deliberate tolerance in plugin-security has no measured stored-metadata population — the prerequisite for ever narrowing it[/-] [+][finding] the deliberate `reference_to` tolerance in plugin-security has no measured stored-metadata population — the prerequisite for ever narrowing it[/+] on Aug 30, 2026
  3. added
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Aug 30, 2026
  4. claude commented on Aug 30, 2026

    @claude
    ContributorAuthor

    分诊定级 · 首次定级 · 持有 finding · domain:services · ⛔ 不入队

    ⚠️ 此前带 finding + pm:retriage。pm:retriage 是误用(本卡从未被定级,没有可异议的对象),本轮摘掉;finding 保留 —— 它正确。

    域锚定:packages/plugins/plugin-security 在 services 车道的身份侧(lanes/services.md:11 逐字列出 plugin-security)⇒ domain:services。

    为什么持有

    卡自己把理由写全了,且不主张今天坏了:容忍是有意的,PR #13541 让它变响而非移除;别名确实到达该读者(裸 registerObject 跳过 Zod,注册表原样发回);而 miss 是 fail-closed —— 读腿答 RLS_DENY_FILTER(每个非 admin 调用者零行)、写腿抛 MasterDetailRelationMissingError。

    ⇒ 收窄一个可达的读者 = 对一个已证明存在的 population 制造可用性中断。 在那份 population 被量出来之前,收窄不可判定 ⇒ 无可派之事。

    ⚠️ 并记一条本席核过的边界:lanes/services.md 的红线写明「安全/权限边界的放宽……是人工地板」。本卡方向是收紧不是放宽,故不因该条恒升级;但其后果(可用性中断)使它在测量之前同样不可代裁。

    ⭐ 重启条件 —— 与 #13543 共用一次测量,⛔ 不要测两遍

    本卡与 #13543 是同一个形状:一个容忍别名的读者,断言了一份 stored-row population,而没有任何东西测量它。两张卡问的是同一个问题的两个实例。

    重启条件:任何一次对「stored-row 里 reference / reference_to / referenceTo 的实际拼写分布」的测量落地 ⇒ 本卡与 #13543 同时可判。

    ⇒ 谁先接到其中一张,请把测量做成覆盖两个读者的一次普查,并把结果落在卡上;⛔ 两张卡各测一次,是把同一份成本付两遍,且两份结果可能不一致。

    其余重启条件:#13250 的选项 C 被维护者重新拾起;或今后任何单已要改 resolveCbpRelation ⇒ 顺带结算。


    Generated by Claude Code

  5. added
    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landed
    and removed
    pm:retriageQuestion for triage, answered each fire; coexists with the standing pm:* label; no dispatch
    on Aug 30, 2026
  6. zhuangjianguo commented on Aug 31, 2026

    @zhuangjianguo
    Collaborator

    定级补齐(skills 席代分诊):priority:p2(domain:services 已在)—— 维护者裁定明言的独立卡:窄化前必须先量 stored-metadata 人口(裁决选项 C 的三步)。fail-closed 的中断代价已在卡上记死 ⇒ ⛔ 任何人不得未量先窄。与 #13543 同族(见彼卡)。


    Generated by Claude Code

  7. os-steve commented on Aug 31, 2026

    @os-steve
    Collaborator

    定级 (domain:services 座位 #6021, 2026-08-31) — finding → pm:on-hold。前提复核通过(含一次差点推翻它的对照);缺的是一个本仓测不到的读数,不是判断力。

    Restart-when: a stored-metadata population reading for reference_to / referenceTo on a controlled_by_parent master-relation field exists — an operator census over a live deployment's metadata tables, a control-plane audit, or a maintainer ruling that no deployment holds such rows and the population may be treated as zero (the same class of reading #12775 is waiting on).
    Restart-touch: packages/plugins/plugin-security/src/security-plugin.ts

    复核:容忍仍在,而且我先试着推翻了这张卡的前提

    在 origin/main 上实测,不是采信原文:

    • 容忍仍在:security-plugin.ts:5918 — const REFERENCE_SPELLINGS = ['reference', 'reference_to', 'referenceTo'] as const;,:5877 的注释记录了 FieldSchema 拒收两个别名而这里仍读它们的原因。fix(security,verify): keep the security reference-alias read tolerant but LOUD, narrow verify with a named finding #13541 把它变响,没有拿掉它 —— 与原报告一致。
    • 反向对照(证明扫描能找到东西):reference_to 在 packages/ + examples/ 的非测试文件里命中 14 个文件。扫描不是空的。
    • 差点推翻前提的那一个:命中里有 packages/plugins/plugin-approvals/src/sys-approval-request.object.ts —— 一个平台对象。若它真的在一个 controlled_by_parent 主从关系字段上拼了别名,本卡的「树内population 为零」就当场为假,卡的形状会从「等读数」变成「有已知迁移对象」。实测:不是。那一处是 :428 的一行注释(说明 console 如何借用 submitter_id 的 lookup 配置渲染用户选择器),该文件通篇没有 controlled_by_parent。前提保住了 —— 但它值得被这样打一次,而不是被转述。

    为什么是 hold 而不是入队

    原报告把要做的事排成了三步,第一步就出不了这个仓:

    1. 给 population 定大小 —— 有多少 raw-registered / 已存储的对象,在解析 controlled_by_parent 主从关系的那个字段上拼了 reference_to / referenceTo。本仓源码扫描已经做完了(fix(security,verify): keep the security reference-alias read tolerant but LOUD, narrow verify with a named finding #13541 时做的,我上面又复核了一遍):只在测试、spec 自己的别名表、以及其他读者的文档里出现,没有任何 example app 或平台对象在 CBP 关系上用它。⛔ 而这恰恰不是要测的那个 population —— 要测的是活部署数据库里存的元数据,那是本仓任何命令都够不到的。
    2. 迁移(仅当 population 非空)。
    3. 才轮到收窄读者。

    第 1 步是硬缺口,不是「还没排上」。派一个 dev 去做这张卡,他能做的只有把我上面这一遍再跑一次,然后停在同一个地方。

    收窄的代价是可用性,不是整洁度 —— 所以不能凭「大概没人用」推进

    这一点原报告写得对,我复核后要把它记得更重:该读者读不中时是fail-closed,读腿答 RLS_DENY_FILTER(对每一个非管理员调用者返回零行),写腿抛 MasterDetailRelationMissingError。也就是说,收窄一个仍可达的读者 = 对一个确实存在的 population 制造停机。而它可达是被实测过的:raw registerObject 绕过 Zod,注册表原样把别名喂回来。

    这就是为什么这张卡 ⛔ 不接受「源码里搜不到 ⇒ 收窄它」这条捷径 —— 那正是把「没测到」当成「测到零」,而两者之间隔着一次停机。

    出处

    维护者 2026-08-30 在 #13250 上裁定(原话「同意」)把真正的收窄划出那张卡的范围,明说是另一张卡,不是搭车。本卡就是那张卡,现在给它一个机器可读的重启条件,免得它变成永久沉默。

    Restart-touch 指向 security-plugin.ts:下一次有人为别的原因动这个文件,巡查会把它顶出来 —— 但 ⛔ 顶出来不等于放行,放行仍以上面的 Restart-when 为准。


    Generated by Claude Code

  8. added
    pm:on-holdDecision made, deliberately deferred — no dispatch, no nag; restart condition in the hold comment
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Aug 31, 2026
  9. objectstack-fleet commented on Sep 23, 2026

    @objectstack-fleet
    Contributor

    关 not_planned —— 维护者选「甲」:保留兼容,不收窄

    分诊席(session_01Tw7jnJinGHvoGSi8aFkhPJ),2026-09-23T10:04Z。维护者 2026-09-23 在分诊会话里逐张复核 pm:on-hold 卡,对第六组的回复原文:「第六组其余 9 张 同意」。本卡在那一组里的建议是关闭。 本卡在那一组里呈了两个选项,推荐的是「甲」,维护者同意了。

    裁定

    resolveCbpRelation(packages/plugins/plugin-security/src/security-plugin.ts)对 reference_to / referenceTo 这两种旧写法的兼容保留,继续由 PR #13541 加上的告警提示。

    为什么

    • 收窄的代价是停机,而不只是代码是否整洁:读不到时是 fail-closed —— 读的那一侧返回 RLS_DENY_FILTER,每个非管理员调用者都看到零行;写的那一侧抛 MasterDetailRelationMissingError。
    • 要判断能不能收窄,得先知道各个在线部署的数据库里还有多少元数据在用旧写法,而这个数量本仓测不到。
    • 保留兼容今天不会造成任何问题(而且会告警)⇒ 没有需要做的事。

    ⚠️ 同一个问题还有一张兄弟卡 #13543。本裁定只针对本卡,⛔ 不替 #13543 做决定。

    重开条件

    有人拿出了在线部署里旧写法的实际数量读数(运维普查、控制面审计,或者维护者明确说可以按零处理),并且有理由要去掉这个兼容。

    关闭理由:not_planned,同时摘掉 pm:on-hold。


    Generated by Claude Code

  10. removed
    pm:on-holdDecision made, deliberately deferred — no dispatch, no nag; restart condition in the hold comment
    on Sep 23, 2026
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

    domain:servicesRetired 2026-10-22, alias of domain:server (services surface); in-flight cards keep it until landedpriority:p2Medium: important, M3

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions