518 lines
52 KiB
Markdown
518 lines
52 KiB
Markdown
# 正文智能体正式优化设计与计划
|
||
|
||
> 状态:评审修订版;Gate A 尚未 real-run
|
||
> 日期:2026-07-20
|
||
> 定位:本文是实验台“正文智能体正式优化”的任务 SoT;稳定概念仍以父仓 `design-docs/` 为准。Gate B 通过后才回填架构-04、专题-01/03/04/05/06/07、相关 API 契约、schema 和索引,本文完成蒸馏后删除。
|
||
> 历史:`2026-07-16-批9c-收官与优化方案.md` 的 run1-run3 只作实验记录。
|
||
> 可视化:[正文智能体架构图](2026-07-20-正文智能体正式优化架构.html)
|
||
|
||
## 1. 意图与双流程
|
||
|
||
核心原则:**卡是索引,根据卡去读原文。** 卡负责定位实体、状态、规则和历史章节;原文负责人物声音、动作习惯、能力表现和叙事质感。卡不能替代原文,原文也不能替代正式设定与状态。
|
||
|
||
这里必须区分两个顺序:
|
||
|
||
- **能力验证顺序**:正文智能体 -> 细纲智能体 -> 大纲+设定智能体,自底向上隔离变量。
|
||
- **正式创作数据流**:大纲+设定 -> 细纲 -> 正文,自顶向下提供输入。
|
||
|
||
本任务只优化正文层。细纲与大纲+设定的真实能力验收,必须等正文层通过跨作品多样本门禁后再启动。
|
||
|
||
## 2. 目标与边界
|
||
|
||
### 2.1 目标
|
||
|
||
1. 卡检索必须带出历史来源指针,并触发原文回读。
|
||
2. 已有事实、人物声音和叙事质感分别有可追溯证据,不再靠 writer 自由猜测。
|
||
3. writer 保留真实创作空间,但不得改变细纲硬事件、结果方向和伏笔动作。
|
||
4. 生产链在交付候选前挡住可机械验证的硬错误;文学质量由独立 judge 评估,不由 detector 凭观感阻断。
|
||
5. Gate B 通过后,生成候选才进入“接受/修改后合并/丢弃”三决策,采纳后成为 Canonical 正文并触发章后抽取。
|
||
6. 多章节、多作品、多场景验证,报告假阴、假阳和无卡实体影响。
|
||
|
||
### 2.2 可信边界
|
||
|
||
- writer、semantic detector、blind judge 都由可信编排器启动为独立模型进程;模型进程只接收各自严格合同,不直接读文件、数据库或共享运行目录。
|
||
- 检索节点是唯一取数入口,负责授权、冻结、排序、预算、哈希和来源回显。
|
||
- 回放时卡与原文都只能使用 `chapter <= as_of` 的事实;目标章、未来章和标准答案不得进入 writer 进程。
|
||
- 卡的终态摘要、未来弧线和无法证明章号的字段不进入回放 `stateAsOf`。
|
||
- 长原文片段和候选正文只存在于本次受控临时数据区,不进入 git、长期报告、知识卡、日志或评测安全摘要。
|
||
|
||
### 2.3 不做
|
||
|
||
- 不由正文智能体生成或修改大纲、细纲、设定和知识卡。
|
||
- 不把双盲 judge 设为每次续写的固定在线成本;它属于离线评测或可选质量详情。
|
||
- 不在正文层自动补齐关键新角色卡;只输出设定层缺口。
|
||
- 不允许诊断实验 A/B 臂的候选进入 Canonical 接受链路。
|
||
|
||
## 3. 两条独立链路
|
||
|
||
### 3.1 产品化生产链(Gate B 后第二阶段)
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
F[已确认细纲] --> RP[检索规划]
|
||
RP --> CI[卡索引与 stateAsOf]
|
||
CI --> PR[按来源指针回读原文]
|
||
PR --> EG[证据包与覆盖门]
|
||
EG --> W[无工具 writer]
|
||
W -->|补证请求且预算可用| RP
|
||
W --> D[detector 硬门]
|
||
D -->|阻塞且返修未满2轮| W
|
||
D -->|通过| S[Shadow 候选展示]
|
||
D -->|满2轮仍阻塞| H[停止并交用户]
|
||
S --> U{用户三决策}
|
||
U -->|原样接受| AP[接受前置校验]
|
||
U -->|修改后合并| M[编辑并生成 candidateVersion+1]
|
||
M --> D
|
||
AP --> C[confirm -> Canonical 正文]
|
||
U -->|丢弃| X[关闭候选]
|
||
C --> E[异步章后抽取]
|
||
E --> K[知识草稿与冲突队列]
|
||
```
|
||
|
||
本链是 Gate B=`passed` 后的产品化第二阶段,不属于 Gate A/B 前置实现范围。生产链不强制运行双盲 judge;用户可请求质量详情,或系统按抽样策略运行单次 judge,但 detector 硬门与用户三决策始终存在。
|
||
|
||
### 3.2 离线评测链
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
P[预注册样本/冻结点] --> O[可信编排器<br/>授权·预算·文件 CAS]
|
||
O --> SCH[全评测集顺序表<br/>位置计数差不超过 1]
|
||
SCH --> A[A 通用原文检索<br/>不用卡]
|
||
SCH --> C[C 卡索引原文检索<br/>卡不进 Writer]
|
||
SCH --> B[B card-only<br/>诊断负对照]
|
||
A --> W[隔离 Writer 进程<br/>stdin + 严格 JSON schema]
|
||
C --> W
|
||
B --> W
|
||
W --> D[隔离 Semantic Detector 进程<br/>真实报告计算指标]
|
||
O --> T[Evaluator-only OracleTruthPack<br/>与臂无关·不进 Writer]
|
||
D --> J1[隔离 Blind Judge 进程 1]
|
||
D --> J2[隔离 Blind Judge 进程 2/反序]
|
||
T --> J1
|
||
T --> J2
|
||
J1 --> JV{双评报告均合法?}
|
||
J2 --> JV
|
||
JV -->|否| F[失败关闭]
|
||
JV -->|是| ST{评分稳定?}
|
||
ST -->|是| R[去盲汇总与归因]
|
||
ST -->|否| J3[隔离 Blind Judge 进程 3<br/>最多一次]
|
||
J3 --> J3V{报告合法且形成稳定配对?}
|
||
T --> J3
|
||
J3V -->|是| R
|
||
J3V -->|否| F
|
||
R --> GB[唯一 GateInputBuilder<br/>manifest + receipts]
|
||
GB --> G{Gate 裁决}
|
||
O -.仅编排器可写.-> V["/private/tmp raw vault<br/>目录 0700·文件 0600"]
|
||
O --> S[安全摘要与原子结果]
|
||
W -->|任一调用失败| F
|
||
D -->|任一调用失败| F
|
||
```
|
||
|
||
Gate 核心比较只有 A 与 C:A 不使用卡,以统一查询做通用历史原文检索;C 只用卡定位历史章节,再回读原文。两臂向 writer 提供完全相同的事实约束和原文字符预算,writer 都看不到卡摘要、里程碑语义或检索轨迹,因此 C-A 只能归因于“卡索引是否改善原文选择”。B 保留为 `card_only_diagnostic` 负对照,候选永不进入接受链路,也不参与 Gate B 通过阈值。
|
||
|
||
A/B/C 都使用 `mode=diagnostic_only`、`acceptanceEligible=false`;Gate 通过只形成离线证据,任何臂都不能直接进入产品接受链路。
|
||
|
||
## 4. 细纲、创作自由与硬约束
|
||
|
||
细纲不是分镜脚本,需拆为两类:
|
||
|
||
| 类型 | writer 权限 |
|
||
|---|---|
|
||
| 硬事件、结果方向、伏笔动作、章末钩子、必须出场实体 | 不得删除、反转或提前回收 |
|
||
| 场景切分、局部顺序、过渡方式、环境质感、动作和对白细节 | 可合并、拆分或局部调序 |
|
||
|
||
writer 可以创造非 Canonical 的环境细节、动作、过渡、无名配角和对白表达。新增地名、能力、组织、人物身份、代际、战绩或关系等 Canonical 事实,必须进入“新设定申报”,不得直接写成已确认事实。
|
||
|
||
补证请求不是固定一次,而是受总预算控制:最多 3 次请求、累计新增上下文不超过本次检索预算的 30%;任一上限达到后停止补证并报告缺口。
|
||
|
||
## 5. 两阶段检索
|
||
|
||
### 5.1 检索规划
|
||
|
||
查询来自细纲硬约束与可调整节拍,包括人物、关系、地点、物品、能力、力量规则、历史回调、伏笔、语言指纹和同类历史场景。
|
||
|
||
`RetrievalPlan` 必须固定。`runId` 是运行元数据,不参与计划身份;`planId` 使用下表除 `runId` 外字段的规范 JSON 计算 SHA-256:UTF-8、NFC、LF 换行、对象键排序、数组保持合同顺序、无额外空白。
|
||
|
||
| 字段 | 含义 |
|
||
|---|---|
|
||
| `planVersion/runId/asOf` | 合同版本、运行 ID、冻结点;runId 不进入 planId |
|
||
| `queries[]` | `queryId`、查询文本、实体类型、检索目的、topK |
|
||
| `cardIndexVersion` | 卡索引和嵌入模型版本 |
|
||
| `proseIndexVersion` | 原文索引/读取器版本 |
|
||
| `filters` | 作品、授权、章号上限、来源状态 |
|
||
| `tieBreak` | `score DESC, sourceVersion ASC, sourceId ASC, offset ASC` |
|
||
| `tokenBudget` | 卡、连续原文、历史证据、范式各自预算 |
|
||
|
||
### 5.2 卡索引与冻结
|
||
|
||
每个卡命中返回:`cardId/name/type/retrievalReason/sourceRefs/stateAsOf`。
|
||
|
||
`stateAsOf` 只能由绝对章号 `<= as_of` 的里程碑重建。以下字段直接排除或阻断:
|
||
|
||
- 全书终态摘要;
|
||
- 未来成长弧线与结局方向;
|
||
- 无法证明绝对章号的演变事实;
|
||
- 内容描述明显属于目标章或未来章的错位里程碑。
|
||
|
||
正向创作没有回放冻结点时,`asOf` 等于当前 Canonical 最新章。
|
||
|
||
离线 eval_draft 的卡只在 C 臂检索器内部用于定位 `sourceRefs`,不得进入 A/C 的 WriterContext。B 负对照若保留 `indexHints`,`content` 只允许卡名、类型和实际回读章号,不得透传里程碑台阶。这个收紧只作用于离线诊断,生产 Canonical 卡继续使用既有冻结状态提示。
|
||
|
||
### 5.3 根据卡回读原文
|
||
|
||
首版必须保留 run3 已验证条件:**目标章之前连续 4 章全文**。选择性裁剪只能作为后续 A/B 实验变量;未证明不降质前,不得替代四章全文基线。
|
||
|
||
在连续四章之外,按卡来源指针补充:
|
||
|
||
1. 最近一次状态变化场景;
|
||
2. 人物代表性语言场景;
|
||
3. 能力、物品或关系的代表性表现;
|
||
4. 与本章细纲同类的历史场景。
|
||
|
||
若 eval_draft 卡没有持久化 `sourceRefs`,C 臂可把冻结线内最近三个里程碑章作为检索候选来源,但送入 writer 的仍只能是回读后的 Canonical 原文。该来源在 manifest 标记 `sourceRef.sourceType=card_chapter_proxy`,不能伪装成精确片段;每个代理章原文必须出现卡规范名或预注册合法别名,否则失败关闭。连续四章基线不可裁剪,A/C 选择性原文统一按同一 `proseCharBudget` 装配。
|
||
|
||
A/C 的 `proseCharBudget`、连续四章基线和规范化字符算法完全相同。除连续基线外,两臂都必须恰好装配预注册字符数;任一臂合格来源不足即样本失败,不得缩小一臂预算迁就另一臂。检索策略和完整 manifest 只留在编排器侧,不送入 writer。A/C WriterContext 的 allowlist diff 只允许所选原文 `sourceRefs/hash/content` 及其派生的上下文 hash 不同;事实约束、细纲、执行配置、篇幅合同和所有其他字段必须逐字节相同。
|
||
|
||
`RetrievalManifest` 保存 `planId`、查询、过滤、排序、来源版本、章号、片段 offset、内容哈希和裁剪原因。`manifestId` 对规范化来源集合计算 SHA-256,排除 `runId`、时间戳和执行节点;同一 `planId` 与索引版本必须产生相同 `manifestId`。
|
||
|
||
## 6. 双证据模型
|
||
|
||
### 6.1 事实证据 `factEvidence`
|
||
|
||
负责“写得对”。可信来源包括:
|
||
|
||
- 已确认设定;
|
||
- Canonical 卡与状态台账;
|
||
- 已确认历史正文;
|
||
- 细纲明确声明的本章新 Canonical 事实。
|
||
|
||
正式设定无需历史正文即可成为硬事实。抽取卡若没有可靠来源或与 Canonical 冲突,则不能单独支撑事实。
|
||
|
||
### 6.2 表现证据 `proseEvidence`
|
||
|
||
负责“写得像”。来源是历史原文场景,用于人物声音、动作习惯、战斗表现、段落节奏和章末钩子。新角色没有历史原文时不构成事实阻断,但必须使用设定/细纲约束,并降低“文风复现”置信度。
|
||
|
||
### 6.3 覆盖状态
|
||
|
||
| 状态 | 含义 | 生产处理 |
|
||
|---|---|---|
|
||
| `supported` | 事实证据充分;需要表现复现时也有原文证据 | 允许 |
|
||
| `declared_new` | 细纲/设定明确声明的新 Canonical 事实 | 允许并申报 |
|
||
| `card_gap` | 原文或正式设定可证,但缺卡 | 允许,输出卡质量问题 |
|
||
| `style_gap` | 事实可证,但没有历史表现样本 | 允许,降低风格置信度 |
|
||
| `unsupported` | 没有可信事实证据 | 阻断硬事实 |
|
||
| `conflict` | 卡、设定、状态或原文互相冲突 | 阻断并交用户 |
|
||
|
||
## 7. 可执行数据合同
|
||
|
||
### 7.1 `WriterContext v1`
|
||
|
||
| 字段 | 类型 | 必填 | 约束 |
|
||
|---|---|:---:|---|
|
||
| `schemaVersion` | string | 是 | 固定 `writer-context-v1` |
|
||
| `runId/attempt` | string/int | 是 | runId 格式受限;attempt 单调递增 |
|
||
| `mode` | enum | 是 | `production` / `diagnostic_only` |
|
||
| `qualityPolicyVersion` | string | 是 | 绑定生产或离线状态机 |
|
||
| `workId/targetChapter/asOf` | int | 是 | `asOf < targetChapter`(回放) |
|
||
| `contextSnapshot` | object | 是 | manifest ID、SHA-256、生成时间不进入哈希 |
|
||
| `sourceVersion` | string | 是 | 原始来源版本 |
|
||
| `authorizationSnapshot` | object | 是 | 不可变授权 ID、用途、重验时间 |
|
||
| `sourceStatus` | enum | 是 | 非允许状态失败关闭 |
|
||
| `retrievalPlan/manifest` | object | 是 | 产品上下文为完整检索信息;A/C 离线 writer 仅保留中性的原文 sourceRefs/hash,不含检索策略、卡命中或卡来源 |
|
||
| `fineOutline` | object | 是 | 硬约束、可调整节拍、新设定声明 |
|
||
| `narrativeState` | object | 是 | 时间、地点、角色位置、即时局面 |
|
||
| `factEvidence[]` | array | 是 | 事实 ID、来源类型、sourceRef、hash |
|
||
| `proseEvidence[]` | array | 是 | 章号、offset、hash、用途、临时片段 |
|
||
| `indexHints[]` | array | 否 | 仅 B 负对照可用;A/C 和产品生产上下文硬拒绝 |
|
||
| `evidenceStrategy` | enum | 否 | 产品生产缺省为 `production_dual_evidence`;离线三臂必须显式记录策略 |
|
||
| `patternReferences[]` | array | 否 | 已授权范式卡,只作结构方法参考 |
|
||
| `evidenceCoverage[]` | array | 是 | 细纲要素到证据的覆盖状态 |
|
||
| `outputContract` | object | 是 | 篇幅、场景、frontmatter、申报规则 |
|
||
| `tokenBudget/omittedSources` | object/array | 是 | 预算与排除原因回显 |
|
||
|
||
所有对象使用严格 schema,额外字段失败;引用的 ID、版本和 hash 必须存在且一致。
|
||
|
||
Gate A 的公共控制还固定 `selectorVersion`、选择器规范 JSON 原始字节 SHA-256、`writerInputProvenance=preregistered_fine_outline`、`oracleInputProvenance=oracle_reference_scaffold` 和 `maxContextChars=140000`。loader 在任何数据库读取前核对并原样沿用,不得按真实输入扩大预算;若固定预算连细纲硬约束和连续四章全文基线都装不下,assembler 必须失败关闭。
|
||
|
||
`evidenceStrategy` 是编排器侧字段:产品生产上下文未填写时按 `production_dual_evidence` 校验;离线 A/B/C manifest 必须分别填写 `generic_prose_retrieval`、`card_only_diagnostic`、`card_indexed_prose_retrieval`。A/C WriterContext 不携带该字段,都必须有相同 `proseCharBudget`、统一 `factEvidence` 且 `indexHints=[]`;这些事实约束只能来自正式设定、细纲声明和独立于被测卡构建的冻结事实台账。C 的卡命中只存在于编排器侧 manifest。只有 B 可在 `mode=diagnostic_only`、`purpose=evaluation/diagnostic`、`acceptanceEligible=false` 时携带严格 `indexHints` 并保持 `proseEvidence=[]`;`claimLedger` 不得引用 `indexHints`。该例外不能用于 A/C 或产品生产。
|
||
|
||
### 7.2 `WriterOutput v1`
|
||
|
||
```text
|
||
schemaVersion
|
||
runId / attempt / mode / qualityPolicyVersion
|
||
contextSnapshotId / contextSnapshotSha256
|
||
candidateVersion
|
||
candidateSha256
|
||
acceptanceEligible
|
||
candidateBody
|
||
claimLedger[]
|
||
evidenceRequests[]
|
||
newSettingDeclarations[]
|
||
selfCheck
|
||
```
|
||
|
||
`diagnostic_only` 输出必须固定 `acceptanceEligible=false`;confirm 对此状态硬拒绝。
|
||
|
||
`candidateBody` 在计算 hash 和 offset 前统一为 UTF-8、Unicode NFC、LF 换行。`candidateSha256` 对该规范化字节计算。`claimLedger[]` 至少包含:`claimId`、`candidateSha256`、`startCodePoint`、`endCodePoint`、事实类型、`factEvidenceId`、可选 `proseEvidenceId`、coverageState;范围采用 Unicode code point 的左闭右开区间 `[start,end)`。规则门机械校验范围、hash 和引用完整性;detector 判断语义是否真的匹配。
|
||
|
||
## 8. 篇幅与叙事基线
|
||
|
||
### 8.1 确定性算法
|
||
|
||
1. 正文先统一为 Unicode NFC 和 LF;“汉字数”= Unicode Script=Han 的 code point 数,不计标点、空白、拉丁字母和数字。
|
||
2. “有效章节”= Canonical、汉字数 >= 500、非空章、章号 `< targetChapter`。
|
||
3. 有细纲显式 `targetChars` 时使用该值,但仍执行 2000-10000 限幅;该字段需加入 outline schema。
|
||
4. 否则取最近 `min(20, 有效章节数)` 章的汉字数中位数;偶数样本取中间两值算术平均,使用十进制 `ROUND_HALF_UP` 取整数;不足 3 章时使用作品初始化默认值。
|
||
5. `density = hardEventCount + 0.5 * foreshadowingActionCount + 0.5 * requiredSceneCount`。
|
||
6. 调整系数 `factor = clamp(0.85 + 0.05 * (density - 3), 0.85, 1.15)`。
|
||
7. `target = round_to_100(medianChars * factor)`;`round_to_100` 使用十进制 `ROUND_HALF_UP`;范围端点同样半入取整,最后限制在 2000-10000 字。
|
||
|
||
回放评测只使用目标章之前的数据,不读取目标章字数。叙事基线同时记录连续四章的场景数、对话占比、段落长度和钩子类型。
|
||
|
||
## 9. 生产质量状态机
|
||
|
||
`qualityPolicyVersion = writer-production-v1`
|
||
|
||
```text
|
||
validating_context -> retrieving -> writing -> detecting
|
||
detecting -> shadow_ready
|
||
detecting -> rewriting(attempt <= 2) -> detecting
|
||
detecting -> blocked_user_action(attempt > 2)
|
||
shadow_ready -> accept_preflight / edited_candidate / discarded
|
||
edited_candidate -> detecting
|
||
accept_preflight -> accepted / revision_conflict / authorization_stale / source_stale / quality_stale
|
||
accepted -> canonical_committed -> extraction_queued
|
||
```
|
||
|
||
detector 只阻断可定位、可验证的问题:细纲硬约束漏项、事实冲突、证据引用缺失、时间地点/知情范围/能力代价矛盾、未来泄漏、输出合同错误。文风、张力和文笔只给建议或交 judge,不作为 detector 硬阻断。
|
||
|
||
每个节点都有 deadline;超时标记当前 attempt,取消下游并丢弃迟到结果。产品化状态仍须 compare-and-set、终态不可回退和重试幂等,但不得直接复用第 11 节 agent-example 离线文件状态;具体持久化必须在 Gate B 通过后按父仓运行时边界设计或另立 ADR。
|
||
|
||
`accept_preflight` 必须实时校验:`mode=production`、`acceptanceEligible=true`、qualityPolicyVersion、detector 报告绑定的 candidateSha256/candidateVersion、授权快照仍有效、sourceStatus 未变化、contextSnapshot 未失效、`expectedRevision` 一致。用户修改后合并必须生成新 candidateVersion、重新跑 detector,再回到 Shadow 展示与接受前置校验。
|
||
|
||
生产自动返修最多 2 轮。用户可在阻塞后手动发起新运行,不复用旧 candidateVersion。
|
||
|
||
## 10. 离线优化与双盲评测
|
||
|
||
`qualityPolicyVersion = writer-eval-v1`
|
||
|
||
- 状态机:`preregistered -> generating -> detecting -> judging_pair -> stable_report`;双评不稳定时进入 `adjudicating -> adjudicated_report`;第三评委报告非法进入 `failed_judge_invalid`,第三评委后仍无稳定配对进入 `failed_judge_unstable`;授权、冻结、合同或模型失败进入对应 `failed_*` 终态。
|
||
- 离线优化允许最多 5 轮,且每轮只改一个变量;与生产两轮返修是两套状态机。
|
||
- 三臂使用相同细纲、冻结点、完整模型 ID、effort、单次预算、上下文上限、篇幅算法和输出 schema;A/C 还必须使用相同原文字符预算和统一事实约束。启动前对完整 WriterContext 执行 allowlist diff,只允许原文内容/来源及派生 hash 不同;出现其他差异即失败。
|
||
- A/B/C 运行顺序由整个预注册评测集一次性生成:先按 `SHA-256(evaluationSetVersion + sampleId)` 排序全部样本,再按索引循环分配 `[A,B,C]`、`[B,C,A]`、`[C,A,B]`。生成完整顺序表后机械验证每个位置上的臂计数差不超过 1;禁止逐样本独立 shuffle。盲化映射使用同样的评测集级分配原则和独立命名空间。
|
||
- judge 的可信输入边界是独立 `writer-blind-input-v2`:盲化候选/哈希、所有臂相同的细纲评测字段,以及 evaluator-only `oracleTruthPack`。真实 A/B/C 映射仅在编排器内存中存在,judge 不得访问各臂 WriterContext、原始运行目录或含臂名的路径。
|
||
- 两个评委使用独立无会话实例,第二评委反转顺序;评分步长为 0.5。
|
||
- 同维分差 > 0.5 时判不稳定,最多增加一次第三评委。三评分中若至少一对差值 <=0.5,则该维最终分取三者中位数;若不存在稳定配对,则样本进入 `failed_judge_unstable`,顶层运行失败。
|
||
- 五维:设定与实体保真、情节与细纲忠实、叙事完整与张力、文风一致、文笔质量。
|
||
- 离线达标不改变 detector 红线。评委可以看到独立真值包,但不能看到被测卡、各臂检索轨迹或臂专属补充原文。
|
||
|
||
`oracleTruthPack` 固定为 `oracle-truth-pack-v1`,由可信 loader 在同一冻结快照内生成:全量 Canonical 历史中 `chapter <= asOf` 的事实断言,加上目标章 reference scaffold 中预注册的目标事实断言。它至少包含 `schemaVersion/evaluationSetVersion/sampleId/workId/asOf/sourceSnapshotSha256/authorizationSnapshotId/historicalAssertions[]/targetAssertions[]/packSha256`;每条断言带稳定 ID、来源版本、章号边界和内容 hash。包中不得包含被测卡、卡派生断言、A/B/C 检索 manifest、各臂原文或目标章文风答案。
|
||
|
||
`oracleTruthPack` 的授权快照必须固定 `allowedPurpose=offline_evaluation`、来源状态、来源版本和重验时间,只授权本次 evaluator;所有 judge 接收字节完全相同的 pack。它不进入 writer、detector、Gate 安全摘要或日志;原始包只在 raw vault 临时存在,长期只保留 schema/hash/授权回执。其历史断言用于核对远端历史事实,目标断言用于核对细纲和目标事实,不得用任一臂检索到的补充原文给候选背书。授权失效、schema/hash 不一致或三位评委 pack hash 不同,样本失败。
|
||
|
||
### 10.1 两级验收门
|
||
|
||
| 门 | 有效样本 | 机械通过条件 | 其他终态 |
|
||
|---|---|---|---|
|
||
| Gate A 链路可运行 | 深空预注册 5 章,五类场景各 1 | 5/5 schema 合法且评委稳定;未来泄漏 0;系统失败 0;C 臂 detector 最终高严重度 0;细纲硬约束覆盖率 100% | 任一系统/schema/hash/泄漏/judge 异常=`failed`;仅预注册集合自身不足 5 或场景不全=`insufficient_evidence` |
|
||
| Gate B 正文层正式通过 | 至少 2 本书、每书 >=5 章、总计 >=10 章;五类场景均覆盖 | Gate A 已 passed;A/C 所有样本合法且稳定;C-A 的“设定与实体保真”平均增量 >=0.25 且至少 60% 样本增量 >0;“文风一致/叙事张力”整体及各非空新角色分层均不退化;C 臂硬约束覆盖率 100%、高严重度 0 | 任一系统/schema/hash/泄漏/judge 异常=`failed`;仅预注册作品/样本/场景自身不足=`insufficient_evidence`;无明显增益且无退化=`no_gain`;B 不参与通过阈值 |
|
||
|
||
裁决按以下顺序执行,命中即停止,保证每次只有一个终态:
|
||
|
||
1. **Gate A**:先检查预注册 manifest、顺序表、allowlist diff、全部预期调用回执、schema/hash、泄漏审计和 judge 稳定性,任一异常 -> `failed`;再检查预注册集合定义时是否已经不足 5 个样本或五类场景不全,命中 -> `insufficient_evidence`;再检查 C 臂硬门,命中 -> `failed`;其余 -> `passed`。
|
||
2. **Gate B**:先检查本次 Gate B 的全部系统/schema/hash/泄漏/judge 状态,任一异常 -> `failed`;再继承 Gate A 终态,Gate A=`failed` -> `failed`,Gate A=`insufficient_evidence` -> `insufficient_evidence`;再检查预注册作品/样本/场景自身规模,不足 -> `insufficient_evidence`;再检查 A/C 硬错误、整体或任一非空新角色分层质量退化,命中 -> `failed`;再判断 C-A 保真增益,达标 -> `passed`;其余 -> `no_gain`。B 只进入诊断报告,不进入这些阈值。
|
||
|
||
只有 Gate B=`passed` 才解锁细纲智能体真实能力验收;`no_gain` 只形成“卡未证明增益”结论,不视为通过。
|
||
|
||
### 10.2 Task10 Gate A 预注册与当前可验证边界
|
||
|
||
唯一配置为 `.claude/skills/replay-eval/configs/writer-gate-a-deep-space-v1.json`。样本固定如下,不得根据生成结果替换章节或场景分类:
|
||
|
||
| 目标章 | 冻结点 | 场景 | 预注册目标 | 大纲/细纲来源 | 预期长度 | 主要实体 | 新角色比例 | 泄漏检查 |
|
||
|---:|---:|---|---|---|---:|---|---:|---|
|
||
| 489 | 488 | 战斗 | 圣蒂曼围攻/加特朗战 | `outline-window:deep-space:481-488` / `fine-outline:deep-space:489` | 7500 | 圣蒂曼、加特朗 | 1.0 | 禁读 489 及以后;目标/未来读取数必须为 0 |
|
||
| 321 | 320 | 人物对话 | 莫妮卡道别与朋友确认 | `outline-window:deep-space:313-320` / `fine-outline:deep-space:321` | 7600 | 莫妮卡、朋友关系 | 0 | 禁读 321 及以后;目标/未来读取数必须为 0 |
|
||
| 544 | 543 | 转折 | 迷途之地内应反水 | `outline-window:deep-space:536-543` / `fine-outline:deep-space:544` | 6700 | 迷途之地、内应 | 未知 | 禁读 544 及以后;目标/未来读取数必须为 0 |
|
||
| 199 | 198 | 信息揭示 | 赛莉丝身份与联赛锁死真相 | `outline-window:deep-space:191-198` / `fine-outline:deep-space:199` | 2000 | 赛莉丝、联赛 | 0 | 禁读 199 及以后;目标/未来读取数必须为 0 |
|
||
| 523 | 522 | 老角色回归 | 伊蕾莉雅与旧部重逢 | `outline-window:deep-space:515-522` / `fine-outline:deep-space:523` | 6100 | 伊蕾莉雅、旧部 | 0 | 禁读 523 及以后;目标/未来读取数必须为 0 |
|
||
|
||
预期长度不是人工填写:配置记录目标章之前连续四章的 `frozenRecentHanCounts`,统一以 `hardEventCount=1`、`foreshadowingActionCount=0`、`requiredSceneCount=0` 调用 `calculate_target_chars`,且 `usesTargetChapterLength=false`。五章机械结果固定为 489=7500、321=7600、544=6700、199=2000、523=6100;上下限取正负 10% 后再受 2000-10000 限幅。
|
||
|
||
新角色比例只统计具名 `requiredCharacters` 在冻结点前无记录的比例。真实 loader 在来源、授权、scaffold、卡和正文所在的同一个 `REPEATABLE READ READ ONLY` 事务内,直接扫描冻结历史 Canonical 正文并返回名字对应的首次命中章与命中章集合,再独立重算 `knownBeforeAsOf/absentBeforeAsOf/newCharacterRatio`,不得相信卡内是否出现该名字。489 的加特朗在 488 前无记录,因此为 1.0;321/199/523 的具名角色已有记录,因此为 0;544 的“内应”是泛称、无法机械判定具体身份,必须为 `null + unresolved_generic_role`,不允许默认成 0。
|
||
|
||
真实装配把目标章 reference scaffold 分成两份:writer 只接收预注册细纲硬约束和统一事实约束;scaffold 的目标事实断言只进入 evaluator-only oracleTruthPack。完整 scaffold、目标断言和原文答案均不得进入 writer。这项验证不覆盖上游清洗、抽卡、范式、细纲生成或完整创作链,不能据此宣称整条创作链完成。
|
||
|
||
仓内配置不含原文全文。`writerContextInput.contentMode=sanitized_contract_fixture`,连续四章只放脱敏合成短文本,用于 dry-run 机械证明 WriterContext 合同、冻结边界、三臂差异、manifest 可复现和候选不可接受;不能据此声称历史原文完整、生成质量通过或 real-run 完成。
|
||
|
||
dry-run 命令:
|
||
|
||
```bash
|
||
.venv/bin/python .claude/skills/replay-eval/scripts/run_writer_replay.py \
|
||
--config .claude/skills/replay-eval/configs/writer-gate-a-deep-space-v1.json \
|
||
--dry-run
|
||
```
|
||
|
||
dry-run 只生成计划、manifest 和上下文摘要,不调用模型。测试注入路径虽可验证 writer、detector 与盲评编排,但 judge 只接收独立盲化内容和共同评测参考,不能取得 raw 目录、真实臂映射或任一臂专属证据;评委顺序变化不得改变共同参考。当前真实 semantic detector 与 judge adapter 尚未实现,CLI `--execute` 必须明确失败关闭;在 adapter 接线、离线测试和预算确认完成前,不得声称真实回放或 Gate A 已完成。
|
||
|
||
当前实现与本版合同仍有明确差距:writer runner 只把 `opus` 当模型参数,未绑定绝对 CLI/hash、完整 model ID、单次预算与输出 schema,也未形成联合回执,stderr 仍可能泄漏;配置仍使用旧三臂证据策略、`inputProvenance=oracle_reference_scaffold` 和 temperature/topP/seed 数值;顺序仍是逐样本处理,缺少全评测集平衡表与完整上下文 allowlist diff;真实 oracleTruthPack、semantic detector、blind judge、GateInputBuilder、confounders、vault lease 和文件 CAS 未接线;测试注入仍把 detector 指标写死,`writer_gate.py` 及错误测试仍可能先判样本不足。以上任一项未整改,Gate A real-run 不得启动。
|
||
|
||
真实 CLI 极小探测还有一条直接证据:一次 Opus 调用等待 177043ms 后因 API 503 失败,进程 `exit=1`;JSON envelope 却同时出现 `type=result`、`subtype=success`、`is_error=true`、`api_error_status=503`、`terminal_reason=api_error`、`stop_reason=stop_sequence`、`total_cost_usd=0`、完整零值 `usage` 和空 `modelUsage={}`。因此 `subtype=success`、合法 JSON、完整 usage 或 `stop_reason=stop_sequence` 都不能单独证明调用成功;该证据也说明每次调用必须有编排器硬 deadline。安全摘要只记录状态码和受控字段,不记录具体网关错误正文。
|
||
|
||
该失败探测没有产生可验证的成功 `structured_output` 或完整 model ID,只能证明失败 envelope 语义。必须先完成第 11.4 节成功探测,才能冻结离线评测 adapter 所需字段;在此之前 `--execute` 继续失败关闭。
|
||
|
||
当前 `writer_gate.py` 把样本不足检查放在部分系统失败之前,错误测试也固化了这一顺序;两者必须按 10.1 重写。detector 指标必须来自严格校验的真实语义报告,禁止常量、默认通过或测试替身进入 real-run。第三评委报告非法或仍不稳定时,样本和顶层都必须失败。
|
||
|
||
### 10.3 Gate 输入与混淆项合同
|
||
|
||
`GateInputBuilder` 是 manifest/receipts 到 `gate-input.json` 的唯一可信入口,owner 固定为 `.claude/skills/replay-eval` 的可信编排器,由 `run_writer_replay.py` 在所有样本终态后调用。它只读取预注册 manifest、全评测集顺序表、A/C allowlist diff 回执、retrieval manifest、writer/detector/judge 执行回执与报告、oracleTruthPack 回执、泄漏审计和授权回执;逐项校验 schema、hash、run/sample/candidate 绑定后生成严格 `writer-gate-input-v2`。`writer_gate.py` 只接受该文件及其 SHA-256,不得接收手工对象、上游聚合数字或缺失回执的补写数据。
|
||
|
||
`writer_gate.py` 是 `writerGateBPassedReceipt` 的唯一签发者。它先从 `gate-input.json` 生成严格 `gate-report.json`;只有 Gate B 报告 `status=passed`,才可签发 receipt。receipt 必须包含 `runId/evaluationSetVersion/gateInputSha256/gateReportSha256/gatePolicyVersion/status=passed/issuedAt/receiptRevision/previousStateSha256/receiptSha256`,其中 `receiptSha256` 对除自身外字段的规范 JSON 计算。`failed`、`insufficient_evidence`、`no_gain` 或报告非法时一律不签发。
|
||
|
||
签发必须进入第 11.5 节同一文件 CAS journal 序列:在 `state.lock` 内先原子落盘并提交 `gate-report.json` 对应 revision,再基于该 `gateReportSha256` 和前一状态 hash 生成 receipt、原子落盘并提交下一 revision;禁止先签 receipt、跨运行复用或在 journal 外补发。细纲 real-run 入口守卫只读取已签发文件,验证 receipt 严格 schema、规范 hash、gate report、gate input、`receiptRevision/previousStateSha256` 与 journal 链全部一致;禁止调用方自算 JSON 冒充 receipt。细纲 dry-run 不要求该 receipt。
|
||
|
||
`gate-input.json` 不含正文、prompt、完整模型响应、oracle 断言或 raw path。每个样本的 `confounders` 必须完整包含以下字段,缺失、`null` 或默认空对象均使 Gate 输入 schema 失败:
|
||
|
||
| 字段 | 确定性算法 |
|
||
|---|---|
|
||
| `falseNegative.A/C` | 对同一 `assertionId` 或 `constraintId`,detector verdict=`pass`、稳定 judge verdict=`fail` |
|
||
| `falsePositive.A/C` | 对同一 `assertionId` 或 `constraintId`,detector verdict=`fail`、稳定 judge verdict=`pass`,且 leakage=false |
|
||
| `leakage.A/C` | 对应臂 `leakageAuditReceipt.findingCount > 0` |
|
||
| `reviewerInstability` | 双评任一维差值 >0.5;第三评委可把样本裁成稳定,但该字段仍为 true;第三评委后不稳定则系统失败 |
|
||
| `newCharactersWithoutCards` | 冻结点前无记录的具名 requiredCharacters 中,在 C 臂卡检索 manifest 无合法卡命中的数量、分母、ratio 与名称集合 hash |
|
||
|
||
Gate B 必须按预注册 `newCharacterRatio` 分为 `zero=0`、`low=(0,0.5]`、`high=(0.5,1]`、`unresolved` 四层,逐层报告样本数、C-A 五维增量、正增益比例、detector 假阴/假阳和无卡新角色。整体平均仍可用于增益阈值,但任一非空层出现硬错误或超过 10.1 的文风/张力退化线,Gate B 必须失败,不能用单层整体平均掩盖。
|
||
|
||
混淆项只按同类、同 ID verdict 计算:事实断言只能比较 detector `assertionVerdicts[]` 与 judge `oracleAssertionVerdicts[]` 的同一 `assertionId`,硬约束只能比较双方 `hardConstraintVerdicts[]` 的同一 `constraintId`,不得跨类型配对。预注册 manifest 固定 `comparableAssertionIds`,它必须等于 detector 冻结事实清单的完整 ID 集,并且是 oracleTruthPack assertion ID 集的子集;硬约束预期集来自预注册细纲。detector 与稳定 judge 必须完整覆盖各自预期集,每个 ID 仅出现一次。任一 verdict=`unknown`,或 ID 缺失、重复、越界、candidateSha256 不同,均使 confounder 计算失败并将样本置为 `failed`。五维分数不得推导或覆盖 verdict。
|
||
|
||
## 11. agent-example 离线评测 adapter 执行合同
|
||
|
||
本节是 agent-example 内 writer、semantic detector、blind judge 的离线 real-run 合同。它是为固定模型、独立预算和可审计回放设立的有限例外,不是 Muse 产品运行时方案。第 10.2 节只描述 Gate A 样本和当前实现状态,不再另定义调用参数、隔离或失败语义。
|
||
|
||
### 11.1 可信编排器与统一调用基线
|
||
|
||
可信编排器是唯一可以读取授权来源、装配输入、持有 A/B/C 映射、管理预算、写临时数据和推进状态的进程。三个模型角色都直连固定 Claude CLI,不调用 `chat_governed`,也不写 New-API 共享额度账本;但每次外发仍必须绑定授权快照、单次/总预算和执行回执。该例外在 Gate B 通过前不得接入产品路径。
|
||
|
||
Gate B 通过后的产品化必须回到父仓 `AI Orchestration -> Integration Execution Facade -> New-API` 边界;若该边界不能满足需求,必须另立正式 ADR 并评审通过,不能把本节直连 CLI 当成生产方案。
|
||
|
||
每次模型调用必须是 fresh process,并显式绑定以下已验证参数:`--print`、`--bare`、`--model`、`--effort`、`--max-budget-usd`、`--output-format json`、`--json-schema`、`--tools ""`、`--no-session-persistence`、`--disable-slash-commands`、`--strict-mcp-config`、`--mcp-config '{"mcpServers":{}}'`、`--system-prompt`。`--print` 是非交互执行及预算、JSON 输出、无会话参数生效的前提;`--bare` 用于跳过 hooks、LSP、插件同步、归因和 auto-memory。业务输入只从 stdin 传入,不得把正文、完整 prompt 或臂名写进命令行参数。
|
||
|
||
| `ExecutionProfile` 字段 | 约束 |
|
||
|---|---|
|
||
| `profileVersion/adapterRole` | 固定合同版本;角色为 `writer`、`semantic_detector`、`blind_judge` |
|
||
| `claudeExecutablePath/claudeExecutableSha256/claudeCliVersion` | 绑定绝对路径、可执行文件 SHA-256 和版本 `2.1.211`;任一变化先重新预注册 |
|
||
| `modelAlias/resolvedModelId/effort` | `opus` 只可作配置输入别名;预检探测解析完整 model ID,实际调用和回执都使用该完整 ID,禁止降级换模 |
|
||
| `maxBudgetUsdPerCall/timeoutSeconds` | 每个角色分别预注册;到限即失败,不扩大、不借用共享账本 |
|
||
| `maxContextChars` | 在装配前校验;A/B/C writer 上限完全相同;A/C 超限不得截断硬约束或连续四章基线,B 臂沿用第 7.1 节诊断例外 |
|
||
| `jsonSchemaId/jsonSchemaSha256` | 输入输出都绑定严格 schema;额外字段、缺字段或 hash 不一致均失败 |
|
||
| `systemPromptId/systemPromptSha256` | 三臂 writer 完全相同;所有评委也完全相同,评委编号只进执行元数据,不改变提示词 |
|
||
| `temperature/topP/seed` | 固定记为 `unsupported`,`reproducibilityClaim=not_claimed`;不作为 CLI 参数或已绑定控制项 |
|
||
|
||
三臂 writer 的 `resolvedModelId/effort/maxBudgetUsdPerCall/maxContextChars/jsonSchemaSha256/systemPromptSha256` 必须逐字段相等,并对规范化配置计算同一 `executionProfileSha256`。回执缺完整 model ID 或与预注册值不一致即失败。detector 对所有候选使用同一 detector profile;所有 judge 调用使用同一 judge profile。
|
||
|
||
每次调用都由 `sandbox-exec` profile 拒绝隔离目录之外的文件读写,只允许 Claude CLI 完成模型调用所需的 DNS、代理和出站网络;工具、插件、hooks、技能、MCP 和其他网络用途全部禁止。cwd、HOME、TMPDIR 均指向本次 0700 隔离目录,调用结束即清理。可执行文件使用已绑定绝对路径,因此不传继承 PATH。
|
||
|
||
环境只允许以下字段:认证 `ANTHROPIC_API_KEY` 或 `CLAUDE_CODE_OAUTH_TOKEN` 中经授权的一种;代理 `HTTPS_PROXY/HTTP_PROXY/NO_PROXY` 及对应小写字段;locale `LANG/LC_ALL`;证书 `SSL_CERT_FILE/SSL_CERT_DIR/NODE_EXTRA_CA_CERTS`。HOME/TMPDIR 由编排器覆盖,其他 repo、数据库、云平台和业务 secret 一律不继承。blind judge 每次调用都使用新目录、新进程和新 stdin,不得发现 raw 目录、真实 A/B/C 映射或含臂名路径。
|
||
|
||
### 11.2 三类输入输出
|
||
|
||
| 角色 | 唯一输入 | 唯一业务输出 | 失败关闭条件 |
|
||
|---|---|---|---|
|
||
| writer | 严格校验的 `WriterContext v1`;A/C 只含统一事实约束与选出的历史原文,不含卡语义、检索策略或完整 manifest;B 为独立诊断例外 | `WriterOutput v1`;候选正文、claim ledger、补证请求、新设定申报、自检 | 上下文/输出 schema 非法,A/C allowlist diff 失败,预算或超时,完整 model ID 不符,候选与上下文 hash/版本不绑定 |
|
||
| semantic detector | `semantic-detector-input-v2`;候选、细纲硬约束、claim ledger、允许核对的冻结前证据和上下文绑定 | `semantic-detector-report-v2`;findings、`assertionVerdicts[]`、`hardConstraintVerdicts[]`、证据定位及报告 hash | 报告非法、候选绑定不符、verdict 为 unknown、ID 集不完整、结论无受控证据或高严重度残留 |
|
||
| blind judge | `writer-blind-input-v2`;盲化候选、统一细纲评测字段和字节相同的 oracleTruthPack | `blind-judge-report-v2`;五维评分、`oracleAssertionVerdicts[]`、`hardConstraintVerdicts[]`、候选/pack hash | pack 授权/hash 不同、verdict 为 unknown、ID 集不完整、看到臂专属证据、schema/候选/顺序非法,或第三评委后仍不稳定 |
|
||
|
||
`semantic-detector-input-v2` 必须包含 `schemaVersion/runId/sampleId/opaqueArmId/candidateSha256/candidateBody/contextSnapshotSha256/fineOutline/hardConstraints/claimLedger/factEvidence/proseEvidence/asOf/authorizationSnapshotId/inputSha256`;不得包含 oracleTruthPack、目标章或未来章正文。`semantic-detector-report-v2` 必须包含 `schemaVersion/runId/sampleId/opaqueArmId/inputSha256/candidateSha256/modelReceiptSha256/findings[]/assertionVerdicts[]/hardConstraintVerdicts[]/status/reportSha256`。两类 verdict 数组分别绑定稳定 `assertionId` 或 `constraintId`、`candidateSha256`、`verdict=pass|fail|unknown` 和受控证据引用。编排器只从 schema、hash、候选和 ID 集均合法的报告计算 `highSeverityCount` 与 `hardConstraintCoverage`;unknown 或 ID 集不完整时报告非法,禁止填默认值。
|
||
|
||
未来泄漏不交给 semantic detector 猜测。可信编排器单独执行 `leakage-audit-v1`:只在编排器边界内比较候选与预注册 `forbiddenFacts[]`、目标/未来读取 trace、`asOf` 和来源 hash,输出不含禁区正文的 `leakageAuditReceipt`。禁区事实不得进入 writer、judge、日志或安全摘要;Gate 只消费该回执的 `status/findingCount/receiptSha256`。
|
||
|
||
`blind-judge-report-v2` 必须包含 `schemaVersion/runId/sampleId/reviewerInvocationId/blindInputSha256/oracleTruthPackSha256/candidateOrder[]/candidateScores[]/oracleAssertionVerdicts[]/hardConstraintVerdicts[]/modelReceiptSha256/status/reportSha256`。每个 `candidateScores[]` 项绑定 `blindCandidateId/candidateSha256`,并为五个维度逐项给出 0.5 步长分数和受控理由。两个 verdict 数组中的每一项分别绑定稳定 `assertionId` 或 `constraintId`、`candidateSha256`、`verdict=pass|fail|unknown` 和受控证据引用;证据只能引用候选区间、oracle assertion 或预注册 constraint,不得引用臂专属检索材料。`candidateOrder[]` 必须与本次 stdin 完全一致;分数与 verdict 独立,禁止用分数阈值生成 verdict。
|
||
|
||
每份 judge 报告先独立校验,再进入稳定性裁决。第三评委不是容错兜底:其报告 invalid,或三份报告仍找不到稳定配对,样本分别进入 `failed_judge_invalid` 或 `failed_judge_unstable`,顶层运行失败。失败样本不得进入 Gate A 的有效样本分母,也不得以“有效样本不足”掩盖系统失败。
|
||
|
||
### 11.3 敏感临时数据
|
||
|
||
原文、候选正文、完整模型输入和完整模型响应只允许写入 `/private/tmp` 下本次运行的独立 raw vault。批准角色只能是用户/创始人;写入任何 raw 字节前,先在非敏感文件 journal 原子持久化 `vaultLease`,绑定 `authorizationId/approvedBy/runId/vaultId/sourceVersion/contentHashes/createdAt/retainUntil/purpose`。没有有效 lease 不得创建 vault。
|
||
|
||
vault 路径由可信编排器生成不可猜测 ID,拒绝调用方传入绝对路径、`..`、软链接和任何 realpath 逃逸。目录权限固定 0700,文件固定 0600;创建、打开、重命名和清理全程拒绝 symlink 跟随。恢复时先扫描所有未关闭 lease:对应 vault 存在则进入清理流程,不存在则补记关闭回执,禁止留下无 lease 的孤儿 raw 目录。
|
||
|
||
默认在安全摘要和最终状态原子落盘后立即清理 raw vault。只有单独的调试授权记录 `authorizationId/approvedBy/runId/vaultId/sourceVersion/contentHashes/retainUntil/reason` 才可保留,授权不得跨运行复用,最长 24 小时。清理成功前运行不得进入 `completed`;失败进入 `failed_raw_cleanup`,由可信清理器持久重试并保持 vault 隔离,24 小时仍未清除升级为安全事件。任何状态都继续禁止输出 raw path。
|
||
|
||
日志、安全摘要和长期报告不得包含原文、候选正文、完整 prompt/response、raw path、真实臂映射或可反推内容的片段。stderr 不落盘、不回显原文;adapter 只输出稳定失败码、退出码、长度/hash 和预定义受控摘要。
|
||
|
||
### 11.4 运行回执、预算与失败语义
|
||
|
||
每次调用都产生不含正文的 `ExecutionReceipt`,至少记录 `adapterRole/invocationId/requestedModelId/actualModelId/modelMatch/effort/maxBudgetUsdPerCall/totalCostUsd/usage/modelUsage/stopReason/terminalReason/isError/apiErrorStatus/exitCode/durationMs/inputSha256/structuredOutputSha256/jsonSchemaSha256`。CLI 结果未提供完整实际 model ID、`total_cost_usd`、usage、modelUsage、stop reason 或 terminal reason,或任一字段无法归一化时,回执非法,不能把该调用算作成功。
|
||
|
||
`envelope.structured_output` 是唯一业务对象,必须直接通过该角色的严格 JSON schema;`envelope.result` 只作审计和受控错误分类,禁止解析为业务 JSON,也禁止作为 structured_output 缺失时的 fallback。当前 503 探测没有证明 2.1.211 成功响应的 `structured_output` 字段形状;实现前必须完成一次极小成功探测并冻结 envelope schema/hash。该探测未成功前 Gate A 不得启动。
|
||
|
||
调用成功必须联合满足:进程 `exitCode=0`;envelope `type=result` 且 `is_error=false`;`terminal_reason` 属于该角色预注册的正常终止集合;业务输出通过严格 schema;`modelUsage` 能证明实际模型且与请求模型一致;`usage` 结构和数值合法并可核账。`subtype=success` 与 `stop_reason` 只作审计字段,不能覆盖非零退出、`is_error=true`、API error、空 `modelUsage` 或 schema 失败。
|
||
|
||
每个 real-run Gate 启动前都必须单独确认 `totalBudgetUsd`,并在预注册配置中列出 writer、detector、judge 的单次预算、最大调用次数和最坏总额。实际美元成本以 envelope `total_cost_usd` 为权威值,按 JSON 十进制原值解析并统一到 6 位小数、`ROUND_HALF_UP`;若 `modelUsage` 提供分模型 `costUSD`,其同规则求和后必须与权威值一致,否则回执非法。编排器在每次启动前预留最坏预算,累计 `totalCostUsd` 与预留上限都不得超过该 Gate 总预算;缺字段、超总额或 CLI 因预算停止都失败关闭。
|
||
|
||
| 稳定失败码 | 触发条件 |
|
||
|---|---|
|
||
| `{ROLE}_TIMEOUT` | 超过该角色 deadline;取消下游并丢弃迟到输出 |
|
||
| `{ROLE}_NONZERO_EXIT` | Claude CLI 非零退出;stderr 仅转为受控摘要 |
|
||
| `{ROLE}_API_ERROR` | `is_error=true`、`terminal_reason=api_error` 或存在 API 错误状态;不记录网关错误正文 |
|
||
| `{ROLE}_RECEIPT_INVALID` | envelope 或联合回执缺字段、terminal reason 非法、成本无法对账 |
|
||
| `{ROLE}_SCHEMA_INVALID` | CLI 包装、业务输出或报告不符合严格 schema |
|
||
| `{ROLE}_BUDGET_EXCEEDED` | 单次预算停止、累计预算超限或 usage 无法核账 |
|
||
| `{ROLE}_MODEL_MISMATCH` | 实际 model 缺失或与预注册 model 不一致 |
|
||
| `JUDGE_INVALID` | 任一必需 judge 报告非法;第三评委非法时样本直接失败 |
|
||
| `JUDGE_UNSTABLE` | 第三评委后仍无稳定配对 |
|
||
|
||
一个异常只产生一个 `primaryCode`,其余命中项进入不含敏感信息的 `causes[]`。主码优先级固定为:`TIMEOUT > API_ERROR > NONZERO_EXIT > RECEIPT_INVALID > BUDGET_EXCEEDED > MODEL_MISMATCH > SCHEMA_INVALID > JUDGE_INVALID > JUDGE_UNSTABLE`。实测 503 因此归 `API_ERROR`,非零退出、空 modelUsage 和零值 usage 只作 causes。任一失败码都使当前样本 `ok=false`、`acceptanceEligible=false`,并停止该样本后续调用;不得换模型、扩大预算、跳过失败臂或把系统失败降级成普通质量分。
|
||
|
||
### 11.5 文件型 CAS 与原子写
|
||
|
||
离线评测 adapter 不使用内存状态作为真实执行依据。每个运行维护不可变 `states/<revision>.json` journal,`state.json` 固定为当前 revision 的完整内容副本,不是路径指针。revision 至少包含 `runId/sampleId/arm/attempt/candidateVersion/state/revision/previousStateSha256/resultSha256/safeSummarySha256/cleanupState`。
|
||
|
||
状态目录通过已验证父目录 fd 使用 `openat` 与 no-follow 语义访问,拒绝路径替换和 symlink;固定锁文件 `state.lock` 在状态目录内排他创建,并用 `fcntl.flock` 包围读、比较、写全过程。推进时先排他创建 0600 revision 临时文件并 `fsync`,rename 为不可变 revision;再写 0600 `state.json.tmp`、`fsync`、rename 覆盖 `state.json`,最后 `fsync` 状态目录。结果、安全摘要和清理标记先原子落盘,其 hash 随同一 revision 提交,未被 revision 引用的文件不算已提交。
|
||
|
||
旧 revision、旧 attempt、旧 candidateVersion、重复终态和迟到结果统一返回 `CAS_CONFLICT`,不能覆盖较新状态。非敏感 journal 保留到运行审计期结束,使 `previousStateSha256` 可逐版验证。进程崩溃后比较 `state.json` 与不可变 journal,恢复最后一个 schema 合法、hash 链与关联文件 hash 完整的 revision;临时文件、孤儿文件、断链状态、异常锁或未关闭 vault lease 一律先失败关闭并清理,不得继续模型调用。
|
||
|
||
### 11.6 Gate A 绑定
|
||
|
||
Gate A real-run 只允许使用满足本节合同的离线评测 adapter。执行前必须机械证明:成功 structured_output 探测已冻结;Gate A 总预算与单次预算已确认;A/C 执行配置、事实约束和原文字符预算相等;全评测集顺序表平衡;完整上下文 allowlist diff 通过;temperature/topP/seed 为 `unsupported/not_claimed`;三类 schema、oracleTruthPack、GateInputBuilder、泄漏审计与回执测试通过;judge 隔离无法发现 raw、映射和臂名;raw lease、vault 权限/逃逸/保留/清理测试通过;文件 CAS journal 的并发、崩溃和迟到结果测试通过。Gate B 启动前另行预注册并批准独立预算,不得沿用 Gate A 批准。
|
||
|
||
本次设计修订只定义合同,不等于 adapter 已实现,更不等于 Gate A 已运行或通过。真实 `--execute` 在第 10.2 节列出的缺口全部关闭、机械测试通过且预算获批前,必须继续失败关闭。
|
||
|
||
## 12. 用户闭环与下游交接(Gate B 后第二阶段)
|
||
|
||
本节不在 Gate A/B 前实现。Gate B=`passed` 后,Shadow 候选展示才提供三决策:
|
||
|
||
1. 原样接受;
|
||
2. 修改后合并,带 `expectedRevision`;
|
||
3. 丢弃。
|
||
|
||
原样接受和修改后合并都必须经过 `accept_preflight`。修改后合并先生成新 candidateVersion 并重新 detector;原样接受也必须重新校验授权、来源、质量策略、candidate hash 和 `expectedRevision`。通过后才调用 confirm;版本冲突返回 `revision_conflict`,不得静默覆盖。Canonical 提交后异步触发章后抽取,产出知识草稿和冲突队列;正文层只定义交接合同,不直接审批知识入库。
|
||
|
||
## 13. 分阶段实施计划与 SoT 回填
|
||
|
||
**第一阶段:做到 Gate B 裁决、receipt 签发和细纲入口守卫。**
|
||
|
||
1. 实现 A/C 两种原文检索、B 负对照、统一事实约束、相同原文字符预算、全评测集顺序表和完整上下文 allowlist diff。
|
||
2. 实现 writer 生成、真实 semantic detector、evaluator-only oracleTruthPack、隔离 blind judge、逐断言/逐约束 verdict、泄漏审计、混淆项合同、唯一 GateInputBuilder 与 `writer_gate.py` 新裁决顺序。
|
||
3. 实现第 11 节离线 CLI adapter:绝对可执行文件/hash/版本、完整 model ID、sandbox、structured_output、预算/回执、raw lease/vault、文件 CAS 和原子结果。
|
||
4. 在第一阶段实现 `writer_gate.py` 唯一 receipt 签发器和细纲 real-run 入口守卫;覆盖系统失败优先、同 ID verdict、unknown/ID 集失败、gate-report 先落盘、非 passed 不签发、journal/hash 链验签和拒绝自算 JSON 的机械测试。
|
||
5. 用户批准 Gate A 预算后 real-run;通过后另批 Gate B 独立预算并执行。第一阶段不得实现 Shadow、confirm、Canonical 写入、章后抽取或父仓产品化回填。
|
||
|
||
**第二阶段:仅在 Gate B=`passed` 后启动。**
|
||
|
||
6. 使用第一阶段已经实现的入口守卫实际启动细纲 real-run;必须提交由 `writer_gate.py` 签发并通过 journal/hash 链验证的 `writerGateBPassedReceipt`。细纲 dry-run 继续豁免。
|
||
7. 接通 Shadow 三决策、confirm、Canonical 和异步抽取;按父仓 AI Orchestration、Integration Execution Facade、New-API 边界完成产品化,或先评审正式 ADR。
|
||
8. 回填父仓设计、API 契约、schema 和索引,删除重复定义;任务完成后蒸馏并删除本文。
|
||
|
||
## 14. 实施前门禁
|
||
|
||
- 本修订版通过产品流程与技术合同两类独立评审。
|
||
- 用户确认本文为正文智能体实验台任务 SoT。
|
||
- 第 11 节离线评测 adapter 未实现前,真实 `--execute` 保持失败关闭;设计评审通过不代表实现完成。
|
||
- Gate A real-run 前,用户明确批准总预算、三类单次预算、最大调用次数和 raw 最长保留期。
|
||
- Gate B real-run 前,按其样本集另行批准独立总预算、三类单次预算、最大调用次数和最坏总额。
|
||
- writer、semantic detector、blind judge、oracleTruthPack、GateInputBuilder、Gate B receipt 签发器与细纲入口守卫的严格 schema、隔离、回执、路径安全、文件 CAS 和失败码均有机械测试证据。
|
||
- Gate B 未通过,禁止实现或接入 Shadow/confirm/Canonical/章后抽取产品路径,禁止父仓产品化回填。
|
||
- `writer_gate.py` 只为 passed Gate B 报告签发不可变 receipt;细纲 real-run 必须通过 journal/hash 链验签,拒绝自算 JSON;dry-run 明确豁免。
|
||
- 独立范式抽取继续运行,但不得与正文实现共享改动文件或进程。
|
||
- 细纲真实回放保持暂停,直到正文 Gate B 通过。
|