Skip to content

[REQ-128][CODE] 将 package compatibility 单一权威接入 Catalog、详情与安装预检 #702

Closed

Description

@jinjunnn

⚠️ 本期范围裁决(2026-07-30,owner)—— 优先于下方原文与基线

REQ-128 分四相,本期只做 Phase 1,只支持单组件 package(无 Bundle)。裁决见
alpha-work#49。

一、上游已交付,本票 pin 它们

产物 位置
host contract(#694) alpha-code@55890367,packages/ui-mac/src/shared/host-extension-package-contract/,aggregate SHA c3c53e05…
producer artifact(alpha-web#95/#97) alpha-web@b7174810,contracts/extension-package/artifact/,aggregate SHA ae9f43cc2a7cf279ff06d2846ff45f39cbb0fdd2fd0c4c5d91718968692e4887
secret prerequisite(#696) alpha-code@77b5554e,shared/package-secret-prerequisite.ts

Phase 1 契约闭包:profile = skill/agent/mcp-local/mcp-remote(无 cloud);
mcp-remote 的 auth 枚举不含 oauth/alpha-connection;
capability 词表只有 alpha.secret-prerequisite.v1。

二、本票被删除的范围(不实现,不写它们的测试)

  • Development plan 第 4 条的「同 ID package shadow legacy」与「binding mismatch 不 fallback」
    —— 本期不做 legacy projection,因此不存在同 ID legacy 对偶,这两条无对象。
    保留:malformed package 本身被拒;连 prelude 都无法安全解码时拒整个新快照并回 LKG。
  • Acceptance 里 catalog-package-legacy-compat.test.ts 的 v0.1.0–v0.1.2 oracle 与
    shadow/no-fallback
    半场。该文件已由 #694 交付,现在测的是旧壳同级键容忍
    与 entries[] 非空,本票沿用它、不要改回 oracle。
  • safe view 里的 skippedOptional[] 与 prerequisite 的 optional-disconnected
    —— 单组件 package 没有 optional child;optional-disconnected 属 Alpha Connection(#704,Phase 2)。
    Phase 1 的 prerequisite 状态只需 ready | required-action。
    不要为将来保留这两个字段的插槽。

三、alpha.secret-prerequisite.v1 的兑现在本票下游

#696 交付的 shared/package-secret-prerequisite.ts 目前零生产调用者 ——
运行期入口链由本票(evaluator 接线)与 #713(admission)交付。
本票负责让 evaluator 真的消费它做 prerequisite 判定;
端到端兑现证据由 #713 收尾时给出,本票不声称已闭合。

四、从前三票两轮审计学到的、必须带进本票的四条

  1. artifact SHA 门是字节漂移门,不是语义门。 #694 R1 实测:把 URL 的 HTTPS/凭证/canonical
    判断整个禁用后重新生成 artifact,SHA --check 全绿。本票的 consumer drift gate 同理 ——
    必须另有直接断言语义的负向用例。
  2. 闸门要测我们真走的那条路。 #696 R2 实测:canary 闸靠把 entry.source 改成 "alpha" 才够得着
    分支,而真实 catalog 里 8 条 MCP 一条 alpha 源都没有 ⇒ 每次真实首装走的是未覆盖的分支。
    写任何闸门前先问:这条路,走我们自己的 catalog 和 runbook,到得了吗?
  3. 条件门的判据不能与被校验对象同源。 alpha-web#95 R1 实测:pin 校验闸的 skip 判据
    就是被校验的 pin 本身 ⇒ 伪造一套自洽的假 pin,闸门自己关掉并通过。
    本票 vendor #97 artifact 时会遇到同一形态 —— 取不到就必须红,不能跳过。
  4. 源码文本闸门挡不住组装点。 #696 R1 实测:零回显闸读 7 个硬编码源文件,
    而 preload result 的真实组装点不在清单里 ⇒ 两个绕过全绿。断言返回值,不要断言源码文本。

五、反过度工程(owner 直令)

必须在当前框架下开发。remote-catalog.ts / catalog-channels.ts 的签名、信任、快照集一致性、
密钥轮换/吊销、LKG 已完备,不要动它们。不新建通用框架 / 抽象层 / registry 引擎;
不引入新依赖;不为 Phase 2/3/4 预留插槽、空接口、TODO 钩子;不做预防性抽象;
发现超范围缺陷写回票,不顺手修。

Covers

alpha-work#49 AC3/AC4/AC7:把 host contract 与 web producer corpus 接到
Catalog refresh、browse、detail 与 install preflight,建立 main-owned 单一兼容权威。

Solution baseline

REQ-128 accepted baseline
§2.3、§2.5。

Ground truth and boundary

  • 主要落点:
    • packages/alpha-contracts-consumer/**:pin alpha-web#97 artifact。
    • packages/ui-mac/src/main/remote-catalog.ts
    • packages/ui-mac/src/main/catalog-channels.ts
    • 新 packages/ui-mac/src/main/package-installability.ts
    • preload/shared safe-view types 与 production wiring tests。
  • renderer 只接 CatalogPackageViewV1,不接 execution payload、asset URL、config 或
    secret target。

Development plan

  1. vendor docs: S18 开批 —— REQ-022~038 全量清扫批(冲突矩阵 + 拍板落档) #97 schema/vectors/profile rules,锁 commit + SHA,接现有 consumer drift gate。
  2. 实现唯一 evaluatePackageForHost():验 shallow header/binding → profile/capability →
    payload fetch/strict decode → safe projection。
  3. 冻结 safe-view union:
    • verdict compatible | update-required | blocked
    • main-owned action/reasonCode
    • skippedOptional[]
    • prerequisite ready | required-action | optional-disconnected
  4. Catalog refresh、browse、detail 与 install preflight全部调用同一函数;同 ID package
    shadow legacy,malformed/binding mismatch 不 fallback,无法解 prelude 回 LKG。
  5. install IPC 只收 catalogId/scope/attempt/grants;main 重取已签 snapshot并重判。

Acceptance and named gates

  • package-installability.wiring.test.ts:四条生产入口同源,renderer tamper 无效。
  • catalog-package-legacy-compat.test.ts:v0.1.0–v0.1.2 oracle、shadow/no-fallback/LKG。
  • unknown profile/capability 对 payload fetch/decoder/secret/OAuth/planner 调用数为零。
  • safe-view reason/action exhaustive;远程文案不能决定按钮或安全 verdict。

Dependencies

Blocked by alpha-code#694 和 alpha-web#97。

Out of scope

认证执行、transaction、renderer 页面实现、动态 decoder、provider-specific UI。

Exit condition

Merged PR + pinned artifact + production wiring tests + canonical docs impact handled。

Activity

  1. self-assigned this
    on Jul 30, 2026
  2. added
    type:featureNew user or system capability
    prio:P1High-value near-term delivery
    area:integrationRepository, API, or external integration
    cross-repoRequires coordinated work in multiple repositories
    on Jul 30, 2026
  3. jinjunnn commented on Jul 30, 2026

    @jinjunnn
    OwnerAuthor

    从 #694 R1 审计转记的一条

    #694 交付的是纯 decoder + 注入式 effects,其 synthetic decoder 先 fetch 全部字节、
    再比对 payloadRef.bytes
    。审计判定这属生产接线问题,不该在契约票拦,转到本票。

    要求:本票做生产 fetch 接线时,在读取字节前就用 payloadRef.bytes 设上界,
    恶意/故障服务器不得靠无界响应体拖垮 main。请在本票的 named gate 里加一条可执行断言
    (喂一个声称 1KB、实际持续吐字节的响应,证明读取在上界处中止且零落盘)。

  4. added a commit that references this issue on Jul 30, 2026
  5. jinjunnn commented on Jul 31, 2026

    @jinjunnn
    OwnerAuthor

    跨模型对抗审计记录:R1 + R2(2026-07-31)

    M 级预算 ≤2,已用满。PR #728 squash 合并为 691f5a57。

    特殊情况:实现方 codex 两次被外部杀在自检阶段(都不是看门狗),没留下自检报告 ——
    无第零问检查、无 OUT-OF-SCOPE、无"拒绝的扩张"。代码之外的一切事实由编排者逐条复核,
    并在派审时明确告知审计方"平时由实现方自证的部分这次没人做过"。

    R1:52 处 mutation,30 处零红存活

    # 判定
    B1(Blocker) 那道「四条生产入口同源」的 named gate 测的不是生产入口 —— wiring 用例自己拼四条链,调的三个函数一个都不是真入口 ⇒ 五处真实接线任删其一,3288 条全绿 修
    M1 detail IPC 忽略 catalogId 也全绿(单夹具盲区,与 #696 canary 同构) 修
    M2 preflight 两条失败分支(catalog 不可用/形状非法)可 fail-open 落回 legacy planner 修
    m4 契约文档声称 consumer 闸执行 production host decoder —— 结构上跨包 import 不到;且 HTTPS/凭据由 producer 编译器拦、published schema 本身放行那两条负向向量 修(措辞)
    m1/m2/m3 三处覆盖缺口(reason code 行为断言、fetchPackagePayload 零覆盖、preflight 值校验零覆盖) 转记 #713 —— 今天均不可达,#713 让它们上路

    编排者自己核实过的(未采信实现方,因其无自证):四条入口结构、safe view 形状
    (零 payload/URL/config/secret target)、vendored artifact 逐字节与 pin、漂移门是真语义门、
    闸门登记簿、typecheck 与 base 一致、north-star。

    R2:R1 四条全 FIXED,又开出 2 Major

    # 判定
    Major-1 cases 里 {verdict:"blocked"} 近乎恒真(preflight 每条失败分支都是 blocked)⇒ 把 loadVerifiedCatalog 换成恒返回 {source:"none"} 的常量、摘掉「main 重取已签事实重判」这一核心反篡改性质,仍全绿 修(断言加 reason)
    Major-2 消费门的生产调用点零红可删,而 refreshChannelCatalog 第四参默认值是 fail-open 的 () => ({ok:true}) ⇒ 坏候选被写成新 LKG ⇒ 健康 LKG 丢失、断网后仍空白,违反 remote-catalog.ts 抬头的「永不空白」 修(LKG 存活用例)

    全部修复只动测试与夹具,零生产代码改动,每条均反向验证变红。

    两处过程记录(都是「假闸门」形态,留给后来人)

    一、编排者的判断被审计证伪。 我判「候选消费门与 :225 的最终评估互为冗余、属纵深防御」,
    并在派 R2 时写明"能构造出行为不同的输入我就是错的"。审计给了反例:
    健康 LKG + 一份签名合法但 packages[] 坏掉的候选 —— 门在时挡在 coherent-set 落盘之前、
    健康 LKG 继续服务;门不在时坏候选被写成新 LKG,:225 只能把整份结果打成 none,
    健康 LKG 就此丢失。它是承重闸。 审计同时纠正:用例其实已存在于
    catalog-channels.test.ts,没被守住的是生产调用点 —— 又是 B1 的形状。

    二、编排者写的第一版 Major-2 用例本身就是假闸门。 它在 HEAD 与 NEW-D 变异下都绿 ——
    因为 remote-catalog.test.ts 里 channelBody 的缺省 sequence 恒为 5,与 seed 那份相同 ⇒
    候选先被 R5 replay 规则拒掉、根本走不到消费门。修法是 docOver:{sequence:6},
    并加一条 error 断言把「绿的理由必须是消费门」钉死 —— 否则将来任何让候选提前被别的规则
    拒掉的改动,都会把它悄悄退化回假闸门。审计方亦坦承其原 probe 是手搓 harness 用了 ++seq,
    "撞对的不是想对的"。

    一条如实留着的未解观察

    编排者接手时全量跑出现过 1 次失败(3287/1),未保存输出、叫不出它的名字;
    之后编排者跑 9 次、审计跑 31 次均未复现。不写它是"基线既有",也不写是本票引入 ——
    两者都没核实。

    已知不修(留痕)

    refreshChannelCatalog 的 consumeCatalog 默认值是 fail-open 缺省 —— 想改必填,
    但本仓 tsconfig 排除 *.test.ts、bun 又剥类型,45 处现有调用不会红,类型层收口是假绿;
    Major-2 的行为测试已让唯一的生产调用点受守。preload 的 packageDetail 桥两侧同删不红
    (cases 文件 mock 掉 electron、不覆盖 preload 面),且今天 renderer 侧无消费方,
    属 owner 分期裁决内(UI 归后续),非缺陷。

  6. added 2 commits that reference this issue on Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:integrationRepository, API, or external integrationcross-repoRequires coordinated work in multiple repositoriesprio:P1High-value near-term deliverytype:featureNew user or system capability

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions