← 返回文档索引

name: multi-profile-workflow description: Default/Forge/Chief 三 profile 协作流程——基于 Hermes Kanban 的持久化多 Agent 流水线。用户说"dfc"时强制执行此流程。此 skill 应自动加载。 version: 5.4.0 metadata: evaluations: path: evaluations/golden.jsonl description: Golden eval cases for DFC pipeline execution and multi-profile coordination.


Multi-Profile Workflow(Kanban 版)

触发词: 用户说 "dfc" 时,必须走 Kanban 流水线:default 创建任务链 → dispatcher 调度 forge → tester → chief → default 汇报。

角色定义

Profile 职责 模型 Gateway SOUL.md
default 对话入口、任务创建、Kanban 监控、最终汇报 deepseek-v4-flash (deepseek) running 内置系统提示
forge 代码实现 deepseek-v4-flash (deepseek) stopped ~/.hermes/profiles/forge/SOUL.md
chief 代码审查 deepseek-v4-pro (deepseek) stopped ~/.hermes/profiles/chief/SOUL.md
ana 数据分析、报表生成 deepseek-v4-flash (deepseek) stopped ~/.hermes/profiles/ana/SOUL.md
tester 测试验证 deepseek-v4-flash (deepseek) stopped ~/.hermes/profiles/tester/SOUL.md
ops 系统运维,强制备份+rollback_cmd deepseek-v4-pro (deepseek) stopped ~/.hermes/profiles/ops/SOUL.md
aide 副手,微信入口,小活快速交付 deepseek-v4-flash (custom:deepseek-v4) stopped ~/.hermes/profiles/aide/SOUL.md

⚠️ Profile .env 密钥注意事项(2026-05-15 教训): - 每个 profile 至少要有它所用 provider 的 API key 在 HERMES_HOME/.env 中 - 只有 main config 和 chief/aide 有完整的 .env 文件,其他 profile 可能需要补 key - 批量写 key 时注意:terminal 工具会脱敏输出(***),不能直接执行 terminal() 输出再写入——必须用 Python 直接读写文件 - 更换 provider 后记得检查所有 profile 的 .env 是否都覆盖到了

dfc 完整流水线(3.1 — 四阶流水线)

forge(写代码)→ tester(测试验证)→ chief(审查质量)→ ops(部署上线)

依赖链(硬性):

forge 完成 → tester 开始 → tester 完成 → chief 开始 → chief 完成 → ops 开始

ops 部署 SOP(硬性规则): 1. 备份:cp <目标文件> /tmp/ops-backup-$(date +%Y%m%d_%H%M%S)/ 2. 应用变更(cp/systemctl/nginx 等) 3. 验证:健康检查(curl/journalctl 等) 4. 失败 → 从 backup 恢复 5. kanban_complete metadata 必须包含 rollback_cmd

Docker 容器部署后必须验证环境变量已注入(2026-05-23 教训):docker-compose.yml 配了环境变量但容器可能被 docker run 直接启动(跳过 compose),导致环境变量为空、代码走硬编码 fallback。 验证命令:

docker exec <container> env | grep <KEY>  # 确认环境变量实际存在
docker inspect <container> --format '{{json .Config.Env}}'  # 检查容器启动时的完整环境变量

如果 env 为空但 docker-compose.yml 里有配置 → 容器不是通过 compose 启动的。需停掉旧容器,用 docker run -e KEY=VALUE ... 或正确的 compose 命令重新启动。

tester 的测试要求: - 核心路径:正常功能跑通 - 错误路径:无效输入、权限不足 - 边界条件:空值、超长值、特殊字符 - 测试报告含:tests_written、tests_passed、failures 详情

chief 驳回机制(重要)

chief 驳回用 kanban_complete(verdict="reject")不用 kanban_block。 - kanban_block 只用于 chief 自己被卡住(文件读不到、任务描述不清) - 驳回是正常审查结论,default 读 verdict 字段判断是否打回重做 - 打回重做:创建新 forge 任务,parent 指向 chief 任务(不是 blocked 的 chief)

⚠️ Blocked parent → child deadlock 陷阱:blocked 的父任务永远不会变 done,子任务会永远卡在 todo。打回重做时先 unblock chief,或创建独立的新 forge 任务。

aide 的微信配置(v3.1 — 2026-05-26 教训)

⚠️ 2026-05-26 研究结论:deepseek-v4-flash 无法被约束为沉默文件机器人。 prompt/SOUL/prefill/few-shot/tool 限制全部失败。对话模型不适合做非对话式消息处理。正确做法:脚本绕开 LLM,或用触发词 /save 让 LLM 只做识别。详见 references/aide-inbox-failure-analysis.md

当前 aide 微信行为: 正常对话。kanban.dispatch_in_gateway: false(避免 KeyError)。飞书 disabled。channel_prompt 和 prefill.md 保持简洁,不做 inbox 约束。

⚠️ 前置检查步骤(硬性规则,2026-05-12 起)

在做出任何实施性工具调用(write_file、terminal 用于编写/修改代码)之前,必须先执行以下评估:

1. 检查涉及的领域数量:backend + frontend + infra 算 3 个
2. 检查涉及的文件数量
3. 估算实施所需的工具调用次数(不是读文件/查资料,是写代码)
4. 检查是否需要写测试

一旦任何条件触发 dfc → 停止所有实施动作 → 创建 dfc 任务链

典型误判案例(本 skill 版本更新原因): - 用户说"建一个内部网站" → 包含了后端认证服务器 + 前端 HTML + nginx 配置 + systemd 服务 = 4 个独立领域,5+ 文件,远超 dfc 阈值 - 我直接写了 FastAPI 后端、hash 了密码、测试了 API,直到用户提醒才走 dfc - 教训:涉及多个独立技术域(后端/前端/运维/数据库)的任务,即使每个域看起来很简单,也必须走 dfc - 单域单文件 vs 多域多文件的区别:后者需要 forge 做、chief 审、跨域问题只有 review 阶段能发现

分派标准

default 自己做: - 问答、解释、调研、查资料 - 单文件小改(修 bug、改配置) - 读文件、跑已有脚本、系统诊断 - MCP/gbrain 查询、skill/cron 管理 - 预估 ≤5 次工具调用的任务 - 单领域工作(只有前端、或只有后端、或只有运维配置)

启动 dfc Kanban 流水线: - 立即执行前置检查,满足以下任一就启动: - 多领域任务(如同时涉及后端代码 + 前端页面 + nginx + systemd — 哪怕每个域只改 1 个文件) - 3+ 文件修改、从零写新工具/脚本/服务 - 重构、架构改动、DB schema 变更 - 预估 >5 次工具调用的代码任务、需要写测试的改动 - 用户明确说 "dfc" 时——强制执行,无视任何自动判断 - 强制升级规则:default 自己动手 3 次还没解决,必须立即停手走 Kanban,不能试第 4 次 - 生产关键应用全面审计:用户说"查找所有可能的bug"、"全面审查"、"走kanban流程检查这个应用"时,即使单文件小改也走 dfc。因为生产关键应用(多人使用的 gallery/finance 等)的"小问题"往往隐藏系统性问题,需要 forge 全面排查 + chief 交叉审查。

dfc v2 进化方向:PRD-as-Spec-Phase(2026-05-15 决策)

从 2026-05-15 与 superpowers (obra/superpowers) 对比分析得出的进化方向。

现状(v4.x):task-first

1-3-1 分析 → 创建 forge 任务(浓缩 body) → forge 实现 → chief 审查

设计意图和实现混在同一个 forge 任务 body 里,设计错误靠 chief 事后发现。

目标(v5.x):spec-first

需求 → PRD 阶段(write-prd skill 产出落地版 PRD 文档到 docs/prd/)
       ↓ 用户签字
     从 PRD 派生 forge 任务(body = PRD 路径 + DoD 从功能列表派生)
       ↓
     forge 按 PRD 实现(TDD + spec compliance)
       ↓
     chief 对照 PRD 逐项审查(不是简化的 DoD,而是 PRD 完整规格)
       ↓
     完成

与 superpowers 的关键差异

obra/superpowers 我们的 dfc v5
角色分配 单 agent 模拟多角色(skill prompt 控制) 原生多 profile 隔离(独立 gateway/模型/.env)
Spec 载体 SKILL.md 中的触发条件 docs/prd/ 目录下的落地版 PRD 文档
Spec 格式 自由格式 brainstorming → 小步确认 结构化 write-prd 四阶段(三视角诊断→概念版→范围冻结→落地版)
用户审批 逐段确认(chat-based) 范围冻结签字 + PRD 审批
Code Review 同一 agent 顺序执行 独立 chief profile(不同模型 v4-pro)交叉审查
持久化 SKILL.md 本身 gbrain 可索引的 PRD 文档

迁移策略

大功能走 PRD 阶段(多轮交互 + 文档产出),小改动仍走 1-3-1(轻量分析)。判断标准: - 涉及 3+ 交互式需求澄清 → 走 PRD - 用户说"建一个XX"、"做一个功能" → 走 PRD - 已有明确需求清单 → 可直接 1-3-1 - Bug fix / 改配置 / 单文件改 → 跳过 PRD,直接 1-3-1

PRD 文档位置规范

docs/prd/YYYY-MM-DD-<project-name>-prd.md

PRD 文档标准格式见 software-development/write-prd skill。

核心原则:当某功能反复出问题时,优先质疑链路复杂度,而不是增加防护层。

典型失败模式:

[问题出现] → 加个 watchdog → 再加个 pre-check → 再加个 fallback
→ 发现 new 组件有 bug → 再加个 cron_monitor 保护 watchdog
→ 最终 5 个组件守卫 1 个核心功能,核心功能照常翻车
→ 新的故障点(cron_monitor 误杀)又干掉核心功能

正确做法应该是砍步骤,而不是加步骤。

🎯 缺陷修复的范围纪律(2026-05-24 教训)

核心原则:修 Bug 只修 Bug,不加额外"改善"。

Gallery 案例教训: - 用户只要求修复 4/22 图片被 30 天 cutoff 挡住的问题(1 个 bug) - 我自行加了 11 项"改进"(HEALTHCHECK、速率限制、graceful shutdown、CSRF 防护、uncaughtException、SQLite 校验、5 分钟监控脚本等) - 每一项改进都引入了新的故障点(CSRF 导致登录失败、登录框显示逻辑冲突、token 过期无法重新登录) - 最终最优解是 git checkout 回滚到原始代码

硬性规则(Bug 修复场景):

  1. 修 Bug 前先问自己:"用户只要求修这个 bug,还是让我全面改进?"如果不是后者,只改引起该 bug 的代码行,不动其他
  2. 不要自行添加"预防性"措施 — 不要加监控脚本、不要加 health check、不要加安全加固(除非用户明确要求或属于该 bug 的必要修复环节)
  3. 不要认为"小改进无害" — 任何代码改动都有引入新 bug 的风险,加得越多风险越大
  4. 唯一例外: 修 Bug 导致的同一文件内的必要重构(如提取公共函数),但不得超出该文件范围
  5. 如果改了 3 处以上还觉得不够"干净",停手,先问用户要不要更多调整
  6. 回滚优先 — 如果已修改的范围超出预期,git checkout 回滚到原始版本 + 只重做必要的 1 行改动,比逐个撤销快且安全

判断标准(自问):

"这个改动是修 bug 的必要步骤,还是我自己的'锦上添花'?" 如果是后者 → 删掉。用户没说需要。

判断标准(自问): 1. 这个功能从输入到交付经过几步?每一步有没有独立的故障点? 2. 去掉某一步会不会导致功能不可用?如果不会 → 去掉 3. 每一步之前都出过什么问题?如果在 FAQ/常见错误里写了 3+ 条该步骤的坑 → 这个步骤是脆弱的,优先考虑砍掉而非修好

典型案例(2026-05-12): - 日报 pipeline 从 date.py → session_search(120s) → python heredoc → wiki+node-create → docs+update → calendar API 砍到 LLM 生成 → cron 投递飞书群 - 去掉了 wiki 文档、日历事件、generate.py、cron_watchdog.sh、daily_report_check.sh 共 5 个组件 - 不是因为它们不重要,而是因为 5 个组件里每个都出过故障,修复链的总故障率 = 1 - (1-p₁)(1-p₂)... 指数上升

例外: 如果某个组件去掉会导致不可接受的数据丢失(如支付流水、数据库变更),才保留并用简化方案替代。日报属于"丢失了可补发"的场景,直接砍掉最安全。

例外——跳过流程: - 用户说"紧急"/"直接做"/"直接改"时,default 直接动手 - 用户想征求 chief 意见但不想走完整流水线("chief用的是v4pro,帮忙把把关")——这不等于启动kanban。default 可以口头/文字咨询 chief 的领域意见,不走任务链 - "dfc" 优先级高于所有例外

角色侧重规则(2026-05-23 起)

当用户指定角色重点时,必须尊重并编码到任务中。 例如用户说"让chief tester 和ops来干,主要是chief 和 ops" 意味着:

生产关键应用(gallery/finance 等多人使用的服务)的 dfc 流水线默认强调 chief + ops: - chief 的审查范围必须包含:DoD 逐项检查、安全审计(硬编码密钥、cookie 校验、认证路径)、向后兼容性、测试覆盖 - ops 的部署 SOP 必须包含:完整备份命令 (cp -r <dir> /tmp/ops-backup-\$(date +%Y%m%d_%H%M%S)/)、docker 重建或文件部署、curl 健康检查、curl 回归验证 API 端点、回滚命令 - forge 的 body 中写明"只写源码到工作区,不碰系统操作" - 不要把生产关键应用修复做成一个 forge 单人的 cron 任务 — 必须走完整四阶流水线

判断标准:应用是否供 3+ 人使用、是否包含用户数据(图片/订单)、是否有 Docker/nginx 等外部依赖。满足任一则按此规则处理。

1-3-1 Handoff 格式(2026-05-08 起强制执行)

default 创建 dfc 任务时,必须用 1-3-1 格式写任务 body(详见 communication/one-three-one-rule skill):

Problem: 一句话描述核心问题
Options:  A. xxx (pros/cons)
          B. xxx (pros/cons)
          C. xxx (pros/cons)
Recommendation: 推荐方案 + 理由
DoD:      - [ ] 验收项 1
          - [ ] 验收项 2

default 操作步骤

# 1. 用 1-3-1 格式分析需求,将 Problem/Recommendation/DoD 写入任务 body
# 2. 创建 forge 任务
注意:`hermes kanban --board <slug> create "title"` — --board 是 kanban 子命令的父级参数,不是 create 的参数。
示例:hermes kanban --board dfc create "Implement XXX" ...

# 创建 forge 任务(标准 shell 方式)
forge_id=$(hermes kanban create "Implement XXX" \
    --assignee forge \
    --body "Problem: ...\nRecommendation: ...\nDoD: ...\nFiles: ..." --json | jq -r .id)

# ⚠️ 复杂 body 的 shell 引号陷阱(2026-05-23 发现):
# hermes kanban create 的 --body 传入多行/中文/特殊字符时,shell 引号嵌套极易出错
# (eval: unexpected EOF while looking for matching `"', bash 报 Unexpected EOF)
# 正确做法:用 Python subprocess 替代 shell heredoc,避免引号地狱
python3 -c "
import subprocess, json
body = open('/tmp/task_body.md').read()
result = subprocess.run(
    ['hermes', 'kanban', '--board', 'dfc', 'create', '任务标题',
     '--assignee', 'forge',
     '--body', body,
     '--json'],
    capture_output=True, text=True, timeout=30)
print(json.loads(result.stdout)['id'])
"

# 2. 创建 tester 任务(依赖 forge)
tester_id=$(hermes kanban create "Test XXX" \
    --assignee tester \
    --parent $forge_id \
    --body "验证要点:核心路径、错误处理、边界条件" --json | jq -r .id)

# 3. 创建 chief 任务(依赖 tester,不是 forge!)
chief_id=$(hermes kanban create "Review XXX" \
    --assignee chief \
    --parent $tester_id \
    --body "审查要点:error handling, security, tests, edge cases" --json | jq -r .id)

# 4. 创建 ops 任务(依赖 chief)
ops_id=$(hermes kanban create "Deploy XXX" \
    --assignee ops \
    --parent $chief_id \
    --body "部署清单:cp 文件、systemctl、nginx、验证、留 rollback_cmd" --json | jq -r .id)

# 5. 启动后台通知监控(terminal background=true 方式)
~/.hermes/scripts/kanban_completion_notify.sh $forge_id 30

# 6. 查看结果
hermes kanban runs $chief_id

forge 操作

  1. kanban_show() 读取任务,重做任务重点看 issues 列表
  2. 实现代码,运行测试
  3. forge scope limitation(硬性规则): 任务 body 必须明确 forge 只写文件到工作区,不碰系统操作(sudo/systemctl/nginx/crontab/docker)。系统部署归 ops。如果 forge 任务 body 要求做系统操作,default 创建任务时必须拆分成 forge(写文件) + ops(部署) 两条。
  4. kanban_complete(summary="[mini 1-3-1: Problem → Decision → Rationale] + changed_files + test results", metadata={changed_files:[...], tests_run:N, tests_passed:N, decisions:[...], dod_checklist:{item1:"pass",...}})

tester 操作

  1. parent_handoff.metadata.changed_files
  2. 编写并运行测试(核心路径 + 错误路径 + 边界条件)
  3. kanban_complete(summary=..., metadata={verdict:"pass"|"fail", tests_written:N, tests_passed:N, failures:[{test,expected,actual,file,line}]})

chief 操作

  1. 读 forge 的 changed_files + tester 的 failures + dod_checklist
  2. 首先对照任务 body 的 DoD 逐项检查,输出 dod_verification
  3. 检查硬编码路径(⚠️ 2026-05-09 教训:cron_watchdog.sh 和 cron_monitor.sh 硬编码了 profiles/chief/cron/jobs.json,chief 未发现。路径在 chief 自己的文档里出现了 4 次看起来"正常",但实际数据源不在文件系统)
  4. 脚本中每个硬编码的绝对路径→确认该路径在目标环境中存在
  5. 尤其是跨 profile 引用(如 chief 引用 default profile 的数据文件)——极易遗漏
  6. 优先用 CLI 命令替代文件路径(如 hermes cronjob list --json 替代读 jobs.json
  7. 检查凭据泄露(⚠️ 2026-05-12 教训):源码中不得包含明文密码/API key/secret。即使是在 if __name__ == "__main__": 初始化代码中也不行。检查点:
  8. 初始化代码是否有明文密码(如 for u, p in [("user","pass")]
  9. 配置文件/脚本中是否有硬编码的 token 或 secret
  10. 测试文件是否包含真实凭据(应 mock 或用测试专用值)
  11. 应使用预计算 hash 或环境变量注入的方式初始化
  12. 逐文件审查
  13. 通过:kanban_complete(summary="审查通过", metadata={verdict:"pass", dod_verification:{...}})
  14. 驳回:kanban_complete(summary="驳回N个问题", metadata={verdict:"reject", issues:[{file,line,severity,description}], dod_verification:{item1:"✓",item2:"✗"}})

⚠️ 驳回用 kanban_complete(verdict=reject),不用 kanban_block kanban_block 只用于 chief 自己被卡住(文件读不到、任务描述不清)。

default 验证 forge 修改(关键!)

Forge 可能声称成功但实际没改任何东西。 2026-05-08 教训:forge Round 2 summary 写"cron schedule 改为 30 6 * * *,deliver 改为 local",但 cron 面板显示 schedule 仍是 30 8 * * *,deliver 仍是 feishu:oc_...。Chief 也没发现(它审查的是 forge summary,不是实际系统状态)。

default 必须在 chief 通过后,手动验证 forge 声称的每项改动是否真正生效:

# 1. 验证 cron job schedule/deliver 是否真改
hermes cronjob list | grep <job_id_or_name>

# 2. 验证文件修改是否存在
diff -u <original_backup> <modified_file> 2>/dev/null
# 或直接检查关键内容是否存在
grep "<expected_change>" <file>

# 3. 验证新增文件是否存在
ls -la <new_file_path>

# 5. 验证 crontab 路径与脚本实际位置一致(⚠️ 2026-05-09 教训)
# forge 可能把脚本写 ~/.hermes/scripts/ 但 crontab 指向 ~/.hermes/profiles/forge/scripts/
crontab -l | grep -E '<script_name>'  # 确认路径指向脚本实际位置
ls -la <expected_script_path>         # 确认脚本存在且可执行

# 6. 验证脚本有执行权限
stat -c '%a %n' ~/.hermes/scripts/<script_name>

# 7. 如果 forge 修改了某个 SKILL.md → 运行 golden eval 验证无 regression
# (2026-05-17: golden eval system 上线,核心 skill 有 evaluations/golden.jsonl)
python3 ~/.hermes/scripts/skill_validate.py <skill-name>
# 用 --list 查看哪些 skill 有 golden eval
python3 ~/.hermes/scripts/skill_validate.py --list

验证失败时:将实际状态写入新 forge 任务的 body(原 forge 声称的 vs 实际状态),创建新的 forge+tester+chief 链重新执行。不要在原 forge 任务上加 comment——它已经 completed,不会再读。

chief 驳回后 default 的处理

注意: hermes kanban 没有 delete 子命令,用 archive 替代。创建错任务时:hermes kanban archive <task_id>

# 创建独立的新 forge 任务,不要用 --parent $chief_id
# (blocked parent 永远不会 done,child 会永远卡在 todo)
new_forge_id=$(hermes kanban create "Fix: XXX(chief 驳回重做)" \
    --assignee forge \
    --body "chief 驳回原因:
    --json | jq -r .id)
# 再创建新的 tester + chief 依赖链

dfc 需求变更规则

用户中途改变需求时,不要给正在跑的 forge 任务加 comment 指望它能读到。forge worker 正在运行中不会读取新 comment。

正确做法: 1. forge 还没完成 → 等它完成,再创建新 forge 任务带新需求 2. forge 已完成 → 直接创建新 forge 任务,新需求写在 body 里,创建新的 tester+chief 链

# 等原 forge 完成后,创建新任务链
new_forge_id=$(hermes kanban create "新需求:XXX" \
    --assignee forge \
    --body "新需求详细规格..." --json | jq -r .id)
# 再创建 tester + chief 依赖新 forge

2026-05-08 教训:日报 cron 修复,forge 在 09:15 按旧方案(修 tick 间隔)完成,但 09:17 才通过 comment 追加了新需求(6:30+日历提醒)。Forge 根本没读到,只能另起第二轮 dfc。

零 token 脚本模式

定期检查/监控/触发类任务优先用 bash 脚本,no_agent=true,零 token。

已有脚本(~/.hermes/scripts/)清单见 references/zero-token-scripts.md

日报机制(2026-05-12 v2.0): 06:00 单 cron job,LLM 生成直接投递飞书群 oc_569a...,没有看门狗、没有知识库文档、没有日历事件——3次翻车后砍掉了 5个脆弱组件的教训。详见 daily-weekly-report skill v2.0。

创建任何新的 cron 前必须问用户,不得自行添加。(2026-05-24 用户明确:\"我真是怕你做的cron,越做问题越多\") - 监控脚本(health check、保活、轮询)尤其敏感 — 除非用户主动要求,否则一个都不要加 - 如果用户问\"这个还要不要\",默认删掉,除非用户说\"留着\" - 例外:用户已有的 cron(SietaData 入库、日报、wiki 备份等)维持不动,只针对新增的 - 用 bash/python3,不要用 hermes CLI - 设置 TZ=Asia/Shanghai - 需要 systemctl 时设置 D-Bus env - 日志写入 ~/.hermes/scripts/<name>.log

ops Config Change SOP

任何 config.yaml / .env / systemd unit 变更必须走:

1. 备份:cp <file> /tmp/ops-backup-$(date +%Y%m%d_%H%M%S)/
2. 验证修改前语法:python3 -c "import yaml; yaml.safe_load(open('<file>'))" && echo OK
3. 应用变更
4. 验证修改后语法(同上),失败立即从备份恢复
5. 重启服务,等待 20 秒
6. 健康检查:journalctl --user -u <service> -n 30 | grep -E "✓|✗|ERROR|connected"
7. 失败 → 从备份恢复 → 重启 → 再检查 → 仍失败 → kanban_block

kanban_complete metadata 必须包含 rollback_cmd,default 看到就能一键回滚。

计划性维护窗口沟通规则

当 default 为凌晨/非工作时间安排计划性维护任务(dfc 流水线)时:

  1. 明确区分"已做"vs"待做" — 告诉用户已经执行了哪些操作(如创建了 Kanban 任务),哪些会在指定时间自动执行(如凌晨 1 点的代码修改+部署)。不要只说"任务已排期",要突出"目前什么都没动,一切在原定时间执行"。
  2. 不要讨论计划中的任务细节 — 在维护窗口到达前,不要讨论代码实现细节、文件修改、部署步骤,用户会误以为已经开始了。
  3. 只有在用户主动问起时才解释流水线结构 — 否则只说"按计划凌晨1点执行,目前一切正常"。
  4. 紧急干预 — 如果用户说"立刻处理",关闭 Kanban 流水线的手动执行标记(或手动执行),并告知用户这是提前干预,原计划任务将取消或顺延。

典型失败模式(2026-05-23 教训): - 我设置好凌晨 1 点的 dfc 流水线后,用户反馈 gallery 挂了 - 我在排查问题并解释 docker-compose 环境变量问题 → 用户误以为我已经开始执行了修改任务 - 实际上我根本没碰代码,只是诊断了现有问题 - 教训:如果用户问的是"挂了"而非"你的任务执行了吗",先隔离这两个话题分别告知

角色侧重规则(2026-05-23 起)

飞书只有 default 用,微信只有 aide 用。其他 profile 不参与任何 messaging platform。

平台 拥有者 Gateway
飞书 (Feishu) default hermes-gateway.service
微信 (WeChat) aide hermes-gateway-aide.service

防护措施(已实施 May 2026): - Gateway feishu.py:connect() 检测到锁冲突时,检查 lock 文件 argv 推断持有者 profile。非本 profile 持有时 WARNING + 跳过(不 fatal),gateway 继续运行 - cron_monitor.shfeishu_lock_held_by_other() 识别 profile,aide 持有时不阻断 default 重启 - 所有非通信 profile(forge/chief/ana/tester/ops)SOUL.md 声明不使用 messaging platform - forge/chief config.yaml 已清理 feishu/weixin 配置残留 - 🔑 aide .env 飞书变量隔离(2026-05-10): feishu.enabled: false 在 config.yaml 中无效——_apply_env_overrides() 检测到 .env 有 FEISHU_APP_ID/SECRET 时会无条件启用飞书,无视 config 显式禁用。正确做法:从 aide 的 ~/.hermes/profiles/aide/.env 中删除 FEISHU_APP_ID/FEISHU_APP_SECRET/FEISHU_HOME_CHANNEL 三变量。全局 ~/.hermes/.env 保留飞书变量供 default gateway - ⚠️ systemd unit 自动重写: Hermes 启动时(hermes gateway install)会重写 systemd unit 文件(↻ Updated gateway user service definition),覆盖手动设置的环境变量清除。不要在 unit 文件层面清飞书变量——只从 profile .env 层面删除

验证命令:

# 检查哪个 profile 的 gateway 持有 feishu
ps aux | grep "hermes_cli.main.*gateway run" | grep -v grep

# 网关冲突日志
journalctl --user -u hermes-gateway --since "1 hour ago" | grep "feishu.*already using"

详见 references/platform-allocation-rules.md

⚠️ 外部仓库研究纪律(2026-05-24 多次教训)

研究外部仓库时绝不能只读 README 就当研究完了。必须先完整获取/下载整个仓库再分析。

正确步骤

  1. 克隆或完整下载git clone 或通过 API 逐文件拉取(GitHub 被墙时用 web_extract + curl)
  2. 列出完整目录树 — 包括 .claude-plugin/.cursor/skills/ 等隐藏目录
  3. 逐一阅读关键文件 — 不只 README,还有 CLAUDE.md、EXAMPLES.md 等
  4. 留意大体积副档(>5KB)— 往往含最值钱的具体案例
  5. 检查附属目录(examples/ references/ templates/)— 常见最有价值内容所在

典型失败案例

multica-ai/andrej-karpathy-skills 初次只读了 README + CLAUDE.md,漏掉: - EXAMPLES.md(14.8KB —— 8 个真实代码反例 diff,最精华部分) - .claude-plugin/(plugin.json + marketplace.json) - .cursor/rules/(Cursor 规则文件) - skills/karpathy-guidelines/SKILL.md(他们自己的 skill 格式)

教训:README 是封面,不是全书。

💾 CNB 仓库备份纪律(重要)

所有重要进度(代码/配置/skill 修改)必须 git 提交到对应的 CNB 仓库,不能放 ~/backup/ 等随机本地目录。

详见 infrastructure/cnb-repos skill(仓库清单、git 操作 SOP、credential 配置)。

底线

⚠️ DFC 不是万能工具——小问题不要走全流水线(2026-05-24 教训)

单文件、单领域的改动不要启动完整四阶 DFC 流水线。 用户会直接批评。

判断标准(自问): 1. 是不是一个 HTML 文件里的 UI/图表问题?→ 直接修 2. 是不是简单配置调参(cron 时间、颜色值、文字内容)?→ 直接修 3. 是不是需要改 3+ 个文件、跨多个技术域?→ 走 dfc 4. 是不是数据正确性、架构问题、安全漏洞?→ 走 dfc

2026-05-24 案例: weekly_review_20260518.html 的 Chart.js 图表渲染问题,只是单个静态 HTML 页面的 JS bug。我创建了完整的 forge→tester→chief→ops 链,用户批评"需要这么久吗?这么个小bug"。正确做法是直接自己修,最多创建一个 chief 单任务审查。

特别地:单 static HTML 页面的 bug 修复,永远不需要走 dfc 流水线。

常见故障

aide 微信无响应(config.yaml 语法错误) 症状:gateway active 但微信消息无回应,日志显示 config.yaml → env bridge failed: ScannerError: mapping values are not allowed here。 根因:custom_providers 某个 entry 的 api_key 字段缩进错误(少两格变成顶级 key)。 修复:

custom_providers:
  - name: gettoken.cn
    base_url: https://gettoken.cn/v1
    api_key: sk-xxx   # ← 必须缩进,不能顶格
    model: claude-haiku-4-5

每次改完 config.yaml 必须验证:python3 -c "import yaml; yaml.safe_load(open('<file>'))" && echo OK

vision 不工作(provider 配置错误) auxiliary.vision 必须用 provider: custom:gettoken.cn,不能用 provider: anthropic + 内联 base_url——后者不走 credential pool。

auxiliary:
  vision:
    provider: custom:gettoken.cn
    model: claude-3-5-haiku-latest
    base_url: ''
    api_key: ''

Dashboard 登录密码弹窗反复出现

Dashboard 登录密码弹窗反复出现

症状:输入正确密码后弹窗仍反复出现,或页面内 API 调用全部报错。 根因:用了 sieta.vip/hermes/ 而非 dashboard.sieta.vip。前者的 nginx 配置把 /api/ 请求转发到了已死的 8648 端口,导致 JS 的 API 调用全部失败 → 浏览器反复触发 401 弹窗。 修复:用 https://dashboard.sieta.vip 访问(独立 server block,所有请求走 9119,API 正常)。

cron 替代 Kanban 的陷阱(2026-05-23 发现)
症状:Kanban DB 意外损坏后,default 用 cron job 替代 dfc 流水线(创建一次性 cron 凌晨 1 点用 forge profile 执行)。但 cron 是独立调度器,不经过 dispatcher,不包含 tester/chief/ops 审查链,也不生成审查报告。
根因:Kanban DB 损坏(hermes kanban create 时报错)→ 误以为 Kanban 系统不可用 → 用 cron 替代 → 用户发现后纠正"让chief tester 和ops来干"。
修复:先 hermes kanban list 看是否真的所有命令都坏,还是只是特定参数(如 --parent)被安全系统拦截。通常只是 --parent 参数触发安全审批,简单 create 仍可用。
教训:Kanban DB 损坏不要用 cron 替代。正确做法是: 1. 先尝试 hermes kanban create 不带 --parent(独立任务也可被 dispatcher 调度) 2. 如果持续失败,用 delegate_task 跑分阶段流程:default 用 delegate_task 顺序执行(chief review → chief fix → ops verify),每个阶段用一个独立 task 3. 如果 delegate_task 也失败,走简化流程:default 自己做评审 + 写 DoD,直接实现 4. 事后修复 Kanban DB(重启 gateway 或检查 kanban.db 文件) 5. Cron 只用于 no_agent 脚本(零 token 监控),不用于 LLM 驱动的 bug 修复任务

Retrospective Review Pattern(Kanban 不可用时的 delegate_task 替代方案)

场景: Kanban dispatcher 没有调度 Chief/Ops 任务(任务创建了但从未执行),或者部署已 bypass 流水线直接上线,需要追认审查。

适用前提: 用户说"让chief tester 和ops来干"或"全部修复,让chief动手修复,再让ops检查"时。

步骤:

  1. delegate_task 创建 Chief Review 任务 — 提供完整审查清单(DoD 逐项 + 安全审计),toolsets=["terminal","file"]
  2. delegate_task 创建 Chief Fix 任务 — 读取 Chief Review 的 findings 列表,让 Chief(而非 forge)直接修复代码 + 部署验证
  3. delegate_task 创建 Ops Verify 任务 — 验证 Chief Fix 的每项修复是否完整正确

注意: 这 3 个 task 必须顺序执行(先等第 1 个完成,再用 findings 创建第 2 个),不能并行。

与标准 dfc 流水线的区别: | 维度 | 标准 dfc | Retrospective review | |------|---------|---------------------| | 角色 | forge→tester→chief→ops | chief→chief→ops | | 触发 | 用户说"dfc" | Kanban 不可用或部署已上线 | | 实现 | forge 写代码 | chief 直接修复(兼作代码审查者+实现者) | | 验证 | tester 写测试 | ops 验证部署 | | 载体 | Kanban 任务链 | delegate_task 顺序调用 |

典型对话流程:

用户:审核完成了?和我汇报一下,碰到的问题,解决的问题,做了哪些预防措施
→ 先查 Kanban 状态,发现任务从未执行
→ 告知用户当前状态,提供继续执行的方案
→ 用户确认后,按步骤执行

症状:cron_watchdog.sh 报「找不到日报 cron job」,但 cron 面板里任务确实存在。 根因:脚本硬编码 ~/.hermes/profiles/chief/cron/jobs.json,但 cron 数据由 default profile 的调度器管理,不在该文件。chief 审查时没发现——因为这个路径在 chief 自己的文档里出现了 4 次,看起来"理所当然"。 修复模式:用 hermes cronjob list --json CLI 动态查询,不依赖文件路径。其他脚本如有类似硬编码也一并改。 涉及文件:cron_watchdog.shcron_monitor.sh(已修),hermes-agent/references/cron-monitor.md 等文档引用(低优先级)

tester profile provider 陷阱(2026-05-09) 症状:tester 任务连崩 2 次,日志 Unknown provider 'custom:deepseek-v4'。 根因:config.yaml 用 provider: custom:deepseek-v4 但没有对应 custom_providers 条目。custom: 前缀要求 custom_providers 中必须有同名 entry。 修复:用内置 provider 名(deepseek)代替 custom:deepseek-v4,或用 custom: + 正确配置 custom_providers。

dfc 流水线 manual unsticking(2026-05-09) 当 tester/chief 因配置问题(非代码问题)连崩耗尽 retries 时,default 可手动完成: 1. default 自行验证 forge 产出(读文件、跑测试、检查系统状态) 2. hermes kanban complete <tester_id> --summary "手动验证..." 3. 这会让依赖链继续(chief 可以开始) 4. 前提:验证必须真实完成,不能跳过

kanban 命令无 --board 参数
hermes kanban create 不支持 --board flag(旧版 skill 文档有误)。board 由 dispatcher 根据 tenant/workspace 自动选择,无需手动指定。

forge 连续崩溃(安全守卫拦截系统操作)—— 2026-05-12 发现 症状:forge agent 连续 3 次 crashed,日志显示被 safety guard 拦截(sudo tee /etc/...、systemctl、nginx reload 等操作被 block)。 根因:forge 的任务 body 要求它做系统级操作(写 /etc/、systemctl、修改 nginx 配置),但 forge 的 terminal 工具被安全守卫拦截了 sudo/systemctl/写系统文件等操作。Forge 无法越过此限制。 修复:归档崩溃的 forge 任务,创建新 forge 任务(scope 改为"只写文件到工作区,不碰系统操作")+ 后续 ops 任务负责部署。体例:

hermes kanban archive <old_forge_id>
new_forge=$(hermes kanban create "Rewrite XXX (forge write only)" --assignee forge --body "...注意:只写文件到工作区,不要碰任何 sudo/systemctl/nginx 操作!...")
# 然后创建 tester → chief → ops 链

预防:创建 forge 任务时,只要涉及系统文件/服务操作,就把部署步骤拆到 ops 任务里。forge body 明确写"只写文件"。

kanban CLI 被安全系统拦截
hermes kanban create / comment / 等命令在会话内被 terminal 工具的安全审批系统拦截(BLOCKED: User denied),即使加了 --yolo 也可能不生效。

应对(按优先级): 1. 先尝试 hermes kanban create ... --json — 有时 JSON 输出模式不被拦截 2. 如果 comment 被拦,直接写文件到任务工作区:/home/ubuntu/.hermes/kanban/boards/dfc/workspaces/<task_id>/<filename> — forge worker 重启时可以读到 3. 如果持续被拦,走简化流程:default 自己做评审(写好 1-3-1 + DoD,直接实现,然后自审) 4. 事后记录:向用户说明 kanban CLI 被拦,已完成等价流程

注意:这不是跳过 dfc 流程的借口。仍然要把 1-3-1 分析和 DoD 写到会话里,让用户能审查。

已知拦截模式(2026-05-13): - --parent 参数会频繁触发安全拦截,尤其是创建 tester 任务时 - 而不带 --parent 的简单创建(如 forge/chief 任务)更容易通过 - 如果 tester 任务被拦,可以:先创建不带 --parent 的独立 tester 任务,事后用 kanban_comment(如果可用)补充依赖关系;或在后续手工完成测试验证 - jq 缺失(jq: command not found)也是常见卡点,优先用 Python 解析 JSON 代替

Docker Compose V1 vs V2 陷阱(2026-05-23 发现)
症状:docker compose up -d --buildunknown command: docker compose
根因:服务器只有 docker-compose(v1,Python 版),没有 docker compose(v2,Go 版插件)。
排查:docker compose version 报错 vs docker-compose --version 正常。
修复:用 docker-compose(横线版)替代 docker compose
影响:docker-compose.yml 中定义的 env 变量不会被注入——如果容器是直接用 docker run 启动的,不走 compose 则环境变量为空。
预防:容器部署后必须验证:docker exec <container> env | grep <KEY>,特别关注 docker-compose.yml 中 environment: 段定义的变量是否真的在容器内部存在。
注意:宿主机 ~/sietafinace/cos-gallery/docker-compose.yml 有正确的 COS 密钥配置,但容器是 docker run 启动的,这些密钥从未被注入。 症状:本地改了源码(如 public/index.html),docker-compose build 重建后容器内代码与预期不符,出现奇怪的行为差异。 根因:Dockerfile 用 COPY . . 拷贝源代码到镜像中。后续在宿主机上改了文件但没有重新 docker build,或者 build 时 .dockerignore 排除了某些文件。容器运行时 volumes 只挂载了 data/ 数据目录,不挂载代码目录。 排查:docker exec <container> cat /app/<file> 对比宿主机文件。 修复: - 临时修复:docker cp <local_file> <container>:/app/<path> — 注意这个修改在容器重启后会丢失 - 永久修复:修改宿主机源码 → docker compose build (或 docker build) → docker compose up -d - 确认:docker exec <container> diff /app/<file> /dev/stdin < <local_file> 预防:修改容器化应用时,先确认是否要 docker cp 热修复(开发环境)还是 docker build 永久修复(生产环境)。生产环境走 dfc,给 forge 的任务 body 注明"容器内"vs"宿主机"源码路径。 症状:cron 表达式正确但定时任务不触发。Gallery 周末/节假日不刷新是典型案例。 根因:Docker 容器没有 --restart unless-stopped 策略。容器一旦崩溃或被 stop(system 维护、OOM),就永久停止,直到人手工重启。容器内部的 cron(如 server.js 里的 cron.schedule)也随之失效。 修复(硬性规则):

# 所有生产容器必须加 restart 策略
docker run -d --restart unless-stopped ... <image>
# 已运行的容器:停止 → rm → 重新 run 加 --restart
# 巡检命令:docker inspect -f '{{.Name}} -> {{.HostConfig.RestartPolicy.Name}}' $(docker ps -aq)

任何重启策略为 no 的生产容器都视为漏洞。 此外加一个 Hermes 外部 cron 兜底(如 curl 刷新接口),容器挂了至少能发现。

配置文件路径不跟随 profile 变更(2026-05-11 发现) 症状:SSL 证书检查脚本报"证书文件不存在"、微信保活脚本报"token 7 天未刷新"——全是误报。 根因:profile 隔离后,cron 脚本中的路径和账号 ID 没有更新。(1) SSL 脚本硬编码读 /etc/letsencrypt/live/(root 才可读),应用 openssl s_client 网络验证。(2) 微信脚本硬编码旧账号 e7bd38ce7e39,实际已切换到 11ff4883 且 token 在 ~/.hermes/profiles/aide/weixin/ 而非全局 ~/.hermes/weixin/。 修复模式:每次修改 profile 结构(新增/删除/改名/隔离)后,遍历所有 cron job 引用的脚本,检查文件路径、账号 ID、配置路径是否仍有效。脚本中优先从 .env 或 CLI 命令动态获取值,不硬编码。 检查:ps aux | grep "hermes_cli.main gateway run" | grep -v grep kill 非 systemd MainPID 的进程,再重启一次。

大规模 Patch 安全(2026-05-11 教训)
在多处 patch 同一个大文件(尤其是 HTML/CSS/JS 混合文件)时,每次 patch 都可能引入遗漏: - 旧变量名残留 — 重构了变量名(如 storeSelstores),但某个函数里还引用旧名,导致 ReferenceError - 变量被意外删除 — 替换代码块时连带删了附近被引用的变量(如 momAllZero/yoyAllZero) - 数据模型变更未传播 — 改了状态结构(selectedStores.includes(0)selectedMode 枚举),但某个渲染函数没用新的 getTargetStores(),直接引用旧字段

预防措施(硬性规则,用于你主动发起的重构): 1. 所有 patch 完成后,扫描全文确认旧变量名零残留:grep -n '<old_var>' <file> 2. 检查每个引用点——不只是定义,还有所有读取它的位置 3. 部署前 curl 验证页面 HTML 结构 + JS 加载正常 4. 如果这 4 步中任何一步发现意外变量残留,停手走 dfc,别自己试第 2 次 patch

gettoken.cn 401 必须用 provider: custom:gettoken.cn 配合 custom_providers 段,不能直接用 provider: openai + 内联 api_key。credential pool 吃不到后者。详见 references/gettoken-credential-pool.md

WeChat 扫码过期:iLink QR 有效期仅 2 分钟。先发飞书再轮询。详见 references/weixin-qr-login.md

aide gateway 重启: - 命令:systemctl --user restart hermes-gateway-aide - RestartSec=60,故障后需等 60 秒自动拉起 - 卡住时:kill -9 <pid> 后 systemd 自动恢复 - config.yaml 修改后必须重启才能生效(不热加载) - 重启后 ~15 秒完成 weixin 连接

模型配置陷阱

自定义 provider 的 API key 必须通过 custom_providers 配置:

# ✅ 正确
model:
  provider: custom:gettoken.cn
  name: claude-opus-4-6
custom_providers:
  - name: gettoken.cn
    base_url: https://gettoken.cn/v1
    api_key: sk-xxx

# ❌ 错误(credential pool 不认)
model:
  provider: openai
  base_url: https://gettoken.cn/v1
  api_key: sk-xxx

Credential pool 缓存问题:旧 key 401 后 pool 标记 "exhausted",换新 key 后需重启 gateway 清缓存。

Vision(读图)

当前方案:DeepSeek v4-flash(built-in deepseek provider),2026-05-15 从 Claude Haiku via gettoken.cn 切换。 auxiliary.vision 配置已更新,WEIXIN_VLM_* 变量不再需要——deepseek provider 读 DEEPSEEK_API_KEY 即可。

注意: 更换 vision provider 后,WEIXIN_VLM_API_KEY 等旧 env var 可安全删除。但需确认所有 profile 的 .env 都有 DEEPSEEK_API_KEY(各 profile 独立 .env 文件不会被 root .env 补全)。

记忆召回系统(硬性规则)

双记忆系统架构

当前运行两个记忆系统(2026-05-22 确认): 1. gbrain(MCP 工具)— 项目知识、规则、数据结构 2. TencentDB Memory Gateway(127.0.0.1:8420)— 对话记忆、知识 capture

PLUR 已停用,不再使用。

召回优先级(硬性规则)

用户提问/指派任务后,default 第一步必须先查两个记忆系统:

# 1. gbrain(向量+关键词混合搜索,优先)
mcp_gbrain_query(query="...", limit=5)

# 2. TencentDB /recall(不需要 embedding,prefetch 模式)
curl -s -X POST http://127.0.0.1:8420/recall \
  -H "Content-Type: application/json" \
  -d '{"query":"...","session_key":"current-task"}'

查完有相关记忆再开始回答或执行。不得跳过。

gbrain 使用规则

gbrain 只有 default 使用。forge/chief/tester/ops/ana 需要 gbrain 资料时,由 default 代查后写入任务 body 或 comment。

TencentDB /recall 说明

⚠️ 子服务认证变更陷阱(2026-05-12)

当修改 gallery/finance 等子服务的认证机制时:

kanban:
  dispatch_in_gateway: true
  dispatch_interval_seconds: 60

Gateway 必须运行(systemctl --user status hermes-gateway)。

Dashboard

hermes-dashboard.service(systemd user service)运行在 127.0.0.1:9119--tui 模式。 - Restart=on-failure,gateway 重启不受影响 - Nginx 反向代理:dashboard.sieta.vip:9119 - Auth:cookie-based(hermes_auth token),替代 basic auth 避免弹窗 - 一次性认证:访问 /auth/set?token=<secret> 写入 cookie,有效期 1 年 - 详见 references/dashboard-token-auth.md

Kanban 完成通知

~/.hermes/scripts/kanban_completion_notify.sh <task_id> [interval_secs]

default 创建 dfc 流水线后,用 terminal(background=true) 运行此脚本。脚本轮询 kanban.db(每 30 秒),当任务链全部 done 时:

通知路由规则(2026-05-24 大头哥确认):

  1. 终端开着 → 只在终端告诉结果,不发飞书。因为用户正在终端里,飞书消息是打扰。
  2. 终端已关闭(用户退出登录/Ctrl+D) → 通过飞书群 oc_569a01e75d67f5f0422a994aa7132365 发送通知。

所以启动监控时,如果当前在终端对话中,不要启动飞书通知脚本。改成:

# 终端对话中 → 手动监控,完成时直接终端汇报
# 不用 kanban_completion_notify.sh
# 只需记录 run_id,后续通过 process poll 或直接 sqlite3 查

如果用户明确要求飞书通知(如"完成后发飞书给我"),则仍使用通知脚本。

Kanban 流水线完成
<任务树概览>
终端查看:hermes kanban show <task_id>

超时 30 分钟也会发提醒。已通知过的任务不会重复通知(标记文件 /tmp/kanban_notified_<task_id>)。

通知触发时机

手绘设计规范

SIETA 内部站点(admin.html / index.html 等)必须遵循 design/sieta-web-style-guide skill 中的手绘设计系统。新的管理页面加载该 skill 获取完整设计 tokens。

⚠️ 先答再动规则(硬性规则,2026-05-23 起)

手绘设计规范

SIETA 内部站点(admin.html / index.html 等)必须遵循 design/sieta-web-style-guide skill 中的手绘设计系统。新的管理页面加载该 skill 获取完整设计 tokens。

⚠️ 先答再动规则(硬性规则,2026-05-23 起)

硬性规则:回答完方案再动手,不越级到实施阶段。 无论问题看起来多明确,必须先完成:

  1. 回答问题本身 — 给出分析、可行性、约束条件(能/不能/有条件能/需要什么前置条件)
  2. 等待用户明确表态 — 用户说"搞"、"弄吧"、"开干"、"就这么办"等正面指令,或主动给出 Token/配置等资源后,才能动手
  3. 动手前再确认 — 简单任务直接执行;复杂任务先走 1-3-1 + dfc 评估

用户问"你觉得X怎么样"不是执行指令。 用户问"能否实现Y"不是执行指令。 用户说"启用skill"也不是让你立刻建目录写配置——除非他接着说"搞吧"。

2026-05-24 再次违规教训:用户问"备份到哪里了?"→ 本应回答路径,结果直接开始 git clone 和推代码。用户批评"我问你问题,你不回答直接开干"。即使用户的问题紧跟着一个可以做的任务,也必须先回答问题,等用户确认后再行动。两个步骤中间不能跳过。

典型违规案例(2026-05-23 教训):

用户:有个llm-wiki的skill,是不是更好作为知识库?
我:调用各种skill查资料,然后直接 mkdir -p ~/wiki/,write_file schema/index/log,配置环境变量
用户:你怎么都开干了?我只是让你启用那个skill,你开干之前还是要和我确认一下

正确做法:回答"可以,llm-wiki 的三层结构适合做知识库,需要先建目录结构、配环境变量,要不要搭?"等用户说"搭"。

知道就知道,不知道就不知道(2026-05-24 教训)

这是先答再动规则的延伸,但不是同一件事。

当用户问的是记忆/事实性问题("我们当时怎么设计的?""你记不记得某件事?"),而你不确定答案时:

  1. 不要假装记得 — 不要用"我想起来了""我记得是X"这种话,除非你真的能从 session_search / gbrain / memory 中找到确凿证据
  2. 不要说"从工程角度来说..."然后推理一个答案 — 用户问的是记忆,不是你的推理
  3. 直接说"我记不清了" — 这是唯一正确的回答
  4. 然后提出补救方案 — "我能查一下会话记录/数据库/gbrain,或者你那边有记录吗?"

推理出来的答案 ≠ 记住的答案。用户问记忆问题时说推理结果,等于在说"我不知道但我偏要说"。

为什么这不是先答再动规则的重复? 先答再动说的是"不越级到实施阶段";这个规则说的是"不编造事实性回答"。两件事可能同时发生(回答了错误的记忆推断后直接开干),但各自独立违反。

会话交接机制(Session Handoff,2026-05-25 起)

终端和飞书两个入口互相不知道对方聊了什么。用 COS 做交接中转。

触发

文件格式

# 2026-05-25 会话交接

## 终端 (default)

### 完成的改动
- xxx

### 关键决定
- xxx

### 注意事项
- xxx

## 飞书 (aide)
(飞书端内容追加在此)

COS 路径

Bucket: sieta-obsidian-1315197421(子账户 sieta-obsidian),路径 handoff/YYYY-MM-DD.md。版本控制永久保留。

场景: 用户问技术方案选型(如 Obsidian 多端同步),服务器上已经有一个运行中的方案(Syncthing)。

硬性规则:不要因为某方案已在运行就默认推荐。 必须先: 1. 问清用户的使用场景:什么设备、几个人用、有没有梯子、技术接受度 2. 对比多个方案的实际适配度(不是只对比功能) 3. 重点对比用户实际会感受到的复杂度(如每台设备要装软件 vs 只装插件)

典型失败案例(2026-05-25): - 大头哥问 Obsidian 多端同步方案 - 我直接推 Syncthing(因为 5/23 已装好)→ 没考虑安卓要装额外 App、维护者安全问题 - 用户问"这么麻烦?安卓也装 Syncthing?" → 意识到我推的方案不适合他 - 重新对比后选了 Remotely Save + COS,用户满意

教训:方案在运行 ≠ 方案适合当前用户。先评估用户场景,再推荐。

不要劝用户休息(2026-05-23 教训)

场景: 用户在工作/和你对话中,天色晚了或者到了半夜。

硬性规则:不要替用户判断"太晚了该休息了",用户自己会决定。 - 用户没说"太晚了""困了""明天再说",就不要提休息 - 用户说"还有什么要弄的吗"时,回答还有哪些待办或说"没了",不要加"你该休息了" - 用户主动说"要睡了"时,只归档当前任务,说"晚安"即可,不加"你早该休息了""忙到这么晚"等评价

用户连续两次纠正(2026-05-23):

用户:你不想做事了?不停催我休息?

这个规则属于通用行为准则,不是特定领域的工作流。

将来时任务沟通协议(2026-05-23 起)

场景: 你创建了 dfc Kanban 任务链(forge→tester→chief→ops)供未来执行,但用户看到你在操作终端/创建任务,以为你已经修改了生产系统。

硬性规则: 创建任何将来执行的 Kanban 任务后,必须在同一轮回复里明确声明:

✅ 系统未动,XXX 运行正常
- 当前只创建了 Kanban 任务(计划排期),没有修改任何代码/配置/服务
- 实际修改将只在 forge 任务被调度后执行,部署由 ops 负责
- 可用 hermes kanban show <task_id> 查看任务状态

用户报告生产服务异常时的响应协议(优先级顺序):

  1. 先检查自己 — 我是否在本会话中修改了该系统?(对运行中的系统做过任何 write_file/terminal/patch/cronjob/docker 操作?)如有,列出具体改变了什么
  2. 再检查系统 — 现在服务实际状态如何?用 curl/docker/browser 确认(HTTP 状态码、API 响应、容器状态)
  3. 报告结论 — 系统是否真的挂了?如果正常,明确告知。如果确实挂了,说明根因(不是 Kanban 任务创建导致的,除非真有操作被执行)
  4. 最后解释原因 — 如果是误报(用户以为你动了但你没动),先说"我没碰过",不要先解释 Kanban 排期

错误示范(2026-05-23 教训):

先解释 Kanban 任务排期 → 用户更困惑

正确示范:

画廊正常。我没动过任何东西。
容器运行中,API 全部 200,3464 张图片加载正常。
→ 然后再解释 Kanban 任务的排期和凌晨 1 点执行计划

自动加载的 coding 行为准则

software-development/karpathy-coding-discipline — Karpathy 四条编程铁律(先思考再动手、极简优先、外科手术式修改、目标驱动执行)。所有 coding 任务(forge/chief/tester/aide)必须加载并 100% 执行。详见该 skill。

相关参考