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_idstring,pk(UUID)namestring,not nulltarget_folder_pathstring,not null,unique —— 本地绝对路径has_git_repoboolean,not null —— 创建项目时校验;若原文件夹不是 Git 仓库,创建流程需询问是否代为初始化graphlemon_subdir_initializedboolean,not null,default false —— 是否已在目标文件夹内创建.graphlemon/子目录(见架构文档 13.2 节目录约定)statusenum,not null ——active|archivedcreated_attimestamp- 唯一约束:
target_folder_path(同一文件夹不能重复创建为两个项目) - 并发/幂等:创建项目时若路径已存在对应
project记录,直接返回已有记录而非报错(幂等创建)
1.1 实体:org_graph_definition
目的:Org Graph 的静态定义(Planner→Coder→Validator 三节点 + 回退边),人工维护,变更需人工评审,不由系统自主修改。
graph_idstring,pk,如dev-organizerversionstring,not null(Git tag/commit 引用)nodesjson,not null —— 数组,每项{ node_id, role, agent_profile_ref }edgesjson,not null —— 数组,每项{ from, to, condition }(如validator→coder的condition: route==fast_lane)file_pathstring,not null —— 指向org/dev-organizer.graph.yaml的相对路径- 状态集合:
draft、active、deprecated - 变更约束:仅人工提交 + 评审后的 Git commit 可以更新此实体,系统不得自主写入
1.2 实体:task
目的:任务队列条目,替代原飞书多维表格的需求表/Bug 表(架构文档 12.1 节已确认)。
task_idstring,pk(UUID)project_idstring,not null,fk →project.project_idgoal_textstring,not null —— 原始 Goal 描述或 Validator 回传的 bug 任务描述task_typeenum,not null ——goal|bug_fixorigin_refstring,nullable —— 若task_type=bug_fix,指向来源bug_record.bug_idcreated_viaenum,not null,defaultapi——api|human_console(区分是控制台人工提出还是程序化创建,用于审计)statusstring,not null —— 状态集合见 04-P 的p_org_task_lifecyclerouteenum,nullable ——fast_lane|full_replan(仅bug_fix类型需要,由 Validator 判定写入)loop_roundint,not null,default 0 —— 当前 Org-level Loop 已执行轮次blocked_reasonstring,nullable —— 达到轮次上限或预算超限时的原因说明assigned_org_nodestring,not null,fk —— 当前所处 Org Graph 节点(planner|coder|validator)created_at/updated_attimestamp- 索引:
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_idstring,pk(UUID)task_idstring,not null,fk →task.task_idorg_nodestring,not null ——planner|coder|validatorgraph_manifestjson,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。
- 补充说明(2026-07-30,回应"task 层级关系看不出来"的核对):
orchestration_script_refstring,nullable —— 若走 Claude Code 原生动态工作流(架构文档 10.1 节方案 A),指向保存的编排脚本路径(.claude/workflows/<name>.js)statusstring,not null —— 状态集合见 04-P 的p_work_graph_executionstarted_at/completed_attimestampresult_artifact_refsjson,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_idstring,pkrun_idstring,not null,fk →work_graph_run.run_idnode_idstring,not null —— 在graph_manifest中的节点标识subagent_typestring,not null —— 绑定的 Subagent 类型skill_refstring,not null,fk →skill.skill_idinput_schema_ref/output_schema_refstring,not null —— JSON Schema 引用,强制校验(课程"给每个节点一个契约"的落地)input_payloadjson,not nulloutput_payloadjson,nullable —— 校验失败时为 null,触发重试model_tierenum,not null,defaultstandard——cheap|standard|premium(对应课程"按节点分层选模型")statusstring,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_countint,not null,default 0reflection_notesjson,nullablegit_worktree_refstring,nullable —— 若节点涉及并行写代码,记录隔离用的 git worktree 路径(对应课程"节点隔离")quota_wait_started_attimestamp,nullable —— 首次检测到 Claude Code plan 额度耗尽的时间,仅status=waiting_for_quota时有值,用于计算是否超过等待上限quota_limit_typeenum,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_idstring,pkartifact_typeenum,not null ——brd|prd|sdd|benchmark|bug_record|code_diff|test_reporttask_idstring,not null,fk →task.task_idproduced_by_run_idstring,not null,fk →work_graph_run.run_idfile_pathstring,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_shastring,not null —— 对应目标项目自身仓库的 Git 提交(不是 graphlemon 平台仓库的提交)depends_on_artifact_idsjson,nullable —— 血缘引用(如sdd依赖某版本prd)validation_statusenum,not null,defaultpending——pending|passed|failedcreated_attimestamp- 唯一约束:
(task_id, artifact_type, git_commit_sha) - 迁移/回滚约束:
artifact一旦写入不可变更(immutable),修订产生新记录并更新depends_on_artifact_ids血缘链,不做原地更新
1.6 实体:bug_record
目的:结构化问题记录(artifact_type=bug_record 的强类型展开),来源可以是 Validator 自动生成,也可以是人在控制台手工反馈(架构文档第 13 节新增诉求)。
bug_idstring,pktask_idstring,nullable,fk —— 人工反馈时可能尚未关联具体 task(先建 bug_record,再由 Validator triage 后创建/关联 task)sourceenum,not null ——validator|humanreported_bystring,nullable ——source=human时记录操作人标识descriptionstring,not nullrepro_stepsstring,nullable ——source=human时允许先留空,Validator triage 阶段补齐root_cause_categoryenum,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 时为 nullroot_cause_detailstring,nullable —— 具体归因说明(引用具体 SDD 章节/Coder 实现记录/Skill ID);source=validator时必填,source=human待 triage 完成后必填related_artifact_idsjson,nullable —— 关联的原始 Artifact 版本;source=human提交时可能为空suggested_routeenum,nullable ——fast_lane|full_replan;triage 完成前为 nullskill_iteration_suggestion_idstring,nullable,fk →skill_iteration.iteration_idstatusenum,not null ——open|triaging|routed|resolved(source=human的记录初始态为open,Validator 认领后转triaging)- 并发/幂等:同一
task_id允许多条bug_record(一次验证可能发现多个问题),互不影响
1.7 实体:skill
目的:Skill 库条目,Git 版本化,可被 Validator 触发自主迭代。
skill_idstring,pk(如write-sdd、code-task-development、qa-task-validation)owner_org_nodestring,not null ——planner|coder|validatorfile_pathstring,not null ——skills/<skill_id>/目录current_git_commit_shastring,not nullsourceenum,not null ——migrated_from_hermes|new|auto_iteratedmigrated_from_profilestring,nullable —— 若来自本地 Hermes profile 迁移,记录来源(code|planning|qa)- 状态集合:
active|archived
1.8 实体:skill_iteration
目的:Skill 自主迭代的变更记录(架构文档 8 节决策 1:允许自主改写并立即生效,但每次变更必须是独立 Git 提交)。
iteration_idstring,pkskill_idstring,not null,fk →skill.skill_idtriggered_by_bug_idstring,not null,fk →bug_record.bug_idbefore_git_commit_sha/after_git_commit_shastring,not nullchange_summarystring,not nullapplied_attimestamprollback_of_iteration_idstring,nullable —— 若本次是对某次迭代的回滚- 约束:每条记录对应一次独立 Git commit,commit message 必须包含
triggered_by_bug_id
1.9 实体:agent_profile
目的:Org Agent 的人设与运行契约文件元数据(迁移自本地 Hermes profile 的 SOUL.md/AGENTS.md)。
org_nodestring,pk ——planner|coder|validatorsoul_file_pathstring,not null ——agents/<org_node>/SOUL.mdagents_file_pathstring,nullable —— 仅validator有AGENTS.mdmigrated_from_profilestring,not null ——planning|code|qacurrent_git_commit_shastring,not null
1.10 实体:budget_guardrail_config
目的:预算/额度护栏配置(架构文档 7.5 节,双层护栏之一:手工配置层)。
config_idstring,pk,defaultdefaultscopeenum,not null ——global|per_task|per_daylimit_typeenum,not null ——token_count|call_countlimit_valueint,not nullcurrent_usageint,not null,default 0on_exceed_actionenum,not null,defaultpause_and_notifyupdated_bystring,not null —— 管理后台操作人updated_attimestamp
1.11 实体:org_concurrency_config
目的:多 Goal 并发数配置(架构文档 8 节决策 5,MVP 默认 1,管理后台可调)。
config_idstring,pk,defaultdefaultmax_concurrent_goalsint,not null,default 1updated_bystring,not nullupdated_attimestamp
1.12 实体:execution_event
目的:架构文档第 13 节新增——控制台实时看板的唯一数据源。所有状态变化在写入各自实体的同时追加一条事件记录,既用于 WebSocket 推送,也用于"检查过程"页面回放历史时间线,避免另建一套单独的日志系统。
event_idstring,pk(单调递增或 ULID,保证可排序)project_idstring,not null,fk →project.project_idtask_idstring,nullable,fkrun_idstring,nullable,fk →work_graph_run.run_idnode_exec_idstring,nullable,fk →work_node_execution.node_exec_idevent_typeenum,not null ——task_status_changed|node_status_changed|artifact_created|bug_recorded|loop_routed|budget_updated|skill_iteratedpayloadjson,not null —— 事件详情(如{from_status, to_status})created_attimestamp,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_idstring,pknode_exec_idstring,not null,unique,fk →work_node_execution.node_exec_id—— 一个 Work Node 执行对应一个日志文件project_idstring,not null,fk →project.project_idfile_pathstring,not null —— graphlemon 平台本地日志目录下的路径,如~/.graphlemon/logs/<project_id>/<task_id>/<run_id>/<node_exec_id>.jsonl(不在任何 Git 仓库内)formatenum,not null ——jsonl|raw_text(取决于底层执行引擎的会话记录格式)size_bytesint,not null,default 0 —— 执行过程中增量更新statusenum,not null ——active(写入中)|closed(节点执行结束,日志文件不再追加)|purged(已被清理任务删除)created_attimestamppurged_attimestamp,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_idstring,pk,defaultdefaultretention_daysint,not null,default 14 —— 超过该天数的execution_log_file(status=closed)会被清理任务标记为purged并删除物理文件max_total_size_mbint,nullable —— 可选的总大小上限,超过时按最旧优先清理(即使未到retention_days)updated_bystring,not nullupdated_attimestamp
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_idstring,pk(UUID)git_commit_hashstring,not null —— 本次候选版本对应的 graphlemon 自身仓库 commitprevious_commit_hashstring,not null —— 回滚目标,取上一条status=finalized的deployment.git_commit_hashstatusenum,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-Pp_deploy_supervisor_blue_green)candidate_portint,nullable —— 健康检查阶段候选实例监听的临时端口candidate_db_pathstring,nullable —— 一次性生产库副本路径,健康检查结束后清理started_at/cutover_at/monitoring_closed_at/rollback_attimestamp,nullablerollback_reasonstring,nullable —— 触发回滚的具体信号快照(哪个signal_type、哪次采样、什么值),或"回滚本身失败"的原因说明previous_instance_dirstring,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_idstring,pkdeployment_idstring,not null,fk →deployment.deployment_idsampled_attimestamp,not nullsignal_typeenum,not null ——process_alive|http_health|canary_task|validator_approval_ratestatusenum,not null ——ok|degraded|faildetailstring,nullable —— 供人工事后排查的具体数值/日志摘录,不参与自动判断逻辑- 索引:
(deployment_id, sampled_at)(按部署拉取信号时间线) - 约束:
deploy_health_signal只追加不更新不删除(append-only),与execution_event的审计哲学一致