发现于 #4754 的实现期(修 `packages/runtime/src/domains/packages.ts` 那处静默 catch 时读到)。**未认领 —— 只是记录。观察类:操作幂等,重跑一次就好。** ## 现象 `POST /packages/:id/publish-drafts` 的 ADR-0045 可见性翻转段(`packages/runtime/src/domains/packages.ts`),结构是: ```ts const unhidden: string[] = []; for (const app of apps) { if (app?.hidden === true && typeof app.name === 'string') { await protocol.saveMetaItem({ /* … hidden: false … */ }); unhidden.push(app.name); } } if (unhidden.length > 0) result.unhiddenApps = unhidden; // ← 只在循环全程无异常时才执行 ``` `unhiddenApps` 的赋值在**循环之后、try 之内**。所以 5 个 app 里第 3 个 `saveMetaItem` 抛异常时:前 2 个**确实已经翻转并落盘了**,但 `unhidden` 数组随栈丢弃,`result.unhiddenApps` 压根不存在。 ## 后果(两层,都不大) 1. **响应少报了真实发生的事。** 调用方看到的是「翻转失败」,看不到「其中 2 个已经成功」。属于 AGENTS.md「Route & surface ownership」第 4 条(machine-readable surfaces must not lie)的轻量版 —— 不是撒谎,是漏报。 2. **`metadata:reloaded` 对这 2 个 app 漏播。** 紧跟其后的重绑定段读的正是这个字段: ```ts ...(((result as any)?.unhiddenApps ?? []) as string[]).map((n) => `app/${n}`) ``` 字段缺失 → 这 2 个已经变可见的 app 不进 `changed` → boot-cached 的消费者(首当其冲是 automation engine)不重新同步它们,得等下一次重启。 ## 为什么不塞进 #4754 #4754 的范围是「`saveMetaItem` 进词表 + 逐处判持久性丢失」,那处 catch 已按范本改成 `error` 并写清后果与修复动作。本条是**同一段代码里的另一个缺陷**(部分进度的报告丢失),和日志级别无关,改它要动 `unhidden` 的作用域和响应语义 —— 与该单的清账互不依赖,单独立卡。 ## 建议做法 把 `unhidden` 提到 try 之外,并在 catch 里一并回填:成功多少就报多少。重跑本身是幂等的(已翻转的 app `hidden !== true`,循环会跳过),所以这纯粹是让报告与事实一致,不改变恢复路径。 ## 关联 #4754(同一段 catch 的日志级别清账)、ADR-0045(publish 让包 live 且可见)、AGENTS.md「Route & surface ownership」第 4 条。
Activity
baozhoutao commentedon Aug 5, 2026
发现分诊轮判级(session_01VkPSGsX9o17MsGv3Lbxu2w,2026-08-05):晋级
pm:queue,同时挂pm:blocked。Blocked-by: #5155两点说明:
domain:engine改domain:cli:按锚定规则(修复落点的包),本单落点packages/runtime/src/domains/packages.ts,packages/runtime属 cli 域 —— 原 engine 标签是按主题猜的,cli 车道 PM 据实纠正。claude/issue-5155-dispatcher-request-kernel)的声明文件面含packages/runtime/src/domains/**全量(DomainHandlerDeps 重接线),与本单同文件。HttpDispatcher 把「本请求解析出的 kernel」存在实例字段上(this.kernel),多租户 host 上并发请求会互相串改 #5155 落地后解锁,届时先核对packages.ts的unhiddenApps段是否被重接线移动过再派。前提核验见 #4604 01:57Z(对
b4ad98435成立:赋值在循环之后)。晋级理由:翻转中途失败时已落盘的 app 从响应整批消失,metadata:reloaded连带漏播 —— 用户可达的静默丢数据。维护者可否决。Generated by Claude Code
baozhoutao commentedon Aug 5, 2026
解锁(cli 车道 PM,session_01VkPSGsX9o17MsGv3Lbxu2w,2026-08-05):Blocked-by #5155 已随 PR #5385 合并(main
fd8521f92)达成,摘pm:blocked回队列。前提已按解锁条款对新 main 重核:unhiddenApps赋值仍在packages/runtime/src/domains/packages.ts:230、仍在循环之后,重接线未移动该段 —— 前提完好,可正常派发。派发时注意:该文件刚被 #5385 重签名(域处理器改收 context 首参),dev 以origin/main现状为准。Generated by Claude Code
baozhoutao commentedon Aug 5, 2026
🔒 认领:PM 循环第 2 轮(cli 车道)
会话:
session_01VkPSGsX9o17MsGv3Lbxu2w分支:
claude/issue-5242-packages-unhidden-appsWorktree:
objectstack-issue-5242域:
domain:cli文件面:
packages/runtime/src/domains/packages.ts+ 测试 + changeset。与同批 #5341 / #5382(均在packages/cli)不相交;#5385 已合并,本文件无在飞触碰。同日 churn(高):本文件今日刚被 #5385 重签名(域处理器改收 context 首参、kernel 从
context.kernel取)—— issue 引用的行号与周边结构已变,前提本身已由 PM 对fd8521f92重核成立(packages.ts:230赋值仍在循环之后)。基于合并后代码工作,新增改动遵循 #5385 确立的显式传参姿态。Generated by Claude Code
baozhoutao commentedon Aug 5, 2026
✅ 验收通过 —— PR #5392,转 ready 挂合并队列(队列等全绿收单)
对实况复核(cli 车道 PM,session_01VkPSGsX9o17MsGv3Lbxu2w):
unhidden在 try 内声明、赋值在循环后、announce 段读该字段),与 PM 解锁时的独立核验一致。saveMetaItem独立落盘、无联合事务可预判,预校验既不可靠也补不上报告缺口。unhidden提到 try 外、逐个兑现后 push、赋值移到 try/catch 后且仍在 announce 之前(顺序承重,注释钉住);部分失败时unhiddenApps与unhideError并存 —— 「名出什么翻了、什么没翻」;广播补播已落盘翻转。响应契约不变(200,同两字段,互斥本是缺陷副作用)。重跑幂等。saveMetaItem是 #4632 词表覆盖不到的持久性接缝:8 处 catch 完全静默吞掉元数据写入失败 #4754 日志措辞:「全部仍 hidden」在部分落盘时是假话 —— 现按两半如实点名;总失败路径逐字不变,saveMetaItem是 #4632 词表覆盖不到的持久性接缝:8 处 catch 完全静默吞掉元数据写入失败 #4754 的日志断言原样通过。诚实优先,认可。changed恰为已落盘两项、日志两半点名;反向验证方向预判命中(expected undefined to deeply equal ['alpha','beta']—— 缺陷本身);runtime 整包 91 文件 / 1337 用例绿;durability-log-level 与 nul-bytes 门通过。CI 完成项绿,余项由 auto-merge 等待。跟到 MERGED。
Generated by Claude Code
fix(runtime): publish-drafts 中途失败时,已落盘的可见性翻转不再从响应消失 (objectstack-ai#5242