diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 472e2e7..512ce21 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,138 @@ # Contributing to OperCerta -**English** | [简体中文](CONTRIBUTING.zh-CN.md) +
+简体中文 + +感谢你帮助改进 OperCerta。所有贡献都应保留项目的核心属性:LLM 输出可以辅助 +调查和解释,但高风险业务写入必须由确定性规则、人工审批和数据库约束控制。 + +## 开始之前 + +- 新建 Issue 前先搜索已有 Issue 和 Pull Request,避免重复。 +- 修改 Agent 状态模型、审批边界、持久化模型、公开 API 或依赖架构前,先建立 Issue 讨论。 +- 每次变更只解决一个明确问题。 +- 示例只使用合成或匿名数据。 +- 禁止提交凭据、token、私有地址、客户记录或原单位机密材料。 + +## 开发环境 + +推荐使用 Linux 或 WSL2、Docker Compose v2、由 `uv` 管理的 Python 3.12, +以及 Node.js 24。 + +```bash +git clone https://github.com/KXHXK/opercerta.git +cd opercerta + +uv sync --frozen --all-groups + +cd web +npm ci +``` + +本地运行时需要把 `.env.compose.example` 复制为 `.env.compose`,将占位符替换为 +仅本地使用的值,然后按照 [README 快速启动](README.md)操作。 + +## 开发流程 + +1. 从最新 `main` 创建分支。 +2. 复现问题或先增加失败测试。 +3. 实现最小且完整的修改。 +4. 运行受影响范围的定向测试。 +5. 运行对应区域的必需质量门禁。 +6. 检查 `git diff`,排除无关修改和敏感数据。 +7. 创建 Pull Request,说明问题、实现、验证和已知边界。 + +不得仅为让测试通过而削弱或删除安全断言。如果契约确实需要修改,应说明业务 +原因,并同步更新实现、测试、文档以及迁移/恢复行为。 + +## Agent 与业务安全规则 + +- 用户输入和模型输出必须经过严格的类型化 Schema。 +- 工具必须加入显式白名单,禁止任意工具执行。 +- 业务数量、权限和状态转换必须保持确定性。 +- 受控写入必须保留人工审批。 +- 审批必须绑定相关证据、规则、事实和计划哈希。 +- 审批后、执行前必须重新读取权威事实。 +- 写工具必须幂等,并验证数据库后置条件。 +- provider、解析、规则、审批或依赖异常时必须 fail closed。 +- 保持 LangGraph 重启恢复语义,不得把 checkpoint 当成业务事实源。 +- 不得记录密钥、完整 Prompt、隐藏推理、SQL 参数或敏感证据。 + +## 质量门禁 + +### Python 与后端 + +```bash +uv run ruff check . +uv run ruff format --check . +uv run mypy src +uv run pytest -q +uv run python scripts/run_opercerta_evaluation.py +uv run python scripts/run_agent_evaluation.py +uv run python scripts/verify_repository_safety.py +``` + +数据库集成测试需要兼容的 PostgreSQL/pgvector。必须使用隔离测试数据库,禁止把 +测试指向业务或个人数据。 + +### 前端 + +```bash +cd web +npm run test:run +npm run build +``` + +### Compose 行为 + +在全新的本地 Compose 项目中执行: + +```bash +docker compose up --build -d --wait +python3 scripts/verify_agent_compose.py +docker compose restart api mcp +python3 scripts/verify_agent_compose.py --recovery-only +``` + +业务验证脚本会创建合成 operation 和工单,不得对需要保留状态的数据库运行。 + +## 文档规则 + +- 公开项目行为变化时,同时更新 `README.md` 内的中英文面板并保持事实一致。 +- 贡献流程变化时,同时更新 `CONTRIBUTING.md` 内的中英文面板。 +- 新增、移动或删除 Markdown 文件时,必须在同一提交更新 `DOCUMENT_INDEX.md`。 +- 区分实测结果与假设,不得把固定合成评测表述为生产准确率或 SLA 证据。 + +## Pull Request 检查表 + +Pull Request 应包含: + +- 问题与预期行为; +- 实现方式和重要取舍; +- 准确的验证命令与结果; +- 数据库或 API 兼容性影响; +- 与恢复、幂等、审批和安全相关的影响; +- 已知限制和后续工作。 + +请求 Review 前确认: + +- [ ] 变更范围明确,分支基于最新 `main`; +- [ ] 行为变化具有测试; +- [ ] 不包含密钥和私有数据; +- [ ] 相关 Python、前端或 Compose 门禁通过; +- [ ] 公开中英文文档保持同步; +- [ ] `DOCUMENT_INDEX.md` 已更新。 + +## 报告安全问题 + +不要在公开 Issue 中发布可利用细节、凭据或敏感数据。请私下联系仓库所有者, +提供最小复现、受影响版本和影响范围。项目计划增加独立安全策略和私密报告渠道, +但当前尚未配置。 + +
+ +
+English Thank you for helping improve OperCerta. Contributions should preserve its core property: LLM output may assist investigation and explanation, but @@ -104,9 +236,9 @@ preserved: it intentionally creates synthetic operations and work orders. ## Documentation -- Keep `README.md` and `README.zh-CN.md` structurally equivalent when public +- Keep the Chinese and English panels in `README.md` equivalent when public project behavior changes. -- Keep `CONTRIBUTING.md` and `CONTRIBUTING.zh-CN.md` equivalent when the +- Keep the Chinese and English panels in `CONTRIBUTING.md` equivalent when the contribution process changes. - Register every added, moved, or removed Markdown file in `DOCUMENT_INDEX.md` in the same commit. @@ -139,3 +271,5 @@ Do not publish exploitable details, credentials, or sensitive data in a public issue. Contact the repository owner privately with a minimal reproduction, affected versions, and impact. A dedicated security policy and private reporting channel are planned but are not yet configured. + +
diff --git a/CONTRIBUTING.zh-CN.md b/CONTRIBUTING.zh-CN.md deleted file mode 100644 index c431ac7..0000000 --- a/CONTRIBUTING.zh-CN.md +++ /dev/null @@ -1,129 +0,0 @@ -# 参与 OperCerta 开发 - -[English](CONTRIBUTING.md) | **简体中文** - -感谢你帮助改进 OperCerta。所有贡献都应保留项目的核心属性:LLM 输出可以辅助 -调查和解释,但高风险业务写入必须由确定性规则、人工审批和数据库约束控制。 - -## 开始之前 - -- 新建 Issue 前先搜索已有 Issue 和 Pull Request,避免重复。 -- 修改 Agent 状态模型、审批边界、持久化模型、公开 API 或依赖架构前,先建立 Issue 讨论。 -- 每次变更只解决一个明确问题。 -- 示例只使用合成或匿名数据。 -- 禁止提交凭据、token、私有地址、客户记录或原单位机密材料。 - -## 开发环境 - -推荐使用 Linux 或 WSL2、Docker Compose v2、由 `uv` 管理的 Python 3.12, -以及 Node.js 24。 - -```bash -git clone https://github.com/KXHXK/opercerta.git -cd opercerta - -uv sync --frozen --all-groups - -cd web -npm ci -``` - -本地运行时需要把 `.env.compose.example` 复制为 `.env.compose`,将占位符替换为 -仅本地使用的值,然后按照[快速启动](README.zh-CN.md#快速启动)操作。 - -## 开发流程 - -1. 从最新 `main` 创建分支。 -2. 复现问题或先增加失败测试。 -3. 实现最小且完整的修改。 -4. 运行受影响范围的定向测试。 -5. 运行对应区域的必需质量门禁。 -6. 检查 `git diff`,排除无关修改和敏感数据。 -7. 创建 Pull Request,说明问题、实现、验证和已知边界。 - -不得仅为让测试通过而削弱或删除安全断言。如果契约确实需要修改,应说明业务 -原因,并同步更新实现、测试、文档以及迁移/恢复行为。 - -## Agent 与业务安全规则 - -- 用户输入和模型输出必须经过严格的类型化 Schema。 -- 工具必须加入显式白名单,禁止任意工具执行。 -- 业务数量、权限和状态转换必须保持确定性。 -- 受控写入必须保留人工审批。 -- 审批必须绑定相关证据、规则、事实和计划哈希。 -- 审批后、执行前必须重新读取权威事实。 -- 写工具必须幂等,并验证数据库后置条件。 -- provider、解析、规则、审批或依赖异常时必须 fail closed。 -- 保持 LangGraph 重启恢复语义,不得把 checkpoint 当成业务事实源。 -- 不得记录密钥、完整 Prompt、隐藏推理、SQL 参数或敏感证据。 - -## 质量门禁 - -### Python 与后端 - -```bash -uv run ruff check . -uv run ruff format --check . -uv run mypy src -uv run pytest -q -uv run python scripts/run_opercerta_evaluation.py -uv run python scripts/run_agent_evaluation.py -uv run python scripts/verify_repository_safety.py -``` - -数据库集成测试需要兼容的 PostgreSQL/pgvector。必须使用隔离测试数据库,禁止把 -测试指向业务或个人数据。 - -### 前端 - -```bash -cd web -npm run test:run -npm run build -``` - -### Compose 行为 - -在全新的本地 Compose 项目中执行: - -```bash -docker compose up --build -d --wait -python3 scripts/verify_agent_compose.py -docker compose restart api mcp -python3 scripts/verify_agent_compose.py --recovery-only -``` - -业务验证脚本会创建合成 operation 和工单,不得对需要保留状态的数据库运行。 - -## 文档规则 - -- 公开项目行为变化时,保持 `README.md` 与 `README.zh-CN.md` 结构和事实一致。 -- 贡献流程变化时,保持 `CONTRIBUTING.md` 与 `CONTRIBUTING.zh-CN.md` 一致。 -- 新增、移动或删除 Markdown 文件时,必须在同一提交更新 `DOCUMENT_INDEX.md`。 -- 区分实测结果与假设,不得把固定合成评测表述为生产准确率或 SLA 证据。 - -## Pull Request 检查表 - -Pull Request 应包含: - -- 问题与预期行为; -- 实现方式和重要取舍; -- 准确的验证命令与结果; -- 数据库或 API 兼容性影响; -- 与恢复、幂等、审批和安全相关的影响; -- 已知限制和后续工作。 - -请求 Review 前确认: - -- [ ] 变更范围明确,分支基于最新 `main`; -- [ ] 行为变化具有测试; -- [ ] 不包含密钥和私有数据; -- [ ] 相关 Python、前端或 Compose 门禁通过; -- [ ] 公开中英文文档保持同步; -- [ ] `DOCUMENT_INDEX.md` 已更新。 - -## 报告安全问题 - -不要在公开 Issue 中发布可利用细节、凭据或敏感数据。请私下联系仓库所有者, -提供最小复现、受影响版本和影响范围。项目计划增加独立安全策略和私密报告渠道, -但当前尚未配置。 diff --git a/DOCUMENT_INDEX.md b/DOCUMENT_INDEX.md index b9f486f..797e14b 100644 --- a/DOCUMENT_INDEX.md +++ b/DOCUMENT_INDEX.md @@ -1,16 +1,16 @@ # OperCerta 文档总索引 -本索引完整登记 OperCerta 当前根工作树中的 118 份 Markdown 文档,并保留旧电脑 6 个 `.worktrees/` 的 456 条历史登记。当前根工作树与每个历史 worktree 使用独立六列表格和独立序号;路径均相对于仓库根目录;日期表示文档首次建立日期。历史 worktree 表用于追溯分支资料,不表示对应物理目录仍存在。Git 元数据、依赖目录、虚拟环境和工具缓存不属于项目文档登记范围。 +本索引完整登记 OperCerta 当前根工作树中的 117 份 Markdown 文档,并保留旧电脑 6 个 `.worktrees/` 的 456 条历史登记。当前根工作树与每个历史 worktree 使用独立六列表格和独立序号;路径均相对于仓库根目录;日期表示文档首次建立日期。历史 worktree 表用于追溯分支资料,不表示对应物理目录仍存在。Git 元数据、依赖目录、虚拟环境和工具缓存不属于项目文档登记范围。 Typora 显示:首次运行 `powershell -ExecutionPolicy Bypass -File scripts/install_typora_index_theme.ps1`,重启 Typora 后选择 `主题 → OperCerta Index`。该主题让正文使用 96% 窗口宽度,并统一设置下列全部六列表格的列宽、自动换行和字号。 ## 项目核心学习导航 -先按 A1–A9 完成一轮“阅读 → 找到代码 → 手动验证 → 自己复述”。后面的 118 份当前文档与 456 条历史 worktree 登记是排查问题和深入学习时使用的资料库,不需要从头到尾顺序阅读。 +先按 A1–A9 完成一轮“阅读 → 找到代码 → 手动验证 → 自己复述”。后面的 117 份当前文档与 456 条历史 worktree 登记是排查问题和深入学习时使用的资料库,不需要从头到尾顺序阅读。 | 阶段 | 核心主题 | 优先阅读 | 代码与配置入口 | 必做实践 | 掌握标准 | | ---: | --- | --- | --- | --- | --- | -| A1 | 项目地图与当前边界 | [README English](README.md)、[README 简体中文](README.zh-CN.md)、[当前状态](docs/development-log/current-state.md)、[实施交接](IMPLEMENTATION_HANDOFF.md) | [Compose](compose.yaml)、[API 运行入口](src/opercerta/runtime/api.py)、[MCP 运行入口](src/opercerta/runtime/mcp.py) | 不看稿,用 60 秒说清楚三个业务场景、系统解决的问题、当前已完成能力和仍关闭的生产门禁。 | 能区分“本地验证通过、静态公网展示、真实生产上线”三种状态,不夸大成果。 | +| A1 | 项目地图与当前边界 | [双语 README](README.md)、[当前状态](docs/development-log/current-state.md)、[实施交接](IMPLEMENTATION_HANDOFF.md) | [Compose](compose.yaml)、[API 运行入口](src/opercerta/runtime/api.py)、[MCP 运行入口](src/opercerta/runtime/mcp.py) | 在 README 页内切换中英文;不看稿,用 60 秒说清楚三个业务场景、系统解决的问题、当前已完成能力和仍关闭的生产门禁。 | 能区分“本地验证通过、静态公网展示、真实生产上线”三种状态,不夸大成果。 | | A2 | 业务动机与三业务闭环 | [OperCerta 详细设计](docs/specs/2026-07-14-opercerta-design.md)、[三业务发布设计](docs/superpowers/specs/2026-07-20-opercerta-three-business-release-design.md) | [场景注册表](src/opercerta/application/scenario_registry.py)、[库存图](src/opercerta/workflow/replenishment_graph.py)、[设备图](src/opercerta/workflow/equipment_maintenance_graph.py)、[任务恢复图](src/opercerta/workflow/task_recovery_graph.py) | 分别画出库存短缺、设备异常、任务阻塞的“异常信号 → 调查 → 审批 → 写入 → 验证”流程。 | 能解释为什么传统工单需要 Agent 辅助,以及哪些规则必须由确定性代码控制。 | | A3 | Agent 总体架构与循环 | [Agent 核心架构设计](docs/superpowers/specs/2026-07-21-opercerta-agent-core-architecture-design.md)、[单根 Agent Loop 设计](docs/superpowers/specs/2026-07-26-single-root-agent-loop-and-case-workspace-design.md) | [主 Agent 图](src/opercerta/workflow/agent_controlled_action_graph.py)、[Harness](src/opercerta/agent/harness.py)、[Prompt 注册表](src/opercerta/agent/prompt_registry.py) | 对照一次 Agent Trace,逐步标出感知、语义理解、规划、工具、记忆、执行反馈和回环位置。 | 能解释 LangGraph 为什么是状态编排内核,而不是一个普通业务节点;能说明何时循环、何时中断等待审批。 | | A4 | LLM、Prompt 与 LangChain | [核心技术手册](docs/learning/opercerta-core-technical-guide.md)、[真实模型证据](docs/release-evidence/real-model-representative-validation.md) | [LangChain 模型适配器](src/opercerta/infrastructure/langchain_model_gateway.py)、[模型端口](src/opercerta/infrastructure/model_gateway.py)、[Tool Loop Prompt](src/opercerta/prompts/tool-loop-v1.md) | 对比 Mock 与 Kimi 模式的输入、结构化输出、超时和失败收口;从 Trace 找出一次模型决策。 | 能说清 LLM 负责语义与规划、不直接越权写库;Prompt、Harness、Provider Adapter 各自解决什么问题。 | @@ -20,15 +20,15 @@ Typora 显示:首次运行 `powershell -ExecutionPolicy Bypass -File scripts/i | A8 | PostgreSQL、Redis、Docker 与可观测性 | [三业务发布证据](docs/release-evidence/three-business-release.md)、[Docker 证据](docs/release-evidence/docker-linux-runtime.md)、[可观测性证据](docs/release-evidence/observability-security-regression.md) | [Compose](compose.yaml)、[Dockerfile](Dockerfile)、[Redis 缓存](src/opercerta/infrastructure/cache.py)、[数据库迁移](migrations)、[Tracing](src/opercerta/observability/tracing.py) | 执行健康检查、查看容器状态、重启 API/MCP,并确认 checkpoint、业务事实和工单没有丢失或重复。 | 能解释容器与 Compose 的区别、Redis 为什么不是权威存储、PostgreSQL/pgvector 的双重职责及日志如何安全关联。 | | A9 | 故障复盘与面试输出 | [面试讲解](docs/learning/opercerta-interview-guide.md)、[工程案例集](docs/development-log/interview-casebook.md)、[最新开发日志](docs/development-log/daily/2026-07-31.md) | 选择前述任一真实故障对应的代码、日志和修复提交。 | 分别完成 30 秒、3 分钟和 10 分钟讲解;独立复述一个“现象 → 根因 → 修复 → 验证 → 取舍”案例。 | 不看文档也能讲清业务价值、核心链路、技术取舍、可靠性证据和未完成边界,并能接受追问。 | -## 根工作树(118 份) +## 根工作树(117 份) 显示说明:本表及后续各 worktree 表均保持“序号、文件名、路径、用途、状态、日期”六列完整字段。 | 序号 | 文件名 | 路径 | 用途(详细) | 状态 | 日期 | | ---: | --- | --- | --- | --- | --- | -| 1 | `README.md` | `README.md` | 英文项目总入口,说明业务背景、三业务功能、Agent 闭环、架构、快速启动、使用流程、模型模式、验证结果、可靠性边界和路线图,并提供中文切换。 | 已重构为开源项目导向英文默认页;移除求职、组合项目和过时设计入口 | 2026-07-30 | +| 1 | `README.md` | `README.md` | 双语项目总入口,在同一仓库首页用互斥折叠面板切换简体中文和英文,说明业务背景、三业务功能、Agent 闭环、完整技术栈、快速启动、使用流程、验证结果、可靠性边界和路线图。 | 已重构为页内双语入口;默认显示简体中文,不再跳转独立语言文件 | 2026-07-30 | | 2 | `IMPLEMENTATION_HANDOFF.md` | `IMPLEMENTATION_HANDOFF.md` | 跨对话和上下文压缩后的实施交接文件,记录当前分支、已验证事实、未完成事项、下一步动作及禁止越过的发布边界。 | 已同步 PR #18、最终 main Compose、静态 production、Showcase 预发布与下一掌握阶段 | 2026-07-30 | -| 3 | `DOCUMENT_INDEX.md` | `DOCUMENT_INDEX.md` | OperCerta 全部项目文档的唯一总登记表,用于按文件名、路径、用途、状态和日期统一检索、复查与交接。 | 当前根工作树 118 份文档已完整登记;另保留 6 个旧 worktree 的 456 条历史记录 | 2026-07-15 | +| 3 | `DOCUMENT_INDEX.md` | `DOCUMENT_INDEX.md` | OperCerta 全部项目文档的唯一总登记表,用于按文件名、路径、用途、状态和日期统一检索、复查与交接。 | 当前根工作树 117 份文档已完整登记;另保留 6 个旧 worktree 的 456 条历史记录 | 2026-07-15 | | 4 | `2026-07-14-agent-project-naming-design.md` | `docs/specs/2026-07-14-agent-project-naming-design.md` | 定义 OperCerta、ForenTrail、SiteVerum、Federune 四个项目的命名原则、语义边界与品牌一致性,防止项目职责和名称漂移。 | 已冻结为命名基线 | 2026-07-14 | | 5 | `ai-agent-portfolio-overall-design.md` | `docs/specs/ai-agent-portfolio-overall-design.md` | 规定四个 AI Agent 项目的整体定位、差异化业务范围、技术能力组合、实施顺序和共同约束,是项目组合的最高层设计依据。 | 已冻结为总体设计基线;文件名已统一为英文路径 | 2026-07-14 | | 6 | `2026-07-14-agent-portfolio-design.md` | `docs/specs/2026-07-14-agent-portfolio-design.md` | 设计四项目如何组合成求职作品集,包括能力覆盖、展示顺序、共享基础设施边界和避免重复建设的原则。 | 已冻结为组合设计基线 | 2026-07-14 | @@ -140,10 +140,9 @@ Typora 显示:首次运行 `powershell -ExecutionPolicy Bypass -File scripts/i | 112 | `tool-loop-v1.md` | `src/opercerta/prompts/tool-loop-v1.md` | Tool Loop 主 Prompt,规定模型在 Observation 后选择继续调用只读工具、请求审批或结束,并约束 JSON 工具协议。 | v1 已用于单根 Agent Loop;真实 Kimi 兼容边界另有事件记录 | 2026-07-26 | | 113 | `verifier-v1.md` | `src/opercerta/prompts/verifier-v1.md` | Verifier 角色版本化 Prompt,用于批准后重新核对事实、识别漂移并决定执行、重审批或安全终止。 | v1 已实施并有事实漂移回归测试 | 2026-07-21 | | 114 | `2026-07-30.md` | `docs/development-log/daily/2026-07-30.md` | 记录新电脑环境最终收口、WSL 登录 shell Node PATH 的 TDD 修复、冻结依赖国内镜像恢复、DrvFS 权限边界、PR/main 门禁,以及发布材料防漂移与静态安全头修订。 | PR #17/main 五项 CI、667/60/9-of-9、Netlify 静态 production 安全头与产物一致性均已验证 | 2026-07-30 | -| 115 | `CONTRIBUTING.md` | `CONTRIBUTING.md` | 英文贡献指南,规定开发环境、TDD 流程、Agent/业务安全规则、Python/前端/Compose 门禁、双语文档同步、PR 检查表和安全问题报告方式。 | 已扩展为完整英文贡献入口,并提供简体中文切换 | 2026-07-30 | -| 116 | `2026-07-31.md` | `docs/development-log/daily/2026-07-31.md` | 记录 OperCerta 最终 main/CI 复核、Netlify 静态发布与回滚点、Showcase 预发布、自动化工程门禁结论、产品边界和下一掌握任务。 | 求职静态展示与自动化工程已收口;个人掌握待实演,产品 production gate 保持 CLOSED | 2026-07-31 | -| 117 | `README.zh-CN.md` | `README.zh-CN.md` | 简体中文项目总入口,与英文 README 对齐说明业务背景、功能、Agent 闭环、技术架构、快速启动、用法、测试结果、开发状态和生产边界。 | 已建立独立中文版;通过顶部链接与英文默认页互相切换 | 2026-07-31 | -| 118 | `CONTRIBUTING.zh-CN.md` | `CONTRIBUTING.zh-CN.md` | 简体中文贡献指南,与英文版对齐说明开发流程、Agent 安全约束、质量门禁、双语文档维护、PR 检查表和安全报告要求。 | 已建立独立中文版;通过顶部链接与英文版互相切换 | 2026-07-31 | +| 115 | `CONTRIBUTING.md` | `CONTRIBUTING.md` | 双语贡献指南,在同一页面用互斥折叠面板切换简体中文和英文,规定开发环境、TDD 流程、Agent/业务安全规则、Python/前端/Compose 门禁、文档同步、PR 检查表和安全问题报告方式。 | 已合并为页内双语贡献入口;默认显示简体中文 | 2026-07-30 | +| 116 | `2026-07-31.md` | `docs/development-log/daily/2026-07-31.md` | 记录 OperCerta 最终 main/CI、Netlify 静态发布、Showcase 预发布、双语开源入口、规格一致性审计、自动化门禁、产品边界和下一掌握任务。 | 本地 Agent MVP 与静态展示已收口;公网交互和产品 production gate 保持 CLOSED | 2026-07-31 | +| 117 | `2026-07-31-spec-release-readiness-audit.md` | `docs/development-log/audits/2026-07-31-spec-release-readiness-audit.md` | 对照四份原始设计及三业务、Agent 核心、信号收件箱和单根 LangGraph 有效修订,逐项核验当前源码、技术栈、测试、Compose、Netlify 和发布证据,区分合理设计演进、真实偏差、开源治理缺口、公网交互条件和简历可用边界。 | 审计完成;架构主线一致,本地/静态发布可用,公网交互与企业生产门禁未通过 | 2026-07-31 | ## 历史 Worktree:agent-core-architecture(82 条记录) diff --git a/README.md b/README.md index ab55a8e..94d0378 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,264 @@ # OperCerta -**English** | [简体中文](README.zh-CN.md) - [![OperCerta CI](https://github.com/KXHXK/opercerta/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/KXHXK/opercerta/actions/workflows/ci.yml) ![Python](https://img.shields.io/badge/Python-3.12-3776AB?logo=python&logoColor=white) +![FastAPI](https://img.shields.io/badge/FastAPI-0.139-009688?logo=fastapi&logoColor=white) +![Pydantic](https://img.shields.io/badge/Pydantic-2.13-E92063?logo=pydantic&logoColor=white) +![LangGraph](https://img.shields.io/badge/LangGraph-1.2.9-1C3C3C) +![LangChain](https://img.shields.io/badge/LangChain_Core-1.4.9-1C3C3C?logo=langchain&logoColor=white) +![FastMCP](https://img.shields.io/badge/FastMCP-MCP_1.28.1-7C3AED) +![PostgreSQL](https://img.shields.io/badge/PostgreSQL-18-4169E1?logo=postgresql&logoColor=white) +![pgvector](https://img.shields.io/badge/pgvector-0.8.2-336791) +![Redis](https://img.shields.io/badge/Redis-8.8-FF4438?logo=redis&logoColor=white) +![FastEmbed](https://img.shields.io/badge/FastEmbed-0.8-FFB000) +![SQLAlchemy](https://img.shields.io/badge/SQLAlchemy-2.0-D71F00?logo=sqlalchemy&logoColor=white) +![Alembic](https://img.shields.io/badge/Alembic-1.18-6BA81E) ![React](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=111) -![Docker Compose](https://img.shields.io/badge/Docker_Compose-supported-2496ED?logo=docker&logoColor=white) +![TypeScript](https://img.shields.io/badge/TypeScript-7.0-3178C6?logo=typescript&logoColor=white) +![Vite](https://img.shields.io/badge/Vite-8.1-646CFF?logo=vite&logoColor=white) +![Vitest](https://img.shields.io/badge/Vitest-4.1-6E9F18?logo=vitest&logoColor=white) +![SSE](https://img.shields.io/badge/Streaming-SSE-0A7EA4) +![OpenTelemetry](https://img.shields.io/badge/OpenTelemetry-1.44-000000?logo=opentelemetry&logoColor=white) +![Prometheus](https://img.shields.io/badge/Prometheus-0.25-E6522C?logo=prometheus&logoColor=white) +![Docker Compose](https://img.shields.io/badge/Docker_Compose-v2-2496ED?logo=docker&logoColor=white) +![Caddy](https://img.shields.io/badge/Caddy-2.11-1F88C0?logo=caddy&logoColor=white) +![GitHub Actions](https://img.shields.io/badge/GitHub_Actions-CI-2088FF?logo=githubactions&logoColor=white) + +[https://opercerta-kxh.netlify.app/](https://opercerta-kxh.netlify.app/) + +
+简体中文 + +OperCerta 是一个面向库存短缺、设备异常和作业阻塞的受控、可审计运营处置 +Agent。它把有边界的大模型推理与确定性规则、人工审批、持久化工作流状态和 +幂等业务写入组合成完整闭环。 + +> **开发状态:** 三业务完整流程可以在本地单节点 Docker Compose 环境中运行。 +> 公开项目页面为纯静态页面,不连接 API 或数据库。项目**尚未达到生产就绪**: +> 生产身份、公网入口、限流、备份、高可用和自动部署仍未实现。 + +## 项目背景 + +运营系统通常可以先检测到异常,但操作人员还需要从库存、设备、任务和操作规程 +等多个系统收集证据,才能决定如何处置;审批等待期间,业务事实还可能变化。 +如果让开放式 Agent 直接写业务系统,会产生不可接受的安全和审计风险。 + +OperCerta 对职责进行了拆分: + +- 确定性检测器发现边界明确的运营异常信号; +- LLM 辅助的 Agent 收集证据并解释建议动作; +- 规则代码判断是否需要审批并校验业务参数; +- 人工审批绑定事实、规则和计划快照; +- 执行前重新获取最新事实; +- PostgreSQL 事务与唯一约束保证重试不会重复写入。 + +因此,Agent 可以辅助调查和规划,但不会成为高风险业务写入的最终权威。 + +## 支持的业务流程 + +| 业务 | 触发条件 | Agent 调查 | 受控结果 | +| --- | --- | --- | --- | +| 库存补货 | 可用库存低于补货点 | 读取库存与规则证据、计算有边界的建议数量、检索相关操作规程 | 审批并完成最新事实复核后,只创建一张补货工单 | +| 设备维修 | 设备离线或产生告警 | 读取设备状态与维修规则、检索隔离和维修规程 | 创建一张维修工单;事实不再匹配时安全终止 | +| 作业恢复 | 运营任务持续阻塞 | 读取任务状态与恢复规则、检索恢复规程 | 创建一张恢复工单;不允许自动恢复时升级处理 | + +## Agent 闭环 + +```mermaid +flowchart LR + UI["React 控制台"] --> API["FastAPI 边界"] + API --> SIGNAL["确定性异常扫描"] + SIGNAL --> GOAL["类型化目标编码"] + GOAL --> GRAPH["LangGraph 规划与执行循环"] + GRAPH --> LLM["LLM 推理"] + LLM --> POLICY["工具策略与 Harness"] + POLICY --> MCP["FastMCP 只读工具"] + MCP --> FACTS["业务事实与 pgvector 规程"] + FACTS --> GRAPH + GRAPH --> HITL["人工审批中断"] + HITL --> FRESH["最新事实与 Verifier"] + FRESH --> WRITE["受控幂等写入"] + WRITE --> DB["PostgreSQL 与 checkpoint"] + DB --> TRACE["Agent Trace、审计与反馈"] + TRACE --> UI +``` + +模型不是业务数量、权限或状态转换的事实来源。LangGraph 负责持久化执行流程, +MCP 只开放少量类型化白名单工具,确定性代码和数据库共同守住写入边界。 + +## 技术架构 + +| 区域 | 实现 | 职责 | +| --- | --- | --- | +| Web 控制台 | React 19、TypeScript、Vite | 异常收件箱、Case 工作区、审批、结果、Trace 和审计展示 | +| API 边界 | FastAPI、Pydantic | 身份校验、严格输入、RBAC、稳定错误、健康检查、SSE 审计回放 | +| Agent 运行时 | LangGraph、最小 LangChain Tool Calling | 有界规划、工具观察循环、中断恢复、重新取证和重启恢复 | +| 工具协议 | FastMCP | 类型化库存、设备、任务、规则、知识和工单工具 | +| 持久化 | PostgreSQL 18、pgvector、Alembic | 业务事实、审批锁、唯一工单、checkpoint、Trace 和规程检索 | +| 缓存 | Redis | 只读证据缓存;审批后复核绕过缓存 | +| 模型适配 | OpenAI-compatible API | 默认 Mock;真实模式具有显式超时和 fail-closed 行为 | +| 运行环境 | Docker Compose | 可复现的 PostgreSQL、Redis、MCP、bootstrap 和 API 服务 | +| 持续集成 | GitHub Actions | 仓库安全、Python 质量、后端、前端和 main 分支 Compose 恢复门禁 | + +## 快速启动 + +### 环境要求 + +- Linux 或 WSL2 +- Docker Engine 与 Docker Compose v2 +- 本地控制台需要 Node.js 24 和 npm 11 +- 源码测试需要 `uv` 0.11 和 Python 3.12 + +### 1. 配置仅本地使用的凭据 + +```bash +cp .env.compose.example .env.compose +``` + +替换 `.env.compose` 中的所有 `CHANGE_ME` 占位符:`POSTGRES_PASSWORD` 和 +`OPERCERTA_DATABASE_URL` 必须使用同一个高强度数据库密码,JWT 使用独立签名密钥; +Mock 模式的模型名和 key 可以分别使用 `mock` 与 `not-used-in-mock-mode` 等非敏感值。 +该文件已被 Git 忽略,默认 Mock 模式不需要真实模型 API key。 + +### 2. 启动后端服务 + +```bash +OPERCERTA_HF_HUB_OFFLINE=false docker compose up --build -d --wait +curl http://127.0.0.1:8080/health/ready +``` + +首次运行会下载 embedding 模型。FastEmbed 缓存准备完成后,后续可以设置 +`OPERCERTA_HF_HUB_OFFLINE=true`。就绪响应中的 `database`、`checkpoint` 和 +`mcp` 应全部为 `ready`。 + +### 3. 启动 Web 控制台 + +```bash +cd web +npm ci +npm run dev +``` + +打开 。Vite 会把 `/api` 代理到本机 FastAPI, +因此不需要额外配置浏览器跨域。 + +## 功能用法 + +1. 选择 `operator` 演示账号并扫描业务异常。 +2. 打开库存、设备或作业 Case,启动 Agent 调查。 +3. 查看类型化 Goal、工具计划、MCP Observation、规程引用和 Agent Trace。 +4. 切换到 `approver`,批准或拒绝已绑定的处置建议。 +5. 切换到 `auditor`,查看最新事实复核、工单结果和审计序列。 +6. 重复请求或重启服务,观察幂等写入与持久化恢复。 + +演示 JWT 只用于本地流程,不是生产身份系统。 + +## 模型模式 + +- **Mock 模式**确定、无需凭据,用于可复现的契约、安全和恢复测试。 +- **Real 模式**连接 OpenAI-compatible endpoint;provider、输出契约或工具循环 + 不合法时会 fail closed。密钥只保存在被忽略的本地环境文件中。 + +Moonshot/Kimi K2.6 的少量代表验证已覆盖三业务只读、库存批准写入和无效 +provider fail-closed。该小样本只证明 provider 兼容性,不代表模型准确率、 +延迟、成本或 SLA。 + +## 测试结果 + +| 门禁 | 当前已验证结果 | +| --- | ---: | +| 后端测试 | 667 条通过 | +| 前端测试 | 19 个测试文件、60 条用例通过 | +| 三业务固定契约 | 42/42 通过 | +| 冻结 Agent 安全与恢复评测 | 9/9 通过 | +| main Compose smoke | 构建、业务数据库副作用、API/MCP 重启、恢复和清理通过 | + +运行本地门禁: + +```bash +uv sync --frozen --all-groups +uv run ruff check . +uv run ruff format --check . +uv run mypy src +uv run pytest -q +uv run python scripts/run_opercerta_evaluation.py +uv run python scripts/run_agent_evaluation.py + +cd web +npm ci +npm run test:run +npm run build +``` + +在全新 Compose 数据库上执行 `python3 scripts/verify_agent_compose.py`,还会断言 +Agent 轨迹和 PostgreSQL 最终事实。固定合成用例只验证已声明契约,不代表生产 +流量或独立准确率评测。 + +## 可靠性与安全属性 + +- 严格输入 Schema 和稳定的安全错误 envelope; +- 工具白名单、类型化参数、有限重试和显式 timeout; +- 审批绑定证据、规则、事实和计划哈希; +- 审批后绕过缓存并重新读取最新事实; +- PostgreSQL 行锁解决审批竞态; +- 确定性幂等键、唯一约束和写后读验证; +- 持久化 LangGraph checkpoint 与业务表主导的重启恢复; +- request ID、trace context、安全结构化日志和低基数指标; +- 只使用合成数据,不包含客户记录或原单位机密材料。 + +## 仓库结构 + +```text +src/opercerta/ API、Agent、规则、持久化、MCP 和可观测性 +web/ React 控制台与静态项目页面 +tests/ 单元、集成、数据库、API、Agent 和运行时测试 +data/ 版本化合成评测用例与规程知识 +migrations/ Alembic 数据库迁移 +scripts/ 启动、评测、安全和 Compose 验证工具 +docs/ 技术指南、开发记录和发布证据 +``` + +## 项目文档 + +- [核心技术手册](docs/learning/opercerta-core-technical-guide.md) +- [手动实验手册](docs/learning/opercerta-manual-experiment-guide.md) +- [当前实施状态](docs/development-log/current-state.md) +- [单根 Agent Loop 实施证据](docs/release-evidence/single-root-agent-loop-case-workspace.md) +- [GitHub Actions 证据](docs/release-evidence/github-actions-ci.md) + +## 开发状态与路线图 + +本地已经完成: + +- 三条受控业务流程和共享 Agent Loop; +- 审批绑定、重新取证、幂等写入和重启恢复; +- 真实 PostgreSQL/pgvector、Redis、FastMCP、FastEmbed 检索和 React 控制台; +- 固定契约/评测以及 main 分支 Compose 恢复证据; +- 只读公开项目页面和可复现预发布版本。 + +生产部署前仍需完成: + +- 生产身份和授权生命周期; +- 公网 HTTPS API、精确 CORS、限流和防滥用; +- 托管密钥、备份、恢复演练和高可用协调; +- 自动部署、迁移编排和运营告警; +- 更广泛的独立模型和业务质量评测。 + +## 参与贡献 + +开发环境、质量门禁、Pull Request 要求和 Agent 安全规则见 +[CONTRIBUTING.md](CONTRIBUTING.md)。 + +
+ +
+English OperCerta is a controlled, auditable operations agent for inventory shortages, equipment incidents, and blocked operational tasks. It combines bounded LLM reasoning with deterministic policy, human approval, durable workflow state, and idempotent business writes. -[Read-only project page](https://opercerta-kxh.netlify.app) · -[Release `v0.1.0-showcase.1`](https://github.com/KXHXK/opercerta/releases/tag/v0.1.0-showcase.1) - > **Development status:** the complete three-business workflow runs locally in > a single-node Docker Compose environment. The public project page is static > and does not expose the API or database. **Not production-ready:** production @@ -242,3 +486,5 @@ Open work before a production deployment: See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup, quality gates, pull-request expectations, and Agent safety rules. + +
diff --git a/README.zh-CN.md b/README.zh-CN.md deleted file mode 100644 index f4fa529..0000000 --- a/README.zh-CN.md +++ /dev/null @@ -1,231 +0,0 @@ -# OperCerta - -[English](README.md) | **简体中文** - -[![OperCerta CI](https://github.com/KXHXK/opercerta/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/KXHXK/opercerta/actions/workflows/ci.yml) -![Python](https://img.shields.io/badge/Python-3.12-3776AB?logo=python&logoColor=white) -![React](https://img.shields.io/badge/React-19-61DAFB?logo=react&logoColor=111) -![Docker Compose](https://img.shields.io/badge/Docker_Compose-supported-2496ED?logo=docker&logoColor=white) - -OperCerta 是一个面向库存短缺、设备异常和作业阻塞的受控、可审计运营处置 -Agent。它把有限的大模型推理与确定性规则、人工审批、持久化工作流状态和 -幂等业务写入组合成完整闭环。 - -[只读项目页面](https://opercerta-kxh.netlify.app) · -[版本 `v0.1.0-showcase.1`](https://github.com/KXHXK/opercerta/releases/tag/v0.1.0-showcase.1) - -> **开发状态:** 三业务完整流程可以在本地单节点 Docker Compose 环境中运行。 -> 公开项目页面为纯静态页面,不连接 API 或数据库。项目**尚未达到生产就绪**: -> 生产身份、公网入口、限流、备份、高可用和自动部署仍未实现。 - -## 项目背景 - -运营系统通常可以先检测到异常,但操作人员还需要从库存、设备、任务和操作规程 -等多个系统收集证据,才能决定如何处置;审批等待期间,业务事实还可能变化。 -如果让开放式 Agent 直接写业务系统,会产生不可接受的安全和审计风险。 - -OperCerta 对职责进行了拆分: - -- 确定性检测器发现边界明确的运营异常信号; -- LLM 辅助的 Agent 收集证据并解释建议动作; -- 规则代码判断是否需要审批并校验业务参数; -- 人工审批绑定事实、规则和计划快照; -- 执行前重新获取最新事实; -- PostgreSQL 事务与唯一约束保证重试不会重复写入。 - -因此,Agent 可以辅助调查和规划,但不会成为高风险业务写入的最终权威。 - -## 支持的业务流程 - -| 业务 | 触发条件 | Agent 调查 | 受控结果 | -| --- | --- | --- | --- | -| 库存补货 | 可用库存低于补货点 | 读取库存与规则证据、计算有边界的建议数量、检索相关操作规程 | 审批并完成最新事实复核后,只创建一张补货工单 | -| 设备维修 | 设备离线或产生告警 | 读取设备状态与维修规则、检索隔离和维修规程 | 创建一张维修工单;事实不再匹配时安全终止 | -| 作业恢复 | 运营任务持续阻塞 | 读取任务状态与恢复规则、检索恢复规程 | 创建一张恢复工单;不允许自动恢复时升级处理 | - -## Agent 闭环 - -```mermaid -flowchart LR - UI["React 控制台"] --> API["FastAPI 边界"] - API --> SIGNAL["确定性异常扫描"] - SIGNAL --> GOAL["类型化目标编码"] - GOAL --> GRAPH["LangGraph 规划与执行循环"] - GRAPH --> LLM["LLM 推理"] - LLM --> POLICY["工具策略与 Harness"] - POLICY --> MCP["FastMCP 只读工具"] - MCP --> FACTS["业务事实与 pgvector 规程"] - FACTS --> GRAPH - GRAPH --> HITL["人工审批中断"] - HITL --> FRESH["最新事实与 Verifier"] - FRESH --> WRITE["受控幂等写入"] - WRITE --> DB["PostgreSQL 与 checkpoint"] - DB --> TRACE["Agent Trace、审计与反馈"] - TRACE --> UI -``` - -模型不是业务数量、权限或状态转换的事实来源。LangGraph 负责持久化执行流程, -MCP 只开放少量类型化白名单工具,确定性代码和数据库共同守住写入边界。 - -## 技术架构 - -| 区域 | 实现 | 职责 | -| --- | --- | --- | -| Web 控制台 | React 19、TypeScript、Vite | 异常收件箱、Case 工作区、审批、结果、Trace 和审计展示 | -| API 边界 | FastAPI、Pydantic | 身份校验、严格输入、RBAC、稳定错误、健康检查、SSE 审计回放 | -| Agent 运行时 | LangGraph、最小 LangChain Tool Calling | 有界规划、工具观察循环、中断恢复、重新取证和重启恢复 | -| 工具协议 | FastMCP | 类型化库存、设备、任务、规则、知识和工单工具 | -| 持久化 | PostgreSQL 18、pgvector、Alembic | 业务事实、审批锁、唯一工单、checkpoint、Trace 和规程检索 | -| 缓存 | Redis | 只读证据缓存;审批后复核绕过缓存 | -| 模型适配 | OpenAI-compatible API | 默认 Mock;真实模式具有显式超时和 fail-closed 行为 | -| 运行环境 | Docker Compose | 可复现的 PostgreSQL、Redis、MCP、bootstrap 和 API 服务 | -| 持续集成 | GitHub Actions | 仓库安全、Python 质量、后端、前端和 main 分支 Compose 恢复门禁 | - -## 快速启动 - -### 环境要求 - -- Linux 或 WSL2 -- Docker Engine 与 Docker Compose v2 -- 本地控制台需要 Node.js 24 和 npm 11 -- 源码测试需要 `uv` 0.11 和 Python 3.12 - -### 1. 配置仅本地使用的凭据 - -```bash -cp .env.compose.example .env.compose -``` - -替换 `.env.compose` 中的所有 `CHANGE_ME` 占位符:`POSTGRES_PASSWORD` 和 -`OPERCERTA_DATABASE_URL` 必须使用同一个高强度数据库密码,JWT 使用独立签名密钥; -Mock 模式的模型名和 key 可以分别使用 `mock` 与 `not-used-in-mock-mode` 等非敏感值。 -该文件已被 Git 忽略,默认 Mock 模式不需要真实模型 API key。 - -### 2. 启动后端服务 - -```bash -OPERCERTA_HF_HUB_OFFLINE=false docker compose up --build -d --wait -curl http://127.0.0.1:8080/health/ready -``` - -首次运行会下载 embedding 模型。FastEmbed 缓存准备完成后,后续可以设置 -`OPERCERTA_HF_HUB_OFFLINE=true`。就绪响应中的 `database`、`checkpoint` 和 -`mcp` 应全部为 `ready`。 - -### 3. 启动 Web 控制台 - -```bash -cd web -npm ci -npm run dev -``` - -打开 。Vite 会把 `/api` 代理到本机 FastAPI, -因此不需要额外配置浏览器跨域。 - -## 功能用法 - -1. 选择 `operator` 演示账号并扫描业务异常。 -2. 打开库存、设备或作业 Case,启动 Agent 调查。 -3. 查看类型化 Goal、工具计划、MCP Observation、规程引用和 Agent Trace。 -4. 切换到 `approver`,批准或拒绝已绑定的处置建议。 -5. 切换到 `auditor`,查看最新事实复核、工单结果和审计序列。 -6. 重复请求或重启服务,观察幂等写入与持久化恢复。 - -演示 JWT 只用于本地流程,不是生产身份系统。 - -## 模型模式 - -- **Mock 模式**确定、无需凭据,用于可复现的契约、安全和恢复测试。 -- **Real 模式**连接 OpenAI-compatible endpoint;provider、输出契约或工具循环 - 不合法时会 fail closed。密钥只保存在被忽略的本地环境文件中。 - -Moonshot/Kimi K2.6 的少量代表验证已覆盖三业务只读、库存批准写入和无效 -provider fail-closed。该小样本只证明 provider 兼容性,不代表模型准确率、 -延迟、成本或 SLA。 - -## 测试结果 - -| 门禁 | 当前已验证结果 | -| --- | ---: | -| 后端测试 | 667 条通过 | -| 前端测试 | 19 个测试文件、60 条用例通过 | -| 三业务固定契约 | 42/42 通过 | -| 冻结 Agent 安全与恢复评测 | 9/9 通过 | -| main Compose smoke | 构建、业务数据库副作用、API/MCP 重启、恢复和清理通过 | - -运行本地门禁: - -```bash -uv sync --frozen --all-groups -uv run ruff check . -uv run ruff format --check . -uv run mypy src -uv run pytest -q -uv run python scripts/run_opercerta_evaluation.py -uv run python scripts/run_agent_evaluation.py - -cd web -npm ci -npm run test:run -npm run build -``` - -在全新 Compose 数据库上执行 `python3 scripts/verify_agent_compose.py`,还会断言 -Agent 轨迹和 PostgreSQL 最终事实。固定合成用例只验证已声明契约,不代表生产 -流量或独立准确率评测。 - -## 可靠性与安全属性 - -- 严格输入 Schema 和稳定的安全错误 envelope; -- 工具白名单、类型化参数、有限重试和显式 timeout; -- 审批绑定证据、规则、事实和计划哈希; -- 审批后绕过缓存并重新读取最新事实; -- PostgreSQL 行锁解决审批竞态; -- 确定性幂等键、唯一约束和写后读验证; -- 持久化 LangGraph checkpoint 与业务表主导的重启恢复; -- request ID、trace context、安全结构化日志和低基数指标; -- 只使用合成数据,不包含客户记录或原单位机密材料。 - -## 仓库结构 - -```text -src/opercerta/ API、Agent、规则、持久化、MCP 和可观测性 -web/ React 控制台与静态项目页面 -tests/ 单元、集成、数据库、API、Agent 和运行时测试 -data/ 版本化合成评测用例与规程知识 -migrations/ Alembic 数据库迁移 -scripts/ 启动、评测、安全和 Compose 验证工具 -docs/ 技术指南、开发记录和发布证据 -``` - -## 项目文档 - -- [核心技术手册](docs/learning/opercerta-core-technical-guide.md) -- [手动实验手册](docs/learning/opercerta-manual-experiment-guide.md) -- [当前实施状态](docs/development-log/current-state.md) -- [单根 Agent Loop 实施证据](docs/release-evidence/single-root-agent-loop-case-workspace.md) -- [GitHub Actions 证据](docs/release-evidence/github-actions-ci.md) - -## 开发状态与路线图 - -本地已经完成: - -- 三条受控业务流程和共享 Agent Loop; -- 审批绑定、重新取证、幂等写入和重启恢复; -- 真实 PostgreSQL/pgvector、Redis、FastMCP、FastEmbed 检索和 React 控制台; -- 固定契约/评测以及 main 分支 Compose 恢复证据; -- 只读公开项目页面和可复现预发布版本。 - -生产部署前仍需完成: - -- 生产身份和授权生命周期; -- 公网 HTTPS API、精确 CORS、限流和防滥用; -- 托管密钥、备份、恢复演练和高可用协调; -- 自动部署、迁移编排和运营告警; -- 更广泛的独立模型和业务质量评测。 - -## 参与贡献 - -开发环境、质量门禁、Pull Request 要求和 Agent 安全规则见 -[CONTRIBUTING.zh-CN.md](CONTRIBUTING.zh-CN.md)。 diff --git a/docs/development-log/audits/2026-07-31-spec-release-readiness-audit.md b/docs/development-log/audits/2026-07-31-spec-release-readiness-audit.md new file mode 100644 index 0000000..10d8a15 --- /dev/null +++ b/docs/development-log/audits/2026-07-31-spec-release-readiness-audit.md @@ -0,0 +1,127 @@ +# OperCerta 规格一致性与发布就绪审计(2026-07-31) + +## 结论 + +OperCerta 当前实现与“受控单 Agent + 三业务共享可靠性内核”的有效设计主线一致, +没有退化为普通 CRUD 工单系统,也没有偏离为自由聊天或多 Agent 角色讨论。库存补货、 +设备维修和作业异常恢复共享同一条生产 LangGraph 生命周期,并真实接入 LLM 决策、 +FastMCP 工具、pgvector SOP 检索、人工审批、批准后复核、幂等写入、PostgreSQL 事实、 +Redis 只读缓存、Agent Trace 和重启恢复。 + +当前已经达到“公开源码 + 静态项目页 + 可重复本地单节点完整 Agent MVP”的发布状态, +尚未达到“公网可交互产品”或“企业生产系统”状态。静态 Netlify 页面可以公开访问,但 +`/api/*` 返回静态 SPA HTML;真实 FastAPI、MCP、PostgreSQL 和 Redis 只在本地/CI 与 +release Compose 中运行。 + +## 核验依据与优先级 + +1. 命名基线:`docs/specs/2026-07-14-agent-project-naming-design.md`。 +2. 总体基线:`docs/specs/ai-agent-portfolio-overall-design.md`。 +3. 组合基线:`docs/specs/2026-07-14-agent-portfolio-design.md`。 +4. OperCerta 原始详细设计:`docs/specs/2026-07-14-opercerta-design.md`。 +5. 有效修订:三业务发布、Agent 核心架构、异常信号收件箱、信号对账与后继调查、 + 单根 LangGraph Agent Loop 与 case 工作台规格。 +6. 当前事实:源码、锁文件、迁移、Compose、CI、固定评测、真实模型代表报告和本审计 + 当日运行结果。后来的明确修订优先于早期设计中被修订的范围,运行事实不由文档状态 + 代替。 + +## 设计—实现映射 + +| 设计要求 | 当前实现证据 | 结论 | +| --- | --- | --- | +| 库存、设备、作业三业务 | scenario registry、三类 signal detector、三类策略和工单 payload | 一致 | +| 有限输入而非自由聊天 | React 三业务表单、严格 Pydantic Goal/Intent、对象和动作 allowlist | 一致;这是后续 Agent 规格对早期“自然语言请求”的安全收敛 | +| 单 Agent Plan-and-Execute | `ControlledAgentRootGraph`、Model → Tool Policy → MCP Observation → Model 有界回环 | 一致 | +| LangGraph 唯一生命周期所有者 | production factory 只构造受控根图;同一 thread/checkpoint 覆盖审批、复核、写入和终态 | 一致;历史场景图只保留回归与等价测试 | +| MCP 工具调用 | FastMCP 注册库存、设备、任务、策略、SOP、工单创建和工单查询共 7 个类型化工具 | 一致;原始 5 工具先由三业务修订扩展,再由 Agent/RAG 修订增加知识工具 | +| RAG 与 Memory | FastEmbed、pgvector 512 维向量、HNSW、版本化合成 SOP、citation;checkpoint/业务事实/知识分层 | 一致;RAG 不提供权威数量和权限 | +| 人工审批和批准后复核 | JWT/RBAC、绑定哈希、PostgreSQL 行锁、fresh-fact cache bypass、模型 Verifier、重新审批 | 一致 | +| 幂等与重启恢复 | 唯一幂等键、写后读、PostgreSQL checkpointer、业务表主导 recovery、API/MCP restart smoke | 一致 | +| API 与前端 | FastAPI 安全 envelope、health、operation/signal/case/trace/SSE API;React case 工作台和局部状态 | 本地一致;公网 API 未部署 | +| 数据与基础设施 | PostgreSQL 18/pgvector、8 个 Alembic 迁移、Redis 8.8、Docker Compose、Caddy | 本地和 CI 一致 | +| 可观测性 | request/operation/thread/tool/trace 关联、JSON 日志、OpenTelemetry、Prometheus、Agent Trace/audit 分层 | 代码与测试一致;公开环境没有 collector、dashboard 或告警 | +| 测试与评测 | 667 条后端、19 文件/60 条前端、42/42 三业务契约、9/9 Agent 安全恢复、main Compose | 已有可重复证据;均不是生产 SLA 或独立准确率 | + +## 原始设计与当前实现的合理变化 + +- 原始详细设计只具体化库存和设备,2026-07-20 三业务修订正式补齐作业异常。因此当前 + 三业务不是范围膨胀或偏差,而是对总体设计缺口的已批准修复。 +- 原始 MCP 清单为 5 个工具;任务工具和 `knowledge.search_sop` 分别由三业务与 Agent + 核心/RAG 规格增加,当前 7 工具与有效设计一致。 +- 原始描述允许自然语言请求,后续规格把产品入口收敛为有限表单和受控 Goal。LLM 仍在 + 根图内完成语义/规划、工具选择、Observation 后续决策和批准后 Verifier,不需要通过 + 无边界聊天框证明 Agent 属性。 +- 早期证据文档记录了当时查询路径不调用模型、旧图或尚未发布等历史事实;当前运行事实 + 以单根 Agent Loop 证据、`current-state.md` 顶部和最新 main CI 为准。历史记录不能被 + 反向解释为当前架构。 + +## 当日新鲜验证 + +- GitHub PR #20 已合并为 main `764f4b5`,main Actions run `30614799180` 五项成功: + repository safety、Python quality、完整 backend、frontend、真实 Compose restart/recovery。 +- 本分支 README/CONTRIBUTING/文档索引定向测试:`14 passed`。 +- GitHub Markdown API 保留两个同名 `
` 分组和默认 `open` 属性,中英文可在同一 + README/CONTRIBUTING 页面互斥展开,不跳转独立语言文件。 +- `https://opercerta-kxh.netlify.app/`、`/console` 和 `/api/v1/auth/demo-token` 均返回 + `200 text/html`;最后一项再次证明公网是静态 SPA,不是 API。 +- 本机 `opercerta-demo` PostgreSQL、Redis、MCP、API 四容器 healthy;readiness 返回 + database/checkpoint/MCP 全部 ready。 +- `docker compose -f compose.release.yaml config --quiet` 通过,说明发布拓扑配置可解析; + 它不等同于公网环境、备份、容量或安全验收。 + +## 尚存问题与优先级 + +### P0:公网交互或生产上线前必须完成 + +- 部署真实 HTTPS FastAPI 后端,并配置与前端完全匹配的 CORS 和公开入口。 +- 用生产身份系统替换本地 demo JWT 签发;补齐身份生命周期、最小权限和会话吊销。 +- 增加限流、配额、模型费用熔断、防滥用、托管密钥和安全数据重置。 +- 使用托管/受维护的 PostgreSQL,完成备份、恢复演练、迁移编排和故障回滚。 +- 部署日志/Trace/指标采集、dashboard 和告警;当前只有埋点与本地测试。 +- 增加公网端到端、浏览器 CORS、超时、并发和失败恢复验收。 + +### P1:优质公开仓库建议补齐 + +- 当前 GitHub community profile 为 42%;缺少明确 `LICENSE`、`SECURITY.md`、 + Code of Conduct、Issue/PR 模板。 +- main 分支尚未启用 branch protection;目前依靠人工坚持 PR 全绿后合并。 +- 缺少独立 ADR 目录;架构取舍存在于规格和技术手册中,但不利于外部贡献者快速定位。 +- 当前真实模型只做少量代表调用,adapter 又没有供应商 usage,不能给出准确率、Token、 + 成本或 SLA 结论。 + +### P2:增强可信度而非阻塞本地 MVP + +- 增加独立人工标注的业务质量集和多次真实模型运行,报告失败样本与方差。 +- 增加 Playwright 类完整浏览器 E2E、无障碍和 Lighthouse 证据。 +- 为容器基础镜像增加 digest/供应链更新策略,为公开部署增加 SBOM 或漏洞扫描。 + +## 发布与作品使用结论 + +| 使用方式 | 当前结论 | 允许表述 | +| --- | --- | --- | +| GitHub 开源源码 | 可用 | 可复现、经过 CI 的受控运营 Agent MVP | +| Netlify 静态项目页 | 已上线 | 公开只读项目说明和静态功能展示 | +| 本地/现场完整演示 | 可用 | Docker Compose 单节点三业务完整闭环 | +| 公网交互演示 | 未完成 | 不可称在线可操作 Agent;需要后端部署与安全治理 | +| 企业生产系统 | 未完成 | 不可声称生产高可用、SLA、真实 WMS/CMMS 接入 | + +因此,OperCerta 已可作为个人 Agent 项目写入简历并用于本地面试演示,前提是明确写成 +“可部署单节点 MVP + 公开静态项目页”,并能亲自解释和操作业务闭环。若希望审阅者无需 +本地环境直接操作真实 Agent,则仍需完成 P0 中的公网交互演示子集;若希望称为生产系统, +则必须完成全部 P0 并补充运行期证据。 + +## 原始完成定义对照 + +| 完成定义 | 状态 | +| --- | --- | +| 核心业务成功/失败/拒绝终态闭环 | 通过 | +| 状态、工具、权限和异常路径测试 | 通过 | +| 固定评测与可重复性能/缓存报告 | 通过,样本边界已声明 | +| 干净 Docker Compose 启动与重启恢复 | 通过 | +| 在线地址可以完成真实核心业务 | 未通过;当前仅静态页 | +| README、架构、API/部署/限制文档 | 部分通过;内容充分但正式 ADR/安全治理文件缺失 | +| 日志、Trace、Token、成本与关键指标 | 部分通过;Trace/指标具备,供应商 usage/公开观测后端缺失 | +| 无密钥、无旧单位专有内容、无未授权材料 | 仓库安全门禁通过 | +| Release tag 与验收记录 | 通过,现有 Showcase pre-release | +| 可重复演示与学习材料 | 材料通过;个人脱稿掌握仍需本人验收 | + diff --git a/docs/development-log/daily/2026-07-31.md b/docs/development-log/daily/2026-07-31.md index d58f00b..39b14e7 100644 --- a/docs/development-log/daily/2026-07-31.md +++ b/docs/development-log/daily/2026-07-31.md @@ -32,3 +32,21 @@ - 扩展 `CONTRIBUTING.md`,补齐开发环境、TDD、Agent 安全边界、质量门禁、PR 检查表和安全报告;新增等价的 `CONTRIBUTING.zh-CN.md`。 - README 不再链接面向个人复盘的讲解材料、组合项目设计或过时的原始设计入口;历史文档继续留在仓库和 `DOCUMENT_INDEX.md` 中供追溯,不做破坏性删除。 - 新增文档防漂移测试,约束中英文互链、关键技术栈、快速启动、真实模型代表验证边界以及不得重新引入明显求职导向内容。 + +## README 页内双语与发布就绪复核 + +- 根据复核意见,将 `README.md` 和 `CONTRIBUTING.md` 从独立语言文件跳转改成 GitHub + 原生同名 `
` 分组:默认展开简体中文,点击 English 在同一页面切换;GitHub + Markdown API 已确认分组属性和默认展开属性均被保留。 +- 删除独立 `README.zh-CN.md`、`CONTRIBUTING.zh-CN.md`,同步修正贡献指南、文档索引 + 和防漂移测试,避免仓库首页进入单独 Markdown 文件页。 +- README 徽章从 CI、Python、React、Compose 扩展为 Agent、API、数据、前端、流式、 + 可观测性、容器和 CI/CD 共 23 项实际技术;公开入口只保留 + `https://opercerta-kxh.netlify.app/`,移除重复 Release 链接和“只读项目页”标签。 +- 完整复核四份原始设计、三业务/Agent/信号/单根图有效修订、当前源码、迁移、Compose、 + CI 与发布证据,形成 + `docs/development-log/audits/2026-07-31-spec-release-readiness-audit.md`。 +- 新鲜事实:公开 Netlify 根页、`/console`、`/api/*` 均为 `200 text/html`,证明其仍是 + 静态 SPA;本机 demo API readiness 为 database/checkpoint/MCP 全 ready;release + Compose 配置解析通过。结论保持“本地完整 Agent MVP + 公网静态展示”,公网交互和 + 企业 production gate 仍关闭。 diff --git a/tests/unit/runtime/test_release_assets.py b/tests/unit/runtime/test_release_assets.py index d1af6fd..ab14f62 100644 --- a/tests/unit/runtime/test_release_assets.py +++ b/tests/unit/runtime/test_release_assets.py @@ -107,35 +107,51 @@ def test_learning_pack_covers_three_business_manual_failure_and_interview_explan def test_release_documents_keep_verified_boundaries_truthful() -> None: readme = (ROOT / "README.md").read_text(encoding="utf-8") - readme_zh = (ROOT / "README.zh-CN.md").read_text(encoding="utf-8") state = (ROOT / "docs" / "development-log" / "current-state.md").read_text(encoding="utf-8") assert "Private GitHub" not in readme assert "Private GitHub" not in state assert "Not production-ready" in readme - assert "尚未达到生产就绪" in readme_zh + assert "尚未达到生产就绪" in readme assert "真实模型代表性" in state assert "尚未" in state -def test_public_entry_documents_are_bilingual_and_project_focused() -> None: +def test_public_entry_documents_switch_language_in_place_and_are_project_focused() -> None: readme = (ROOT / "README.md").read_text(encoding="utf-8") - readme_zh = (ROOT / "README.zh-CN.md").read_text(encoding="utf-8") contributing = (ROOT / "CONTRIBUTING.md").read_text(encoding="utf-8") - contributing_zh = (ROOT / "CONTRIBUTING.zh-CN.md").read_text(encoding="utf-8") - assert "[简体中文](README.zh-CN.md)" in readme - assert "[English](README.md)" in readme_zh - assert "[简体中文](CONTRIBUTING.zh-CN.md)" in contributing - assert "[English](CONTRIBUTING.md)" in contributing_zh - assert readme.count("\n## ") == readme_zh.count("\n## ") - assert contributing.count("\n## ") == contributing_zh.count("\n## ") - assert "## 中文说明" not in readme - assert "## Why OperCerta" not in readme_zh + assert not (ROOT / "README.zh-CN.md").exists() + assert not (ROOT / "CONTRIBUTING.zh-CN.md").exists() + assert readme.count('
None: "作品集", ): assert forbidden.lower() not in readme.lower() - assert forbidden.lower() not in readme_zh.lower() def test_agent_delivery_documents_cover_architecture_learning_and_truthful_evidence() -> None: @@ -206,7 +221,6 @@ def test_agent_delivery_documents_cover_architecture_learning_and_truthful_evide def test_current_demo_and_learning_docs_match_the_single_root_agent_release() -> None: readme = (ROOT / "README.md").read_text(encoding="utf-8") - readme_zh = (ROOT / "README.zh-CN.md").read_text(encoding="utf-8") demo = (ROOT / "docs" / "demo-script.md").read_text(encoding="utf-8") manual = (ROOT / "docs" / "learning" / "opercerta-manual-experiment-guide.md").read_text( encoding="utf-8" @@ -223,15 +237,13 @@ def test_current_demo_and_learning_docs_match_the_single_root_agent_release() -> assert "新 Agent 核心的 Real Kimi Tool Calling 代表 query 为 failed" not in content normalized_readme = " ".join(readme.split()) - normalized_readme_zh = " ".join(readme_zh.split()) assert ( "three read-only business paths, an approved inventory write, and " "invalid-provider fail-closed" in normalized_readme ) - assert "三业务只读、库存批准写入和无效 provider fail-closed" in normalized_readme_zh + assert "三业务只读、库存批准写入和无效 provider fail-closed" in normalized_readme assert "667 条后端测试" in interview - assert "v0.1.0-showcase.1" in readme assert "v0.1.0-showcase.1" in interview assert ".worktrees/agent-core-implementation" not in manual assert "cd frontend" not in manual