PMFlow/docs/architecture/PMFLOW_OS_PRODUCT_CONTRACT.md

45 KiB
Raw Permalink Blame History

PMFlow OS Product Contract

版本日期:2026-04-26

本文档是 PMFlow OS 从本地高保真主链走向真实数据闭环的产品级合同。它锁定对象真源、读写边界、状态流转和后续开发接口,避免 frontend/src/features/pmflow-os/ 继续围绕 mock store 扩散。A3 已完成真实只读 projection,Phase B 已完成 Project Launch 创建链,Phase C1 已完成 Change Review 数据底座与审查状态机;Phase C2 backend 已按 atomic commit 合同实现,后续前端接入不得再自行改变 API shape。

产品方向真源仍以 docs/PMFLOW_PRODUCT_BLUEPRINT.md 为准;UI 行为与状态标签以 docs/PMFLOW_UI_CONTRACT.md 为准;推进节奏以 docs/PMFLOW_PRODUCT_DELIVERY_STANDARD.md 为准。

1. 合同结论

PMFlow OS V1 的主链是:

Project Thread
-> Structured Extraction
-> ChangeSet Review
-> Project Memory / Work Graph commit
-> Execution Bridge
-> Release / Growth feedback

当前复用边界:

  • Requirement / Decision / Risk / Release 优先从 truth_nodes 投影,不新建另一套正式业务对象表。
  • Task 复用 tasks,并通过 truth_node_id 绑定需求/宪章/项目真相节点。
  • Project Memory 由 truth_nodes + semantic_facts 聚合投影;semantic_facts 是 read model,不是人工确认记录本身。
  • ModelDecision / PromptPackage / ReleaseValidation / Feedback / Revenue / ROI / Compliance 复用 ai_project_control 模型与 sstc_api/model_control.py 现有接口。
  • ExecutionContext 复用 prompt_packages + repo_bindings + task_code_links + progress_events + dev_sync summary;运行端接入凭据复用 ai_project_control 域新增的 pmflow_execution_runtime_credentials,只保存短期签名回流合同,不保存明文 secret。
  • Thread / ThreadMessage 已由 Phase B 落到 pmflow_threads / pmflow_thread_messages。
  • ChangeSet / ChangeItem / Approval / EvidenceLink 已由 Phase C1 落到 pmflow_change_sets / pmflow_change_items / pmflow_approvals / pmflow_evidence_links。

PMFlow OS 专属表:

pmflow_threads
pmflow_thread_messages
pmflow_change_sets
pmflow_change_items
pmflow_approvals
pmflow_evidence_links

/commit 后端代码与前端真实模式接入已实现;真实模式下 promoteAcceptedToGraph 必须调用后端 POST /pmflow-os/change-sets/{change_set_id}/commit,不得用本地 mutation 冒充正式 Project Memory 写入。

2. 对象映射表

前端对象 后端来源 是否新增表 读 API 写 API 状态流转 证据/审计 风险点
ProjectTruthState 聚合投影:projects、truth_nodes、tasks、semantic_facts、PMFlow OS 专属 review 表、ai_project_control、dev_sync 不直接建总表 GET /pmflow-os/projects/{project_id}/truth-state 由各子对象 API 写入 loopStage 由最近线程、提取和审查状态计算 返回 customer-safe 状态,不暴露内部 raw label 需要 projection service,不能由前端拼多个旧接口冒充
Thread pmflow_threads;绑定 project_id、默认目标、当前阶段 是,Phase B 已建 truth-state 内返回 创建项目时初始化,或 C1 messages 首次写入时懒创建 idle -> loading -> ready 仅表示提取状态 线程本身是后续 ChangeSet 证据源 不能复用飞书 thread/session 作为唯一项目线程
Message pmflow_thread_messages;可引用 Feishu/QA/message 来源 是,Phase B 已建 truth-state 内返回 POST /pmflow-os/projects/{project_id}/threads/{thread_id}/messages C1 先写 sent,后续可扩 analyzing/resolved/failed message id 可被 EvidenceLink 引用 写 message 不等于写项目真相层
ChangeSet pmflow_change_sets 是,Phase C1 已建 GET /pmflow-os/projects/{project_id}/change-sets/{change_set_id} POST /pmflow-os/projects/{project_id}/extractions 生成;C2 才实现 commit C1:open -> reviewed;C2:committed / partially_committed 记录生成来源、routing_meta、LLM call id、actor 不能用 truth_nodes 直接模拟 ChangeSet;ChangeSet 是待确认变更包
ChangeItem pmflow_change_items 是,Phase C1 已建 ChangeSet detail C1:accept / edit / defer;C2:commit 后写正式对象 C1:pending_review -> accepted / edited / deferred;C2:committed / skipped 每项必须绑定 evidence ids 与 risk level accept 只改审查状态,不得静默落库
Evidence pmflow_evidence_links 投影,来源可为 message、truth_node、task、progress_event、release_validation、feedback、metric 是,Phase C1 已建 link 表 truth-state、ChangeSet detail C1 随 extraction 创建 thread message evidence;C2 随 commit、execution/growth 回写扩展 证据不走业务状态,只可 active/archived 必须记录 source_type/source_id/excerpt/display_label ai_project_control.EvidencePack 只适合发布/合规证据包,不能替代通用证据链
Approval pmflow_approvals 是,Phase C1 已建 truth-state、ChangeSet detail C1:accept / edit / defer 写入;C2:commit gate 扩展 approved / edited / deferred / rejected 记录 actor、role、decision、before/after 高风险变更必须有 approval 记录;C1 只记录,C2 才强制 gate
Requirement truth_nodes.node_type in ('charter','requirement') 投影;V1 可从 charter content 中拆分 requirement block 否 truth-state commit accepted ChangeItem 后创建/更新 truth_nodes draft/proposed -> confirmed -> archived,前端映射到 draft/confirmed/done commit 时绑定 ChangeItem/EvidenceLink;semantic facts hook 后台抽取 当前 TruthNode.node_type 历史值不统一,需在 projection 层做白名单映射
Decision truth_nodes.node_type='decision' 或 charter/review content 决策块投影 否 truth-state commit 写 truth_nodes draft/proposed -> confirmed 必须保留来源 ChangeItem 和 owner 若历史没有 decision node,先从 charter content 投影,不新增前端-only 决策
Task tasks + truth_nodes 否 truth-state;后续可复用 SSTC task board commit 创建/更新 tasks;执行进度走 dev-sync draft -> in_progress -> blocked/done 任务来源 ChangeItem、验收标准、assignee 建议进入审计 tasks.status 与前端状态枚举需 projection 映射
Risk truth_nodes.node_type='risk' 或 charter/release/check content 风险块投影 否 truth-state commit 写 truth_nodes draft/proposed -> confirmed -> archived 高风险必须绑定 approval 与 mitigation ReleaseValidationRun.risk_items 是发布检查结果,不等于正式风险对象
ModelDecision project_model_bindings、model_recommendation_snapshots、model_eval_runs 投影 否 truth-state 可聚合;细节复用 /projects/{project_id}/model-recommendations、/model-usage /model-binding recommended -> active -> archived 映射到前端 confirmed/released selection_reason、snapshot_input、eval summary 作为证据 不做独立模型市场页,必须嵌入项目主链
TestRun model_eval_runs、release_validation_runs、progress_events(event_type=test*) 投影 否 truth-state、execution-summary dev-sync progress event 或 release validation pending/running -> passed/failed/blocked 测试日志和 PR/commit 可作为 evidence 当前没有通用 test_runs 表,V1 先按投影聚合
Release truth_nodes.node_type='release' + release_validation_runs 否 truth-state;SSTC release APIs SSTC release 创建;run_release_validation check_pending -> ready -> shipping -> live/watch release gate、rollback_plan、validation_summary 发布对象和发布验证结果需要在 projection 中分清
MetricSignal feedback_ingests.metrics、revenue_events、roi_snapshots、增长埋点结果投影 否 truth-state;/roi-snapshots feedback-ingest、revenue-events draft/proposed -> confirmed 指标来源和采样窗口必须展示 只做轻量反馈,不引入完整财务系统
ExecutionContext prompt_packages、repo_bindings、task_code_links、progress_events、pmflow_execution_runtime_credentials、dev_sessions 否 GET /pmflow-os/projects/{project_id}/execution-summary 聚合 GET /projects/{project_id}/dev-sync/summary POST /pmflow-os/projects/{project_id}/execution-handoffs 生成/复用 PromptPackage 并创建 ProgressEvent 起点;POST /pmflow-os/projects/{project_id}/execution-handoffs/{prompt_package_id}/runtime-credential 生成短期签名回流凭据;POST /pmflow-os/runtime/execution-results 或登录态 POST /execution-progress-events 写入 execution_result_protocol_v1 执行结果;repo 绑定仍走 dev-sync/GitHub App queued -> pushed -> coding -> pr_open -> testing -> synced/failed progress events、deliveries、credential use count、repo/PR/commit/test/blocker 是执行证据 不得重造 dev-sync;PMFlow OS 只做项目内执行投影、handoff 与签名 result contract,不直接执行本机命令,不保存运行端明文 secret
TeamFeed / TeamInbox pmflow_change_sets、pmflow_approvals、progress_events、release/feedback 事件聚合 暂不新增专表,先 projection truth-state 由各业务动作写入源表 feed item 不承载主状态 必须能追溯到源对象 Phase F 才补 Role Inbox/Decision Desk 的真实模型

3. ProjectTruthState 后端投影

GET /pmflow-os/projects/{project_id}/truth-state 返回前端兼容结构,但数据必须由后端 projection service 组装:

project:
  projects + latest confirmed truth_nodes
thread/messages:
  pmflow_threads + pmflow_thread_messages
changeSets/changeItems/evidence/approvals:
  PMFlow OS 专属 review 表
requirements/decisions/risks/releases:
  truth_nodes 投影
tasks:
  tasks + related truth_nodes
modelDecisions:
  model_recommendation_snapshots + project_model_bindings + model_eval_runs
testRuns:
  release_validation_runs + model_eval_runs + progress_events(test)
metricSignals:
  feedback_ingests + revenue_events + roi_snapshots
feed/teamInbox:
  review/actions/progress/release/growth 事件聚合
execution:
  dev-sync summary + prompt_packages + recent progress_events

投影规则:

  • AI 已生成 对应 ChangeSet.open 和 ChangeItem.pending_review,不得进入正式对象列表。
  • 待你确认 对应 ChangeItem.pending_review 或高风险 Approval.requested。
  • 已确认 对应 ChangeItem.accepted/edited,但尚未必然写入 Project Memory。
  • 已写入项目记忆 只能在 ChangeSet.commit 成功写入 truth_nodes / tasks / semantic_facts 后出现。
  • semantic_facts 只用于 read-side facts-first 查询与 Project Memory projection,不作为人工确认动作记录。

审查与写入顺序:

  • Structured Extraction 只生成 ChangeSet / ChangeItem / EvidenceLink,不得写正式对象。
  • ChangeReviewPage 是正式审查动作的唯一主入口;accept / edit / defer / reject / review decision 都只写审查状态、approval 和审计,不写 truth_nodes / tasks / semantic_facts。
  • TeamLayerPage 只消费 reviewerRouting / reviewDecision / approvalState 做责任路由、角色收件箱、决策台和阻塞解释;团队层不得直接执行 commit,也不得成为第二套 Change Review。
  • reviewerRouting 只是建议与状态投影;除非用户显式 request_review 或后续合同定义自动分派,否则不得把建议 reviewer 当成已分派任务。
  • 高风险、跨角色、缺证据或需要专业判断的 item 必须先满足 required reviewer / approval gate,再允许 commit。
  • commit 是 Project Memory 写入唯一边界;成功后才允许正式对象进入 Work Graph,并成为 Execution Bridge 的可执行候选。

项目级副驾投影合同:

  • 前端当前由 ProjectTruthState + execution summary + reviewer routing + release signals + ai readiness 派生 CopilotContextPacket,只作为客户可见解释、建议、跳转和受限动作投影。
  • ProjectCopilotPanel 可以显示当前对象、阶段、风险、证据、待确认、AI readiness 和下一步动作,但不得自行写 ChangeSet / Project Memory / ProgressEvent / ReleaseValidationRun / FeedbackIngest。
  • 副驾里的 Commit 类动作必须跳回或调用 Change Review 的正式提交链路;Execute 类动作必须跳回或调用 Execution Bridge 的正式 handoff / progress / memory writeback 链路;发布增长动作只能进入 release validation 或 recommendation -> ChangeSet draft。
  • 在后端补齐项目级 ask/action 合同前,副驾输入只能作为页面回调或受控 ask 入口,不得让自由 QA 绕过 Query Route Gateway、Project Memory commit、reviewer gate 或 Execution Bridge。
  • 客户可见副驾只能展示中文化业务标签、证据摘要和下一步动作;不得暴露 provider、model、trace、prompt body、raw source label 或内部 agent 编排。

4. API 合同草案

所有接口统一返回:

{ "code": 0, "message": "success", "data": {} }

错误仍走项目现有失败包络与 HTTP 状态;客户可见错误必须明确失败原因,不得用 mock 或默认句冒充成功。

4.1 获取项目真相投影

GET /pmflow-os/projects/{project_id}/truth-state

Response data:

{
  "loopStage": "extraction_ready",
  "lastWritebackAt": "2026-04-25T10:00:00+08:00",
  "project": {},
  "thread": {},
  "messages": [],
  "changeSets": [],
  "changeItems": [],
  "evidence": [],
  "requirements": [],
  "decisions": [],
  "tasks": [],
  "risks": [],
  "modelDecisions": [],
  "testRuns": [],
  "releases": [],
  "metricSignals": [],
  "approvals": [],
  "feed": [],
  "teamInbox": {},
  "activeChangeSetId": null,
  "selectedTaskId": null,
  "execution": {}
}

失败语义:

  • 404 project_not_found:项目不存在或不属于当前租户。
  • 403 forbidden:当前用户不是项目成员或管理角色。
  • 409 projection_incomplete:核心合同对象缺失,不能拼装可信 ProjectTruthState。

4.2 写入线程消息

POST /pmflow-os/projects/{project_id}/threads/{thread_id}/messages

Request:

{
  "content": "用户输入",
  "source": "web",
  "attachments": []
}

行为:

  • 只写 pmflow_thread_messages。
  • 可触发异步 extraction job,但不能直接写 truth_nodes / tasks。
  • 返回 message 和可选 extraction_job_id。

4.3 创建结构化提取

POST /pmflow-os/projects/{project_id}/extractions

Request:

{
  "thread_id": "thread_123",
  "message_id": "msg_123",
  "scope": "latest_message",
  "proposed_items": [
    {
      "group": "new_object",
      "object_type": "Requirement",
      "title": "待审变更标题",
      "summary": "待审变更摘要",
      "payload": {},
      "confidence": 0.82,
      "risk_level": "medium"
    }
  ]
}

行为:

  • C1 采用 proposed_items 最小闭环,不默认调用 LLM;后续 AI 结构化提取应在上游生成 proposed items 后调用该接口。
  • 生成 pmflow_change_sets 与 pmflow_change_items。
  • ChangeSet 默认 open,ChangeItem 默认 pending_review。
  • 生成 pmflow_evidence_links,至少绑定触发消息。
  • 不写 truth_nodes / tasks / semantic_facts。

失败语义:

  • 422 invalid_proposed_items:未提供可审查 proposed items,不生成 ChangeSet。
  • 404 message_not_found:message 不属于当前 tenant/project/thread。

4.4 获取 ChangeSet

GET /pmflow-os/projects/{project_id}/change-sets/{change_set_id}

Response data:

{
  "changeSet": {},
  "items": [],
  "evidence": [],
  "approvals": []
}

4.5 审查 ChangeItem

POST /pmflow-os/change-items/{change_item_id}/accept
POST /pmflow-os/change-items/{change_item_id}/edit
POST /pmflow-os/change-items/{change_item_id}/defer

edit Request:

{
  "summary": "修改后的摘要",
  "diff": "修改后的业务 diff",
  "payload_patch": {}
}

行为:

  • accept:仅将 ChangeItem 置为 accepted,写 pmflow_approvals,不写正式对象。
  • edit:保存人工修改后的 payload,状态为 edited,写 pmflow_approvals。
  • defer:状态为 deferred,不进入项目真相层,但保留审计。

产品动作语义:

  • 接受 只能表示当前 actor 认可候选变更进入待写入集合;不得显示为“已写入”或触发执行桥。
  • 修改 必须生成可审计 before/after,不得覆盖原始 AI proposal 和 evidence。
  • 暂不落库 对应 deferred,用于当前不写入但保留后续恢复空间;它不是 reject。
  • 拒绝 若前端或后端提供,必须作为 terminal discard / rejected 审计处理,不得被批量 commit 重新捞回;在未实现 reject API 前,UI 不得用 defer 冒充拒绝。
  • 稍后处理 是队列提醒 / 排序动作,不应调用本节三个审查 API;它不得改变 ChangeItem 状态。
  • 批量接受 只能调用一组满足低风险、证据充分、无需 required reviewer gate、对象类型受支持的 item;包含任一不满足项时必须 fail-closed 或拆分处理。

失败语义:

  • 409 changeset_not_open:ChangeSet 非 open,不能继续审查。
  • 409 item_already_reviewed:ChangeItem 已被接受、编辑、暂缓、提交或跳过,不重复写 approval。
  • 422 invalid_change_payload:修改后的 payload 不满足对象合同。

4.6 提交 ChangeSet

Phase C2 必须按此合同实现,后端与前端不得自行发明其它请求或响应形状。

POST /pmflow-os/change-sets/{change_set_id}/commit

Auth:

  • 当前用户必须是项目成员、OWNER 或 REVIEWER。
  • tenant_id 必须来自当前 JWT,不得从请求体传入。

Request:

{
  "item_ids": ["12", "13"],
  "mode": "atomic",
  "note": "确认写入项目记忆"
}

字段规则:

  • item_ids 可选;为空时提交该 ChangeSet 下全部 accepted / edited 项。
  • mode C2 V1 只允许 atomic;未来若支持部分提交,必须先更新本文档。
  • note 可选,仅进入审计,不参与业务字段生成。

行为:

  • 只处理 accepted / edited 的 ChangeItem。
  • pending_review / deferred / committed / skipped 不写正式对象,只进入 skippedItems 明细。
  • C2 V1 使用单事务原子提交:任一 eligible item 写入失败时,整个 commit 回滚,不允许出现半写入 Project Memory。
  • 按 objectType 写入正式对象:
    • Requirement / Decision / Risk / Release -> truth_nodes
    • Task -> truth_nodes(node_type='task') + tasks.truth_node_id
    • ModelDecision -> project_model_bindings 或绑定选择记录
    • MetricSignal -> 反馈/收入/ROI 相关记录,或生成下一轮 recommendation 草案
  • 创建或更新 pmflow_evidence_links。
  • 提交成功后触发 semantic facts 抽取/刷新。
  • 全部 eligible item 成功后 ChangeSet 进入 committed。
  • partially_committed 是未来扩展状态,C2 V1 不应写出该状态。

Response data:

{
  "changeSet": {
    "id": "10",
    "status": "committed",
    "rawStatus": "committed",
    "committedAt": "2026-04-26T10:00:00+08:00",
    "committedItemIds": ["12"],
    "skippedItemIds": ["14"],
    "failedItemIds": []
  },
  "committedItems": [
    {
      "changeItemId": "12",
      "objectType": "Requirement",
      "targetType": "truth_node",
      "targetId": "301",
      "status": "committed",
      "evidenceIds": ["44"],
      "semanticFactStatus": "queued"
    }
  ],
  "skippedItems": [
    {
      "changeItemId": "14",
      "objectType": "Task",
      "status": "deferred",
      "reason": "item_not_accepted_or_edited"
    }
  ],
  "failedItems": [],
  "projectTruthState": {}
}

响应规则:

  • projectTruthState 可选;若返回,必须是 commit 后的后端真实 projection,不得由前端本地拼装。
  • committedItems[].targetId 必须是正式对象 id,如 truth_nodes.id、tasks.id、project_model_bindings.id。
  • semanticFactStatus 取值:queued / seeded / skipped / failed;失败不能影响已完成的正式对象写入,但必须进入审计或 failed detail。

失败语义:

  • 404 changeset_not_found:ChangeSet 不存在或不属于当前 tenant/project。
  • 409 changeset_not_reviewed:仍存在 pending_review 项且请求未显式只提交 item_ids。
  • 409 changeset_already_committed:ChangeSet 已经提交,不能重复提交。
  • 409 no_accepted_items:没有 accepted / edited 可提交项。
  • 409 high_risk_approval_required:高风险项缺少 required approval。
  • 422 invalid_commit_item_ids:item_ids 不属于该 ChangeSet 或包含不可提交状态。
  • 422 unsupported_object_type:objectType 不在 C2 白名单。
  • 422 invalid_change_payload:有效 payload 不满足正式对象必填字段。
  • 500 commit_failed:写入正式对象失败;C2 V1 必须回滚整个事务,并返回 failedItems 明细,不得冒充部分成功。

4.7 获取执行桥摘要

GET /pmflow-os/projects/{project_id}/execution-summary

行为:

  • 优先调用或复用 GET /projects/{project_id}/dev-sync/summary。
  • 额外补齐最近 Prompt Package、活动 repo、PR/commit/test progress event。
  • 返回前端 ExecutionContext 兼容结构、详细 dev task 列表、qualityContract、acceptance、deliveryArtifacts、artifactCompleteness 与 artifactReview。qualityContract 表达必测层级、阻塞发布的测试项、测试环境、真实/可 mock 数据边界和证据要求;acceptance 表达 waiting_execution / waiting_test_evidence / pending_user_acceptance / pending_technical_review / technical_review_approved / accepted / changes_requested / rejected / execution_blocked 等状态与 canEnterReleaseGate;artifactCompleteness 表达结构化交付证据 empty / incomplete / blocked / ready;artifactReview 把缺证据/失败证据转成补截图、补测试输出、修 failed command、补 review checklist 等返工审查项。

4.8 创建执行交接

POST /pmflow-os/projects/{project_id}/execution-handoffs

请求:

{
  "task_id": "123",
  "repo_binding_id": "456",
  "runtime_target": "local_bridge",
  "note": "可选交接备注"
}

行为:

  • 先复用项目成员/OWNER/REVIEWER 权限边界,再校验 task_id 必须属于当前 tenant/project。
  • repo_binding_id 可选;传入时必须属于当前 tenant/project 且为 active。未传入时允许创建 handoff draft,但 response 的 warnings 必须继续暴露 repo_bindings_empty 或等价缺口。
  • 若当前任务已有 active PromptPackage,复用该包并写入 latest handoff metadata;否则从真实 Project / Task / Project Memory / RepoBinding 生成 deterministic PromptPackage(package_kind='execution_handoff'),禁止硬编码 demo 文案。PromptPackage 必须包含 Quality Contract 章节,列出单元测试、合同测试、冒烟测试、联调测试、必要技术审查、测试环境和证据返回格式。
  • 创建 ProgressEvent(event_type='handoff_created', source='pmflow_os') 作为可追踪起点,payload 记录 runtime_target / prompt_package_id / repo_binding_id / boundary。
  • 返回最新 ExecutionSummaryProjection:execution / qualityContract / acceptance / releaseGate / promptPackage / repoBindings / activeDevTasks / recentProgressEvents / recentDeliveries / warnings。

错误:

  • 404 task_not_found:任务不存在、跨 project 或跨 tenant。
  • 422 repo_binding_not_found:传入的 repo binding 不存在、跨 project/tenant 或不是 active。

边界:

  • PMFlow backend 只创建 handoff 合同、PromptPackage 与 progress event,不直接执行本机命令。
  • 本地 stdio、宿主机配置写入和真实执行必须经过 Local Bridge、Codex、GitHub agent 或兼容 MCP host;PMFlow 后端不得写 ~/.codex/config.toml。

4.9 写回执行结果

POST /pmflow-os/projects/{project_id}/execution-progress-events

请求:

{
  "task_id": "123",
  "repo_binding_id": "456",
  "event_type": "pr_opened",
  "source": "codex",
  "branch_name": "codex/execution-result-protocol-p1",
  "commit_sha": "abc123def456",
  "pr_number": 77,
  "test_summary": "pytest 与 typecheck 通过",
  "blocker_summary": null,
  "execution_status": "pr_open",
  "delivery_artifacts": {
    "changed_files": [
      {"path": "frontend/src/features/pmflow-os/pages/ExecutionBridgePage.tsx", "change_type": "modified", "summary": "展示交付证据包"}
    ],
    "commands_run": [
      {"command": "npm run build", "status": "passed", "summary": "前端构建通过"}
    ],
    "test_outputs": [
      {"name": "frontend build", "status": "passed", "summary": "构建与类型检查通过"}
    ],
    "screenshots": [
      {"label": "Execution Bridge desktop", "artifact_ref": "artifact://execution-bridge-d11.png", "summary": "UI 改动截图证据"}
    ]
  }
}

行为:

  • 只记录 Codex / IDE / Local Bridge / GitHub agent 已产生的执行结果,不执行本机命令、不推送、不发布。
  • 写入 ProgressEvent 时同时保留兼容 flat payload 与协议 envelope:protocol_version='execution_result_protocol_v1'、execution_result={eventType, source, status, branchName, commitSha, prNumber, testSummary, blockerSummary, repositoryFullName, delivery_artifacts}。
  • 返回最新 ExecutionSummaryProjection,其中 execution 展示 branch/commit/PR/test/status,qualityContract 按测试证据计算必测项状态,acceptance 计算用户验收/技术审查门禁,deliveryArtifacts / artifactCompleteness 聚合 changed files、commands run、test outputs、screenshots、logs、risk notes、review checklist,releaseGate 基于 passed/failed/blocked/checks 事件、acceptance.canEnterReleaseGate 与 artifactCompleteness 推导 ready / blocked / needs_confirmation / empty,truth-state.feed 后续只读展示执行进展。
  • blocker_summary 优先作为 failed/blocked 事件的客户可见阻塞原因;test_summary 优先作为测试类事件摘要。
  • delivery_artifacts 只允许保存结构化摘要或外部 artifact ref,不保存无限长日志、二进制截图、secret、token 或宿主机文件内容。

边界:

  • 该接口是执行结果回写协议,不是任务创建、发布执行或命令代理;缺证据时只能返回 pending/needs_confirmation/blocked,不得伪造测试或发布成功。

4.9a 记录交付证据审查动作

POST /pmflow-os/projects/{project_id}/execution-artifact-review-actions

请求:

{
  "task_id": "123",
  "action": "request_fix",
  "review_item_ids": ["missing_ui_screenshots", "failed_command_0"],
  "note": "请补 UI 截图并修复 build 失败后重新回写 delivery_artifacts。"
}

行为:

  • 读取当前 ExecutionSummaryProjection.artifactReview.items,校验传入审查项必须来自当前 task/project 的投影。
  • 写入 ProgressEvent(payload.protocol_version='artifact_review_action_v1'),事件类型为 artifact_review_requested / artifact_fix_recorded / artifact_recheck_ready。
  • 返回最新 ExecutionSummaryProjection,artifactReview.actionHistory 展示审查动作历史。

边界:

  • 该接口只记录交付证据审查/返工意图,不执行命令、不创建分支、不推送、不开 PR、不合并、不部署、不发布、不创建正式 Task、不写 Project Memory。

4.9b 生成交付证据返工执行包

POST /pmflow-os/projects/{project_id}/execution-artifact-rework-packages

请求:

{
  "task_id": "123",
  "repo_binding_id": "456",
  "runtime_target": "codex",
  "review_item_ids": ["missing_ui_screenshots", "failed_command_0"],
  "note": "根据交付证据审查项生成返工执行包。"
}

行为:

  • 从当前 artifactReview.items 选择待返工项,生成新的 PromptPackage(package_kind='execution_handoff', package_payload.handoff_type='artifact_rework')。
  • 返工包内必须包含 rework_contract:审查项、预期证据、上一轮 delivery_artifacts、当前 artifactCompleteness 和 callback 要求。
  • 写入 ProgressEvent(event_type='artifact_rework_package_created', payload.protocol_version='artifact_rework_package_v1')。
  • 运行端继续用 D9/D10 的运行端凭据和签名 POST /pmflow-os/runtime/execution-packages 领取;拉包响应返回 package.reworkContract。

边界:

  • 返工包仍只是上下文包,不执行命令、不创建分支、不推送、不开 PR、不合并、不部署、不发布、不创建正式 Task、不写 Project Memory。
  • 普通 handoff 不得复用 handoff_type='artifact_rework' 的 PromptPackage,避免返工上下文污染新一轮普通执行。

4.9c 返工结果关闭与 UI 证据验收

行为:

  • 运行端基于 artifact_rework 包重新回写 /runtime/execution-results 时,必须继续携带同一个 prompt_package_id。
  • ExecutionSummaryProjection.artifactReview.closure 从 artifact_rework_package_created / execution_package_pulled / execution_result_protocol_v1 事件生成返工闭环,返回:
    • items[].status = resolved | open
    • items[].evidenceRefs:覆盖该审查项的 passed command/test、screenshot artifact ref、changed file 或 review checklist。
    • timeline[]:package_created / package_pulled / result_returned 审计线。
  • command/test/review checklist 的阻塞状态按同名最新证据优先计算;新 passed 证据可以覆盖旧 failed/blocked 证据,但旧事件仍保留在审计时间线和原始 deliveryArtifacts.events 中。
  • Execution Bridge 与 Release Growth 必须展示同源 closure 和 UI screenshot artifact ref,避免只显示“证据完整”的笼统结论。

边界:

  • closure 只表示返工审查项被当前交付证据覆盖,不等于用户验收、技术审查通过、Project Memory 写回、合并、部署或发布。

4.9d 发布门禁复检与执行写回证据链

行为:

  • ExecutionSummaryProjection.releaseGate.releaseReadinessProof 必须消费同一份 artifactCompleteness / artifactReview.closure / acceptance / execution_memory_writeback:
    • status=awaiting_acceptance:测试和交付证据已满足复检输入,但还未完成验收或技术审查。
    • status=awaiting_memory_writeback:验收已完成,但执行结果还未写回 Project Memory。
    • status=ready:测试、返工关闭、验收和 Project Memory 写回均已形成证据。
    • status=blocked:仍有未关闭失败或阻塞证据。
  • acceptance.evidenceProof 与 releaseGate.releaseReadinessProof 必须使用同一套未关闭失败证据判断;当 artifactCompleteness.status=ready 且 artifactReview.closure.status=all_resolved/none 时,历史 delivery artifact 里的 failed command/test/checklist 不得继续阻塞。
  • 显式 failed / blocked / test_failed progress event 仍然 fail-closed,不能被 closure 自动覆盖。
  • execution_memory_writeback_v1 必须把 writeback_proof / release_readiness_proof / artifact_review / artifact_completeness 写入 payload 与 Project Memory writeback metadata。

边界:

  • releaseReadinessProof.status=ready 只表示发布复检输入完整,不自动执行发布、不自动合并、不自动部署、不绕过最终人工确认。

4.9e 创建运行端凭据与签名回流

POST /pmflow-os/projects/{project_id}/execution-handoffs/{prompt_package_id}/runtime-credential
POST /pmflow-os/runtime/execution-packages
POST /pmflow-os/runtime/execution-results

行为:

  • 登录态凭据创建接口只允许项目成员、OWNER 或 REVIEWER 对当前项目的 execution_handoff PromptPackage 生成短期运行端凭据。
  • 凭据绑定 tenant_id / project_id / task_id / prompt_package_id / repo_binding_id / runtime_target / allowed_sources / expires_at;响应只返回一次 raw secret,数据库仅保存 secret_hash。
  • 运行端拉取执行包和回流结果接口都不吃 JWT,必须提供 X-PMFlow-Key-Id / X-PMFlow-Timestamp / X-PMFlow-Signature,签名基串为 "{timestamp}.{raw_body}",算法为 HMAC-SHA256。
  • 执行包拉取请求体必须携带 prompt_package_id / task_id / source / delivery_id / event_source_id,成功后返回机器可读 Project / Task / RepoBinding / PromptPackage / Project Memory context / Quality Contract / callback contract / forbiddenActions,并写入 ProgressEvent(event_type='execution_package_pulled', payload.protocol_version='runtime_execution_package_pull_v1');重复 delivery/source id 必须幂等复用。
  • 回流请求体必须携带 prompt_package_id,并继续使用 execution_result_protocol_v1 的 task_id / event_type / source / branch / commit / PR / test / blocker / delivery_id / event_source_id / delivery_artifacts 元数据。
  • 后端按凭据精确校验 handoff、任务、repo、source allowlist、过期时间和签名;通过后复用登录态执行结果写入服务,继续按 delivery_id / event_source_id 幂等。
  • 前端 /execution-bridge 的执行源包区域只展示运行端接入包、示例 header、拉包 payload 和回写 payload,帮助 Codex / Local Bridge / GitHub agent 领取上下文并回传事实;它不是“开始执行”按钮,也不代表 PMFlow 后端获得宿主机命令执行权。

边界:

  • 运行端凭据不是长期 API token,不保存明文 secret,不可跨 handoff、跨 task、跨 repo 或跨 tenant 使用。
  • 签名拉包只返回执行上下文,签名回流只接收执行结果 metadata;不得执行本机命令、写宿主机配置、创建分支、推送、开 PR、合并、部署、发布或写 Project Memory。
  • 签名错误、source 不在 allowlist、handoff 不匹配、凭据过期或缺少 key 时必须显式失败,不得降级为匿名写入。

执行责任与分派边界:

  • 执行交接只能针对已属于当前 project / tenant 的正式 Task,不得针对 pending_review ChangeItem 直接创建 handoff。
  • Execution Capability Graph 在 handoff 前产出执行模式建议:ai_direct / ai_with_user_acceptance / ai_with_technical_review / needs_human_judgement / blocked。
  • 人类或 agent 的执行责任在 handoff 创建前后形成;在 ChangeSet 阶段最多展示建议 owner / reviewer / agent,不得写成正式 assignment。
  • ai_with_technical_review 必须绑定 reviewer 或返回 warning / blocked,不得把 agent 执行结果直接视为完成。
  • 缺 repo binding、runtime target、PromptPackage、测试命令、权限、回写证据或 reviewer 时,允许创建 draft handoff 或 blocked projection,但不得展示为已开始开发。

4.10 记录执行验收 / 技术审查决策

POST /pmflow-os/projects/{project_id}/execution-acceptance-decisions

请求:

{
  "task_id": "123",
  "decision": "accept",
  "note": "测试证据和业务验收均通过",
  "evidence_event_ids": ["progress-event-id"]
}

行为:

  • 支持 accept / request_changes / reject / request_technical_review / approve_technical_review。
  • accept 与 approve_technical_review 必须先存在 test_passed 或 checks_passed 证据;缺失时返回 acceptance_test_evidence_required。
  • 若质量合同要求技术审查,accept 必须在 technical_review_approved 之后发生;否则返回 technical_review_required。
  • 写入 ProgressEvent(payload.protocol_version='execution_acceptance_decision_v1'),记录决策、备注、证据 event id 与质量合同 id。
  • 返回最新 ExecutionSummaryProjection,供 /execution-bridge、/space 和 /release-growth 消费。

边界:

  • 该接口只记录人工验收/技术审查决策,不执行 merge、deploy、release,也不写 Project Memory。
  • accepted / technical_review_approved 不是 Project Memory commit;执行结果写回必须走 execution_memory_writeback_v1 明确动作。

4.11 记录执行结果写回项目记忆

POST /pmflow-os/projects/{project_id}/execution-memory-writebacks

请求:

{
  "task_id": "123",
  "progress_event_ids": ["progress-event-id"],
  "result": "completed",
  "note": "验收通过后写回项目记忆"
}

行为:

  • 只允许当前 project / tenant 下的正式 Task 写回,不允许 pending ChangeItem 或候选任务写回。
  • 必须已经完成用户验收:acceptance.status=accepted 且 userAccepted=true;仅技术审查通过不能代替用户验收。
  • 必须存在 branch / commit / PR / test / checks / merged / failed / blocked 等执行结果证据;accepted 验收事件本身不算执行证据。
  • 写入 ProgressEvent(event_type='execution_memory_writeback', payload.protocol_version='execution_memory_writeback_v1'),记录 result、note、task_status、evidence_event_ids、acceptance 与 quality_contract_id。
  • result=completed 时将 Task 稳定状态更新为 done 并写 completed_at;blocked / changes_requested 写为 blocked。
  • Project Memory writebacks 读模型会把该 ProgressEvent 投影为 sourceType=execution_memory_writeback 的写回记录。
  • releaseGate 只有在测试证据、验收通过和执行写回三者都满足后才允许 ready;验收后未写回必须保持 needs_confirmation / 等待写回项目记忆。

错误:

  • 404 task_not_found
  • 409 execution_acceptance_required
  • 409 execution_evidence_required
  • 409 writeback_already_exists
  • 409 unresolved_blocker_exists
  • 422 invalid_progress_event_ids

边界:

  • 该接口只把已验收的执行事实写入 PMFlow 项目记忆读模型;不执行 merge、deploy、release、本机命令、外部推送或 ChangeSet commit。
  • Space 只能消费该写回状态派生下一步提醒,不得直接调用写接口。

5. ChangeSet 写入正式对象规则

ChangeItem.objectType 的提交规则:

有效 payload 生成规则:

  • edited 项优先使用 edited_payload,否则使用 payload。
  • PMFlowChangeItem.title / summary / diff 是展示与审计主字段;payload 中同名字段只能补充,不能覆盖人工 edit 后的主字段。
  • 每个正式对象 content/payload 必须写入:source=pmflow_change_set_commit、change_set_id、change_item_id、evidence_ids、confidence、risk_level、committed_by、committed_at。
  • 所有正式写入必须带 tenant_id 查询边界;truth_nodes 历史模型若无显式 tenant_id 字段,必须通过所属 project_id 的 tenant 校验间接保证租户边界。
objectType 正式写入目标 必填字段 写入后前端状态
Requirement truth_nodes(node_type='requirement') title、summary、stage、证据 confirmed
Decision truth_nodes(node_type='decision') title、summary、owner、证据 confirmed
Task truth_nodes(node_type='task') + tasks title、description/summary、priority、acceptanceCriteria draft
Risk truth_nodes(node_type='risk') title、summary、riskLevel、mitigation、证据 confirmed
ModelDecision project_model_bindings 或 model_recommendation_snapshots 引用 catalog_item_id 或推荐快照引用 confirmed
Release truth_nodes(node_type='release') + release validation 引用 title、summary、gate items check_pending/ready
MetricSignal feedback_ingests、revenue_events、roi_snapshots 投影或 recommendation 草案 source、value、window confirmed

C2 V1 白名单:

  • 必须实现:Requirement / Decision / Task / Risk。
  • 可实现但不阻塞 C2:Release。
  • 暂缓实现:ModelDecision / MetricSignal,若收到这两类 item,必须返回 422 unsupported_object_type,不得假成功。

禁止规则:

  • 禁止 accept 时直接写正式对象。
  • 禁止没有 evidence 的高风险项进入 commit。
  • 禁止把 AI 生成内容直接投影为 Project Memory confirmed facts。
  • 禁止让前端用本地 promoteAcceptedToGraph 代替后端 commit。
  • 禁止 commit 后仍让 activeChangeSetId 指向已 committed 的 ChangeSet;projection 应选择最近 open/reviewed ChangeSet,或返回 null。

高风险 approval gate:

  • risk_level=high 的 item 必须存在同 item 的 pmflow_approvals 记录,且 decision in ('approved','edited')、after_status in ('accepted','edited')。
  • 高风险 item 必须能解析到至少一个 evidence link;ChangeSet 级 evidence 可以继承给 item,但 response 里必须显式返回 evidenceIds。
  • gate 失败时整个 commit 不写入正式对象。

6. Execution Bridge 复用合同

PMFlow OS 不重造开发执行系统。执行桥复用:

  • PromptPackage:开发上下文包,创建接口为 POST /projects/{project_id}/charters/{charter_id}/prompt-packages。
  • RepoBinding / GitHubAppInstallation / GitHubAppRepository:仓库与 GitHub App 授权状态。
  • TaskCodeLink:任务与 branch/PR/commit 绑定。
  • ProgressEvent:branch、commit、PR、test、blocker、manual progress 的统一回写事件;PMFlow OS 写入 execution_result_protocol_v1 envelope,保留执行状态和外部执行证据。
  • ProgressEvent 也承载 execution_acceptance_decision_v1 验收审计事件:只表达验收/技术审查决策,不表达合并、发布或项目记忆写入。
  • DevSession:开发活跃会话。
  • GET /projects/{project_id}/dev-sync/summary:当前执行桥最小真实读路径。

ExecutionContext 字段映射:

前端字段 后端来源
taskId active dev task id
status ProgressEvent.derived_task_status + Task.status projection
prompt latest PromptPackage.package_text
commitLog recent ProgressEvent.summary / payload commit fields
prStatus TaskCodeLink.pr_number + progress event
testSummary test progress event / release validation summary
writebackStatus latest progress event workflow state
qualityContract latest execution PromptPackage payload 或正式 Task fallback 生成的测试合同
acceptance progress event 中的测试、失败、技术审查、用户验收事件推导

7. 后续实施顺序

  1. A3 最小真实读路径:已实现 pmflow_os_api read-only projection,提供 truth-state 与 execution-summary。
  2. Phase B:已把 /project-launch 的草案确认接入真实项目创建和初始 Project Memory 写入。
  3. Phase C1:已实现 ChangeSet/ChangeItem/Approval/EvidenceLink 表与 accept / edit / defer 审查 API。
  4. Phase C2 backend:已实现 ChangeSet atomic commit,把 accepted / edited 写入 truth_nodes / tasks / semantic_facts 并补齐高风险 approval gate。
  5. Phase C2 frontend:已把真实模式下的 promoteAcceptedToGraph 接到 POST /pmflow-os/change-sets/{change_set_id}/commit,commit 后 refetch truth-state。
  6. Phase D:把 ExecutionBridgePage 切到 execution-summary 和 dev-sync 真实数据。
  7. Phase D.2:通过 POST /pmflow-os/projects/{project_id}/execution-handoffs 创建执行交接合同,生成/复用 PromptPackage 并记录 handoff_created progress event 起点。
  8. Phase D.6:通过 POST /pmflow-os/projects/{project_id}/execution-memory-writebacks 把已验收执行事实写回 Project Memory / Work Graph 读模型,并把 release gate 的 ready 前置条件收紧为测试证据 + 验收 + 执行写回。
  9. Phase D.10:通过 handoff-bound runtime credential 支持 POST /pmflow-os/runtime/execution-packages 机器可读执行包领取,并继续用 POST /pmflow-os/runtime/execution-results 回写执行事实。
  10. Phase D.11:execution_result_protocol_v1 新增 delivery_artifacts,ExecutionSummaryProjection.deliveryArtifacts / artifactCompleteness 成为 Execution Bridge、Release Gate、Project Memory writeback 与 /space next action 的同源交付证据;缺 changed files、commands run、test outputs、UI 截图或存在 failed artifact 时 fail-closed。
  11. Phase D.12:新增 ExecutionSummaryProjection.artifactReview 与 POST /execution-artifact-review-actions,把交付证据缺口/失败项转为同源审查项,并记录 request_fix / record_fix / mark_recheck_ready 历史;该动作只记录返工意图,不执行命令或写 Project Memory。
  12. Phase D.13:新增 POST /execution-artifact-rework-packages,把 artifact review items 重新包装为可被签名 /runtime/execution-packages 领取的 rework handoff package;运行端拉包响应带 reworkContract,但仍只生成上下文,不执行命令或写 Project Memory。
  13. Phase D.14:artifactReview.closure 把 rework package、package pull 和 runtime result 串成返工闭环;新 passed command/test/checklist 可覆盖同名旧 failed evidence,Execution Bridge / Release Growth 展示 closure、timeline 与 UI screenshot artifact ref,但 closure 不自动验收、不写 Project Memory、不发布。
  14. Phase D.15:releaseGate.releaseReadinessProof / acceptance.evidenceProof / execution_memory_writeback_v1.writeback_proof 共用返工闭环后的复检证据链;closure resolved 且 artifacts ready 时旧 failed artifact 不再阻塞,显式 failed/blocked/test_failed 事件仍 fail-closed;proof ready 不自动发布。
  15. Phase E:把 Release/Growth 投影接入 release validation、feedback、revenue、ROI、compliance。

本文档若与后续实现不一致,必须先更新合同再改代码。