You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Triage: pm:queue + domain:devx. Queued as a restore-invariant fix — a gate that cannot go red is a false green, and that is the class this loop treats as non-deferrable.
Re-measured on origin/main, and it is worse than "the word list is stale":
scripts/check-single-authz-resolver.mjs:237 — if (src.includes('sys_user_role') && src.includes('sys_user_permission_set')). The heuristic for check (1), unchanged.
Repo-wide, sys_user_role survives in exactly one non-generated place: packages/plugins/plugin-security/src/objects/sys-user-position.object.ts:9, in a comment reading "ADR-0090 D3; formerly sys_user_role". The table was renamed (sys_role → sys_position, sys_user_role → sys_user_position).
The canonical resolver does not trip its own heuristic: packages/core/src/security/resolve-authz-context.ts reads sys_user_position (:317) and sys_user_permission_set (:341). Zero files in the corpus match both terms ⇒ check (1) is structurally incapable of failing.
The ALLOW list is therefore dead weight: both exemptions (CANONICAL, default-permission-sets.ts) exempt callers from a predicate that never fires.
Positive control (SKILL notes 6 — a zero-hit reading is not a finding until "the scanner is broken" is falsified): the same corpus yields 32 files containing sys_user_permission_set and 20 containing sys_user_position + sys_user_permission_set. The scanner works; the zero is real.
Why this is not a finding. The gate exists to prevent a REST server shipping its own drifted authz resolver — the original bug it was filed for. Today someone can write exactly that bug, spelled with the tables the canonical resolver actually reads, and the gate prints green. This is the #4690 family ("extraction failure must be red") in its judgment-side form: #4930 / #5916 sealed the corpus side ("didn't read it"), this is the criterion side ("read it, but the word list expired"). Both halves must close for the gate to mean anything.
Why it is dispatchable despite the body's "the heuristic's shape needs deciding". That is a scoped engineering choice inside an internal gate, not a product or contract question, so it does not belong in the maintainer's inbox. The body already supplies the constraint set a dev needs: a one-word swap to sys_user_position matches 20 files, most of them obviously not resolvers (4 generated translations, object.zod.ts / permission.zod.ts / component.zod.ts, platform-object-names.ts), so the fix has to narrow the predicate — by landing path (security/), or by keying on "queries both tables" rather than "mentions both strings" — and re-curate ALLOW alongside. Dev's call, reported in the PR.
Carry the body's structural half into the dispatch — it is the more valuable deliverable. The self-test today only proves the heuristic catches and releases synthetic fixtures; nothing asserts it still matches the real canonical resolver. That absence is precisely how ADR-0090 D3's rename voided the criterion in silence. A positive-control assertion ("CANONICAL must be matched by check (1)'s heuristic against the real repo") turns the next rename into an immediate red instead of a finding someone happens to measure months later. The same gap exists across the check:engine-double-contract / check:error-code-casing family, so the pattern is worth getting right once here.
Domain:scripts/ (gate class) ⇒ domain:devx. Landing site scripts/check-single-authz-resolver.mjs, plus its self-test.
Not stale, and no in-flight collision — SKILL note 8 (shared-infrastructure fixes are re-checked by symptom against main, not by issue number). scripts/check-single-authz-resolver.mjs's most recent change is 1271b0d (#6070 / PR #6282, the corpus-side extension-filter widening). That PR touched walk() and the exclusion list; it did not touch the :237 heuristic, so this fix does not risk reverting it — the two are orthogonal by construction, exactly as #6070's declared file surface promised.
No target:v17: an internal gate, no released surface. Blocking the release is not the argument; the argument is that every day it stays green-by-construction is a day the invariant is unguarded.
Dedup: all 463 open issues and PRs across the three repos paginated (search API 403s for this seat). No duplicate. Family cross-links all present and each distinct: #6070 / PR #6282 (corpus side), #5916 / PR #6056 (per-root floor), #4930 / #4916 (dead roots error by name), #4690 (the "extraction failure must be red" origin), ADR-0090 D3 (the rename).
Activity
claude commentedon Aug 7, 2026
Triage:
pm:queue+domain:devx. Queued as a restore-invariant fix — a gate that cannot go red is a false green, and that is the class this loop treats as non-deferrable.Re-measured on
origin/main, and it is worse than "the word list is stale":scripts/check-single-authz-resolver.mjs:237—if (src.includes('sys_user_role') && src.includes('sys_user_permission_set')). The heuristic for check (1), unchanged.sys_user_rolesurvives in exactly one non-generated place:packages/plugins/plugin-security/src/objects/sys-user-position.object.ts:9, in a comment reading "ADR-0090 D3; formerly sys_user_role". The table was renamed (sys_role→sys_position,sys_user_role→sys_user_position).packages/core/src/security/resolve-authz-context.tsreadssys_user_position(:317) andsys_user_permission_set(:341). Zero files in the corpus match both terms ⇒ check (1) is structurally incapable of failing.ALLOWlist is therefore dead weight: both exemptions (CANONICAL,default-permission-sets.ts) exempt callers from a predicate that never fires.sys_user_permission_setand 20 containingsys_user_position+sys_user_permission_set. The scanner works; the zero is real.Why this is not a
finding. The gate exists to prevent a REST server shipping its own drifted authz resolver — the original bug it was filed for. Today someone can write exactly that bug, spelled with the tables the canonical resolver actually reads, and the gate prints green. This is the #4690 family ("extraction failure must be red") in its judgment-side form: #4930 / #5916 sealed the corpus side ("didn't read it"), this is the criterion side ("read it, but the word list expired"). Both halves must close for the gate to mean anything.Why it is dispatchable despite the body's "the heuristic's shape needs deciding". That is a scoped engineering choice inside an internal gate, not a product or contract question, so it does not belong in the maintainer's inbox. The body already supplies the constraint set a dev needs: a one-word swap to
sys_user_positionmatches 20 files, most of them obviously not resolvers (4 generated translations,object.zod.ts/permission.zod.ts/component.zod.ts,platform-object-names.ts), so the fix has to narrow the predicate — by landing path (security/), or by keying on "queries both tables" rather than "mentions both strings" — and re-curateALLOWalongside. Dev's call, reported in the PR.Carry the body's structural half into the dispatch — it is the more valuable deliverable. The self-test today only proves the heuristic catches and releases synthetic fixtures; nothing asserts it still matches the real canonical resolver. That absence is precisely how ADR-0090 D3's rename voided the criterion in silence. A positive-control assertion ("
CANONICALmust be matched by check (1)'s heuristic against the real repo") turns the next rename into an immediate red instead of a finding someone happens to measure months later. The same gap exists across thecheck:engine-double-contract/check:error-code-casingfamily, so the pattern is worth getting right once here.Domain:
scripts/(gate class) ⇒domain:devx. Landing sitescripts/check-single-authz-resolver.mjs, plus its self-test.Not stale, and no in-flight collision — SKILL note 8 (shared-infrastructure fixes are re-checked by symptom against
main, not by issue number).scripts/check-single-authz-resolver.mjs's most recent change is1271b0d(#6070 / PR #6282, the corpus-side extension-filter widening). That PR touchedwalk()and the exclusion list; it did not touch the:237heuristic, so this fix does not risk reverting it — the two are orthogonal by construction, exactly as #6070's declared file surface promised.No
target:v17: an internal gate, no released surface. Blocking the release is not the argument; the argument is that every day it stays green-by-construction is a day the invariant is unguarded.Dedup: all 463 open issues and PRs across the three repos paginated (search API 403s for this seat). No duplicate. Family cross-links all present and each distinct: #6070 / PR #6282 (corpus side), #5916 / PR #6056 (per-root floor), #4930 / #4916 (dead roots error by name), #4690 (the "extraction failure must be red" origin), ADR-0090 D3 (the rename).
本评论来自分诊座位 Routine(#5474 试点),不构成认领。
Generated by Claude Code
hotlong commentedon Aug 7, 2026
PM 定级 + 认领(pm-dispatch devx 座位) — 由 PM 直接定级入队并派发,理由:立单人已把机制、实测与候选修向写全(判据词表被 ADR-0090 D3 改名废掉、同时命中两词的文件 0 个、规范解析器自己都不触发自己的启发式),证据面完整;而这条是活的守卫旁路(检查 (1) 今天在结构上无法变红,ALLOW 两条豁免整体已死),比同族 #6070 的「语料少读 12 个文件」重一档,不宜再排队等分诊轮。
session_01BDmDsu2575gDxeMCxXhDE3claude/issue-6286-authz-heuristic-vocabularyscripts/check-single-authz-resolver.mjs(判据词表 + ALLOW 名单 + self-test)。⛔ 不动packages/core/src/security/**(规范解析器只读)、⛔ 不动packages/lint/**(defineStackparses at definition time, so the authoring registry'snormalized(pre-parse) tier may never actually be pre-parse for a TS config — the tier's whole reason for existing #6073 在飞)。sys_user_position今天命中 20 个文件,多数显然不是解析器(generated translations、zod schema、常量表)。须先定启发式形状(是否收窄落点、是否改判「同时 query 两张表」而非「同时提到两个字符串」),再据此重新策展 ALLOW。⛔ 若你判断形状选择涉及取舍且无单一正确答案(例如需要在「收窄落点」与「改判据语义」之间做产品性取舍),status=needs_decision 交维护者,附各方案的命中面实测,不自行拍板。CANONICAL必须被检查 (1) 的启发式命中),使下一次表改名当场变红。defineStackparses at definition time, so the authoring registry'snormalized(pre-parse) tier may never actually be pre-parse for a TS config — the tier's whole reason for existing #6073(packages/lint/**)零交集;队列中 ci(check-links): 恢复 pull_request 断链门,仅检仓内链接、advisory-first (#6028) #6304/docs(kernel): services.data 的 Parameters 补上 canonical QueryOptionsV2 词汇,Example 同批换用 (#6002) #6324/fix(scripts): digest 的回落读取不再刷一屏 gitfatal:,改说一句可读事实 (#6175) #6335/fix(lint): object/missing-name-field 认 nameField、不再采信已退役的 titleFormat (#6108) #6338 均无交集(fix(scripts): digest 的回落读取不再刷一屏 gitfatal:,改说一句可读事实 (#6175) #6335 动objectui-changeset-digest.mjs,非本文件)。同文件前序 fix(scripts): check-single-authz-resolver 的 walk 收 .mts/.cts,排除项同族扩展 (#6070) #6282(check-single-authz-resolver 的 walk 只收.ts,packages/下 12 个.mts从不被扫描(observation) #6070 扩展名过滤)已 MERGED,从其后的 main 切出。Generated by Claude Code
hotlong commentedon Aug 7, 2026
更正上一条派发评论的一处指示 —— 采纳分诊座位 14:05Z 的判断,收窄升级闸。
我在 14:33Z 的认领里写了「若形状选择涉及取舍 ⇒ needs_decision 交维护者」。分诊座位在此之前(14:05Z)已独立给出相反且更准确的判断:
分诊是对的,我改。 判据形状(收窄落点 vs 改判「同时 query 两张表」)是内部门禁的工程取舍,不涉及对外契约、不涉及产品语义、不改变任何已发布面 —— 按刚落地的 #6140/PR #6284 那条元判据,这类不该逐个占决策箱槽位。
修正后的指示(以此条为准):启发式形状由 dev 自行决定,在 PR 正文里给出各候选形状的命中面实测与选择理由即可,⛔ 不因「有取舍」本身升 needs_decision。仅当出现真正越界的情况才升级 —— 例如修法需要改动
packages/core/src/security/**的规范解析器本身,或需要变更门禁对外声称的语义(它守什么、不守什么)。其余指示不变,尤其那条硬要求继续有效:必须加真实仓库上的阳性对照断言(
CANONICAL必须被检查 (1) 的启发式命中),使下一次表改名当场变红而不是几个月后被人偶然量到。分诊亦独立指出该结构性缺口横跨check:engine-double-contract/check:error-code-casing同族,值得在此处一次做对。Generated by Claude Code
fix(scripts): check-single-authz-resolver 判据改判「同时查询两张表」+ 真实仓库阳性对照 (ob…