Files
Cyrene_v2/AGENTS.md
T
AskaEth df8fc660c0
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled
docs(agents): §10 补铁律——提交一律逐文件 git add(实测吞过别人在途文件)
2026-10-05 11:31:24 +08:00

14 KiB
Raw Blame History

Cyrene v2 开发铁律(AGENTS.md)

本文件是项目级开发铁律,由运行环境在每次工作会话时自动注入。即使发生上下文压缩/丢失,以下约束仍会强制生效。必须遵守,违反即偏离。

1. 先读设计,再写代码

  • 动任何代码前:先读 DevDocs/开发时间线.md(当前里程碑 + §3 功能状态清单),确定这一步属于哪个里程碑/功能。
  • 具体功能实现:先读对应 DevDocs/design/*.md,按其规格实现,不得自行发挥(design/01~13 是权威设计)。

2. 按里程碑推进,不跳步、不漂移

  • 严格按 M0 → M12 顺序。每个功能的依赖与归属见时间线 §2/§3。
  • 不得「想到什么做什么」。新需求/新想法:先写入设计或时间线清单,再开发,不脱离清单。
  • 上下文压缩后:先读 DevDocs/工作小结/00-当前态.md 恢复锚点,再继续,不得凭印象跳走。

3. 每阶段审查并勾选

  • 阶段完成:后端 go build ./... + go vet ./... + go test ./... 全绿;前端 tsc --noEmit + vite build 通过。
  • 在 DevDocs/开发时间线.md §3 勾选状态:✅ 已完成 / ⚠️ 未完成/阻塞(⚠️ 必须记录原因与延后里程碑)。
  • 与 DevDocs/design/* 比对:不一致时以设计为准——先改设计文档或修正代码,不允许带着偏离堆叠。

4. 改动前确认归属

  • 修改任一文件/功能前,明确它在哪个里程碑、对应哪份 design 文档;改完同步该文档(若设计变了)。

5. 实时同步工作小结

  • 每完成一步,更新 DevDocs/工作小结/00-当前态.md:当前里程碑 / 进度 / 已完成+未完成 / 关键决策 / 变更日志。

6. 小步提交 + 频繁验证

  • 小粒度 commit;每步 build/test 通过再提交;提交信息按 Git 规范(feat/fix/refactor/docs/chore,scope 用模块名)。

7. 不信任记忆,信任清单

  • 关键决策、架构铁律、用户红线(如身份识别靠元数据、不靠提示词)都记录在 DevDocs/工作小结/00-当前态.md 的「关键决策」区;压缩后回读,不得丢失。

8. 上下文保护:可并行项交给后台子代理,主会话当监工

  • 相互独立、不依赖主会话开放状态的开发任务(如 M0 地基各件、层 1 并行件),用 Agent(run_in_background=true) 派后台子代理并行实现。
  • 主会话只当监工:等子代理回报 → 验收(go build/vet/test)→ 更新 DevDocs/工作小结/00-当前态.md + 时间线 → 小步 commit → 派下一批。不在主会话里重复子代理已做的搜索/实现。
  • 子代理 prompt 必须自包含:写清目标、已知信息、精确文件路径、必须遵守的编码约束(02-development-constraints.md)、验收命令;不要让它去搜已经知道的东西。
  • 只有真正独立才并行;有依赖的串行。避免两个子代理同时改 go.mod/go.sum——若都要改,指定其中一个负责或先把依赖拉好。
  • 目的:防主会话上下文超限触发压缩;压缩后靠本文件 + DevDocs/工作小结/00-当前态.md 恢复锚点,继续当监工。

9. 全球红线(跨里程碑,必须遵守;违反即架构偏离)

  • 单二进制、单端口 :8080、零跨进程 IPC:模块间同步走进程内接口 + 依赖注入(直接方法调用),异步走进程内 bus;不另开监听端口、不 HTTP 互调。
    • ♢ 已登记例外(主人 2026-10-04 裁决):qq-obv11 渠道的 OneBot 反连(server)模式需要独立 net.Listen 端口 —— 仅限该渠道的 server 模式,且端口必须由配置显式给出(listen_addr),不得默认开启;其余渠道/模式一律不得新开监听端口。规格见 design/08 §4、design/13 §0。
  • 身份识别靠 channel 层强类型 actor 元数据 + 策略引擎,绝不靠提示词/LLM 判断(主人/群聊/陌生人判定与权限永远由 actor 元数据 + 白名单 + policy engine 决定)。
  • 人格 = 身份(不限制能力);行为模式 = 呈现(≠边界,可热切换、不构成能力边界);能力全局全能;前端(Web)是第一公民。
  • IM 是镜像:只 chat 文本,Web 不回流 IM;输出一律 chat 文本。
  • 前端(用户端 + 管理面板)统一 Miuix 设计语言(小米 HyperOS Miuix / Miuix Console),实现须对齐六大核心(Smooth Corner/多层 Surface/弹簧动效/深色优先/毛玻璃/Liquid Glass),不混用其他 UI 语言。
  • 存储:SQLite 默认 + PG/pgvector 可选增强;配置了增强必须真实走语义/向量路径(非空壳)。
  • 工具循环上限 8 轮;任务:后台声明 / 前台 2s 转后台 / 消息队列回输出。
  • 记忆三类作用域隔离:用户习惯(全局共享)/ 角色日常(他角色只读)/ 项目(人人读写 + 项目索引分层);群聊 / 陌生人:查记忆只读不写、不入主会话上下文、不泄露主人敏感信息。
  • 敏感操作主代理代审 + 审计日志 + 前端小字(「xxx 想要干什么,我审查后批准了」)。
  • 模型:per-role 路由 + 接口报错自动降级(主→备→本地);多模态/流式。
  • 🔴 后端常驻(主人 2026-10-04 追加要求):在下一次构建产物就绪之前,正在运行的后端(cyrene.exe,:10942)不准关,除非出现恶性 Bug(进程致命错误/必须阻断的严重故障)。推论:① 禁止为「跑全树验收 / 重启清理 / 图省事」而停它——go test/go build/git 都不需要停后端;② 换二进制只允许在新产物已构建好之后一次性 restart(即「先 build 到位,再一次切换」,不得留空窗);③ 启动后端不许用前台阻塞式命令(scripts\ctrl.bat start 会守着进程不返回)——必须确认它脱离工具进程,否则工具超时会连带杀掉后端(2026-10-04 实测:TaskStop 掉阻塞包装后进程存活、PID 文件已写 757788,属脱离式启动);④ 上下文压缩/会话中断后:先探活(netstat -ano | grep 10942 + curl /api/v1/health)再决定,不要凭印象以为它停了。

9.5 学习成熟开源实现,禁止闭门造车(⚠️ 用户强制红线)

  • 已成熟的能力/模块,必须优先学习并复用现有开源项目的业务逻辑与交互范式,严禁闭门造车/按设计文档凭空推演。对照基准(按 design 主题):
    • agent 工具循环 / 工具分发 → Claude Code、OpenClaw、Cursor(工具 schema、循环上限、权限门、流式输出)
    • 子代理编排 / 隔离上下文 / 审计代审 → Claude Code 的 subagent、OpenAI Swarm、CrewAI
    • MCP → 官方 Model Context Protocol SDK(Go/Python/TS 客户端接入、工具自动发现)
    • WS 实时协议 / 流式 token → OpenAI/Anthropic 官方 SDK 的流式惯例、Claude Code 的实时事件
    • checkpoint 恢复 / 长任务持久化 → Claude Code 的 resume / Cursor 的会话恢复
    • 跨平台渠道接入(QQ/微信/Telegram) → OneBot v11、Telegram Bot API、微信 iLink 既有客户端
    • 管理面板 / 前端交互 → Miuix Console(本项目设计基准)、以及成熟 admin 面板范式
  • 实现前:先在该主题的 design 文档下补一行「开源对照」——列出参考项目 + 借鉴点(模板:## 开源对照(实现前必读))。实现时逐点对齐其成熟逻辑。
  • 若某个能力已有成熟开源实现而项目选择了自研,必须写明理由(如协议差异、单二进制约束),不得默认自研。
  • 上下文压缩后:本铁律强制生效;每个模块补全前先查 DevDocs/开源对照清单.md(集中记录各主题的参考项目与已完成对照),未对照不得开工。

10. 代码与流程硬性规范(压缩后仍需遵守)

  • 🔴 文件 ≤500 行、函数 ≤80 行;模块按职责拆成多个源文件,严禁把整个模块塞进一个超大文件;三次复制必须抽取共享。
  • 🔴 禁 interface{}(用 any)、禁包级全局变量(除 var ErrXxx)、禁裸 return err、禁魔法数字;错误一律 %w wrap;SQL 全参数化、主键 id、时间戳 created_at/updated_at、索引 idx_{table}_{col}(♢ 已登记例外(主人 2026-10-04 裁决):表名统一用复数、以既有迁移为准——本条原「表名单数」不再作为硬约束,命名口径以 DevDocs/design/13/design/16 为准);敏感信息打日志。
  • 🔴 日志必须标来源:模块/子功能用 internal/logger.WithSource/Scoped(source=module/subfeature)标注,跨模块可追溯定位;禁止无来源裸日志。
  • 🔴 客户端 API 契约先行:REST /api/v1 + WS /ws + admin /api/v1/admin/* 统一版本化契约,供跨平台客户端(Web/移动/IM bridge)接入与治理;JSON 响应 {data} / {error:{code,message}}。
  • 🔴 用户侧 API 文档随实现更新:每实现/变更一个 REST 端点、WS 事件、admin API,立即同步更新 Docs/api-client.md(用户侧跨平台客户端 API 文档),供后期原生客户端开发;契约变更版本化。
  • 🔴 .env.example 与实现同步(同一类固定动作,2026-10-04 登记为协同 E6):每新增 / 改名 / 删除一个 env 键(env:"…"、os.Getenv/LookupEnv("…")、自定义 env helper、Go const 形式的 env 名),立即同步 .env.example —— 键名必须与代码逐字一致、值一律占位符、绝不写真实凭据;已废弃但未删除的键在模板里显式标注「未接线,配了不生效」。否则照模板部署的新实例会漏配且静默失效。自查命令(代码键 ↔ 模板键,comm -23/‑13 必须只剩已说明的噪声):见 DevDocs/开发习惯与约定.md 与协同清单 E6 条目。
  • 🔴 每次模块/功能改动「前」与「后」都推仓库(用户红线,留恢复误操作余地):改动前若工作树有未推改动,先 git push origin dev 存一个干净基线;改动完成验收通过后,立即 git commit + git push origin dev 存档。绝不攒一堆改动到阶段末一次性推——坏操作可随时 git reset/rebase 到任一推过的 commit 回滚。每个模块/功能提交(或里程碑归档)后均 git push origin dev 同步远端。
  • 🔴 压测纪律(2026-10-04 实测事故,必守):子代理做负载/竞态验证时不许用无界进程风暴占机(如 yes ×30、sleep 风暴)—— 实测一次「yes 没杀干净」把 12 核占满约 15 分钟,期间所有 go build/test 近乎停滞,并把工具链误判成死锁。规矩:① 负载限核(GOMAXPROCS/单包并行/-p)或限时(几分钟级),优先用「可控对抗条件 + 注入时钟 + 门控」而不是堆进程;② 压测结束必须确认无残留进程(Get-Process yes 之类计数为 0)再出证据;③ 出现「整机变慢/命令不动」先查是不是自己刚起的压测进程,再怀疑工具链。
  • 🔴 仓库根产物卫生(2026-10-04 实测事故,必守):go build ./cmd/cyrene/... 这类单 main 包命令会把可执行文件写到当前工作目录 ⇒ 实测静默覆盖了正在用的发布产物 cyrene.exe(且不带 -ldflags "-s -w",体积 39.3 MB → 49.1 MB)。规矩:子代理一律不许跑会在仓库根产出可执行文件的构建 —— 只跑 go build ./...(多包 ⇒ 丢弃产物)、go build ./<非 main 包>/...、go vet、go test。换二进制只允许「scripts\ctrl.bat build(唯一权威构建,带 strip)+ 一次 restart」,且必须在整树验收通过之后执行(对齐「后端常驻」红线:换产物不留空窗)。
  • 🔴 等待子代理:不许用长 WaitFor 阻塞回合(主人 2026-10-04 反馈):主会话在 WaitFor 里等子代理时,主人无法给任何补充输入 —— 等于把主人锁在门外。规矩:派完就结束回合(子代理的完成通知会自动唤醒主会话);确需同回合内等,单次 WaitFor ≤ 60s,且只用于「马上就要用它的结果」;等待期间若有并行工作,先做工作再结束回合,不要空等。
  • 🔴 遇到开发文档冲突 / 意义不明 / 规格矛盾时:阻塞会话,用 AskUserQuestion 询问主人,不得自行猜测;文档清、不冲突则自主推进。
  • 🔴 阶段验证:后端 go build ./... + go vet ./... + go test ./... 全绿 + windows/darwin 交叉编译;前端(M9+)tsc --noEmit + vite build 通过。
  • 🔴 换二进制前先确认前端是否变更(2026-10-05 登记):scripts\ctrl.bat build 只跑 go build,不含前端。若本次改动触及 frontend/web/**,必须先在 frontend/web 跑 npm run build(会把 dist 拷到 internal/webui/dist),再 ctrl.bat build + 一次 restart;否则后端产物里带的是旧前端。反过来:纯前端改动不需要重启后端(运行时优先读磁盘 frontend/web/dist),刷新浏览器即可。
  • 🔴 裁定必须带完成状态(2026-10-05 登记):凡是给主人 / 给安卓端的裁定、承诺、回执,每一条都必须标注「已完成 / 在办 / 未开始」;标「已完成」须附 commit 号或验收证据,且完成后回原条目处补记「已完成 + commit」——不得只在别处口头称完成。禁止把「未验证」表述成「已修好」。
  • 🔴 提交一律逐文件 git add <显式路径>(2026-10-05 实测事故):禁止在「同一目录下有多路在途切片」时用 git add -A -- <目录> —— 实测它会把别的子代理的在途文件一起吞进提交(本次误把 237 的 sessionenv.go 提交并推了)。修复套路:git reset --soft HEAD~1 → git restore --staged <误入文件> → 重新 commit → git push --force-with-lease origin dev(工作树内容不丢)。