Skip to content

[REQ-128][CODE] 发布 HostExtensionPackageV1 contract、profiles 与 legacy oracle #694

Closed

Description

@jinjunnn

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

REQ-128 分四相交付,本期只做 Phase 1 原生主干(#694、alpha-web#95、
alpha-web#97、#702、#695、#696、#713),只支持单组件 package
(Skill / Agent / MCP),不含 Bundle。裁决记录见
alpha-work#49 分期裁决。

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

  • compileLegacyProjection() 与"唯一 legacy transform 权威";
  • v0.1.0 / v0.1.1 / v0.1.2 三版 old-host oracle 与 canonical projection bytes;
  • prelude 里的 legacyProjectionDigest 与 package↔legacy entry 绑定;
  • 同 ID shadow、malformed/binding-mismatch 的 no-fallback、LKG 规则;
  • 下方 Development plan 第 3 条的 projection digest 部分、第 4 条整条、第 6 条整条;
  • Acceptance 里 "old-host oracle 对三个 release commit 的 parser/planner 预期 plan"。

理由(实读,非推断):v0.1.2:packages/ui-mac/src/main/remote-catalog.ts
的 saneCatalog() 只校验 {version:string, entries:非空数组},新增同级
packages[] 会被旧壳直接忽略;App 走 electron-updater 自动更新,旧宿主人群自然收敛。
因此 packages[] 定为新宿主专用,旧宿主看不见新内容即为正确行为。

替代进来的两条闸门(便宜、必须有):

  1. entries[] 永不为空 —— 旧壳 saneCatalog 要求非空,空数组会让旧宿主整份拒绝并回落缓存;
  2. 一条回归测试:目录顶层新增同级键后,v0.1.x 的壳解析语义仍然成功。

其余(shallow header、payload-ref-only、profile/capability 前置门、unknown/missing 下
fetch/decoder/secret/OAuth/planner 调用数为零、limits/负向、artifact path+SHA +
generator --check)照原文做,不打折。

禁止扩张:不新建通用框架 / 抽象层 / registry 引擎;不为"以后可能有 Phase 2"预留
插槽;发现超范围缺陷写回本票,不顺手修。

Outcome

由 Alpha 宿主先发布 HostExtensionPackageV1 contract artifact:稳定浅
AlphaPackageEnvelopeV1、strict component payload profiles、正交 capability vocabulary、
synthetic decoder corpus。它是跨仓关键路径第一张可开发票。

Covers

alpha-work#49 AC2/AC3/AC7 的 host contract foundation。

Solution baseline

Accepted REQ-128 baseline
§2.1、§2.3、§5 —— 但 §2.3 中 legacy projection / old-host oracle / 同 ID shadow 部分
已由上方裁决删除,以裁决为准。

Code boundary

  • packages/ui-mac/src/shared/host-extension-package-contract/**
    • CONTRACT.md
    • shallow envelope/profile payload JSON schemas
    • capability/profile registry artifact
  • strict pure decoder/registry module(无 Electron、网络或磁盘副作用)
  • artifact path+SHA/generator checks供 alpha-web#95 git-vendor

Development plan

  1. Envelope只允许固定浅header与content-addressed payload ref,禁止inline object payload。
  2. profileId/version负责payload schema gate;capability只表达跨profile行为,package union
    由compiler派生,作者不声明raw token。
  3. prelude固定 {packageId, version} 与 canonical bytes 算法(不含 projection digest)。
  4. legacy oracle —— 已删除,见顶部裁决。改为:entries[] 非空不变量 + 旧壳同级键容忍回归测试。
  5. decoder固定顺序:header limits → profile/capability → fetch/decode payload;
    unknown/missing门下fetch/decoder/secret/OAuth/planner为零。
  6. malformed/binding mismatch 与 foundation shadow/no-fallback/LKG —— 已删除,见顶部裁决。
    保留:malformed package 本身被拒(无 fallback 语义可言,因为不存在同 ID legacy 对偶)。
  7. 仅发布contract/synthetic decoder;production Catalog/UI/IPC接线归[REQ-128][CODE] 将 package compatibility 单一权威接入 Catalog、详情与安装预检 #702。

Acceptance and named gates

  • host-extension-package-artifact.test.ts
  • package-envelope-v1.test.ts
  • depth/count/bytes/control/prototype/unknown version/profile/capability负向。
  • entries[] 非空不变量;旧壳同级键容忍回归测试。
  • artifact可由commit+SHA固定且generator --check。

Dependencies

仅依赖accepted baseline与顶部裁决;可立即进入Ready/开发。

Out of scope

web Declaration/compiler、production Catalog wiring、auth/transaction、dynamic registry/decoder、
legacy projection 与 old-host oracle(本期删除)、Bundle 相关一切(Phase 2)。

Exit condition

Merged host artifact + pure decoder/testvectors + docs contract;解除 alpha-web#95 阻塞。

Activity

  1. added
    type:featureNew user or system capability
    prio:P1High-value near-term delivery
    area:contractsContracts, schemas, or compatibility
    area:runtimeServices, jobs, infrastructure, or operations
    area:securitySecurity or access control
    area:integrationRepository, API, or external integration
    source:skill-auditOriginated from a skill or repository audit
    on Jul 30, 2026
  2. self-assigned this
    on Jul 30, 2026
  3. changed the title [-][REQ-128][CODE] 实现稳定 Package Envelope 与 Host Capability negotiation[/-] [+][REQ-128][CODE] 发布 HostExtensionPackageV1 contract、profiles 与 legacy oracle[/+] on Jul 30, 2026
  4. jinjunnn commented on Jul 30, 2026

    @jinjunnn
    OwnerAuthor

    R1 跨模型对抗审计记录(2026-07-30)

    实现方 codex,审计方 Opus(只读)。审计做了真实 mutation 测试:30 处生产检查逐个禁用,
    20 处零红存活;并实测 --check 漂移门、顺序门、计数器断言均绕不过去。
    预算:M 级 ≤2 轮,本轮 R1,R2 只判闭合 + 修复 diff。

    采纳并回传实现方(编排者过筛后)

    # 判定 对应 AC / 门
    B1 闸门文件登记簿红(bun test src 3214/1,gate-files.tsv 未登记三个新测试文件) 修 CI bun-test-floor.sh 3000
    M1 payload 侧负向集零覆盖(20/30 mutation 存活;SHA 门是字节漂移门不是语义门) 修(只加数据行,不动生产结构) 票面 named gates + AC3 零副作用
    M2 capability 词表超卖两个本期不存在的前置 修,扩大为整包删除(见下) AC3 / AC7
    M3 已发布 schema 与 decoder 已漂移(裸 origin URL、大写主机名被拒;排序唯一未写进契约) 修,方向=保持 decoder 严格 + 写进契约面 + canonical 化归 producer AC1 / AC2
    缺 await、两处测试名超卖实际断言 修 —

    编排者对 M2 的裁决:比审计建议更进一步

    审计判定 capability 词表在这份 decoder 里就是白名单(在册即放行),因此写进词表 =
    肯定式声明"宿主支持"。alpha.mcp-oauth.v1(#703)与 alpha.connection-prerequisite.v1(#704)
    均在 Phase 2、桌面侧零实现。审计要求 owner 在"cloud profile 属不属 Phase 1"上二选一。

    裁决:连 cloud profile 一起删。 依据:①owner 分期裁决原文是"单组件 package:
    Skill/Agent/MCP";②cloud 今天经 legacy entries[] 正常交付且是 receipts-only(不写盘、
    不写配置),没有本期用户需求要把它搬进 packages[];③它是唯一恒定派生 Connection 前置的
    profile,删它一刀解开整个结。删除属删除动作,不是重新设计。

    Phase 1 收敛为:profile = skill / agent / mcp-local / mcp-remote(auth 去掉 oauth 与
    alpha-connection);capability 词表 = alpha.secret-prerequisite.v1 一个。未在册者一律
    fail-closed。并新增一条类级闸门:枚举全部 profile schema 可达取值,断言
    derivePayloadCapabilitiesV1 派生出的 capability 全部落在词表内 —— 防这一类复发。

    已知不修 + 理由(留痕)

    finding 不修理由
    把 decoder 改成消费 JSON schema / 扩展 validateSchemaLite 把窄票升级成通用框架,审计方自己也标了不建议
    合并 canonicalArtifactJsonBytesV1 与 catalog-curation.ts 的 canonicalJsonBytes artifact 需自包含;差异(NFC)在全 ASCII 内容下不可达
    给 --check 加"语义快照" 预防性加固;M1 的数据行修法已覆盖同一风险
    inspectValue 的 node 计数早于 depth 检查 两者结果都是 blocked,用户可观察结果相同
    maxHeaderNodes=128 偏紧 无可复现的合法输入被误拒,纯调参
    decodeString 用 UTF-16 长度比 max、字节上限用 UTF-8 两个上限都在,不存在绕过组合
    sha256Hex 三处重复 风格;artifact 要自包含
    synthetic decoder 先 fetch 全部字节再比 payloadRef.bytes 属生产接线,转记 #702
    decodeMcpLocalPayload 不校验 command[0] 属执行面 admission,转记 #713

    附带核实(编排者自验,非审计方结论)

    • typecheck:HEAD 202 条 = base 202 条,新增 0 条,contract 目录 0 条。
    • north-star:改动全在 packages/ui-mac,不触 UPSTREAM_PATHS。
    • 替代闸门②(旧壳同级键容忍)没有写替身 —— 它 import 了真的 readCachedCatalog;
      且审计逐字比对确认 v0.1.1/v0.1.2 的 saneCatalog() 与今天 main 相同(v0.1.0 尚无此文件)。
    • 但 entries[] 非空的生产端强制不在本仓(本仓不产 catalog),已作为硬要求带入 alpha-web#95。
  5. added a commit that references this issue on Jul 30, 2026
  6. jinjunnn commented on Jul 30, 2026

    @jinjunnn
    OwnerAuthor

    R2 审计记录与合并裁决(2026-07-30)

    R2 结论:RECOMMEND: MERGE —— R1 六条(B1/M1/M2/M3/minor/F6)全部 FIXED,
    ed2917c4..fb85d3ac 内无新 Blocker/Major。审计方在本轮又做了 43 处 mutation
    (实现方自测 8 处),并单独验证了 M2 新增的类级闸门双向都拦得住
    (词表多一个没人派生的 token → 红;schema 派生出一个不在词表的 token → 红;
    把 derivePayloadCapabilitiesV1 打空 → 红)。

    M2 的删除经两条独立检索轴交叉验证(符号轴 + 键名轴)在 packages/、scripts/、
    docs/contracts/ 全部零命中,无死路径、无孤儿类型、无悬挂引用。

    编排者从 out-of-round 里捞出来自行修掉的一条(未开第三轮)

    synthetic-decoder.ts 的 secret 前置阶段零语义覆盖 —— 假闸门。
    整段删掉、再照 CONTRACT.md 的正常流程重新生成 artifact,48 条测试全绿。
    而 CONTRACT.md 把它作为固定顺序第 5 步公开承诺,scripts/gate-files.tsv 的 guarantee
    写着「变异即红」—— 登记簿在替它撒谎。

    过三问:①对应 AC3/AC4 的固定顺序;②闸门是假的,且契约与登记簿都在超卖;③修法是既有循环加一行断言。
    三条全中,且属"删代码/加断言"类而非扩张类,故按预算规则(Major 及以下筛完直接修、修完不复审、直接合)
    自行修掉,不开第三轮。

    反向验证(编排者自跑):加断言后 0 fail → 删掉整个 secret 阶段 3 fail →
    改成无条件触发 3 fail → 恢复 0 fail。

    注:这一条不是修复 diff 引入的,R1 自己的枚举就漏了(ed2917c4 同一段也只断言
    fetch/decoder/planner 三个计数器)。记下来作为「枚举漏」的又一实例。

    同批修掉的文档漂移

    已批基线 docs/design/2026-07-30-req128-extension-package-baseline.md 顶部加相位勘误框:
    标注 legacy projection 半场与 §2.9 自缚作废、§6 的
    package-mcp-oauth.wiring.test.ts / package-alpha-connection.test.ts 随 #703/#704
    移入 Phase 2。理由:基线是下一轮 review 的对照物,对不上会误导。

    结转的 follow-up(本票不做,已记录)

    项 处置
    payload 侧仍有 8 处单点检查零覆盖(HEADER_NAME_RE、requiredSecrets 名字正则、command 条数、asset text/markdown 绑定、asset 5 MiB 上限、decodeString 单字段 max / 空串、record 32 属性上限) 今天实现都是对的、不影响用户可观察行为;语义分量最重的是 asset mediaType 绑定与 secret 名字正则。留给后续同一张负向表补数据行
    类级闸门的枚举源可静默清空(behavior.properties 取不到即退化为单变体;认死 requiredSecrets 字面名) 不影响它拦住 M2 复发的两个方向;硬化方式是对枚举出的维度/变体数加下界断言
    docs/contracts/host-extension-package-v1.md 里的 aggregate SHA 无门钉住 后果 fail-closed(alpha-web#95 照文档 pin 会在消费端硬失败,不会放坏字节过)
    审计方明确说不必补的四条(PROFILE_ID_RE/CAPABILITY_RE/component.required/envelope 对象性) 实测被下游注册表门、词表门与最终 guard 拦死,补了是纯冗余

    合并

    PR #718 已 squash 合并为 55890367。

    下游 pin 三件套:commit 55890367、路径
    packages/ui-mac/src/shared/host-extension-package-contract/、
    aggregate SHA c3c53e0580782884d441ed04064e31020949bef87ae01b4a0403f8576e3fd483。

  7. added a commit that references this issue on Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:contractsContracts, schemas, or compatibilityarea:integrationRepository, API, or external integrationarea:runtimeServices, jobs, infrastructure, or operationsarea:securitySecurity or access controlprio:P1High-value near-term deliverysource:skill-auditOriginated from a skill or repository audittype:featureNew user or system capability

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions