Files
Jyotisha/tools/agent-loop/README.md
T

82 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 双 agent 自动循环(agent loop)
Claude(开发机,Linux)负责规划与验收,Grok Build(产品负责人的 Windows 电脑)负责执行,两边靠 Gitea issue 标签交接。设计与红线见 `docs/tasks/TASK-agent-loop-pilot-20261013.md`,进度见 `docs/tasks/PROGRESS-agent-loop-pilot-20261013.md`。
本目录不在 `deploy/gated-paths.txt` 内:改这里不触发门禁、不部署。
## 状态流转
| 标签 | 谁处理 | 结束时 |
| --- | --- | --- |
| `agent/待规划` | Claude:诊断 → 任务书推 staging | `agent/待执行` 或 `agent/需拍板` |
| `agent/待执行` | Grok:按任务书在 `codex/*` 实现、自测、推分支 | `agent/待验收` 或 `agent/需拍板` |
| `agent/待验收` | Claude:只验 Grok 回报的 SHA | 通过 → 推 staging → `agent/部署中`;不通过 → 修复单 → `agent/待执行`(打回 2 次 → `agent/需拍板`) |
| `agent/部署中` | Claude 脚本(不用模型):核对 `/api/health` | `agent/待真机`;3 小时未部署 → `agent/需拍板` |
| `agent/待真机` | 产品负责人 | 关 issue,或评论问题并改回 `agent/待规划` |
| `agent/需拍板` | 产品负责人 | 回复后改回原状态 |
锁标签:`agent/规划中`、`agent/验收中`(Claude)、`agent/执行中`(Grok)。试点期只处理同时带 `agent/试点` 的 issue。
## 安全设计
- **只认标签**:只有有写权限的人能打标签。issue 正文与评论只读**本人账号**写的,其他人写的一律不交给模型。
- **两侧都不关权限检查**:Claude 用 `claude-settings.json` 白名单 + `dontAsk`;Grok 用 `grok-permissions.json` 白名单 + `dontAsk`。白名单外的操作自动拒绝。
- **推送钩子**(`hooks/`,只在循环进程内通过 `GIT_CONFIG_*` 生效,不写进共用的 `.git/hooks`):Claude 不能推 main、不能删分支,每晚复盘只能推纯文档;Grok 只能推 `codex/*`、不能删分支。
- **脚本核对模型的每个声明**:任务书真在 staging 上、回报的 SHA 真是远端分支 head、staging 真包含验收的 SHA;对不上就作废本轮并留言。
- **公开仓库**:发评论前脚本扫一遍邮箱、JWT、私钥、`password=` 之类,命中就不发。
- **熔断**:同一单连续 3 轮出错或被打回 2 次就停下 @产品负责人。
## Claude 侧(这台 Linux 机器):会话里跑 `/loop`
2026-10-13 产品负责人决定:Claude 侧照 yetone/magpie 的做法,**在一个常开的 Claude Code 会话里跑 `/loop`**,不用后台脚本。理由:每一步都在会话的权限检查之下,产品负责人随时能看、能插话;后台脚本被 Claude Code 安全检查判为「无人值守 agent」拦下。
循环里用 `gitea.sh` 改标签、发评论,规则与评论首行标记同下文。要粘贴的 `/loop` 提示词在 `prompts/loop-claude.md`。会话关掉或机器重启,循环就停,重开会话再粘贴一次即可。
## 备用:Claude 侧后台脚本(默认不用)
`claude-tick.sh`、`nightly-review.sh`、`agentctl.sh` 是同一流程的无人值守版本,**未实跑**。只有产品负责人明确要求不依赖会话时才启用。
需要:`~/.config/jyotisha-agent/gitea-token`(0600)、`claude` 已登录、`jq`、`flock`。
```bash
tools/agent-loop/agentctl.sh install # 复制到 ~/.local/share/jyotisha-agent/bin
~/.local/share/jyotisha-agent/bin/agentctl.sh once # 跑一轮看看
~/.local/share/jyotisha-agent/bin/agentctl.sh start # 后台常驻:每 30 分钟一轮,23:30 每晚复盘
~/.local/share/jyotisha-agent/bin/agentctl.sh status
~/.local/share/jyotisha-agent/bin/agentctl.sh pause # 暂停(STOP 文件);resume 恢复;stop 停进程
```
本机没有 cron / systemd:**机器重启后要再运行一次 `start`**。日志在 `~/.local/state/jyotisha-agent/`,每轮的上下文、模型输出、评论草稿在 `runs/<时间>/`。
## Grok 侧(Windows):会话里跑 `/loop`
Grok Build 同样支持 `/loop`,两侧对称:Windows 上开一个常开的 Grok 会话跑 `/loop`,提示词与开会话前的环境设置见 `prompts/loop-grok.md`。下面的计划任务方式降为备用(未实跑)。
## 备用:Grok 侧计划任务(默认不用)
需要:`%USERPROFILE%\.config\jyotisha-agent\gitea-token`、Grok 已登录、T1 建好的工作树 `G:\Ferti\Jyotisha\.worktrees\agent-loop`、Docker Desktop(跑 `test:db` 时)。路径不同就改 `grok-config.json`。
首次安装前,让 Grok 在交互模式里做两件事(见 PROGRESS「Grok 侧安装」):核对 `grok-permissions.json` 的规则语法;把 13 条 Windows 已知失败的测试名填进 `windows-known-failures.txt`。
```powershell
cd G:\Ferti\Jyotisha\.worktrees\agent-loop\tools\agent-loop
powershell -NoProfile -ExecutionPolicy Bypass -File install-grok.ps1 -RunOnce # 先跑一轮
powershell -NoProfile -ExecutionPolicy Bypass -File install-grok.ps1 # 注册计划任务,每 15 分钟
powershell -NoProfile -ExecutionPolicy Bypass -File install-grok.ps1 -Uninstall # 移除
```
暂停:新建空文件 `%USERPROFILE%\.config\jyotisha-agent\STOP`。日志:`%USERPROFILE%\.jyotisha-agent\state\grok-tick.log`。
`.ps1` 文件只用 ASCII 字符(Windows PowerShell 5.1 按 ANSI 读无 BOM 的脚本),中文标签与留言都在 `grok-strings.json`。
## 交接评论的首行标记
```
<!-- agent:claude plan brief=<任务书> branch=<codex/...> base=<staging sha> -->
<!-- agent:grok report branch=<codex/...> sha=<head> -->
<!-- agent:claude review sha=<head> verdict=pass staging=<sha> checklist=<docs/testing/...|-> -->
<!-- agent:claude review sha=<head> verdict=fail brief=<修复单> branch=<codex/...> -->
<!-- agent:claude deployed sha=<部署 sha> -->
<!-- agent:claude|grok error ... --> <!-- agent:claude|grok escalate -->
```