06-验收与测试锚点.md 12 KB

06-验收与测试锚点

对应架构文档第 11 节 MVP 验收标准,逐条映射到 requirement_id,并给出 M/V/C/P 覆盖和至少 3 类验收用例(happy / boundary / failure)。场景统一采用"贪吃蛇游戏"作为验收任务。

REQ-01:Org Graph 三节点链路可触发

  • 覆盖:M=org_graph_definition,task;C=c_task_create,c_org_node_trigger;P=p_org_task_lifecycle
  • 验收用例:
    • happy:创建 goal_text="实现贪吃蛇游戏" 的 task,依次触发 planner/coder/validator 三个 org_node,task.status 按状态机正确流转
    • boundary:max_concurrent_goals=1 时,同时创建第二个 task,验证其落 queued 而不被立即调度
    • failure:goal_text 为空时 c_task_create 返回 INVALID_PARAM

REQ-02:Planner 产出四类 Artifact 并通过校验

  • 覆盖:M=artifact,work_graph_run;V=v_task_detail;C=c_work_graph_plan,c_work_graph_execute,c_artifact_write;P=p_work_graph_execution
  • 验收用例:
    • happy:Planner Work Graph 跑完后,artifact 表中存在 brd/prd/sdd/benchmark 四条记录,且 depends_on_artifact_ids 血缘链完整(sdd→prd→brd)
    • boundary:PRD 中出现互相矛盾的场景假设时,一致性校验应在 verifying 态被拦截,触发 reflecting 而非直接放行
    • failure:sdd 生成时找不到对应 prd 版本引用,c_artifact_write 应拒绝写入(depends_on_artifact_ids 指向不存在的 artifact_id)

REQ-03:Coder 依据 SDD 完成编码并自测通过

  • 覆盖:M=work_node_execution;C=c_work_node_run;P=p_work_graph_execution
  • 验收用例:
    • happy:Coder Work Graph 完成后产出 code_diff 与 test_report 两类 artifact,且 unit + integration test 全部通过
    • boundary:两个无依赖的模块并行编码,验证各自 git_worktree_ref 不冲突,合并后代码无冲突残留
    • failure:某模块单测失败,work_node_execution.status 应为 reflecting→retrying,达到节点级重试上限后冒泡为 blocked

REQ-04:Validator 完成测试/Benchmark + 根因归属 + 结构化 bug list

  • 覆盖:M=bug_record;C=c_bug_record_create;P=p_validator_root_cause_trace
  • 验收用例:
    • happy:人为植入一个"边界撞墙判定错误"的 bug,Validator 应判定 root_cause_category=coder(而非 planning 或 skill_defect),且 root_cause_detail 引用具体 SDD 章节和代码位置
    • boundary:植入一个"PRD 未定义撞墙行为"的需求缺口型 bug,Validator 应判定 root_cause_category=planning
    • failure:三视角判断不一致时,流程应落在 inconclusive_escalate 而不是强行给出一个归因结论

REQ-05:Org-level Loop 完整闭环

  • 覆盖:C=c_org_loop_route;P=p_org_task_lifecycle
  • 验收用例:
    • happy:REQ-04 的 bug 记录经 suggested_route=fast_lane 路由后直达 Coder,修复后重新进入 Validator,最终 task.status=done,全程 loop_round 从 0 增至 1
    • boundary:suggested_route=full_replan 时应回到 Planner 而非 Coder,验证路由分支正确
    • failure:连续 3 轮同一 bug 未收敛,task.status 应转 blocked_pending_human 且调度器继续执行队列中其他任务(若有)

REQ-06:Graph Engine 断点恢复

  • 覆盖:M=work_graph_run,work_node_execution;P=p_work_graph_execution
  • 验收用例:
    • happy:在 work_graph_run.status=running 时人为中断进程,重启后能从已持久化的 work_node_execution 状态继续,不重跑已 done 的节点
    • boundary:中断发生在某节点 retrying 中途,重启后应恢复到该节点重试逻辑而非跳过
    • failure:持久化数据损坏(模拟)时,系统应明确报错并转 blocked_pending_human,而不是静默丢失进度继续跑

REQ-07:执行器抽象层(Claude Code ACP 后端)可用

  • 覆盖:C=c_work_graph_execute;对应 05 节 5.3(架构文档 7.2 节决策,2026-07-29:MVP 阶段只用 Claude Code ACP 一种后端,不再考虑 Hermes CLI)
  • 验收用例:
    • happy:Claude Code ACP 后端下完整跑通 REQ-01~06 全部场景
    • boundary:claude -p 调用不加 --bare(见 A-1 spike 结论),确认额外冷启动开销在可接受范围内
    • failure:auto mode 分类器连续拦截 3 次或累计 20 次,返回 CLASSIFIER_BLOCKED,task 转 blocked_pending_human,blocked_reason=classifier_blocked

REQ-08:Skill 自主迭代 + Git 可追溯可回滚

  • 覆盖:M=skill,skill_iteration;V=v_skill_audit_log;C=c_skill_update,c_skill_rollback
  • 验收用例:
    • happy:REQ-04 中判定 root_cause_category=skill_defect 的 bug 触发 c_skill_update,生成独立 Git commit,v_skill_audit_log 可查看该次变更
    • boundary:triggered_by_bug_id 缺失时 c_skill_update 应拒绝(不允许无来源变更)
    • failure:c_skill_rollback 到不存在的 iteration_id 应返回 ITERATION_NOT_FOUND

REQ-09:循环终止与人工升级

  • 覆盖:P=p_org_task_lifecycle 的 blocked_pending_human 分支
  • 验收用例:(与 REQ-05 failure 用例共享验证场景)
    • happy:blocked_pending_human 后,人工在 v_task_detail 点击"人工干预"(manual_resume),任务能恢复到触发前状态继续执行
    • boundary:多个任务同时有一个 blocked_pending_human、其余 queued 时,调度器应继续调度 queued 任务,不被阻塞任务卡住
    • failure:manual_resume 在任务已经是 done 终态时调用,应返回明确错误而非误操作已完成任务

REQ-10:预算护栏双层机制

  • 覆盖:M=budget_guardrail_config;V=v_budget_settings;C=c_budget_check,c_budget_config_update;P=p_budget_guardrail
  • 验收用例:
    • happy:配置 limit_type=token_count, limit_value=<小值>,运行到超限后任务自动转 blocked_pending_human,blocked_reason='budget_exceeded'
    • boundary:调高额度后(c_budget_config_update),paused 态任务能恢复调度
    • failure:budget_guardrail_config 触发的超限走 blocked_pending_human;Claude Code plan 额度耗尽走独立的 p_usage_limit_wait 子流程(见 REQ-14),两者不应共用同一个 blocked_reason

REQ-14:Claude Code plan 额度耗尽的等待重试(架构文档 7.5 节决策,2026-07-29)

  • 覆盖:M=work_node_execution(status=waiting_for_quota、quota_wait_started_at、quota_limit_type);V=v_dashboard,v_graph_visualizer;C=c_work_node_run,c_org_node_trigger;P=p_usage_limit_wait
  • 验收用例:
    • happy:模拟 claude -p 返回 You've hit your session limit,work_node_execution.status 转 waiting_for_quota,退避轮询后探测成功恢复正常执行,全程不产生 blocked_pending_human
    • boundary:quota_limit_type=opus 时不走退避轮询,直接降级到非 Opus 模型重试
    • failure:模拟超过超时阈值(session 8 小时 / weekly 9 天)仍未恢复,转 blocked_pending_human,blocked_reason='usage_limit_wait_timeout'

REQ-11:项目创建与人机交互入口(架构文档第 13 节)

  • 覆盖:M=project,bug_record;V=v_project_setup,v_goal_composer,v_bug_feedback;C=c_project_create,c_task_create,c_bug_report_create;P=p_validator_root_cause_trace(human_reported 起点)
  • 验收用例:
    • happy:选择一个已有 Git 仓库的本地文件夹创建项目 → .graphlemon/ 子目录被创建 → 通过 v_goal_composer 提出"实现贪吃蛇游戏"目标 → 成功创建 task 并进入 Org Graph
    • boundary:选择一个非 Git 仓库的文件夹,用户确认初始化后应执行 git init 并继续;用户不确认则整个创建流程中止,不留下任何写入
    • failure:对同一 target_folder_path 重复调用 c_project_create,应幂等返回已有项目而非报错或创建重复记录;v_bug_feedback 提交空 description 应被前端和后端双重拦截

REQ-12:实时看板(架构文档 13.1 节决策 3)

  • 覆盖:M=execution_event;V=v_dashboard,v_graph_visualizer,v_task_detail;C=c_ws_subscribe
  • 验收用例:
    • happy:某 work_node_execution.status 变化后,v_graph_visualizer 对应节点应在可感知的短时间内(作为非功能验收目标,建议 ≤2 秒)完成着色更新,无需人工刷新页面
    • boundary:WebSocket 连接断开后自动重连,重连期间页面展示"实时连接已断开,正在重连"而不是冻结或报错崩溃;重连后能补齐断线期间遗漏的关键状态(通过重新拉取 task/work_graph_run 当前快照兜底,不要求完整补齐每一条中间事件)
    • failure:订阅一个不存在的 project_id,连接应被拒绝并返回 PROJECT_NOT_FOUND,而不是建立空连接后无声无息不推送任何数据

REQ-13:原始日志控制台内查看 + 定时清理(架构文档 13.1 节决策 4)

  • 覆盖:M=execution_log_file,log_retention_config;V=v_log_viewer,v_log_retention_settings;C=c_execution_log_get,c_ws_log_tail,c_log_retention_config_update;P=p_log_retention_cleanup
  • 验收用例:
    • happy:某 Work Node 运行中,v_log_viewer 能实时滚动显示新追加的日志内容;节点结束后自动切换为静态模式,仍可完整查看
    • boundary:配置 retention_days=1,构造一条 created_at 超过 1 天的 closed 状态日志,清理任务运行后应转为 purged 且物理文件被删除;v_log_viewer 打开该日志时展示"已被清理"提示而非报错
    • failure:订阅一个不存在的 node_exec_id 的日志流,应返回 NODE_EXEC_NOT_FOUND;清理任务遇到某个文件删除失败(如被占用)时,应仅记录该项失败、不影响其余候选项的清理,且该条目下次周期继续重试

REQ-15:Deploy Supervisor 蓝绿部署与自动回滚(PH5 新增,2026-07-30,见 docs/done/supervisor-auto-rollback-design.md)

  • 覆盖:M=deployment,deploy_health_signal,bug_record(root_cause_category=core_engine);C=c_deploy_supervisor_stage,c_deploy_supervisor_health_check,c_deploy_supervisor_cutover,c_deploy_supervisor_monitor,c_deploy_supervisor_rollback,c_org_loop_route;P=p_deploy_supervisor_blue_green
  • 验收用例:
    • happy(正常 cutover 到 finalize):graphlemon 自身仓库一处真实植入 bug(self-development-feasibility.md 第 3 节场景),标记 root_cause_category=core_engine,Coder 修复、Validator PASS、worktree 合并主分支后,Deploy Supervisor 依次完成 staged→candidate_starting→health_check_running→health_check_passed→cutover_in_progress→live→monitoring,监控窗口内四类信号均正常,最终 monitoring_window_clean→finalized,全程无需人工评审代码内容
    • boundary(路径 A:健康检查失败):人为让候选实例的 canary_task 检查失败(如返回结果与预期不符),Deploy Supervisor 应立即判定 health_check_failed,不重试,直接走回滚路径 A(终止候选、git revert、发 bug_record),Live 全程未受影响,可通过对比 Live 进程 PID/端口在 cutover 前后未发生变化来验证
    • boundary(路径 B:post-cutover 异常回滚):cutover 完成后,人为把 validator_approval_rate 信号推到偏离历史基线阈值(VALIDATOR_RATE_DEVIATION_THRESHOLD,05 节 §5.9)之外,Deploy Supervisor 应判定 anomaly_detected,走回滚路径 B,最终 previous_instance_dir 重新成为 Live,rolled_back,生产库数据在整个过程中未丢失(因为生产库本身没有被替换,只是替换了跑在它前面的代码进程)
    • failure(回滚本身失败):人为让 previous_instance_dir 也无法正常启动(如故意损坏该目录),路径 B 的回滚应终态到 rollback_failed→blocked_pending_human,blocked_reason='rollback_failed',且控制台展示的原因应清楚区分"自动恢复机制本身失效"与"代码内容有问题"两种情况,不能让用户误以为又需要人工评审代码