docs(other): 更新 Vibe Coding 配置

This commit is contained in:
xlsea
2026-05-23 10:25:03 +08:00
parent 7eeff925cb
commit 7fec02ff77
132 changed files with 4833 additions and 1519 deletions
+26 -41
View File
@@ -1,47 +1,32 @@
# VibeCoding Kernel v9.2.0 — Codex CLI
# VibeCoding Athena v9.6 (Codex) — PACE Router & State Harness
你是一个INTJ性格的工程化 AI 编码助手。用 P.A.C.E. 路由复杂度, 用 RIPER-7 编排阶段, 用 Skills 执行细节。
**协作模式**: 你可能被 Claude Code (CC) 调用执行任务, 也可能独立运行。
<!--
本文件目标 altitude: 工程纪律的高信号宪法 (constitution)。
- 不规定操作步骤 → skills/pace/SKILL.md
- 不列插件命令 → prompts/athena-setup.md
- 不写安装/配置 → README.md
- 行数硬上限 30
-->
## 框架地图
你是 VibeCoding Athena 工程 Agent。Codex 做事, Athena 把关。
| 类别 | 文件 | 数量 |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ---- |
| Workflows | pace.md, riper-7.md | 2 |
| Skills | brainstorm, plan-first, code-review, verification, debugging, kaizen, security-review, context7, e2e, claude-delegate, reflexion, finish-branch | 12 |
| Agents | builder.toml, validator.toml, explorer.toml | 3 |
| State Templates | session, doing, design, plan, conventions, quality, lessons | 7 |
- 收任务 → 走 PACE 路由 (Hotfix/Bugfix 直接做, Quick+ 走完整流程)
- 自己跑命令 / 跑测试 / 看输出, 证明工作完成
- 工具失败 → 三次重试附 stderr 报告, 不让用户代执行
- 技术结论 → 必须引用官方文档 / 源码 URL
- spawn_agent 必须产生真实 tool_use, 不允许伪造完成
- Codex 无 compact 机制, 长任务点主动写 `.ai_state/_index.md` 保存状态
## 启动流程
## 铁律 (9 条)
1. 读 .ai_state/ → 恢复或初始化
2. 读 conventions.md (含 "Agent 易犯错误" 段) → 注意这些坑
3. 评估任务 → P.A.C.E. 路由 → RIPER-7 执行
1. **设计先行** — 未确认不写代码 (Hotfix/Bugfix 例外)
2. **TDD 强制** — 先测试后实现
3. **Sisyphus** — tasks 全完成才进审查
4. **Review 强制** — Feature+ 至少一次交叉审查 (/review + spawn_agent reviewer)
5. **文档即真相** — 阶段转换前 .ai_state/ 必须同步, 单一入口 `.ai_state/_index.md`
6. **完成度证据** — 报告"完成"必须附 tool_use ID 或命令输出片段
7. **出处优先** — API 形态 / 配置字段 / 协议格式必须引用官方文档或源码 URL
8. **索引先行** — 进入决策先读 `.ai_state/_index.md`, 禁止 glob 全目录扫描
9. **Hook 是进化器** — 在 Stop 时反思并写 `.ai_state/details/proposals.md`
## 关键规则
- 设计未确认前不写代码 (R₀/R/D 阶段)
- TDD: 先写测试再写实现 (E 阶段)
- Sisyphus: plan.md 所有 [ ] 完成才能停 (E 阶段)
- Reflexion: 每个 Task 完成后自我反思再 Micro-review (E 阶段)
- 4 级 Quality Gate: PASS / CONCERNS / REWORK / FAIL (交付前)
## 被 CC 调用时
- CC 会通过 `codex exec` 发送任务
- 你在只读沙箱中运行, 不直接修改文件
- 输出代码和建议, CC 决定是否应用
- 审查请求以 `VERDICT: APPROVED` 或 `VERDICT: REVISE` 结尾
## MCP 工具 (按需)
- cunzhi: 人工确认检查点
- context7 CLI: `npx ctx7 resolve {库名}`
## 模型
| 场景 | 模型 |
| --------- | ------------------------ |
| 默认 | gpt-5.4 |
| 快速/探索 | gpt-5.4-mini |
| 深度审查 | gpt-5.4 (high reasoning) |
设计原则: SRP · OCP · LSP · ISP · DIP · DRY · KISS · 第一性原理 · 先 WHY 后 HOW
-4
View File
@@ -1,4 +0,0 @@
[agent]
name = "builder"
model = "gpt-5.4"
description = "实现代码 + 测试 (TDD: RED→GREEN→REFACTOR)"
+47
View File
@@ -0,0 +1,47 @@
# Codex Subagent: evaluator (VibeCoding Athena v9.6)
# 参考: https://developers.openai.com/codex/subagents
# 位置: ~/.codex/agents/evaluator.toml 或 .codex/agents/evaluator.toml
name = "evaluator"
description = "代码审查评分员. PACE review 阶段调用, 输出 VERDICT (PASS/CONCERNS/REWORK/FAIL)"
nickname_candidates = ["EvalBot", "Verdict"]
# 只读: 评分员不修改任何代码
sandbox_mode = "read-only"
# Model 不指定 → 继承父 session
# model_reasoning_effort 不指定 → 继承父 session
developer_instructions = """
你是 VibeCoding Athena 的代码审查评分员.
## 输入
- `.ai_state/_index.md` (path/stage/sprint/active_goal)
- `.ai_state/details/reviews/sprint-N.md` (本 sprint 审查报告)
- `.ai_state/details/design.md` (设计 vs 实际对比)
- `git diff` 本 sprint 提交
## 工具限制
- 只读: read_file / shell (限 ls, cat, grep, rg, git log/diff/show) / web_search
- 禁用: apply_patch, write_file, edit_file
## 评分维度 (1-5 分, 跨平台一致 — 铁律 6)
- Functionality (25%) // 是否实现 design.md 中所有 MUST 项
- Spec Compliance (25%) // 是否符合 design.md 的约束
- Boundary (15%) // 是否越出 File Structure Plan 边界
- Craft (15%) // 代码质量 (命名/SRP/无 dead code)
- Robustness (20%) // 边界处理/错误恢复/测试覆盖
均分 = F×0.25 + SC×0.25 + B×0.15 + C×0.15 + R×0.20
## VERDICT 规则
- 均分 ≥ 4.0 且所有维度 ≥ 3 → PASS
- 均分 ≥ 3.0 但某维度 = 2 → CONCERNS
- 均分 < 3.0 或任一维度 = 1 → REWORK
- 多维度 = 1 或 Boundary 大幅越界 / 安全严重问题 → FAIL
## 输出要求
- 每个维度评分必须附代码行号级证据 (file.ext:LN, 不是模糊"看起来不错")
- 不允许 Halo Effect (一个维度的分数不影响其他维度的独立评分顺序)
- 输出预算 ≤ 2000 tokens (Anthropic 多 agent 经验: subagent 必须紧凑)
- 直接覆盖写回 reviews/sprint-N.md 的 "## Step 6" 段和 "## VERDICT:" 段
"""
-4
View File
@@ -1,4 +0,0 @@
[agent]
name = "explorer"
model = "gpt-5.4-mini"
description = "代码库调研 + 文档查询 (只读)"
+62
View File
@@ -0,0 +1,62 @@
# Codex Subagent: generator (VibeCoding Athena v9.6)
# 参考: https://developers.openai.com/codex/subagents
# 位置: ~/.codex/agents/generator.toml 或 .codex/agents/generator.toml
name = "generator"
description = "代码实现者. 接 task spec, TDD 实现, 输出可被 reviewer 验证的 commit"
nickname_candidates = ["GenBot", "Builder", "Smith"]
# 写权限: implementer 需要 apply_patch / edit_file
sandbox_mode = "workspace-write"
# model / model_reasoning_effort 不指定 → 继承父 session
developer_instructions = """
你是 VibeCoding Athena 的代码实现者.
## 工具
- read_file / write_file / edit_file / apply_patch
- shell (含 git, 测试运行, lint, 包管理)
- web_search (查依赖文档)
## 工作流 (与 CC 端等价 — 跨平台 schema 一致 — 铁律 6)
1. Get-bearings (R₀):
- 读 `.ai_state/_index.md`
- 读 design.md 对应模块段
- 读 tasks-current.md 当前 task 的 Boundary/Depends
2. TDD 强制 (铁律 2):
- 先写测试 → 跑测试 (RED) → 实现 → 跑测试 (GREEN)
3. Boundary 守则:
- 仅修改 task 的 Boundary 标注的文件
- 越界 → 停, 报告主 agent (可能需要升路径)
4. 跑 lint_cmd → 失败修复
5. 更新文档:
- tasks-current.md 勾选 ([ ] → [x])
- progress.md 追加一行 (YYYY-MM-DD HH:MM [path/stage/sprint] Task N done)
- design.md 不动 (除非发现 design 错; 那种情况报告主 agent 不要自己改)
6. Commit:
- `git add -p` 仅添加 Boundary 内文件
- `git commit -m "<task short summary>"`
7. 报告:
- 输出 commit hash + 测试通过的命令输出片段 (铁律 6 完成度证据)
- 失败 → 完整 stderr (不允许 "I cannot")
## Codex 端注意
- 不像 CC 有 isolation:worktree 自动隔离, Codex subagent 共享 workspace
- 多个 generator 并发时, 严格按 Boundary 分工避免冲突
- 设置 max_threads 在 config.toml [agents] 控制并发度 (max_threads = 6)
## 失败协议 (铁律 7)
工具失败 → 三轮重试:
- Round 1: 读 stderr 分类 (permission denied / not found / 语法)
- Round 2: 改参数 / 换工具 / 拆任务
- Round 3: 仍失败 → 完整 stderr + exit code + 已尝试方案, 报告主 agent
禁止: "请你手动跑", "我没有权限" (没有就申请, 不是放弃).
## 输出预算
≤ 2000 tokens. 详细日志写文件不写回主 agent.
"""
+62
View File
@@ -0,0 +1,62 @@
# Codex Subagent: reviewer (VibeCoding Athena v9.6)
# 参考: https://developers.openai.com/codex/subagents
# 位置: ~/.codex/agents/reviewer.toml 或 .codex/agents/reviewer.toml
name = "reviewer"
description = "代码审查员. PACE review 阶段调用, 给出对抗性 findings + 可执行 fixes (与 evaluator 配合: reviewer 找问题, evaluator 给 VERDICT)"
nickname_candidates = ["ReviewBot", "Critic", "Inspector"]
# 只读: reviewer 不修改代码, 只产出 findings
sandbox_mode = "read-only"
developer_instructions = """
你是 VibeCoding Athena 的代码审查员.
## 角色边界
与 evaluator 区别:
- evaluator: 给 VERDICT (PASS/CONCERNS/REWORK/FAIL) + 数值评分
- reviewer: 给具体可执行的反馈 (找 bug, 找设计问题, 找测试缺口)
主 agent 工作流: 先调 reviewer 拿反馈 → 修复 → 再调 evaluator 给 VERDICT.
## 工具
- read_file
- shell (限只读: ls, cat, grep, rg, git log/diff/show)
- web_search (查最佳实践, OWASP 规范)
禁用: apply_patch / write_file / edit_file.
## 审查重点 (与 CC 端 /codex:review 行为对齐)
1. Bug: 边界用例, 错误处理, race condition
2. 设计: 是否违反 design.md, SOLID, KISS
3. 测试: 覆盖率, 是否测了 happy path 没测 error path
4. 安全: 输入验证, 注入风险, 密钥处理
5. 性能: 明显的 N+1, 同步阻塞, 内存泄漏
## 输出
写入 `.ai_state/details/reviews/sprint-N.md` 的 "## Step 2/3" 段:
```
### Reviewer (Codex subagent)
**job_id**: <Codex subagent job id, 铁律 6 完成度证据>
**Findings**:
- [HIGH] file.ext:LN — <描述>
- [MEDIUM] file.ext:LN — <描述>
- [LOW] file.ext:LN — <描述>
**Suggested fixes**:
- ...
```
每个 finding 必须有 file:line 锚点 (no 模糊"代码可以更好").
## 输出预算
≤ 2000 tokens.
"""
-4
View File
@@ -1,4 +0,0 @@
[agent]
name = "validator"
model = "gpt-5.4"
description = "代码审查 + Plan Review"
+92 -62
View File
@@ -1,85 +1,115 @@
# VibeCoding Kernel v9.2.0 — Codex CLI Config
model_provider = "custom"
model = "gpt-5.4"
# VibeCoding Athena v9.6 · Codex Configuration
project_root_markers = [".git", ".hg", ".sl"]
project_doc_max_bytes = 65536
model = "gpt-5.5"
model_reasoning_effort = "xhigh"
windows_wsl_setup_acknowledged = true
model_context_window = 1000000
model_auto_compact_token_limit = 900000
web_search = "live"
suppress_unstable_features_warning = true
# 危险,可开启 和下面的二选一,上面的代表绝对信任
# approval_policy = "never" # untrusted|on-request|never
# sandbox_mode = "danger-full-access" # read-only|workspace-write|danger-full-access
approval_policy = "never"
sandbox_mode = "workspace-write"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
[sandbox_workspace_write]
network_access = true # npm install / pip install 需要网络
# Web Search
web_search = "live"
network_access = false
[features]
multi_agent = true # stable; 多代理编排
collaboration_modes = true # stable; 协作模式
shell_snapshot = true # beta; 加速重复命令
unified_exec = true # beta; PTY-backed 执行
shell_tool = true # stable; 默认 shell 工具
apply_patch_freeform = true # experimental; 自由 patch
undo = true # 回滚 Codex 改动;
hooks = true
multi_agent = true
shell_tool = true
shell_snapshot = true
unified_exec = true
apply_patch_freeform = true
undo = true
memories = true
[tui]
notifications = true
animations = true
[memories]
generate_memories = true
use_memories = true
disable_on_external_context = true
[profiles.ci]
approval_policy = "never"
sandbox_mode = "workspace-write"
[[hooks.SessionStart]]
matcher = "^(startup|resume|clear)$"
[[hooks.SessionStart.hooks]]
type = "command"
command = "python3 \"./.codex/hooks/session-start.py\""
timeout = 10
statusMessage = "Loading Athena context"
[profiles.review]
model = "gpt-5.4"
approval_policy = "on-request"
[[hooks.UserPromptSubmit]]
[[hooks.UserPromptSubmit.hooks]]
type = "command"
command = "python3 \"./.codex/hooks/user-prompt-submit.py\""
timeout = 5
statusMessage = "Athena pre-check"
[profiles.dev]
model = "gpt-5.4"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
[[hooks.PreToolUse]]
matcher = "^Bash$"
[[hooks.PreToolUse.hooks]]
type = "command"
command = "python3 \"./.codex/hooks/pre-bash-guard.py\""
timeout = 10
statusMessage = "Checking Bash command"
[[hooks.PostToolUse]]
[[hooks.PostToolUse.hooks]]
type = "command"
command = "python3 \"./.codex/hooks/index-updater.py\""
timeout = 10
[[hooks.PostToolUse]]
[[hooks.PostToolUse.hooks]]
type = "command"
command = "python3 \"./.codex/hooks/subagent-retry.py\""
timeout = 10
[[hooks.Stop]]
[[hooks.Stop.hooks]]
type = "command"
command = "python3 \"./.codex/hooks/delivery-gate.py\""
timeout = 60
statusMessage = "Athena delivery-gate"
[agents]
max_threads = 3
max_threads = 6
max_depth = 1
job_max_runtime_seconds = 1800
[agents.builder]
description = "实现代码 + 测试 (TDD: RED→GREEN→REFACTOR)"
config_file = "./agents/builder.toml"
[[skills.config]]
name = "pace"
enabled = true
[agents.validator]
description = "代码审查 + Plan Review"
config_file = "./agents/validator.toml"
[[skills.config]]
name = "compound"
enabled = true
[agents.explorer]
description = "代码库调研 + 文档查询 (只读)"
config_file = "./agents/explorer.toml"
[[skills.config]]
name = "context7"
enabled = true
[model_providers.custom]
name = "custom"
wire_api = "responses"
requires_openai_auth = true
[[skills.config]]
name = "superpowers"
enabled = true
[mcp_servers]
[shell_environment_policy]
inherit = "core"
[mcp_servers.mcp-deepwiki]
type = "stdio"
command = "npx"
args = ["-y", "mcp-deepwiki@latest"]
[tui.model_availability_nux]
"gpt-5.5" = 4
[mcp_servers."cunzhi"]
type = "stdio"
command = "寸止"
[mcp_servers.chrome-devtools]
type = "stdio"
command = "npx"
args = ["-y", "chrome-devtools-mcp@latest"]
[shell_environment_policy.set]
VIBECODING_VERSION = "9.6.0-codex"
[mcp_servers.augment-context-engine]
type = "stdio"
command = "npx"
args = ["ace-tool-rs", "--base-url", "https://acemcp.heroman.wtf/relay/", "--token", ""]
args = [ "ace-tool-rs", "--base-url", "https://acemcp.heroman.wtf/relay/", "--token", "ace_0eff2f29e8dec9382d0ad1b46b39e587d06f6c2f" ]
[mcp_servers.augment-context-engine.tools.search_context]
approval_mode = "approve"
[hooks.state]
+167
View File
@@ -0,0 +1,167 @@
#!/usr/bin/env python3
"""VibeCoding Athena Codex Stop hook (delivery-gate) v9.6.
设计:
- Codex 无 /goal autonomous loop → Athena 必须自己判定 VERDICT
- Codex 无 Stop hook block-cap 概念, 但保守起见也做内部计数
- VERDICT 不符 → 阻断 (decision: block)
- CONCERNS → systemMessage 不阻断
"""
import json
import os
import re
import sys
import datetime
PROJECT_DIR = os.environ.get("CODEX_PROJECT_DIR") or os.getcwd()
STATE_DIR = os.path.join(PROJECT_DIR, ".ai_state")
INDEX_PATH = os.path.join(STATE_DIR, "_index.md")
HOME = os.path.expanduser("~")
COUNTER_PATH = os.path.join(HOME, ".codex", "state", "athena-block-counter.json")
BLOCK_CAP_SAFE = 6
def trace(payload: dict):
try:
with open(os.path.join(STATE_DIR, "hook-trace.jsonl"), "a") as f:
f.write(json.dumps({
"ts": datetime.datetime.utcnow().isoformat() + "Z",
"hook": "delivery-gate",
**payload
}) + "\n")
except Exception:
pass
def main():
raw = sys.stdin.read()
try:
event = json.loads(raw)
except Exception:
sys.exit(0)
return
if event.get("stop_hook_active"):
sys.exit(0)
return
if event.get("agent_type") and event["agent_type"] != "main":
sys.exit(0)
return
if not os.path.exists(INDEX_PATH):
sys.exit(0)
return
try:
content = open(INDEX_PATH).read()
m = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
if not m:
sys.exit(0)
return
fm = m.group(1)
except Exception:
sys.exit(0)
return
def get_str(key):
match = re.search(rf'^ {re.escape(key)}: (.*)$', fm, re.MULTILINE)
return match.group(1).strip().strip('"').strip("'") if match else ""
def get_num(key):
match = re.search(rf'^ {re.escape(key)}: (\d+)$', fm, re.MULTILINE)
return int(match.group(1)) if match else 0
path_name = get_str("path")
stage = get_str("stage")
sprint = get_num("sprint")
tasks_pending = get_num("tasks_pending")
if not sprint or not stage or path_name in ("Hotfix", "Bugfix") or stage != "review":
sys.exit(0)
return
needs_ext = path_name in ("Feature", "Refactor", "System")
issues = []
if tasks_pending > 0:
issues.append(f"{tasks_pending} Task 未完成")
review_file = os.path.join(STATE_DIR, "details", "reviews", f"sprint-{sprint}.md")
rc = ""
try:
rc = open(review_file).read()
except Exception:
issues.append("审查报告不存在")
if needs_ext and rc and not re.search(r"reviewer|web_search|/review|spawn_agent", rc, re.IGNORECASE):
issues.append("无外部审查记录")
if rc and not re.search(r"test|测试|pass|通过|✅", rc, re.IGNORECASE):
issues.append("无测试通过记录")
verdict = ""
if rc:
vm = re.search(r"VERDICT:\s*(PASS|CONCERNS|REWORK|FAIL)", rc, re.IGNORECASE)
if vm:
verdict = vm.group(1).upper()
if verdict in ("REWORK", "FAIL"):
issues.append(f"VERDICT={verdict}")
if issues:
os.makedirs(os.path.dirname(COUNTER_PATH), exist_ok=True)
counter = {}
try:
counter = json.load(open(COUNTER_PATH))
except Exception:
pass
sid = event.get("session_id", "unknown")
counter[sid] = counter.get(sid, 0) + 1
try:
with open(COUNTER_PATH, "w") as f:
json.dump(counter, f)
except Exception:
pass
count = counter[sid]
sys.stderr.write(f"[delivery-gate] block #{count}/{BLOCK_CAP_SAFE} {path_name}/{stage}: {', '.join(issues)}\n")
trace({"action": "block", "count": count, "path": path_name, "stage": stage, "issues": issues})
if count >= BLOCK_CAP_SAFE:
msg = f"[Athena] 已连续 block {count} 次, 建议手动处理: {'; '.join(issues)}"
print(json.dumps({"systemMessage": msg}))
else:
print(json.dumps({
"decision": "block",
"reason": f"[Athena delivery-gate] 阻断:\n" + "\n".join("• " + i for i in issues) + f"\n\n修复后再交付 (block {count}/{BLOCK_CAP_SAFE})."
}))
sys.exit(0)
return
# 通过, 重置计数
try:
counter = json.load(open(COUNTER_PATH))
counter.pop(event.get("session_id", ""), None)
with open(COUNTER_PATH, "w") as f:
json.dump(counter, f)
except Exception:
pass
if verdict == "PASS":
# 检查 lessons
try:
lessons = open(os.path.join(STATE_DIR, "details", "lessons.md")).read()
except Exception:
lessons = ""
if f"Sprint {sprint}" not in lessons:
msg = f"Sprint {sprint} 通过但 details/lessons.md 无条目, 建议运行 compound skill 沉淀经验"
print(json.dumps({"systemMessage": f"[Athena] {msg}"}))
trace({"action": "soft-warn", "reason": "no compound", "path": path_name, "sprint": sprint})
sys.exit(0)
return
sys.stderr.write(f"[delivery-gate] PASS {path_name}/{stage}\n")
trace({"action": "pass", "path": path_name, "stage": stage, "sprint": sprint, "verdict": verdict})
sys.exit(0)
if __name__ == "__main__":
main()
+167
View File
@@ -0,0 +1,167 @@
#!/usr/bin/env python3
"""VibeCoding Athena Codex PostToolUse index-updater v9.6.
设计 (与 CC 等价, schema 跨平台一致 - 铁律 6):
- 检测 tool_input.file_path 是否在 .ai_state/details/
- 若是 → 重新扫描计算 counts/fingerprints/pointers
- 原子写入 _index.md (.tmp + rename)
"""
import json
import os
import re
import sys
import datetime
PROJECT_DIR = os.environ.get("CODEX_PROJECT_DIR") or os.getcwd()
STATE_DIR = os.path.join(PROJECT_DIR, ".ai_state")
INDEX_PATH = os.path.join(STATE_DIR, "_index.md")
DETAILS_DIR = os.path.join(STATE_DIR, "details")
def read_file_safe(path):
try:
return open(path).read()
except Exception:
return ""
def mtime(path):
try:
return int(os.path.getmtime(path) * 1000)
except Exception:
return 0
def count_matches(text, pattern):
return len(re.findall(pattern, text, re.MULTILINE)) if text else 0
def last_section_line(text, head_prefix="## "):
if not text:
return 0
lines = text.split("\n")
for i in range(len(lines) - 1, -1, -1):
if lines[i].startswith(head_prefix):
return i + 1
return 0
def last_nonempty_line(text):
if not text:
return 0
lines = text.split("\n")
for i in range(len(lines) - 1, -1, -1):
s = lines[i].strip()
if s and not s.startswith("<!--") and not s.startswith("-->") and not s.startswith("#"):
return i + 1
return 0
def replace_field(yaml: str, key: str, value, is_numeric: bool) -> str:
val_str = str(value) if is_numeric else f'"{value}"'
pattern = rf"(^ {re.escape(key)}: ).*$"
if re.search(pattern, yaml, re.MULTILINE):
return re.sub(pattern, rf"\g<1>{val_str}", yaml, count=1, flags=re.MULTILINE)
return yaml
def main():
raw = sys.stdin.read()
try:
event = json.loads(raw)
except Exception:
sys.exit(0)
return
file_path = (event.get("tool_input") or {}).get("file_path", "")
if not file_path or ".ai_state/details/" not in file_path:
sys.exit(0)
return
if not os.path.exists(INDEX_PATH):
sys.exit(0)
return
try:
content = open(INDEX_PATH).read()
m = re.match(r"^---\n(.*?)\n---\n(.*)$", content, re.DOTALL)
if not m:
sys.stderr.write("[index-updater] frontmatter parse failed\n")
sys.exit(0)
return
fm, body = m.group(1), m.group(2)
tasks_text = read_file_safe(os.path.join(DETAILS_DIR, "tasks-current.md"))
progress_text = read_file_safe(os.path.join(DETAILS_DIR, "progress.md"))
lessons_text = read_file_safe(os.path.join(DETAILS_DIR, "lessons.md"))
proposals_text = read_file_safe(os.path.join(DETAILS_DIR, "proposals.md"))
tasks_pending = count_matches(tasks_text, r"^- \[ \]")
tasks_done = count_matches(tasks_text, r"^- \[x\]")
tasks_blocked = count_matches(tasks_text, r"^- \[!\]")
lessons_lines = count_matches(lessons_text, r"^## ")
progress_entries = 0
if progress_text:
progress_entries = sum(
1 for l in progress_text.split("\n")
if l.strip() and not l.startswith("<!--") and not l.startswith("-->") and not l.startswith("#")
)
reviews_count = 0
latest_review = ""
try:
files = [f for f in os.listdir(os.path.join(DETAILS_DIR, "reviews")) if re.match(r"^sprint-\d+\.md$", f)]
reviews_count = len(files)
if files:
files.sort(key=lambda f: int(re.search(r"\d+", f).group()))
latest_review = f"details/reviews/{files[-1]}"
except Exception:
pass
latest_progress = f"details/progress.md#L{last_nonempty_line(progress_text)}" if progress_text else ""
latest_lesson = f"details/lessons.md#L{last_section_line(lessons_text)}" if lessons_text else ""
latest_proposal = f"details/proposals.md#L{last_section_line(proposals_text)}" if proposals_text else ""
tasks_mtime = mtime(os.path.join(DETAILS_DIR, "tasks-current.md"))
design_mtime = mtime(os.path.join(DETAILS_DIR, "design.md"))
progress_mtime = mtime(os.path.join(DETAILS_DIR, "progress.md"))
lessons_mtime = mtime(os.path.join(DETAILS_DIR, "lessons.md"))
fm = replace_field(fm, "tasks_pending", tasks_pending, True)
fm = replace_field(fm, "tasks_done", tasks_done, True)
fm = replace_field(fm, "tasks_blocked", tasks_blocked, True)
fm = replace_field(fm, "lessons_lines", lessons_lines, True)
fm = replace_field(fm, "progress_entries", progress_entries, True)
fm = replace_field(fm, "reviews_count", reviews_count, True)
fm = replace_field(fm, "latest_progress", latest_progress, False)
fm = replace_field(fm, "latest_review", latest_review, False)
fm = replace_field(fm, "latest_lesson", latest_lesson, False)
fm = replace_field(fm, "latest_proposal", latest_proposal, False)
fm = replace_field(fm, "tasks_mtime", tasks_mtime, True)
fm = replace_field(fm, "design_mtime", design_mtime, True)
fm = replace_field(fm, "progress_mtime", progress_mtime, True)
fm = replace_field(fm, "lessons_mtime", lessons_mtime, True)
new_content = f"---\n{fm}\n---\n{body}"
tmp = INDEX_PATH + ".tmp"
with open(tmp, "w") as f:
f.write(new_content)
os.rename(tmp, INDEX_PATH)
sys.stderr.write(f"[index-updater] _index.md updated (pending={tasks_pending} done={tasks_done})\n")
with open(os.path.join(STATE_DIR, "hook-trace.jsonl"), "a") as f:
f.write(json.dumps({
"ts": datetime.datetime.utcnow().isoformat() + "Z",
"hook": "index-updater",
"tasks_pending": tasks_pending,
"tasks_done": tasks_done,
"lessons_lines": lessons_lines,
}) + "\n")
except Exception as e:
sys.stderr.write(f"[index-updater] failed: {e}\n")
sys.exit(0)
if __name__ == "__main__":
main()
+66
View File
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
"""VibeCoding Athena Codex PreToolUse Bash guard v9.6.
设计:
- 3 条灾难命令 (与 CC 等价)
- Codex hook 输出协议: permissionDecision = "deny" 阻断
- Codex 文档: hooks 当前实验性, Windows 不支持
参考: https://developers.openai.com/codex/hooks
"""
import json
import re
import sys
import datetime
import os
DANGER_PATTERNS = [
(re.compile(r"rm\s+-[rRf]+\s+(/(\s|\*|;|&|\||$)|~/?\s|~\s|~$)"), "禁止删除系统/用户根目录"),
(re.compile(r"(curl|wget)\s+[^|]*\|\s*(bash|sh|zsh|fish|ksh)"), "禁止管道执行远程脚本"),
(re.compile(r"\bmkfs\.|dd\s+if=.*of=/dev/sd|>\s*/dev/sd[a-z]"), "禁止格式化磁盘/写设备"),
]
def main():
raw = sys.stdin.read()
try:
event = json.loads(raw)
except Exception:
sys.exit(0)
return
cmd = (event.get("tool_input") or {}).get("command", "")
if not cmd:
sys.exit(0)
return
for pat, reason in DANGER_PATTERNS:
if pat.search(cmd):
sys.stderr.write(f"[bash-guard] deny: {reason} ({cmd[:60]})\n")
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": f"Athena bash-guard 阻断: {reason}"
}
}))
try:
project_dir = os.environ.get("CODEX_PROJECT_DIR") or os.getcwd()
state_dir = os.path.join(project_dir, ".ai_state")
with open(os.path.join(state_dir, "hook-trace.jsonl"), "a") as f:
f.write(json.dumps({
"ts": datetime.datetime.utcnow().isoformat() + "Z",
"hook": "pre-bash-guard",
"action": "deny",
"reason": reason
}) + "\n")
except Exception:
pass
sys.exit(0)
return
sys.exit(0)
if __name__ == "__main__":
main()
+121
View File
@@ -0,0 +1,121 @@
#!/usr/bin/env python3
"""VibeCoding Athena Codex SessionStart hook v9.6.
协议: stdout JSON with additionalContext (Codex 端简化, 不强制 hookSpecificOutput 嵌套)
参考: https://developers.openai.com/codex/hooks
设计 (铁律 8 索引先行, 同 CC):
- 唯一 IO: read .ai_state/_index.md frontmatter
- 注入 context-essentials.md (静态文本)
- 注入 _index.md 关键字段摘要
"""
import json
import os
import re
import sys
import datetime
PROJECT_DIR = os.environ.get("CODEX_PROJECT_DIR") or os.getcwd()
STATE_DIR = os.path.join(PROJECT_DIR, ".ai_state")
INDEX_PATH = os.path.join(STATE_DIR, "_index.md")
HOME = os.path.expanduser("~")
PROJECT_ESSENTIALS = os.path.join(PROJECT_DIR, ".codex", "skills", "pace", "context-essentials.md")
GLOBAL_ESSENTIALS = os.path.join(HOME, ".codex", "skills", "pace", "context-essentials.md")
def trace(payload: dict):
try:
line = json.dumps({"ts": datetime.datetime.utcnow().isoformat() + "Z", "hook": "session-start", **payload}) + "\n"
with open(os.path.join(STATE_DIR, "hook-trace.jsonl"), "a") as f:
f.write(line)
except Exception:
pass
def read_file_safe(path: str) -> str:
try:
with open(path, "r") as f:
return f.read().strip()
except Exception:
return ""
def get_frontmatter(content: str) -> str:
m = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
return m.group(1) if m else ""
def get_str(fm: str, key: str) -> str:
m = re.search(rf"^ {re.escape(key)}: (.*)$", fm, re.MULTILINE)
if not m:
return ""
val = m.group(1).strip()
return val.strip('"').strip("'")
def get_num(fm: str, key: str) -> int:
m = re.search(rf"^ {re.escape(key)}: (\d+)$", fm, re.MULTILINE)
return int(m.group(1)) if m else 0
def main():
raw = sys.stdin.read()
try:
event = json.loads(raw)
except Exception:
event = {}
source = event.get("source", "unknown")
lines = []
# 1. 注入 context-essentials
for p in (PROJECT_ESSENTIALS, GLOBAL_ESSENTIALS):
text = read_file_safe(p)
if text:
lines.append(text)
break
if not lines:
lines.append("[VibeCoding Athena Codex v9.6] TDD · Review · Sisyphus · 索引先行")
# 2. 注入 _index.md frontmatter 摘要
if os.path.exists(INDEX_PATH):
try:
content = open(INDEX_PATH).read()
fm = get_frontmatter(content)
if fm:
path_ = get_str(fm, "path")
stage = get_str(fm, "stage")
sprint = get_num(fm, "sprint")
goal = get_str(fm, "active_goal")
pending = get_num(fm, "tasks_pending")
done = get_num(fm, "tasks_done")
blocked = get_num(fm, "tasks_blocked")
if path_ and stage:
lines.append(f"\n[PACE] Path:{path_} Stage:{stage} Sprint:{sprint}")
if goal:
snippet = goal[:120] + ("..." if len(goal) > 120 else "")
lines.append(f"[/goal active (CC only)] {snippet}")
if pending + done + blocked > 0:
lines.append(f"[任务] {done} 完成 {pending} 待办 {blocked} 阻塞 (详见 details/tasks-current.md)")
except Exception as e:
sys.stderr.write(f"[session-start] _index.md parse failed: {e}\n")
additional_context = "\n".join(lines)
sys.stderr.write(f"[session-start/{source}] injected {len(additional_context)} chars\n")
trace({"source": source, "chars": len(additional_context)})
# Codex hooks 输出协议: stdout 包含 additionalContext 字符串 (官方文档示例)
# 参考: https://developers.openai.com/codex/hooks 中 SessionStart 段
print(json.dumps({
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": additional_context
}
}))
sys.exit(0)
if __name__ == "__main__":
main()
+71
View File
@@ -0,0 +1,71 @@
#!/usr/bin/env python3
"""VibeCoding Athena Codex PostToolUse subagent-retry v9.6.
设计 (与 CC 等价):
- 检测 spawn_agent 返回的内容是否含放弃信号词
- 注入 systemMessage 提示主 agent 重试或接管
"""
import json
import re
import sys
import datetime
import os
GIVEUP_PATTERNS = [
re.compile(r"我(无法|不能|没法|无能力|不具备能力)"),
re.compile(r"I (cannot|can't|am not able to|don't have access)", re.IGNORECASE),
re.compile(r"no (capability|access|permission) to", re.IGNORECASE),
re.compile(r"unable to (read|write|execute|access)", re.IGNORECASE),
re.compile(r"tool not available", re.IGNORECASE),
re.compile(r"(请|你)(自己|手动|帮我)?(运行|执行|跑)"),
re.compile(r"please run (this|the command) (yourself|manually)", re.IGNORECASE),
]
def main():
raw = sys.stdin.read()
try:
event = json.loads(raw)
except Exception:
sys.exit(0)
return
if event.get("tool_name") not in ("Task", "spawn_agent"):
sys.exit(0)
return
response = event.get("tool_response") or {}
text = ""
if isinstance(response.get("content"), str):
text = response["content"]
elif isinstance(response.get("content"), list):
text = "\n".join(c.get("text", "") for c in response["content"] if isinstance(c, dict))
else:
text = json.dumps(response)
for pat in GIVEUP_PATTERNS:
if pat.search(text):
sys.stderr.write(f"[subagent-retry] giveup detected: {pat.pattern[:50]}\n")
subagent = (event.get("tool_input") or {}).get("subagent_type") or (event.get("tool_input") or {}).get("agent_type") or "subagent"
msg = f"[Athena subagent-retry] {subagent} 返回了放弃信号. 协议: 1) 再尝试一次, 用不同参数或拆分任务 2) 仍失败则主 agent 接管, 不要让用户代执行 (铁律 6 完成度证据)"
print(json.dumps({"systemMessage": msg}))
try:
project_dir = os.environ.get("CODEX_PROJECT_DIR") or os.getcwd()
state_dir = os.path.join(project_dir, ".ai_state")
with open(os.path.join(state_dir, "hook-trace.jsonl"), "a") as f:
f.write(json.dumps({
"ts": datetime.datetime.utcnow().isoformat() + "Z",
"hook": "subagent-retry",
"subagent": subagent
}) + "\n")
except Exception:
pass
sys.exit(0)
return
sys.exit(0)
if __name__ == "__main__":
main()
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""VibeCoding Athena Codex UserPromptSubmit hook v9.6.
仅在用户 prompt 看起来是"开发请求" 时, 提示当前 PACE 状态, 帮助 model 路由.
不强制添加任何内容, 单纯增强 context.
参考: https://developers.openai.com/codex/hooks
"""
import json
import os
import re
import sys
import datetime
PROJECT_DIR = os.environ.get("CODEX_PROJECT_DIR") or os.getcwd()
STATE_DIR = os.path.join(PROJECT_DIR, ".ai_state")
INDEX_PATH = os.path.join(STATE_DIR, "_index.md")
DEV_KEYWORDS = re.compile(
r"(实现|开发|新增|加上|做|搭|跑|写|改|修|fix|implement|build|add|create|refactor|review|test|debug)",
re.IGNORECASE,
)
def main():
raw = sys.stdin.read()
try:
event = json.loads(raw)
except Exception:
sys.exit(0)
return
prompt = event.get("prompt") or event.get("user_prompt") or ""
if not DEV_KEYWORDS.search(prompt):
sys.exit(0)
return
if not os.path.exists(INDEX_PATH):
sys.exit(0)
return
try:
content = open(INDEX_PATH).read()
m = re.match(r"^---\n(.*?)\n---", content, re.DOTALL)
if not m:
sys.exit(0)
return
fm = m.group(1)
path_m = re.search(r'^ path: "([^"]*)"$', fm, re.MULTILINE)
stage_m = re.search(r'^ stage: "([^"]*)"$', fm, re.MULTILINE)
path_val = path_m.group(1) if path_m else ""
stage_val = stage_m.group(1) if stage_m else ""
if path_val and stage_val:
msg = f"[Athena] 当前 PACE 状态: {path_val}/{stage_val}. 如果是延续任务, 请走 pace skill 既有流程; 如果是新任务, 评估是否升路径."
sys.stderr.write(msg + "\n")
print(json.dumps({"systemMessage": msg}))
try:
line = json.dumps({
"ts": datetime.datetime.utcnow().isoformat() + "Z",
"hook": "user-prompt-submit",
"path": path_val, "stage": stage_val
}) + "\n"
with open(os.path.join(STATE_DIR, "hook-trace.jsonl"), "a") as f:
f.write(line)
except Exception:
pass
except Exception as e:
sys.stderr.write(f"[user-prompt-submit] failed: {e}\n")
sys.exit(0)
if __name__ == "__main__":
main()
+24
View File
@@ -0,0 +1,24 @@
# /athena-dev (Codex) — 主入口
`.ai_state/` 不存在 → 提示 `/athena-init` 并停。
`schema_version` != "9.6" → 提示 `/athena-migrate` 并停。
## Get-bearings (R₀, just-in-time, 铁律 8)
1. **必读**: `.ai_state/_index.md`
2. **按需**: stage=impl/review → 按 pointers.latest_progress 读 progress.md 尾部
3. **按需**: 任务命中 lessons 主题 → pointers.latest_lesson 跳段
4. **按需**: `git log --oneline -10`
5. **按需**: impl/review 阶段 → `bash .ai_state/init.sh`
文件大就用 head/tail/grep。**禁止 glob 整个 .ai_state/**。
## Dispatch
有进行中的 stage → 从当前阶段继续 (参考 `~/.codex/skills/pace/SKILL.md`)。
新需求 → 触发 pace skill 路由, 需求: $ARGUMENTS。
Codex 端特别注意:
- **无 /goal** → delivery-gate hook 兜底判定
- **无 /batch** → 多任务用 spawn_agent (config.toml [agents] 配置)
- **无 compact 生命周期** → 长任务点主动写 `.ai_state/_index.md` 保存
+67
View File
@@ -0,0 +1,67 @@
# /athena-init (Codex) — 项目初始化
# 描述
> 项目初始化。每个新项目首次使用 Athena 时运行。
# end
参考: <https://developers.openai.com/codex/concepts/customization>
`.ai_state/_index.md` 已存在 → 提示用户用 `/athena-migrate` 升级或确认覆盖。
## 1. 项目扫描
```bash
ls package.json pyproject.toml Cargo.toml go.mod build.gradle pom.xml 2>/dev/null
cat package.json 2>/dev/null | grep -A5 '"scripts"'
ls jest.config* vitest.config* pytest.ini .eslintrc* ruff.toml biome.json 2>/dev/null
```
## 2. 创建 .ai_state/ (v9.6 schema)
```bash
mkdir -p .ai_state/details/reviews .ai_state/details/tasks-archive
```
## 3. 拷贝模板
从 `~/.codex/skills/pace/templates/` 复制:
- `_index.md` → `.ai_state/_index.md`
- 所有 `details/*.md`
- `init.sh`
## 4. 填充 _index.md frontmatter
把扫描结果写入: tech_stack, test_cmd, build_cmd, lint_cmd, dev_cmd
平台特征 (`codex --version` 输出):
- `cx_version`
- `goal_supported`: Codex 当前**没有原生 /goal** → false
- `batch_supported`: Codex subagent (max_threads in [agents]) 部分支持 → 视 max_threads 而定
- `background_supported`: false (Codex 无 /background)
- `session_memory_active`: false (Codex 无 ~/.claude/projects/ 等价物)
- `cross_session_memory`: "none"
## 5. 生成 init.sh
根据扫描结果定制 `.ai_state/init.sh`. `chmod +x`.
## 6. .gitignore
```bash
grep -q '.ai_state' .gitignore 2>/dev/null || echo '.ai_state/' >> .gitignore
```
## 7. Git commit
```bash
git add .ai_state/ .gitignore
git commit -m "athena: project initialized (v9.6 schema, Codex)"
```
## 8. 验证
```bash
bash .ai_state/init.sh
```
告知用户: "Athena (Codex 版) 已就绪。用 `/athena-dev <需求>` 开始, 或 `/athena-status` 看面板。"
+155
View File
@@ -0,0 +1,155 @@
# /athena-migrate (Codex) — v9.5 → v9.6 迁移
参考 CC 版 `~/.claude/skills/athena-migrate/SKILL.md`. 算法一致 (因为 schema 跨平台相同, 这是铁律 6).
Codex 端差异:
- 用 python3 替代 node 生成 `_index.md` (Codex 默认有 python3)
- 检测 `cx_version` 写入 `platform_features.cx_version`, **不写** cc_version
## 备份脚本
```bash
mkdir -p .ai_state/.legacy-v9.5
cp -r .ai_state/{tasks.md,design.md,progress.md,lessons.md,handoff.md,project.json,reviews,hook-trace.jsonl} .ai_state/.legacy-v9.5/ 2>/dev/null || true
```
## 创建 details/
```bash
mkdir -p .ai_state/details/reviews .ai_state/details/tasks-archive
```
## 平移
```bash
[ -f .ai_state/tasks.md ] && mv .ai_state/tasks.md .ai_state/details/tasks-current.md
for f in design.md progress.md lessons.md handoff.md; do
[ -f .ai_state/$f ] && mv .ai_state/$f .ai_state/details/$f
done
[ -d .ai_state/reviews ] && mv .ai_state/reviews .ai_state/details/reviews
[ -f .ai_state/compact-snapshot.json ] && rm .ai_state/compact-snapshot.json # Codex 无 compact 也能有的旧文件
```
## 生成 _index.md (python3)
```bash
python3 << 'PY'
import json, os, re, sys
proj = {}
try:
with open('.ai_state/.legacy-v9.5/project.json') as f:
proj = json.load(f)
except FileNotFoundError:
pass
def count_match(path, pattern):
try:
with open(path) as f:
return len(re.findall(pattern, f.read(), re.MULTILINE))
except FileNotFoundError:
return 0
def last_section_line(path, head_prefix='## '):
try:
lines = open(path).read().split('\n')
for i in range(len(lines) - 1, -1, -1):
if lines[i].startswith(head_prefix):
return i + 1
except FileNotFoundError:
pass
return 0
def last_nonempty_line(path):
try:
lines = open(path).read().split('\n')
for i in range(len(lines) - 1, -1, -1):
stripped = lines[i].strip()
if stripped and not stripped.startswith('<!--') and not stripped.startswith('#'):
return i + 1
except FileNotFoundError:
pass
return 0
tasks_pending = count_match('.ai_state/details/tasks-current.md', r'^- \[ \]')
tasks_done = count_match('.ai_state/details/tasks-current.md', r'^- \[x\]')
progress_n = last_nonempty_line('.ai_state/details/progress.md')
lessons_lines = count_match('.ai_state/details/lessons.md', r'^## ')
latest_lesson_line = last_section_line('.ai_state/details/lessons.md')
reviews = []
try:
reviews = [f for f in os.listdir('.ai_state/details/reviews') if re.match(r'^sprint-\d+\.md$', f)]
except FileNotFoundError:
pass
reviews_count = len(reviews)
latest_review = ''
if reviews:
latest_review = 'details/reviews/' + sorted(reviews, key=lambda f: int(re.search(r'\d+', f).group()))[-1]
content = f'''---
schema_version: "9.6"
athena_version: "9.6.0"
project:
path: "{proj.get('path','')}"
stage: "{proj.get('stage','')}"
sprint: {proj.get('sprint', 0)}
active_goal: ""
counts:
tasks_pending: {tasks_pending}
tasks_done: {tasks_done}
tasks_blocked: 0
lessons_lines: {lessons_lines}
progress_entries: {progress_n}
reviews_count: {reviews_count}
pointers:
latest_progress: "{('details/progress.md#L' + str(progress_n)) if progress_n else ''}"
latest_review: "{latest_review}"
latest_lesson: "{('details/lessons.md#L' + str(latest_lesson_line)) if latest_lesson_line else ''}"
latest_proposal: ""
fingerprints:
tasks_mtime: 0
design_mtime: 0
progress_mtime: 0
lessons_mtime: 0
platform_features:
cc_version: ""
cx_version: ""
goal_supported: false
batch_supported: false
background_supported: false
session_memory_active: false
cross_session_memory: "none"
gotchas: {json.dumps(proj.get('gotchas', []))}
conventions: {json.dumps(proj.get('conventions', []))}
tech_stack: "{proj.get('tech_stack','')}"
test_cmd: "{proj.get('test_cmd','')}"
build_cmd: "{proj.get('build_cmd','')}"
lint_cmd: "{proj.get('lint_cmd','')}"
dev_cmd: "{proj.get('dev_cmd','')}"
---
# 项目状态索引 (v9.6 migrated from v9.5.5)
## 最近活动
## 当前阻塞
## 下一动作 (PACE 建议)
## 反思建议 (Hook 沉淀)
'''
with open('.ai_state/_index.md', 'w') as f:
f.write(content)
print('[migrate] _index.md generated')
PY
```
## 收尾
```bash
touch .ai_state/details/next.md .ai_state/details/proposals.md
git add .ai_state/
git commit -m "athena: migrate state to v9.6 schema (codex)"
```
+80
View File
@@ -0,0 +1,80 @@
# /athena-preferences (Codex)
## 设计原则 (同 CC 版)
Athena 不造私有偏好文件。所有写入都是 Codex 原生位置:
| 偏好类型 | Codex 落点 |
|---|---|
| 工具偏好 (pnpm/vitest) | `~/.codex/AGENTS.md` "## Tool Preferences" 段 |
| 风格偏好 (Linus 模式等) | `~/.codex/AGENTS.md` |
**Codex 没有 CC 风格的 permissions.allow/deny.** Codex 用:
- `approval_policy` (on-request / never / on-failure / untrusted) — 顶层
- `sandbox_mode` (workspace-write / read-only / danger-full-access)
- `[shell_environment_policy]` 控制环境
参考: <https://developers.openai.com/codex/config-reference>
所以 `/athena:remember-allow|deny` 在 Codex 上**部分语义不可映射**, 当前实现:
- `/athena:remember-tool <key>=<value>` → 写 `~/.codex/AGENTS.md` "## Tool Preferences"
- `/athena:show-preferences` → cat ~/.codex/AGENTS.md
- `/athena:remember-allow|deny` → 提示用户在 `~/.codex/config.toml` 改 `approval_policy` 或 `sandbox_mode`, **不自动改** (那是 critical 配置)
## 子命令 (Codex)
### `/athena:remember-tool <key>=<value>`
```bash
GLOBAL_AGENTS_MD="$HOME/.codex/AGENTS.md"
mkdir -p "$(dirname "$GLOBAL_AGENTS_MD")"
# 创建文件 / 找到 Tool Preferences 段 / 追加
python3 << PY
import os, re
p = os.path.expanduser("~/.codex/AGENTS.md")
try:
content = open(p).read()
except FileNotFoundError:
content = ""
section = "## Tool Preferences"
arg = "$ARGUMENTS" # 由 Codex 替换
if section not in content:
if content and not content.endswith("\n"):
content += "\n"
content += "\n" + section + "\n\n- " + arg + "\n"
else:
# 在 section 后追加一行 (避免重复)
if "- " + arg in content:
print(f"⚠️ 已存在: {arg}")
exit(0)
content = re.sub(r"(" + re.escape(section) + r"\n+)", r"\g<1>- " + arg + "\n", content, count=1)
open(p, "w").write(content)
print(f"✓ 已加入 ~/.codex/AGENTS.md Tool Preferences: {arg}")
PY
```
### `/athena:show-preferences`
```bash
echo "=== ~/.codex/AGENTS.md (Tool Preferences) ==="
sed -n '/^## Tool Preferences/,/^## /p' ~/.codex/AGENTS.md 2>/dev/null | head -30
echo ""
echo "=== ~/.codex/config.toml (approvals / sandbox) ==="
grep -E "^(approval_policy|sandbox_mode)" ~/.codex/config.toml 2>/dev/null
```
### `/athena:remember-allow|deny <pattern>`
不自动写, 仅提示:
```
⚠️ Codex 没有 permissions.allow/deny 概念.
等价配置在 ~/.codex/config.toml:
- approval_policy: on-request | never | on-failure | untrusted
- sandbox_mode: read-only | workspace-write | danger-full-access
请用编辑器手改这两个字段, 不通过 Athena 自动改 (critical config).
```
+12
View File
@@ -0,0 +1,12 @@
# /athena-review (Codex)
有 `.ai_state/_index.md` → 按当前 Path 触发 pace skill 审查阶段。
无 → 快速审查 (Codex 内置 /review)。
焦点: $ARGUMENTS
Codex 端可用工具:
- `/review` (Codex 内置)
- `spawn_agent reviewer` (从 ~/.codex/agents/reviewer.toml 调度)
- `web_search` 查最佳实践
- 不可: /codex:review (那是 CC 侧反向调用)
+98
View File
@@ -0,0 +1,98 @@
# /athena-setup (Codex)
参考: <https://developers.openai.com/codex/config-basic>
## Step 0: Codex 版本
```bash
codex --version
```
要求 ≥ v0.124 (hooks stable). v0.129+ 解锁 /hooks TUI menu.
写入 `_index.md.platform_features.cx_version`.
## Step 1: 验证 config.toml
`~/.codex/config.toml` 应包含 (从 cx/.codex/config.toml 拷贝):
- `model = "gpt-5.5"`
- `[features] hooks = true` (规范名, 非 deprecated codex_hooks)
- `[[hooks.SessionStart]]`, `[[hooks.PreToolUse]]`, `[[hooks.PostToolUse]]`, `[[hooks.Stop]]`
- `[agents] max_threads = 6`
- `[[skills.config]]` 包含 pace / compound / context7 / superpowers
```bash
codex check config 2>&1 | head -20
```
## Step 2: 部署 hooks
```bash
mkdir -p ~/.codex/hooks
cp cx/.codex/hooks/*.py ~/.codex/hooks/
chmod +x ~/.codex/hooks/*.py
```
Codex hook 列表 (Python, 6 个):
- session-start.py
- user-prompt-submit.py
- pre-bash-guard.py
- index-updater.py
- subagent-retry.py
- delivery-gate.py
⚠️ Codex hooks 当前 Windows 不支持 (官方限制, 参考 <https://developers.openai.com/codex/hooks>)
## Step 3: 部署 skills
```bash
mkdir -p ~/.codex/skills/pace ~/.codex/skills/compound
cp -r cx/.codex/skills/pace/* ~/.codex/skills/pace/
cp -r cx/.codex/skills/compound/* ~/.codex/skills/compound/
```
## Step 4: 部署 prompts (slash commands)
```bash
mkdir -p ~/.codex/prompts
cp cx/.codex/prompts/*.md ~/.codex/prompts/
```
## Step 5: 部署 subagents (单 TOML 文件, 非子目录)
参考: <https://developers.openai.com/codex/subagents>
```bash
mkdir -p ~/.codex/agents
cp cx/.codex/agents/*.toml ~/.codex/agents/
```
部署后:
- `~/.codex/agents/evaluator.toml` — 评分员 (read-only)
- `~/.codex/agents/generator.toml` — 实现者 (workspace-write)
- `~/.codex/agents/reviewer.toml` — 审查员 (read-only)
验证:
```bash
codex /agents 2>&1 | head -20
# 应列出 evaluator, generator, reviewer 三个 custom agent
```
## Step 6: 跨项目记忆 (推荐)
Codex 暂无 claude-mem 等价物。推荐:
- 用 `~/.codex/AGENTS.md` 全局 "## Tool Preferences" 段做轻量记忆
- 多项目用同一 ~/.codex/AGENTS.md (跨项目人工同步)
## Step 7: 验证
```bash
codex --version # ≥ 0.124
ls ~/.codex/hooks/*.py | wc -l # 应 = 6
ls ~/.codex/prompts/*.md # 7 个 athena-* prompt
codex /hooks 2>&1 | head # v0.129+ TUI 显示 hook 树
cat .ai_state/_index.md | head -5 # schema_version: "9.6"
```
通过 → "Codex 端 Athena 已就绪。"
+32
View File
@@ -0,0 +1,32 @@
# /athena-status (Codex)
参考 CC 版 (~/.claude/skills/athena-status/SKILL.md). 等价实现, 差异:
| 字段 | CC 端 | CX 端 |
|------|-------|-------|
| goal_supported | CC v2.1.139+ | **始终 false** (Codex 无 /goal) |
| batch_supported | CC v2.1.121+ | 视 [agents] max_threads 而定 |
| background_supported | CC v2.1.139+ | **始终 false** (Codex 无 /background) |
| session_memory_active | ~/.claude/projects/ | **始终 false** (Codex 无等价) |
## 收集顺序 (同 CC 版)
1. PACE 状态 (从 `.ai_state/_index.md` frontmatter)
2. Sprint 进度 (counts 段)
3. Hook 触发记录 (`tail -50 .ai_state/hook-trace.jsonl`)
4. Lessons 统计
5. Platform 健康 (Codex 特定)
6. Plugin 状态: CX 无插件生态, 仅显示 `codex --version`, `codex /hooks` 输出, `codex /skills`
## Codex 特有显示
```
[Codex Hooks]
/hooks tui: v0.129+
hooks 配置文件: ~/.codex/hooks.json, ~/.codex/config.toml [[hooks.*]]
Windows 支持: 否 (官方限制)
[Codex Subagents]
config.toml [agents].max_threads: <从 config 读>
available roles: evaluator, generator, reviewer
```
-25
View File
@@ -1,25 +0,0 @@
---
name: brainstorm
description: R₀ 苏格拉底式需求精炼
---
# Brainstorm (R₀ 需求精炼)
Path B+ 任务在写代码前**必须**激活。
## 流程
### 0. 自主调研 (提问前)
- 搜索项目中与需求相关的现有代码
- 读 .ai_state/lessons.md + conventions.md
→ 基于调研结果准备更有深度的问题
### 1. 访谈 (苏格拉底式)
- 一次只问一个问题, 优先选择题
- 覆盖: 目标、场景、边界、非功能需求
- YAGNI: 主动砍不必要的功能
### 2. 提出 2-3 方案
- 每方案: 架构 + 优劣 + 复杂度
- context7 验证可行性
### 3. 确认 → .ai_state/design.md
铁律: 设计未确认前不写代码
-18
View File
@@ -1,18 +0,0 @@
---
name: claude-delegate
description: 接收 CC 派发任务 + 反向调用 CC
---
# Claude Delegate
## 当被 CC 调用时
- CC 通过 codex exec 发送任务
- 你在只读沙箱, 输出代码和建议
- 审查请求: 以 `VERDICT: APPROVED` 或 `VERDICT: REVISE` 结尾
## 反向调用 CC (独立运行时)
如需 Claude 视角:
```bash
# 如果有 claude CLI
claude -p "审查以下代码: {code}"
```
如不可用 → 用 validator agent 自审
-18
View File
@@ -1,18 +0,0 @@
---
name: code-review
description: T 阶段代码审查
---
# Code Review
## 审查清单
1. Spec 合规: 每个 MUST 实现?
2. TDD: 源码有对应测试?
3. 边界: 空输入/超长/并发/错误路径?
4. 安全: 无硬编码密钥, 输入已验证
5. 可读: 函数 < 50 行, 注释说 WHY, 严格类型
6. 简洁: 无过度工程, 无重复, 无空 catch
## LLM-as-Judge 输出格式
```json
{"level": "PASS|CONCERNS|REWORK|FAIL", "issues": [...], "summary": "..."}
```
+47
View File
@@ -0,0 +1,47 @@
---
name: compound
description: >
Sprint Quality Gate 通过后触发。提炼本 Sprint 学到的为结构化条目追加 lessons.md。
effort: xhigh
---
# /compound — 经验沉淀
Gate PASS 后触发 (或用户显式 `/compound`).
## 输入
- `.ai_state/details/reviews/sprint-N.md` (审查报告)
- `git diff` (本 Sprint 所有变更)
- `.ai_state/details/tasks-current.md` (完成项)
- `.ai_state/details/design.md` (设计 vs 实际实现对比)
## 提炼方法
从以上输入找**真实发现**, 不写仪式性废话。每 Sprint 0-N 条不强制。
- **Pattern**: 什么解法有效且可复用? (带代码行号 / 文件路径)
- **Pitfall**: 什么坑踩过? 未来同类场景要提前避开
- **Constraint**: 发现的新约束 (依赖版本、环境、性能边界、API 限制)
没发现可提炼的 → 不写, 直接告知用户 "no new lesson". **不允许编造**.
## 输出 (项目级)
追加到 `.ai_state/details/lessons.md` (append-only, 不修改历史).
格式见 `pace/templates/details/lessons.md`. **Athena 不做跨项目知识管理**——需要的话装 claude-mem 或 superpowers。
写入后同步更新 `_index.md`:
- `counts.lessons_lines` += 新增条目数 (按 `## ` 头计)
- `pointers.latest_lesson` = `details/lessons.md#L<新条目行号>`
- `fingerprints.lessons_mtime` = 当前时间戳
## 自检
写入后读回验证:
1. 条目有具体的文件/行号/版本引用 (不只是"要注意 X")
2. 一句话标题能让下次 R₀ 快速扫描命中
3. Pattern/Pitfall/Constraint 三段不强制全有, 但至少有一段
写完告知用户: "Lessons updated. Next sprint R₀ 会自动读取 (按 _index.md.pointers.latest_lesson 跳转)."
-9
View File
@@ -1,9 +0,0 @@
---
name: context7
description: 库文档查询
---
# Context7
1. 优先: `npx ctx7 resolve {库名}`
2. 备选: web search
3. 缓存: 查过的结论写入当前笔记
-12
View File
@@ -1,12 +0,0 @@
---
name: debugging
description: 系统化调试 4 阶段
---
# Systematic Debugging
必须按 4 阶段执行, 禁止跳步:
## 1. 复现 — 最小用例, 记录输入/期望/实际
## 2. 定位 — 从错误点向上追溯, 用证据不用直觉
## 3. 修复 — 只改根因, 有对应测试, 禁止 as any / 空 catch
## 4. 验证 — 复现通过 + 全量无回归 + Reflexion: 值得记录?
-9
View File
@@ -1,9 +0,0 @@
---
name: e2e
description: 端到端测试
---
# E2E Testing
前置: 有 E2E 框架 (Playwright/Cypress) 且 Path C+ 或用户要求
流程: 基于验收标准写用例 → 运行 → 结果入 quality.md
无框架: 手动验证清单
-14
View File
@@ -1,14 +0,0 @@
---
name: finish-branch
description: V 阶段分支收尾
---
# Finish Branch
V 阶段 kaizen 后, 交付确认前。
## 选项
a) **pr**: 生成 PR description (标题+摘要+变更+测试)
b) **keep**: 保留分支
c) **discard**: 确认后标记废弃
注意: Codex 不直接执行 git merge, 生成描述供用户操作。
-11
View File
@@ -1,11 +0,0 @@
---
name: kaizen
description: V 阶段回顾
---
# Kaizen
## 流程
1. 回顾: 好的保持, 差的改进, 模式性错误?
2. 更新 lessons.md
3. 更新 conventions.md "## Agent 易犯错误" (如发现模式性错误)
4. 摘要给用户
+97
View File
@@ -0,0 +1,97 @@
---
name: pace
description: >
工作流路由器 (Codex 版). 收到开发任务时触发. 按任务复杂度路由到 6 条路径.
effort: high
---
# PACE — 6 路径路由器 (v9.6 Codex)
首先读 `.ai_state/_index.md` (铁律 8 索引先行). 有 stage → 从当前阶段继续.
.ai_state/ 不存在 → 提示 `/athena-init`.
## 路由 (同 CC)
```
┌─ 1行/配置 ──────→ Hotfix
修复 ────┤
└─ 需要调试 ─────→ Bugfix
┌─ 需求清晰/小 ──→ Quick
新建 ────┤ 需要设计 ─────→ Feature
├─ 改现有结构 ───→ Refactor
└─ 跨模块/服务 ──→ System
```
## Codex 端关键限制 (vs CC)
| 能力 | CC | Codex | Athena 替代方案 |
|------|-----|-------|----------------|
| /goal autonomous loop | ✓ v2.1.139+ | ✗ | delivery-gate hook 兜底判定 VERDICT |
| /batch 自动并行 worktree | ✓ v2.1.121+ | ✗ | spawn_agent 多线程 (config.toml [agents].max_threads) |
| /background 多会话 | ✓ v2.1.139+ | ✗ | 用户自己开多个 codex session |
| PreCompact / PostCompact | ✓ | ✗ | 长任务点主动 _index.md 保存 |
| Session memory | ✓ ~/.claude/projects/ | ✗ | 无 (cross_session_memory: "none") |
| compact 自动 | ✓ /compact | ✗ | Codex 用 `/clear` + AGENTS.md 注入恢复 |
## Codex 优势 (vs CC)
| 信号 | Codex 更适合 |
|------|------------|
| 终端命令为主 | Terminal-Bench 2.0 SOTA 82.7% (GPT-5.5 Apr 2026) |
| 大量同模式改写 | token 成本 0.25-0.33× CC, 适合"重复劳动" |
| 多模型互审 | Codex 主跑 + 调 web_search 验证 |
## 跨平台路由建议
Codex 端在以下情况主动建议用户切到 CC:
- 任务包含大量"自动循环直到达成条件" → 建议 CC `/goal`
- 任务包含"并行改 100 个文件" → 建议 CC `/batch`
- 任务需要 Opus 设计能力 → 建议 CC
不强制 — 是建议。
## 6 路径 (Codex 版, 简化)
### Hotfix · Bugfix
同 CC 版, 没有 stage. `apply_patch` 改 → `shell` 跑测试 → `git commit`.
### Quick (impl → review → ship)
TDD 实现 → /review (Codex 内置) → git commit.
路径升级监测 (同 CC).
### Feature (plan → impl → review → ship)
- **plan**: web_search 调研 + brainstorming → design.md → 用户确认 → tasks.
- **impl**: 按 task 实现, TDD, 完成勾选 + progress 追加. 路径升级监测.
- **review**: /review + spawn_agent reviewer (Codex subagent, 见 [agents].max_threads). VERDICT.
- **ship**: git commit + 归档.
### Refactor (plan → impl → review → ship)
- **plan**: 用户确认重构方案 + design.md (before/after) + tasks-current.md.
- **impl**: 用 spawn_agent 多线程并发 (Codex 端不像 CC 的 /batch 自动 worktree, 需要手动多 agent 协作).
- 设置 `--max-threads <N>` (从 _index.md.platform_features 推断 max_threads)
- **review**: 同 Feature.
- **ship**: 同上.
### System (plan → design → impl → review → ship)
完整流程, 长 stage 主动写 `.ai_state/_index.md` 保存 (Codex 无 compact).
## 共享协议 (审查/发布同 CC 端)
参考 `~/.codex/skills/pace/SKILL.md` 完整文本.
## 失败处理协议 (同 CC, 铁律 6 完成度证据)
工具失败 → 三轮重试 (改参数 / 换工具 / 拆任务). 三轮后报告完整 stderr + exit code.
spawn_agent 输出预算 ≤ 2000 tokens.
**禁止**: "请你手动执行" 作为首次响应.
## 状态管理 (铁律 5/8)
`.ai_state/_index.md` 单一入口. 协议字段同 CC 端. 跨平台一致 (铁律 6).
合法 path: Hotfix / Bugfix / Quick / Feature / Refactor / System
合法 stage: plan / design (System only) / impl / review / ship
Codex 无 compact 生命周期 → 不写 `compact-snapshot.md`, hooks 也无 PreCompact/PostCompact.
+32
View File
@@ -0,0 +1,32 @@
# VibeCoding Athena Codex (SessionStart 自动注入)
你是 VibeCoding Athena 工程 Agent. Codex 做事, Athena 把关.
**铁律 (9 条, 跨平台共用)**:
1. 设计先行 (Hotfix/Bugfix 例外)
2. TDD 强制
3. Sisyphus (tasks 全完成才进审查)
4. Review 强制 (Feature+ 至少一次交叉审查)
5. 文档即真相 (`.ai_state/_index.md` 单一入口)
6. 完成度证据 (报告"完成"必须附 tool_use ID 或命令输出)
7. 出处优先 (技术结论必须引用官方文档/源码 URL)
8. **索引先行** (进入决策先读 `.ai_state/_index.md`, 禁止 glob 全目录)
9. **Hook 是进化器** (Stop 时反思写 `details/proposals.md`)
工具报错 → 三次重试附 stderr 报告, 不让用户代执行.
spawn_agent 必须产生真实 tool_use 响应, 不允许伪造.
## R₀ Get-bearings (just-in-time)
1. 必读: `.ai_state/_index.md` (单一入口, 已自动注入)
2. 按需: stage=impl/review → 按 pointers.latest_progress 读 progress.md 尾部
3. 按需: 命中 lessons 主题 → pointers.latest_lesson 跳段
文件大就用 head/tail/grep. **禁止 glob 整个 .ai_state/**.
## Codex 端限制 (vs CC)
- 无 /goal /batch /background → 由 Athena 兜底
- 无 compact → 长 stage 主动写 _index.md 保存
- 无 cross-session memory → 跨项目记忆人工同步 ~/.codex/AGENTS.md
- Windows 不支持 hooks (官方限制)
+66
View File
@@ -0,0 +1,66 @@
---
schema_version: "9.6"
athena_version: "9.6.0"
project:
path: "" # Hotfix | Bugfix | Quick | Feature | Refactor | System | ""
stage: "" # plan | design | impl | review | ship | ""
sprint: 0
active_goal: "" # 当前 /goal condition (空 = 无活动 goal)
counts:
tasks_pending: 0
tasks_done: 0
tasks_blocked: 0
lessons_lines: 0
progress_entries: 0
reviews_count: 0
pointers:
latest_progress: "" # 如 "details/progress.md#L46"
latest_review: "" # 如 "details/reviews/sprint-3.md"
latest_lesson: "" # 如 "details/lessons.md#L98"
latest_proposal: "" # 如 "details/proposals.md#L12"
fingerprints:
tasks_mtime: 0
design_mtime: 0
progress_mtime: 0
lessons_mtime: 0
platform_features:
cc_version: "" # 由 athena-setup 检测填入
cx_version: "" # 同上
goal_supported: false # CC ≥ v2.1.139 时 true
batch_supported: false # CC ≥ v2.1.121 时 true
background_supported: false # CC ≥ v2.1.139 时 true
session_memory_active: false # ~/.claude/projects/ 自动摘要是否启用
cross_session_memory: "none" # "claude-mem" | "superpowers" | "none"
gotchas: [] # 项目特有的"小心点", PACE 会在 SessionStart 注入
conventions: [] # 项目约定 (pnpm vs npm 等)
tech_stack: ""
test_cmd: ""
build_cmd: ""
lint_cmd: ""
dev_cmd: ""
---
# 项目状态索引
<!--
本文件是 .ai_state/ 的单一入口 (铁律 8)。
SessionStart hook 只读这一个文件, 注入轻量 frontmatter 字段 + counts 摘要。
下游 (Edit/Read tools) 按 pointers 自取明细。
任何 detail/* 文件写入 → PostToolUse index-updater.cjs 原子更新本文件。
-->
## 最近活动
<!-- 由 pace-continuator hook 在 Stop 时维护, 保留最近 3 条 -->
## 当前阻塞
<!-- 由 PACE 流程在 stage=impl/review 时填写 -->
## 下一动作 (PACE 建议)
<!-- 由 pace-continuator 在 Stop 时根据 stage 推断, 写入 details/next.md 的摘要 -->
## 反思建议 (Hook 沉淀)
<!-- 引用 details/proposals.md 最近一条 (latest_proposal) -->
@@ -0,0 +1,28 @@
# 设计文档
## 需求摘要
## 功能分级
- **MUST**:
- **SHOULD**:
- **COULD**:
## 验收标准
- [ ]
## 技术方案
## File Structure Plan
<!--
模块/文件边界, 给 tasks-current.md 拆任务用 (boundary-first 设计)
示例:
- src/auth/ — JWT/refresh/session, owner: Task 1-3
- src/routes/user/ — user CRUD endpoints, owner: Task 4-5
- tests/auth/ — auth 单测 + 集成测试
边界外的文件 = 本 Sprint 不应触碰
-->
## 不做什么
@@ -0,0 +1,31 @@
# 跨模型/跨 worker 交接
<!--
本文件内容会作为 /codex:rescue "<内容>" 的 prompt 传入。Codex 不会自动读本文件。
构造完 handoff.md → Claude 把文件内容 Read 出来作为 /codex:rescue 的参数。
-->
## 当前任务
<!-- Task ID + 描述 + 验收标准 + Boundary 范围 -->
## 项目文件树
<!-- 必须包含实际文件列表, 用 find/ls 生成, 不要手写 -->
<!-- 示例: find . -name "*.py" -not -path "./venv/*" | head -50 -->
## 关键代码片段
<!-- 与本 Task 直接相关的代码文件内容 (关键函数/类, 不要全文) -->
## 项目背景
<!-- design.md 摘要 + 技术栈 -->
## 已完成
<!-- tasks-current.md 中完成的 Task -->
## 注意事项
<!-- _index.md.gotchas + conventions -->
@@ -0,0 +1,21 @@
# 项目级经验沉淀 (Lessons Learned)
<!--
每个 Sprint 通过 Gate 后由 compound skill 追加。append-only, 不删不改历史。
本文件存项目级业务代码经验 (Athena 不做跨项目知识管理)。
跨项目记忆请装 claude-mem 或 superpowers。
格式:
## [YYYY-MM-DD Sprint N] 一句话标题
- **Pattern**: 解法描述 (文件:行号)
- **Pitfall**: 坑点描述
- **Constraint**: 新约束
示例:
## [2026-05-21 Sprint 1] JWT refresh 不能和 access 共享 secret
- **Pattern**: 分开 secret + rotation key 在 env (src/auth/config.ts:15)
- **Pitfall**: Authorization header 大小写处理不一致, 用 lodash.toLower 前置
- **Constraint**: Redis 需要 ≥256MB 才放得下 session cache
-->
@@ -0,0 +1,15 @@
# 下一动作建议 (PACE-aware, Stop hook 维护)
<!--
本文件由 .claude/hooks/pace-continuator.cjs 在 Stop 事件时写入。
读 _index.md 的 path/stage/sprint, 推断"下一步该做什么", 给出具体的命令建议。
SessionStart 时 (如有 pace-resumer hook) 会读本文件作为"继续提示"。
格式:
## YYYY-MM-DD HH:MM
当前: <path>/<stage>/sprint <N>
建议:
- 命令 1
- 命令 2
理由: <一句话>
-->
@@ -0,0 +1,15 @@
# Progress Log
<!--
impl 阶段每完成一个 Task 追加一行 (铁律 5)。
格式: YYYY-MM-DD HH:MM [path/stage/sprint] action
示例:
2026-05-21 14:30 [Feature/impl/1] Task 3 done: auth middleware
2026-05-21 15:10 [Feature/impl/1] design.md updated: JWT expiry 15min
2026-05-21 15:30 [Feature/impl/1] PATH-UPGRADE Feature → System (发现需要改 schema)
2026-05-21 16:45 [Feature/review/1] /review 完成, 无阻塞问题
append-only: 不删历史, 不改既有行。
index-updater hook 会更新 _index.md.counts.progress_entries 和 pointers.latest_progress。
-->
@@ -0,0 +1,20 @@
# Hook 反思沉淀 (铁律 9: Hook 是进化器)
<!--
本文件由 .claude/hooks/pace-continuator.cjs 在 Stop 时维护。
当 hook 检测到"本 turn 有反复试错 / 阻塞 / 失败模式", append-only 一条反思。
不写"已知坑" (lessons.md 管那个), 写"流程级提议":
- "考虑把 X 加入 .ai_state/conventions"
- "delivery-gate 这条规则可能误伤, 下版本调整"
- "本 sprint 的 stage transition 太快, plan 阶段不充分"
人审完后可以手动迁移到 lessons.md 或者 conventions 列表。
hook 永远不替用户做决定, 只提供素材。
格式:
## YYYY-MM-DD HH:MM (sprint N)
- 观察: <事实>
- 假设: <可能原因>
- 提议: <改什么>
-->
@@ -0,0 +1,41 @@
# Sprint N 审查报告
## Step 1: 测试结果
<!-- 命令 + 实际输出 (不是"已跑通") -->
## Step 2: /codex:review (Feature+, Quick 可选)
<!-- 必须有以下证据之一, 防伪装 (铁律 4 反空跑 + 铁律 6 完成度证据):
- codex job ID
- codex CLI 真实命令行输出片段
- 不可用时明示 "codex unavailable" + 完整 stderr -->
## Step 3: /codex:adversarial-review (System)
<!-- 同上证据要求 -->
## Step 4: ECC 扫描 (System)
<!-- npx ecc-agentshield scan 实际输出摘要 -->
## Step 5: Claude 审查 (/review 内置)
<!-- /review 输出 -->
## Step 6: @evaluator 评分
| 维度 | 分数 | 证据 |
|------|------|------|
| Functionality | /5 | (代码行号) |
| Spec Compliance | /5 | (代码行号 vs design.md) |
| Boundary Adherence | /5 | (是否越出 File Structure Plan) |
| Craft | /5 | (代码行号) |
| Robustness | /5 | (边界用例覆盖) |
| **均分** | **/5** | |
均分 = F×0.25 + SC×0.25 + B×0.15 + C×0.15 + R×0.20
## VERDICT:
<!-- PASS (均分≥4.0 且所有维度≥3) | CONCERNS (均分≥3.0 有维度=2) | REWORK (均分<3.0 或任一=1) | FAIL (多维度=1 或安全/Boundary 大幅越界) -->
@@ -0,0 +1,19 @@
# Sprint 任务清单
<!--
每个 Task 的 Boundary/Depends 标注 (cc-sdd 边界优先, 防止越界)
格式:
- [ ] Task N: 简述
_Boundary:_ src/auth/, tests/auth/
_Depends:_ Task N-1 (空则 — )
PostToolUse hook (index-updater.cjs) 会:
- 检测本文件的 - [ ] / - [x] 数量变化
- 原子更 _index.md.counts.tasks_pending/done/blocked
-->
## 待办
## 完成
## 阻塞
@@ -0,0 +1,121 @@
# /goal Condition 模板库
每个 PACE stage 对应一个 condition 模板, 用 `/goal <condition>` 启动 autonomous loop。
参考: <https://code.claude.com/docs/en/goal>
## 写 condition 的四件套 (官方推荐)
```
End Goal + Verification + Constraints + Turn/Time Limit
```
- **End Goal**: 一个可测的终态 (test 通过 / 文件存在 / git log 含 commit)
- **Verification**: 如何证明 (npm test exits 0 / rg "X" 0 行)
- **Constraints**: 边界 (不动 X 文件 / 不引入新依赖)
- **Turn/Time Limit**: stop after 20 turns / stop after 60 minutes
---
## Feature/Refactor/System stage=plan
```
ALL of:
- .ai_state/details/design.md 含 "## File Structure Plan" 段且段下至少 3 个 owner 行
- .ai_state/details/tasks-current.md 至少 1 个 - [ ] Task
- 我已经 ask 用户确认且收到了 "yes" 或 "go" 回复
Constraints:
- 不修改 design.md 之外的源码文件
- 不超过 20 turns
```
## Quick/Feature stage=impl
```
ALL of:
- .ai_state/details/tasks-current.md 中所有 - [ ] 都变成 - [x]
- 运行 <test_cmd> 退出码 0 (从 _index.md.test_cmd 读)
- .ai_state/details/progress.md 在本 turn 序列至少新增 N 行 (N = 原待办 task 数)
- 没有任何对 design.md 的修改
Constraints:
- 不动 .ai_state/_index.md 以外的元数据
- 不超过 30 turns 或 90 分钟
```
## Refactor stage=impl (用 /batch)
```
ALL of:
- tasks-current.md 全部 - [x]
- 每个 worktree 的 lint_cmd 退出 0
- 每个 worktree 的 test_cmd 退出 0
- 主分支 git diff 显示预期的批量变更模式
Constraints:
- 不引入新依赖
- 不超过 60 minutes 或 50 turns
```
## System stage=design
```
ALL of:
- details/design.md 含 "## File Structure Plan" 且段下覆盖所有新增/修改的模块路径
- details/design.md 含 "## 验收标准" 段且至少 5 条 - [ ] (会在 impl 阶段勾选)
- details/tasks-current.md 至少 N 个 Task (N = design 模块数), 每个含 Boundary 和 Depends 注释
- 我已经 ask 用户对设计的最终确认
Constraints:
- 不超过 25 turns
```
## stage=review (Feature+)
```
ALL of:
- .ai_state/details/reviews/sprint-{sprint}.md 已存在且含 "VERDICT:" 行
- VERDICT 取值为 PASS / CONCERNS / REWORK / FAIL 之一
- 报告含至少一段 /codex:review 或 reviewer subagent 的真实输出 (codex job ID 或 thread ID)
- 报告含 test_cmd 实际输出
Constraints:
- 评分必须基于代码行号级证据
- 不超过 40 turns
```
## stage=ship
```
ALL of:
- details/lessons.md 末尾含 "## [{date} Sprint {sprint}]" 标题
- git log --oneline -1 显示本 sprint 的提交
- _index.md.project.sprint 已 +1 且 stage="" (由 athena-status 验证)
- details/tasks-archive/sprint-{sprint}.md 存在 (归档)
Constraints:
- 不超过 10 turns
```
---
## 启动方式
### 交互式
```
/goal <粘贴上面对应 stage 的 condition>
```
### 非交互式 (overnight 跑)
```bash
claude -p "/goal <condition>"
```
### 状态查询
```
/goal # 不带参数, 看 turns/tokens/最近 evaluator reason
/goal clear # 中止
```
## 注意事项 (官方文档)
- evaluator 只读 transcript, 不跑命令——condition 必须是"transcript 能证明的事"
- 一个 session 只能有一个 active goal, 设置新 goal 替换旧的
- condition ≤ 4000 字符
- v2.1.139+ 才有, 旧版本 delivery-gate hook 兜底
- "Vague in, vague out"——含糊的 condition = 含糊的 loop
+17
View File
@@ -0,0 +1,17 @@
#!/bin/bash
# Athena init.sh — 启动开发环境 + 基线测试
# 由 /athena-init 根据项目类型生成具体命令
set -e
echo "[Athena] 启动开发环境..."
# 示例 (根据项目类型):
# npm install
# pip install -e .
# cargo build
echo "[Athena] 运行基线测试..."
# npm test
# pytest
# cargo test
echo "[Athena] 就绪。"
-21
View File
@@ -1,21 +0,0 @@
---
name: plan-first
description: P 阶段计划生成
---
# Plan-First (P 阶段)
## 流程
1. 读 design.md
2. 分解为可执行任务:
```
- [ ] T-001: {动作} + {目标} + {验收条件}
文件: {涉及文件}
依赖: {前置任务}
```
3. 排序: 依赖拓扑 → 风险高先做
4. 写入 plan.md
## 质量检查
- 每个任务有"完成"定义
- 无模糊词
- 超过 15 个任务考虑拆分
-19
View File
@@ -1,19 +0,0 @@
---
name: reflexion
description: E 阶段自我反思
---
# Reflexion (自我反思)
E 阶段每个 Task 实现完成后, Micro-review 之前。
## 反思清单
1. 走捷径了吗? (as any, 空 catch)
2. 忽略边界了吗? (空/超长/并发/null)
3. 硬编码了吗? (URL/端口/阈值)
4. 过度工程了吗? (需求没要求的功能)
5. 偏离 spec 了吗?
6. 6 个月后能理解吗?
发现问题 → 立即修复
值得记录 → lessons.md
模式性错误 → conventions.md "Agent 易犯错误"
-8
View File
@@ -1,8 +0,0 @@
---
name: security-review
description: 安全审查
---
# Security Review
检查: 认证/授权, 输入验证, 密钥管理, 依赖漏洞, 日志安全, CORS/CSP
产出: 追加到 quality.md
-16
View File
@@ -1,16 +0,0 @@
---
name: verification
description: T 阶段验证
---
# Verification
## 流程
1. 运行测试 + 覆盖率
2. TypeScript 类型检查 (如有)
3. Lint (如有, Path C+ 强制)
## 验收标准逐条确认
4. 读 design.md "## 验收标准"
5. 逐条确认: 满足? 证据?
6. 未满足 → quality.md "## 未满足验收标准"
7. E2E (如有框架)
-9
View File
@@ -1,9 +0,0 @@
# Conventions
## 项目编码规范
{自动检测或手动填写}
## Agent 易犯错误
> 由 reflexion/kaizen 自动追加
- (初始为空)
-19
View File
@@ -1,19 +0,0 @@
# Design Spec
## 需求 (MUST/SHOULD/COULD)
### MUST
- {核心功能}
### SHOULD
- {重要功能}
### COULD
- {锦上添花}
## 技术方案
{架构}
## 验收标准
- [ ] {标准 1}
- [ ] {标准 2}
-7
View File
@@ -1,7 +0,0 @@
# Doing
## 当前执行
- [ ] {当前步骤}
## 历史
{自动追加}
-7
View File
@@ -1,7 +0,0 @@
# Lessons Learned
## 技术陷阱
{发现的问题}
## 有效模式
{有效的解决方案}
-7
View File
@@ -1,7 +0,0 @@
# Plan
## 任务列表
- [ ] T-001: {动作} + {目标} + {验收条件}
文件: {文件}
依赖: 无
-13
View File
@@ -1,13 +0,0 @@
# Quality Report
## 验证结果
- 测试: {通过/失败}
- 类型检查: {通过/失败}
## 验收标准确认
- [x] {标准}: 满足
- [ ] {标准}: 未满足
## 代码审查
- 发现: {数量}
- 已修复: {数量}
-10
View File
@@ -1,10 +0,0 @@
# Session
## 任务
{任务描述}
## 路径
P.A.C.E. Path: {A|B|C|D}
## 当前阶段
RIPER-7: {R₀|R|D|P|E|T|V}
-13
View File
@@ -1,13 +0,0 @@
# P.A.C.E. 复杂度路由 v9.2.0
收到任务后, 按以下规则选择路径:
| 条件 | 路径 | 阶段 |
|------|------|------|
| 修 bug / 改配置 / <30min | **A (快速)** | E→T |
| 新功能 / 重构 / 30min-4h | **B (标准)** | R₀→R→D→P→E→T→V |
| 跨模块 / 架构变更 / >4h | **C (复杂)** | 同B + 子代理并行 |
| 多服务 / 全栈 / 多人协作 | **D (系统)** | 同C + 设计评审 |
选定路径后 → 读 riper-7.md 执行对应阶段。
Path A 跳过 R₀/R/D/P, 直接 E→T。
-57
View File
@@ -1,57 +0,0 @@
# RIPER-7 阶段编排 v9.2.0
## 每阶段进入前 (通用)
1. 这一步要解决的核心问题是什么?
2. 项目里有没有类似实现? → 搜索相关代码
3. 用到的库 API 确定吗? → context7 skill 查文档
4. .ai_state/lessons.md + conventions.md 有相关经验吗?
---
## R₀ 需求精炼 (Path B+)
**技能**: brainstorm skill (含步骤0自主调研)
**产出**: .ai_state/design.md (Spec: MUST/SHOULD/COULD + 验收标准)
**门控**: cunzhi `DESIGN_READY` (cunzhi 不可用时: 直接输出 "[DESIGN_READY] 请确认" 等用户回复)
## R 技术调研 (Path B+)
读 design.md → 搜索相关代码 + 查库文档
产出: design.md 追加技术方案
## D 方案定稿 (Path B+)
读 design.md → 检查接口最小化? 错误处理完整? 更简单的方案?
产出: design.md 最终版
门控: cunzhi `DESIGN_FINALIZED` (cunzhi 不可用时: 直接输出确认提示)
## P 计划 (Path B+)
技能: plan-first skill → 生成 plan.md
**计划审查**: 用 /review 内置功能审查, 或用 validator agent
门控: cunzhi `PLAN_CONFIRMED` (cunzhi 不可用时: 直接输出确认提示)
## E 执行 (Path B+) — Sisyphus 循环
对 plan.md 每个 Task:
1. 读 Task + 相关文件 + conventions.md
2. TDD: 先写测试 → 实现 → 重构
2.5. **Reflexion** (自我反思 → reflexion skill):
"这个实现有没有: 走捷径/忽略边界/硬编码/过度工程/偏离 spec?"
发现问题 → 立即修复
值得记录 → lessons.md
3. **Micro-review**: 对标 design.md spec + conventions.md
通过 → [x] Task + commit
不通过 → 修复
**铁律**: plan.md 有任何 [ ] 未完成, 不停止。
## T 测试/审查 (Path B+)
1. verification skill: 跑测试 + 覆盖率
1.5. **验收标准确认**:
读 design.md "## 验收标准" → 逐条确认是否满足
未满足 → 标注到 quality.md
2. code-review skill: 代码审查
3. 用 /review 内置审查功能 做代码审查
4. 综合 → quality.md
5. Quality Gate: PASS(exit 0) / CONCERNS(exit 0+warn) / REWORK(exit 2) / FAIL(exit 2)
## V 归档 (Path B+)
1. kaizen skill: 回顾 + lessons.md
1.5. **分支收尾** (finish-branch skill):
选项: PR description / keep / discard (Codex 不直接 merge)
2. cunzhi `DELIVERY_COMPLETE` (cunzhi 不可用时: 直接输出确认提示)