01-M-模型设计.md 20.8 KB

01-M-模型设计

数据落地原则(继承架构文档 7.3 节):Artifact、代码、Skill、Memory、Agent 人设文件全部纳入 Git 仓库版本化;执行记录(状态转移、reflection 记录)独立于 Git,落结构化存储(MVP 阶段可用 SQLite/本地文件型数据库,不强制引入外部数据库服务)。

新增原则(架构文档第 13 节):目标项目是独立于 graphlemon 平台自身的代码空间。project.target_folder_path 指向的文件夹拥有自己的 Git 仓库;graphlemon 平台自己的结构化存储(本文件描述的全部实体)与目标项目的 Git 历史是两套独立的持久化,前者只是引用后者的文件路径,不托管目标项目的代码本身。

1.0 实体:project

目的:一个目标项目 = 一个独立代码空间(用户选择的本地文件夹)。MVP 阶段只有一个 active 项目,但数据模型按多项目设计以便后续扩展。

  • project_id string,pk(UUID)
  • name string,not null
  • target_folder_path string,not null,unique —— 本地绝对路径
  • has_git_repo boolean,not null —— 创建项目时校验;若原文件夹不是 Git 仓库,创建流程需询问是否代为初始化
  • graphlemon_subdir_initialized boolean,not null,default false —— 是否已在目标文件夹内创建 .graphlemon/ 子目录(见架构文档 13.2 节目录约定)
  • status enum,not null —— active|archived
  • created_at timestamp
  • 唯一约束:target_folder_path(同一文件夹不能重复创建为两个项目)
  • 并发/幂等:创建项目时若路径已存在对应 project 记录,直接返回已有记录而非报错(幂等创建)

1.1 实体:org_graph_definition

目的:Org Graph 的静态定义(Planner→Coder→Validator 三节点 + 回退边),人工维护,变更需人工评审,不由系统自主修改。

  • graph_id string,pk,如 dev-organizer
  • version string,not null(Git tag/commit 引用)
  • nodes json,not null —— 数组,每项 { node_id, role, agent_profile_ref }
  • edges json,not null —— 数组,每项 { from, to, condition }(如 validator→coder 的 condition: route==fast_lane)
  • file_path string,not null —— 指向 org/dev-organizer.graph.yaml 的相对路径
  • 状态集合:draft、active、deprecated
  • 变更约束:仅人工提交 + 评审后的 Git commit 可以更新此实体,系统不得自主写入

1.2 实体:task

目的:任务队列条目,替代原飞书多维表格的需求表/Bug 表(架构文档 12.1 节已确认)。

  • task_id string,pk(UUID)
  • project_id string,not null,fk → project.project_id
  • goal_text string,not null —— 原始 Goal 描述或 Validator 回传的 bug 任务描述
  • task_type enum,not null —— goal | bug_fix
  • origin_ref string,nullable —— 若 task_type=bug_fix,指向来源 bug_record.bug_id
  • created_via enum,not null,default api —— api|human_console(区分是控制台人工提出还是程序化创建,用于审计)
  • status string,not null —— 状态集合见 04-P 的 p_org_task_lifecycle
  • route enum,nullable —— fast_lane | full_replan(仅 bug_fix 类型需要,由 Validator 判定写入)
  • loop_round int,not null,default 0 —— 当前 Org-level Loop 已执行轮次
  • blocked_reason string,nullable —— 达到轮次上限或预算超限时的原因说明
  • assigned_org_node string,not null,fk —— 当前所处 Org Graph 节点(planner|coder|validator)
  • created_at / updated_at timestamp
  • 索引:status、assigned_org_node、project_id(用于调度器扫描和控制台按项目筛选)
  • 唯一约束:无(同一 Goal 可能因 loop 产生多条 bug_fix 类型的派生 task,但需通过 origin_ref 追溯血缘)
  • 并发/幂等:调度器认领 task 需用乐观锁(status 字段的 CAS 更新),避免并发调度重复认领

1.3 实体:work_graph_run

目的:某个 Org Agent 针对某个 task 的一次 Work Graph 执行实例(动态生成、每次任务重新规划)。

  • run_id string,pk(UUID)
  • task_id string,not null,fk → task.task_id
  • org_node string,not null —— planner|coder|validator
  • graph_manifest json,not null —— 本次生成的 Work Graph 结构化定义(节点、边、fan-out/fan-in 分组、loop 规则),对应课程里的 sdd_exec_graph_manifest.json 风格
    • 补充说明(2026-07-30,回应"task 层级关系看不出来"的核对):org_node=coder 的这份 graph_manifest 就是架构文档 §6.2 所说的"to-do list"本身——to-do 项 = graph_manifest 里的节点,to-do 项之间的先后/并行依赖 = 节点间的边和 fan-out/fan-in 分组。不新建独立的 todolist 实体或 artifact_type,避免同一份数据有两个来源。层级关系是:project → task(一个 goal = 一个 task = 一个 Org Graph)→ work_graph_run(按 org_node 各一次)→ graph_manifest 定义的 to-do/节点树 → work_node_execution → execution_log_file。控制台侧 v_task_detail 需要把这棵树画出来(见 02-V §2.6 更新),而不是平铺展示 Work Node。
  • orchestration_script_ref string,nullable —— 若走 Claude Code 原生动态工作流(架构文档 10.1 节方案 A),指向保存的编排脚本路径(.claude/workflows/<name>.js)
  • status string,not null —— 状态集合见 04-P 的 p_work_graph_execution
  • started_at / completed_at timestamp
  • result_artifact_refs json,nullable —— 本次运行产出的 artifact.artifact_id 列表
  • 生命周期:planning → running → merging → verifying → done|failed|blocked
  • 并发/幂等:同一 task_id + org_node 同一时刻只允许一个 active 状态的 work_graph_run(唯一约束:(task_id, org_node) WHERE status IN ('planning','running','merging','verifying'))

1.4 实体:work_node_execution

目的:work_graph_run 内每个 Work Node 的执行记录,对应课程"给每个节点一个契约"。

  • node_exec_id string,pk
  • run_id string,not null,fk → work_graph_run.run_id
  • node_id string,not null —— 在 graph_manifest 中的节点标识
  • subagent_type string,not null —— 绑定的 Subagent 类型
  • skill_ref string,not null,fk → skill.skill_id
  • input_schema_ref / output_schema_ref string,not null —— JSON Schema 引用,强制校验(课程"给每个节点一个契约"的落地)
  • input_payload json,not null
  • output_payload json,nullable —— 校验失败时为 null,触发重试
  • model_tier enum,not null,default standard —— cheap|standard|premium(对应课程"按节点分层选模型")
  • status string,not null —— pending|running|reflecting|retrying|waiting_for_quota|blocked|done|failed(waiting_for_quota 新增,2026-07-29,见下方与 03-C 3.6/3.5 节)
  • retry_count int,not null,default 0
  • reflection_notes json,nullable
  • git_worktree_ref string,nullable —— 若节点涉及并行写代码,记录隔离用的 git worktree 路径(对应课程"节点隔离")
  • quota_wait_started_at timestamp,nullable —— 首次检测到 Claude Code plan 额度耗尽的时间,仅 status=waiting_for_quota 时有值,用于计算是否超过等待上限
  • quota_limit_type enum,nullable —— session|weekly|opus,从 claude -p 报错文本判断额度类型(新增,2026-07-29,见 03-C 3.6 节)
  • 并发/幂等:output_payload 写入前必须通过 output_schema_ref 校验;校验失败自动重试,retry_count 达上限后置为 failed 并冒泡到 work_graph_run 层
  • 额度等待语义(新增,2026-07-29):waiting_for_quota 不是失败态,是自愈型阻塞——retry_count 不计入这类重试(避免和真实的 schema 校验失败重试混淆),退避轮询策略和超时兜底见 03-C 3.6 节

1.5 实体:artifact

目的:BRD/PRD/SDD/Benchmark/测试用例集/Bug 记录等结构化产物,版本化、有血缘。

  • artifact_id string,pk
  • artifact_type enum,not null —— brd|prd|sdd|benchmark|bug_record|code_diff|test_report
  • task_id string,not null,fk → task.task_id
  • produced_by_run_id string,not null,fk → work_graph_run.run_id
  • file_path string,not null —— 路径语义按 artifact_type 区分:brd/prd/sdd/benchmark/bug_record 落在目标项目 <target_folder_path>/.graphlemon/runs/<task_id>/...(架构文档 13.2 节);code_diff/test_report 落在目标项目自身源码目录内,路径由 Coder 按目标项目既有约定决定,不强制结构
  • git_commit_sha string,not null —— 对应目标项目自身仓库的 Git 提交(不是 graphlemon 平台仓库的提交)
  • depends_on_artifact_ids json,nullable —— 血缘引用(如 sdd 依赖某版本 prd)
  • validation_status enum,not null,default pending —— pending|passed|failed
  • created_at timestamp
  • 唯一约束:(task_id, artifact_type, git_commit_sha)
  • 迁移/回滚约束:artifact 一旦写入不可变更(immutable),修订产生新记录并更新 depends_on_artifact_ids 血缘链,不做原地更新

1.6 实体:bug_record

目的:结构化问题记录(artifact_type=bug_record 的强类型展开),来源可以是 Validator 自动生成,也可以是人在控制台手工反馈(架构文档第 13 节新增诉求)。

  • bug_id string,pk
  • task_id string,nullable,fk —— 人工反馈时可能尚未关联具体 task(先建 bug_record,再由 Validator triage 后创建/关联 task)
  • source enum,not null —— validator|human
  • reported_by string,nullable —— source=human 时记录操作人标识
  • description string,not null
  • repro_steps string,nullable —— source=human 时允许先留空,Validator triage 阶段补齐
  • root_cause_category enum,nullable —— planning|coder|skill_defect|core_engine(新增,2026-07-30,见 05 节 §5.8:覆盖 .claude/agents/*.md 身份文件变更、Graph Engine 调度器/执行器抽象层核心逻辑变更、01-M 自身数据库 schema 变更三类 self-target 场景,命中时 c_org_loop_route 路由到 p_deploy_supervisor_blue_green 而非常规 fast_lane/full_replan,见 1.15/1.16 节、03-C、04-P);source=human 且尚未 triage 时为 null
  • root_cause_detail string,nullable —— 具体归因说明(引用具体 SDD 章节/Coder 实现记录/Skill ID);source=validator 时必填,source=human 待 triage 完成后必填
  • related_artifact_ids json,nullable —— 关联的原始 Artifact 版本;source=human 提交时可能为空
  • suggested_route enum,nullable —— fast_lane|full_replan;triage 完成前为 null
  • skill_iteration_suggestion_id string,nullable,fk → skill_iteration.iteration_id
  • status enum,not null —— open|triaging|routed|resolved(source=human 的记录初始态为 open,Validator 认领后转 triaging)
  • 并发/幂等:同一 task_id 允许多条 bug_record(一次验证可能发现多个问题),互不影响

1.7 实体:skill

目的:Skill 库条目,Git 版本化,可被 Validator 触发自主迭代。

  • skill_id string,pk(如 write-sdd、code-task-development、qa-task-validation)
  • owner_org_node string,not null —— planner|coder|validator
  • file_path string,not null —— skills/<skill_id>/ 目录
  • current_git_commit_sha string,not null
  • source enum,not null —— migrated_from_hermes|new|auto_iterated
  • migrated_from_profile string,nullable —— 若来自本地 Hermes profile 迁移,记录来源(code|planning|qa)
  • 状态集合:active|archived

1.8 实体:skill_iteration

目的:Skill 自主迭代的变更记录(架构文档 8 节决策 1:允许自主改写并立即生效,但每次变更必须是独立 Git 提交)。

  • iteration_id string,pk
  • skill_id string,not null,fk → skill.skill_id
  • triggered_by_bug_id string,not null,fk → bug_record.bug_id
  • before_git_commit_sha / after_git_commit_sha string,not null
  • change_summary string,not null
  • applied_at timestamp
  • rollback_of_iteration_id string,nullable —— 若本次是对某次迭代的回滚
  • 约束:每条记录对应一次独立 Git commit,commit message 必须包含 triggered_by_bug_id

1.9 实体:agent_profile

目的:Org Agent 的人设与运行契约文件元数据(迁移自本地 Hermes profile 的 SOUL.md/AGENTS.md)。

  • org_node string,pk —— planner|coder|validator
  • soul_file_path string,not null —— agents/<org_node>/SOUL.md
  • agents_file_path string,nullable —— 仅 validator 有 AGENTS.md
  • migrated_from_profile string,not null —— planning|code|qa
  • current_git_commit_sha string,not null

1.10 实体:budget_guardrail_config

目的:预算/额度护栏配置(架构文档 7.5 节,双层护栏之一:手工配置层)。

  • config_id string,pk,default default
  • scope enum,not null —— global|per_task|per_day
  • limit_type enum,not null —— token_count|call_count
  • limit_value int,not null
  • current_usage int,not null,default 0
  • on_exceed_action enum,not null,default pause_and_notify
  • updated_by string,not null —— 管理后台操作人
  • updated_at timestamp

1.11 实体:org_concurrency_config

目的:多 Goal 并发数配置(架构文档 8 节决策 5,MVP 默认 1,管理后台可调)。

  • config_id string,pk,default default
  • max_concurrent_goals int,not null,default 1
  • updated_by string,not null
  • updated_at timestamp

1.12 实体:execution_event

目的:架构文档第 13 节新增——控制台实时看板的唯一数据源。所有状态变化在写入各自实体的同时追加一条事件记录,既用于 WebSocket 推送,也用于"检查过程"页面回放历史时间线,避免另建一套单独的日志系统。

  • event_id string,pk(单调递增或 ULID,保证可排序)
  • project_id string,not null,fk → project.project_id
  • task_id string,nullable,fk
  • run_id string,nullable,fk → work_graph_run.run_id
  • node_exec_id string,nullable,fk → work_node_execution.node_exec_id
  • event_type enum,not null —— task_status_changed|node_status_changed|artifact_created|bug_recorded|loop_routed|budget_updated|skill_iterated
  • payload json,not null —— 事件详情(如 {from_status, to_status})
  • created_at timestamp,not null,index
  • 索引:(project_id, created_at)(看板按项目拉取时间线)、(task_id, created_at)(任务详情页时间线)
  • 约束:execution_event 只追加不更新不删除(append-only),是审计和实时推送的唯一事实源;写入 execution_event 与写入对应业务实体(如 task.status)需在同一事务内完成,避免看板显示与实际状态不一致
  • 原始执行会话日志(Claude Code ACP 的完整对话记录)不存入本表,本表只记录结构化摘要事件;原始日志存储见 1.13 execution_log_file,event_type 新增 log_appended 用于驱动控制台实时滚动日志(见下方实体更新)

(event_type 枚举补充:task_status_changed|node_status_changed|artifact_created|bug_recorded|loop_routed|budget_updated|skill_iterated|log_appended|quota_wait_started(新增,2026-07-29,见 03-C 3.6 节额度等待重试语义))

1.13 实体:execution_log_file

目的:架构文档第 13.1 节决策 4——Work Node 执行的原始会话日志本地落盘,控制台内直接可看,与 Git 版本化的 Artifact/Skill 是两套不同生命周期的存储。

  • log_file_id string,pk
  • node_exec_id string,not null,unique,fk → work_node_execution.node_exec_id —— 一个 Work Node 执行对应一个日志文件
  • project_id string,not null,fk → project.project_id
  • file_path string,not null —— graphlemon 平台本地日志目录下的路径,如 ~/.graphlemon/logs/<project_id>/<task_id>/<run_id>/<node_exec_id>.jsonl(不在任何 Git 仓库内)
  • format enum,not null —— jsonl|raw_text(取决于底层执行引擎的会话记录格式)
  • size_bytes int,not null,default 0 —— 执行过程中增量更新
  • status enum,not null —— active(写入中)|closed(节点执行结束,日志文件不再追加)|purged(已被清理任务删除)
  • created_at timestamp
  • purged_at timestamp,nullable
  • 索引:node_exec_id(唯一)、project_id
  • 约束:日志文件由执行器抽象层(架构文档 7.2 节)在 Work Node 执行期间流式追加写入,每次追加同时写一条 execution_event(event_type=log_appended) 驱动控制台实时滚动;status=purged 后 file_path 指向的物理文件已被删除,但记录本身保留作审计(不物理删除 execution_log_file 行,只标记状态),避免"日志曾经存在过"这件事本身也查不到

1.14 实体:log_retention_config

目的:日志清理策略配置,对应用户诉求"定时清理就好"。

  • config_id string,pk,default default
  • retention_days int,not null,default 14 —— 超过该天数的 execution_log_file(status=closed)会被清理任务标记为 purged 并删除物理文件
  • max_total_size_mb int,nullable —— 可选的总大小上限,超过时按最旧优先清理(即使未到 retention_days)
  • updated_by string,not null
  • updated_at timestamp

1.15 实体:deployment(PH5 新增,2026-07-30,见 docs/done/supervisor-auto-rollback-design.md)

目的:Deploy Supervisor 对 graphlemon 自身(self-target 场景)执行一次蓝绿部署的记录,覆盖从候选实例拉起到最终 finalized/rolled_back/blocked_pending_human 的完整生命周期。Deploy Supervisor 是独立于 Graph Engine 之外的进程,不要与架构文档里"Supervisor(调度子 Agent,Coder Work Graph 内部监控节点)"混淆,两者是完全不同的概念(详见 supervisor-auto-rollback-design.md 开头命名说明)。

  • deployment_id string,pk(UUID)
  • git_commit_hash string,not null —— 本次候选版本对应的 graphlemon 自身仓库 commit
  • previous_commit_hash string,not null —— 回滚目标,取上一条 status=finalized 的 deployment.git_commit_hash
  • status enum,not null —— staged|candidate_starting|health_check_running|health_check_passed|health_check_failed|cutover_in_progress|live|monitoring|anomaly_detected|rollback_in_progress|rolled_back|rollback_failed|blocked_pending_human|monitoring_window_clean|finalized(完整状态转移见 04-P p_deploy_supervisor_blue_green)
  • candidate_port int,nullable —— 健康检查阶段候选实例监听的临时端口
  • candidate_db_path string,nullable —— 一次性生产库副本路径,健康检查结束后清理
  • started_at / cutover_at / monitoring_closed_at / rollback_at timestamp,nullable
  • rollback_reason string,nullable —— 触发回滚的具体信号快照(哪个 signal_type、哪次采样、什么值),或"回滚本身失败"的原因说明
  • previous_instance_dir string,not null —— 上一个已知良好版本的 checkout 目录,在本次 deployment 监控窗口正常关闭(finalized)前不允许清理
  • 约束:同一时刻 graphlemon 自身仓库只允许一条处于非终态(不在 finalized|rolled_back|blocked_pending_human)的 deployment 记录,避免并发蓝绿部署互相干扰

1.16 实体:deploy_health_signal(PH5 新增,2026-07-30,见 docs/done/supervisor-auto-rollback-design.md)

目的:deployment 生命周期内每次健康检查/监控采样的记录,全部是确定性判断结果,不涉及任何 LLM 判断。

  • signal_id string,pk
  • deployment_id string,not null,fk → deployment.deployment_id
  • sampled_at timestamp,not null
  • signal_type enum,not null —— process_alive|http_health|canary_task|validator_approval_rate
  • status enum,not null —— ok|degraded|fail
  • detail string,nullable —— 供人工事后排查的具体数值/日志摘录,不参与自动判断逻辑
  • 索引:(deployment_id, sampled_at)(按部署拉取信号时间线)
  • 约束:deploy_health_signal 只追加不更新不删除(append-only),与 execution_event 的审计哲学一致