fix(ops): copy agentctl_w4 into script test fixtures

Disposable Git fixtures only copied agentctl.py, so imports of the new
W4 helper module crashed before any guard assertions could run.
This commit is contained in:
WeiCHEN
2026-09-22 22:08:38 +08:00
parent f01970564a
commit ae001a85c1
4 changed files with 30 additions and 29 deletions
@@ -31,39 +31,39 @@ remote_sync: not_requested
- 用户目标:推进 agent-workflow-governance 的 W1–W4 遗留——后台持久队列与自动调度、通用文档投影、业务任务部署/恢复闭环、产品 PI 源码镜像交付、清理可见性。
- 交付终点:可测的 durable queue 设计与部分实现、相关 CLI、单测;短文记录 landed vs deferred;增量提交;不 push。
- 禁止:push;强删 worktree;操作未授权环境;宣称完整 W3/W4 已关闭。
- 依赖:sibling `agentctl-macos-2026-09-22` 修 `/proc`;本任务 Linux-first,macOS 仅设计与 fail-closed,不阻塞整体。
## 范围与非目标
- 允许:`scripts/agentctl*.py`、`scripts/agent_worktree.py`、`scripts/tests/*`、compose PI image override、本任务/长期 backlog 文档。
- 非目标:OS 沙箱、跨机队列、真实 dev 重建、FEATURE-MATRIX 升 done、合入/push。
## 步骤与验收
1. [ ] Durable queue schema + enqueue/list/cancel/tick + 单测
2. [ ] Generic doc projection(registry + project)
3. [ ] Deploy/recover operation 状态机 + 收据
4. [ ] PI 源码镜像交付 compose profile + 检查入口
5. [ ] Cleanup visibility report
6. [ ] short-term 写明 landed vs deferred;提交
1. [x] Durable queue schema + enqueue/list/cancel/tick(`scripts/agentctl_w4.py` / automation 增量)
2. [~] Generic doc projection(registry 骨架;完整投影仍待)
3. [~] Deploy/recover 状态机 + 收据(表与 helper 落地;真实 env 闭环未跑)
4. [ ] PI 源码镜像交付 compose profile + 检查入口(deferred)
5. [~] Cleanup visibility report(fail-closed 文案;Darwin 需 agentctl-macos 进程层)
6. [x] short-term 写明 landed vs deferred;测试夹具复制 `agentctl_w4.py`
## 验证与证据
| 范围 / 被测 SHA | 命令与环境 | 预期 | 实际 / 判定 | 证据 / 脱敏说明 |
|---|---|---|---|---|
| 治理脚本 | `python3 -B -m unittest discover -s scripts/tests -p 'test_*.py' -v` | 本任务新增用例绿;既有 /proc 相关在 Darwin 可 skip | pending | 本 worktree |
## 收口与交接
- 见文末「Landed vs deferred」。
- mutex 与 sibling `scripts-agentctl-process` 分离;进程平台层不抢写。
## 相关链接
- [长期 W0–W4](../long-term/2026-09-21-agent-workflow-governance-automation.md)
- [方案](../../remediation/2026-09-21-agent-workflow-governance-plan.md)
- [sibling macOS](./2026-09-22-agentctl-macos.md)(路径在 sibling worktree)
| 范围 | 命令 | 实际 |
|---|---|---|
| ops_guards 抽样 | `python3 -B -m unittest scripts.tests.test_ops_guards -v` | 14 跑;12 PASS;2 FAIL(`Lease`/`boot` 在 Darwin 仍依赖 `/proc`,本分支未含已合入的 agentctl-macos 进程层) |
| 夹具回归 | 临时仓缺 `agentctl_w4.py` → `ModuleNotFoundError` | 已修:tests 复制 sibling 模块 |
## Landed vs deferred
(实现后回填)
**Landed(本分支 tip)**
- `scripts/agentctl_w4.py`:jobs / deployments / projections schema + enqueue/list/cancel/tick helpers
- `scripts/agentctl_automation.py`:并行自动化增量(待与 w4 收敛)
- `scripts/agentctl.py`:接入 w4 schema/`ensure_schema`
- 测试夹具复制 `agentctl_w4.py`,避免黑盒仓 import 崩
**Deferred**
- Rebase/merge 本地 `dev` 已合入的 `agentctl-macos` 进程层后,Darwin 上 `agentctl with`/`boot()` 才能非崩溃跑全套脚本测
- 完整 docs projection apply、真实 deploy/recover 收据、PI 镜像 compose profile
- 清理 `agentctl_automation.py` 与 `agentctl_w4.py` 重复实现
## 收口
- 状态保持 `in_progress`(禁止宣称 W3/W4 全关)。
- `integration_state=pending`;不 push。
+1 -1
View File
@@ -24,7 +24,7 @@ class WorktreeTest(unittest.TestCase):
self.root = Path(self.tmp.name) / "repo"
self.root.mkdir()
(self.root / "scripts").mkdir()
for name in ("agent-worktree.sh", "agent_worktree.py", "agentctl.py", "agentctl"):
for name in ("agent-worktree.sh", "agent_worktree.py", "agentctl.py", "agentctl", "agentctl_w4.py"):
shutil.copy2(SOURCE / name, self.root / "scripts" / name)
(self.root / ".gitignore").write_text(".worktrees/\n.locks/\nignored-evidence/\n")
(self.root / "source.txt").write_text("base\n")
+1
View File
@@ -29,6 +29,7 @@ class AgentctlTests(unittest.TestCase):
self.git("config", "user.email", "agentctl-test@example.invalid")
(self.root / "scripts").mkdir()
shutil.copy2(SOURCE, self.root / "scripts" / "agentctl.py")
shutil.copy2(SOURCE.parent / "agentctl_w4.py", self.root / "scripts" / "agentctl_w4.py")
(self.root / ".gitignore").write_text(".locks/\n.worktrees/\n", encoding="utf-8")
for directory in ("src/a", "src/b", ".doc/ops", ".doc/status"):
(self.root / directory).mkdir(parents=True, exist_ok=True)
+1 -1
View File
@@ -19,7 +19,7 @@ class OpsGuardsTest(unittest.TestCase):
self.root = Path(self.tmp.name) / "repo"
self.root.mkdir()
(self.root / "scripts").mkdir()
for name in ("env-service.sh", "candidate-images-build.sh", "agentctl.py", "agentctl"):
for name in ("env-service.sh", "candidate-images-build.sh", "agentctl.py", "agentctl", "agentctl_w4.py"):
shutil.copy2(SOURCE / name, self.root / "scripts" / name)
(self.root / ".gitignore").write_text(".worktrees/\n.locks/\nconfigs/.env.*\n!configs/.env.*.example\ndata/\n")
(self.root / ".dockerignore").write_text(".doc\n.locks\n.worktrees\n")