返回设计文档

EVIDENCE · 05/08

Five-Bucket Evidence

Core、engines、aiskills、memory、golden 的 active contract。

真相源
docs/DESIGN_五桶证据.md
读取方式
构建时本地读取
规模
455

Status: active Scope: nexrur substrate Evidence Traceability: GitHub issues #10, #26, #42, #95, #212 Updated: 2026-08-19

本文只定义底座通用 Evidence 能力。任何 App 名、产品名、业务阶段名、领域字段、 来源分类和模型供应商都不属于本文真相。

1. 定义

Evidence 把当前执行需要的事实整理成五桶:

内容读取原则
coreoutcome、manifest、core audit只读 App 合同声明的 core sources
enginesorchestrator、campaign、ToolLoop 运行事实只读允许的底座/核心账本
aiskills已投影的业务资产和显式 extra sources只执行 aiskills read plan
memory已登记 memory source 与选择结果backend 状态由运行 envelope 显式提供
golden已审核 Diagnosis 案例与显式历史事实只读登记的 Golden 资产

Evidence 不判断业务成败,不诊断根因,不选择 Campaign 路由,也不决定资产晋升。

2. 唯一公开入口与固定内部链

App 和 App orchestrator 只允许调用一个 Evidence 公开入口:

nexrur_evidence_obligations

nexrur_step6_evidence_obligations 只是同一入口在 Step 6 state 下的语义别名, 不是第二套 Evidence runner。Bundle、五个 Reader 和 Digest 是底座内部受审计 子链,不得暴露为 App phase,也不得要求 App 按顺序分别调用。

每次公开调用必须闭合以下内部链:

Obligations public facade
  -> Bundle
       -> read core
       -> read engines
       -> read aiskills / materialize required lanes
       -> read golden candidates
  -> Digest
       -> digest core / engines / aiskills
       -> read and digest memory
       -> select and digest golden
  -> deterministic obligation assembly
  -> handoff schema/identity validation
  -> Projection
  -> success receipt

已有 Bundle/Digest 只有在 identity、state、trace/cycle、source hashes 和完整性 receipt 全部一致时才可幂等复用。缺 Bundle 必须补跑 Bundle;缺 Digest 必须补跑 Digest。不存在“没有 Digest 也继续组装 Obligations”的合法路径。

2.1 公开状态与 fail-closed

公开状态条件handoff是否可继续
success全部 required 子链完成,handoff 验证与 Projection 成功必须存在
degraded只有 optional source 缺失,且 App 合同显式允许该降级必须标记 degraded仅在 App 显式授权时
failedrequired 缺失,或任一内部执行、Digest、身份/状态、handoff 验证、Projection 失败禁止产生可用 handoff

partialmissing_required 可作为 Reader/内部 finding,但不得被顶层包装为 success 或默认允许下游继续。未显式声明 degraded 继续策略的 App 默认 fail closed。Active 只验证并晋升已闭合的产物,不补跑 Bundle、Digest 或 Obligations。

3. 显式 Evidence envelope

底座只认以下通用身份:

current_scope:
  product: <opaque product key>
  asset_band: <optional opaque band>
  asset_id: <optional>
  canonical_id: <optional>
  subject_id: <optional>
  trace_id: <required when writing trace>
  run_id: <optional>
  step_run_id: <optional>
  target_subagent: <optional opaque owner>
  target_module: <optional opaque module>
  target_step: <optional opaque step>
  current_artifact_refs: []
  memory_backend_status:
    backend: <opaque backend>
    read_status: <opaque status>
    write_status: <opaque status>
    degraded: false
    degraded_reason: null
    source: engines

规则:

  • orchestrator/ToolLoop 在 Evidence 边界构造 current_scope
  • reader 可以把顶层同名通用字段规范化进 current_scope
  • 不允许从目录名、phase 名、结果字段名或历史文件内容推断 product、asset 或 step;
  • App 私有身份别名只能声明在 App 的 evidence.yml::identity_aliases
  • 别名缺失时不猜;别名配置损坏时 fail closed;
  • 同时出现冲突状态或冲突身份时 fail closed。
  • subject_idcanonical_idasset_id 是三个独立身份;除非 App 在 identity_aliases 显式声明,否则任何一个都不得冒充另一个。
  • identity_aliases 只把 App 原始字段名归到同一个通用身份,不允许把 subject_idcanonical_idasset_id 三种通用身份互相匹配;任一同时存在的 身份或 trace/run 身份冲突都必须拒绝该记录。
  • LLM usage attribution 只写真实 asset_id;unbound 请求写 trace_id,不得把 subject/canonical 填进 asset_id 记账字段。
  • 包级公共 scope 编译接口只有 compile_current_scope(...);Evidence 不提供 runtime-object marshal、旧 payload adapter 或第二套 schema alias 翻译。

4. Evidence state

允许的通用状态只有:

evidence
step6_evidence
restart_evidence

provenance_lane 必须与 evidence state 相同。App 风格状态名、历史 phase 状态名和 隐式映射全部禁止。

通用 ToolLoop callable 可以通过其明确身份选择默认状态:

  • regular Evidence callable -> evidence
  • Step 6 Evidence callable -> step6_evidence

其他 callable 必须显式传 state。

5. App Evidence contract

Canonical path:

<app>/.gemini/skills/_shared/engines/evidence/evidence.yml

底座只解析通用结构:

version: 1

identity_aliases: {}

core:
  sources: []

engines:
  sources: []

aiskills:
  sources:
    - name: aiskills_projection_contract
      enabled: true
      required: true
      projection_contract_path: .gemini/skills/_shared/engines/projection/projection.yml
  summary_fields: []
  extra_sources:
    <current_product>:
      <source_id>:
        product: <explicit source product>
        target_steps: []
        root: <explicit template>
        files: []
        copy: true

memory:
  sources: []

golden:
  sources: []

obligation_targets: []

App 拥有:

  • source 名称、路径模板、业务字段和 source taxonomy;
  • identity aliases;
  • aiskills summary fields;
  • extra source 的 product、target steps、root、files、copy 策略;
  • obligation targets 与 declaration 内容;
  • memory backend 的实现与状态产生。

底座不得提供上述内容的 App 默认值。

纯 optional source 缺失只进入 degraded_optional_sources,不把 bundle readiness 降为 partial;否则 fresh Product 在尚无历史 Core/Engines/AIskills/Memory 时会被 自己锁死。optional empty bucket 仍写 empty receipt 并继续,required source 不可用仍然 fail closed。LLM profile/model 路由不属于 App,由 llm.yml 按 稳定 caller role 统一声明。

6. core reader

core reader 只允许已登记的通用 artifact type:

  • outcome_json
  • manifest_json
  • core_audit_jsonl

读取顺序:

  1. 显式 artifact/evidence refs;
  2. 当前 scope 约束下的合同路径;
  3. 无 scope 时 required source 不得靠全局扫描通过。

reader 输出 bounded content unit、artifact ref、source report 和 scope report。它不解释 业务字段,不根据字段名推断状态。

7. engines reader

engines reader 只读底座允许的运行账本根和 App 合同声明的 source。它按 trace_id/run_id/step_run_id 过滤当前执行,不读取历史目录补事实。

规则:

  • 模板越过允许根时 fail closed;
  • 超限文件只输出索引和明确 degraded 原因;
  • JSONL 先按 current scope 过滤,再生成 bounded unit;
  • 不从 runtime 记录推断 App 产品或业务 phase。

8. aiskills reader

aiskills reader 必须消费 aiskills_read_plan。没有 plan 直接 failed,不允许恢复 全局 glob 或旧 business/local reader。

read plan 至少包含:

state: evidence|step6_evidence|restart_evidence
scope:
  product: <explicit>
  asset_id: <explicit when bound>
  trace_id: <explicit when writing>
  target_step: <explicit when selectors need it>
upstream: []
reference: []
current:
  include_active: <true only when asset_id exists>
diagnosis: {}

额外规则:

  • projection product 由 App step/orchestrator 显式传入;
  • extra_sources 每项必须有 product
  • target_steps selector 时,current_scope.target_step 必须存在;
  • reader 不得把 phase 当 product,也不得从路径猜 product;
  • upstream/diagnosis raw lanes 通过 Projection trace 原子写入;
  • materialization receipt 可幂等复用,但损坏或半提交必须 fail closed;
  • reference 只作候选上下文,不冒充 active truth。

9. memory reader

memory reader 消费 core/engines/aiskills 三个 primary bucket 的 digest context,再执行通用 program/LLM 选择链。它不探测 provider key、环境变量或 App 本地模型配置。

运行 envelope 必须显式提供 current_scope.memory_backend_status。缺失时返回 degraded:

explicit_memory_backend_status_missing

任何 LLM 选择器或仲裁器都必须使用稳定的 caller role;具体 profile、provider、 model 和 Flash/Pro 路由只由 llm.yml 声明。App payload 不得覆盖该路由。

Memory 只调用 evidence.yml::memory.sources 中显式启用的 store。每个 source 必须声明 artifact_typeroot_type: memory_storeretrieval_mode: store_apiconfig_pathstore_path;不得探测默认目录,也不得在 backend unavailable 时先调用 store 再补一个 degraded 标签。LLM 输出 schema、候选 ID 或状态不合法时 fail closed,不能静默过滤坏 ID 后继续。

10. golden reader

Golden 只读已审核 Diagnosis 资产或 App 显式声明的历史 source:

  • positive case;
  • counterexample;
  • pattern。

Diagnosis assets root 必须由 payload 或 App contract 显式提供。底座不从目录布局猜根。 候选文件损坏、索引冲突、路径越界或 hash/span 不一致时 fail closed。

Golden ref 与普通 business evidence ref 必须分槽:

  • golden_artifact_refs:selector/audit;
  • artifact_refs/evidence_refs:production/diagnosis facts。

Golden 不能被当作当前业务事实。

11. digest

digest 只压缩 bounded reader units:

  • core 与 engines 互不依赖,可使用通用 Flash digest prompt 并行压缩;两路 计算完成后必须按 canonical bucket 顺序串行执行 Projection 原子写入;
  • aiskills upstream/diagnosis raw truth 不二次改写,只生成 reference digest;
  • memory 必须先执行程序 gate,再由 Flash 选择;只有 Flash 与程序结果冲突时 才进入 Pro 仲裁,最后用 Flash 生成 memory digest;
  • golden 只用 Flash 生成 selector digest,不做常驻 Pro 仲裁。

每个被请求的 bucket 都必须落一个 digest receipt;合法空桶写 deterministic empty receipt,不能因为没有 content unit 就消失。AIskills 空桶仍写 aiskills/reference.json,不得恢复同级 aiskills.json。Memory 的 Flash/Pro 选择结果必须把 program candidate pool 完整划分为 selected/rejected;Golden 同样必须把所有 eligible cards 完整划分,重复、交叉或遗漏均 fail closed。

具体 provider/profile 的能力声明与路由解析只能来自 llm.yml。Evidence Python 只提交稳定 caller role,不 hardcode provider、model 或 App 默认值;App 也不传 Evidence 专用 profile/model 覆盖底座路由。

调用要求:

evidence_state: <explicit>
current_scope: <explicit>

禁止:

  • provider/model 默认值;
  • key/env 探测;
  • use_flash 之类 provider 选择旁路;
  • Evidence 专用 max_output_tokens、按 unit 数估算输出上限,或在 Evidence 中截断 LLM 输出;
  • 领域 claim/formula/operator/slot preservation 规则;
  • App source type 白名单;
  • 把 oversized 原文直接塞进 LLM。

LLM 的 provider 输出能力、续写/重试和统一输出策略归 LLM 底座。Evidence 不传 专用输出上限;它只在返回后验证每个 input unit 都有且只有一个对应输出。 如果底座最终返回不完整结果,Digest fail closed,不用 Python 补写或伪造覆盖。

输入“裁剪”只允许是可审计的去重、哈希、结构化索引、retrieval 或 chunking; 禁止字符串静默截断。oversized source 只能进入 App 声明的 memory/index 能力, 返回 bounded retrieval;无法安全路由时 fail closed。

12. obligations 与 Step 6

App 通过 obligation_targets 声明要携带的 obligation。底座只做机械 envelope:

obligations:
  <target without _obligations suffix>:
    source: app_obligation_declaration
    truth_source: app_manifest
    declaration: {}
    evidence_refs: []
    source_digest_refs: []

底座不得内置某一种业务 obligation。

Step 6 diagnosis packet 只从显式通用字段组装:

  • phase_failure_facts
  • production_failure_facts
  • validation_facts
  • runtime_failure_facts
  • phase_issue_facts
  • schema_errors
  • requires_diagnosis

禁止扫描任意 *_result、按字段名猜 validation、从 phase history 找 reason,或读取 App 私有结果名。reason code 只能来自显式 failure facts。

builder 不得修改调用方 payload。多个显式 evidence state 冲突时 fail closed。 Diagnosis packet 的 source_phase 只能来自显式 current_scope.target_step 或 显式 source_phase;不得从 failed_phase 或目录名反推。

13. Projection 与 unbound trace

Evidence 不手写 ai-skills 目录。所有 trace/digest/handoff 写入通过通用 Projection:

  • 未出生资产写 <product>/<trace_id>/...
  • 已绑定资产写 <product>/<asset_id>/<trace_id>/...
  • bind 成功后才承认 asset id;
  • archive/bind 由授权动作执行;
  • Evidence 不决定何时 bind 或 archive。

Evidence handoff 和 digest 在资产未出生时立即写入 trace scope;不存在 deferred handoff,也不存在资产出生后由 Orchestrator 回头补写 Evidence 的 finalizer。 projection_identity 必须随 handoff 明确记录 scope/product/trace_id/cycle_no; 只有真实 asset_id 存在时才允许 scope: asset

写入必须原子、幂等、冲突失败,禁止复制出双份真相。

14. 公开接口与内部模块

App-facing ToolLoop 公开接口只有 nexrur_evidence_obligations,以及指向同一 callable 的 Step 6 语义别名。下列 Python 模块可供底座内部组合、聚焦测试和 显式导入,但它们不是 App ToolLoop 的八个公开 phase:

build_evidence_bundle
build_evidence_digest
build_obligations
compile_current_scope
read_core_artifacts
read_engines_artifacts
read_aiskills_artifacts
read_memory_artifacts
read_golden_artifacts

内部子链可以使用各模块的 run(...),但必须由 Obligations facade 按本文 固定顺序编排,并保留每个子链的 deadline、audit 和 receipt。__init__.py 不保存 执行逻辑或 Evidence cache。重放、checkpoint、幂等和落盘 receipt 分别由 ToolLoop、Orchestrator 与 Projection 负责。

15. App-neutral 禁止项

nexrur Evidence Python、prompt 和 active substrate contract 禁止出现:

  • App/product/phase 名称及别名;
  • App source taxonomy;
  • 领域 ID、公式、operator、slot、claim 规则;
  • App validation count、业务状态或私有结果字段;
  • 目录名/phase/result 字段猜测;
  • provider 默认值、provider key/env 探测;
  • 旧 business/local/RAG compatibility 接口;
  • fallback success。

App 业务词只允许存在于 App DESIGN、prompt、schema、evidence.yml 和 production callable。

16. 验收

每次 Evidence 改动至少验证:

  1. Python compile;
  2. App evidence/projection/toolloop YAML parse;
  3. 五桶聚焦测试;
  4. 无 plan 的 aiskills reader fail closed;
  5. 缺 product/target step/backend status 或 caller route 未在 llm.yml 声明时按合同失败或 degraded;
  6. state 冲突 fail closed;
  7. materialization 重放幂等,半提交不产 success receipt;
  8. Golden 与普通 evidence ref 分槽;
  9. 代码和 prompt 不包含 App/provider 默认值;
  10. git diff --check 与凭据扫描通过。
  11. bound/unbound handoff 都直接投影,且 subject_id 不会生成假资产目录;
  12. 旧 private scope/asset-birth 标记只能用于 fail-closed 退场测试,active 路径不再 接受它们;不得存在 deferred handoff 或 Evidence 包级 cache。
  13. App 只登记 Obligations,Bundle/Digest/Reader 未出现在 App graph 或 App ToolLoop block;
  14. 缺 Digest、required missing、handoff validation 失败和 Projection 失败均不产 success 或可用 handoff;
  15. resume/replay 只复用 identity/state/source hashes 完整一致的 durable receipt。