From 4629b871db8df32aeea4d620886dc8956296ddb9 Mon Sep 17 00:00:00 2001 From: weichen Date: Tue, 13 Oct 2026 08:21:46 +0000 Subject: [PATCH] Connect delivery windows and recovery to the repository rules Why: agents need consistent entrypoints and recording defaults to avoid retrying synchronization and CI outside the final delivery window. Evidence: SELF generated-task-card red-green regression and governance suite recorded through make evidence; pending shared record created as Issue #518. Impact: rules, task template and capability matrix stay explicit about pending activation, default strict startup, manual coordination and unchanged CI triggers. Refs: U4; policy/merge-queue.md; .task/feature-merge-queue-policy-draft.md --- AGENTS.md | 8 ++++++-- PROJECT.md | 2 +- policy/adoption.md | 3 ++- policy/delivery.md | 7 +++++++ policy/merge-queue.md | 16 +++++++++------- policy/tool-adaptation-matrix.md | 10 ++++++---- scripts/task.sh | 8 ++++++++ tests/test_task.py | 5 +++++ 8 files changed, 44 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 98963749..bcc40c3a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -25,8 +25,9 @@ 完整脱敏收据(不要求已有任务卡);按输出完成必读。`SHARED_WORKSPACE_BUSY / SYNC_REQUIRED / REMOTE_UNVERIFIED` 均不得进入写入流程;失败后排除原因再启动,不把缓存远端当最新事实。 - 新任务运行 `make task-start NAME=feature/ PRECHECK_RECEIPT=/tmp/<本次唯一名称>.json`, - 建立独立 worktree 与任务卡并导入首次收据。恢复已有任务在原任务工作区导入收据: - `IMPORT_RECEIPT=/tmp/<本次唯一名称>.json make evidence`。任务中途不重复启动检查。 + 建立独立 worktree 与任务卡并导入首次收据。恢复已有登记任务在原 worktree 用 + `make task-resume PRECHECK_RECEIPT=/tmp/<本次唯一名称>.json` 验证并原样导入收据。 + 默认 delivery 要求严格 READY;局部恢复接口、启用条件与旧收据处理见 [开发门禁](policy/governance.md#启动与恢复)。任务中途不重复启动检查。 - **分支层级**:任务分支一律从权威 `origin/main` 切(`task-start` 已强制);同批互不依赖的 子任务用同一 R0 的兄弟分支。确有顺序依赖需从父 feature 分支切子分支时(collaboration.md 允许的堆叠例外):启动命令增加 `PARENT=feature/<父slug> PARENT_PR=<父PR链接>`, @@ -35,6 +36,9 @@ base 改回 main,方可声明可合入(分支保护要求 head 含 origin/main,未同步必被拦)。 - **验收、请求审核、合入前**各运行一次 `make task-sync`;完成声明的 precheck、task-sync、 测试三段输出由 `make evidence` 写入任务卡(见「证据与验证门禁」),不手抄。 +- **多个分支交付 / CI 调度**:先读 [合入调度](policy/merge-queue.md),核对采纳状态、协调者、 + 记录及当前窗口。新模式尚未启用时保留既有同步节点;启用后最终同步至合入核验共用窗口, + 同基线 `task-sync` 只核验,固定后检查用源码外 RECEIPT 保存(见 [证据流程](policy/governance.md#候选固定前后))。 - 合入后由工作区 owner 确认所有写者退出,在**已登记任务 worktree 根目录**运行 `TASK_WRITERS_STOPPED=1 make task-finish`。父子仓改动、未跟踪/ignored 唯一文件先保存或显式处置;删除被拒时 保留现场并按原因处理,禁止强删兜底。放弃未合入工作用 diff --git a/PROJECT.md b/PROJECT.md index 8fef460e..7d00d111 100644 --- a/PROJECT.md +++ b/PROJECT.md @@ -51,7 +51,7 @@ U2 起实施与部署分别评审。 ## 验证 -规范修订:[最终验证与合入调度 r1](policy/merge-queue.md) 已作为实施计划基线。Documents 的 U1–U6 计划待阶段 5 评审,独立候选位置见本任务卡;当前 gitlink、脚本、CI 和平台模式未切换。 +规范修订:[最终验证与合入调度 r1](policy/merge-queue.md) 及 Documents 的 U1–U6 计划已批准,位置及固定提交见本任务卡。同步幂等化、显式局部恢复和源码外证据基础在本分支实施;当前规范 gitlink、CI 触发与平台调度模式尚未切换。 `make test` 先核对子模块工作树与固定指针,再运行治理脚本、公开边界、跨仓指针、库及各模块 测试。实际目标以根 Makefile 为准。`make test-governance` 可独立检查开发门禁,使用临时 diff --git a/policy/adoption.md b/policy/adoption.md index 0b594ed9..110a9393 100644 --- a/policy/adoption.md +++ b/policy/adoption.md @@ -11,7 +11,7 @@ |---|---|---| | core/baseline.md | 日常 | manual | | workflows/delivery.md(含启动自检 §1) | 交付 | 本地命令检查;首次收据与 BUSY/SYNC/REMOTE_UNVERIFIED 语义见 policy/governance.md | -| standards/collaboration.md | 并行/同步节点 | **enforced(本地)**:pre-commit 拒绝集成分支直提与坏分支名(负例:hook-main/badbranch 拒绝输出);节点同步由 task-sync 落卡 | +| standards/collaboration.md | 并行/同步节点 | **enforced(本地命令)**:分支、现场、组件检查;task-sync 实际合并时记录,同基线只核验。最终平台与阶段授权另验 | | 提交格式(主题行/四段 body) | 全部提交 | 主题行 enforced(local),body manual;任务工具生成四段 body,历史 PR 仅作旧版本证据 | | standards/verification.md | 验收 | 本地 make test-governance + 组合测试;当前证据与历史 scratch 记录分开 | | standards/multi-repo.md | 跨仓/gitlink | manual;受控历史迁移通道已于 2026-09-30 行使一次(documents/records/2026-09-30-history-migration.md) | @@ -20,6 +20,7 @@ | standards/tool-adaptation.md(draft.8) | 为工具创建规则/钩子实例 | 本组合 CLI/git 级实例已登记:policy/tool-adaptation-matrix.md(A1–A7 逐行定级+正负例证据) | | 同上(zcode 实例) | zcode 客户端写路径 | policy/tool-adaptation-zcode.md:PreToolUse 写守卫;脚本负例与客户端接线分开,客户端 pending-live | | core/baseline.md「规范层级」+ documentation.md「记忆分层/机制化」(draft.9) | 层级效力、记忆权威、经验机制化 | manual:本仓 policy/ 仅收紧不放宽;记忆四层按条文执行(任务卡=任务记忆,documents/records=项目记忆,Dev 仓 AGENTS.md 指针已就位) | +| draft.11 合入调度候选 | approved;尚未采纳固定 gitlink/启用模式 | 本地 CLI 支持已自检(SELF,任务卡);平台、共享调度记录和真实试行待完成;保留现行准入条件 | ## 项目差异 diff --git a/policy/delivery.md b/policy/delivery.md index 733d798f..10c6f594 100644 --- a/policy/delivery.md +++ b/policy/delivery.md @@ -46,6 +46,11 @@ 正式测试和最终 Review 的顺序不限制设计阶段试验、实施期测试或提前审阅。 文本合并无冲突不证明组合兼容;合入后仍核验真实内容与被测候选是否一致。 +多个就绪任务的最终验证与合入按 [合入调度](merge-queue.md) 的采纳状态执行。 +新模式生效后,阶段 7–9 在同一目标交付窗口内完成;对象未变时各节点重复核验, +不因记录检查再创建提交或重跑有效 CI。窗口领取不代替人工结论、独立 Review 或平台准入; +未生效时继续既有同步规则。固定后的证据按 [源码外收据流程](governance.md#候选固定前后) 保存。 + ## 长期方向与任务衔接 用户提出大方向、长期目标或跨任务规划时,必须在项目中留存可接续的主记录,不能仅保留 @@ -169,6 +174,8 @@ 本流程由智能体执行,任务卡模板和本地提示不构成平台强制门禁。平台能力按 [能力矩阵](tool-adaptation-matrix.md) 核验;分支保护变更仍由用户按双钥匙边界执行。 +交付窗口覆盖普通 PR、闭合 PR、机器人及紧急通道;coordination 仍为 manual 时如实登记, +当前目标在窗口内被外部推进则建立新尝试,不继续使用旧候选的绿色结果。 ### 清理与恢复 diff --git a/policy/merge-queue.md b/policy/merge-queue.md index e9e4abb9..cdc88a9f 100644 --- a/policy/merge-queue.md +++ b/policy/merge-queue.md @@ -3,7 +3,7 @@ 状态:approved(r1 条文作为实施计划基线);执行模式:未切换;日期:2026-10-13(Asia/Shanghai);规范采纳负责人:weichen。 本聊天在 r1 草案交付后收到用户「继续」,按上一轮出口进入实施计划编制;r1 来源提交为 913b214f2826a50b3dab65f79d9ebf83e84f2519。实施与测试计划仍须阶段 5 评审,规范批准不等于模式已启用。 现行规则仍以根 AGENTS.md、[迭代交付](delivery.md)、[开发门禁](governance.md) 和已采纳 gitlink 为准。 -本草案不启动线上队列,不改变脚本、CI、平台保护或当前 gitlink,也不承诺调度能力已就位。 +本分支已实施 CLI 同步/恢复及源码外证据基础,自检依据见本任务卡;线上队列、CI 分流、平台保护和当前 gitlink 尚未切换,不承诺自动调度能力已就位。 ## 通用规范与项目职责 @@ -20,7 +20,8 @@ Dev 目标身份使用实际托管实例、仓库 ID 与 `refs/heads/main`;其 采纳后的首版使用每个目标一份 Gitea 调度 Issue,由一个明确协调者维护,标为 manual。 任务卡引用 Issue 条目及尝试标识,原任务仍是授权、需求和阶段的状态权威。 -当前尚未创建该 Issue,协调者应在试行启动前指定;不得向既有任务或其他执行者自动发送调度消息。 +共享记录已建立:[Dev main 调度记录 #518](https://git-home.u1680832.nyat.app:30319/weichen/Agent-System-Dev/issues/518),状态准备中、尚无条目/窗口;创建命令及结果见任务卡 SELF 收据。 +协调者应在试行启动前指定;当前记录不开放领取,也不自动向其他任务分配工作。 必须记录目标、条目、执行者、源 HEAD、依赖、顺序、尝试、最终 base/head、组件清单、 检查定义及相关配置、实际 CI 链接/身份、Review 对象、真实合入结果和暂停/恢复原因。 @@ -41,14 +42,15 @@ Dev 目标身份使用实际托管实例、仓库 ID 与 `refs/heads/main`;其 | 场景 | 拟采用动作 | 当前实现边界 | |---|---|---| | 新任务启动 | 保留唯一 precheck 收据与 `task-start`,从最新权威 main 建独立工作区 | 现有命令保留 | -| 恢复落后任务的局部工作 | 核对现场、授权和落后状态,记录待最终同步;允许已授权局部编辑 | 当前 precheck 的 SYNC_REQUIRED 仍阻断写入;需实施后才能启用新模式 | +| 恢复落后任务的局部工作 | 核对现场、授权和落后状态,记录待最终同步;允许已授权局部编辑 | 已实现显式 local/LOCAL_READY 及 task-resume;默认仍严格,流程待采纳启用 | | 其他任务合入、排队等待 | 更新落后/依赖提示,不自动同步各分支或触发完整 CI | 无自动调度能力,不能宣称已接线 | | 领取最终交付窗口 | 成功 fetch,运行 `make task-sync`,实际合并最新 main、处置冲突、物化固定组件 | 使用真实同步及祖先检查,保留脏状态/远端失败拒绝 | -| 窗口内再次到达验收、审核、合入节点 | 再查最新目标和候选;未变只核验,不创建元数据提交 | 当前 task-sync 每次追加并提交记录,幂等化属于后续实施 | +| 窗口内再次到达验收、审核、合入节点 | 再查最新目标和候选;未变只核验,不创建元数据提交 | 已实现同基线不提交,保留组件核对和完整最终 SHA | | base/head、组件或相关配置变化 | 保留旧结果对象范围,重新建立尝试并按影响补测/复审 | 当前 HEAD 的全部必需 CI 仍必须实际通过 | -SYNC_REQUIRED 不能被整体降级为 READY。后续应明确区分“允许局部工作”和“允许最终交付”, -并同步修改写守卫、启动收据验证、任务恢复入口及回归用例;共享工作区忙、未知远端和活动 Git 操作继续拒绝相应写入。 +SYNC_REQUIRED 不整体降级为 READY;local 与 delivery 用独立结果和验证用途区分。 +已同步启动收据验证、恢复入口及回归,写守卫保留原分支检查,不宣称已校验阶段批准。 +共享工作区忙、未知远端和活动 Git 操作继续拒绝相应写入。 幂等化的判据是:成功 fetch、目标已包含、递归组件检查通过时,重复核验不改变 HEAD、索引和提交内容; 仍产生可复核的实际输出。任务真正需要纳入新目标时保留 merge 与对应对象记录。 @@ -124,7 +126,7 @@ SYNC_REQUIRED 不能被整体降级为 READY。后续应明确区分“允许局 |---|---|---| | MQ1 | A/B/C 正常顺序交付;各任务轮到后最终同步一次,无外部推进时不因其他正常合入反复跑最终 CI | NOT_RUN(后续隔离试行) | | MQ2 | 同目标重复领取被拒,不同目标可在资源预算内并行 | NOT_RUN(后续机制验证) | -| MQ3 | 同步后目标未变,重复核验不改 HEAD;固定后记录不改变候选 | NOT_RUN(脚本尚未修改) | +| MQ3 | 同步后目标未变,重复核验不改 HEAD;固定后记录不改变候选 | 本地 CLI/证据回归已执行(SELF,原始输出见任务卡);平台试行 NOT_RUN | | MQ4 | 新 HEAD、base 或组合不能使用旧 CI/Review 直接放行 | NOT_RUN(后续正负例) | | MQ5 | 冲突、代码失败、等待人工决定超时释放窗口,不阻塞无依赖任务 | NOT_RUN(后续试行) | | MQ6 | 紧急插队有依据,受影响候选失效;跨仓依赖和组件能力不回退 | NOT_RUN(后续试行) | diff --git a/policy/tool-adaptation-matrix.md b/policy/tool-adaptation-matrix.md index 50e8a8db..31212a36 100644 --- a/policy/tool-adaptation-matrix.md +++ b/policy/tool-adaptation-matrix.md @@ -2,13 +2,13 @@ 适配对象:通过 shell/git 操作本仓的执行者。要求来自固定的 Development-Guidelines `standards/tool-adaptation.md` 与根 AGENTS.md;本表登记机制范围,不复制另一套规则。 -当前修订为治理可靠性修复候选;实际验证记录见 `.task/feature-governance-reliability.md` -及其关联 PR。历史 19/19 临时测试不代替本次回归。 +历史治理可靠性记录见 `.task/feature-governance-reliability.md`;本轮调度与恢复候选的 +实际 SELF 命令记录见 `.task/feature-merge-queue-policy-draft.md`。历史测试不代替当前对象回归。 | 要求 | 执行能力及范围 | 机制 | 复验入口 | |---|---|---|---| -| A1 启动 | 本地命令阻断;执行者首次调用仍属 manual | precheck 区分忙/落后/远端未核实;start 验证首次收据 | `tests/test_task.py`、`tests/test_evidence.py` | -| A2 同步 | 本地命令阻断;最终准入由平台承担 | 合并父仓、保护组件分支、物化固定指针、递归核对 | `tests/test_task.py`、`make test-worktree` | +| A1 启动/恢复 | 本地命令阻断;首次调用及阶段授权仍属 manual | 默认严格 READY;显式 local 验证既有任务/R0及 LOCAL_READY;start 固定严格用途,resume 验证后导入 | `tests/test_task.py`、`tests/test_task_recovery.py`、`tests/test_evidence.py` | +| A2 同步 | 本地命令阻断;最终准入由平台承担 | 合并父仓、保护组件分支、物化固定指针、同基线幂等、完整最终 SHA | `tests/test_task.py`、`make test-worktree` | | A3 集成分支 | 本地提交闸;平台状态须独立核验 | pre-commit 拒绝 main/master 与坏分支名 | 本地 hook 负例;远端缺 CI/陈旧候选/直推等负例另验 | | A4 提交格式 | 主题行 enforced(local),body manual | commit-msg 校验宽度/句点;任务工具生成四段 body | `tests/test_task.py`;人工核对 PR/卡片同源 | | A5 回收 | 本地命令检查;写者退出由 owner 确认 | 登记根目录、锁/操作状态、父子仓与唯一文件、合入核验 | `tests/test_task.py` | @@ -16,6 +16,8 @@ | A7 证据 | 本地 SELF 收据;外部来源独立核验 | 首次捕获、完整脱敏输出/摘要、对象记录、原样导入 | `tests/test_evidence.py`;CI/审阅链接另核 | | A8 阶段评审与迭代 | manual(人工/Agent 执行);前序人工决策,智能体 Review/合入;模板和提示不构成批准身份校验或全流程阻断 | policy/delivery.md;任务卡分别记录阶段结论、Review、冲突、当前 HEAD 的 CI 和合入;post-merge 默认仅提示 | `tests/test_task.py` 核对模板及钩子不自动写入;智能体核对 Review、冲突及匹配 HEAD 的 CI/平台准入;人工批准范围仍须核验 | | A9 长期方向与后续任务 | manual;模板不校验规划有效性或自动调度任务 | policy/delivery.md;PROJECT.md 提供规划入口,任务卡关联规划/里程碑并记录下一步建议 | `tests/test_task.py` 核对生成字段与未授权默认值;人工核对当前规划、进展、重复任务和建议依据 | +| A10 交付窗口 | manual(待启用);无自动互斥或接管 | policy/merge-queue.md;Issue #518 已建,协调者/规范 gitlink/平台与真实试行待完成 | tests/test_merge_queue_trial.py 临时 Git 场景 SELF;平台/真实 CI 三任务试行 NOT_RUN | +| A11 固定后证据 | manual 选择源码外位置;工具捕获绝对未用路径/原始输出;无 OS 冻结 | policy/governance.md;RECEIPT 捕获,后续授权闭合再原样导入 | `tests/test_evidence.py` 固定对象、权限、覆盖拒绝、原样导入与幂等 | ## 失败处理 diff --git a/scripts/task.sh b/scripts/task.sh index 22daeff8..902c8b7e 100755 --- a/scripts/task.sh +++ b/scripts/task.sh @@ -256,6 +256,14 @@ ${parent_note} | 时间(UTC) | 命令 | 被测HEAD | exit | 来源 | sha256(16) | |---|---|---|---|---|---| +## 交付调度 + +- 调度状态:未入队;调度记录:无 +- entry_id:无;attempt_id:无;窗口执行者:无 +- 固定候选:无(base/head、组件与相关配置引用实际尝试) +- 调度依据:policy/merge-queue.md;新模式启用前按既有交付门禁 +- 固定后证据:源码外 RECEIPT;实际结果后按授权原样导入和闭合 + ## 结果与验证(完成后填写) - 结果: diff --git a/tests/test_task.py b/tests/test_task.py index 3b6a0ad3..323797b6 100644 --- a/tests/test_task.py +++ b/tests/test_task.py @@ -697,6 +697,11 @@ class TaskLifecycleTests(unittest.TestCase): self.assertIn(f"{field}:无", card) for field in ("当前阶段", "当前增量", "方案引用", "实施计划引用", "测试计划引用"): self.assertIn(field + ":", card) + self.assertIn("## 交付调度\n", card) + queue = card.split("## 交付调度\n", 1)[1].split("\n## ", 1)[0] + self.assertIn("调度状态:未入队", queue) + for field in ("调度记录", "entry_id", "attempt_id", "窗口执行者", "固定候选"): + self.assertIn(field + ":无", queue) self.assertIn("## 关联方向与规划\n", card) planning = card.split("## 关联方向与规划\n", 1)[1].split("\n## ", 1)[0] for field in ("适用状态", "主记录路径/版本", "对应里程碑"):