Skip to content

discussion: Knowledge / Workbench / Benchmark 三模块目标架构——现状、原语、交接时序与遗留问题 #362

Open

Description

@Dong1017

Current state: 设计讨论。本文整理 OmniRSI #6 四轮评审后收敛的目标架构,以便在本仓按模块拆分开发任务。方案正文以 #6 的三模块架构最终讨论稿 为准;本 issue 补充的是它的证据链、交接时序和遗留问题。
Decision needed: 三模块边界、四个公开接口的最小交接内容,以及第 7 节五个遗留问题的归属,由维护者决定。
Next action: 在评论里记录边界与接口的意见;实施切片另开 task。本 issue 不授权源码迁移、实验、付费调用或合并。

核查基线:main 01c73521,PR #338 固定在 8f3aebd2。本轮为静态源码、文档与调用关系检查,未运行测试、模型或设备实验。


1 仓上现状:问题不在模块怎么命名

把一次真实运行穿过的代码切出来看,会看到几条互不相通的执行通道,每条有自己的控制器、自己的外部端点,也各自强制着一条规则:

通道 控制器 它强制什么 外部端点
KV 编辑 model/anthropic_edit_agent.py receipt 按 revision 失效,同字节写回也失效(:293 递增、:515 抛 stale_or_missing_receipt) 沙箱内合成 Python 文件
通用 runner harness/runner.py 源码快照三重相等(:101-107),改了又恢复仍判无效;终态提交失败写 termination_failed(:137,151) 真实推理服务 / 引擎
预算 tools/skill_eval_budget.py 预留即计费,不退款 付费模型服务 + Git 账本

强制是通道局部的,而且没有任何结构保证一条新通道会继承已有的保证。 这是提出模块化的直接动因,而不是目录名不好看。

两个现成的证据:

一、同一个 PR 里已经长出两套平行实现。 #338 在 8f3aebd2 上有两个内容库(data/engineering_benchmarks/ 与 data/engineering_scenarios/),文件角色几乎相同,入口分成 inferrsi benchmarks <action> 与 python -m tools.moe_benchmark 两套,pyproject.toml 因此加了第二条 package-data 规则;身份冻结也分成两份——harness/scenarios/moe.py 自己写了 _hashes / _prepare / _adjudicate,不导入同一个 PR 早先加的 harness/benchmarks/contract.py。两者保护的对象确实不同,但分叉的理由没有写在未来适配器作者会读到的地方。

二、保障集合从导入关系上看不出来。 四个入口都复用叶子函数 harness/scenarios/external.py 的 execute_trial,而源码快照裁决在包装它的 run_experiment 里:

入口 执行路径 源码快照裁决 父进程侧身份复核
benchmarks compare runspec() → run_experiment 有 有
benchmarks plan 只返回规格,不执行 不适用 准备阶段绑定
benchmarks grade grade_artifact → run_action → execute_trial 无 有:前后两次 task.identity() + assert_unchanged() + 结果内 identity 回显
check / measure / profile run_action → execute_trial 无 无
MoE moe.evaluate → execute_trial 无 有,自己的 _prepare / _adjudicate

缺少 runner 快照不等于缺少该操作所需的保证——grade 直接比对身份,可能本就不需要。但这个差异必须是声明出来的,不能由「复用了哪个函数」推断。

三、本周合入的代码已经出现没有归属的部分。 harness/ 从 13 个文件涨到 23 个,#319 与 #341 新增约 2,737 行:dashboard_data.py 865、optimization_log.py 360、dashboard.py 296、campaign_records.py 248、optimization_trace.py 247、optimization_story.py 230、knowledge_capture.py 169、dashboard_timeline.py 163、dashboard_live.py 126、campaign_trace.py 33,加 dashboard 与 campaign 两组 CLI 子命令。按职责它跨「运行记录」和「结果解释」两边。

值得注意的是这一簇不是日志系统,口径恰好相反:optimization_trace.py 自述「The record is a caller assertion, not proof that an agent consumed its context. It is never populated from raw requests, logs, or the process environment」,dashboard_data.py 自述「log contents are deliberately omitted」,而 optimization_story.py 的职责是列出叙事与留存证据不一致的地方。它是声明加对账层,不是事件流。

2 新架构解决什么

现状问题 三模块如何处理
新通道默认不继承任何保证,且无人察觉 保障集合成为 ExecutionRecord 的显式字段,由 Benchmark 在判定时核对,而不是由调用链推断
任务冻结与执行代码同处一包,重构可能顺手改掉基准 Benchmark 独立:它的职责是不变,工作台的职责是演进,两者对变更的要求相反
评价目的、执行方式、任务实例混为同级概念 系统对照/技能效果是评价目的,本地/云端是执行方式,KV/parser/算子是任务实例,三者不再并列
「运行成功」与「任务通过」混用 Workbench 输出执行事实,Benchmark 输出判定;进程退出码为零不能直接变成 PASS
知识读取被实验流程捆绑 Knowledge 可独立使用,inferrsi knowledge search 已经是现成入口

3 三个模块与依赖规则

flowchart TB
    USER["人 / Coding Agent"]:::external --> APP["应用入口与装配:CLI / Python / Plugin"]:::thin
    subgraph K["Knowledge 知识库"]
        direction TB
        KR["知识检索与交付"]:::module --> KS["知识资产、版本与受控更新"]:::module
    end
    subgraph B["Benchmark 评测模块"]
        direction TB
        BT["任务、输入与参考实现"]:::module --> BG["正确性、测量与判分"]:::module
    end
    subgraph W["Workbench 实验工作台"]
        direction TB
        WP["运行计划与实验编排"]:::module --> WE["执行、资源与进程管理"]:::module
        WE --> WR["运行记录与结果报告"]:::module
    end
    APP --> KR
    APP --> BT
    APP --> WP
    WE <--> TARGET["外部运行环境:引擎、服务、项目代码与硬件"]:::external
    classDef module fill:#DEEBFA,stroke:#B6C1CC,color:#23354B
    classDef thin fill:#FFFFFF,stroke:#0E6C6C,color:#23354B
    classDef external fill:#FFF0D6,stroke:#B6C1CC,color:#23354B
    style K fill:#EDF4FC,stroke:#B6C1CC,color:#23354B
    style W fill:#EDF4FC,stroke:#B6C1CC,color:#23354B
    style B fill:#EDF4FC,stroke:#B6C1CC,color:#23354B
    linkStyle default stroke:#788A9D
Loading

三个模块之间没有任何直线相连,这是本图最重要的一条。 独立性落在依赖方向上,不是只改目录名。四条规则:

  1. Knowledge 核心独立提供检索、版本读取和受控写入,不依赖 Workbench 或 Benchmark。
  2. Benchmark 核心定义任务与判分,不导入 KnowledgeReader、Agent 客户端或 Workbench 执行器。评测 Knowledge 本身时,被测检索接口由应用适配器注入。
  3. Workbench 核心执行已准备的计划,不自行检索知识,也不硬编码某个具体 Benchmark 的数学定义与评分公式。
  4. 应用层只经三个模块的公开接口组合流程,自身不承载业务判断。

main 上已经有一个符合规则 3 的自发实例:harness/knowledge_capture.py 不导入任何 inferrsi 模块,reader 作为参数注入(capture_context(root, *, context_id, reader, …))。工作台到知识库的数据流存在,而导入依赖没有反向。

4 原语与公开接口

名称表示设计方向,具体类型在兼容现有契约后确定。四类接口可分别使用。

# 接口 输入 交付结果
① Knowledge.read / collect → KnowledgeBundle 知识范围、版本、资源需求 固定版本内容、来源、选择范围、可读取资源引用。读取不触发实验;更新另走受控接口
② Benchmark.prepare → PreparedEvaluation 任务与 grader 版本、操作、输入、候选格式、采样协议、资源要求 冻结的任务/输入/判据,指标单位与方向、计时与聚合规则、各项判定所需证据。候选未生成时明确标注未绑定
③ Workbench.execute(ExecutionSpec) → ExecutionRecord 明确的命令、工作目录、输入输出引用、资源上下文、时限与执行限制;候选引用及预期身份 实际输入绑定、运行与尝试身份、状态、退出码、耗时、清理结果、日志、原始产物、实际用量,以及本次实际完成了哪些完整性检查
④ Benchmark.assess(prepared, outputs, execution_facts) → EvaluationResult 冻结任务与协议、实际候选绑定、执行事实、原始产物 声明范围内的判定、指标有效性与原因、分数及证据引用。缺证据保留 INCONCLUSIVE;允许离线重算,不隐式启动新实验

③ 的最后一项是本提案相对前几版的实质新增。理由就是第 1 节那张入口表:保障集合各入口不同,而差异从导入关系上看不出来,所以必须由记录本身声明「实际完成过什么」。

三个跨模块原语:

  • 冻结身份:从实际字节重算身份,与预先绑定的引用比对。各协议保护的对象不同(离线证据包字节、编辑会话内的写入顺序、执行身份与漂移),不预设必须归并;但每处都要说清保护对象、适用操作、身份字段、失效事件、强制检查位置、反例测试和保留消费者。
  • 受控执行:owner、时限、预算、清理与释放证据。取消请求与实际退出分别记录。
  • 范围化主张:这份证据支持什么命题、适用边界与资格。执行状态不等于判定。

5 交接时序

sequenceDiagram
    actor U as 人 / Coding Agent
    participant A as apps 应用层
    participant K as Knowledge
    participant B as Benchmark
    participant W as Workbench
    participant T as 外部运行环境

    U->>A: 声明目标、任务与候选来源
    A->>B: ② prepare(task, grader_version)
    B-->>A: PreparedEvaluation(任务/输入/判据已冻结,候选未绑定)
    opt 需要知识
        A->>K: ① read(scope, version)
        K-->>A: KnowledgeBundle(固定版本、来源、选择范围)
        A-->>U: 交付知识包
    end
    Note over U: 提出假设、选择方法、编辑候选
    U->>A: 提交候选引用
    A->>W: ③ execute(ExecutionSpec, 候选引用, 预期身份)
    W->>W: 绑定实际候选字节,记录 identity
    W->>T: 下发命令
    T-->>W: 原始产物与测量
    W->>W: 进程清理、用量记账
    W-->>A: ExecutionRecord(状态、产物、用量、已完成的完整性检查)
    A->>B: ④ assess(prepared, outputs, execution_facts)
    B->>B: 核对身份匹配与证据完整性
    B-->>A: EvaluationResult(PASS / FAIL / INCONCLUSIVE + 适用范围)
    A-->>U: 判定与证据引用
    opt 知识晋升
        U->>K: 受控更新(显式审阅,与判定分开)
    end
Loading

三处顺序是有意的:

  • ② 在候选存在之前。 任务、输入、判据先冻结,候选后绑定。改候选不会让任务和判据跟着悄悄变。
  • ③ 里绑定身份,不在 ② 里。 每次检查或测量前重新捕获并核验实际候选身份,但不修改已冻结的任务与判据。
  • ④ 读执行事实,不发起执行。 离线判分可独立进行;需要重验时显式创建新运行,旧记录与原结论保持可追溯。

失败路径同样分开记录:候选错误保留 FAIL,清理失败另记,基础设施失败不洗掉已发生的预算开销,取消请求不等于进程已退出。

6 一个现成的检验:性能上限分析

#303 的 Decision needed 是一个二选一——SOL 模型「extends performance-ceiling-analysis 作为第二个切片,还是成为新的 methods/ owner」。它正文自己点出了症状:

InferRSI already owns both halves of this and connects neither to a number.

optimization-search-policy 的停止规则只能定性引用 headroom,因为没有一个冻结的 distance-to-bound 可比。

在三模块下这个二选一会消解,因为答案是两个都不是:

部分 归属
三级上限模型、怎么算、用哪些常数 Knowledge(读给 agent 看的方法)
冻结的 bound 值、distance-to-bound 判据、跨 flow 的比较规则 Benchmark(判据必须冻结,变了过去的比较就失效)
实测 F / P / T / B 这些量 Workbench(执行与测量)

同理 #348 修的是 Knowledge 侧的条目内容,与冻结判据是两回事。建议把 #303 的范围决定按这三段拆开回答,而不是在原二选一里选。

7 遗留问题

  1. 本周新增的 dashboard / trace 簇归谁? 约 2,737 行,职责表里没有「可视化与追溯」这一项。按内容它跨 Workbench 的运行记录与 Benchmark 的结果解释;而且它的证据强度是「调用方主张」而非「捕获的事实」,这一点要写进接口约定,否则会被当成 trace 日志使用。其中 campaign_trace.py 是唯一真正 trace-like 的部分,正是 #333 候选 2 要的统一事件信封。

  2. 第一阶段承诺哪几条不变量? 「承诺的规则全部需有拒绝路径与测试」比配额严谨,但现有文档把 40 条都写成无条件不变量,没有分阶段承诺清单。

  3. 谁判定预算 gate 是否必需? 「必需则整体 INCONCLUSIVE,否则保留观察并降级主张」方向正确,但这个判定尚未分配给任何角色或对象字段。另有一处语义需要分开:「预留即计费、永不退款」对不可逆的外部支出是对的,当成通用预算规则就是错的——金额与 token 花了就是花了,而 wall time、设备时间、并发槽位在取消后确实会被释放。用一个 budget_ref 统管五个维度,会逼着设备时间也按不退款算。

  4. 知识条目的生命周期状态怎么定? repo_packs 下 108 个条目全部 status: imported,字段存在但只有一个取值。不建议为此新开 issue——#350 的验收项已经要求「区分已覆盖、待细化、缺失、过时和暂不纳入」并「整理重复、冲突和过时条目」,缺的是把这几个词落成 status 取值。触发条件应当事件驱动而非定时:知识按上游失效不按时间失效,钉在固定 revision 的条目在上游未变时不会过期。可用触发是「钉住的 revision 与当前上游不一致」与「持续不命中且确实进过候选集」(后者依赖 #344 补的候选集合记录)。#177 已有一套五级成熟度用在外部研究条目上,可直接借用。

  5. 依赖规则怎么机械检查? tests/test_module_boundaries.py 目前只对 infra / model / harness 的直接导入做 AST 规则检查,没有构建依赖图、没有计算传递闭包,也不覆盖动态导入与经由重新导出间接到达的路径。若要承诺传递依赖检查,需先补依赖图解析。静态导入规则、运行时调用与实验结果校验回答三个不同问题,哪一项都不能替代其余两项。

8 迁移约束(实施前必须知道)

  • 目录迁移会让带前缀依赖的知识包装载失败,不只是版本号漂移。 knowledge_operations.py 的依赖解析按路径前缀收集成员(path.startswith(dependency + "/")),成员集合变空或变化会直接抛 ValueError: Missing dependency 或 RevisionConflict。所以优先保留逻辑路径与兼容入口;确需迁移时同步重算并更新 dependencies 里的 pinned revision。
  • repo_packs/*/pack.json 有双重用途。 catalog.repository_pack() 读它,而 infra/inspection.py 把结果放进环境检查输出的 repository_pack 字段。运行目标描述的读取职责应归 Workbench 的环境适配,嵌套的 repo_packs/*/knowledge 仍归 Knowledge——这棵目录不能整体搬迁。
  • 已有的真实耦合点。 harness/skill_evaluation.py 同时依赖 KnowledgeReader、执行器与工程任务;feat: add shared engineering evaluation and dual-NPU MoE task #338 的 TaskPackage.runspec() 直接构造 Workbench 的 RunSpec。这两处是拆分的起点。
  • 共享 package 内容变化会改变未来实验的源码 hash。 新实验重新冻结,旧实验原记录与原始来源版本保持不变。

9 本提案不授权什么

未授权源码迁移、目录重命名、实验执行、模型或设备调用、付费操作、合并,也不为任何在途 PR 追加合并前置条件。图中出现一个框不代表该能力已具备。第 1 节的入口表与行号为静态源码检查结果,未重跑测试或 CI;#338 相关结论固定在未合并的 8f3aebd2,不能写成 main 已交付的能力。


讨论上下文:OmniRSI #6 四轮评审与一轮全仓清理梳理。该线中四处事实错误已在原处更正未删改,根因均为人工枚举消费者种类或依赖方向时漏项——这也是第 7 节第 5 条的由来。

Activity

  1. added
    kind:rfcProposal / design discussion; scope review before build
    area:workbenchCLI workbench: profile, A/B loop, quality gates, evidence reports
    area:knowledgeKnowledge line: packs, skill library, knowledge admission
    status:proposedWaiting for the decision named in the status block
    on Nov 6, 2026
  2. amy-why-3459 commented on Nov 6, 2026

    @amy-why-3459
    Collaborator

    (schema probe - will not use)

  3. amy-why-3459 commented on Nov 6, 2026

    @amy-why-3459
    Collaborator

    (请忽略上一条误发的短评。)

    感谢整理这份架构讨论稿——从「通道局部强制、保障集合不可推断」出发,到四类接口与交接时序,证据链很扎实;也正确地把本 issue 限定在讨论,不授权迁移或合入前置。

    对 Decision needed 的几点意见,方便后续拆 task:

    1. 三模块边界

    同意 Knowledge / Workbench / Benchmark 互不直线依赖、由应用层组合的规则。尤其赞同:

    • 把「评价目的 / 执行方式 / 任务实例」拆开,不再并列;
    • ExecutionRecord 显式声明本次实际完成了哪些完整性检查——这正好对上第 1 节入口表里 grade / check / MoE 保障差异「从导入关系看不出来」的问题;
    • 「运行成功」与「任务通过」分开:Workbench 出执行事实,Benchmark 出判定。

    2. 四个公开接口的最小交接

    接口 建议的最小必交内容
    ① KnowledgeBundle 固定版本、来源、选择范围、可读取资源引用;读取不触发实验
    ② PreparedEvaluation 任务/输入/判据已冻结;指标单位与方向、计时与聚合规则、各项判定所需证据;候选未绑定时明确标注
    ③ ExecutionRecord 实际输入绑定、身份、状态、退出码、耗时、清理结果、产物与用量,以及已完成的完整性检查清单(必填)
    ④ EvaluationResult 声明范围内的判定、指标有效性与原因、分数及证据引用;缺证据保留 INCONCLUSIVE;assess 不隐式启动新实验

    时序上同意:② 在候选存在之前;③ 里绑定身份,不改已冻结的任务与判据;④ 只读执行事实。

    3. 第 7 节五个遗留问题的归属建议

    1. dashboard / trace 簇:运行记录与「调用方主张」对账归 Workbench;判定解释与证据完整性核对归 Benchmark;campaign_trace 与 discussion: what trace evidence should InferRSI persist beyond per-run artifacts? #333 候选 2 对齐后再定统一事件信封。证据强度(主张 ≠ 捕获事实)必须写进接口约定,避免被当成 trace 日志用。
    2. 不变量:需要一份分阶段承诺清单,不要把文档里约 40 条都当成无条件不变量;首期只承诺「有拒绝路径与测试」的那几条。
    3. 预算 gate:判定角色建议落在 PreparedEvaluation / ExecutionSpec 的显式字段(例如 budget_policy),并区分不可逆外部支出与可释放资源(wall time / 设备槽位);不要用单一 budget_ref 五维统管。
    4. 知识生命周期:同意落在 task: 细化 vLLM Ascend 知识蒸馏与知识库整理 #350 的 status 取值上,并借用 [Research Radar] AI inference performance & RSI — daily categorized insights #177 的五级成熟度;触发用事件驱动(钉住 revision 与上游不一致,或候选集持续不命中),不必新开 issue。
    5. 依赖检查:在承诺传递闭包之前,先把现有 AST 直接导入规则扩到 Knowledge / Workbench / Benchmark 包边界;依赖图解析可作为后续切片,不阻塞边界约定本身落地。

    4. 与 #303 的关系

    同意按三段回答,而不是在原二选一里选:

    • Knowledge:三级上限模型与计算方法(给人/agent 读的方法说明)
    • Benchmark:冻结的 bound 值、distance-to-bound 判据、跨 flow 比较规则
    • Workbench:实测 F / P / T / B

    5. 实施切入点

    实施切片另开 task 时,建议:

    我这边可以继续在边界与接口字段草案上跟评论;具体实施 PR 再逐个 review。若对第 7.1 / 7.3 的归属有不同取舍,欢迎直接在本帖拍板。

  4. Dong1017 commented on Nov 6, 2026

    @Dong1017
    CollaboratorAuthor

    补充 §1 预算行 / §7.3:预算占用不能直接当作实际支出。 在本文固定的 01c73521 上,Ledger.charged 累加的是 worst_case;状态机允许 reserved → cancelled,即使未执行也不返还该 PR 的预算容量。actual_cost 则单独记录,取消项仍为 None。所以“预留即计费”的准确含义是预留即占用预算上限,不是已经发生供应商收费;也不能把未知实付记成零或预留金额。

    建议公开接口保留三类独立事实:预算预留/占用及其策略、已观测用量/可得账单、活跃资源租约与确认释放。取消后可释放的是后续设备/并发容量,已消耗的设备时间和累计 wall time 仍应保留;不应因设备已释放而回退现有不退款账本,也不应把保守预留放进 ExecutionRecord 的“实际用量”。§7.3 的预算 gate 归属仍由维护者决定。

    这是静态状态机核对和接口语义建议,未运行测试、修改预算规则或授权实施。

  5. Dong1017 commented on Nov 6, 2026

    @Dong1017
    CollaboratorAuthor

    @zengchuang-hw 请从 plugin / install 的角度看看这份 Knowledge / Workbench / Benchmark 三模块架构方案,给一些建议。尤其想听听模块拆分对插件入口、安装打包、依赖和兼容性有什么影响。

  6. zengchuang-hw commented on Nov 6, 2026

    @zengchuang-hw
    Contributor

    回复 plugin / install 评审请求。我支持首期在同一个发行包内拆清 Knowledge、Workbench、Benchmark 的边界。建议把以下四项写进后续迁移 task 的验收范围。

    1. 保留现有宿主入口和安装身份。 Codex 和 WorkSwarm 各自使用原生清单和安装流程,继续让宿主适配层处理技能定位、会话和本机启动,由共用的 inferrsi CLI/应用装配层调用三模块公开接口。迁移时覆盖原插件 ID、清单与归档根、--plugin-info、既有命令的参数与输出,以及已公开的 Python 导入。WorkSwarm 继续验证紧凑载荷、只读 inferrsi_runtime_info 定位与 Windows 长路径安装。feat(dsh): add structured iteration form and SSH execution #361 的 DSH 仍是手动安装预览,远端还要执行随包的 remote-runtime.zip。SSH bootstrap 直接调用 inferrsi.arguments.parser 和 inferrsi.cli.main,模块迁移需同时核对远端参数解析和仓库路径约束,保留现有会话归属、关闭和重试语义。 Codex 安装 · WorkSwarm 安装 · DSH 远端启动

    2. 给 wheel 和宿主包核对同一份必需资源。 wheel 通过 pyproject.toml 选择 package data,插件构建器单独筛选 Python 文件及 data/ 内的资源。若把任务输入、参考实现、许可证或知识附件移到新包目录,源码测试可能通过,安装包却漏文件。建议第一步保留逻辑 ID 与资源路径,在移动资源的切片里核对各产物都能解析同一份必需资源及其摘要,并沿用当前运行时版本与文件哈希校验。旧冻结记录继续通过原版本或既有快照读取。 Wheel 资源声明 · 插件资源筛选

    3. 让按功能安装的依赖留在使用点。 当前核心要求 Python 3.10+,基础依赖为空,PyYAML 与图像验证依赖走 extras。启动入口、知识读取和历史报告查询应继续在基础运行时可用。引擎、设备及特定 grader 的依赖,在实际选择对应操作时检查,并给出缺失项和执行位置。DSH 经 SSH 执行时,应在目标机核对目标机的依赖。查询入口保持只读。 运行时与 extras · DSH 安装与远端说明

    4. 先验证安装后的兼容性,再迁移物理目录。 复用 Ready 的干净 wheel 检查和 Release 的 Codex/WorkSwarm 成品检查。现有 wheel smoke 安装了 [skills],建议补一个无 extras、在 checkout 外运行的知识读取用例,再用同版本归档验证入口、代表性资源、历史结果读取,以及旧版本升级到新版本后的行为。原生宿主的安装/选择/升级和 DSH SSH 路径各保留对应证据,避免用构建成功推断宿主行为。 Ready wheel smoke · Release 成品检查

    本次依据主线快照 1246348 和 #361 草稿 f404981 做静态设计核对。安装、升级和真实宿主运行留待实施切片验证。

  7. Dong1017 commented on Nov 6, 2026

    @Dong1017
    CollaboratorAuthor

    接口细化与讨论收口建议(v0.3)

    本轮把三模块方向补成可交接给开发者的接口草案:9 组公开接口、19 组内部职责、18 个验收场景、6 个实施切片。下面先列需要维护者决定的增量,完整契约放在折叠区,其他 reviewer / agent 可以直接读取评论正文。

    当前判断:大结构已有明确支持,可以收束;具体接口尚未完成维护者确认。 边界评审、预算语义修正、安装评审分别支持了方向和约束,不能据此把本条新增 DTO / 错误语义称为已达成共识。

    1. Apps 到底是不是独立模块?

    建议明确写成:三个业务模块 + 一个应用入口与装配层。 Apps 在代码中独立组织,首期可形成 inferrsi.apps 包;架构图放在三模块上方,名称用“应用入口与装配层”。首期仍是一个 inferrsi 发行物,包边界独立不意味着各自发布 wheel。

    部分 拥有的职责 对外边界
    Knowledge 内容、版本、来源、检索与上下文组装、受控存储 固定版本知识及选择/省略原因
    Workbench 优化循环、候选调度、实际输入绑定、执行生命周期、预算准入、资源与运行记录 执行事实及不可变记录修订
    Benchmark 任务与参考、完整测量协议、任务测量程序、质量检查、聚合与判定 冻结评测规则及有适用范围的结论
    Apps 应用层 CLI / 宿主入口、配置、适配器装配、DTO 转换、显式归档、展示 调用三模块公开接口;不产生另一套循环、预算规则或 grader

    特别澄清“测量”归属:采样、计时边界、重复顺序、聚合和任务 worker 属于 Benchmark;启动 worker、控制进程、绑定输入和留存产物属于 Workbench。 不能因为 worker 在 W 的子进程中执行,就把测量规则也交给 W。优化循环由 W 推进,任务允许的重复/重试仍受 B 冻结协议约束。

    三个核心包互不导入;W 所需 CandidateProvider / EvaluationPort / ContextProvider 由消费方 W 定义,Apps 实现桥接。各模块拥有自己的 DTO;首期不设通用业务 shared/contracts 包。内部 19 项是职责边界,只有真实替换点需要 Protocol,并不要求先创建 19 个空接口类。

    2. 本轮真正补齐的交接内容

    原先容易让实现者自行猜测的地方 建议固定的契约
    候选引用没有对应的可执行输入;适配器自行生成 attempt / 预算 CandidateProposal={candidate, inputs, generation_record_ref};W 的 allocate_attempt 只分配 AttemptContext 身份。目标、deadline、BudgetRequest 与重试关联原样传递;真正准入、资源获取与启动在 execute。
    prepared 只留 ID,换进程后无法离线判定 B 提供纯 encode/decode/validate_prepared;Apps 在评测执行前显式保存完整信封与所需资源,得到 PreparedRef。protocol_digest 标识规则语义,protocol.sha256 标识完整文件字节,二者分开。
    原始记录被后补清理状态覆盖,旧结论无法复现 W 返回有版本的 RecordRef;补充事实产生新 record_version。B 判定固定记录版本,Apps 保存结果后才生成 AssessmentRef。读取 last-known 快照不等于确认进程仍活着或资源已释放。
    同一个 execute 调用可能等待、接管、重跑,含义不确定 同一 RunStore 内,同 key 不同请求摘要报冲突;已完成返回原记录;正在执行返回 AttemptInProgress;控制者状态不明返回 RecoveryRequired。执行后的超时/取消/非零退出留在记录里;持久化失败显式报告是否已经启动。
    Agent provider 可能绕过统一执行与预算 plan_generation → W.execute → collect_candidate 两阶段 provider。W 先保存 generation manifest,再作为固定输入执行;collect 只读本 attempt 的实际绑定与留存产物。生成/评测是不同 attempt,共用任务预算 scope 和期限。
    一份 hash 被误当成来源与资格证明 输入、产物和 checks 同时携带 role、subject、attempt、producer/checker、schema 与证据来源;内容相同仍不能跨 attempt 或跨验证范围借用证据。task 自报与控制器确认分开。
    预算占用被当实际收费;调用方把申请写成准入成功 BudgetRequest 是输入;W 生成准入/预留回执。预算容量、已观测用量/账单、资源租约与确认释放分别记录。未知实付保留 null,沿用现有保守容量规则。

    3. 建议本 issue 只收口四项维护者决定

    决定 推荐结论 后续交付
    A. 模块与职责(D01/D02/D07) 按上表冻结“三模块 + Apps 应用层”;同一发行物。B 拥有测量语义,W 拥有循环与执行事实,Apps 只装配。 S1 写入包边界及字段 owner;Dashboard 分别读取 W 事实和 B 结论。
    B. 交接不变量(D03/D04/D05) 接受冻结规则/实际绑定分离、执行事实/判定分离、不可变记录修订及三类预算事实。发起方在已接受计划与预算策略约束内声明执行预算,W 强制准入;验收方与 B 冻结任务所必需的证据并判定缺项。 S1 联审 DTO、编码、版本与错误表;随后 S2/S3 可并行实现。
    C. Knowledge 状态语义(D06) 修正主帖 §7.4 及跟评中的统一 status 建议。 catalog 的 imported、知识存储 state、#177 研究证据成熟度、#350 主题覆盖、许可证与实证资格是不同维度,应分别表达。上游变化,或在有候选集记录的前提下持续不命中,可触发复核,不能自动判失效、晋升或降级。 K owner 保留现有 hash/CAS/写入语义;#350、#177 分别处理本来的问题。
    D. 首期完成范围(D08/D09) 首期交付独立知识读取、真实 CPU 单次执行生命周期、留存证据离线判定、Apps 装配及实际迁移路径的安装兼容。保留已公开 CLI/import、资源逻辑路径、插件 ID/清单与会话语义。 S1 契约 → S2/S3/S4 并行 → S5 应用装配。真实 Agent、共享调度、投机、视频新指标另按各 issue 的接受范围推进。

    这一轮不需要等待所有 reviewer 对每个 DTO 字段都一致后才切 task。建议维护者先确认 A–D;S1 的小范围联审负责字段、错误、兼容 fixture,模块负责人据此进入后续切片。有异议请指明 A/B/C/D、需要替换的条款、受影响的调用路径或反例;确认应明确记录,不以沉默视为接受。

    另修正主帖 §6:把 #303 的方法说明 / 冻结判据 / 执行事实分配到 K/B/W 后,Knowledge 内“扩展既有 method 还是新增 owner”的内容组织选择仍需由 #303 决定,不能说原选择自然消失。

    4. 最新相关讨论与映射快照

    完整接口草案

    下列折叠内容是 v0.3 设计正文,代码基线固定在 1246348f252dbc7e473efb1752c2d81da15e23fd。其中的阶段标记和上面的讨论状态应一起阅读;提议接口不表示源码已经实现。HTML 架构稿、全量映射 XLSX、完整 JSON 已打包准备;本评论尚未包含已上传的附件链接,因此先将完整接口契约内嵌,评审无需依赖外部文件。

    模块边界与事实拥有者

    2. 包边界与事实归属

    建议先约束三个业务包核心不导入其他业务包的具体实现,跨包装配放在 apps。运行时数据流、通过注入调用被测对象,与静态导入关系是三件不同的事。Benchmark 测试 Knowledge 检索能力时可以使用由 apps 注入的被测接口;这不意味着 Benchmark 核心导入 KnowledgeReader。

    每个包拥有自己的公开 DTO。不同包中的 ArtifactRef、CandidateRef 可以形状相近,但不共用一个不断扩张的 shared/contracts 业务包。apps 负责版本检查、字段转换、路径装配,不重新计算业务结论。需要去重的 JSON 编码、hash、原子文件写入等叶子工具,只在确有共同消费者时抽取,不能借此新增第四个业务模块。

    事实 / 决策 权威拥有者 其他层如何使用
    知识内容、逻辑路径、revision、选择/省略原因 Knowledge Workbench 留存交付快照;Benchmark 按任务检查对照条件
    题目、输入、参考实现、质量参考、采样、计时、聚合、评分、反馈可见性 Benchmark Workbench 执行任务提供的操作;apps 不能补写统计规则
    候选生产目标、假设、方法选择、候选编辑 人或外部 Agent;相关支持能力由 Workbench 适配器提供 不因为包拆分就接管宿主会话或推理状态
    实际候选快照、启动事实、attempt、退出、取消、清理、资源与用量 Workbench Benchmark 接收只读事实投影;Dashboard 展示原记录
    task worker 的正确性/质量/采样报告 Benchmark 的任务实现产出;Workbench 负责留存和执行出处 “由子进程产出”不自动等于独立执行器已确认其语义
    任务判定、有效指标、比较适用范围 Benchmark 不由 apps、Dashboard 或 Knowledge 根据 exit code 再生成 PASS
    实验总预算、哪些条件是验收必需 发起方 / 指定验收方声明,Workbench 执行其支持的准入与记账;Benchmark 按冻结的评测条件解释相关证据 单独有 budget_policy 字段不等于已经分配了决定权
    合并、发布、知识推广 各自审阅与验收流程 不由 execute 或 assess 的返回值自动触发

    2.1 apps 允许和不允许承接的工作

    允许:读取配置、选择公开适配器、将知识快照作为显式输入、将 Benchmark 的操作描述转换成 Workbench 的请求、将 ExecutionRecord 转成 Benchmark 的 EvidenceInput、选择用户明确请求的流程、输出结果。

    不允许:循环重试直到通过、累计第二套预算、维护第二套候选状态机、解释 PSNR/MoE rank 聚合、凭 exit code 填入通过的检查、将预算预留伪装成实付、覆盖既有 verdict。运行步骤推进和重试状态属于 Workbench;任务允许什么重试/重复顺序属于冻结的 Benchmark 协议。来源1 §3–7来源2 §3–4

    跨模块接口、数据对象与失败语义

    4. Knowledge:保留 Bundle,固定读取快照,受控写入

    4.1 公开 Protocol

    from __future__ import annotations
    
    from typing import Protocol
    
    # Bundle 沿用当前实现及身份语义,迁移到 Knowledge 自己的公开面。
    # Collection 是现有 collect 输出的类型化投影,不重命名 Bundle。
    
    class KnowledgeReaderPort(Protocol):
        def read(self, reference: str, *, revision: str | None = None) -> Bundle: ...
    
        def resource(
            self, reference: str, path: str, *, revision: str
        ) -> bytes: ...
    
        def collect(self, request: CollectRequest) -> Collection: ...
    
    
    class KnowledgeWriterPort(Protocol):
        def create(self, bundle: Bundle) -> str: ...
    
        def update(
            self,
            bundle: Bundle,
            *,
            expected: str,
            reason: str,
            evidence: list[dict],
        ) -> str: ...
    
        def history(self, reference: str) -> list[dict]: ...

    新 collect(request) 可以是类型化入口;原 collect(query, ids=..., revisions=..., ...) 的参数与错误语义由兼容 wrapper 保留。当前 Bundle.metadata / content / dependencies 内部包含可变容器,frozen dataclass 不提供深不可变性;公开快照必须先复制、校验、计算 revision,再交付,不能仅凭 frozen=True 声称已冻结。来源4 · KnowledgeStore

    DTO 必需字段 / 语义
    Bundle 保留 metadata、content、dependencies、manifest、revision;reference 使用明确 authority:id;资源路径是逻辑路径
    CollectRequest query / 显式 ids、revision pins、范围过滤、limit / max_bytes / context_bytes、relevance_method;保留当前参数能力
    Collection schema_version、查询/选择方法版本、selected 中每个 qualified ref + revision、omitted 原因;按现有支持范围保留排序与候选集合事实
    Collection 的选择记录 区分 inspected / eligible / selected / delivered;若当前未捕获完整候选集,必须明确 unavailable,不能把 selected 冒充候选全集
    Knowledge update authority、identity、expected revision、完整新 Bundle、reason、evidence 引用;返回新 revision;包内内容及 checkout 内容不直接写入 store

    read(revision=None) 可以解析“当前”,但输出必须包含解析后的 revision。后续 resource 或实验消费使用该 pin,不能在每次读资源时重新解析 current。collect 不承诺多个独立 authority 的全局事务快照;精确对照实验由调用者提供 pins 并保留本次 resolved 集合。

    4.2 写入和知识状态

    沿用现有实现:create 仅建立 store-owned candidate;update 要求 expected revision、理由与证据列表,不能顺手改变内容状态。package / checkout 身份不能由 store shadow;仓库知识改动仍走 PR。来源4 · KnowledgeStore

    保留现有多维状态,不发明新的统一生命周期枚举:

    维度 当前含义与迁移规则
    catalog record 状态 imported 描述目录记录,不能转换成源 skill 的 candidate
    源内容状态 保留 candidate 等已有原义;Store.update 当前不允许晋升
    研究成熟度 #177 的研究标签只适用于其对象,不作为全库统一状态机
    覆盖范围 覆盖、未知、N/A、补充建议与冲突分别保留,可能并没有可写的知识条目
    权限与实证 许可/使用权限、source observation、作者报告、实际执行证据分别表达

    上游 revision 变化和检索持续未命中是 review signals,附适用范围、来源和触发证据;不是自动失效、自动删除或自动降级的充分条件。检索未命中还需区分没有进入候选集、排序后未选中、已交付但未使用;不要求 Knowledge 核心获知外部 Agent 是否真的理解了内容。

    晋升策略和 reviewer 角色尚待决定,不能通过增加一个 promote() 默认放开。首期保留现有写入语义足够,不建立新的知识工作流引擎。

    5. Benchmark.prepare:冻结比较规则,不禁止已有候选

    5.1 Protocol 与核心 DTO 草图

    以下类型归 Benchmark;Workbench 不导入它们。

    from __future__ import annotations
    
    from dataclasses import dataclass
    from typing import BinaryIO, ContextManager, Literal, Protocol
    
    
    @dataclass(frozen=True)
    class ArtifactRef:
        location: str
        sha256: str
        size_bytes: int
        media_type: str
    
    
    @dataclass(frozen=True)
    class DefinitionRef:
        name: str
        revision: str
    
    
    @dataclass(frozen=True)
    class EvidenceRequirement:
        allowed_producer_kinds: tuple[str, ...]
        matching_rule_revision: str
        check_id: str
        checker_revision: str
        subject: str
        phase: str
        for_claims: tuple[str, ...]
        artifact_schema: str
    
    
    @dataclass(frozen=True)
    class PreparedEvaluation:
        schema_version: str
        prepared_id: str
        task: DefinitionRef
        grader: DefinitionRef
        operation: str
        validation_scope: str
        protocol: ArtifactRef
        protocol_digest: str
        candidate_contract: CandidateContract
        expected_candidate: CandidateExpectation | None
        required_evidence: tuple[EvidenceRequirement, ...]
        recipe: OperationRecipe
    
    
    class ArtifactReader(Protocol):
        def open(self, ref: ArtifactRef) -> ContextManager[BinaryIO]: ...
    
    
    class BenchmarkPort(Protocol):
        def prepare(self, request: PrepareRequest) -> PreparedEvaluation: ...
    
        def assess(
            self,
            prepared: PreparedEvaluation,
            evidence: EvidenceInput,
            *,
            artifacts: ArtifactReader,
        ) -> EvaluationResult: ...

    可使用注册表选择 TaskAdapter,但首期只需少量静态注册、按任务懒加载。不要默认 import 全部 Torch / NumPy / 云客户端。TaskAdapter 可以实现 prepare 和 assess;按任务可再有 quality evaluator / sample parser,属于 Benchmark 内部接口。只为第二实现或真实外部边界抽 Protocol,不为每个 parser / 数学 helper 增加抽象类。

    5.2 字段和冻结规则

    对象 字段 / 语义
    PrepareRequest task id + 请求版本、operation、validation_scope、输入 pins、任务配置、对照条件、可选既有候选预期身份、预先声明的预算/验收政策引用
    protocol 版本化、可留存的规范 JSON 或 task-owned 文档;包括输入/种子/样本、baseline、reference、质量参考、候选格式、计时边界、重复与顺序、聚合、单位/方向、反馈可见性、必需证据、规则适用范围
    CandidateContract 代码/配置/技能等受支持格式、入口、必需文件/资源、允许内容、任务要求的身份和修改代次规则;不强制给所有候选制造编辑 revision
    CandidateExpectation 若已有候选,可在 prepare 记录预期 id / digest / format;不代表已经执行、已经验证或 Workbench 可以省略实际捕获
    OperationRecipe task-owned 操作入口/实现版本、runtime role / module / digest、显式参数、固定输入/输出角色、资源/能力要求;将相对文件角色转换为执行路径的规则明确化
    指标定义 name、unit、direction、aggregation / timing、protocol revision、claim scope;数值阈值属于具体任务,不引入全仓统一阈值
    EvidenceRequirement 检查 id / 实现版本、对象、阶段、适用 claim、预期产物 schema;必需条件由协议声明,不能由实际跑了哪些检查反推

    prepared_id 识别本次准备信封,protocol_digest 识别实际比较规则;protocol.sha256 只识别完整协议文件字节。已有候选的 expected_candidate 可以改变准备信封,但不能因此把两个不同候选误判为使用不同的统计协议;比较适用性按协议、环境等具体字段判定,不只比较 prepared_id。

    对新增候选搜索:先固定题目、规则、输入、生成约束和预算政策,候选可暂未绑定。对已有候选:允许带预期候选同时 prepare。每次 execute 都要核对实际候选字节,不可在运行后为了适配候选而改 protocol。

    prepare 不是执行授权。现有 plan 仍是预览;新 execute 必须明确消费所选 PreparedEvaluation,而非重新读取 latest task 重建一份可能不同的规格。prepare 无隐式存储副作用;B 提供 encode/decode/validate,apps 在评测执行前显式保存完整准备信封并取得 PreparedRef;不调用模型、设备或候选程序。来源1 §4来源2 §4–5

    recipe 不绑定控制机的 sys.executable 或本地绝对安装路径。Workbench 的目标适配器在受支持的运行环境中解析 runtime role 和入口,核对版本/能力并记录实际解释器、模块及命令身份;不能把本地 Python 路径原样交给远端 executor。

    5.3 保留任务专属测量程序

    Workbench 接管生命周期并不意味着 Benchmark 只剩一个结果 parser。MoE 的同一进程/通信域内交错采样、rank 同步和聚合属于测量算法,可以封装为一个粗粒度 task worker;Workbench 负责该受支持入口的进程树、期限、日志与产物。

    单算子 AB/BA 若已表达为固定顺序步骤,可由 Benchmark 给出步骤和参数,Workbench 推进执行。禁止 Workbench 自己猜测采样顺序,也禁止 apps 外包一轮 AB/BA 到已含交错测量的 MoE 入口上。通用 workflow、重试和资源调度归 Workbench;任务内为测量语义必要的循环归 Benchmark。

    任务启动子 rank 不意味着跨主机进程清理天然受支持。适配器必须说明它控制的资源域及确认释放能力;缺少必需能力时启动前拒绝,不能给本地 process group 的测试扩大到所有远端 launcher。

    5.4 #364 的落点

    建议新增任务特定、独立版本化的 DiffusionVideoQualityPolicy,放在 Benchmark 的 quality evaluator。原 PNG ImageQualityGate 与已冻结历史协议保留。MetricDefinition 明确 gate/diagnostic、单位、范围、aggregation、reference 条件与缺失行为。

    #364 的最新评审指出:随机高频噪声可以增加 Laplacian 方差,闪烁也可能增加帧间差分。故锐度、帧差、亮度目前是待验证的指标候选,不能直接替代成通用 PASS 真值。建议分开媒体几何/完整性与质量,在同精度、同布局、匹配输入的 dense 对照上冻结双侧偏差,再用清晰、模糊、噪声、闪烁与正常运动的独立标注样本验证误接受/误拒。阈值与验收范围仍待原 owner 决定。

    已有留存帧可以显式用新版本离线重评,保留旧 assessment;缺少匹配参考或原始数据时返回缺证据,不生成新视频补齐。来源:#364 增量评审

    6. Workbench.execute:同步尝试、明确绑定、完整保留事实

    6.1 Protocol 与核心 DTO 草图

    以下类型归 Workbench,Benchmark 不导入。配套 DTO 在后文列出。

    from __future__ import annotations
    
    from dataclasses import dataclass
    from typing import Protocol
    
    
    @dataclass(frozen=True)
    class InputSpec:
        role: str
        source: str
        source_namespace: str  # controller / target / artifact
        snapshot_format: str
        expected_sha256: str | None
        materialized_path: str
    
    
    @dataclass(frozen=True)
    class CommandStep:
        step_id: str
        runtime_role: str
        entrypoint_kind: str
        entrypoint: str
        entrypoint_revision: str
        args: tuple[str, ...]
        cwd: str
        outputs: tuple[OutputSpec, ...]
        timeout_seconds: str | None  # 规范十进制秒数字符串
    
    
    @dataclass(frozen=True)
    class ExecutionSpec:
        schema_version: str
        request_id: str
        run_id: str
        attempt_id: str
        owner: str
        target_request: TargetRequest
        retry_of: str | None
        retry_reason: str | None
        generation_record_ref: RecordRef | None
        prepared_ref: PreparedRef | None
        protocol_digest: str | None
        operation: str | None
        validation_scope: str | None
        inputs: tuple[InputSpec, ...]
        candidate: CandidateSubmission | None
        steps: tuple[CommandStep, ...]
        output_root: str
        deadline_utc: str
        resources: ResourceRequest
        budget: BudgetRequest
        required_capabilities: tuple[str, ...]
    
    
    class Cancellation(Protocol):
        def requested(self) -> bool: ...
    
    
    class WorkbenchPort(Protocol):
        def allocate_attempt(
            self, *, run_id: str, owner: str, target_request: TargetRequest,
            deadline_utc: str, resources: ResourceRequest, budget: BudgetRequest,
            retry_of: str | None = None, retry_reason: str | None = None,
        ) -> AttemptContext: ...
    
        def execute(
            self,
            spec: ExecutionSpec,
            *,
            cancellation: Cancellation | None = None,
        ) -> ExecutionRecord: ...
    
        def read(self, attempt_id: str, *, record_version: int | None = None) -> ExecutionRecord: ...

    上述 command steps 只需支持现有固定顺序,不承诺任意分支图或脚本编排语言。首期入口可限定 python_module / executable 两种,runtime_role 和入口由目标适配器解析成实际 argv,并记录解析后的可执行文件/代码身份;未知 kind 明确拒绝。若首个适配器只支持一个粗粒度命令,公开说明该能力即可。任务需要的多步骤不能由 apps 临时维护自己的状态机来补齐。

    首期同步 execute 足够;Cancellation 由 CLI 中断处理或调用方提供,受控执行在轮询点与异常清理路径观察取消。read 只返回已知记录。取消意图、实际退出与确认释放分开记录。跨进程 cancel、reconcile、submit、daemon 和自动 takeover 不属于首期公开 API;未来增加时仍复用同一 attempt/预算账目,不自动重启未知的外部调用。

    Workbench 的普通命令模式允许 prepared_ref、protocol_digest、operation、validation_scope、candidate 为空,因此 W 可在完全没有 Benchmark 的情况下执行 CPU 命令。评测模式中,adapter 必须携带固定 prepared/protocol、operation 和 validation_scope,并满足该任务的输入角色约束;不得用空值绕过。assess(record) 根据记录中的固定 prepared_ref 与 scope 解析,不能依赖最近一次 execution_for 的内存状态。

    6.2 运行前后的记录

    对象 最小字段 / 不变量
    CandidateSubmission candidate_id、kind、input_role、可选 parent id + parent digest、生产者上下文引用;输入来源/预期 digest 只保存在所引用的 InputSpec,不重复维护两份权威字段
    实际输入绑定 role、retained ref、digest、快照格式、捕获时点、attempt / step、预期身份核对结果;真正执行留存快照或经验证的物化副本
    ExecutionRecord schema_version、request_id、run_id、attempt_id、request_digest、owner、target_request/actual TargetBinding、record_version/RecordRef、retry_of/retry_reason、generation_record_ref、prepared_ref、protocol digest、operation、validation_scope、实际绑定、状态、每步开始/结束/退出、取消请求、终止/清理结果、产物清单、检查、预算/用量/租约、错误
    检查事实 check_id、checker revision、对象/阶段、status、producer、evidence refs;通过、失败、未运行、不适用、执行错误须可区分
    证据来源 Workbench 实际捕获、任务 worker 报告、调用方声明分别记录;unknown 不转换为 captured
    产物 角色、格式/schema、留存路径/定位符、digest、大小、产出 attempt/step;输出位置按 attempt 隔离
    环境 所要求条件与实际观测分开;保留执行器/适配器版本、平台、实际加载代码或环境身份中本次协议要求的部分
    时间 绝对 deadline 用于跨层约束;进程内持续时间和超时使用单调时钟;子步骤上限不得延长 run / campaign deadline

    输入捕获后,不继续从原始可变路径执行。目录候选需要明确定义树清单、路径规范与 hash 版本;内容 hash 仅证明所捕获的字节身份,不自动证明整个期间未发生过写入,更不替代某些编辑适配器的操作代次 receipt。现有更严格语义保留,简单内容快照流程不强行引入编辑会话。

    任务入口读取自己的冻结协议和已物化的候选路径;Workbench 保留它实际执行的路径/字节绑定。task worker 的回显身份必须与本次 attempt、operation、candidate 相符。apps 只转换已有事实,不能自行生成通过记录。

    API的ExecutionRecord采用平铺返回信封;持久payload排除record_ref、observed_at、controller_observation,recorded_at仍参加摘要。评测只消费固定RecordRef对应的payload。

    6.3 同步状态机应足够小

    建议存储 phase 和结束事实,避免一个 SUCCESS 同时代表所有层:

    phase 语义与允许后继
    registered 请求身份与输出位置已登记,尚未预算准入/启动;进入 preparing,或以 not_started 结束
    preparing 预算准入、资源检查、输入捕获/绑定;进入 running,或以 not_started 结束
    running 正在推进已授权步骤;进入 stopping 或 finalizing
    stopping 已请求/正在终止;不能宣称 cancelled 已完成,也不能立即重分配未确认释放资源
    finalizing 收集可得产物、确认清理、核算用量、提交记录
    finished 记录完整提交且生命周期收束;仍可能 exit nonzero / timed_out / cancelled,并不表示任务 PASS
    recovery_required 控制器失联、清理未确认或提交未完成;读取可展示已知事实,禁止当作成功或自动重启

    process_outcome 独立记录 not_started / exited / timed_out / cancelled / execution_error,exit_code 另列。cleanup 独立记录 not_needed / confirmed / failed / unknown;“取消已请求”另有字段。

    先登记 attempt 和预算范围再启动。执行前的资源不足、能力不支持、身份不符要保留 not_started 原因。若连 attempt 记录都无法持久化,抛 ExecutionPersistenceError(started=false) 并不启动;启动后提交失败尽力清理并保留局部记录,统一抛 ExecutionPersistenceError(started=true, partial_record, retained_refs)。接口不能承诺磁盘不可写时仍必然得到完整记录。

    6.4 预算、用量、资源租约必须三个对象

    DTO 必需内容 不能推导什么
    BudgetAdmission / Reservation(W产生的结果) 同一 campaign / PR 的 scope_id、policy id + revision、声明者、维度/单位、限额、reserved / charged capacity、准入结果、实际强制能力 charged capacity 不是供应商实付;改变 run_id 不创建新预算
    UsageObservation token / wall time / device time / 可得费用;amount 可未知,unit、采集来源、完整性和观测时点明确 未知不记零,也不拿最坏预留替代 actual cost
    ResourceLease 设备/进程/服务或隔离资源域、owner、lease_id、取得时间、释放请求、确认释放、失败原因 已释放未来容量不能抹掉已消耗时间或退回既有不退款预算容量

    金额使用带币种的十进制值,token 使用整数;不将不同维度相加为一个 cost。硬上限只对执行器已支持并可验证的能力作承诺。token 停止准入阈值和供应商实际收费硬封顶不是同一能力。

    BudgetRequest 是执行前政策输入,不含已准入/已预留回执;BudgetAdmission / Reservation 只由 W 产生。预算政策由发起方与验收主体确定。Workbench 负责支持能力检查、预留、限制和累计记录;Benchmark 只根据预先冻结的某项 claim 是否要求预算证据作解释。超额、缺证据、policy 不支持是不同原因。预算政策缺失不能由 apps 在结果出来后默认为非必需。来源1 §7来源3

    包装现有账本必须保留其不同政策:既有 PR 的保守预算容量、daily ledger 的窗口和 claim_once 的一次性执行权不能用同一个“退款/重放”规则覆盖。claim 结果不确定或 claimed 后崩溃,不能仅凭新 request_id / 新进程自动接管执行。读账、准入、执行权和实际消费四种事实分别说明。

    6.5 优化循环:Workbench 自有端口

    Workbench 的 CampaignCoordinator 拥有尝试推进、累计预算、deadline、候选依赖和取消。apps 创建并注入适配器。首期已有候选路径直接组合 prepare / execute / assess;接真实优化循环时再实现以下 W 自有端口。

    class CandidateProvider(Protocol):
        def plan_generation(self, context: CandidateContext, attempt: AttemptContext) -> GenerationPlan: ...
        def collect_candidate(self, record: ExecutionRecord, *, artifacts: ArtifactReader) -> CandidateProposal: ...
    
    class EvaluationPort(Protocol):
        def execution_for(
            self, prepared_ref: PreparedRef, proposal: CandidateProposal,
            attempt: AttemptContext, *, scope: str
        ) -> ExecutionSpec: ...
    
        def assess(self, execution: ExecutionRecord) -> AssessmentSummary: ...
    
    class ContextProvider(Protocol):
        def collect(self, request: ContextRequest) -> DeliveredContext: ...

    完整 DTO 字段与调用例见“可实施契约”。CampaignPlan 搜索前持有各验证阶段的 PreparedRef / protocol digest。execution_for 不改 W 分配的身份、目标、期限和 BudgetRequest,不重选 latest 任务。apps 注入的 adapter 调用 B 公共接口并转换 DTO;知识 adapter 调 K,W 留存实际交付快照。

    真实Agent固定为 plan_generation → W.execute → collect_candidate;两端不发外部调用。CandidateProposal 包含candidate、完整InputSpec及generation_record_ref。generation和evaluation各自attempt共享预算scope和总deadline。首期fixture不等于真实Agent资格。

    AssessmentSummary 带实际已保存的 AssessmentRef、candidate/attempt/protocol/scope、分范围结论、metric validity和证据。选择策略需要的eligible/ineligible/unknown或better/equivalent/worse/incomparable由B给出,W按冻结策略消费;PASS不自动表示更优或最终接受。assess按固定record revision与PreparedRef恢复,不依赖最近一次调用内存。

    7. Benchmark.assess:离线、范围化、不覆盖历史

    7.1 EvidenceInput 不是直接传 Workbench 内部对象

    apps 的适配器将 ExecutionRecord 转为 Benchmark 自有的只读 EvidenceInput。转换必须保留原记录引用及 digest、protocol / candidate / operation / attempt 关联、退出/清理事实、检查的来源与状态、原始产物、预算和环境中本次协议需要的事实。

    映射可以是字段一一复制和格式转换;不能替 Benchmark 判定哪些证据足够,也不能默默省略执行错误。建议对这个适配器用一个固定输入/输出 golden fixture 证明没有丢失关键身份、状态和单位,而非为每个字段写一套镜像单元测试。

    DTO 字段 / 语义
    EvidenceInput schema、原 ExecutionRecord 引用/摘要、prepared/protocol/task/candidate/operation/validation_scope/run/attempt 身份、只读执行事实、artifact refs、check observations、可选 lineage 关联
    EvaluationResult schema、assessment_id、task / protocol / assessor 版本、所依据 record / artifact digests、candidate + attempt、claims、metrics、评估时间、可选 supersedes / derived_from
    ClaimResult claim id、scope、PASS / FAIL / INCONCLUSIVE、理由码、使用证据、缺失证据、适用限制
    MetricResult 指标名、单位、数值或 unavailable、validity 及原因、原始样本引用、聚合方法/协议版本;不要要求每个任务给一个总 score

    assess 先核对对象与版本,再检查每项 claim 的必需证据,再由 task-owned evaluator 解析和计算。离线可以做文件解析、hash 核对、统计重算;不调用候选程序,不访问模型服务/设备,不从可变 upstream 拉新资料,不在缺原始数据时偷偷重测。ArtifactReader 仅提供已留存且可校验的只读材料。

    task-owned 解析器代码是安装包的一部分;历史记录不能把任意 Python 模块路径或 pickle 作为 assessor 指令。读取历史材料按支持的 schema 转换,未知版本明确不支持;历史重判不是自动运行归档中的代码。

    7.2 失败不能跨范围互相覆盖

    输入情况 应有结果
    候选格式独立检查已证明错误,但测量未启动 该格式 / 正确性范围可 FAIL;执行状态仍 not_started;无性能结论
    正确性已证明失败,随后清理失败 正确性 FAIL 保留;性能可能无效;清理失败独立存在
    进程退出 0,但缺 rank / 缺必需原始样本 相关比较 INCONCLUSIVE 或对应 metrics invalid,不能从退出码补 PASS
    进程非零退出,但 task grader 已产出可信的明确错误证据 依协议保留候选 FAIL,不能统一降成“基础设施失败”掩盖候选错误
    产物来自另一候选 / operation / attempt 不作为本次通过证据;标识不匹配及缺本次证据;不能随意认定本次候选数学上错误
    尚未启动,仅资源不够 执行 not_started,相关评测证据不足;不制造候选 FAIL
    预算用量未知 按预先声明的具体 claim 要求处理;无关的已证候选错误不被抹掉

    按 task 固定规则可给一个 scoped task verdict,但不能生成涵盖执行完成、任务通过、实验验收、发布和知识推广的“总 PASS”。

    7.3 重判与版本

    同一 prepared + 同一证据 + 同一 assessor 版本应得到确定的语义结果;评估时间等非语义元数据不影响结果身份。重判持久化为新 assessment 或返回已有相同结果,不覆盖原执行记录。

    Benchmark 与 grader 可以演进。升级版本不使所有旧比较自动失效;旧结论保留原 protocol / grader / 数据范围。若发现特定旧 grader 缺陷,单独记录哪些结论需复核或撤回,以及为什么;新评分版本和旧评分不能未经可比性确认混排。

    重新运行检查是另一次显式 execute / attempt,不是 assess 的降级路径。旧 benchmarks grade 当前会执行检查的兼容入口,不能在迁移中悄悄改成纯离线;需要保留行为并说明与新 assess 的区别,或另行宣布弃用。来源1 §4–5、§8来源2 §1

    8. 错误、幂等与版本:不做新的基础设施平台

    8.1 错误类别

    每包公开自己的错误类或稳定 reason_code,保留旧入口原异常/CLI 语义。可共享文档词汇,不要求全仓共继承一个巨型错误体系。

    类别 典型情况 后续处理
    InvalidRequest 参数/路径/schema 格式错误 不重试执行;调用方修正
    UnsupportedOperation / UnsupportedSchema 不支持 task action、平台能力或记录版本 明确拒绝;不得静默走近似功能
    RevisionConflict / IdentityMismatch Knowledge CAS 冲突、candidate / task / artifact 身份不符 不采纳旧结果;保留冲突事实
    AdmissionRejected 资源/预算/硬能力不足,deadline 已过 not_started;可在政策允许下新建 attempt
    ExecutionError / Timeout / Cancelled 启动或运行发生的事实 保留本次 attempt、局部产物和已知消耗
    CleanupUnconfirmed / PersistenceError 退出/释放未确认、记录提交失败 recovery_required 或显式不完整记录,不自动再启动
    EvidenceInvalid / EvidenceMissing 证据格式、对应关系、完整性不足 通常是 assess 的结构化原因,不因可预期缺证据就把整份报告异常丢弃

    数据损坏导致整个输入无法识别、或 assessor 自身程序 bug 时可抛异常。候选不正确、样本不完整、缺预算证据等可预期评估结果,应返回可解释的 ClaimResult。

    8.2 幂等策略

    操作 首期规则
    Knowledge read / resource 指定 revision 的读取稳定;latest 解析可能随时间变化,但返回实际 pin
    Knowledge collect 固定集合/方法/参数才有可重放性;动态搜索结果不能宣称永久相同
    Knowledge create / update 保留现有唯一身份与 CAS;重试写入前核对 current/history,不把 conflict 当成功;首期不假装已有请求去重日志
    Benchmark prepare 规范化冻结内容形成可验证身份;别把时间戳、临时目录混入协议 hash
    Workbench execute request_id 是提交幂等键,首期必须等于 attempt_id;同时保存规范化 request_digest;同 request_id + 同 spec 已finished则返回原记录,进行中抛AttemptInProgress,控制者未知/recovery_required抛RecoveryRequired,不重复启动;同 request_id + 不同 spec 明确冲突;既有 attempt 不得被另一 request 覆盖或重新启动
    重新测量 / 重试 新 attempt_id,引用前次 attempt / retry reason;沿用同 budget scope 和 campaign deadline;不是“把原 attempt 再跑一遍”
    Benchmark assess 原始输入与 assessor 固定时语义确定;可重复读/算,无外部执行副作用

    execute 至少用现有本地锁/事务或原子创建保留 request / attempt 记录;request_id 的去重不等于外部 side effect 的 exactly once。网络断连、provider 状态未知或控制器崩溃时,无法确认是否执行过则标记 recovery_required / side_effect_unknown,不因未看到最终输出就再启动。清理和实际资源核对是后续显式恢复流程的工作。重试新 request 也不得绕过已有 claim_once 或同一预算 scope 的限制。

    若以后需要写入请求的幂等保证,Knowledge 可加 write_request_id + request digest 的事务记录,原子保存写入结果;这是新能力,不能绕过现有 expected revision 直接靠目标 hash 猜测某次写入是否已成功。

    8.3 版本策略

    1. 包一起发行不等于持久化格式无需版本:新 PreparedEvaluation、ExecutionRecord、EvaluationResult 信封各有 schema_version。现有 Bundle 沿用原 manifest/revision;新增版本信息放在外层交付信封,不改变历史 Bundle hash。
    2. 数据使用 JSON 及显式资源引用;禁止 pickle 绑定 Python 模块路径作为跨版本持久契约。
    3. 未知主版本明确不支持;可选新字段的读取策略有测试。保留原始旧记录,适配投影不能回写历史。
    4. 逻辑知识路径、ID、依赖 pins、plugin manifest/ID 和宿主 session 协议都是兼容面;物理迁移不能顺手改变。
    5. 持久 record 中的 command、代码/适配器版本、实际环境身份与 task/候选身份分开,不能仅凭整个发行物版本解释所有差异。

    具体返回表、不可变记录修订、来源匹配、编码投影及新进程用例见“可实施契约”。

    可实施契约与完整交接用例

    可直接用于实施的契约补充(v0.3,待讨论确认)

    以下约定补齐接口的构造者、持久化、调用顺序和返回行为。它们是本稿明确推荐的设计,尚未成为 main 的实现或 #362 的 accepted 决定。开发者应先引用已确认的决策,再实现对应切片。

    1. 谁定义类型,谁持有数据,谁负责转换

    内容 类型与编码规则的 owner 保存 / 读取 交接位置
    Bundle、Collection、知识版本 Knowledge 现有 source / store Apps 把实际交付内容交给 W 留存
    PreparedEvaluation 与协议 Benchmark Apps 通过注入的字节存储保存;离线可使用目录存储 B 提供 encode/decode/validate;Apps archive_prepared 返回固定引用
    AttemptContext、ExecutionSpec、ExecutionRecord Workbench W RunStore 与 artifact store Apps 将 B 配方转换为 W 的请求
    EvaluationResult Benchmark Apps 保存 B 编码后的结果,再给 W 摘要及引用 B 解释结果;Apps 不重新计算 verdict
    NormalizedTask 与字段来源 Apps 预览不保存;显式 plan/run 可按现有规则留存 Apps 将配置投影为 K / B / W 自有请求

    核心模块只依赖本模块类型、标准库及明确的纯叶子工具。Apps 可以导入三个模块的公开 api;K、W、B 均不得反向导入 Apps,也不互相导入实现。W 通过声明的命令启动 B 的 task worker 是执行关系,不要求 W import B。测试只在真实适配边界验证转换;无需创建第四个业务 contracts 包。

    固定引用的字段

    下面是结构规范。B 和 W 各自公开所需的值类型;同名字段通过 Apps 显式转换,不让 W 的 PreparedRef 继承 B 的实现类。

    类型 字段 构造与不变量
    ArtifactRef location, sha256, size_bytes, media_type 读取先核验字节;location 可变化但不能改变 sha256。写入方返回成功后才产生可引用对象
    PreparedRef prepared_id, schema_version, artifact: ArtifactRef 指向不可变的完整准备信封;协议和 assess 所需资源一并可访问。只存 prepared_id 或临时内存 registry 不合格
    RecordRef attempt_id, record_version, artifact: ArtifactRef 指向一份不可覆盖的运行记录修订;current 指针可以推进,旧 revision 必须可读
    AssessmentRef assessment_id, schema_version, artifact: ArtifactRef B 确定内容和语义身份;Apps 保存后返回引用。存储失败不能制造引用或推进候选
    TargetRequest target_id, executor_kind, config_revision 无凭据的目标配置请求,纳入 request digest;首期只接受实际实现支持的 kind。每一步的runtime_role是唯一运行时请求,目标配置按step解析
    TargetBinding target_id, config_revision, executor_version, runtime_bindings_by_step, control_domain, capability_checks W 记录目标端实际解析;请求支持某能力不代表目标已具备
    BudgetRequest policy_ref、scope_id、请求限额/预留估计及单位、所需强制能力 仅表达输入政策,不能自填已准入/已预留;是否适用由 W 按现有能力和政策校验
    AttemptContext request_id, run_id, attempt_id, owner, target_request, deadline_utc, resources, budget: BudgetRequest, retry_of, retry_reason W 分配。首期 request_id == attempt_id;仅分配身份不占用预算、不获取资源、不启动。adapter 不能重建 ID 或延长期限。retry_of/retry_reason同时为空或同时提供
    CandidateProposal candidate: CandidateSubmission, inputs: tuple[InputSpec, ...], generation_record_ref: RecordRef 或 null candidate.input_role 必须唯一指向 inputs 中的一个 role;来源/预期摘要以 InputSpec 为唯一权威。已有人工候选允许 generation_record_ref=null 并保留来源声明
    OutputSpec role、相对 attempt 目录的 path、required、media_type、format_schema W 按明确路径收集并绑定 attempt/step;缺必需产物记录 failed check,不从旧目录补成功文件

    所有 snapshot ref 都引用规范编码后的字节。记录自己的 ref 放在返回信封外层,不参与它引用的 payload 摘要;其余业务字段包括 record_version 必须参加摘要。新协议规定 UTF-8 JSON、键排序及字段级数值编码并提供固定 fixture;JSON 内禁止 NaN/Infinity,参与新请求摘要的非整数阈值/限额使用规范十进制字符串。Knowledge 的旧 Bundle 编码与 revision 算法保持原样。实现 S1 必须给出规范编码的精确 fixture,未通过它不能宣称跨语言摘要兼容。

    API 的 ExecutionRecord 采用平铺返回信封:持久 payload 字段加 record_ref、observed_at、controller_observation。持久字节仅编码 payload,明确排除上述三个读取/引用字段;recorded_at 是已提交事实时间,仍在 payload 内。to_evidence 使用 RecordRef 对应的固定 payload,读取时新观测到的控制者状态不能无引用混入评测;需要采用时先形成新的记录修订。S1 的 schema/fixture 应固定这个投影,不由各 adapter 自选嵌套形状。

    2. 准备与判定都可脱离工作台进程

    Benchmark.prepare 是无实验副作用的准备计算:读取显式声明的资产、验证配置、生成 PreparedEvaluation。它不占用执行预算、不启动服务、不调用模型,也不自行写入隐式全局目录。B 提供 encode_prepared / decode_prepared / validate_prepared 纯函数。

    执行前必须由 Apps 的 archive_prepared 完成显式保存,取得 PreparedRef。保存至少包括准备信封、协议及离线判定所需的数据资源;已有大对象可保留经过摘要核验且离线可读的固定位置。引用不保证永远可访问,后续缺失必须报 unavailable,不能重新 resolve latest 来补齐。

    assess(record) 的 Apps 适配器按 record.prepared_ref 读取固定准备信封,交由 B 解码、验证,再把该 record revision 投影为 EvidenceInput。适配器不依赖上一次 prepare 或 execution_for 的进程内状态。

    B.assess 返回结果 DTO;B 的 encode_assessment 负责规范编码及验证。Apps archive_assessment 显式保存后,才能交付带 AssessmentRef 的 AssessmentSummary。独立离线使用者可自己提供本地 ArtifactReader 和存储,不必创建 W 服务。重复计算允许生成相同语义结果;时间等非语义元数据独立,旧结果不覆盖。

    3. 现有候选的完整交接

    下面的名称是目标 API 草案,不是声称仓库已经存在这些调用。archive_* 是 Apps 的小型装配函数,字节存储通过构造参数注入;W 提供的存储只认识字节和引用,不理解 B 的评分规则。

    # Apps:三个模块的公开 API 只在这里组合。
    prepared = benchmark.prepare(prepare_request)
    prepared_ref = bridge.archive_prepared(prepared)  # 保存成功后返回引用
    
    attempt = workbench.allocate_attempt(
        run_id=run_id,
        owner=owner,
        target_request=target_request,
        deadline_utc=deadline,
        resources=resource_request,
        budget=budget_request,
    )
    spec = bridge.bind_execution(
        prepared_ref=prepared_ref,
        prepared=prepared,
        proposal=existing_candidate,
        attempt=attempt,
    )
    record = workbench.execute(spec, cancellation=cancellation)
    
    # 可在新进程完成下面的逻辑;只从固定 record/prepared/产物引用恢复。
    evidence = bridge.to_evidence(record)
    loaded = bridge.load_prepared(record.prepared_ref)
    result = benchmark.assess(loaded, evidence, artifacts=artifact_reader)
    assessment_ref = bridge.archive_assessment(result)
    summary = bridge.to_summary(result, assessment_ref)

    bind_execution 检查 prepared_ref 与 prepared 的身份一致;按任务输入角色绑定 CandidateProposal,逐字段保留 AttemptContext。目标条件不支持、阶段不匹配、缺必要输入时明确拒绝。环境、授权和资源等即时状态仍由 W 执行前检查,预览通过不保证稍后准入。

    ExecutionSpec 必须含 target_request、retry_of/retry_reason、generation_record_ref;后两类可明确为空。bind_execution 将 AttemptContext 的重试来源与 CandidateProposal 的生成记录引用保留到 spec/record,并纳入请求及记录摘要。人工候选的 generation_record_ref 为null,不能制造生成执行历史。

    CommandStep.outputs 使用 tuple[OutputSpec, ...],InputSpec.materialized_path、CommandStep.cwd 及 OutputSpec.path 采用相对于 attempt 工作目录的逻辑路径,拒绝逃出允许根的路径;输出按 attempt 隔离。固定 steps 默认 fail-fast:某步启动失败、非零退出、必需输出缺失、超时或取消后,后续步骤记 not_started。测量算法若需要采集并继续,由一个 task-owned worker 实现并报告,其内部规则在协议里冻结,Apps 不增加另一套循环。

    4. 同步 execute 的唯一返回规则

    情况 行为 是否可自动启动
    请求 schema / 路径不合法,尚未登记 抛 InvalidExecutionSpec,携带字段错误;不保留“已运行”记录 否,修正后由调用者提交
    首次合法请求,登记持久化失败 抛 ExecutionPersistenceError(attempt_id, started=false, partial_record=null) 否
    已登记,预算/资源/能力/输入身份未通过 持久化并返回 not_started 的 ExecutionRecord,含拒绝原因 否,显式新 attempt 仍受同 scope 政策约束
    同 request_id、不同 request_digest 抛 RequestConflict,保留原请求 否
    同请求,旧记录 finished 返回原固定记录;不能重跑 否
    同请求,有有效 owner lock 且仍在进行 抛 AttemptInProgress(attempt_id, latest_record_ref),不等待、不替换控制者 否,调用者可 read
    同请求,控制者状态无法确认,或记录 recovery_required 抛 RecoveryRequired(attempt_id, latest_record_ref),不接管外部操作 否
    本次执行结束,记录已持久化 返回 ExecutionRecord;其 process/cleanup/phase 如实表达,可能为 recovery_required 否
    本次启动后记录无法提交 抛 ExecutionPersistenceError(attempt_id, started=true, partial_record, retained_refs),尽力清理 否,异常所带局部事实不冒充已提交记录

    阶段统一为 registered → preparing → running → stopping/finalizing → finished 或 recovery_required。registered 仅表示身份登记,不表示预算准入已经通过。finished 允许 process_outcome 为 not_started / exited / timed_out / cancelled / execution_error;cleanup 是独立的 not_needed / confirmed / failed / unknown。存在未确认的外部进程/租约不能转为生命周期 finished。

    read(attempt_id, record_version=None) 返回最新已提交快照;传 record_version 返回该固定历史版本。返回信封包括 record_ref、observed_at 和 controller_observation(observed / unavailable,附来源与时间)。旧 running 记录只证明曾进入 running,不能单凭它推断当前存活或已清理;read 不执行恢复或重启。首期跨进程 cancel、daemon、自动 takeover 均不在契约内。

    评测引用固定 RecordRef。后续清理补证形成新 record_version,可派生新的 assessment;旧 assessment 继续指向原记录版本。给“当前文件”重新写内容、保持旧 ref 不变,违反本契约。

    去重仅在同一配置的 RunStore 执行命名空间内成立。output_root 只是该命名空间下的产物位置,不得借改路径绕开 claim;不同本地目录不是全局去重系统。BudgetRequest 在执行前表达意图,BudgetAdmission/Reservation 只能由 W 的实际准入产生;没有政策的付费请求必须拒绝,不能把 null 当作预算豁免。

    普通免费本地CPU可用 policy_ref=null、空请求限额,前提是W确认所选执行能力不含付费行为且该任务不要求预算政策;仍记录scope、期限和实际可观测用量,不创建假政策。后续真实Agent/provider要求有实际预算规则时,该空值请求启动前拒绝。

    5. 优化循环中的三类端口

    Workbench 拥有循环、候选依赖、执行尝试和推进状态。它声明自己需要的端口;Apps 构造具体适配器。这些类型属于 W,B/K 不 import 它们。

    class CandidateProvider(Protocol):
        def plan_generation(
            self, context: CandidateContext, attempt: AttemptContext
        ) -> GenerationPlan: ...
    
        def collect_candidate(
            self, record: ExecutionRecord, *, artifacts: ArtifactReader
        ) -> CandidateProposal: ...
    
    
    class EvaluationPort(Protocol):
        def execution_for(
            self, prepared_ref: PreparedRef, proposal: CandidateProposal,
            attempt: AttemptContext, *, scope: str
        ) -> ExecutionSpec: ...
    
        def assess(self, record: ExecutionRecord) -> AssessmentSummary: ...
    
    
    class ContextProvider(Protocol):
        def collect(self, request: ContextRequest) -> DeliveredContext: ...
    配套类型 最小内容
    CandidateContext campaign_id、generation_id、当前候选/父依赖、任务可见材料、DeliveredContext 引用、允许反馈、目标候选格式;不包含 final holdout
    GenerationPlan spec: W 自有 ExecutionSpec、manifest: GenerationManifest;spec初稿尚不含generation_plan输入,计划生成本身不调用模型/设备
    GenerationManifest schema_version、provider_id/revision、output_contract、已存在的context_refs、attempt_id;output_contract含候选manifest角色、主候选角色、格式、必需输入角色、parser_revision
    AssessmentSummary assessment_ref、candidate/attempt/protocol/scope、分范围结论、指标有效性、Benchmark 已给出的 eligibility/comparison、使用证据
    ContextRequest 查询、版本 pins、选择限制、交付字节上限与本轮标识
    DeliveredContext 内容产物引用、每项知识身份/revision、实际交付范围、选择与遗漏说明;交付不证明采用
    CampaignPlan 目标、固定起点、各 scope 的 PreparedRef、共享 budget scope、campaign deadline、推进/停止策略、允许反馈范围

    真实 Agent 的执行路径固定为 plan_generation → W.execute → collect_candidate。plan_generation 与 collect_candidate 不做外部执行,generation 与 evaluation 使用各自 attempt 但共享 budget scope / 总期限。首期 fixture 可生成确定候选验证装配,不能据此宣布真实模型、宿主或远端能力已验收。

    两步之间由 W Coordinator 的 seal_generation 小型内部函数明确留存计划:先保存 GenerationManifest 取得 ArtifactRef,再把 role=generation_plan、expected_sha256=该摘要的 InputSpec 加入最终 spec,最后计算 request_digest 并执行。manifest 不含自身引用、完整 spec、本次尚未产生的 RecordRef 或候选引用;已有 context_refs 可作为输入,因此不存在循环摘要。该保留角色冲突时拒绝,不覆盖调用方输入。

    collect_candidate 从 record 的实际 BoundInput 读取 generation_plan,按其固定 output_contract 解析本 attempt 的产物;不读原可变 source 或内存里的最新配置。缺 manifest、版本不支持、候选角色/格式/attempt 不匹配时明确失败。provider_id/revision 本身是计划声明,必须与实际 worker/命令身份对照才能归因,不能单凭字符串声称某个模型已执行。

    execution_for 只能使用既有 prepared_ref、proposal 和 W 分配的 attempt;不得在 adapter 中重选 latest task、修改门槛、生成另一套 ID 或延长总预算。assess 的返回只有在对应结果已经持久化后才带 assessment_ref。W 根据 B 给出的比较资格和冻结推进规则行动,PASS 本身不表示更优或最终验收。

    #363 的后续扩展仍按单父 + 单投机后继建议讨论。multiple starting points 尚待独立范围决定;不能因接口能保存多个 ID 就声称已实现多分支调度或失效传播。范围澄清

    6. 模块内部的实际依赖与首批实现

    模块 内部调用关系 首期真实实现 后续扩展点
    Knowledge API → sources / selection / bundle;写入 API → 现有 store 固定 revision 读取、选择结果、资源交付、CAS 兼容 新检索算法接 selection;新来源实现 KnowledgeSource,不建立全库统一状态机
    Workbench ExecutionService → RunStore / InputBinder / ProcessExecutor;按适用政策使用 BudgetController / ResourceManager 一个真实 CPU 进程树、快照输入、超时取消、不可变记录修订、查询 CampaignCoordinator 调用注入端口;实际受支持的 remote/resource 能力逐项增加
    Benchmark API → TaskCatalog → TaskAdapter;prepare 形成 task worker 配方;assess → EvidenceValidator / parser / quality / metrics 准备信封与编码、已有任务配方、原始证据离线判定 新任务添加 adapter/worker;新质量政策版本化,不在 W 增加评分分支
    Apps TaskDocument → normalize / validate → K/B/W 请求;Bridge ↔ 三模块公开 API;Host adapter → Apps CLI 与纯配置转换、持久引用装配、显示原结果 实际宿主各自迁移;#365 YAML 依赖和 DSH v1 范围单独确认

    先移动责任和稳定出口,保留兼容 wrapper,再迁移物理目录。不要按目录名整块移动混合职责代码。例如 runner 中的 AB/BA 规则归 B,进程与记录归 W;dashboard 的原始记录 helper 应先下沉到 W,避免 W 反向依赖展示层。资源移动同时检查 wheel 和宿主包,而不只验证 checkout。

    7. 开发者必须能演示的三个用例

    用例 输入与步骤 输出与应验证的反例
    仅查询知识 在 checkout 外安装普通发行物;K.collect 得到固定 pins,再 K.resource 不导入设备/Agent 依赖;指定旧 revision 不存在明确失败;逻辑资源与摘要保持兼容
    已有候选执行与离线判定 B.prepare → 保存 prepared → W.execute → 保存记录 → 退出进程 → 新进程 B.assess 不依赖内存 registry;篡改 candidate/record摘要拒绝;缺原始样本返回缺证据;离线阶段无 subprocess/网络/设备调用
    注入 provider 的循环 固定 CampaignPlan;生成计划 → W执行 → 收集候选;评测后按冻结策略推进 generation/evaluation 不重置预算;旧父依赖/迟到结果不能推进;fixture 成功与真实Agent资格分开记录

    S1 的契约 fixture 必须覆盖同 key 冲突、进行中重入、prepared/record 修订引用、适配器字段保真、目标端能力拒绝和 fail-fast。S2/S3/S4 分别实现真实行为后再做 S5 组合;不把所有新门禁一并施加给无关在途 PR。

    8. 新信封的摘要与检查匹配规则

    S1 推荐固定 inferrsi-json-v1:新信封键为 ASCII schema 字段或明确的 ASCII ID;键按字典序排序、数组保持定义顺序、UTF-8、无 BOM、无末尾换行、无无意义空格,字符按 JSON 必需规则转义且中文不转义。输入拒绝重复键、孤立 surrogate、浮点/NaN/Infinity。整数使用十进制无前导零;字段需要非整数时使用规范十进制字符串(不含指数、无多余零、负零归零),数值域由字段 schema 校验。原始样本文件可保留任务格式,摘要直接针对其原始字节。用户 YAML 在 Apps 正规化后才进入此编码,Knowledge 旧编码不变。

    身份 参与摘要的内容 明确排除
    protocol_digest 冻结规则、操作/scope、样本/输入要求、判据、任务/规则版本;资源按逻辑 role + hash + size + format 投影 存放 location、展示文本、准备时间、尚未绑定的候选
    prepared_id 准备信封语义,包括 protocol_digest、recipe、required evidence、candidate contract/expectation;资源引用用身份投影 自己的 id、存放位置、生成时间
    PreparedRef.artifact.sha256 完整规范编码的准备 payload,包括 prepared_id 及实际可读资源引用 外层 ArtifactRef 本身
    request_digest ExecutionSpec 全部 v1 定义字段,含目标、输入来源、身份、prepared 引用、scope、steps、输出、期限、资源和 BudgetRequest 外层回执及计算出的 request_digest;未知字段直接拒绝
    RecordRef.artifact.sha256 本次完整固定记录 payload,含 record_version、事实来源、时间及产物绑定 外层 record_ref 与读取时增加的观测信封
    assessment_id 依据的 prepared/protocol/record 与证据字节身份、规则/实际 assessor 版本、claim/metric/原因;资源引用用身份投影 自己的 id、assessed_at、存放位置;完整结果字节仍由 AssessmentRef.artifact.sha256 固定

    PreparedEvaluation 明确同时保存 protocol_digest 和 protocol: ArtifactRef:前者是表中规则投影的语义摘要,后者的 sha256 是完整协议文件字节摘要。ExecutionSpec / ExecutionRecord / EvidenceInput 都传递名为 protocol_digest 的语义字段;读取 protocol 文件还必须核对其独立字节摘要,二者不可互换。迁移旧字段时 adapter 根据其原定义转换,不能仅改名字便宣称等价。

    这里排除的展示文本仅指纯UI注释;任务指令、提示词、判据解释及影响测量/评分/生成的内容必须按角色保留并参加对应身份。输入角色的集合先按 role 排序;执行步骤和样本顺序有语义,不能重排。目录快照采用有版本的 manifest,路径使用相对 POSIX 形式并拒绝逃逸、重复逻辑路径和未支持链接;不能把 OS 遍历顺序当摘要规则。S1 交付至少两个跨入口编码 fixture,其中一份含非 ASCII 值、十进制阈值、空值、重排键及数组顺序反例。

    EvidenceRequirement 还须冻结允许的来源种类/控制域及匹配规则;默认匹配 check_id、checker_revision、subject/candidate、attempt、operation/scope、phase、artifact schema。完全相同的证据可去重,矛盾记录形成 conflict;未有更具体任务规则时,受影响 claim 为 INCONCLUSIVE,不能最后一条覆盖。不同范围的失败按各自规则保留,清理状态不覆盖已有正确性错误。worker 自填 producer.kind 不会升级为独立核验,来源强度以实际采集路径和可核对证据为准。

    冻结 grader/rule 版本与实际运行的 assessor 版本分别记录。默认 assessor 必须显式支持 prepared 的冻结规则;不支持则 UnsupportedRuleVersion,不按新默认阈值解释。新政策重评创建新的 prepared/policy 引用及派生关系,旧结论保留。

    内部 TaskAdapter.assess 与公开接口统一:assess(prepared, evidence, *, artifacts: ArtifactReader)。TaskCatalog / task asset reader 在 Benchmark 服务构造时注入;单次 evidence reader 从参数传入,不使用全局隐式 store。

    数据格式、检查、事件与兼容

    数据格式的共同规则

    这些是协议约定,不要求引入共同业务包。每个 owner 维护自己的类型;apps 的 adapter 验证并保留字段意义。

    主题 必须写入实现的约定
    schema 与规则版本 持久信封使用各自 schema_version;task、worker、protocol、assessor、artifact format 分开固定。未知主版本拒绝。新可选字段不得改变已有 verdict 含义。
    数据格式 JSON + 显式字节资源。普通数据不包含任意 Python callback、pickle 或从证据指定导入的模块。任务 worker 只能来自已支持且固定身份的入口。
    摘要 canonical JSON 编码/路径规则须随 schema 固定并提供跨平台fixture。payload 摘要排除自己的回执字段,record_ref 在外层保存。Knowledge Bundle 仍沿用既有算法,不为统一格式重算历史 revision。
    标识 task_id、protocol_digest、candidate_id、run_id、attempt_id、request_id、assessment_id 不混用。request_id 首期必须等于 attempt_id,作为提交去重键并绑定唯一请求摘要;同key同spec已finished返回原记录,进行中抛AttemptInProgress,未知控制者抛RecoveryRequired,不同spec冲突;既有attempt不能被其他request覆盖。
    时间与金额 UTC用于关联,单调时钟用于进程时长/deadline;跨节点wall time不由时长相加。金额为带币种十进制,token整数,未知null,与已观察零分开。
    产物读取 ArtifactRef 只含 location/sha256/size_bytes/media_type。ArtifactRecord 另含 role、artifact: ArtifactRef、format_schema、producer: ProducerRef、subject_ref、attempt_id(准备资产可null)。EvidenceInput 使用产物记录;ArtifactReader.open只读取其artifact,校验留存字节。location不等于身份。
    输入冻结 进入执行前绑定真实字节并从留存快照或核验物化副本执行。task-owned候选修改代次/receipt约束继续保留,不被内容hash替代。
    兼容入口 旧参数、CLI exit code、输出字段与公开import由wrapper保留。旧grade会执行check;新assess离线。行为变化用显式新版本/弃用计划。

    来源与执行阶段字段

    ProducerRef 的字段为 kind、identity、version、source_ref。kind 取 caller_assertion / adapter_report / controller_observation / independent_verifier / unknown;version或source_ref不适用/不可得时明确null,不伪造已验证出处。PreparedEvaluation、ExecutionSpec、ExecutionRecord 和 EvidenceInput 必须保留评测模式的 operation 与 validation_scope,并与冻结 CampaignPlan 的阶段相符;同一候选可有多次attempt,但开发和最终验收证据不能互换。

    检查事实与预期要求的逐项对账

    PreparedEvaluation.required_evidence 在执行前声明 check_id、对象/阶段、checker版本、artifact schema、适用claim。ExecutionRecord.checks 记录实际 status、producer、subject、attempt、expected/observed 和 evidence refs。Benchmark 逐项检查其是否满足要求。执行后生成的检查列表不能反过来定义“本来就只需要这些”。caller_assertion、adapter_report、controller_observation、independent_verifier 是出处类别,不能被包装成同一 verified。

    事件与 Dashboard 的最小契约

    RunEvent 包含 schema_version、event_id、run_id/attempt_id、可选candidate_id/branch_generation、producer、sequence、occurred_at、recorded_at、event_type、payload/evidence_refs。相同producer+event_id去重;不假装全分布式总序。未知时间/事件缺口/断连显式保留。ProgressObservation 使用 completed、total可null、unit和stage;total未知时展示不定进度,0/未运行/N/A不同,100%仅代表工作量完成。

    KnowledgeDelivery 只表示 query/selection版本、实际知识ID/revision和交付快照;KnowledgeUse 单列采用/未采用/未知及证据,不通过“已检索”推断被使用。相关评测结果保留B assessment引用,不按条目分摊因果收益。具体持久索引范围由 #333 继续决定。

    生命周期与结果实例(示意)

    一个可信任务报告已证明当前候选正确性错误,随后子进程清理未确认:ExecutionRecord 保留 process_outcome=exited、cleanup=unknown、lifecycle=recovery_required;EvaluationResult.correctness=FAIL,performance=INCONCLUSIVE/invalid。这个例子只说明新schema语义,不改写旧 evaluator 的整体 INCONCLUSIVE 或历史结论。

    模块内接口与现有代码迁移

    2.1 建议组件与现有落点

    内部组件 具体责任 建议接口 现有代码 首期处理
    api.py 唯一稳定读写入口及导出类型 KnowledgeReader.read/collect/resource;KnowledgeStore.create/update/history 当前同名类 兼容导出,保持旧 import 转发
    bundle.py 逻辑资源名、字节、manifest、依赖闭包和 revision Bundle.manifest/revision/view knowledge_operations.Bundle、safe_path/_normalized 保留现有 hash 规则;不重算旧历史身份
    sources.py package / checkout / store 三种来源、身份碰撞、固定快照读取 内部 KnowledgeSource.identities/read;解析函数 resolve KnowledgeReader._knowledge/_checkout/_skill/owners/resolve、skill_catalog 可先一文件,来源变大时再拆文件;只抽真实复用协议
    selection.py 过滤、词法排序、显式 ID 顺序、context 字节预算与 omissions select(query, records) 纯函数;assemble_context 纯函数 _skill_selection、collect 中排名和上下文生成 现有默认检索语义不变;不用抽象基类包装每一个 helper
    store.py 只对 store-owned candidate 做原子写入、版本 CAS 和 history 保留 create、update(expected, reason, evidence) KnowledgeStore SQLite 事务 package/checkout 继续只读,不把更新扩展成 promotion
    research.py 研究来源、适用范围、能力画像的查询组合 保留现有查询函数 research_knowledge、model profiles、knowledge records 仍是知识方法/资料,不成为实验调度器

    catalog.repository_pack() 是例外:它返回运行目标描述,消费者为环境检查,应移到 W 的 target descriptors;repo_packs/*/knowledge 仍归 K。不要按目录整体移动 repo_packs。

    2.2 最小内部协议

    只有来源存在真实替换需求,值得使用 Protocol。下面为接口方向,先不要求所有方法变成新类:

    class KnowledgeSource(Protocol):
        authority: str  # package / checkout / store
    
        def identities(self) -> tuple[str, ...]: ...
    
        def read(self, identity: str, *, revision: str | None = None) -> Bundle: ...
    
    
    class KnowledgeWriter(Protocol):
        def create(self, bundle: Bundle) -> str: ...
    
        def update(
            self, bundle: Bundle, *, expected: str, reason: str, evidence: list[dict]
        ) -> str: ...

    KnowledgeReader 组合多个只读来源。KnowledgeStore 另外实现 writer,不让 package/checkout 提供会在运行中报“不支持”的假写接口。Store 已经有足够具体的接口,不需要额外泛型 CRUD 层。

    当前 Bundle 是 frozen dataclass,但字段包含 dict;它不等于深层不可变。目标实现应在边界复制/验证输入,revision 必须对应真正交付的字节。这里应保留 manifest 编码、逻辑资源路径和 hash 算法的兼容测试,避免为了加 immutable wrapper 而改变身份。

    3.1 内部组件和最少端口

    内部组件 责任 建议内部接口 复用来源
    execution.py 一次执行的生命周期:准入、绑定、启动、收集、清理、结算、提交 ExecutionService.execute(spec) -> ExecutionRecord harness.runner 中生命周期部分;不保留具体 AB/BA 规则
    inputs.py 捕获输入字节、运行代码身份和留存位置;校验执行前后身份 bind_inputs(request, workspace) -> BoundInputs;check_inputs(bound) infra.targets.repository_identity、任务/候选捕获
    executors.py 实际启动和监督一个进程树/任务入口 ProcessExecutor.run(command, context) -> ProcessOutcome infra.executors.local.execute_command、infra.processes
    resources.py 实际资源租约、所有权与释放确认 acquire(request, owner) -> Lease;release(lease) -> ReleaseRecord 现有资源上下文及 #249 后续资格;无能力的平台显式不支持
    budget.py 适用预算准入、预留、单次 claim、累计用量与证据 适配现有 reserve/claim_once/advance 与 AtomicStore tools.skill_eval_budget*;不要再建第二本账
    records.py 运行/尝试事实、产物引用、只读状态查询、完整提交 RunStore.begin/append/finalize/read infra.artifacts、runner 文件、campaign/optimization 记录
    agents.py 执行用的 Agent 客户端适配:argv、结果、provider usage 解析 有真实多个实现时提供 AgentInvocationAdapter CodexClient、Anthropic 请求适配、trace usage
    campaign.py 多次尝试和候选间依赖;执行声明好的搜索/调度策略 后续 CampaignCoordinator 经 W 自有 EvaluationPort 消费 B 的评估结果,复用上表执行服务 harness.improvement 中选择/推进部分;#249、#363 增量

    首期不用每行都创建新文件或 Protocol。生命周期、executor、record store 必须有真实实现;预算接入有付费消费者才抽取;资源/并发策略随着 #249/#363 被接受的切片接入。模块设计应写出这些责任,不能用空实现占位并宣布能力完成。

    4.1 组件与端口

    内部组件 责任 建议接口 现有落点
    api.py 任务发现、准备和离线判定 list_tasks / prepare / assess 新稳定面;旧入口保留适配
    tasks.py 内置/外部任务加载、包校验、版本与资源闭包 TaskCatalog.load(ref) -> TaskDefinition #338 TaskPackage / load_task / load_builtin_task;工程/诊断任务
    preparation.py 冻结规则、受控资料、输入规范和执行配方 TaskAdapter.prepare(request) -> PreparedEvaluation(无隐式写入) #338 manifest/hash/identity 逻辑
    workers/* 在受控进程内实施任务专属 check/measure/profile 协议 versioned task entrypoint numpy_task、npu_task、MoE grader、image/media 采样协议
    assessment.py 身份与证据完整性校验、任务范围判定 TaskAdapter.assess(prepared, evidence, *, artifacts) -> EvaluationResult evaluation、grade_artifact 判定部分、MoE _score/_adjudicate
    metrics.py 单位、方向、聚合、数值域、缺失/无效原因 纯函数、明确 MetricDefinition model.protocols.metrics、_summary、MoE 聚合
    adapters/* 外部测量包/任务/媒体质量/技能效果的语义适配 有具体消费者才增加 Flare adapt/validate_pair、image quality、SkillEval/Indexer 条件和 scorer

    任务 registry 首期静态注册即可。TaskAdapter 是需要变化的端口;不要将 load、parse、score、每个数学函数都再抽一层接口。

    class TaskAdapter(Protocol):
        kind: str
    
        def prepare(self, request: PrepareRequest) -> PreparedEvaluation: ...
    
        def assess(
            self, prepared: PreparedEvaluation, evidence: EvidenceInput,
            *, artifacts: ArtifactReader
        ) -> EvaluationResult: ...

    prepare 可以读取和验证已声明任务资产、计算 manifest/digest,但不运行候选、模型或加速器。assess 读取留存内容,核验并重新计算判分;不导入 executor,不创建新执行,也不隐式抓取外部资源。较大的 artifacts 通过 B 的只读 ArtifactReader.open(ref) 端口读取;由 apps 提供基于 W artifact store 的 adapter,必须按 digest 验证读取到的字节。

    4.4 当前混合代码的具体拆法

    当前实现 归入 B 的部分 归入 W / apps 的部分
    harness.runner.run_experiment AB/BA 次序和 repetition 作为外部比较 task 的测量协议 受控执行、输入快照、状态和产物属 W;旧入口到新三模块的装配由 apps/legacy adapter 保持
    harness.evaluation.evaluate 统计、required check 消费、质量/收益规则 移除对 W RunSpec 的实现依赖,转换为 B 的 ComparisonPolicy 输入;旧函数接口保留
    scenarios.external.execute_trial read_metric / validate_metric 的语义、任务报告解析 execute_command 和日志/产物留存属 W;旧组合函数兼容转发
    #338 TaskPackage manifest、load、task/grader identity、candidate format、command recipe runspec() 直接构造 W RunSpec 的桥接搬 apps;不让 B import W
    #338 grade_artifact 结果 identity/check/exitcode 一致性、正确性判定 其会执行 check 的旧行为必须保留为组合入口;新的 assess 才是纯离线
    #338 MoE task resources、_expected_calls、_score、task reports、候选错误判定 token-owned 清理、launch 监督、timeout、输入留存归 W;apps 组合 prepare/execute/assess
    skill_evaluation verifier、task_verdict、条件配对、质量/回归统计与证据检查 Codex argv/usage parsing/execution/capture 属 W;Knowledge export/read 到 apps 装配
    harness.improvement assessment、quality/regression 条件和 holdout 规则的计算 choose/推进/组合后重跑等声明好的搜索策略属 W;正式接受与知识写入仍是授权主体决策
    ImageProtocol / collect_samples 请求语义、seed/warmup/sample/timing;image gate 属 B 受测服务启动/停止和任务进程生命周期属 W;普通 HTTP 字节工具可以保持小型共用 utility
    Flare adapt、raw packet 验证、validate_pair、scope-specific metric 重算 W 仅提供产物引用/字节读取,CLI adapter 在 apps;保留文档化入口

    5. Dashboard / context capture 的具体归属

    目前 campaign_records.py 反向导入 dashboard_data 的文件和路径 helper;如果把 dashboard_data 整个放 apps,会让记录写入模块依赖展示层。建议先将路径/原始记录读取 helper 放入 W records 内,双方复用,再拆业务解释与展示。

    部分 落点 理由
    optimization_trace 的 caller assertions、campaign/candidate/run 关联、引用/hash 检查 W records 管运行叙事及它与事实的关联;不保证 agent 实际消费了 context
    knowledge_capture 的 collect 选择语义与 context 文本组装 K 的只读结果/纯格式化 是 K 输出语义,不应该在 K/W 两边维护两份不同 assemble_text
    capture 写入 campaign、留存输入 envelope 和 hash W records 记录实际交付内容;apps 调 K 后将返回结果交 W 保存,W 不自行检索
    optimization_story 的声明与留存证据对账 W read model 报告关系是否可核对,不产生任务 PASS
    质量 verdict、指标是否有效、可比较范围 B assessment/read adapter 解释判据;不能由 UI 根据 returncode/median 重新发明
    HTML、timeline、浏览器 live 展示 apps views 展示及轮询已存在事实,不执行任务

    现有 dashboard 的 outcome/noise/quality 是派生展示语义,应明确标为显示标签,并保留正式 evaluation.verdict。对于旧 archive 的兼容显示可保留现有规则,不将 outcome 当成新的正式判定。

    新提案的扩展位置

    6. #363 与 #364 对接口设计的增量要求

    #363 投机验证

    在 W 增加有界策略和候选依赖记录,复用 #249 的执行/预算/资源端口。不要建立第四模块或第二个 scheduler/ledger。

    • CandidateRecord:候选身份、parent、generation_dependencies、artifact refs、producer context、comparison baseline、quality reference。
    • ValidationRequest:development_quick / development_full / final_acceptance 的独立协议引用。阶段不是新的 verdict。
    • CampaignState:stable_head、verified_head、speculative_head、state_revision。只有 W controller 的条件更新可推进开发基线,当前 dashboard record_decision 的调用者声明不能冒充这个控制动作。
    • 迟到结果先校验 attempt、候选、父依赖及 generation,再允许推进;父失败时后继为 invalidated_dependency,不伪造其正确性 FAIL。
    • “一个父候选验证 + 一个投机后继”只是提案范围。首期 API 不必引入无限深 DAG。
    • B 冻结快速检查、完整开发验证与最终验收规则;K 的旧/新技能包保持版本与受控写入。holdout 不进入知识检索上下文、不反馈继续搜索。
    • 初始三模块 API 可以支持这些字段/关联,但实现 [RFC] RSI 投机验证:覆盖推理引擎优化与 Agent/Skill 自我改进 #363 的并发、恢复、真实试点必须按其后续被接受切片交付,不能以架构重构绕过范围和资源资格。

    #364 Diffusion 质量

    • MetricDefinition 应区分 metric role:gate / diagnostic,计量范围和适用 modality。不能把所有存在的指标都自动用于 PASS。
    • QualityPolicy 版本化,明确 comparison reference、precision/layout 条件、几何要求、样本集合与聚合。它归 B。
    • K 存放方法、失败示例、来源和适用限制;W 保存实际媒体、配置、调用与执行事实。
    • 当前 issue 提出的 sharpness、temporal difference、luma 是候选质量诊断/判据。是否足以验收,需要任务所有者冻结规则与反例验证;尤其不能从一个反例就把 Laplacian variance 宣称为感知质量的充分判据。
    • 保留旧 PSNR/SSIM/image gate 与历史结果原始版本。新视频质量规则应是新 policy/version,不全仓替换所有 deterministic image comparison,也不改写历史冻结证据。

    #363 的多起点方向仍待范围决定;本稿推荐首期保持单父+单后继,后续多分支另定身份、晋升冲突和失效传播。

    必须保留的验收反例

    必须保留的反例

    1. launcher 退出 0,子进程仍在运行,输出目录留着旧 attempt 的成功文件。Workbench 不得确认释放/完整结束;Benchmark 不得采用旧成功产物。
    2. 正确性明确 FAIL,随后发生 timeout 或 cleanup error。原 FAIL 不被全局 INCONCLUSIVE 抹掉,性能与清理另行呈现。
    3. prepare 指向 revision A,execute 装配时又解析 latest 得到 B。执行前报 identity mismatch,不能修改 prepared 让它看似一致。
    4. 取消了尚未执行的预留,现有保守预算仍占用容量,actual_cost 未知;租约已释放。三个字段必须能同时表达。
    5. 离线 assess 缺原始样本。必须报告缺证据,不能偷偷调用旧 grade 重跑。
    6. Knowledge 物理目录迁移后,包里的文件存在,但逻辑 prefix 依赖集合变化。安装成品读取/Bundle revision 测试应发现它;source-tree 测试通过不够。
    7. 对 [RFC] RSI 投机验证:覆盖推理引擎优化与 Agent/Skill 自我改进 #363,父候选失败后后继返回 PASS。保存该范围的原结论,但不得推进失效分支,不能删掉其实际开销。

    测试复用已有有效回归;上述每项新增测试对应具体迁移风险,不为 DTO 的每个字段建立无意义镜像测试。导入边界先扩展现有 AST 直接规则,再明确是否要求传递闭包;它们不能替代执行和结果语义测试。

    Agent开发交付卡

    共识之后怎样分配给 agent

    在 #362 记录每项 D01–D11 的 accepted/revise/deferred、确认者和决策链接。涉及 #303、#355、#363、#364 的新能力仍由各自 issue 记录范围。接口共识与具体 task 的资源/实验范围分别保留。

    每个开发 task 至少包含下面的交付卡:

    task: S2 / Workbench 单次执行
    decision_refs: [已接受的 D01, D03, D04, D05, D09 链接]
    base_sha: 实施时重新固定的 main SHA
    owner_module: inferrsi.workbench
    public_contracts: [W-EXECUTE, W-READ]
    inputs_outputs: 对应 schema 版本、字段、单位、缺失语义
    allowed_changes: 执行服务、输入绑定、记录、适配器和必要回归
    compatibility: 既有 CLI / import / budget ledger / 历史记录语义
    acceptance: CPU 子进程、timeout、取消、子进程清理、同请求不双启动
    evidence: 实际执行输出与未覆盖平台说明
    exclusions: [新调度服务, GPU收益实验, 新退款规则]

    S2、S3、S4 可在 S1 契约固定后并行;S5 在三个模块的首批契约可用后做组合验收。迁移 task 不擅自重开已关闭目标,不把其他在途 PR 统一附加全部新门禁。接口字段的存在、mock的成功、代码合并、宿主实测、任务收益和项目验收分别报告。

    最先应写的端到端用例:安装包外知识读取;真实 CPU 命令的取消与清理;保留单算子/MoE证据的纯离线判定。生成流程首期可用受控provider fixture验证装配。真实Agent新增接入在后续#337切片完成;每实际迁移一个已有宿主/SSH路径,分别补真实路径验收,未迁移者沿用原适配器,不用mock代替资格。

    #365 按 D11 单独冻结 parser 依赖、覆盖优先级和 DSH v1 迁移范围;当前主仓映射更新为365项,使用15:17:08上海时间的增量快照。

    共享YAML任务输入与协议版本反例

    #365:CLI 与 Agent 共享任务输入的接口

    建议将任务文档入口放在 inferrsi.apps.task_input,随普通 InferRSI 安装交付。它属于应用入口,负责把用户意图转换成三个模块已经定义的请求。任务语义、执行事实与知识内容仍分别由 B、W、K 拥有。#365

    明确的公开面

    load_task_document(source: TaskDocumentSource) -> TaskDocument
    normalize_task(document, *, explicit_overrides, path_context) -> NormalizedTask
    validate_task(task, *, operation: str) -> TaskValidation
    preview_task(task, validation) -> TaskPreview
    类型 必需字段与行为
    TaskDocumentSource 本地文件或调用方提供的文本、origin、source format;不隐式抓取 URL,不运行文件内容
    TaskDocument schema family/version、原始字节摘要、三段原始字段及位置;语法错误含路径/行列信息
    PathContext 文档所在本地目录、调用入口、显式本地/远端路径角色;不得用某个宿主 cwd 暗中替代文件目录
    ExplicitOverrides 仅包含用户实际提供的 flags;保留字段来源。argparse 默认 Namespace 不可整体充当该对象
    NormalizedTask optimization / environment / acceptance 的类型化字段、effective values、每字段 origin、规范化版本和摘要;凭据只保存现有渠道的引用,不保存 secret 值
    TaskValidation operation、issues: tuple[FieldIssue,...]、execution_ready;结构错误与缺失执行字段分别说明
    FieldIssue field_path、code、message、source_location、required_for;错误提示不回显凭据
    TaskPreview 生效字段及来源、解析后的路径/目标、仍缺的字段、拟使用的任务/政策引用;不包含“已准入”的结论

    推荐语义,供 D11 确认

    1. 优先级:显式 CLI > YAML > 内置默认。 未提供的 flag 不覆盖 YAML。先合并,再补允许默认值,再统一校验。已接受协议中的锁定字段不属于可覆盖默认值;冲突必须显示并拒绝按旧协议执行,不能靠 CLI flag 改写门槛。
    2. 路径:本地相对路径相对于文档所在目录。 内存文本输入必须提供 base directory;本地缺失该上下文则报错。远端路径保留目标端语义,直到 W 对目标进行绑定,不能在本机 resolve 成另一条绝对路径。
    3. 部分文件可以预览。 未知字段、重复键、错误类型、未知 schema version 始终拒绝。缺少某 operation 的必需字段时,preview 返回字段级缺项且 execution_ready=false;plan/run 按各自已有完整性与执行边界拒绝。preview 不建立工作目录、不写账本、不申请资源、不导入候选代码、不启动后台操作。
    4. 版本化的是语义与符合性 fixture。 建议核心族名为 inferrsi.task,首个主版本为 1;已有 DSH prototype 的无族名三段 v1 不能被静默当作兼容。按明确迁移适配器转换,或纳入本期并验证同一 fixture。
    5. 推荐依赖决定:task: support shared YAML task input for the InferRSI CLI and agents #365 接受时,将成熟 YAML parser 作为显式核心安装依赖。 这是对当前核心零必需依赖事实的有意变更,需在该 task 确认并验证普通 wheel。不要手写不完整 YAML parser,也不在 preview 时临时安装。底层 K/W/B 的 import 与无关操作仍不因 YAML 解析器缺失而启动其他功能。三模块初始迁移本身不提前引入这项依赖。
    6. 限定配置语言。 使用安全数据加载,拒绝自定义 tag、多文档、alias/merge、重复键及 schema 外字段;不允许执行型表达式、任意环境变量插值或从配置指定任意 Python 导入。配置只表达任务字段,完整任务脚本由已有明确执行路径处理。
    7. 建议首期 core CLI + Agent,同期记录 DSH 后续迁移责任。 如决定把 DSH 纳入首期,必须将其独立解释器接到统一规范化语义;语言可以不同,但不得维护另一套默认值。当前 Draft feat(dsh): add structured iteration form and SSH execution #361 不构成 task: support shared YAML task input for the InferRSI CLI and agents #365 已交付。

    本接口产生任务输入,不产生执行授权。文档 hash、NormalizedTask hash、PreparedRef、实际 InputBinding 分别保存;同一文件不等于同一运行环境。用户显式执行后,仍使用现有 acceptance、冻结 gate、预算和证据规则。默认 flag 与依赖评审 · DSH 兼容评审 · triage 回复

    #353 提供的协议版本反例

    当前 #353 正文的 B1/B2 规则写两次独立服务启动,但最新评论报告同一服务连续 R1/R2,轮间不重启;正文的暂停描述与最新活动报告也不一致。这次设计不重新裁决作者的实验结论。它说明必须保存生效 protocol_ref、接受依据和实际 service instance / attempt / 阶段拓扑,而不能只引用一个可编辑的 issue URL。B 对照固定规则与执行事实,Apps 不静默替换解释;原作者报告保留来源和适用范围。报告一 · 最新报告

    按开发切片分配的验收矩阵

    5. 最小验收矩阵

    这些是针对确定迁移风险的用例,优先复用现有测试。没有必要为每个 DTO 字段写镜像测试。

    ID 所属切片/责任 输入或操作 必须看到的结果 能说明什么/不能说明什么
    A01 S1/契约 B→apps→W→apps→B 的一个完整 golden fixture operation、scope、target、candidate、attempt、来源、单位、未知值完整保留 证明转换无关键语义丢失;不证明真实执行
    A02 S1/契约 prepared 引用正确但文档 hash/schema/id 任一不符 启动前明确拒绝,不能修正文档掩盖差异 证明冻结身份约束
    A03 S2/W 一个真实 CPU 命令写入仅本 attempt 的产物 actual bindings、退出、清理、完整提交与文件字节一致 CPU local path 有效;不外推 NPU/SSH
    A04 S2/W 同 request/spec 并发提交两次 只启动一次;第二调用进行中抛AttemptInProgress;finished返回原记录 本地准入去重;不声称分布式 exactly-once
    A05 S2/W 同 request_id 改 candidate、target、deadline 或规则摘要 冲突且不启动 请求摘要覆盖影响执行的输入
    A06 S2/W prepare 后改候选源;执行前捕获与 expected hash 不同 not_started + identity mismatch,旧成功文件不被采纳 实际输入约束
    A07 S2/W launcher 退出后仍有子进程;随后 timeout/cancel 记录取消意图、终止与确认清理;未确认资源不重分配 控制域内子进程生命周期
    A08 S2/W 准入前不可持久化;以及启动后 final commit 失败 前者零启动;后者抛ExecutionPersistenceError并携带attempt/partial;不自动重启 持久化失败语义
    A09 S2/W 第一步非零退出或必需产物缺失的多步请求 后续步骤 not_started,完整记录停止原因 首期固定 stop-on-failure
    A10 S3/B 新进程只读取 frozen prepared、record 和 retained artifacts 得到同语义结果,不启动设备/模型/候选,不读取 mutable latest 真正离线、跨进程恢复
    A11 S3/B exit 0 但缺 rank/原始样本,或产物属于另一个 attempt 相关 claim INCONCLUSIVE/metric invalid,不能补 PASS 不把进程成功等同任务成功
    A12 S3/B 身份成立的正确性 FAIL 后 cleanup unknown correctness FAIL 保留,性能与清理分别表示 范围化结果;旧历史保持原语义
    A13 S4/K 干净安装、包外 cwd、旧 revision、非 ASCII 内容、逻辑依赖资源 原 revision/字节预算/资源闭包保持一致 K 包迁移兼容,不只是源码树能读
    A14 S4/K stale expected revision 或修改非 store authority 现有冲突/权限错误,状态不自动晋升 CAS 与写入边界
    A15 S5/装配 受控 CPU fixture generation → capture → evaluate → offline assess generation/evaluation 不同 attempt,共同预算 scope/deadline,候选输入闭环 三模块组合与 provider 契约;不代表真实 Agent
    A16 S5/装配 改 adapter 实例或重建进程后 assess 一条旧记录 仍按记录中的 prepared_ref/scope 解析 不依赖“最近一次调用”的内存
    A17 S5/循环 generation 失败、输出清单缺失或 deadline 已到 不开始 evaluation,不自动重试;保留实际消耗 有界推进与失败责任
    A18 S5/反馈 让 final assessment 含有只能验收时见到的信息 下一轮 provider 的 context 中不存在该信息;计划不继续搜索它 冻结反馈可见性;不等于绝对防泄漏证明

    对于真实 Agent、每一种新宿主、SSH、GPU/NPU、跨主机 rank 控制,另列真实路径验收。上述 CPU fixture 的通过不能替代它们。新资源政策、收费对照、投机并发、质量阈值的接受,仍按各自 issue 的具体范围进行。

  8. Dong1017 commented on Nov 6, 2026

    @Dong1017
    CollaboratorAuthor

    @amy-why-3459 @zengchuang-hw 麻烦 review 一下这版 接口细化与讨论收口稿 v0.3。完整契约已放在该评论的折叠区,可以直接在 issue 内阅读。

    希望这轮明确 A–D 四项哪些可以确认、哪些需要修改,据此冻结架构方向并拆实施任务:

    • amy:请重点看 A/B/C——三模块职责是否清楚;“Benchmark 拥有完整测量协议与任务 worker,Workbench 拥有优化循环和受控执行”是否合理;固定 prepared / record / assessment 引用、执行失败语义、两阶段候选生成接口是否有交接缺口。另请明确回应 C:是否同意将知识导入状态、存储 state、研究成熟度和主题覆盖分别表达,修正此前统一 status 的建议。
    • zengchuang:请重点看 A/D——Apps 独立组织为应用入口与装配层,首期仍在同一个 inferrsi 发行物中,这个定位是否合适;CLI/import、插件 ID/清单、打包资源、会话及真实宿主/SSH 兼容的验收范围是否有遗漏。task: support shared YAML task input for the InferRSI CLI and agents #365 的核心 YAML/PyYAML 依赖变更与 DSH 接入按原 issue 单独推进,是否有需要提前约束三模块迁移的地方。

    请尽量按 “决定编号 → 同意 / 需修改 / 尚缺信息 → 具体原因、替代方案或反例” 回复,并区分 启动 S1 契约切片前必须解决的问题 与 可以交给后续实施切片的细节。也请直接指出是否还存在阻止大结构冻结的分歧。

  9. zengchuang-hw commented on Nov 6, 2026

    @zengchuang-hw
    Contributor

    回复 v0.3 复检请求。我这轮重点看 A/D,按当前 main 1246348f、#365 的待分诊条款和 #361 的 f4049814 做静态核对。

    S1 开始前要定下的边界

    • A(D01/D02/D07)· 同意。 inferrsi.apps 可以独立组织,首期继续由一个 inferrsi 发行物交付。Apps 负责 CLI、宿主入口、配置和公开接口之间的转换。测量协议由 Benchmark 持有,执行生命周期由 Workbench 持有,知识与资源身份由 Knowledge 持有。S1 开始前应把兼容责任写入交付卡,列明旧 CLI/import、参数与返回语义、资源 ID/逻辑路径及版本、插件 ID/清单与会话入口分别由谁保留,并用现有入口做代表性用例。 v0.3 模块边界 · 现有发行与入口

    • D(D08/D09)· 需补一条产物验收规则。 A13 覆盖普通安装中的知识读取,后续移动资源或迁移入口时,应在对应切片核验实际发行物。改动共用 launcher、打包器或 CLI 时,也把使用该路径的宿主纳入验证。当前 wheel 的 package-data 与插件构建器的资源筛选各自维护,现有 Codex 完整性测试聚焦 inferrsi/data/。例如把任务输入或 schema 移到新子包,源码测试可通过,而某个宿主包会漏掉资源。建议 S1 先约定按消费者核对必需资源清单、摘要和明确的宿主差异,由发生迁移的切片负责验证。公开包只包含获准分发的任务资源。 Wheel 资源声明 · 插件筛选 · 现有完整性测试

    • D(D09)· 明确共享 CLI 新功能的宿主边界。 feat(dsh): add structured iteration form and SSH execution #361 允许远端调用 plan/run,SSH bootstrap 在调用 CLI 前检查 argparse 顶层路径和脚本字段。以后随远端包带入 --task 时,YAML 内的仓库和命令可能在这层检查之后才解析。建议 S1 约定远端只开放已验证的输入形式。task: support shared YAML task input for the InferRSI CLI and agents #365/[RFC] Agent plugins: a consistent InferRSI workflow in Codex, DSH and openJiuwen #152 接入时,可先在远端明确拒绝 --task,或在远端解析后对生效路径、脚本和执行限制做同等检查,再开放并补越界拒绝用例。这个约束适用于将来的组合路径。 SSH 参数和路径检查 · 远端命令范围

    交给实施切片的验证

    A/D 视角没有阻止大结构冻结的分歧。S1 前应定下兼容承诺和验证归属,具体打包实现、宿主实测和 YAML 依赖由相应切片完成。本轮未执行安装、升级或 SSH 实测。另一个状态更新可随修订带上:#361 当前为 Ready,f4049814 已有两份正式批准。 Amy 批准 · Dong 批准

  10. david6666666 commented on Nov 6, 2026

    @david6666666
    Collaborator

    回复 v0.3(按决定编号)。对照 main 1246348f,与 v0.3 同一基线。

    我此前整理的观察多数已被 v0.3 吸收:测量协议归 B、生成与检查分成两次 attempt、required_evidence 在执行前冻结、检查按 producer kind 区分出处、持久信封带 schema_version、预算三类对象、dashboard helper 先下沉到 W records。以下只列增量。结论:不存在阻止冻结大结构的分歧;A-1、A-2、A-4、B-1 可直接写进 S1 的交付物,不需要在启动 S1 前另行解决。

    A(D01/D02/D07):同意,补四项

    1. tools/ 需要在 S1 的「包边界及字段 owner」里定位(S1)。 它被 MANIFEST.in 排除在 wheel 之外,却承载预算账本和 SkillEval 控制器:skill_eval_compare.py 1,138 行、自行写 verdict,skill_eval_pr.py 由 CI 以 python -m tools.skill_eval_pr 调用;现有边界测试只扫 src/inferrsi 下三个平面。建议 S1 写明它算 Apps(受「不产生另一套循环、预算规则或 grader」约束),还是 repo ops(不进发行物,但纳入同一方向规则),并写清 tools.skill_eval_budget* 迁入 W 后 wheel 内容如何变化。这与安装评审第 2 点的资源对等核对相关。
    2. agent 入口契约要同步改(S1)。 AGENTS.md 的 one plane per campaign step、contributing 的 Harness/Model/Infra 平面、architecture.md 的扩展验收规则(新适配器必须复用 AB/BA 循环、进程清理和性能裁决)仍按旧坐标轴写;最后一条与 v0.3「AB/BA 归 B、MoE 不再外套」直接冲突。交付卡由 agent 执行,而 agent 先读 AGENTS.md,建议 S1 一并改写。可以顺带写进 D01:拆出 Benchmark 后,明确 campaign 步骤不得修改评判它的 Benchmark;现行平面规则并不阻止 harness 步骤修改 harness/evaluation.py。
    3. §4.4 拆分表缺 skill_eval_engineering.verify(S2/S3)。 它是包内代码(不含 data/)中 infra 之外唯一自行起进程的地方(bwrap 沙箱,rlimit,无宿主回退)。建议评分语义归 B,沙箱隔离作为 W 的 required_capabilities,不支持时启动前拒绝,与 v0.3 的 not_started 规则一致。另:dashboard helper 下沉到 W records 时把 STAGES 一起带上,它目前在 dashboard_data 与 optimization_log 各定义一份,campaign_trace 也从 dashboard 取。作为 Add offline and live optimization workflow dashboard #319 的提交者,我同意 v0.3 §5 对这一簇的落点。
    4. 导入边界不需要传递闭包(S1)。 v0.3 在「必须保留的反例」末尾留了「是否要求传递闭包」。只要「模块 → 组」映射是全的(含根模块、兼容转发层和 tools/),组间允许关系构成 DAG,逐条检查直接边就能保证传递合规。缺的是覆盖面,外加包内唯一一处动态加载 runpy.run_path(加载 request_guard),列入白名单即可。runner → evaluation、inspection → catalog、skill_evaluation → knowledge_operations 三条已知越界边先进带 issue 链接、只减不增的白名单。

    B(D03/D04/D05):同意,补两项

    1. inferrsi-json-v1 只能有一个实现(S1)。 main 上现有三个编码器都不满足 v1:infra.artifacts.digest 与 anthropic_agent.canonical 对同一个含中文的值算出不同摘要(后者转义非 ASCII),knowledge_operations._json 接受 NaN,三者都不拒绝浮点。S1 应新增一个叶子实现加 §8 要求的 fixture,不复用其中任何一个。这正是 v0.3「确有共同消费者时抽取」的情形:B 产出 protocol_digest 与 assessment 编码,W 产出 request_digest 与记录摘要,Apps 保存时生成 ArtifactRef。
    2. 验收矩阵可以从现有回归改写(S2–S4):源码身份变化(A06)可从 test_runtime 的 source changed 改写,A08 对应 termination_failed,A11 对应 test_trial_checks,A13/A14 对应 test_bundle_manifest 与 test_knowledge_store,反例 4 对应 test_skill_eval_budget。

    C(D06):同意分维度表达,补两点(K owner / S4)

    1. 上游变化按锚点判断,不按「钉住的 commit ≠ 上游 HEAD」,后者几乎总是成立;check_vllm_ascend_source_anchors.py 是现成的离线原型。
    2. package Bundle 的 revision 变化不能当复核信号:95 条记录共用一个 skill_library 依赖摘要,任何 skill 编辑都会让它们一起换 revision。由此 CampaignPlan 钉住的知识 revision 在升级后按 package 读取会失败(「Historical revisions require the matching installed snapshot」),除非存入 store;离线复核依赖 W 留存的交付快照,建议在 A13 写明。

    D(D08/D09):同意,补一处兼容细节(S5)

    旧 run 的退出码 2 同时表示 INCONCLUSIVE 和参数/前置检查错误。wrapper 可以保留,但新 Apps 入口不要继承这个映射,否则 §7.2 表格里分开的 not_started 与 INCONCLUSIVE 会在进程边界上重新合并。

    D10

    #357 明确说 anthropic_edit_agent.py 作为通用适配器有意保留,留待维护者另行决定;它在包内与 tools/ 中已没有其他调用方,EDIT_KIND 拒绝分支和 model README 的 edit 一节也还在。建议在 D10 记录里给出去留,或单开 issue。


    核查范围:main 1246348f 的静态源码、文档与调用关系,编码差异用本地脚本核对;未运行测试、CI 或实验。本评论不授权迁移、实验或合并。由 coding agent 协助整理。

  11. Dong1017 commented on Nov 6, 2026

    @Dong1017
    CollaboratorAuthor

    v0.4 方案收敛:固定三模块职责,将实施细节落到 S1–S5

    根据 v0.3 接口稿、zengchuang 的 A/D 评审 与 David 的 A–D 评审,本轮采用下列方案。当前没有收到阻止大结构冻结的具体反例,建议维护者接受 A–D,并据此启动 S1。 Amy 尚未对 v0.3 回复,不记录为默认同意;评审支持与维护者最终接受也分别记录。

    以下条款覆盖 v0.3 对应部分,其余接口定义保留。本轮是设计收敛,不表示源码已迁移或验收已完成。

    一、收敛为四项决定

    决定 v0.4 采用的设计 评审状态
    A · 模块职责 Knowledge 负责知识内容、选择、版本与受控写入;Workbench 负责优化循环、候选调度、预算及受控执行;Benchmark 负责任务定义、完整测量协议、任务 worker 和判定;Apps 负责入口、配置、DTO 转换、显式归档和展示。 zengchuang 与 David 支持;兼容及归属增量已吸收。
    B · 交接契约 保留固定 PreparedRef / RecordRef / AssessmentRef、W 分配的 attempt、实际输入绑定、不可变记录修订;执行事实与评测结论分开,预算容量/实际用量/资源租约分开;Agent 生成采用 plan → W.execute → collect。 David 支持;S1 补单一编码实现、字段/错误/fixture 定稿。
    C · Knowledge 状态 导入状态、存储 state、研究成熟度、主题覆盖和实证资格分维度表达;沿用既有 hash/CAS。相关来源变化或有候选集记录的不命中触发复核,不自动改知识状态。 David 支持;历史 pin、来源锚点与复核证据的规则见下。
    D · 首期交付 独立知识读取、真实 CPU 单次执行生命周期、留存证据离线判定、Apps 装配,以及受影响入口的兼容。新增 Agent 能力、并发、投机和新质量指标按原 issue 推进。 两位评审均给出可落实的修订;按切片验证产物与宿主。

    Apps 是独立组织的应用入口与装配层,可以有独立目录、Python 包和维护责任;首期四者由同一 inferrsi 发行物交付。 三个核心模块互不导入,包括彼此的 DTO;Apps 在边界转换并装配消费方定义的端口。优化循环、知识选择和评分规则各有唯一负责模块。维持 9 组公开接口、19 组内部职责,不因这轮评审再增加抽象层。

    二、将评审增量落为明确选择

    1. tools/ 按职责拆分,S1 建完整归属表。 CI、发布和仓库管理入口属于 repo ops,可留在发行物外;可发布的应用入口属于 Apps;预算政策/账本/执行核心属于 W;任务协议/结果解释/判分属于 B。不能将整个目录归 Apps,也不能因为它在 wheel 外就豁免依赖规则。tools.* 可保留必要的薄兼容包装。S1 列迁移目标、旧调用方及 wheel/ZIP 影响,S2/S3/S5 再迁移对应实现。

    2. 同步修改 agent 入口规则,保留两个坐标轴。 change_plane 表示候选修改哪个 Harness/Model/Infra 平面;owner_module 表示能力属于 K/W/B/Apps,不能机械替换。S1 同步 AGENTS.md、contributing 和 architecture:保留一次迭代围绕一个假设、一个声明平面的意图,并明确 候选不得修改评价本次候选的冻结 Benchmark、worker、grader、参考输入或协议。Benchmark 自身维护可另立有版本的任务。AB/BA 属于具体任务的 B 协议,W 执行该协议;不再强制给 MoE 等任务外套通用 AB/BA。

    3. 补齐包内执行与记录归属。 skill_eval_engineering.verify 的测试向量与评分语义归 B,沙箱、rlimit 与进程控制归 W,并声明 required_capabilities。已知隔离能力不足且候选尚未启动时,持久记录 not_started,不回退宿主执行;若已有部分执行,保留事实,不能倒改为未启动。preflight 探针及消耗也留存。STAGES 统一由 W-RECORD 定义,dashboard/campaign 读取它;保留原有活动阶段语义,不与 attempt 执行状态混并。

    4. 采用一个新的 inferrsi-json-v1 叶子实现。 B/W 拥有各自语义投影,Apps 用相同编码保存字节并计算产物摘要;该实现不导入业务模块。现有三个编码器均不能直接当作 v1。S1 固定 Unicode、拒绝浮点、十进制负零规范化、拒绝重复键和无尾随换行等 golden fixture。不顺带改变 Knowledge、旧 agent 或历史产物的现有摘要规则。

    5. Knowledge 复核看相关来源与适用条件;历史复现靠真实留存。 不将“pin 不等于上游 HEAD”或共享资源引发的 package revision 变化直接当作失效依据。现有 source-anchor 工具可复用为离线校验原型,后续复核仍需核对相关定义、片段与适用条件。升级后旧 package pin 可能明确不可读;A13 必须验证原安装快照,或 W 留存的实际知识交付内容及所需资源快照能支撑离线复核。若走 store,使用其自己的 authority/pin,不静默把 package 引用改成 store 引用;未留存的资源仍算缺失证据。

    6. 导入边界检查完整覆盖,同时约束允许关系图。 根模块、兼容转发、tools/ 均需归组,直接依赖边逐条检查;固定动态加载列明调用点、目标及用途。这里修正一个论证:DAG 只保证无环,并不保证核心隔离,例如 W → bridge → B 仍是无环图。因此允许关系图本身还必须不存在经 bridge/legacy/shared 到另一个核心的路径。现有越界边登记精确例外、issue、owner 和退出条件,只减不增;有例外时不宣称目标隔离已经达成。不引入通用全仓传递闭包框架。

    7. CLI 保留兼容,同时给新入口明确结果语义。 旧 run 保留原退出码映射;新 Apps 入口用版本化结果信封分别表达请求/准入结果、执行状态、固定记录引用和评测结论,不继续把参数错误、未启动、INCONCLUSIVE 全压成同一个 2。具体数值表及优先级由 S1 固定,S5 实现。not_started 与 INCONCLUSIVE 可以同时成立;退出码只概括主要操作结果,完整事实以信封为准。

    三、S1 固定兼容责任;迁移切片验证实际行为

    兼容项目 设计责任 验证归属
    旧 CLI、参数/返回、入口组合与宿主适配 Apps;语义所属模块提供 fixture 修改入口或共用 CLI 的切片
    公开 Python import、DTO/错误语义 对应接口所属模块;Apps 维护装配与兼容转发 修改公开面的切片
    知识逻辑 ID/路径、pins、revision/hash、读取/受控写入 Knowledge 知识资源或 reader/store 迁移切片
    任务输入/参考/worker/grader、协议与指标含义、历史判定读取 Benchmark;W 保留执行出处和原始事实 任务资源或评测接口迁移切片
    运行记录、attempt、预算与取消/清理 Workbench;Apps 保留宿主会话边界 执行与宿主集成切片
    wheel/插件 ZIP 必需资源、摘要、依赖;插件 ID/清单/launcher 发布维护与 Apps;资源所属模块提供清单 打包、资源移动或共用 launcher 修改的切片

    按实际受影响的消费者验收。 直接迁移宿主,或改动它使用的共用 CLI、launcher、打包器,都必须把该宿主纳入验证;不能因宿主目录未改便排除。S1 固定各产物的必需资源、摘要、允许的宿主差异及获准分发范围,迁移切片再核验实际 wheel / 插件 ZIP。安装、选择、升级、只读入口、session/取消/清理证据要关联产物版本与宿主环境。S1 不要求提前做完全部宿主实测。

    18 项验收矩阵维持不变并补足上述含义;优先沿用 runtime、trial checks、bundle/store、budget 等已有回归中的行为用例,避免另写一套只重复字段定义的测试。

    四、YAML 契约修正,仍由 #365 / #152 独立推进

    1. 修正 v0.3“先合并再统一校验”。 先检查原 YAML 结构和已提供值,再应用允许的显式覆盖、补可选默认值,最后校验生效任务与冻结门槛。原文非法值即使被 flag 覆盖也拒绝;合法但不完整的草稿可只读 preview,并列缺项。
    2. 按字段来源解析路径。 YAML 本地相对路径基于文档目录;显式 CLI 覆盖路径基于调用方 cwd;保留字段 origin。远端路径保留目标端语义。任务文件模式的验收字段来自 YAML,冲突验收 flag 拒绝。
    3. 沿用四个入口。 load_task_document 安全解析及原文检查;normalize_task 应用允许的覆盖/默认值并按 origin 解析路径;validate_task 校验生效任务与操作完整性;preview_task 只展示结果与缺项。冻结门槛和执行准入继续强制。
    4. 未来远端 --task 默认拒绝,验证后开放。 task: support shared YAML task input for the InferRSI CLI and agents #365/[RFC] Agent plugins: a consistent InferRSI workflow in Codex, DSH and openJiuwen #152 接入时,对解析后的生效路径、脚本与执行限制完成同等检查及越界拒绝用例,再开放该组合。这是未来组合路径的约束,不宣称当前已证实漏洞。
    5. 依赖按产物交付。 PyYAML 核心依赖由 task: support shared YAML task input for the InferRSI CLI and agents #365 确认;wheel 声明不能代替宿主 ZIP 的依赖交付。各产物开放 YAML 前需说明依赖来源,并验证既有知识/查询入口仍可启动。DSH 通过共享 fixture 后再声明核心 v1 兼容。
    6. schema_family 暂不列为 core v1 必需字段。 按 #365 当前 schema_version 提案推进,族名有实际需要再由该 issue 决定。

    这些任务可沿现有入口独立推进;消费新模块组合时再声明实际依赖,不统一等待 S1 或 S5。沿现有入口推进的任务在原 issue 列自己的消费者、资源和依赖清单,遵守同等验收规则。

    五、开发顺序与本轮收口范围

    三模块迁移:S1 契约与兼容基线 → S2 Workbench / S3 Benchmark / S4 Knowledge 并行 → S5 Apps 装配。

    S1 的实际交付物是:完整模块归属/依赖表、公开 DTO 与错误/编码 fixture、agent 开发规则、兼容责任表、发行物/消费者资源清单、分阶段验收矩阵。上述细节属于 S1 的工作,不要求在启动 S1 前再开一轮把所有字段和实现先做完。

    • 建议现在确认: 维护者将 A–D 标记为接受,按上述范围拆 S1;后续 reviewer 如有异议,请给出具体调用路径、缺失字段、失败/恢复反例或兼容破坏,针对对应条款修订。
    • Amy 的复核: 仍欢迎补充,尤其 B 的交接/恢复与 C 的分维度状态;尚未回复仅记为未回复,不阻止我们形成明确推荐。
    • D10: 新主架构不纳入 KV 专项 edit/check 流程;已合并的 #357 中有意保留的通用 anthropic_edit_agent 暂留兼容,不发展成新模块/接口。另列清理任务核实公开消费者后,一并决定适配器、EDIT_KIND 分支与 README;不能仅凭仓内无调用就宣布死代码删除。
    • 独立内容选择: [RFC] Per-task SOL modeling and a KDA-flow gap metric for fused operators #303 的 Knowledge 内容组织等仍在原 issue 决定,不因 owner 明确便自动关闭。

    365 项全量映射继续保留 2026-11-06 15:17:08(UTC+8) 的独立清单快照;本轮更新设计与接口说明,不改写历史 issue/PR 状态。本条和更新后的 HTML/JSON/XLSX 是后续拆解的收敛依据,源码迁移、实验和验收由后续实施任务交付。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:knowledgeKnowledge line: packs, skill library, knowledge admissionarea:workbenchCLI workbench: profile, A/B loop, quality gates, evidence reportskind:rfcProposal / design discussion; scope review before buildstatus:proposedWaiting for the decision named in the status block

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions