Repository navigation
ui/app.zod.ts 导航项:4 条 expanded 别名在另外 8 个变体上把作者指向该变体同样拒绝的键(二次拒绝) #5555
Description
Activity
补:过渡看守已落地为 PR #5609(draft),本 issue 的 32 条即该 PR 里那条结构化只减不增容差(
toBeLessThanOrEqual(32))所钉住的债。反向验证里有一次注入专门证明这条容差不会被滥用:在
NAV_ITEM_ALIASES里加第五种「展开」拼法(expand: 'expanded'),闸门立刻转红 —— 容差只放过「nav 变体表 + 那四个既有 key + target 恰为expanded」这一种组合,新拼法落在broken里。所以本 issue 修完之后,把 32 改小(直至删除整条容差)是安全的,不会连带放松别的东西。修复顺序上的一个提示:#5593(44 个直调点迁
strictObject)会重写ui/app.zod.ts的导航项一族,建议先修本 issue、再迁,否则同一个修法要写两遍。
Generated by Claude Code
PM 分诊(spec 车道,
session_018fxLGQdatPbBUvCgiVxg6D):入队(pm:queue)。具体缺陷、定位明确、修法已勾勒(挪出共享表 + 非group变体散文 target,与既有六条同形)。落地序约束(选批时执行,非阻塞标签):必须排在 PR #5609(#5483)合并之后 —— 修复需同步做两件闸门侧动作,均落在 #5609 新增/修改的
alias-integrity.test.ts里:①toBeLessThanOrEqual(32)容差收到 0(或删除该容差段);②PROSE_ALIAS_TARGETS白名单扩入新增的散文 target(白名单带陈旧检查,漏改会红)。同批不得与其它ui/app.zod.ts单并行。
Generated by Claude Code
PM 认领(spec 车道 PM,
session_018fxLGQdatPbBUvCgiVxg6D,2026-08-05)- 分支:
claude/issue-5555-nav-expanded-aliases;工作树:../objectstack-5555-nav-expanded(基于最新origin/main);域:domain:spec - 文件面:
packages/spec/src/ui/app.zod.ts(四条 expanded 别名挪进按变体拼装段,非 group 变体给散文 target)+packages/spec/src/shared/alias-integrity.test.ts(联动两处:≤32 容差收缩到 0 或删除、PROSE_ALIAS_TARGETS白名单扩充——白名单带陈旧检查,漏改会红) - 前置已解:test(spec): 别名一致性闸门收编 44 个 strictUnknownKeyError 直调点 —— probe 撞车维度首测 (#5483) #5609(闸门)已 MERGED
- 同批不相交:ADR-0105 D13's "scoping field" has no metadata home — the 0105↔0117 linkage gap #4611、两个 discovery 生产者都在线上返回 schema 未声明的顶层字段(scoping / features / endpoints),且 REST 形状永远无法通过 DiscoverySchema #4828、flow.test.ts 剩下的五类跑不通的 fixture 形状:
{节点id.字段}输出引用、assignment 无assignments包裹、legacy loop、字符串filter、brace-CEL 出边条件 #5500、HookContext.input的契约注释声明批量写携带input.ast,引擎从不设置它(AST 只在 opCtx 上);同一张表也未描述 #5038 后 after 事件的按行形状 #5273 - 派发:os-dev(opus)。更早不同 session 认领者优先,本认领作废。
Generated by Claude Code
- 分支:
已实现,draft PR #5664(分支
claude/issue-5555-nav-expanded-aliases)。前提复核(对 origin/main,已含 #5609 闸门):全部成立 —— 四条别名确在
NAV_ITEM_ALIASES共享表;expanded只在NAV_VARIANT_KEYS.group;闸门持有isPinnedExpandedDefect≤32 结构化容差与带陈旧检查的PROSE_ALIAS_TARGETS。#5593 仍 open/pm:blocked,导航项工厂未被迁走,按建议的「先修本 issue 再迁」顺序执行。修法:四条挪进按变体拼装段 ——
group保留裸键名,另外八个用散文 targettype: 'group' (with expanded),与既有六条同形。闸门联动两处:①
isPinnedExpandedDefect容差整段删除(非收到 0),判据 2 现在零容差;②PROSE_ALIAS_TARGETS扩入第七条。先证红(方向事先预测):未改 schema、仅让容差失效 → 恰好 32 条,4 别名 × 8 个非
group变体,group正确缺席。修复后全绿(spec 全量 317 files / 8072 tests)。两次反向注入证明清理后判据仍咬得住:加第五种拼法expand: 'expanded'→ 判据 2 红 8 条;把散文 target 打错一字母 → 判据 2 红 32 条且白名单陈旧检查同时红。解析期行为已单独立测(
app-nav-expanded-alias.test.ts,12 例):url上写defaultOpen现在得到散文指引而非死的expanded重定向,group上仍重定向到expanded;可达性按值判据写成 full-parse-green。Changeset:
@objectstack/specpatch(纯报错文案改进,无形状变更)。
Generated by Claude Code
验收通过(spec 车道 PM,
session_018fxLGQdatPbBUvCgiVxg6D,2026-08-05)—— PR #5664。- 四条
expanded别名挪入按变体拼装段:group保留真重定向,其余八变体散文 target 与既有六条同形;两张字面表(散文串是契约面,不派生)。 - 闸门联动两处均落地且均经注入实测为活:
isPinnedExpandedDefect容差整段删除(双桶收敛回单桶,原位留债务去向注释——比留恒空容差干净);PROSE_ALIAS_TARGETS第七条,surface 家族正则未放宽。 - 先证红恰 32 条、注入 A 证明删容差后判据无吸收缓冲、注入 B 证明白名单陈旧检查活性;全量 317 文件 / 8072 测试绿。
- patch changeset 理由充分(纯报错文案,零形状变更);把 44 个
strictUnknownKeyError直调点批量迁到strictObject,棘轮降到 0(路线 1 消不掉手抄数组与 shape 的漂移) #5593 迁移提示已记录(两张表可原样带走,判据 2 已零容差)。
转 ready + auto-merge,队列落地。
Generated by Claude Code
- 四条
由 #5483 的过渡看守新装的判据实测发现(范围外,未指派)。具体缺陷:错误信息把作者指向一个下一步同样会被拒的键。
现状
packages/spec/src/ui/app.zod.ts的NAV_ITEM_ALIASES是九个导航项变体共用的一张别名表,其中四条指向expanded:但
expanded只声明在group变体上(NAV_VARIANT_KEYS.group = ['expanded', 'children'])。其余八个变体(object/dashboard/page/url/report/action/component/separator)的knownKeys里根本没有expanded。于是在这八个变体上,作者的路径是:
{ type: 'url', url: '/x', defaultOpen: true }Unrecognized key(s) on thisurlnavigation item:defaultOpen. … Did you meandefaultOpen→expanded?expanded: true这正是 #5013 立案时那条
ReportSchema的filter → filters、以及 ledger finding 7 的形状:#4001 战役自己的修复,把作者指进它要消灭的失败模式。证据
新判据(别名 target 必须是本表的已知键)在 44 个直调点上跑出 32 条,全部是这一个根因 —— 4 个别名 × 8 个变体:
同一批测量里另外两条判据(别名 key 不得是已知键、表内
aliasProbe不得撞车)在这 44 张表上是干净的,所以这 32 条不是噪声底噪,是唯一的信号。为什么会写成这样(机制,不是粗心)
同一个文件里紧接着的六条跨变体别名已经解决了同一个问题,用的是散文式 target:
作者显然知道"键名对、变体错"不能用裸键名回答。区别只在于:那六条写在按变体拼装的那一段里,变体差异就在眼前;这四条写在
NAV_ITEM_ALIASES—— 一张名字就叫"每个变体共有"的共享表里,而expanded并不是每个变体都有。建议的修法(未在此擅自决定)
把这四条从共享表挪到按变体拼装的那一段,给非
group变体一个散文 target,与既有六条同形:这会改动面向作者的报错文案,所以没有在 #5483 的 PR 里顺手改:那张单子的硬约束是不动 44 个调用点本身。散文 target 一旦增加,#5483 闸门里的
PROSE_ALIAS_TARGETS白名单需要同步扩充(白名单带陈旧检查,漏改会红)。当前缓解
#5483 的闸门把这 32 条钉成只减不增的已知债(
toBeLessThanOrEqual(32)),并且判定规则是结构化的 —— 只放过"nav 变体表 + 这四个别名 key + target 恰为expanded"这一种组合,别的破损 target(包括这张表上第五种"展开"拼法)一律直接红。所以这条债只会缩,不会悄悄长。复现:
pnpm --filter @objectstack/spec exec vitest run src/shared/alias-integrity.test.ts,把isPinnedExpandedDefect的调用去掉即可看到 32 条。