# 开发记录：从一条规则到一条证据链

这份记录只整理仓库里已经存在的提交，不补造过去不存在的工作。时间和 commit hash 以公开 Git 历史为准。

## 先把核心问题说小

- `f066212`：先实现最小行为契约评估器，验证调用、结果、重试和写入副作用这些核心关系。
- `6a524f6` / `a8dad80`：补充结构图和事件流程图，帮助审核者先理解边界，再看代码。
- `0ea4993` / `86adcc5`：记录范围决策与验收方式，明确不做 runtime、MCP transport 和云端控制台。

## 让失败真的能被复现

- `81149d5`：增加重复结果、缺少操作 ID 等回归检查，并把 Python 对照示例放进 CI。
- `5d7d030`：收窄 README，只承诺已经存在的结构化结果和离线测试能力。
- `0480e24`：加入仓库助手的读后写 smoke fixture，把“先读后写”变成可执行证据。

## 从规则走向可消费结果

- `fca34de`：增加 `AGC001`–`AGC009` 稳定错误码，未知规则保留 `unknown` 回退。
- `535d416`：把失败工具结果纳入核心检查，并补数据处理场景的回归测试。
- 本轮：增加 `AGC011`，拒绝工具名或 `operation_id` 与同一 `call_id` 不一致的 result，并让该调用不能成为成功结果。
- `306cef1`：修复无效的 MoonBit CI action，改用官方 CLI 安装脚本。
- `1e7c087`：刷新 README、CHANGELOG 和审计记录，让公开材料与代码、测试结果一致。

## 把项目从规则集合扩成工具层

- `4baa41c`：增加 `Trace` 构造器、事件统计和输入预检，把适配器收到的坏数据在语义扫描前明确拒绝；
- `4baa41c`：增加 `RuleSummary`、`SuiteSummary`、场景明细 JSON 和套件汇总 JSON，让多条轨迹的证据可以被 CI 消费；
- `4baa41c`：增加通用 Python 记录 adapter，并把缺字段、非法类型、未知事件的失败路径加入 smoke test；
- `4baa41c`：补充行为契约、验收矩阵、架构说明和申报材料，明确扩展的是验证工具边界，不是重新实现 Agent runtime。

本轮完成后，MoonBit 非测试源码为 537 行，测试源码为 439 行，`moon check` 通过且 32 个测试通过。这个数字用于审计当前规模，不作为单独的质量承诺；质量边界仍由可复现事件、测试和 CI 共同决定。

## 从工具层扩展到可运行的回归工作台

- `f1fc7ed`：增加 `TraceQuery`、`Replay` 和检查点能力，支持按工具/调用/操作检索、逐事件回放和前缀验证；
- `f1fc7ed`：增加 `diff_events` 字段级差分与 `collect_metrics` 风险统计，分别服务版本回归和问题定位；
- `f1fc7ed`：增加 `PolicyProfile`、`QualityGate`、`ScenarioCatalog` 和 `SuiteRunner`，让权限策略、场景选择、运行历史和 CI 门禁有可复用实现；
- `f1fc7ed`：为新增 API 增加 34 个回归测试，包版本推进到 `0.2.0`，同步更新申报材料和验收矩阵。

本轮完成后，MoonBit 非测试源码为 4,242 行，测试源码为 995 行，累计 66 个测试通过。规模增长来自不同职责的可执行模块；仍然不实现 Agent runtime、MCP transport 或模型调用。

## 当前工作方法

每个功能先有一个能说明问题的事件序列，再有 MoonBit 规则和测试，最后才补 Python fixture 或 CI。发现假设不成立时，优先修正规则和测试，不用增加一层空抽象。后续提交继续沿用 `feat`、`fix`、`test`、`docs` 前缀，但提交信息只描述实际发生的变化。

## 策略穿透多场景回归

- 本轮：补齐 `evaluate_scenarios_with_policy`，并让场景目录、质量门禁和 `SuiteRunner` 传递完整 `EvaluationPolicy`；此前它们只传递重试上限，会在回归批次中丢失工具 allowlist。
- 新增允许/拒绝场景、标签选择和单条运行的 MoonBit 回归，确保只读策略下的 `write_file` 保留 `AGC012`，而允许的读取轨迹不受其他场景影响。
- 这项修复不扩张到策略 DSL、外部授权或 Agent runtime；它只使已有离线策略在用户实际调用的套件入口与单轨入口一致。

## 策略来源成为可归档证据

- 本轮：新增 `PolicyContext` 与 `evaluation_report_json`，将策略的非空接入配置来源、allowlist、重试上限和违规明细放入同一稳定 JSON 证据；空来源固定报告 `AGC017`。
- 策略来源由接入方配置提供，不能从待检 trace 读取；这避免日志自述扩大权限，仍不引入外部权限服务或 Agent runtime。

## 写入完成必须回指同一调用

- 本轮：补齐 `write-complete` 的元数据关联检查。此前成功 result 仅按 `call_id` 使写入通过，错配的工具名或 `operation_id` 可以借用那次成功。
- 现在错误路径固定产生 `write-call-mismatch`（`AGC016`）；MoonBit 测试覆盖工具名和业务操作错配及正常路径，Python 离线 fixture 保持同一判断。
- 这是事件证据链的完整性修复，不增加 Agent runtime、传输层或外部副作用执行能力。

## CI 在编译前固定格式边界

- 本轮：在 MoonBit job 的 `moon check` 前加入 `moon fmt --check src main`，同时覆盖核心库和可运行验收 demo；
- 选择复用本地已执行的官方 MoonBit 格式检查，而非新增格式化工具或脚本，避免引入依赖和第二套规则；
- 格式漂移会在编译、测试和 demo 前立即失败，使公开复现路径与本地验收命令保持一致。

## 重复调用不能重定义证据链

- 本轮：重复 `call_id` 曾会覆盖已记录的 tool 和 `operation_id`，使后续 result 或 `write-complete` 能匹配错误的第二条 call；现改为保留首个 call，重复记录只报告既有的 `duplicate-call-id`。
- 新增 MoonBit 与 Python 离线回归：第二条 call 试图把文件写入改成邮件发送时，结果与写入分别固定报告 `result-call-mismatch`、`write-call-mismatch`，不能借用成功。
- 该修复只收紧不可信遥测的身份关联，不限制不同 call ID 的异步结果顺序，也不增加 Agent runtime 或外部状态。

## Responses 适配同样固定首个调用身份

- 本轮：Responses adapter 曾会在重复 `function_call.call_id` 时覆盖内部字段映射；后续 output 因而可能被映射为第二条记录的工具和业务操作，与核心评估器的首个身份规则矛盾。
- 现在适配器保留所有原始 call 事件供核心报告重复 ID，但仅用首条 call 回填 output；MoonBit 回归与 Python 离线 fixture 都检查该 output 仍映射为 `write_file` / `export-47`，评估结果只留下 `duplicate-call-id`。
- 这只修复已观测 Responses 字段的离线映射一致性，不接入 API、JSON 解析、执行器或 Agent runtime。

## 验收整改与 0.2.0 发布

- `1e6dc10`：将仓库中不完整的 Apache 许可证摘录替换为 Apache 官方完整 2.0 文本；GitHub 现可识别 SPDX `Apache-2.0`。
- `551b093`：在 CI 中单列 `moon build`，让验收清单中的构建证据清楚可见；最低版本、格式、构建、检查、测试和可运行 demo 均由 MoonBit job 验证。
- `554bd08`：刷新 0.2.0 发布说明与审计材料；该提交对应的 MoonBit 和 Python CI jobs 均通过。
- 发布 Mooncakes `2515050242/moonagentcheck@0.2.0`；registry manifest 将其标记为 latest 且 build success。随后在隔离消费方中安装包、import `src` 并真实调用 `Event::new` 与 `evaluate`，`moon run cmd/main` 成功。
- 本轮没有修改申报书，也没有把离线 fixture 描述为真实 Agent runtime 或线上系统测试。

## Responses 混合输出保持行为边界

- 十月范围聚焦在完整 Responses 输出序列中区分工具行为与普通消息内容；`message`、`reasoning` 不代表工具调用，不应进入核心事件评估。
- MoonBit 适配器新增显式非工具项标记，只跳过已支持的两类项目；其他项目类型保留输入索引并报告映射问题。
- 新增混合输出和未支持类型的回归用例，并扩展现有 Python fixture。示例不含用户数据，也不连接模型或网络。

## 未知工具结果不能被判为通过

- 本轮针对 Responses `completed` 仅表示输出项结束、不能证明业务执行成功这一边界，补上未知结果本身的失败关闭规则 `unknown-result`（`AGC018`）。
- MoonBit 核心与 Responses 适配器回归验证 `ok: null` 会产生违规，归档报告为 `passed: false`；诊断摘要也将其列为错误。
- 本次规则目标由开发者确定，AI 辅助实现、测试与文档整理，开发者复核结果并承担提交责任。

## Responses 轨迹提供可复现输入

- 为适配器补充四条人工构造的 JSON 遥测样例：明确成功、未知 outcome、没有前置调用的 output、未支持的输出类型；字段和预期结果都可直接检查。
- `operation_id` 与 `outcome` 明确标为应用侧遥测字段，不冒充 Responses API 原生字段，也不把样例描述为真实用户日志。Python fixture 读取 JSON 并逐条核对预期，GitHub Actions 单独展示该步骤。
- 本次问题与验收目标由开发者确定；AI 辅助样例、校验代码和说明整理，开发者负责最终复核和申报判断。

## 申报定位引用 MoonBit 生态现状

- 按 2026-10-09 可见的 Mooncakes 发布页和上游 README 核对 workflow、agent-sdk、OpenTelemetry 的职责与版本，记录各自定位及与 MoonAgentCheck 的邻接处。
- 申报摘要承认局部重叠，不作“没有相似项目”的排他性断言；同时写明本仓库尚未集成这些包。来源和核对日期保存在生态对照文档。
- 本次核对范围由开发者确定；AI 辅助检索、对照和摘要整理，开发者复核事实并负责最终申报判断。

## 发布包与开发线版本对齐

- Mooncakes 包页在 2026-10-09 标记 `0.2.0` 为 latest；十月分支 `moon.mod` 改为 `0.3.0`，并在 changelog 中标记为未发布。
- README、申报材料、验收矩阵与路线图统一说明两者的区别。没有执行包发布或创建 GitHub release；未发布分支功能不归入公开 `0.2.0`。
- 版本状态由开发者确认，AI 辅助来源核验和文字同步；开发者对提交材料负责。

## 十月验收：JSON 入口与已发布包消费检查

- 修正 README 和架构说明中“没有 CLI”的过期描述，明确仓库 JSON 入口接入 Responses 适配器与 MoonBit 评估器，核心库本身不读写文件。
- 为 JSON 入口增加混合 message/reasoning、非法 JSON、错误字段类型的回归；正常场景、unknown-result 和不支持输出已有独立检查。
- 新增隔离的 MoonBit 消费方 fixture，固定从 Mooncakes 获取 `0.2.0`，通过公开 API 评估事件；CI 将其复制到仓库目录之外再构建和测试。
- MoonBit 96 项回归、格式检查、构建、静态检查、验收演示、5 个 Python→MoonBit fixture 和 Mooncakes 消费方测试均通过 GitHub Actions。
- 当前包页仍标记 `0.2.0` 为 latest；消费方检查只验证该已发布版本，不将 `0.3.0` 开发线描述成已发布。
- 首次消费方 CI 因注册表索引未刷新而无法解析固定版本；在 job 中加入 `moon update` 后，后续完整 CI 通过。结果见[GitHub Actions](https://github.com/2515050242/moonagentcheck/actions/runs/39393485493)。
- 本次目标与验收范围由参赛者提出；AI 辅助实现回归用例、消费方 fixture 和文档整理，结果以公开 CI 和可复现命令为准。

## 十月工具链验证更新至 0.10.16

- 将三个 CI job 的安装版本集中为 `0.10.16+b1a0e846e`，版本检查比较完整编译器版本号。
- 按 0.10.16 格式器将 `Int` 标注规范化为 `Int32`，并调整相应换行；规则行为保持不变，96 项回归通过。
- 格式、构建、静态检查、演示、5 个 Python→MoonBit fixture、已发布包独立消费与打包检查均在 0.10.16 下通过。
- 更正 README 与验收矩阵中的旧版本表述，将 0.10.14 结果明确保留为历史记录。工具链验证结果与赛事强制版本要求分别按实际证据说明。

## 申报正文与验收复现入口统一（2026-10-20）

- 将当前申报正文统一到 `docs/项目申报书.md`，旧链接保留为入口；公开副本不列出个人联系方式。PDF 从同一正文生成，渲染检查为一页。
- 修正旧的 89 项测试与 Python 参考评估表述，统一为 96 项 MoonBit 回归及 5 个实际调用 MoonBit CLI 的 Python fixture。
- 增加验收指南：区分轨迹通过、正确拒绝负例和进程正常退出，索引十月实现提交与三个 CI job。已发布包仍为 0.2.0，0.3.0 尚未发布。
- 在 Windows 验证中确认 Git 自动换行会干扰格式检查，Python 默认编码会影响子进程日志解码；复现说明加入保留 LF 的克隆方式与 Python UTF-8 模式。格式检查、96 项 MoonBit 测试和 5 个 Python→MoonBit fixture 均重新通过。
- 本次范围由参赛者提出，AI 辅助文档整理与自动验证；不将这些检查写成人工逐行审核。

## 0.3.0 发布版本（2026-10-21）

- 发布材料统一到 0.3.0，保留九月 0.2.0 与 2026-10-20 验证快照的真实范围和日期。
- 独立消费方固定依赖 0.3.0，通过安装包公开 Responses API 验证明确成功通过、未知 outcome 产生 AGC018 并拒绝通过；两项测试与源码 96 项分开计数。
- 继续使用 0.10.16+b1a0e846e，Python fixture 实际调用 MoonBit CLI。发布与安装验证入口见[发布说明](releases/0.3.0.md)，对应 CI 结果按最终提交查看。
- 范围由参赛者提出，AI 辅助消费测试、发布材料和自动验证；没有补造人工逐行审核记录。
