[REQ-105][CODE] #319 receipt 记下并显示 Excel 连接器执行物的内容地址 - #1110
Merged
Conversation
REQ-105 AC2/AC5 的缺口不是「版本号错了」,是**数据模型缺一项**:receipt 上的 `version` 取自 catalog 卡片(`mcp:alpha-excel` = 1.0.0),它命名连接器、不命名 连接器执行的字节;`payloadDigest` 只在 `entry.remoteAsset.files` 在场时才有值, 而 MCP 条目没有 remoteAsset ⇒ 修复前 receipt 上零 digest 能指认执行物; `manifestDigest` 覆盖的是合成 manifest 的 canonical JSON,里面没有 installSpec/命令/钉版,换掉 server.py 它一个字不变。renderer 那一侧更早断: `toV1Receipt` 投影时丢掉全部 digest,而 renderer 读的正是这份 v1 视图 (`listInstalls` → `ext-list-installs`)。 改动: - `ext-mcp-policy.ts` —— 随包 Office server 的 realpath 本就只有这道写盘闸口在解, digest 与那次解路径同点取得(不留「解的是 A、哈的是 B」的缝)。放行时返回 `artifactDigest`(与 skill payloadDigest 同域 = aggregateFilesDigest);读不出 随包文件与「随包 server 不可用」落同一条 fail-closed 分支。 - `ext-install-planner.ts` —— 单装与 bundle 成员两条路都把裁决里的 digest 原样落进 receipt(planner 不自算、不推断);seed 路径按既有语义仍拒 workspace-policy MCP。 - `ext-receipt-v2.ts` / `preload/types.ts` / `alpha-installs.ts` —— digest 随 v1 投影 出到 renderer 读得到的那份视图;落盘校验只认合法形状或不在场。 - `shared/receipt-artifact-facts.ts` + `extension-detail.tsx` + i18n —— 头部在版本旁 显示短 digest(完整值在 title/data 属性);缺省或形状非法一律显式说「未记录」, 不留空、不拿 catalog 版本顶上(AC5)。 判据: - 落盘 + 重启可恢复:装完直接 `JSON.parse` 账本文件,records[] 与 receipts[] 两份 视图都必须带上独立算出的内容地址 —— 只记在内存里的实现在这里必红。 - digest 追内容不追路径(同路径不同字节必须不同值),且不是 manifestDigest 的别名。 - 非 Office 的 MCP 不得凭空多出 digest;畸形串不得被当身份呈现。 - 详情页判据挂在生产 ExtensionDetail 上(真 Solid DOM),已登记进 scripts/gate-files.tsv。 Refs jinjunnn/alpha-work#7 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj
Uh oh!
There was an error while loading. Please reload this page.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes#319
Refs jinjunnn/alpha-work#7
先勘破:「当前显 1.0.0 与静态 0.1.8 不一致」今天长什么样
票面括号里的
0.1.8是 2026-07-14 审计时的社区excel-mcp-server,REQ-133/REQ-135 之后它已退役(
shared/office-advisories.ts:61-68),Hub Excel 只剩随包的mcp:alpha-excel。数字换了,形态一个字没变,而且在代码里可逐行指认:
1.0.0packages/ui-mac/src/renderer/extensions/alpha-catalog.json:194office-mcp/server.py+ 钉版openpyxl==3.1.5alpha-catalog.json:196-208version取的就是那个卡片版本packages/ui-mac/src/main/ext-install-planner.ts:426(entry.version ?? catalogVersion)→:1362payloadDigest只在entry.remoteAsset.files在场时才有 —— MCP 条目没有 remoteAsset ⇒ 修复前恒缺省ext-install-planner.ts:432-440manifestDigest覆盖的是合成 manifest 的 canonical JSON,不含 installSpec/命令/钉版 ⇒ 换掉 server.py 它一字不变ext-install-planner.ts:418-442+ext-manifest-v2.ts:301-303ext-receipt-v2.ts:793-805(修复前)alpha-installs.ts:214→ext-ipc.ts:440→preload/index.ts:235→use-extensions.ts:523→extension-detail.tsx:646ext-list-installs-v2在ext-ipc.ts:1296注册,但没有 preload 绑定,renderer 消费不到preload/index.ts所以这不是「版本号写错了」,是数据模型缺一项:receipt 上没有任何一个字段能指认
「这次安装会执行哪一份字节」,于是
1.0.0既证伪不了也印证不了。改了什么
main/ext-mcp-policy.ts—— 随包 Office server 的 realpath 本来就只有这道写盘咽喉在解(
:69-77),digest 与那次解路径同点取得,不留「解的是 A、哈的是 B」的缝。放行时返回artifactDigest(aggregateFilesDigest,与 skillpayloadDigest同域);读不出随包文件与「随包 server 不可用」落同一条既有 fail-closed 分支 —— 不写一张说不出执行物的 receipt。
main/ext-install-planner.ts—— 单装 MCP 与 bundle 成员两条路都把裁决里的 digest 原样落进 receipt(planner 不自算、不推断)。seed 路径按既有语义仍拒 workspace-policy MCP,未动。
main/ext-receipt-v2.ts/preload/types.ts/main/alpha-installs.ts—— digest 随 v1 投影出到 renderer 真正读得到的那份视图;落盘校验只认合法形状或不在场。
shared/receipt-artifact-facts.ts(新)+extension-detail.tsx+ i18n(en/zh) —— 头部在版本旁显示短 digest,完整值在
title与data-artifact-digest上;缺省或形状非法一律显式说「未记录」,不留空、不拿 catalog 版本顶上(AC5:不得把未知或未验证 digest 表示为已审计)。
scripts/gate-files.tsv—— 新的子进程宿主按#647登记簿要求登记(不登记即红,实测)。CHANGELOG.md—— 用户可见变化,含四条诚实边界。判据,以及它们真的会红
八次绕过实验,每次都在干净树上做、跑完
git checkout --还原并复验干净:2 fail,planner3 fail2 fail—— 落盘与重启两条1 fail—— 正是「重启后两份视图」那条manifestDigest冒充 payloadDigest2 fail10 fail;组件里 DOM 实测渲染出Artifact digest sha256:deadbeef…,即 AC5 要禁的那一幕2 fail+ planner1 fail2 fail+ planner3 fail判据设计上刻意避开两个本仓踩过的坑:
node:crypto现算随包 server.py 的字节,不 import 生产返回值、不抄字面量常量;另加一条「换成不可能的文件哈希聚合值必须不同」,
堵掉「压根没读文件、只返回常量」。
JSON.parse账本文件,records[]与receipts[]两份视图分别判(E3 证明这不是一句空话:只丢 v1 那半边,判据照红)。
本地门(真实输出,非「应该会绿」)
base =
origin/alpha@8ba7d11ec,base fail-set 空(先量的:typecheck exit 0;4455 pass / 0 fail / Ran 4455 tests across 308 files)。与 base 的差:
+24 pass / ±0 fail / +2 files。24 条正是本 PR 新增的判据数(policy 4、planner 4、纯函数 15、子进程宿主 1;组件 4 条在子进程内跑,不计入 ui-mac 计数)。
seed 资产门不适用 —— diff 未触及
resources/extension-seed、同步脚本或 catalog 快照。pre-push 用了
--no-verify:钩子 exec 的是scripts/alpha-check.sh,它第 [8/9] 步会在共享主 checkout 里真建探针 worktree 并写共享
core.hooksPath;此刻ac-1108/ac-402两条 lane 在跑,CLAUDE.md 明确要求并行期间不得逐 lane 跑它(会互相制造假红,并泄漏探针树)。
上面四道门已在本 worktree 内逐一跑过。push 前后确认:
core.hooksPath仍是.githooks、git worktree list无新增探针树。明确没做的事(留给主 session 裁决)
与 receipt 显示完全一致的 digest」,但 catalog 侧是 alpha-web 产出、
alpha-catalog.json是生成快照(REQ-133 基线原文:"not edited by either decision"),且构建侧被本票列为 out-of-scope。
本 PR 只做桌面端能独立取得且可复现的那一半:随包字节的内容地址。
建议(不是本票 AC):开一张跨仓票,让 catalog 的
mcp:alpha-*条目携带同一域的artifact digest,再加一条「catalog 值 ≠ receipt 值即拒装」的闸 —— 那时 AC2 的「完全一致」
才是可机器判定的。
openpyxl==3.1.5)的字节。 它由uv run --with在首次运行时联网取,桌面端装的时候拿不到,伪造一个就是把未验证的东西说成已审计。钉版本身仍由既有的
exact-command 闸口(
checkAlphaOfficeMcpSafety)逐字守着。启动比对随包字节是否仍与 receipt 一致」,那是一条新行为(且要先定漂移了怎么处置),
超出本票 AC。建议另开票。
ext-list-installs-v2补 preload 绑定。 它注册了却无 renderer 消费方 —— 是既有状态,不是本票引入的;本 PR 走 v1 投影这条 renderer 真正在读的路,没有顺手扩通道。
建议记一张清理票(要么接上,要么删掉)。
.claude/rules/adrs/里的 ADR-028。 receipt schema 描述在受保护的 rule 资产里,改它是一次决策而不是实现。建议由主 session 判断是否需要同步一句。
alpha-ext-dhead-meta行里的一个<span>+ 一个复用alpha-ext-dhead-id样式的<code>芯片(与同一行里已有的 id 芯片同款),没有新组件、没有新视觉语言。若认为仍需过 design-loop,请裁决。
🤖 Generated with Claude Code
https://claude.ai/code/session_01QHDS2BFKuzm9uNH1svU2oj