diff --git a/.trae-html-share-packages/scripts/create-cloudbird-agent-app.html.zip b/.trae-html-share-packages/scripts/create-cloudbird-agent-app.html.zip index 2caa849..b5cf63e 100644 Binary files a/.trae-html-share-packages/scripts/create-cloudbird-agent-app.html.zip and b/.trae-html-share-packages/scripts/create-cloudbird-agent-app.html.zip differ diff --git a/.trae-html-share-packages/scripts/create-verifier-app.html.zip b/.trae-html-share-packages/scripts/create-verifier-app.html.zip index 4983cdf..c63a385 100644 Binary files a/.trae-html-share-packages/scripts/create-verifier-app.html.zip and b/.trae-html-share-packages/scripts/create-verifier-app.html.zip differ diff --git a/specs/IR-0006/absorption-map.md b/specs/IR-0006/absorption-map.md new file mode 100644 index 0000000..c1b685b --- /dev/null +++ b/specs/IR-0006/absorption-map.md @@ -0,0 +1,50 @@ +# 总纲 v1.0 吸收落位表 + 词汇归并表(IR-0006 附件一) + +> 状态口径:**已覆盖**=现有机制直接映射,总纲该章吸收为引用(不新建); +> **本 IR 吸收**=六波次内落盘;**延后**=明确非目标,触发条件成熟后另行立项。 +> 铁律:凡标"已覆盖"的章,禁止平行新建同类对象(防双 SSOT——ADR-0103 决策 6)。 + +## 一、18 部分落位表 + +| 总纲部分 | 落点 | 状态 | 说明 | +|---|---|---|---| +| 第一部分 背景(三条产品线/两铁律/基础设施盘点) | REPOS.yaml 各仓 role + GOVERNANCE risk_posture | 已覆盖 | 公司形态与资产盘点=组织地图既有职责;两铁律吸收为本表注释 | +| 第二部分 目标函数(注意力最小化/风险旋钮/两支柱) | 宪法 §0/§7 + metrics.yaml | 已覆盖 | 注意力会计已在跑(签署耗时/needs-human p90);注意力硬预算=W2-C3(human_minutes 入卡) | +| 第三部分 整体架构(五层平面+五回路+三横切) | ADR-0103 决策 2(三面分离) | 本 IR 吸收 | 五层平面收编为声明/执行/判定三面;五回路中 R3/R5=R4/R5 波次补建 | +| 第四部分 宪法八条 I1-I8 | constitution.md v2.3 条款 | 已覆盖(I3/I7 扩展) | I1=AR-3+runs;I2=ghcb/arbiter/conductor;I3=W2-C3/C4(票据入卡);I4=GOVERNANCE 分域表 W1 增补;I5=holdout 仓+红队+诱饵;I6=portability 段+EX-1;I7=W2-C3+metrics;I8=C1/ADR/元测试/drill | +| 第五部分 对象模型(Wave+六 manifest) | card issue+wave-plan(扩展非新建) | 本 IR 吸收 | Wave≡卡+波次计划(schema 扩展);Tenant=tenant tag;AgentRole≡ROLE-*.md;Gate≡policy/testing.yaml+g060;Sandbox≡env 定义仓;Channel≡投影体系第四投影;>6 kind 维持暂缓 | +| 第六部分 控制平面(broker 六职能/propose-dispose/JIT/污点) | ADR-0103 决策 2/4/5 + providers.yaml+dispatch+gh-app-token | 本 IR 吸收 | broker=逻辑契约非物理咽喉;propose-dispose 已覆盖;JIT=W2-C2/C4;污点标记延后(随 inbound) | +| 第七部分 执行基座(Job Contract/放置策略/云电脑池/否决多账号) | ADR-0103 决策 4 + providers.yaml 新条目 | 本 IR 吸收 | 织物分界=GitHub 能启动的不自建;池化以服务器为锚;多账号轮换维持否决 | +| 第八部分 门禁体系(分类+元治理+路书治理) | gate.yml/adversary/holdout/drill/metrics.yaml | 已覆盖 | 门禁四列指标=metrics 北极星对既有体系扩展(W6-M1 评审);docs-as-tests 承 test-navigation.sh | +| 第九部分 AI 能力开发 MLOps(两类交付物/优化波次/合成数据血统) | holdout 仓扩展(eval registry) | 本 IR 吸收(W5) | 复用 wave/gate/evidence 三件套;评测基建先于优化循环(投资顺序纪律不变) | +| 第十部分 Harness 与 Swarm(四条缝/conformance/swarm 编制) | 暂缓清单 + W6-M1 语料种子 | 已覆盖(暂缓不变) | 四条缝=AGENTS.md/MCP/Wave+证据包/broker 票据——前三已在位;conformance suite 种子 W6;自建判据 ≥3 次妥协不变 | +| 第十一部分 界面层飞书(三职责/铁律/声明方式) | W3-F(outbound 多维表格) | 本 IR 吸收 | outbound-only;inbound/污点/审批回写延后另行立项 | +| 第十二部分 多租户与潮玩公司 | tenant tag(W1-B2)+资产登记簿 | 本 IR 吸收(窄面) | 仅计量先行+登记簿;分家工程/可分离部署验收测试延后 | +| 第十三部分 治理外输产品化(三层/编译器/签名证据包) | 延后 | 延后 | 内部跑通后另行立项;签名证据包 v0 承 SC-4 在 W4-R3 先落地基 | +| 第十四部分 R3 运行回路(环境管理/SLO/值班/反馈边) | W4-R + sli-weekly | 本 IR 吸收 | drift 模式泛化;责任边界文件在首个托管客户前写死 | +| 第十五部分 治理元环(学习机制/continuity) | runs 报告+ADR+drill 已覆盖;决策语料 W1-D1 | 已覆盖(+1 新件) | 治理回归测试=drill 既有语义;决策语料=唯一新增资产 | +| 第十六部分 风险清单 | SECURITY.md+risk_posture+本表 | 已覆盖 | 各风险行均有既有缓解机制锚点(见 governance 各条款) | +| 第十七部分 路线图 P0-P3 | wave-plan.md(六波次重排) | 本 IR 吸收 | 按内部跑通优先重排;原 P0-P3 与 W1-W6 映射见波次计划头部 | +| 第十八部分 待决参数(风险刻度/分钟预算/责任边界) | ADR-0103(已裁决)+W2/W4 | 本 IR 吸收 | 裁决模型已裁决;分钟预算先跑数据后定(W2-C3 前提);责任边界 W4-R2 | + +## 二、词汇归并表(总纲词汇 → 现有机制,防双 SSOT) + +| 总纲词汇 | 归并到 | 动作 | +|---|---|---| +| Wave | card issue + wave-plan.md | 扩展 schema(budget/capabilities/evidence 字段),不新建 kind | +| Capability Broker / Egress Proxy | providers.yaml + dispatch 经纪人 + gh-app-token + 内网服务器路由 | 升级不重建(逻辑契约,分域物理适配) | +| 证据账本 | metering(ADR-0062)+ butler audit + drill history 三源统一 → archive 仓 evidence/ | 合并不另立(hash 链平移) | +| Channel manifest | label→board 投影体系第四投影(飞书多维表格) | 延用 label 唯一真源 | +| Sandbox manifest | env 定义仓(新建) | 新建(三面分离的声明面载体) | +| AgentRole | docs/agent/ROLE-*.md + ghcb 入口协议 | 已覆盖,不新建 kind | +| Gate 注册表 | governance/policy/testing.yaml + g060 锁 | 已覆盖 | +| 风险等级 risk_class / Profile | 参数包选择器(门禁集/entitlement 档/介入点) | 新概念吸收为参数包,非裁决输入(ADR-0103 决策 1) | +| Holdout / eval registry | holdout 仓(扩展四元组 pin+非劣性 gate) | 扩展不新建 | +| 收件箱(五类决策+SLA) | metrics 注意力会计 + 飞书投影 | 部分已覆盖,human_minutes 入卡补全 | +| Job Contract | 内网调度器契约(W2-C1) | 新建(执行面基础设施,非 harness) | +| 决策语料 | archive 仓 append-only 文件 + 链式 hash | 新建(本 IR 唯一无先例资产) | + +## 三、退役规则 + +总纲 v1.0 原文不进 git(git 外文档不具权威);其内容经本表全部映射后,讨论过程中的 +任何总纲副本视为草稿,权威以落点文件为准。本表自身是 C1 资产:修正走 PR+ADR。 diff --git a/specs/IR-0006/run-suite.sh b/specs/IR-0006/run-suite.sh new file mode 100755 index 0000000..d58ae62 --- /dev/null +++ b/specs/IR-0006/run-suite.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# 套件执行器(adversary 目标目录契约):bash run-suite.sh +# impl-dir 须含 spec.md(被审"实现"= spec+附件文档对);exit 0 = 全绿。 +# IR-0006 形态:治理总纲吸收 spec(条款+落位表+六波次总图),本套件断言 +# spec 结构完整性(AC 三段/条款唯一/附件在场/落位 18 行/波次六段)—— +# 攻击面=伪造"结构齐全但内容空洞"的文档对(红队 S1'/S2' 语义)。 +set -euo pipefail +DIR="$(cd "$(dirname "$0")" && pwd)" +IMPL="${1:?用法: run-suite.sh }" +[[ -f "$IMPL/spec.md" ]] || { echo "impl 目录缺 spec.md: $IMPL" >&2; exit 2; } +PY="${METERING_PYTHON:-}" +if [[ -z "$PY" ]]; then + PY=python3; command -v python3 >/dev/null 2>&1 || PY=python +fi +TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT +mkdir -p "$TMP/specs/IR-0006/suite" +cp "$DIR"/suite/*.py "$TMP/specs/IR-0006/suite/" +cp -- "$IMPL/spec.md" "$TMP/specs/IR-0006/spec.md" +for f in absorption-map.md wave-plan.md; do + [[ -f "$IMPL/$f" ]] && cp -- "$IMPL/$f" "$TMP/specs/IR-0006/$f" || true +done +cd "$TMP/specs/IR-0006/suite" +IMPL_DIR="$TMP/specs/IR-0006" "$PY" test_spec_ir0006.py diff --git a/specs/IR-0006/spec.md b/specs/IR-0006/spec.md new file mode 100644 index 0000000..27daa1f --- /dev/null +++ b/specs/IR-0006/spec.md @@ -0,0 +1,194 @@ +--- +taskId: IR-0006 +specVersion: 1 +title: 治理总纲吸收——三面分离治理架构、证据账本统一与云内网入图(条款级规格+六波次总图) +irRef: Cloudbird-Software/.github#402 +adrRef: archive/adr/ADR-0103-governance-charter-absorption-three-plane-separation.md +acceptanceReport: specs/IR-0006/acceptance.md +amendments: +- rev: 1 + reason: 首版——owner 2026-08-29 会话 11 项锁定决策全集(ADR-0103 背书);AC 自 IR#402 十条期望变化逐条派生;总纲 v1.0 分散吸收不立独立文档 +acceptanceCriteria: +- id: AC-1 + given: 总纲 v1.0 十八部分章节与现有治理机制的映射关系 + when: 检查 specs/IR-0006/absorption-map.md 与本 spec PR 的红队审计 + then: 落位表覆盖 18 个部分(每行含落点/状态:已覆盖-直接映射、本 IR 吸收、延后-另行立项三类之一)且词汇归并表含 Wave/Broker/证据账本/Channel 四项等价映射;spec PR adversary check verdict=survived。运行时证据:adversary check run URL + absorption-map.md diff + 红队审计 issue 记录 +- id: AC-2 + given: ADR-0103 已按家园单仓化流程落 archive 仓 + when: gate adr-required 与 drift-check §10 对 ADR-0103 的解析 + then: archive/adr/INDEX.yaml 含条目 103(content_sha256 与正本一致)且正本可达、lifecycle=active;宪法 §5(硬谓词+shadow)语义在 ADR-0103 与 constitution.md 中均未被推翻。运行时证据:INDEX.yaml diff + drift-check §10 run 日志 +- id: AC-3 + given: 判定层账本载体落 archive 仓(evidence/ 目录)且证据 schema v1 定稿 + when: 对判定层写入与月度归档做核验 + then: 判定/轨迹/丢弃三层分离落 schema;payload 内联上限 4KB 超限拒写;hash 链头与月度 checkpoint 可由独立脚本复算验证(链断=红);tenant 字段存在于每条判定记录。运行时证据:checkpoint 验证 run 的 JSONL 日志 + 账本目录 tree +- id: AC-4 + given: metering(ADR-0062)/ butler audit / drill history 三源事件存量 + when: 三源对齐改造完成后的统一查询 + then: 三源新事件可按同一 schema 查询(对齐 OTel gen_ai.* 字段命名),card-meta 为 join key;原 JSONL 只读保留可回退(平移不搬移);tenant tag 注入到 metering 归账。运行时证据:统一查询 run 的 JSONL 输出 + 三源文件 diff(只增不改) +- id: AC-5 + given: 云内网(公网服务器+云电脑池+Vault+LLM 路由)为事实生产工厂 + when: 治理版图申报与漂移检测 + then: providers.yaml 含 self-cloud-pool 与 vault 条目(entry=服务器调度器,removal 声明同 CNB 模式);env 定义仓按 flows.new_repo 建仓并申报 REPOS.yaml(layer/visibility/role/key_paths);drift-check 对新申报面零漂移。运行时证据:providers.yaml/REPOS.yaml diff + drift-check run 日志 + env 仓建仓记录 +- id: AC-6 + given: PM 会话已在云电脑上运行且个人 PAT 分布多机 + when: PM 凭证收敛完成后的日常写仓操作 + then: PM 的 GitHub 凭证由内网服务器代签 cloudbrid-agent 短令牌(gh-app-token 机制上收,单仓作用域);个人 PAT 退出日常流程;应急回退通道(App 失效→owner PAT,24h 窗口)文档化。运行时证据:服务器令牌签发的 JSONL 记录 + TTL 到期收回断言日志 +- id: AC-7 + given: 飞书多维表格作为 factory-floor 投影载体 + when: 投影运行与 drop & rebuild 演练 + then: 多维表格每行一卡(字段=状态/关卡/认领者/停留时长),数据源=label 唯一真源;整表删除后单轮同步内重建且字段一致;人工在表格上的修改被下一轮投影纠正(label 为准并告警)。运行时证据:rebuild 演练 run 日志 + 纠正实测记录 + 飞书 API 调用账本 +- id: AC-8 + given: env repo 存期望态(环境定义/镜像/allowlist)且云内网上报实况 + when: R3 漂移对账与 SLO 周报 + then: 期望态与实况偏差触发漂移 issue(泛化 governance-drift 模式,自动开/自动关);SLO 骨架进 sli-weekly;责任边界文件(SLO 定义/值班范围/破线升级路径/break-glass)落盘——在第一个托管客户出现之前。运行时证据:drift run 日志 + sli-weekly 报告 issue + 责任边界文件 diff +- id: AC-9 + given: card issue 模板扩展 budget/capabilities/evidence 字段 + when: 一张带波次预算的卡触发预算硬停 + then: conductor/cost-check 消费波次级预算(usd/tokens/wallclock/human_minutes)按 subject 聚合自统一账本;超限硬停+熔断标记;/elevate 评论走 arbiter 策略表(elevation 记录进账本)。运行时证据:预算超限硬停实测的 issue 记录 + cost-check run 日志 +- id: AC-10 + given: holdout 仓扩展为 eval registry 且决策语料开始记录 + when: 首个 wave.kind=optimization 波次收口与语料累积 + then: eval registry 条目四元组 pin(代码+数据集+提示+模型)+ 非劣性 eval gate(不得比基线差超 δ)走通;决策语料文件(情境→选项→决策→理由→后果)append-only 落 archive 仓且不可篡改(链式 hash)。运行时证据:eval gate run 记录 + 语料 JSONL 及其 hash 链校验 run +blastRadius: +- repo: Cloudbird-Software/.github + path: specs/IR-0006/(新增 spec/wave-plan/absorption-map/suite) +- repo: Cloudbird-Software/.github + path: governance/(providers.yaml、REPOS.yaml、policy/ 账本条款、ISSUE_TEMPLATE 卡模板) +- repo: Cloudbird-Software/archive + path: adr/(ADR-0103)、evidence/(判定层账本)、runs/、决策语料 +- repo: Cloudbird-Software/CI-Workflows + path: pipeline/metering/(三源对齐、tenant tag 注入) +- repo: Cloudbird-Software/ + path: 新仓(环境定义:拓扑/镜像/allowlist) +nonGoals: +- 不做治理编译器/policy rego 重写(GOVERNANCE.yaml intent/platform 分离已是手写编译器,演进不重写) +- 不建物理统一 egress 单点(broker=逻辑契约,物理分域适配) +- 不自建 harness(调度器=执行面基础设施≠harness;≥3 次妥协触发判据不变) +- 不做多账号 key 轮换(已否决,合规是护城河) +- 不做飞书 inbound 意图通道(污点标记/typed intent 延后另行立项) +- 不做外输三件套产品化(Profile/Policy Pack/Conformance Report——内部跑通后另行立项) +- 不做小模型训练与复杂 swarm 拓扑 +- 不做潮玩公司完整分家工程(仅计量 tenant tag 先行) +inv: | + INV-01 判定语义不随本次吸收改变:risk_class 仅参数包选择器(门禁集/entitlement 档/ + 人工介入点),放行裁决仍硬谓词白名单+shadow 域解锁(宪法 §5 原样不动,ADR-0103 决策 1)。 + INV-02 判定锚点永不外置:云内网池与 CNB 同为可删除层;删除后 gate/org-gate/conductor + 语义不变(EX-1 延伸,ADR-0103 红线重申)。 + INV-03 append-only:判定层账本与决策语料只追加不改写;三源改造保留原 JSONL 只读 + (平移不搬移);ADR-0062 hash 链机制平移且链断=红。 + INV-04 凭据纪律:key 只存 org secret/Vault,agent 上下文零凭据;PM 令牌收敛不改变 + 此边界(服务器代签≠凭证进上下文)。 + INV-05 label 唯一真源:飞书多维表格=物化视图,可 drop & rebuild;投影与 label 漂移 + 时以 label 为准并告警(宪法 §12 延伸)。 + INV-06 payload 指针纪律:判定层只存结论+指针,内联上限 4KB;轨迹层原始体只落内网 + blob,git 只存 sha256 摘要+指针+保留策略(ADR-0103 决策 3)。 +budget: | + BUDGET-01 判定层存储护栏:archive 仓 evidence/ 年增长软上限 200MB(gzip 后), + 超限开 governance-debt issue 而非静默扩容——账本膨胀本身是漂移信号。 + BUDGET-02 保留策略声明位:hot(90d)/warm(1y)/digest-only 三级+checkpoint 月度节奏 + 声明在 governance/policy/(可 drift 对账、红队可审);调整走 C1。 + BUDGET-03 波次预算四元组(usd/tokens/wallclock/human_minutes)真源=卡 issue 模板 + 字段,cost-check 按统一账本 subject 聚合执法(超限硬停承 ADR-0040 复位流程)。 + BUDGET-04 本 IR 建设期消耗按 tenant=solo-co 归账(tenant tag 生效后追溯注入)。 +decision: | + DECISION-01 裁决模型调和:旋钮管配置不管裁决(ADR-0103 决策 1);外输语言= + 参数包+谓词白名单+域解锁进度清单,非风险分。 + DECISION-02 三面分离:声明面=Git/执行面=内网+GitHub+CNB 多域/判定面=GitHub 恒定 + (ADR-0103 决策 2);云内网=执行域+证据冷存储层。 + DECISION-03 证据三层承 ADR-0003 过程数据三分离:判定层 archive 仓永久/轨迹层内网 + blob+摘要指针/丢弃层 GitHub 原生保留(ADR-0103 决策 3)。 + DECISION-04 执行织物分界:GitHub 能启动的一律 GitHub Actions;自建调度器只承载 + PM 长驻会话与需内网资源作业;池化以公网服务器为锚(唯一出入口+调度+票据签发) + (ADR-0103 决策 4)。 + DECISION-05 PM 凭证收敛 App 短令牌+JIT 分发由服务器承担;个人 PAT 退出日常 + (应急回退通道保留)(ADR-0103 决策 5)。 + DECISION-06 总纲分散吸收:18 章节落位表+词汇归并表为本 spec 附件;不立独立总纲 + 文档;已覆盖机制直接映射防双 SSOT(ADR-0103 决策 6)。 + DECISION-07 飞书 outbound-only 多维表格投影;inbound 延后(ADR-0103 决策 7)。 + DECISION-08 建设时序内部跑通优先;潮玩公司仅计量 tenant tag 先行(ADR-0103 决策 8)。 +--- + +# IR-0006 条款正文 + +本 spec 把《治理战略总纲 v1.0》按 ADR-0103 的裁决分散吸收进现有治理结构。 +三个附件分工:[absorption-map.md](absorption-map.md)(18 章节落位表+词汇归并表—— +总纲内容的唯一去向清单)、[wave-plan.md](wave-plan.md)(六波次建设总图—— +本 IR 的执行计划)。本正文只立条款:不变量、行为、接口、预算、决策、假设。 + +## 条款 + +- **INV-01 裁决语义恒定**(AC-1/AC-2 承接):risk_class 仅参数包选择器,放行裁决仍硬谓词+shadow(宪法 §5 不动)。任何把裁决语义参数化的条款变更=违宪,须新 ADR 推翻 §5 才可提出。 +- **INV-02 判定锚点不外置**(AC-3/AC-5 承接):云内网池为可删除层,removal 声明同 CNB 模式(REMOVAL 清单+删除后语义不变断言)。 +- **INV-03 append-only 三处**(AC-3/AC-4/AC-10 承接):判定层账本、决策语料、三源原 JSONL——只追加;hash 链平移(ADR-0062);链断=红(fail-closed)。 +- **INV-04 凭据纪律**(AC-6 承接):服务器代签令牌仍单仓作用域+短 TTL;agent 上下文零凭据边界不变(AR-2 延伸)。 +- **INV-05 label 唯一真源**(AC-7 承接):飞书表格=第四投影(宪法 §12 三投影之外新增),人工修改被下轮纠正。 +- **INV-06 payload 指针纪律**(AC-3 承接):内联 ≤4KB 超限拒写;轨迹层 git 只存摘要+指针+保留策略。 +- **BEH-01 账本写入路径**(AC-3 承接):判定事件(gate 裁决/成本/审批/决策)经统一发射器写 archive evidence/,字段对齐 OTel gen_ai.* 语义约定;写入失败=fail-closed(同 butler-audit 守卫模式)。 +- **BEH-02 月度 checkpoint**(AC-3 承接):每月末对判定层做 checkpoint(链头 hash+当月汇总)提交 git;独立验证脚本可从任意旧 blob 复算整链。 +- **BEH-03 三源渐进对齐**(AC-4 承接):metering/butler/drill 新事件按 schema v1 双写过渡期一个波次,验证一致后旧格式停写;原文件冻结只读。 +- **BEH-04 云内网对账**(AC-5/AC-8 承接):env repo 存期望态;服务器上报实况快照;drift 引擎泛化(GitHub org 对账→环境对账),偏差开 issue、消除自动关(GM-1 模式复用)。 +- **BEH-05 令牌签发与收回**(AC-6 承接):服务器按 wave 生命周期签发短令牌(TTL≤波次);TTL 到期自动收回;elevation 走 arbiter 策略表(附理由+spec 引用,批准记录进账本)。 +- **BEH-06 投影同步与重建**(AC-7 承接):同步器周期(≤15min,同 butler-ledger 节奏)从 label 真源重建表格差异;drop & rebuild 单轮完成;漂移告警进账本。 +- **BEH-07 波次预算硬停**(AC-9 承接):cost-check 从统一账本按 subject 聚合四元组预算;超限置熔断+撤 auto-merge+开 issue(ADR-0040 复位流程不变)。 +- **BEH-08 非劣性 eval gate**(AC-10 承接):optimization 波次的 exit gate=eval 家族(非劣性检验不得比基线差超 δ+污染检查+成本/延迟回归);四元组 pin 进 registry。 +- **IFACE-01 证据记录 schema v1**(AC-3/AC-4 承接):`{subject:{wave,card,tenant,commit}, actor:{identity,role,model}, action, verdict, cost:{tokens,usd,wall_sec}, inputs_digest, payload_ref?, ts}`;字段命名对齐 OTel gen_ai.*;schema 文件落 standards/。 +- **IFACE-02 providers.yaml 新条目**(AC-5 承接):`self-cloud-pool`(kind: compute,entry=服务器调度器,secrets=[]——凭据在内网域 Vault,非 org secret)与 `vault`(kind: secret,entry=内网 Vault,标注"仅执行面内网域生效")。 +- **IFACE-03 卡模板扩展**(AC-9 承接):card 模板新增 `budget:`(四元组+on_exceed)与 `capabilities:`(allowlist 式 org secret/Vault 引用)字段;conductor 解析存储、cost-check 消费。 +- **IFACE-04 多维表格 schema**(AC-7 承接):字段=卡 ID/状态/AC 进度/关卡状态/认领者/停留时长/谓词状态;与 factory-floor 板字段同源(宪法 §12 投影一)。 +- **IFACE-05 env 定义仓结构**(AC-5/AC-8 承接):`environments/*.yaml`(拓扑/镜像/网络 allowlist/secret 引用非值/资源上限)+ `reports/`(实况快照落点)。 +- **BUDGET-01 判定层存储护栏**:见 frontmatter。 +- **BUDGET-02 保留策略声明位**:见 frontmatter。 +- **BUDGET-03 波次预算真源**:见 frontmatter。 +- **BUDGET-04 建设期归账**:见 frontmatter。 +- **DECISION-01..08**:见 frontmatter decision 块(ADR-0103 逐条承接)。 +- **ASSUMPTION-01** 云内网服务器上报通道可用(不可用=对账 fail-closed 转 issue,不静默)。 +- **ASSUMPTION-02** 飞书开放平台 API 配额满足 15min 级投影刷新(不足则降级为小时级,多维表格为物化视图不受损)。 +- **ASSUMPTION-03** 云电脑池 worker 可承受无状态约束(任何持状态负载一律拒置内网池——同 CNB 定位纪律)。 + +## 测试设计(逐类讨论,ADR-0095 一等公民) + +判断口径:每个测试映射三类风险之一(customer_upgrade_failure / llm_behavior_drift / fake_tests)。 + +### active_now + +- **T-01 属性(unit_property_golden)— adopt**:证据 schema v1 记录做属性测试(必填字段/枚举值/ISO 时戳/payload ≤4KB 不变量)——映射 fake_tests 风险(摆拍账本)。suite 本 PR 先锁 spec 结构属性;实现波次锁记录属性。 +- **T-02 race — adopt**:判定层并发追加幂等(同事件双写=一条+审计行);checkpoint 验证与追加并发不死锁——映射 fake_tests。 +- **T-03 泄漏 — adopt**:账本/语料/轨迹摘要中扫描 secret 模式(gitleaks 复用)+ holdout 诱饵内容出现在任何账本记录=报警——映射 llm_behavior_drift 与凭据纪律。 +- **T-04 模糊 — adopt**:schema 解析器对畸形输入 fuzz(未知字段不崩、缺字段拒收、超限 payload 拒写)——映射 fake_tests。 +- **T-05 文档示例 — adopt**:absorption-map.md 与 wave-plan.md 中出现的命令/路径引用做可执行校验(导航断链=test-navigation.sh 同款)。 +- **T-08 flaky — reject**:本 IR 断言全部确定性(账本/声明面),无网络依赖断言;飞书投影测试用录制 fixture。 +- **T-09 差分 — reject**:非重写项目(无新旧实现并存面);三源对齐用对账而非行为差分。 +- **T-10 变异 — adopt**:实现波次的判定/预算逻辑(checkpoint 验证、预算聚合)做变异测试(承宪法 §4A 三档阈值)。 +- **T-12 diff 覆盖 — reject**:治理仓无产品代码面,沿现有 gate 语义。 +- **T-13 测试完整性 — adopt**:本 suite 即 spec 结构完整性的机器断言(AC 三段/条款唯一/附件在场)。 +- **T-14 卡绑定+suite 门 — adopt**:本 spec PR 自身受 T-14 约束(suite 随 PR、CI 真实执行);实现卡卡绑定走 conductor。 +- **T-15 意图回探 — adopt**:acceptance.md 验收时逐条回探 IR#402 十条期望变化(ROLE-ACCEPT 对账基准)。 + +### 条件激活族 + +- **L-01..L-04(eval/semantic golden/蜕变/对抗语料)— reject**:本 IR 不改变任何 LLM 判定链行为(verifier/adversary 不动);L 族属 R5 optimization 波次届时激活。 +- **L-05 成本时延 — adopt(窄)**:判定层账本写入路径与投影刷新的时延断言(预算旋钮 K/pivots 不变,承 automation-limits verifier 档先例)。 +- **L-06 换模型差分 — reject**:同上,无判定模型变更。 +- **R-01..R-06(升级/回滚/迁移幂等/抓 golden)— adopt(R-02/R-03 窄面)**:PM 凭证收敛有回退形态(App 失效→PAT 应急);三源 schema 迁移幂等(双写过渡+可回退);其余 reject(无系统重写)。 +- **G-01 契约漂移 — adopt**:providers.yaml/REPOS.yaml/env 定义与线上实况对账即本 IR 的 drift 面(BEH-04)。 +- **G-02..G-08 — reject**:无真实依赖集成/DAST/bench 面(治理仓无运行时服务;内网调度器 W2 建成时另行补充)。 + +### rejected 清单(X-01..X-06) + +不启用任何 X 族条目(如全局覆盖率门槛)——维持 testing.yaml 声明的拒绝态;启用须先走治理变更(ADR)。 + +## holdout 测试设计(ADR-0095 必备) + +封存验收场景三条(payload 由 verifier-app 经 `scripts/holdout-register.sh` 注册至 +holdout 仓,W1 内完成;本 spec 只设计场景不携带内容——防泄题): + +1. **HO 账本篡改检测**:对判定层账本注入一条被篡改记录(改 verdict 不改链),验证 checkpoint 复算必红(fail-closed 活体证明)。映射 fake_tests。 +2. **HO 投影重建保真**:对多维表格注入人工违规修改(绕过 label 真源改字段),验证下轮投影必纠正且告警进账本。映射 llm_behavior_drift(投影漂移)。 +3. **HO 凭证边界**:PM 令牌 TTL 过期后持旧令牌写仓必拒;elevation 无理由请求必拒。映射 customer_upgrade_failure(凭证失效面)。 + +注册后 spec/卡引用仅 `id@sha8` 形态;泄漏监控承 holdout 仓既有诱饵机制(I5 延续)。 + +## 验收对账 + +acceptance.md(W6 收口)按 T-15 逐条回探 IR#402 十条期望变化+冷上下文六问复测 +(a-f 六问有真实来源可答,主链路零假链——IR-0005 AC-7 同款)。 diff --git a/specs/IR-0006/suite/test_spec_ir0006.py b/specs/IR-0006/suite/test_spec_ir0006.py new file mode 100644 index 0000000..d944e26 --- /dev/null +++ b/specs/IR-0006/suite/test_spec_ir0006.py @@ -0,0 +1,174 @@ +"""IR-0006 spec 结构自测(suite/——T-14:spec PR 必含非空测试文件且含真实断言)。 + +零第三方依赖(frontmatter 用正则解析,不 import yaml——本地 gates-pr 与 CI 同语义)。 +校验:frontmatter 完整、AC 十条三段俱全且带运行时证据、条款唯一、三附件在场 +(spec/wave-plan/absorption-map)、落位表 18 行、词汇归并四等价、波次六段各带退出判据。 +""" +import re +import unittest +from pathlib import Path + +BASE = Path(__file__).resolve().parents[1] +SPEC = BASE / "spec.md" +MAP = BASE / "absorption-map.md" +PLAN = BASE / "wave-plan.md" +IR_ITEM_COUNT = 10 # IR #402 期望变化十条 → AC-1..AC-10 + + +def _fm_text(): + text = SPEC.read_text(encoding="utf-8") + m = re.match(r"^---\n(.*?)\n---\n", text, re.S) + assert m, "frontmatter 定界符缺失或未闭合" + return m.group(1), text + + +def _fm_key(fm, key): + m = re.search(rf"^{key}: (.+)$", fm, re.M) + assert m, f"frontmatter 缺 {key}" + return m.group(1).strip() + + +def _fm_block(fm, key): + m = re.search(rf"^{key}: \|\n(.*?)(?=^\w[\w-]*: |\Z)", fm, re.M | re.S) + assert m, f"frontmatter 缺 {key} 块" + return m.group(1) + + +def _fm_list_block(fm, key): + """捕获顶层 key 下的多行列表块(条目可跨行),止于下一个顶层键。""" + m = re.search(rf"^{key}:\n((?:(?!^\w[\w-]*: ).*\n?)*)", fm, re.M) + assert m, f"frontmatter 缺 {key} 列表块" + return m.group(1) + + +class TestFrontmatter(unittest.TestCase): + def test_identity(self): + fm, _ = _fm_text() + self.assertEqual(_fm_key(fm, "taskId"), "IR-0006") + self.assertTrue(int(_fm_key(fm, "specVersion")) >= 1) + self.assertEqual(_fm_key(fm, "irRef"), "Cloudbird-Software/.github#402") + self.assertIn("ADR-0103", _fm_key(fm, "adrRef")) + + def test_blocks_nonempty(self): + fm, _ = _fm_text() + for key in ("inv", "budget", "decision"): + block = _fm_block(fm, key) + self.assertGreaterEqual(len(block.strip()), 40, f"{key} 块过薄") + self.assertIn("INV-01", _fm_block(fm, "inv")) + self.assertGreaterEqual( + len(re.findall(r"DECISION-\d+", _fm_block(fm, "decision"))), 6, + "decision 块不足 6 条") + + def test_nongoals(self): + fm, _ = _fm_text() + items = [l for l in _fm_list_block(fm, "nonGoals").splitlines() if l.startswith("- ")] + self.assertGreaterEqual(len(items), 5, "nonGoals 过少") + + def test_blastradius(self): + fm, _ = _fm_text() + items = [l for l in _fm_list_block(fm, "blastRadius").splitlines() + if l.startswith("- repo:")] + self.assertGreaterEqual(len(items), 3, "blastRadius 仓面过少") + for l in items: + self.assertIn("path:", _fm_list_block(fm, "blastRadius"), "blastRadius 条目缺 path") + + +class TestAcceptanceCriteria(unittest.TestCase): + def _ac_block(self): + fm, _ = _fm_text() + return _fm_list_block(fm, "acceptanceCriteria") + + def test_count_and_ids(self): + ids = re.findall(r"^- id: (AC-\d+)$", self._ac_block(), re.M) + self.assertEqual(len(ids), IR_ITEM_COUNT, f"AC 数 {len(ids)} != {IR_ITEM_COUNT}") + self.assertEqual(ids, [f"AC-{i}" for i in range(1, IR_ITEM_COUNT + 1)], + "AC 编号不连续") + + def test_three_segments_and_evidence(self): + blocks = re.split(r"(?=^- id: AC-\d+$)", self._ac_block(), flags=re.M) + acs = [b for b in blocks if b.startswith("- id:")] + self.assertEqual(len(acs), IR_ITEM_COUNT) + for b in acs: + aid = re.match(r"- id: (AC-\d+)", b).group(1) + for seg in ("given", "when", "then"): + self.assertRegex(b, rf"{seg}: .+", f"{aid} 的 {seg} 段为空") + then = re.search(r"then: (.+)", b).group(1) + self.assertIn("运行时证据", then, f"{aid} 缺运行时证据子句") + self.assertTrue( + any(w in then for w in ("run", "日志", "JSON", "JSONL", "记录", "diff", "issue")), + f"{aid} 运行时证据未指向具体工件类型") + + +class TestBodyClauses(unittest.TestCase): + def test_clauses_unique(self): + _, text = _fm_text() + body = text.split("---", 2)[2] + # 兼容两种仓内样式:`- **INV-01** 标题…` 与 `- **INV-01 标题**…` + defs = re.findall( + r"^- \*\*((?:INV|BEH|IFACE|BUDGET|DECISION|ASSUMPTION)-\d+)(?:[^*\n]*)\*\*", + body, re.M) + self.assertGreaterEqual(len(defs), 20, f"正文条款过少: {len(defs)}") + self.assertEqual(len(defs), len(set(defs)), + f"条款定义重复: {[k for k in defs if defs.count(k) > 1]}") + + def test_key_clauses_present(self): + _, text = _fm_text() + for anchor in ( + "INV-01 裁决语义恒定", "INV-06 payload 指针纪律", "BEH-02 月度 checkpoint", + "BEH-07 波次预算硬停", "IFACE-01 证据记录 schema v1", + ): + self.assertIn(anchor, text, f"缺关键条款 {anchor}") + + def test_test_design_covers_categories(self): + _, text = _fm_text() + self.assertIn("测试设计", text, "缺测试设计节(ADR-0095 一等公民)") + self.assertIn("holdout 测试设计", text, "缺 holdout 设计节") + for cat in ("T-01", "T-02", "T-03", "T-04", "T-05", "T-08", "T-09", + "T-10", "T-12", "T-13", "T-14", "T-15"): + self.assertIn(cat, text, f"测试设计缺 active_now 类 {cat}(逐类讨论不完整)") + for fam in ("L-05", "R-02", "G-01"): + self.assertIn(fam, text, f"测试设计缺条件激活族 {fam}") + + +class TestAbsorptionMap(unittest.TestCase): + def test_exists_and_sections(self): + self.assertTrue(MAP.is_file(), "absorption-map.md 缺失") + text = MAP.read_text(encoding="utf-8") + self.assertIn("落位表", text) + self.assertIn("词汇归并表", text) + rows = re.findall(r"^\| 第\w+部分", text, re.M) + self.assertGreaterEqual(len(rows), 18, f"落位表仅 {len(rows)} 行(须 18)") + for status in ("已覆盖", "本 IR 吸收", "延后"): + self.assertIn(status, text, f"落位表缺状态类 {status}") + + def test_vocabulary_equivalences(self): + text = MAP.read_text(encoding="utf-8") + m = re.search(r"## 二、词汇归并表.*?(?=\n## )", text, re.S) + self.assertIsNotNone(m, "词汇归并表节缺失") + for word in ("Wave", "Capability Broker", "证据账本", "Channel"): + self.assertIn(word, m.group(0), f"词汇归并缺 {word}") + self.assertIn("扩展 schema", text, "Wave 归并未声明扩展现有对象(防新建 kind)") + + +class TestWavePlan(unittest.TestCase): + def test_six_waves_with_exit(self): + self.assertTrue(PLAN.is_file(), "wave-plan.md 缺失") + text = PLAN.read_text(encoding="utf-8") + for i in range(1, 7): + self.assertIn(f"## W{i} ", text, f"缺波次 W{i}") + self.assertEqual(text.count("退出判据"), 6, "每波次须有退出判据") + + def test_card_count(self): + text = PLAN.read_text(encoding="utf-8") + cards = re.findall(r"^\| W\d-[A-Z]\d", text, re.M) + self.assertGreaterEqual(len(cards), 15, f"波次卡仅 {len(cards)} 张(须 ≥15)") + + def test_w1_covers_four_tracks(self): + text = PLAN.read_text(encoding="utf-8") + m = re.search(r"## W1 .*?(?=\n## W2)", text, re.S) + for track in ("W1-A", "W1-B", "W1-C", "W1-D"): + self.assertIn(track, m.group(0), f"W1 缺 {track} 线") + + +if __name__ == "__main__": + unittest.main() diff --git a/specs/IR-0006/wave-plan.md b/specs/IR-0006/wave-plan.md new file mode 100644 index 0000000..bfab579 --- /dev/null +++ b/specs/IR-0006/wave-plan.md @@ -0,0 +1,77 @@ +# IR-0006 波次计划(六波次总图) + +> 依赖:W1 →(W2 ∥ W3)→ W4 → W5 → W6;W1 内 A/B/C/D 四线可并行(A 是 B/C 的法律基础)。 +> 与原总纲 P0-P3 映射:P0≈W1、P1≈W2、P2≈W3/W4、P3≈W5/W6——按"内部跑通优先"重排。 +> 波次内每卡独立小 PR(C1 路径:PR+ADR 引用+owner merge);治理变更不需要卡, +> 但涉及仓外执行面(内网/CNB)的卡按 ROLE-IMPLEMENT 走 dispatch/自建调度器。 + +## W1 地基(本 IR 主体) + +| 卡 | 内容 | 关键 AC | +|---|---|---| +| W1-A1 | absorption-map.md + wave-plan.md + spec 正文/suite 落盘(本 PR) | AC-1 前半:落位表 18 行+词汇归并;红队 survived | +| W1-A2 | 宪法 v3 修正 PR:按落位表把 I3/I4/I7 扩展条款吸收进 constitution.md(§5 不动=硬边界);GOVERNANCE.yaml 增账本/保留策略条款 | AC-1 后半;adr-required 引用 ADR-0103 | +| W1-B1 | 证据 schema v1 定稿(standards/,对齐 OTel gen_ai.*)+ archive 仓 evidence/ 判定层载体 + checkpoint 机制与验证脚本 | AC-3:payload ≤4KB 拒写、链断=红、tenant 字段 | +| W1-B2 | 三源对齐:metering/butler/drill 新事件按 schema v1 双写过渡(BEH-03)+ tenant tag 注入 metering 归账 | AC-4:统一查询可跑、原 JSONL 只读 | +| W1-B3 | 轨迹层指针协议:内网 blob 引用约定(sha256+指针+保留策略字段)+ 热数据先留内网本地的最小实现 | AC-3 轨迹层面:git 侧只见摘要 | +| W1-C1 | providers.yaml 增 self-cloud-pool/vault 条目 + 资产登记簿(repo/密钥/额度/环境归属+license 边界)| AC-5 前半:条目在场+removal 声明 | +| W1-C2 | env 定义仓建仓(flows.new_repo)+ REPOS.yaml 申报 + environments/*.yaml 骨架(拓扑/镜像/allowlist) | AC-5 后半:drift 对新申报面零漂移 | +| W1-D1 | 决策语料 append-only 文件 + 链式 hash + 记录约定(情境→选项→决策→理由→后果) | AC-10 后半:语料开始累积 | + +退出判据:判定层可写可验(checkpoint run 绿);三源统一查询一条命令出结果;drift 对 env 仓/self-cloud-pool 零漂移;决策语料 ≥1 条真实记录。 + +## W2 控制平面成形 + +| 卡 | 内容 | 关键 AC | +|---|---|---| +| W2-C1 | 内网调度器 v0(服务器侧 Go):Job Contract 消费+worker 池内短票据签发+egress allowlist+无状态约束执法 | AC-5 执行面:worker 不直连公网、持状态负载拒置 | +| W2-C2 | PM 凭证收敛:gh-app-token 上收服务器代签(单仓+短 TTL)+ 应急回退通道文档化 | AC-6:PAT 退出日常、TTL 到期收回实测 | +| W2-C3 | Wave schema 入卡:card 模板 budget/capabilities/evidence 字段 + conductor 解析 + cost-check 波次视图(subject 聚合自统一账本)+ human_minutes 预算 | AC-9 前半:预算超限硬停实测 | +| W2-C4 | JIT elevation v0:/elevate 评论→arbiter 策略表(附理由+spec 引用;批准记录进账本) | AC-9 后半:无理由必拒(HO 场景 3) | + +退出判据:一张真实带预算的卡走完"超限硬停→复位";PM 用服务器代签令牌完成一次全流程写仓;elevation 有账本记录。 + +## W3 界面层(飞书 outbound) + +| 卡 | 内容 | 关键 AC | +|---|---|---| +| W3-F1 | 飞书多维表格投影:factory-floor 每行一卡(IFACE-04 字段)+ 同步器(≤15min,BEH-06)+ 调用账本 | AC-7 前半:投影运行 | +| W3-F2 | 重建保真与漂移纠正:drop & rebuild 演练 + 人工违规修改被纠正实测 + holdout HO 场景 2 注册 | AC-7 后半:单轮重建一致 | + +退出判据:多维表格连续一周无人工干预自同步;rebuild 演练绿;漂移告警进账本。 + +## W4 运行回路 R3 + +| 卡 | 内容 | 关键 AC | +|---|---|---| +| W4-R1 | env repo 期望态+实况上报+drift 引擎泛化(GitHub org 对账→环境对账;偏差开 issue/消除自动关) | AC-8 前半 | +| W4-R2 | SLO 骨架进 sli-weekly(复用 sli-report.sh 扩数据源)+ 责任边界文件(SLO/值班/破线/break-glass) | AC-8 后半:首个托管客户前写死 | +| W4-R3 | 签名证据包 v0:部署产物 attestation+SBOM(承 SC-4 provenance 先例)绑定 evidence/ 判定记录 | AC-8 附加:部署可回溯 | + +退出判据:一次环境变更从期望态 diff→漂移 issue→修复→自动关闭全链路;SLO 周报含环境面。 + +## W5 能力回路 R5 + +| 卡 | 内容 | 关键 AC | +|---|---|---| +| W5-E1 | eval registry:holdout 仓扩展四元组 pin(代码+数据集+提示+模型)+ 非劣性 eval gate 家族(δ 阈值+污染检查+成本/延迟回归) | AC-10 前半 | +| W5-E2 | 首个 optimization wave:wave.kind=optimization 走 transitions 状态机,exit gate=eval 家族(BEH-08) | AC-10 中段:非劣性 run 记录 | + +退出判据:一个真实优化目标(任一产品仓既有能力)从基线评测→优化→非劣性通过全链路,四元组 pin 可复现。 + +## W6 元环与收口 + +| 卡 | 内容 | 关键 AC | +|---|---|---| +| W6-M1 | conformance 语料库种子:30-50 张已完成卡回放语料(初始快照+目标+密封验收)+ 门禁元治理四列指标评审(metrics 扩展) | AC-1 联动:胜出实践晋级机制首跑 | +| W6-M2 | R3→R1 反馈边骨架:运行信号(错误/用量/SLO)自动生成候选 spec 入 backlog(走 R1 的门) | AC-8 联动 | +| W6-M3 | acceptance.md 汇总(T-15 逐条回探十条)+ 冷上下文六问复测 | 全 AC 收口 | + +退出判据:IR#402 十条期望变化逐条有运行时证据;六问复测 a-f 全有真实来源;acceptance.md 合并后 IR 可置 done(T9 谓词)。 + +## 变更分级提示 + +- W1 全部/W2-C3/C4/W3/W6:C1 路径(PR+ADR 引用,多数引用 ADR-0103 即可)。 +- W2-C1/C2、W4:涉及内网执行面建设,卡上须声明 capabilities 与 placement(自建域), + 判定与验收仍锚 GitHub(INV-02)。 +- 新仓(env 定义仓):走 flows.new_repo + GM-4 申报(W1-C2)。