docs: define multi-host agent coordination and recovery plan
This commit is contained in:
@@ -8,3 +8,4 @@
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| ISSUE-20260923-nullable-duty | docgov / nullable / 23503 / reviewer_id | 可选职责空值写 0 导致 FK 失败 | high | resolved | Codex(历史补录) | 2026-09-17;历史 PG / API 冒烟;当前未复测 | [主记录](2026-09-23-historical-issue-records.md#nullable-duty) | [LESSON-20260923-nullable-duty](../ops/lessons/2026-09-23-nullable-duty.md) |
|
||||
| ISSUE-20260923-content-hash | docrevision / canonicalize / hard-break / 404 | 规范化破坏 Markdown 语义并造成正文哈希漂移 | critical | resolved | Codex(历史补录) | 2026-09-14;历史真实 UI / 重启;当前未复测 | [主记录](2026-09-23-historical-issue-records.md#content-hash) | [LESSON-20260923-content-hash](../ops/lessons/2026-09-23-content-hash.md) |
|
||||
| ISSUE-20260923-coordination-authority | agentctl / claim / SQLite / CAS / CURRENT / FEATURE-MATRIX | 本地副本 CAS 与任务许可不能表达跨主机全局权威认领 | high | investigating | Codex(研究) | 2026-09-23;源码/只读状态,未复现具体丢写 | [主记录](../ops/short-term/2026-09-23-coordination-db-daemon-research.md#issue-20260923-coordination-authority) | 沿用 content-hash 投影经验;跨机结论待实施验证 |
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: "多主机 Agent 数据库协调机制调研"
|
||||
task_id: coordination-db-daemon-plan-2026-09-23
|
||||
status: in_progress
|
||||
created: 2026-09-23
|
||||
updated: 2026-09-23
|
||||
owner: Codex
|
||||
task_type: research
|
||||
task_tier: multi_stage
|
||||
policy_revision: "agent-governance-2026-09-21-r1 + systemic-issue-analysis-2026-09-23-r1 + issue-learning-2026-09-23-r1 @ a0fd52a6276b1b531df9ba53e329a645cf8527c9"
|
||||
branch: feature/coordination-db-daemon-plan-2026-09-23
|
||||
worktree: .worktrees/coordination-db-daemon-plan-2026-09-23
|
||||
base_dev_sha: a0fd52a6276b1b531df9ba53e329a645cf8527c9
|
||||
write_scope:
|
||||
- .doc/ops/short-term/2026-09-23-coordination-db-daemon-research.md
|
||||
- .doc/remediation/2026-09-23-coordination-db-daemon-plan.md
|
||||
- .doc/audit/ISSUES.md
|
||||
allowed_environments: []
|
||||
mutex: coordination-db-daemon-plan-docs
|
||||
review_state: approved
|
||||
integration_state: pending
|
||||
deployment: not_required
|
||||
cleanup: retained-with-reason
|
||||
cleanup_owner: 独立维护者
|
||||
cleanup_trigger: 用户审核及后续集成结束、owner 退出后复查
|
||||
remote_sync: not_requested
|
||||
---
|
||||
|
||||
# 多主机 Agent 数据库协调机制调研
|
||||
|
||||
## 用户目标与授权
|
||||
|
||||
用户要求深入核查所附 SQLite/分布式数据库报告,评估将任务认领、执行、文档状态放入数据库,制定非容器 daemon 方案;后续明确“多台主机需要共同协调”。授权终点为可审研究与实施方案,不含安装服务、业务编码、迁移现有状态、恢复旧操作、部署、push 或 dev 集成。
|
||||
|
||||
基线主目录干净;本地 dev 如 frontmatter。首次本地引用比较为 ahead 18 / behind 245(相对 origin/dev 的本地缓存;未 fetch,不表示当前远端实况)。检查已有 worktree 与机器登记后,通过现行 agent-worktree/agentctl 创建并登记本任务;不修改别人现场。
|
||||
|
||||
## 范围与相关经验
|
||||
|
||||
研究 scripts/agentctl.py、agent_worktree.py、相关 hooks/tests 和 CURRENT/FEATURE-MATRIX 的权威边界;检索词:认领、锁、并发、CAS、agentctl、governance、CURRENT、FEATURE-MATRIX。ISSUES/lessons 索引无直接同机制历史项;正文 hash 经验与投影保持语义有关,后续复核。研究型子审查共用本记录,均只读。
|
||||
|
||||
本方案优先遵守仓库 .doc taxonomy,成果放 remediation;不采用 ce-plan 默认 docs/plans 路径。CURRENT 是现行协调快照,机器 task register 是本次启动登记;本轮不为调研改写共享快照或模块能力声明。
|
||||
|
||||
## 研究步骤与验收
|
||||
|
||||
1. 核对现行 SQLite/文件锁、认领/执行、文档 CAS 实现及真实只读状态。
|
||||
2. 官方来源核实报告技术结论,按多主机需求比较方案。
|
||||
3. 明确权威数据、事务与执行边界、失联恢复、daemon 运维和迁移。
|
||||
4. 文档审查、链接/一致性检查,交付方案;不执行实现测试。
|
||||
|
||||
## 验证与交接
|
||||
|
||||
研究已完成,等待用户审核。方案入口: [实施方案](../../remediation/2026-09-23-coordination-db-daemon-plan.md)。
|
||||
|
||||
## ISSUE-20260923-coordination-authority
|
||||
|
||||
- issue_state: investigating;severity: high;owner: Codex(研究);recurrence_count: 0;登记日 2026-09-23。
|
||||
- 预期:所有 Agent 对认领归属和共享文档状态读取相同权威;冲突尽早可见,不在合并时才暴露。
|
||||
- 实际/触发:用户报告读写 FEATURE-MATRIX/CURRENT 与认领容易出问题。源码确认 docs snapshot/apply 读各自 worktree 的副本,scope 注册不含跨任务长期排他;跨主机还超出现有 L1 声明范围。
|
||||
- 机制证据:scripts/agentctl.py:173–185 主仓唯一 SQLite;219–236 写事务;310–329 数据模型;639–688 当前副本文档 CAS;999–1028 task 注册/关闭;scripts/tests/test_agentctl.py:322–341 测试预期主仓文档保持旧值。
|
||||
- 已证实:上述实现边界;数据库已存在;CURRENT 与机器状态独立。未证实:用户具体哪次冲突的丢写、实际发生频率、SQLite 写吞吐瓶颈;未做复现或故障注入,不称为已修复。
|
||||
- 因果链:分散 worktree 基线 + 本地行 CAS → 各副本可以分别合法更新 → Git 集成再解决分歧;scope 许可 + 短操作锁 ≠ 长期任务归属;单主机身份与 flock ≠ 跨主机协调。
|
||||
- 同类检查:CURRENT 与 MATRIX 都走本地副本 CAS;task register/close 与 Markdown 状态双轨;docs:publish 粒度为全局文件写回;worktree create 与 register 分开;Git/环境外部副作用无法加入数据库事务。
|
||||
- 影响边界:工程协调工具、任务归属、状态投影、未来跨主机接入;未对产品数据库/运行链路作故障结论。
|
||||
- 已有防护为何未覆盖:现行 L1 明确只覆盖本机入口、操作锁和副本 CAS;现有测试并未声明验证跨 worktree 全局记录或跨主机长期 claim。
|
||||
- 推荐处理:[方案](../../remediation/2026-09-23-coordination-db-daemon-plan.md);不以数据库换型单独宣称解决。待实施后用两旧 worktree 同版本更新、两主机认领与旧 writer 存活恢复等验收。
|
||||
- 本次时间线:只读定位现机制 → 用户明确多主机 → PostgreSQL/daemon 主方案与 SQLite API 备选 → 设计与数据一致性复核;未开始修复。
|
||||
- 下一步/owner:用户审核方案后由实施 owner 逐 U1–U7 实施;issue 继续 investigating,研究任务完成不关闭问题。
|
||||
- 经验处理:采纳 LESSON-20260923-content-hash 的原文语义/投影恢复检查;没有修复验收,不新增 validated 经验。未来经故障注入与真实双机验收再提炼跨机协调 lesson。
|
||||
|
||||
## 只读验证记录
|
||||
|
||||
| 检查 | 当前证据 / 限制 |
|
||||
|---|---|
|
||||
| Git | 主目录 dev = a0fd52a6276b1b531df9ba53e329a645cf8527c9;启动时 tracked clean;origin/dev 本地缓存 ahead 18 / behind 245,未联网核验远端 |
|
||||
| agentctl status | version=1;唯一主仓 .locks;1 条 env:dev recovery_required、supervisor_alive=false;仅表示 supervisor 不存活,未核查 child/Docker/环境;未执行 recover |
|
||||
| 源码与测试 | 静态核对 Repo.db/Lease/docs/register/recover/hooks/worktree;未运行脚本测试,不将既有测试名记为 PASS |
|
||||
| 主机基础 | Linux;Python 3.14.7 内嵌 SQLite 3.53.4;systemd 259;pg_config 不在 PATH;未检查其他主机、服务账户权限或数据库服务可用性 |
|
||||
| 官方来源 | SQLite、PG、rqlite 等官方文档/项目 README;链接见方案;性能结论均待实测 |
|
||||
| 保全与敏感数据 | 只记录判断所需代码位置及最小状态;未读取 .env,未保存凭证/业务正文,未修改真实环境 |
|
||||
|
||||
## 专项复核及处置
|
||||
|
||||
对 Deep/跨机状态迁移方案进行了架构与数据一致性两个独立只读专项复核;不是运行验收。原始可判定结论及处置如下,5 项均已纳入现有授权的方案修订:
|
||||
|
||||
| 来源 / 级别 | 原文与具体风险 | 处置及复核依据 |
|
||||
|---|---|---|
|
||||
| 架构 P1 | “已确认提交丢失 0”与异步备份“RPO ≤5 分钟”范围不清 | 限定零丢失为持久盘完整的进程/网络故障;灾难恢复按真实 RPO;两类验收分开,不暗含同步异地复制 |
|
||||
| 架构 P1 | 跨机 Git 对象/远端 PASS 不能满足本机 task/worktree HEAD + candidate receipt | 依据 agentctl.py admit_candidate/integrate,U4 增加本机 integration task/worktree 构造两父候选、精确验证及 expected-dev 再核对 |
|
||||
| 数据 P1 | 旧备份没有备份点之后已成功 operation 的 request_id/tombstone | 恢复屏障遍历 executor journal/目标收据,回填结果或 tombstone;未知不重放、失联主机隔离;加入备份后成功再恢复原 ID 重试测试 |
|
||||
| 数据 P2 | 恢复低位事件序号时旧高位 cursor 会漏更新,旧同号 generation 可能误去重 | 事件 cursor、projection identity、manifest/Git receipt 加 authority_epoch;错误 epoch 强制重建 snapshot |
|
||||
| 数据 P2 | U7 导入矩阵后旧已审/已提交 candidate 迟到集成,会破坏 DB 权威 | 增加 matrix authority_version 与独立 drain barrier;最终集成校验版本,覆盖 approved/committed/待 integrate 三种在途情形 |
|
||||
|
||||
主审另补:迟到 heartbeat 不复活过期/quarantined lease;父子路径共享实际执行域的代次;heartbeat/投影回执不递归产生文档发布;proposals 从 U5 起、feature_records 从 U7 起,避免阶段矛盾。
|
||||
|
||||
完成后确认每项已写入方案对应章节与 U-ID 验收。方案 SHA256:fc0f0959298f5589bf7300026322c24528bc69081c2de8e54cf84737a71b8812。
|
||||
|
||||
ce-plan 要求的正式 ce-doc-review 调用结果:`fixes_applied=0, proposed_fixes_count=0, decisions_count=0, fyi_count=0, skipped_reason=skill_unreachable`。本会话没有可调用的通用技能执行入口,未用 generic subagent 冒充该技能调用;ce-doc-review 未运行。上述为 ce-plan 自身授权的专项研究/复核,不将它描述为正式文档技能 PASS,也没有启动外部模型 CLI。下一次有该入口时可追加正式审查;本次研究证据足以支撑可审方案,用户 review_state 仍 pending。
|
||||
|
||||
## 首轮研究交付快照
|
||||
|
||||
- 授权内研究完成:源码/只读状态、官方资料纠错、7 个实施单元、迁移/回退/验收与非容器运维设计均已落盘。
|
||||
- 文档检查:两主文档全部本地相对链接目标存在;R=10、KTD=7、U=7 无重复;六个契约章节存在;git diff --check 通过。未运行实现测试、压力测试、双主机或灾难恢复,不宣称系统已具备新能力。
|
||||
- 本地文件:2 个新增研究/方案文件、ISSUES 新增 1 条;尚未 commit,未合入 dev,未部署,未 push。主目录 tracked clean 且 dev 仍为基线 a0fd52a6276b1b531df9ba53e329a645cf8527c9。
|
||||
- 现行 CURRENT/FEATURE-MATRIX 未改动:没有模块声明变化;本任务通过 machine task register 登记并收口。问题 remains investigating,不伪关。
|
||||
- review_state=pending(用户方案审核);integration_state=not_required(本轮交付终点为可审工作区文档);deployment=not_required;remote_sync=not_requested。
|
||||
- cleanup=retained-with-reason:工作区含待审未提交研究成果,必须保留;独立维护者在用户审核、后续提交/集成与 owner 退出后复查,不自动删除。
|
||||
- 后续建议:审核主方案与首期可停机边界;获实施授权后从 U1–U2 隔离验证起步,跨机真实接入/安装前补齐主机清单、目标权限和备份故障域。采用本方案时同步修改 AGENTS/PROJECT/runbook/验证契约与矩阵权威说明,不能只新增 daemon。
|
||||
|
||||
## 文档集成授权与执行
|
||||
|
||||
用户随后明确要求:“合入dev,然后通过对话再把这个说明返回给我”。据此允许将本任务方案、研究记录与问题台账提交并受控合入本地 dev;不包含业务实施、服务安装、旧操作恢复、环境变更或远端 push。
|
||||
|
||||
沿用 task_id=coordination-db-daemon-plan-2026-09-23;原机器登记已经关闭,现行工具不支持重新打开,故仅为执行登记新增 coordination-db-daemon-plan-2026-09-23-integration-prep,原主任务身份不变。owner=Codex;写范围仍为 frontmatter 的三份文件;mutex=coordination-db-daemon-plan-docs;环境权限为空。
|
||||
|
||||
集成前重读 AGENTS/PROJECT/CURRENT、worktree 规范与验证契约;当前 dev 完整 SHA 与原基线相同,相关 policy 无差异。复核 ISSUES/lessons 无新增同机制条目;继续采用既有文本语义/投影一致性检查。主目录干净;远端仅本地缓存 ahead 18 / behind 245,未 fetch。
|
||||
|
||||
review_state=approved 指用户批准文档进入 dev,不代表授权执行 U1–U7。当前 integration_state=pending;拟提交三份文档,在独立 integration worktree 以原 dev 为第一父节点构建 --no-ff 候选,按验证契约做纯文档检查后,经 agentctl integrate 锁内 --ff-only 推进 dev。实际 SHA、验证与集成收据于完成后补记。
|
||||
|
||||
验证范围:变更清单仅上述三份文档;相对链接及锚点、问题 ID/状态一致、R/KTD/U 唯一、计划六契约、方案 hash 和任务记录一致、Markdown 表格连续性、git diff --check。此为文档集成,不运行产品/脚本实现测试、不重建容器。
|
||||
@@ -0,0 +1,396 @@
|
||||
---
|
||||
title: "多主机 Agent 认领、执行与文档状态数据库化方案"
|
||||
created: 2026-09-23
|
||||
type: feat
|
||||
artifact_contract: ce-unified-plan/v1
|
||||
product_contract_source: ce-plan-bootstrap
|
||||
execution: code
|
||||
task_id: coordination-db-daemon-plan-2026-09-23
|
||||
source_revision: a0fd52a6276b1b531df9ba53e329a645cf8527c9
|
||||
deepened: 2026-09-23
|
||||
---
|
||||
|
||||
# Multi-host Agent Coordination Plan
|
||||
|
||||
## Goal Capsule
|
||||
|
||||
**目标**:不同主机上的智能体看到一致的任务归属,冲突能在执行前被发现,失联或重启后不会让两个写者同时操作共享资源;用户能追溯每次认领、执行与状态变更。
|
||||
|
||||
**推荐手段**:独立原生 PostgreSQL + 中央协调 daemon + 每台主机执行代理;保留现有本机 flock、worktree、精确候选集成和证据门禁。详见 KTD1–KTD7。
|
||||
|
||||
**授权**:本次只交付研究与方案。后续编码、安装服务、接入其他主机、切换状态权威、部署与远端写入需相应实施授权;本方案不自动产生这些权限。执行时以 AGENTS / PROJECT 和当前生效 runbook 为准。
|
||||
|
||||
**交付组织**:U1–U6 构成首期可用交付,U7 完成 FEATURE-MATRIX 结构化治理。只部署协调服务,无需重建产品容器。不恢复已移出的个人中控台,不接入产品管理后台或产品数据库。
|
||||
|
||||
**停止条件**:无法确认旧写者已退出、身份/epoch 不一致、旧新权威同时可写、外部副作用结果未知时,冻结相应资源并保留现场,不自动抢占或回滚。
|
||||
|
||||
---
|
||||
|
||||
## Product Contract
|
||||
|
||||
### Summary
|
||||
|
||||
思路合理,但收益主要来自统一权威数据与操作协议,不能归结为换一个“并发更强的数据库”。用户已明确需要多主机共同协调,因此推荐 PostgreSQL 原生服务;中央 SQLite + API 仍是可行的低运维备选,并非一跨主机就必须放弃 SQLite。禁止的是多台主机通过网络文件系统直接共享 WAL 数据文件。
|
||||
|
||||
日常 Agent 使用结构化命令申请任务、认领范围、执行、更新状态;不再手工改表格认领。任务状态入库,CURRENT 的运行表格变成生成快照。FEATURE-MATRIX 分阶段迁移,能力声明和证据审核保留独立门禁。
|
||||
|
||||
### Problem Frame
|
||||
|
||||
现有系统已是“SQLite + flock + Git/Markdown”,不是只有 Markdown:
|
||||
|
||||
| 已核对事实 | 证据与影响 |
|
||||
|---|---|
|
||||
| 主仓唯一 SQLite,WAL / FULL / BEGIN IMMEDIATE / 5 秒 busy timeout | `scripts/agentctl.py` 的 Repo.db / initialize;已有数据库写事务保护 |
|
||||
| 注册保存 scope;没有独立长期 claim 表 | task register 只防同 worktree 重复 active;许可范围不能表达全任务排他归属 |
|
||||
| 文档 snapshot/apply 读写当前 worktree | 两个旧副本可分别通过本地行 CAS;全局 docs 锁不能使副本变成同一全局记录 |
|
||||
| CURRENT 与 DB 任务状态独立更新 | tasks.state 为 active/done/cancelled;文档任务状态有五种,存在状态映射与可见性延迟 |
|
||||
| 所有 docs apply 共用 docs:publish 锁 | 不同行修改也串行执行文件解析/写回;可以缩短元数据临界区 |
|
||||
| 机器状态仍有恢复待核验操作 | 本次只读 status 发现 1 条 env:dev 的 recovery_required,supervisor_alive=false;不能据此断定子进程消失或环境安全 |
|
||||
| 现行能力声明仅覆盖本机 L1 | FEATURE-MATRIX 的“Agent worktree 治理自动化”为 partial,明确跨机隔离尚未完成 |
|
||||
|
||||
本次确认了实现边界和状态分散的机制,未复现用户某一次具体丢写事故,也没有数据库吞吐、QPS 或延迟证据。问题记录与只读证据见[研究任务](../ops/short-term/2026-09-23-coordination-db-daemon-research.md)。不能把 SQLite 单写者当作已证实根因。
|
||||
|
||||
### Requirements
|
||||
|
||||
| ID | 必须实现的结果 |
|
||||
|---|---|
|
||||
| R1 | 多台主机、多个 checkout/worktree 对同一逻辑仓库使用同一任务和资源权威;本地路径不能充当全局仓库 ID |
|
||||
| R2 | 区分授权 scope、长期 claim、短期 execution lease;重叠排他认领原子拒绝,非冲突工作可并行 |
|
||||
| R3 | 任务、能力记录采用版本 CAS;所有变更具有 request_id、操作者、授权来源与审计,不接受最后写入覆盖 |
|
||||
| R4 | 多资源全有或全无授予;等待有上限、可取消、可查询 holder/原因,读快照不能作为执行授权 |
|
||||
| R5 | 断网、代理/daemon 崩溃、主机重启和响应丢失后仍保持执行排他;未知外部结果不自动重放 |
|
||||
| R6 | CURRENT 状态来自数据库投影;Git 版本可追溯,投影失败不撤销已提交的状态;保留人工正文 |
|
||||
| R7 | FEATURE-MATRIX 完成声明保持范围、审核者、提交、制品/环境与证据绑定;task done 不推导 feature done 或 production_ready |
|
||||
| R8 | 各主机经认证 API 使用已授予能力;CLI 与 hooks/执行代理使用同一协议,不允许客户端自授 capability |
|
||||
| R9 | 协调数据库、进程、配置、备份独立于产品容器和业务数据库;可以原生 daemon 开机启动、升级与恢复 |
|
||||
| R10 | 从当前 SQLite/Markdown 可审计迁移,旧客户端被写入门禁隔离;回退不丢新事件、不恢复旧写权限 |
|
||||
|
||||
### Scope and Assumptions
|
||||
|
||||
多主机是用户明确要求,替代此前单主机假设。初始容量设计按 2–10 台 Linux 主机、20–100 个并行 Agent、同一管理域估算;这不是实测规模。首期接受中央节点故障时暂停受保护写,不承诺高可用;单机故障自动接管、跨地域低延迟和恶意 root 对抗留作独立项目。
|
||||
|
||||
源码编辑继续在独立本地 worktree;普通文件不能靠远程 token 获得内核强制保护。首期提供对合作 Agent 的一致协调,共享 Git 引用/部署动作通过指定执行入口与凭证隔离加强防护;不能宣称任意同 UID shell 都不可绕过。
|
||||
|
||||
不把 Markdown 全文、业务内容或原始日志搬进数据库。方案、规范理由、验收报告和证据主体继续受 Git 管理;数据库保存结构化事实及不可变引用。Web 看板和 MCP 是后续 API 客户端,不是首期依赖。
|
||||
|
||||
---
|
||||
|
||||
## Planning Contract
|
||||
|
||||
### Database Report Review
|
||||
|
||||
以下为官方资料核查后的选型判断,均不等于本仓库性能测试:
|
||||
|
||||
| 报告观点 | 校正与对本任务的意义 |
|
||||
|---|---|
|
||||
| rqlite 最推荐、适合高并发 | Raft 主要解决复制与可用性;写仍经 leader,增加网络/共识成本。HTTP 批量事务并不等同 PG 可交互的读取-判断-写入事务;不能仅为解决 Markdown 冲突就引入三节点 |
|
||||
| dqlite 是嵌入式多节点 SQLite | 基本方向正确,需承担复制、协议及原生依赖;不能从 LXD 使用推导本任务写吞吐或集成成本 |
|
||||
| libSQL 是 SQLite 官方分支 | 是独立项目的 fork,不是 SQLite 官方分支;embedded replica 不等于多写主协调,客户端授权读取不能用可能滞后的副本 |
|
||||
| LiteFS 透明复制可解决锁 | 复制数据库文件不等于跨主机执行锁;单主写、FUSE 与部署约束不能替代任务协议 |
|
||||
| PocketBase 相当于轻量高并发数据库 | 是 SQLite 驱动的后端应用框架;自带用户/订阅不等于已具备本项目 claim、fencing、Git 发布模型 |
|
||||
| bbolt / Badger / Pebble 都有更好的多写者并发 | bbolt 同时只允许一个读写事务;Badger 有并发 ACID 事务,Pebble 提供 batch/snapshot 而非完整事务层,不能笼统排名或当成跨主机协议 |
|
||||
| DuckDB 事务写入也是单写者 | 过度简化:单进程可支持多线程写与乐观冲突控制;其分析型定位及跨进程限制使它不适合此协调服务 |
|
||||
| WAL 读几乎无限并发,NORMAL 就够 | 读仍受 I/O、长事务和 checkpoint 影响;NORMAL 与 FULL 的断电持久性不同。权威认领记录不以降低持久性换吞吐 |
|
||||
|
||||
若启用 SQLite 备选,验收实际程序链接的 SQLite 版本与官方 WAL 已知问题/修复,而非只查 sqlite CLI;本机 Python 当前内嵌 3.53.4,未发现依据可将本问题归因于旧版本 WAL 缺陷。
|
||||
|
||||
来源:[rqlite FAQ](https://rqlite.io/docs/faq/)、[rqlite API](https://rqlite.io/docs/api/api/)、[SQLite WAL](https://sqlite.org/wal.html)、[SQLite PRAGMA synchronous](https://sqlite.org/pragma.html#pragma_synchronous)、[dqlite](https://github.com/canonical/dqlite)、[libSQL](https://github.com/tursodatabase/libsql)、[LiteFS](https://fly.io/docs/litefs/)、[PocketBase](https://pocketbase.io/docs/)、[bbolt](https://github.com/etcd-io/bbolt)、[Badger](https://github.com/dgraph-io/badger)、[Pebble](https://github.com/cockroachdb/pebble)、[DuckDB concurrency](https://duckdb.org/docs/stable/connect/concurrency)。
|
||||
|
||||
### Key Technical Decisions
|
||||
|
||||
- KTD1. **主方案使用专用 PostgreSQL,而不是产品 PG。** 多主机经 API 访问,关系约束、短事务、行锁与审计查询适合此模型;这是维护与正确性选择,不是已测出 SQLite 不够快。原生 PG 有安装、升级、备份成本;采用当前受支持稳定大版本及补丁,实施时锁定版本。
|
||||
- KTD2. **中央 SQLite + API 是低运维备选,首期不同时实现两种后端。** 可保留现行 WAL/FULL 并让单 daemon 串行短写,远端不直接开库。若部署资源极受限可重新采用;并发、安全与投影协议仍然必须实现。rqlite 只在明确要求独立节点多数派容灾且接受其事务模型时再评估;三进程同宿主不构成宿主级容灾。
|
||||
- KTD3. **单权威写服务、稳定 API、独立工具模块。** 建议新增 `tools/agentcoord/` 独立 Go module,产出一个二进制的 server / executor / CLI 子命令;不引用产品 internal 包。现有 Python CLI/hooks 做薄适配,逐步迁移;保留可验证行为,避免同时重写所有 Git 门禁。
|
||||
- KTD4. **长期锁是数据库记录,数据库锁只维持毫秒级事务。** 不把 PG connection / session advisory lock 持续占用到 Agent 工作结束;连接中断不能证明旧工作结束。可用事务级锁或固定命名空间行锁保护认领事务。见[PG 锁说明](https://www.postgresql.org/docs/current/explicit-locking.html)。首期不增加 PgBouncer;其 transaction pooling 不支持 session-level advisory lock,未来引入须按[官方兼容矩阵](https://www.pgbouncer.org/features.html)复核。
|
||||
- KTD5. **安全接管依赖目标侧执行控制。** 单调 token 只是协议字段,目标必须验证并串行执行;对不支持 fencing 的 Git/Docker/普通文件操作,失联后一律隔离等待核验,禁止 TTL 自动接管。
|
||||
- KTD6. **先迁移高频状态,再迁移能力行。** U1–U6 令任务/CURRENT 的机器状态入库;U7 经明确切换将矩阵结构化行权威迁入 DB。每个阶段只有一处权威,禁止 Markdown↔DB 双向自动同步。
|
||||
- KTD7. **数据库变更与外部执行之间使用持久操作状态和 outbox。** 不声称 DB commit 与 Git、文件 rename、Docker 构成一个事务;受控副作用最多一次接受启动、重复查询,无法判定完成则进入恢复。
|
||||
|
||||
### High-Level Technical Design
|
||||
|
||||
以下图与协议描述是设计约束,命名可在实现中细化。
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
A[主机 A: Agent / CLI] --> EA[本机 executor + supervisor + flock]
|
||||
B[主机 B: Agent / CLI] --> EB[本机 executor + supervisor + flock]
|
||||
EA <-->|mTLS: claim / lease / events| C[中央 agentcoord daemon]
|
||||
EB <-->|mTLS: claim / lease / events| C
|
||||
C --> P[(专用 PostgreSQL)]
|
||||
C --> O[持久 outbox / 排队 / 恢复]
|
||||
O --> E[指定集成与环境执行主机]
|
||||
E --> G[Git candidate / env-service 受控入口]
|
||||
O --> W[专用 publisher worktree]
|
||||
W --> D[CURRENT / FEATURE-MATRIX Git 快照]
|
||||
```
|
||||
|
||||
中央 daemon 不向任意主机暴露无范围的 shell;executor 主动连中央服务领取绑定 host 的操作,本机 CLI 可经 Unix socket 请求 executor。普通源码工作在登记任务 cwd;共享操作绑定批准的目标主机和主运行路径。
|
||||
|
||||
**身份模型**:人工登记 `repo_id`(逻辑项目)及 `checkout_id / host_id / worktree_id`;不要把带凭证的 Git URL 当身份,也不按目录字符串合并两个仓库。中央登记唯一 integration target(当前逻辑 dev 权威)及 source ref;其他主机本地 dev SHA 是观测值,不能假装等于权威。新任务从权威基线的精确 SHA 建立,跨机对象通过已授权 Git 读取或校验后的 bundle 传输;制品具有 hash、大小限制和来源。提交 bundle 不等于允许 push origin。数据库 token 不能代替 Git 对象存在性、父链与 expected ref CAS。
|
||||
|
||||
**数据模型**:
|
||||
|
||||
| 记录 | 主要字段与不变量 |
|
||||
|---|---|
|
||||
| repositories / hosts / checkouts | 稳定 UUID、canonical target、协议版本、host boot identity、状态;同 repo 的不同主机路径单独保存 |
|
||||
| principals / grants | 身份、允许 repo/task/resource/action、授权证据/有效期;由已授权管理者登记,不信任客户端 cap 自报 |
|
||||
| tasks | 五态 task_status、owner、base SHA、policy revision、record_version;review/integration/deployment/cleanup/remote_sync 独立字段 |
|
||||
| registrations / authorized_scopes | registration_status、host/worktree/branch、可写范围;登记有效不推导 task in_progress |
|
||||
| claims | task、逻辑资源、claim revision、holder、active/releasing/quarantined/released;只在显式交接/关闭后释放 |
|
||||
| operations / execution_leases | request_id 唯一、payload hash、task、host、状态、token、expires_at、进程身份、结果引用;执行代次与任务状态分离 |
|
||||
| resources / namespace_guards | 逻辑父子路径、环境/分支/index/worktree 类型;创建和重叠检查有统一事务互斥 |
|
||||
| proposals / feature_records | U5 引入待审 proposals 及 canonical Git 基线;U7 引入权威 feature_records,含稳定 feature_id、scope/evidence ref、maturity、row_version;proposal 不等于生效记录 |
|
||||
| events / outbox / projections | 持久事件、请求/记录版本、投影 generation、source refs、输出 hash、Git commit 和发布状态 |
|
||||
|
||||
需有 PK/FK/check 约束、request_id/主体域唯一约束、active exact-resource 辅助唯一约束。父子目录重叠不能靠 exact-key UNIQUE 保证;不得将不存在的记录 `SELECT FOR UPDATE` 当成已锁定未来插入。
|
||||
|
||||
**资源与认领协议**:
|
||||
|
||||
- 授权 scope 是许可上界;claim 是跨主机开发归属;lease 是一次真实操作占用。长期 claim 默认按模块 mutex 或逻辑源码前缀,普通文档用精确文件,不认领整份 CURRENT/MATRIX。
|
||||
- 第一版统一资源申请事务:按固定顺序锁定涉及的 repo/environment namespace guard 行 → 读取并规范化所有 requested resources → 检查 grant、freeze、长期 claim、活跃/隔离 lease → 全部创建或全部拒绝 → 同事务写事件/幂等收据。使用 READ COMMITTED 下锁后新语句重新读冲突集合;所有申请、释放、续期、冻结、恢复路径遵守同一锁顺序。
|
||||
- 命名空间锁只保护短元数据修改,不覆盖命令运行。不同 repo 可并行,同 repo 非冲突执行也可并行;未来仅在压测证实此事务瓶颈后拆 namespace。这样避免“两个事务都查到无冲突后插入”的 phantom 竞态。
|
||||
- 长期 claim 中父/子前缀冲突必须拒绝;`internal/a` 不与 `internal/ab` 冲突。路径去别名、拒绝逃逸/符号链接;大小写与系统文件语义作为接入契约。全局 module/env/ref 资源与 host-local index/worktree 资源分域。
|
||||
- 所有权变更必须带 expected_version;资源忙返回 holder/task/host、等待原因与可安全开展的不冲突范围。排队保留到达序号和有限 deadline,同一冲突域 FIFO;无冲突请求可越过被阻塞队首。取消与授予用同一事务判定,只有一个结果。
|
||||
- 不用大量写数据库的轮询自旋。事件游标 + 有界长轮询;通知只是唤醒,事实读 events。事件游标是 `(authority_epoch, sequence)`;恢复换 epoch 返回 CURSOR_RESET,客户端获取新一致 snapshot 及新起点,不能等旧高序号追平。全局事件顺序采用显式提交序列:同事务锁 event_clock 分配序号并提交,禁止仅以会先分配后提交的 PG sequence ID 推进不可回退游标。
|
||||
|
||||
**执行生命周期**:
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> queued
|
||||
queued --> granted: 全资源授予
|
||||
granted --> starting: executor持本机锁并复核代次
|
||||
starting --> running: 记录进程身份
|
||||
running --> succeeded: 退出与结果已核验
|
||||
running --> failed: 明确失败
|
||||
queued --> cancelled
|
||||
granted --> recovery_required: 启动结果未知
|
||||
starting --> recovery_required: 崩溃或响应丢失
|
||||
running --> recovery_required: 失联/过期/子进程未知
|
||||
recovery_required --> failed: 核实停止及外部结果
|
||||
recovery_required --> succeeded: 核实已完成结果
|
||||
```
|
||||
|
||||
续租在同一资源事务内校验 owner/session、authority_epoch、generation、lease 当前状态及 DB 时间未过期;过期或已隔离的租约不因迟到 heartbeat 自动复活。重新授权需先完成恢复,不借用旧 token。
|
||||
|
||||
可取消排队;取消运行要 executor 确认进程退出并核验副作用后才终态。取消不是撤销已经发生的外部变更。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant A as CLI
|
||||
participant C as Coordinator
|
||||
participant P as PostgreSQL
|
||||
participant E as Host executor
|
||||
A->>C: request_id + scopes + expected_version
|
||||
C->>P: 短事务校验并持久授予
|
||||
P-->>C: operation + token
|
||||
C-->>E: 绑定host的执行请求
|
||||
E->>E: 本机flock + supervisor/cgroup
|
||||
E->>C: 复核lease/epoch/授权
|
||||
C-->>E: 允许该代次启动
|
||||
E->>E: 启动一次,保存本机执行收据
|
||||
E->>C: heartbeat / 完成结果
|
||||
C->>P: 结果、释放及outbox同事务
|
||||
A->>C: 按原request_id查询最终结果
|
||||
```
|
||||
|
||||
**失联处理**:建议初始 heartbeat 10 秒、lease 60 秒,仅用于检测,实施压测后可调。中央以 DB 时间决定有效期,本机用 monotonic deadline 控制启动/续作;时钟跳变、重启、boot 不符进入隔离。所有新副作用启动必须在线确认;续租失败时 executor 停止接收新动作并暂停/终止受监督进程。中央租约过期将资源标 quarantined,不会立即变可用。
|
||||
|
||||
executor 持久保存 operation/request/token 与启动/进程收据;spawn 与记账之间有崩溃窗口时按已命名 cgroup、PID/start/boot 核验,不按“日志没记录”判为未执行。完整子进程必须处于受监督 cgroup,子进程不能靠 setsid 脱管;无法验证范围则保留恢复状态。文件路径仍是 L1 合作边界,若允许旧 Agent 直接写,必须明确其不在强制防护覆盖内。
|
||||
|
||||
**目标侧 fencing**:每个实际写入目标使用 `authority_epoch + generation`,成功持久授予才返回 token。父子路径映射至同一执行冲突域的目标代次;多目标请求返回与各目标绑定的 token 集,不能只按用户任意 path 字符串建互不相识的计数器。目标执行器将“核验代次→串行执行→核验结果→写收据”放在同一操作闸口,持有本机锁直到已知结束;仅在命令前查一次 DB 然后放开锁不够。旧代次完成结果可作为调查证据,不能回写新代次状态。
|
||||
|
||||
首期将 dev 集成与每个共享环境绑定单一指定 executor,部署凭证只在该执行账户,避免其他主机绕过闸口;不设计自动主机接管。若原主机不可达,必须确认电源/访问已被隔离或目标原生拒绝旧 token,才可更换执行主机。Docker 已接受的长操作、远端 Git 已成功的更新不因 kill 本地 client 而取消,必须核对目标事实。对未知外部动作不承诺 exactly-once。
|
||||
|
||||
### API and Agent Experience
|
||||
|
||||
协议是结构化版本化 JSON API,CLI 给人可读摘要并可输出 JSON;不提供通用 SQL,也不让 Agent 直接连 PG。身份主体绑定 repo/grants,所有详情、列表、事件、证据索引均按同一权限过滤。
|
||||
|
||||
| 操作族 | 语义 |
|
||||
|---|---|
|
||||
| task create/get/list/update/close | 创建、CAS 更新五态/交付维度,close 前核对活跃/恢复 operation;不隐式关闭能力 |
|
||||
| claim acquire/get/release/transfer | 全资源认领、明确归属;交接校验 owner/revision/未结束执行 |
|
||||
| execute / operation get/wait/cancel | 幂等请求、有限等待、完整受监督生命周期 |
|
||||
| resource list / freeze / recover | 查询实际占用与隔离,恢复必须 reason + 现场证据 + 管理能力 |
|
||||
| feature propose/review/apply | U7 的版本化能力声明,不以普通 task scope 获得审批权 |
|
||||
| snapshot/export/publish/reconcile | 读一致快照、生成文件、提交发布收据和修复投影 |
|
||||
| candidate validate/integrate / env guard | 沿用冻结 SHA、候选父链、环境批准范围与本机执行身份 |
|
||||
|
||||
每次可重试写请求带 request_id;同主体域同 ID 同 payload 返回原结果,不同 payload 拒绝。保存幂等终态或不可复用 tombstone,不能清日志后让旧 request_id 再次执行。客户端遇超时先查询原 operation;只有明确未接受的新请求可安全重发。返回 CONFLICT_VERSION / RESOURCE_BUSY / RECOVERY_REQUIRED / AUTHORITY_UNAVAILABLE / STALE_EPOCH / PERMISSION_DENIED,区别数据库内部重试和用户资源冲突。
|
||||
|
||||
所有工作区启动读取稳定安装客户端或主仓 bootstrap,协议协商拒绝旧版本写。不要依赖各 worktree 内可能陈旧的 Python 源码执行新权威规则。
|
||||
|
||||
### Document Authority and Publication
|
||||
|
||||
| 信息 | 首期权威 | 后续 |
|
||||
|---|---|---|
|
||||
| 任务状态、owner、claim、队列、操作、恢复、cleanup 接管 | DB | CURRENT 只读投影,CLI 查询实时值 |
|
||||
| CURRENT 焦点、受控约束、说明 | Git 手工区块 | 与生成区块明确边界,不自动丢弃 |
|
||||
| FEATURE-MATRIX 能力行 | 首期 Git;DB 仅保存待审变更建议及基线 hash | U7 切换后结构化行以 DB 为准,Git 保存发布历史 |
|
||||
| 规范、方案、验收报告、证据正文 | Git 不可变提交引用 | 不变;URI/commit/path/hash 组合,不能只存主机绝对路径 |
|
||||
| 发布门禁与 production_ready | gap-matrix | 本方案不迁移、不自动推导 |
|
||||
|
||||
首期通过中央 proposal 队列串行处理 MATRIX 修改,校验指定 dev 的行 hash 与审查证据,停止旧副本直接改行入口,合入成功才确认发布。U7 导入经审核的 canonical dev 表为 feature_records,校验稳定 ID、行数、正文、scope 与证据引用;替换生成区块的权威声明同一个切换窗口生效。U7 有独立 matrix authority_version 切换屏障:冻结 proposal apply/publish,排空或隔离 approved、committed、待 integrate 的所有旧发布,再固定 canonical dev SHA 完成导入核验;原子推进 authority_version 后启用新门禁。最终集成入口也验证此版本,旧候选必须拒绝或显式重基线,不能在导入后迟到集成。先前待审 proposal 重新基线,不能直接当生效数据导入。
|
||||
|
||||
生成器在一致性读事务中获取数据版本;数据库状态变更同时写 outbox。投影 identity 与去重键采用 `(authority_epoch, document_id, generation)`,Git receipt/manifest 必须同样绑定 epoch;旧 epoch 的同号 generation 仅供恢复调查,不抵销新发布。采用 schema/renderer version、源证据 SHA、生成时间、文件 hash manifest;多文件生成先写独立 staging,再由单 publisher 工作区提交同一 Git commit。普通 Agent 不能编辑生成区块;手工区块变动用 hash CAS,保留 Markdown 硬换行与其他正文。只有投影内容字段的变更才推进 document generation;heartbeat、投影自身回执与投影操作审计不递归触发新文档,避免自激发布循环。投影滞后可见,不因滞后阻止普通 DB task 查询;关键授权绝不读 Markdown 快照。
|
||||
|
||||
publisher 不直接写主目录 dev,每次构造最新 dev 的可验证候选并走现行集成入口。快照只在用户请求、任务里程碑或受控批次发布,不每个 heartbeat 产生 Git commit。投影状态 queued/rendered/committed/integrated 分离;Git commit 已完成但 DB receipt 丢失时按 generation/manifest 和提交父链找回,不能重复发布或用旧数据覆盖新快照。
|
||||
|
||||
U7 的 feature done 需要 server 校验审核 grant、已提交证据、适用 source/artifact/environment、验证结论及 record_version;审核者对范围负责。服务器能校验证据结构和身份,不能自动证明报告业务事实。feature maturity、task_status、production_ready 保持不同状态空间。
|
||||
|
||||
### Native Daemon Operations
|
||||
|
||||
推荐一台长期在线 Linux 协调主机原生安装 PostgreSQL 与 agentcoord-server;每台执行主机安装 agentcoord-executor。中央服务可与其中一台开发主机同机,但产品容器重启不得停协调服务。所有路径由安装清单声明,DB data、运行 socket、配置、日志、备份不放 worktree 或产品 data 目录。
|
||||
|
||||
| 服务 | 管理方式与建议 |
|
||||
|---|---|
|
||||
| PostgreSQL 专用实例 | 发行版包与 systemd 管理;专用 cluster/DB/roles/端口,默认仅本机 socket,API 主机是唯一 DB 客户端 |
|
||||
| agentcoord-server | systemd system service,专用非 root 用户,固定已校验制品路径;Restart=on-failure、有限重启退避;启动后 schema/identity/reconcile 完成才 ready |
|
||||
| agentcoord-executor | 每主机专用受授权账户、systemd 管理;本机 socket 控制权限;任务 cgroup 生命周期与守护进程恢复一起核验 |
|
||||
| publisher | 指定 host/worktree 的受控 worker,复用执行代理,不增加第二权威 |
|
||||
| 定期维护 | systemd timer 触发备份/保留/巡检;不自动清除 quarantined 操作或旧 worktree |
|
||||
|
||||
user service 可用于开发试验;要注销后/开机运行必须核验 user manager、linger 和权限,不能拿 nohup 或一次启动成功代替可靠常驻。正式配置优先系统级 unit;Watchdog 仅在实现 sd_notify 心跳后启用,不放一个没有消费的配置。
|
||||
|
||||
中央对执行主机只开放受限私网 mTLS API;host 证书、操作者身份与 task grant 分开,host 有证书不等于能修改任何 task。grant 由明确管理员授权登记;旧 CLI 自报能力的方式不能照搬。DB schema migration 使用独立高权限 role,正常服务不使用超级用户。秘密由 service credential/权限受限配置提供,不读产品 .env,不进入命令参数、日志或 Git。
|
||||
|
||||
/health 只表示进程活,/ready 表示 DB 可达、schema/协议兼容、权威身份已校验并完成启动恢复;某资源 quarantine 单独报告,不要求所有旧问题都解决才能接受无冲突操作。指标至少包含:认领冲突/版本冲突/DB 等待分别计数、事务时长、队列等待、最后 heartbeat、quarantine、投影滞后、备份年龄、磁盘与 PG WAL 增长。
|
||||
|
||||
备份以每日一致性基础备份 + 连续 WAL 归档为目标,保存到另一故障域,做定期隔离恢复演练;保留周期按实际容量配置。启动目标 RPO ≤5 分钟、RTO ≤30 分钟须经测量才承诺;只做每日逻辑备份时不能声称 5 分钟 RPO。[PG PITR](https://www.postgresql.org/docs/current/continuous-archiving.html)
|
||||
|
||||
恢复旧备份后控制平面仍可能落后已发生的 Git/部署事实:生成新 authority_epoch,全部执行租约隔离,撤销旧执行凭据,核对所有 target 后再开放。恢复屏障覆盖每个登记 executor 的持久 journal、最高接受代次与请求收据,不能只遍历备份中存在的 operation。按旧 epoch/主体/request_id 回填结果或不可复用 tombstone;恢复点之后不可重建的请求保持未知并拒绝重放。所有相关 executor 持久确认新 epoch 后才开放其资源;不可达主机继续隔离。新 epoch 的请求必须重新取得授权且不能自动包装未知旧请求为新请求。旧 epoch 与新 epoch 不按 UUID 大小排序,而是严格匹配当前已登记 authority。恢复期间禁止通过“创建空库”开机成功。
|
||||
|
||||
systemd 自动重启服务不代表自动重试任务;二者必须分开。维护升级先 drain、暂停新授予、处理在途 operation、备份、迁移 schema、滚动升级兼容客户端,然后核验后开放。单节点中央故障时允许读最后快照(标 stale),受保护写拒绝;禁止自动回退本地 SQLite 或 Markdown。
|
||||
|
||||
参考:[PostgreSQL 原生启动](https://www.postgresql.org/docs/current/server-start.html)、[systemd service 原始文档](https://github.com/systemd/systemd/blob/main/man/systemd.service.xml)、[PG SSL](https://www.postgresql.org/docs/current/ssl-tcp.html)。本机只读探测已见 Linux/systemd,未验证目标主机/管理员权限;pg_config 不在 PATH 不等于没有运行 PG 服务。
|
||||
|
||||
### Migration and Rollback
|
||||
|
||||
1. 盘点每台主机的 repo/checkout、旧 .locks identity、task/run、文档基线、客户端与 hooks 版本;验证 canonical integration target。把旧 active/done/cancelled 与新五态分开映射,冲突列入人工对照,不猜测 task done。
|
||||
2. 用新服务做只读 shadow 导入与比对,旧入口仍是唯一写权威;影子系统不得授予执行租约。不要在线双写两套权威。
|
||||
3. 切换窗口暂停新旧认领和执行,排空或隔离旧进程;保留原 lock inode。现有 env:dev recovery_required 必须由原 owner/获授权维护者检查,研究任务不替其 recover。
|
||||
4. 各主机安装统一客户端/hook/执行入口,验证旧程序无法再取得共享目标写权限;收紧共享目标凭证。无法升级或核验的主机注销写能力并保持隔离,不能一边放行旧客户端一边宣布多主机已统一。
|
||||
5. 冻结后做最终快照导入,持久保存来源 hash、转换报告与导入 ID;切换 authority/protocol epoch,所有主机核对新的 repo/host 映射后开启首期服务。
|
||||
6. 两台真实主机试点:同资源争抢、不同任务并行、断网与重启、生成投影与 Git 收据;通过后扩大接入,最后单独实施 U7 的矩阵权威切换。
|
||||
|
||||
回退规则:未启用新写时可恢复旧唯一入口;一旦接受新写,不能还原旧 SQLite 快照直接继续。应冻结新入口、排空/隔离执行、导出全量新事件与状态、核验 Git/环境外部事实,再以有版本转换/人工对照的方式恢复兼容权威;无法无损转换时保持新库只读并修复服务。不回滚产品数据库,不强制 reset dev,不自动恢复旧 lease。
|
||||
|
||||
### Capacity and Delivery
|
||||
|
||||
首期压测建议:100 个客户端并发,分布在至少两台主机,持续 30 分钟;混合任务查询、独立认领、同资源冲突、10 秒 heartbeat。100 个执行器约 10 次 heartbeat/秒只是容量估算,不是数据库基准。
|
||||
|
||||
提议验收目标:健康局域网中不含有意资源排队的元数据写 p95 ≤200ms;事务 p95 ≤50ms;在持久盘未丢失的正常运行/进程/网络故障中已确认提交丢失 0、重复共享副作用 0、非法双授予 0。磁盘/整机灾难恢复的数据损失按实测 RPO 报告,不能把异步备份承诺成所有故障零丢失。数据规模、RTT、硬件、样本数、错误类型与长尾均记录。跨地域按实际网络重订时延目标;不以降低同步提交或跳过权限达标。
|
||||
|
||||
工程量估算(未做 prototype):U1–U6 约 15–22 人日,U7 再 3–5 人日;多主机故障注入与迁移演练是主要不确定项。可先用 3–5 人日完成 U1–U2 的独立验证,依据证据继续,不把演示当正式接管。DB 高可用、Web/MCP、跨地域、多租户和恶意用户隔离不计入首期。
|
||||
|
||||
---
|
||||
|
||||
## Implementation Units
|
||||
|
||||
### U1. Identity and Storage Foundation
|
||||
|
||||
**目标 / Requirements**:R1、R3、R8、R9。建立独立工具模块、版本协议、身份与 grant 数据模型、短事务和迁移版本。
|
||||
|
||||
**文件**:拟新增 `tools/agentcoord/go.mod`、`cmd/agentcoord/`、`internal/control/`、`internal/store/`、`migrations/`、`internal/store/store_integration_test.go`(均在该工具模块下)。
|
||||
|
||||
**方法**:先对现有 register/with/docs 行为做特征测试;只复用契约不引入产品依赖。固定命名空间 guard、请求指纹、事件提交序列、授权校验同事务落地。
|
||||
|
||||
**测试与验收**:真实 PG 下相同 task/request 双创建只保留一个;错误主体拒绝;未提交/回滚事务不留下有效 grant/event;两 repo 可隔离;先分配事件后提交的乱序不会丢游标。此阶段不接管真实仓库。
|
||||
|
||||
### U2. Claims and Queue
|
||||
|
||||
**依赖**:U1。**Requirements**:R2–R4。
|
||||
|
||||
**文件**:`tools/agentcoord/internal/control/claims.go`、`queue.go`、`claims_integration_test.go`、`api_contract_test.go`;后续命名可调整,职责不合并到 handler。
|
||||
|
||||
**方法**:授权/长期归属/执行占用分表;所有资源在短事务原子申请,CAS 修改,公平有限等待与取消;CLI 显示可行动的冲突信息。
|
||||
|
||||
**测试与验收**:两主机争父/子路径只一个获准;a 与 ab 不误冲突;批量请求一项冲突则全部不授予;不同记录均能更新、相同行旧 version 失败;grant/release/cancel/续租竞争无双赢;长期 claim 不随一次命令结束释放。
|
||||
|
||||
### U3. Host Executor and Fencing
|
||||
|
||||
**依赖**:U2。**Requirements**:R1、R5、R8。
|
||||
|
||||
**文件**:`tools/agentcoord/internal/executor/`、`executor_integration_test.go`、`recovery_integration_test.go`;适配 `scripts/agentctl.py`、`scripts/agent_worktree.py`、`scripts/tests/test_agentctl.py`、`scripts/tests/test_agent_worktree.py`。
|
||||
|
||||
**方法**:保留本地 flock/生命周期/进程身份,加入 cgroup、host token、本地启动 journal 与续租;创建 worktree 与注册之间采用可恢复步骤,失败保留可归因工作区,不宣称 SQL 可回滚 Git。
|
||||
|
||||
**测试与验收**:kill 中央服务/代理/客户端分别观察真实 child;SIGSTOP、setsid 子进程、主机重启、PID 重用、响应丢失和两次投递均不重复启动;lease 过期后旧 child 活着仍禁止接管;恢复旧 epoch 拒绝旧 token;同 UID 绕过边界明确记录,不冒称已沙箱化。
|
||||
|
||||
### U4. Shared Targets and Git Integration
|
||||
|
||||
**依赖**:U3。**Requirements**:R1、R5、R8。
|
||||
|
||||
**文件**:`tools/agentcoord/internal/executor/targets.go`、`targets_integration_test.go`;适配 `scripts/agentctl.py` 的 validate/integrate/hooks、`scripts/env-service.sh`、`scripts/candidate-images-build.sh`;关联现有脚本测试。
|
||||
|
||||
**方法**:每共享目标一个批准 executor;中央目标身份与本机主目录/环境绑定,不能从任意工作区调用。跨主机移交冻结的 source head 和必要 Git 对象,验证 hash/来源/父链后,由指定 integration executor 在本机注册独立 integration task/worktree,从当前 canonical dev 构造两父候选。按现行准入约束,在该 worktree HEAD 上执行验证并生成绑定本地 task + candidate SHA 的收据,再锁内复核 expected-dev 后推进。远端源分支 PASS 仅为辅助证据,不能代替本机候选验证;dev 前进必须重建重验。publisher 复用此流程。保留冻结制品与真实业务验收门禁。
|
||||
|
||||
**测试与验收**:两个主机同时集成只有一条合法 ref 前进;旧 dev 基线拒绝;候选对象缺失/错 hash 拒绝;远端 source head 的 PASS 不能授权不同 merge candidate,缺本地 owning task/worktree 或精确候选收据拒绝;非目标 executor/无 env grant 拒绝;Docker 已接受操作但 client 死亡时进入恢复并核对实际结果,不能再次自动部署。
|
||||
|
||||
### U5. Current Projection and Matrix Proposal
|
||||
|
||||
**依赖**:U2、U4。**Requirements**:R3、R6、R7。
|
||||
|
||||
**文件**:`tools/agentcoord/internal/projection/`、`projection_integration_test.go`;受控更新 `.doc/ops/CURRENT.md` 的生成区块契约及 Python docs 适配;新增稳定 feature ID 导入映射。
|
||||
|
||||
**方法**:DB 任务/claim 状态自动投影,CURRENT 人工区块保留;MATRIX 先经中央待审 proposal 与 canonical Git CAS,现行矩阵仍为权威。publisher 单独工作区,outbox/manifest/提交/集成收据可恢复。
|
||||
|
||||
**测试与验收**:两个旧 worktree 不再分别宣称同一权威修改成功;同一 generation 多次消费只一个发布结果;两文件中途失败、Git 成功回执丢失、dev 前进均能重建或找回;人工正文/硬换行/其他任务不丢失;未批准 MATRIX done 被拒绝。
|
||||
|
||||
### U6. Native Deployment and Authority Cutover
|
||||
|
||||
**依赖**:U1–U5。**Requirements**:R9、R10。
|
||||
|
||||
**文件**:`tools/agentcoord/deploy/systemd/`、`tools/agentcoord/tests/multihost/`;拟新增原生安装/备份/恢复 runbook;更新 AGENTS、PROJECT、worktree 操作规范、policy-registry、验证契约,按规范单独认领共享文件。
|
||||
|
||||
**方法**:固定制品安装、mTLS、专用 PG、独立配置、schema migration/drain/ready;先 shadow 再一次权威切换。规范修订与工具验收同步,未接入主机不得继续写共享目标。
|
||||
|
||||
**测试与验收**:两真实主机跑完整流程;重启/注销/开机后 unit 状态与 ready;撤销证书/伪造 task/capability 拒绝;冷恢复演练、RPO/RTO 记录,区分完整存储下确认事务零丢失与灾难恢复实际损失窗口;恢复低序号备份时旧高位事件 cursor 收到 reset,旧投影同号收据不可抵销新 epoch 产物;旧 SQLite 客户端/hook 写入拒绝;备份后一次操作成功再恢复旧库,原 request_id 重试不得再次执行;PG 不可用没有本地降级写;完整记录迁移差异与回退条件。
|
||||
|
||||
### U7. Feature Record Authority
|
||||
|
||||
**依赖**:U5、U6 且首期稳定。**Requirements**:R3、R7、R10。
|
||||
|
||||
**文件**:`tools/agentcoord/internal/control/features.go`、`features_integration_test.go`;`.doc/status/FEATURE-MATRIX.md` 的结构化行投影、稳定 ID 映射与版本契约;更新发布规范但不更改 gap-matrix 的门禁结果。
|
||||
|
||||
**方法**:仅迁移完成度表及明确结构化字段;后续 prose/特殊章节逐项保留,不假设当前文件只有一张表。导入后切换生成区块权威;scope/evidence 留 Git 引用,批准记录入 DB。
|
||||
|
||||
**测试与验收**:行数/稳定 ID/原义务/证据/状态完全对照;原模块改名不丢历史;未完成不得因任务关闭变 done;scope 缩小必须显式保留义务迁移;旧报告/错误制品/未提交证据无法升级;将旧 proposal 分别暂停在 approved、committed、待 integrate 后切换 U7,旧 authority 候选均不能迟到进入 dev;production_ready 保持独立。
|
||||
|
||||
---
|
||||
|
||||
## Verification Contract
|
||||
|
||||
所有下列测试为未来实施验收要求,本研究未执行。按现行[验证契约](../ops/2026-09-21-validation-contract.md)分层记录,源码阅读不等于通过。
|
||||
|
||||
| 层次 | 证据与判定 |
|
||||
|---|---|
|
||||
| 原有门禁回归 | `python3 -B -m unittest discover -s scripts/tests -p 'test_*.py' -v`;保留真实退出码,原有 scope/hooks/候选/恢复负例必须通过 |
|
||||
| 新模块静态/单元 | 独立 Go module 内 fmt/vet、`go test -race ./...`;不得用 mock PG 代替事务语义验证 |
|
||||
| 真实数据库 | 并发连接与真实提交、锁竞争、进程终止、SQLSTATE 重试;记录 PostgreSQL/driver/平台版本 |
|
||||
| 多主机协议 | 至少两台实际 Linux host、独立文件系统/boot identity,真实网络故障;单机多进程不冒充跨机 |
|
||||
| 用户使用路径 | 两个真实 Agent 会话通过 CLI 注册/认领/执行/关任务,第三会话观察一致状态;冲突解释可操作,重启后仍保留 |
|
||||
| 共享副作用 | 隔离测试仓库/测试环境实际 Git 和外部执行结果;不污染真实产品对话;受授权上线时再验目标环境 |
|
||||
| 迁移与灾难恢复 | 导入差异、旧入口隔离、数据库恢复、外部结果重核、epoch 失效、备份恢复耗时 |
|
||||
| 文档投影 | 一致 snapshot、CAS、重放、Git 发布恢复、原文语义与各权威状态分离 |
|
||||
| 性能 | 按 Capacity workload 报 p50/p95/p99、错误分类、资源等待与事务等待;未测不宣称达标 |
|
||||
|
||||
额外不变量:任何时刻同一共享目标不存在两个可实际执行的 writer;数据库成功状态不早于已持久结果;暂停/超时/未知不得写成 succeeded;不能以健康检查代替原例、变体与正常路径验收。现有产品 API/浏览器不在此工具变更主验收范围;若实施改变业务行为,再追加相应真实产品验收。
|
||||
|
||||
---
|
||||
|
||||
## Definition of Done
|
||||
|
||||
首期完成:U1–U6 验收通过、两主机真实试点、旧新权威切换可审计、CURRENT 投影与发布可恢复、备份恢复实测;FEATURE-MATRIX 仍明确使用 Git 权威与中央 proposal。完整方案完成还需 U7 完成结构化行迁移与审批验收。
|
||||
|
||||
研究任务 done 仅表示可审方案交付。实施时分别报告本地 commit、dev 集成、协调制品版本与运行主机、数据库 schema、远端是否同步、cleanup;不因文档存在升级 FEATURE-MATRIX。移除试验遗留,保留真实故障证据,按原有保守门禁清理 worktree。
|
||||
|
||||
---
|
||||
|
||||
## Appendix
|
||||
|
||||
**直接源码**:`scripts/agentctl.py` 的 Repo.db、Lease、supervise、docs_snapshot/docs_apply、task register/close、recover、hooks、integrate;`scripts/agent_worktree.py` 的 create/write_lock/removal_lock;`scripts/tests/test_agentctl.py` 和 `test_agent_worktree.py`。
|
||||
|
||||
**关联规范**:[工作规范](../ops/2026-09-21-agent-worktree-workflow.md)、[规范登记](../ops/2026-09-21-policy-registry.md)、[文本/投影经验](../ops/lessons/2026-09-23-content-hash.md)、[能力矩阵](../status/FEATURE-MATRIX.md)。
|
||||
|
||||
**尚需部署时确定的信息**:中央主机及执行主机清单、私网/mTLS 签发方式、管理员账户、可用磁盘与备份目标、明确环境授权。这些不阻止方案和隔离实现,但阻止真实安装与权威切换。实际性能、恢复时长、旧任务处置由验收决定,不在研究中预报 PASS。
|
||||
Reference in New Issue
Block a user