# 05-实施约束与依赖 ## 5.1 现有资产复用清单(来自本地 Hermes profile 调研,架构文档第 9 节) | Org Agent | 复用来源 | 复用内容 | 迁移动作 | |---|---|---|---| | Planner | `~/.hermes/profiles/planning/` | `SOUL.md`(16 条根本原则);`planning-requirement-expansion`、`project-brd-planning`、`project-prd-planning`、`project-sdd-planning`(本 SDD 采用的方法论本身)、`project-unit-decomposition`、`review-blocker-verification` 等 skill | `SOUL.md` 正文迁移到目标项目 `.claude/agents/planner.md`(frontmatter 配 `skills:`/`memory: project`/`tools:`/`model:`,见架构文档 7.2 节),skill 迁移到 `graphlemon/skills/*` 供 `skills:` 字段引用 | | Coder | `~/.hermes/profiles/code/` | `SOUL.md`(认领→实现→测单→证据回写);`code-task-development`、`code-agent-engineering`、`debugging-toolkit`、`software-planning-execution` | 迁移到 `.claude/agents/coder.md` + `graphlemon/skills/*`,**需要改造**:原流程强绑定飞书 Base 认领机制,改为消费 `task` 表 + `c_org_node_trigger` | | Validator | `~/.hermes/profiles/qa/` | `SOUL.md` + `AGENTS.md`(三态判定、双向可追溯矩阵、工作区权限契约);`qa-task-validation`、`unattended-agent-operations` | 迁移到 `.claude/agents/validator.md`(`AGENTS.md` 的工作区权限契约折入 `tools`/`disallowedTools` frontmatter),双向可追溯矩阵直接对应 04-P `p_validator_root_cause_trace` 的血缘追溯步骤 | **不复用**:三个 profile 的 `memories/MEMORY.md`/`USER.md`(内容重叠、未按角色隔离);`.archive/`、`migration/`、`openclaw-imports/` 下的通用助理技能(apple、creative、feishu-lark 等)。 ## 5.2 飞书 Base 替换计划(架构文档 12.1 节已确认) - 不做历史数据自动迁移,MVP 从空任务队列开始运行 - 原 `lark-cli --as user` 的认领/回写语义,改由 `c_org_node_trigger` + `task.status` 状态机承接 - 原飞书 Base 的人工可视化能力,由本 SDD 02-V 的 `v_task_board`/`v_task_detail`/`v_graph_visualizer` 承接 ## 5.3 执行后端范围(架构文档 7.2 节决策,2026-07-29,取代此前"双后端不对等"框架) - MVP 阶段只实现并使用 **Claude Code ACP** 一种执行后端,不考虑 Hermes CLI 作为执行后端。此前"Org Graph 层两后端一致、Work Graph 层两后端不对等"的处理方案已作废——不存在第二个后端。 - Org Graph 层:`c_org_node_trigger` 底层是 `claude --agent -p "..."`,Org Agent 身份由目标项目 `.claude/agents/*.md` 承载(见 5.1 节迁移动作) - Work Graph 层:`c_work_graph_execute` 跑完整的 fan-out/fan-in/loop 能力(见 03-C 3.5 节),MVP 验收标准是这一条能跑通即可,不再需要"至少验证一种后端"这类留有余地的表述 - `v_graph_visualizer` 不再需要"简化模式"展示逻辑(02-V 2.7 节保持单一展示模式) - Executor Interface 的抽象层设计仍保留为未来扩展点,但不是当前实现范围 ## 5.4 依赖的外部能力(对应 00 节 A-1,已通过 spike 实测确认) - Claude Code 动态工作流的 `agent()`/`parallel()`/`pipeline()` 原语已实测确认可通过 `claude -p`(非交互式)编程方式调用,方案 A 成立(`spikes/a1-dynamic-workflows/`,真实账号验证,2026-07-29,成本 $0.46): - `claude -p 'Run / with args {...}' --output-format json --json-schema < /dev/null` 无交互提示、无挂起、40s 内完成,`structured_output` 精确匹配预期输出,`permission_denials` 为空 - **发现的约束**:不能加 `--bare`。`--bare` 会跳过登录态/凭据发现(报 `Not logged in`,与是否存在 workflow 无关),必须用不带 `--bare` 的完整冷启动调用,代价是启动稍慢,但可靠性优先 - 具体实现契约(写入 workflow 脚本、子进程调用、解析 `structured_output`、回填预算用量)已落地到 03-C 3.5 节 - 原风险已解除,不再需要在实施第一周单独排期做技术验证;架构文档 10.1 节的方案 B(完全自研 Graph Engine)作为长期备选保留,暂不启用 ## 5.4.1.1 `--agent` 与 `--json-schema` 不能同时生效(发现,2026-07-31,U-011) - 实测确认:`claude --agent -p ... --json-schema ` 时,`--json-schema` 被静默忽略——返回的 JSON payload 里 `structured_output` 字段整个不存在,模型改成把结构化内容以自由文本 + ```` ```json ```` 围栏代码块的形式塞进 `result` 字段里;但 `--agent` 本身工作正常(人设确实生效,回复里引用了迁移后 SOUL.md 的具体条目编号) - 这条约束和 5.4 节 A-1 spike 的场景不同:A-1 验证的是**不带 `--agent`** 的动态工作流调用(`claude -p 'Run /...'`),`--json-schema` 在那种调用形式下是生效的(`structured_output` 精确匹配);只有**同时**传 `--agent` 和 `--json-schema` 时才会出现这个静默失效 - **应对方式**:需要"某个 Org Agent 身份 + 结构化输出"同时成立时(如 `c_work_graph_plan`,见 03-C 3.4 节/U-011),不要依赖 `--json-schema`/`structured_output`,改为在 prompt 里明确要求模型把结果包在单个 ```` ```json ```` 围栏代码块里,再从 `result` 字段用正则提取解析,对"整段就是 JSON"和"围栏代码块"两种情况都做兜底解析(参考实现:`src/work_graph_plan.py` 的 `_extract_graph_manifest`) - 未在 Anthropic 官方文档里找到这条限制的说明,是靠实测发现的,不排除后续版本行为会变——如果这里升级过 Claude Code 版本,值得重新验证一次 ## 5.4.2 Claude Code plan 额度等待重试参数(架构文档 7.5 节决策,2026-07-29) - 退避轮询间隔(5→10→20→30 分钟,上限 30 分钟)、超时兜底阈值(session 8 小时、weekly 9 天)是 MVP 阶段的硬编码默认值,不在管理后台开放用户配置,和 `log_retention_config` 的"保留天数可配、清理频率不可配"是同一个 MVP 简化原则 - 这组参数的合理性依赖 Claude Code 官方文档给出的窗口周期(5 小时滚动 / 7 天)本身不变;若未来 Claude Code 调整了额度窗口周期,需要同步调整这里的超时阈值,不是一次性写死可以忽略的常量 ## 5.3.1 `c_work_graph_execute` 权限模式决策(03-C 3.5 节,2026-07-29) - 选定 `--permission-mode auto`,而非 `--dangerously-skip-permissions`/`bypassPermissions`:后者官方文档明确要求只能在隔离容器/VM+无网络访问环境下使用;graphlemon 目前的节点隔离手段(git worktree)是同机目录级隔离,达不到这个前提,用 `bypassPermissions` 会暴露 prompt injection 风险 - **约束 1(模型选型)**:`auto` mode 要求会话模型为 Claude Sonnet 5 / Opus 4.7+ / Fable 5(Anthropic API 上),架构文档 10 节"按节点分层选模型"给 Coder/Validator 节点选便宜模型时不能选到这个集合以外 - **约束 2(失败模式)**:`-p` 非交互模式下,分类器连续拦截 3 次或累计 20 次会导致会话直接中止(无人可确认),对应 `c_work_graph_execute` 新增 `CLASSIFIER_BLOCKED` 错误码,路由到 `blocked_pending_human`(04-P 已补充) - **待办(非 MVP 阻塞项,值得后续排期)**:`auto` mode 支持通过"受信任基础设施"配置(`autoMode.environment`)减少误拦截,architecture.md 目前未定义 graphlemon 自己的可信基础设施清单(例如目标项目的 git remote、允许访问的包registry等),MVP 阶段先接受更高的误拦截率、靠人工在 `v_task_detail` 复核放行,后续可评估是否要把这份配置纳入 `org_graph_definition` 或新增专门的设置页 ## 5.4.1 控制台载体形态的实施约束(架构文档 13.1 节决策 5,已确认) - 控制台是本地 Web 应用,后端是本机常驻进程(同时也承担 Graph Engine 的调度职责),前端是普通网页,两者本地通信(如 `localhost` 端口) - `c_pick_folder` 依赖后端所在操作系统的原生对话框能力:macOS 用 `osascript`,Windows/Linux 需要各自的原生方案(如 PowerShell 脚本 / `zenity`/`kdialog`),实施时需要按目标操作系统分别验证,不是一套代码天然跨平台 - 若后端运行在无图形界面的环境(纯服务器/容器),`c_pick_folder` 会返回 `DIALOG_UNAVAILABLE`,`v_project_setup` 需要有手动路径输入的兜底交互(MVP 阶段可以直接做成兜底默认项,不必等图形环境不可用时才现场适配) ## 5.5 上线顺序与兼容性 1. 先落地 01-M 的数据模型(`task`/`artifact`/`skill` 等核心表)+ Git 仓库目录结构(架构文档 7.3 节) 2. 再落地 Org Graph 层接口(3.1-3.3, 3.11-3.13)+ `p_org_task_lifecycle` 状态机,此时可先用手工调用验证 Planner/Coder/Validator 三个 Org Agent 分别可被触发 3. 最后落地 Work Graph 层(3.4-3.6)与 Claude Code 动态工作流的集成;A-1 已通过 spike 实测确认(见 5.4 节),可按 03-C 3.5 节的已验证实现契约直接开发,无需再单独排期做技术验证 ## 5.6 迁移与回滚约束 - `org_graph_definition` 的变更(Org Graph 结构本身)走人工 PR 评审流程,不允许系统自主提交 - `skill` 的自主迭代(`c_skill_update`)允许系统自主提交,但必须可通过 `c_skill_rollback` 一键回滚到迭代前版本 - MVP 阶段数据库 schema 变更暂不考虑蓝绿发布/双写迁移(单用户本地运行,允许停机迁移)——**例外**:graphlemon 平台自身的 self-target 场景不适用这条"允许停机迁移"的简化假设,见 5.8 节 ## 5.7 graphlemon 自身实现技术栈(决策,2026-07-30) - graphlemon 自身的后端(HTTP API + WebSocket/SSE server + Graph Engine 调度)与 PH5 的 Deploy Supervisor 进程,统一采用**纯 stdlib Python** 实现,不依赖任何第三方包(不用 Flask/FastAPI/Express/Node.js),对齐前身项目 graphloop 的既有约定(`graphloop/CLAUDE.md`原话:"Everything is stdlib: argparse, sqlite3, http.server, subprocess, threading, unittest, etc.") - 前端是本地 Web 应用(浏览器页面),后端用 `http.server`/`socketserver` 等 stdlib 原生能力提供 HTTP API;WebSocket 若 stdlib 支持不足,实施时(U-007)需要验证并可退化为 SSE/长轮询,但仍在 stdlib 范围内解决,不引入第三方包;前端不引入 npm/构建步骤,可以是原生 HTML/CSS/JS 或参考 graphloop `graph.html`/`project.html` 的单文件 no-build 页面模式 - **例外**:这条约束只针对 graphlemon 平台自身的实现语言,不代表 graphlemon 生成/审查的目标项目代码也必须是 Python——目标项目用什么语言由目标项目自己的技术栈决定 - **影响**:development-plan.md 的 U-007(本地后端骨架)、U-008(前端骨架)、U-036(Deploy Supervisor 骨架)的 Done 标准隐含"纯 stdlib"这条约束 - **源码目录约定(2026-07-30 补充,2026-07-31 订正)**:graphlemon 平台自身的后端源码(U-001 的 schema 实现、U-007 起的 HTTP/WebSocket 后端)落在 graphlemon 仓库根目录的 `src/`。这与**目标项目**仓库自己已有的 `src/` 是两个完全不同的目录,分属两个物理仓库(见架构文档 §13.1"目标项目是独立代码空间"决策)——PH5 self-target 场景下二者会同时存在于同一台机器上,实现时不要混淆,必要时以绝对路径而非相对路径区分。**订正**:目标项目的 `src/` 不是 U-002 生成的——U-002 只在目标项目里创建 `.graphlemon/` 子目录(架构文档 §13.2),目标项目自己的 `src/` 是其原有源码目录,graphlemon 不创建也不规定其结构;development-plan.md 此前 U-002 那行误引用了架构文档 §7.3 的旧目录树,已于 2026-07-31 订正(§7.3 是"graphlemon 只服务自己开发自己"阶段的旧设计,已被 §13 取代,§7.3 里的 `.claude/agents/`、`skills/`、顶层 `runs/` 实际是 graphlemon 平台自己仓库的资产,属于 U-003 范围) ## 5.8 self-target 场景治理规则(`self-development-feasibility.md` 缺口 1/3,2026-07-30 回填) - **worktree 无条件强制**:`target_folder_path == graphlemon 平台自身安装路径` 时,无论并行还是串行,Coder/Validator 一律强制使用 `git_worktree_ref`,不适用 03-C 3.6 节"仅并行写代码节点才强制申请 worktree"的一般规则——这是该规则的 self-target 特例 - **`core_engine` 分类路由**:`bug_record.root_cause_category` 新增枚举值 `core_engine`,覆盖 `.claude/agents/*.md` 身份文件变更、Graph Engine 调度器/执行器抽象层核心逻辑变更、01-M 自身数据库 schema 变更三类场景。命中 `core_engine` 时,`c_org_loop_route`(03-C)路由到 PH5 的 `p_deploy_supervisor_blue_green` 流程(04-P),而不是常规的 `fast_lane`/`full_replan` - **不要求提交前人工评审**:`core_engine` 改动不强制在合并主分支前经过人工评审(此前"比照 `org_graph_definition` 强制人工 PR 评审"的提案已被用户明确否决),改为合并后由 Deploy Supervisor 持续监控运行时行为、检测异常时自动回滚(见 04-P `p_deploy_supervisor_blue_green`、`docs/supervisor-auto-rollback-design.md`)。5.6 节"允许停机迁移"的简化假设不适用于这类 self-target 场景——self-target 的 schema 变更同样走蓝绿部署+监控流程,不是简单停机迁移 ## 5.9 Deploy Supervisor MVP 固定参数(`docs/supervisor-auto-rollback-design.md` §9,2026-07-30 回填) | 参数 | 草案值 | 说明 | |---|---|---| | `HEALTH_CHECK_STARTUP_TIMEOUT` | 30s | Candidate 进程从拉起到能响应探活 | | `HEALTH_CHECK_HTTP_TIMEOUT` | 10s | 单次 `/api/health` 请求 | | `HEALTH_CHECK_CANARY_TIMEOUT` | 120s | 一次最小 canary 任务从提交到出结果 | | `MONITOR_SAMPLE_INTERVAL` | 5min | process/http 采样间隔 | | `CANARY_INTERVAL` | 1h | 监控期 canary 任务运行间隔 | | `MAX_CRASH_COUNT` / `CRASH_WINDOW` | 2 次 / 10min | 判定进程反复崩溃 | | `MAX_CONSECUTIVE_HTTP_FAIL` | 3 次 | 判定健康端点持续不可用 | | `VALIDATOR_RATE_DEVIATION_THRESHOLD` | ±30 个百分点 | 判定 Validator 行为异常(`validator_approval_rate` 信号阈值) | | `MONITORING_WINDOW_HOURS` | 24h | 监控窗口时长上限 | | `MONITORING_MIN_TASK_COUNT` | 10 个真实任务 | 监控窗口任务数上限,先到者结束 | **与 5.4.2 节额度等待参数的差异**:5.4.2 节的退避/超时参数依据是 Anthropic 平台文档定义的外部事实(5 小时/7 天窗口周期),可以合理标注为"MVP-fixed";本节这组阈值是纯粹的工程经验草案,没有类似的外部权威来源,标注为"可调,需在真实跑通几轮自我修改后实测校准",不建议实现时直接当成不可变常量硬编码进测试断言。