games-development-ai/.agents/rules/engineering-conventions.md
zizi ebb994b155 docs(conventions): §10.5 立 canonical 活档约定 + knowledge 加 canonical 指针
§10.5(补 §10.4 子系统粒度落地):canonical 活档=无日期主题名子系统SoT,与§10.1 dated命名词表互补;
dated spec 波次收口折进对应 canonical;分层 canonical>knowledge速查>architecture基线>总账状态(不双写)。
product-and-architecture 加子系统 canonical 指针(知识层→canonical 接线)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 14:14:11 +00:00

25 KiB
Raw Blame History

工程编码与协作硬规范

本文是造梦AI 全栈工程师 / 前端 / AI 工程师 / QA 必须遵守的硬规则。违反即不通过 review。 蒸馏来源:docs/architecture/系统概要设计-开发团队版.md(§4 编码 / §5 Git / §6 联调 / §7 测试 / §11 Checklist)、docs/architecture/系统概要设计-技术决策版.md(§7.6-7.8 工程治理)、docs/superpowers/specs/mvp-execution-spec-design.md(§8 技术约束)。 配套:可靠性/安全红线见 security-and-reliability.md;元流程见 ../workflows/ai-development-protocol.md;事实蓝图见 ../knowledge/product-and-architecture.md;模块落地手册见 ../skills/add-business-module.md。


1. 后端(Java)编码规范

规则 硬要求
包命名 com.wanxiang.huijing.game.module.{模块}.{层},如 com.wanxiang.huijing.game.module.aigc.service。模块名小写,与 game-module-{模块} 一致
类命名 后缀严格统一:XxxController / XxxService+XxxServiceImpl / XxxMapper / XxxDO / XxxVO / XxxDTO
异常处理 业务异常一律 throw exception(错误码枚举)(Huijing ServiceException),禁止裸抛 RuntimeException、禁止吞异常返回 null
日志 类上 @Slf4j;关键链路成功 INFO、失败 ERROR,错误日志必须含 trace_id 与关键业务 ID(如 taskId/versionId)
注释 类注释 +复杂方法注释 +字段注释,一律简体中文;对外接口、错误路径、补偿逻辑必须有注释
事务 @Transactional 只加在 Service 层,范围尽量小;事务内禁止远程调用(Feign/HTTP/MQ 发送放事务提交后)

1.1 DO / VO / DTO 分层语义(不可混用)

类型 定位 所在包 约束
DO 数据库映射对象,字段与表一一对应 -server 的 dal/dataobject 不出现在 Controller 出入参;不做业务组合
VO 视图对象,面向前端,可裁剪/组合 -server 的 controller/.../vo 仅 Controller 层使用;分 ReqVO/RespVO
DTO 模块间传输对象(Feign 契约) -api 包 跨模块共享,消费方引用 -api,不得引用对方 -server

1.2 SQL 规范

  • 禁止 select *,必须显式列出字段。
  • 大表查询必须命中索引;WHERE/ORDER BY/JOIN 字段需有对应索引,新查询要确认执行计划。
  • 分页用游标或 LIMIT;禁止深分页 LIMIT 100000,20 这类全表扫描。
  • 复杂查询走 MyBatis XML,简单 CRUD 用 MyBatis-Plus。
  • JSON 列写入:映射 MySQL json 列的 DO 字段必须存合法 JSON 文本——用 JsonUtils.toJsonString(obj) 序列化,严禁 Map/对象.toString()(产出 {k=v} 非合法 JSON,MySQL 抛 Invalid JSON text 致整批事务回滚)。⚠️ 单测 mock mapper 测不到此约束,须靠集成测试(Testcontainers)或 staging 实测兜底(B2 实测教训)。
  • CJK 写入连接字符集:用 mysql 客户端 / docker exec mysql 灌含中文的 SQL(种子/修数据)必须带 --default-character-set=utf8mb4,否则 UTF-8 字节被按 latin1 解析→双重编码存入 utf8mb4 列→读出/接口返回乱码(HEX 表现为 C3A5.. 而非 E5B08F=「小」)。前端/接口看似乱码 bug,实为灌数环节编码错(B2′ 实测,浏览器渲染才暴露)。
  • feed/stream 消费红线:参数名是 size(单页上限 30,超出 400「单页条数不能超过 30」;传错参数名如 count 不报错只回默认 10 条,极易误判卡数);nextCursor 当前为骨架占位(恒空串,FeedServiceImpl TODO),翻页续接未实现——程序化全量核对用 size=30 单页或自实现探测翻页(batch-001 postcheck 误熔断实测教训)。
  • runtime manifest 取包场景参数:/app-api/runtime/package/{vid} 与 .../manifest 两端点 scene 缺省 play(仅放行 status=1 已发布包)——预览未发布包必须显式 ?scene=preview,裸 GET 拿到的是错误 envelope(HTTP 200+code 1102001002),宿主/脚本对其算 sha256 必败误判 demo 兜底(部署窗口冒烟⑥实测;后端 manifestUrl 已按请求 scene 拼参 9517f4e)。
  • 可开关组件禁组件扫描:huijing 单体里 MQ 消费者自动配置自带全局 @EnableScheduling(无条件装配)——任何「配置开关控制启停」的 @Scheduled 组件必须只经 @Bean 方法注册(配置类上挂 @ConditionalOnProperty),类上禁 @Component/@Service,否则组件扫描使开关失效、回滚开关形同虚设(M-b spec 核验实证)。
  • ON DUPLICATE KEY UPDATE 与租户拦截器:原生 @Insert ... ON DUPLICATE KEY UPDATE 列=列+#{增量} 经 MyBatis-Plus 租户拦截器(jsqlparser)运行期改写实证兼容(staging 断言通过 b87511b);注意 wrapper 式 CAS update 不触发 MP 字段自动填充,时间戳依赖列上 ON UPDATE CURRENT_TIMESTAMP。
  • 非 Web 线程写库必须注入系统身份:@Scheduled/job/MQ 消费线程无登录态 → DefaultDBFieldHandler.updateFill 不填 updater,而 MP fill=INSERT_UPDATE 字段无条件进 UPDATE SET(null 直出)→ 表 updater NOT NULL 拒绝 → 主链与补偿写共用 updateById 同死、任务卡死无终态(M-b 冒烟实证,Mockito 测不到)。修法=线程边界注入系统 LoginUser(id=0)+finally clearContext(范本 AigcGenerateExecutor.executeWithSystemIdentity);同款雷潜伏 SettlementJob 等一切非 Web 写路径,启用前必须带上。
  • staging 前端构建必须 --mode staging:mini-desktop 的 vite preview 直接 serve 工作树 dist——任何人跑默认 npm run build 即事实上改部署(缺 staging env → mock 中间件接管 → 宿主静默 demo 兜底且 2b 分支无 warn,M-b② 验证构建实翻车一次)。在 mini-desktop 构建 game-studio 一律 npm run build -- --mode staging。
  • 匿名(@PermitAll)写路径=非 Web 线程同款审计列雷:匿名 HTTP 请求无登录态,与调度线程同根——上一条的全部结论适用(鉴权波 e2e 实证:匿名会话/遥测/注册/ad 计费四链全断 500)。修法同款=入口注入系统身份 LoginUser(id=0)+finally clearContext(Web 线程版范本 EventIngestServiceImpl.injectSystemIdentityIfAnonymous),单写点可 DO 显式 setCreator/setUpdater("0") 兜底;「MP 会跳过 null 字段」的静态推断在 huijing fill 体系下不成立(markAggregated UPDATE SET updater=null 运行时证伪),凡 DB 写过的链路必须部署后实测。新增 ALTER 放宽业务列时必须同查继承审计列(V11 漏 creator/updater 即此雷)。
  • 契约事件登记须同步后端枚举守门人:contracts/events.schema.json eventRegistry 只是文档源,TelemetryEventEnum 才是上报通道真守门人——只改契约不改枚举=事件被静默 rejected(accepted:0 信封仍 code:0,极难发现;鉴权波 user_login e2e 实证)。新增事件=契约+枚举两处同步,缺一即断。
  • 重打包必须 clean+产物内嵌核验:mvn -pl huijing-server package 增量模式会秒级"SUCCESS"但不重建 fat jar(旧 BOOT-INF/lib 原样)——部署级构建一律 clean install 联合反应堆(改动模块+huijing-server 同 -pl),部署前 unzip -p fat.jar BOOT-INF/lib/<模块>*.jar | strings | grep 新符号 核验产物(鉴权波部署 #3 实测假成功一次;注意 telemetry 等模块产物为定制 finalName 无版本号)。核验符号优先取 ASCII(类名/方法名/英文常量)——strings\|grep 中文字面量 因多字节 UTF-8 提取不可靠会假阴性,中文符号改用 curl 运行时实证或 javap -c -p 常量池(Wave4 分享OG修实测:jar 内确含「我在绘境AI玩」字面量但 strings\|grep 绘境AI玩 返 0,curl 拿到真 ogDescription 才证修复已入 jar)。
  • 重启脚本与含 jar 名的命令必须拆 ssh 会话:start-app.sh 内 pkill -f "huijing-server.jar" 会击杀 cmdline 含同串的承载 shell 本身(远程 bash -c 的命令文本计入匹配)——部署拷贝(含 jar 路径)与重启调用分两次 ssh;进程匹配宁用窄模式 pkill -f 'java .*huijing-server.jar'(鉴权波两例实证:e2e E9 代理+主 agent 部署 #2 各中一次)。
  • mini-desktop 跑 huijing-module-system 测试必须改嵌入式 Redis 端口:宿主 16379 已被 staging redis 容器占用且带密码,而 huijing 测试基座 RedisTestConfiguration 起嵌入式 RedisServer 失败被 catch(ignore) 吞掉 → 测试静默连上真 Redis 报 NOAUTH。跑 system-server(或任何 BaseDbAndRedisUnitTest)一律 SPRING_DATA_REDIS_PORT=26379 mvn test ...(环境变量可穿透 surefire fork;鉴权波构建门实证 8 测假红→改口全绿)。
  • v-for 内模板 ref 是数组:Vue 3 对 v-for 内部的模板 ref 填充【数组】而非元素——即使只渲染 1 个;按元素直读 .contentWindow 类属性得 undefined 且 TS 类型声明不报(声明可以撒谎)。取用必须显式 Array.isArray 解包(范本 GamePlayer.currentIframe())。此雷曾致 HostBridge.targetWindow=undefined、host→game 全方向静默断(storage/ad/pay 回包+init),穿过两个波次五级门未现形(2026-06-11 回包链路专项修实证)。
  • 跨边界出口的静默降级必须配挂接时刻告警:fire-and-forget 出口(如 bridge.post 的 if (!win) return)静默丢弃是稳定性正确姿势,但出口哑火必须在挂接/初始化时刻打一次 console.warn,否则断链不可观测(同上实证:回包断链唯一症状=5s 超时兜底,无任何日志)。
  • 「从未有人消费过的方向」不算被验证过:双向信道只押单向门禁=另一方向可能自建成起即断(host→game 即此例——iframe 自启动兜底掩盖 init 丢失)。新增首个反向消费者前,先跑双边探针 orchestrator/probe_bridge_channel.py(四锚点:CALL/RECV × TOP/SUB,常备诊断件)。

1.3 错误码分配(每模块独占一段,禁止冲突)

错误码格式 1-{模块段}-{业务}-{细分},各模块独占一段:

段 模块 段 模块
1-001-***-*** system 1-104-***-***(推断顺延) telemetry
1-002-***-*** infra 1-105-***-***(推断顺延) pay
1-100-***-*** project 1-106-***-***(推断顺延) trade
1-101-***-*** aigc 1-107-***-***(推断顺延) community
1-102-***-*** runtime 1-108-***-***(推断顺延) ip
1-103-***-*** feed 1-109-***-***(推断顺延) compliance
1-002-***-*** 之后 bpm 等 Huijing 原生沿用 Huijing 既有段 1-110 / 1-111-***-***(推断顺延) biz / ad

源档明确给出 system/infra/project/aigc/runtime/feed 六段;其余模块按"每模块一段顺延"规则分配(推断),新增模块时在 -api 的错误码常量类登记,避免与既有段重叠。


2. 前端(TypeScript / Vue)编码规范

规则 硬要求
组件命名 PascalCase 单文件组件,如 GameContainer.vue
API 文件 按模块一个文件(api/game/project.ts);函数名 = {HTTP方法}{资源}{动作},如 getProjectList / postProjectPublish
状态管理 Pinia,按业务域拆 store(一个域一个 store,禁止 god store)
样式 game-admin 用 Element Plus 变量;game-studio 用 Vant + CSS Variables(移动优先,适配 360-430px)
类型 严格 TypeScript,禁止 any(必须用时注释说明充分理由)
请求 统一使用封装的 request 实例,自动处理 Token 注入 / Refresh 刷新 / 错误提示;禁止裸 fetch/axios

admin 二开:新页面放 views/wanxiang/、API 放 api/wanxiang/(仓内实际目录,2026-06-10 审计校正;旧档所写 views/game/ 已废),复用 Huijing CRUD 组件(XTable/XForm/Dialog),不改 Huijing 原生 views。


3. SDK(WanxiangGameSDK,TypeScript)编码规范

规则 硬要求
零依赖 SDK 不引入任何第三方库
体积预算 Core(Lifecycle+EventBus+Telemetry+ErrorTrack)压缩后 < 8KB;每个 Plugin < 5KB(Ad<5 / Pay<3 / Social<4 / Storage<2 / Debug<15,仅 dev);首屏只加载 Core
异步安全 所有对外 API 不返回 Promise(fire-and-forget),零同步等待,不占游戏主线程
错误隔离 每个 Plugin 内部 try-catch,异常绝不向游戏抛;游戏主循环(requestAnimationFrame)永不被 SDK 阻塞
版本兼容 新版本只增字段/方法,不删不改已有签名;semver 管理,manifest 记录版本号

SDK 降级铁律与合规定位(同意即可用/未成年保护)属可靠性红线,详见 security-and-reliability.md。


4. API 路径与端鉴权规范

/app-api/**    → 产品端接口(game-studio 调用),需要用户 Token
/admin-api/**  → 管理后台接口(game-admin 调用),需要管理员权限

端前缀 /app-api·/admin-api 沿用 huijing 默认,由框架(HuijingWebAutoConfiguration + WebProperties)按 **.controller.app.**·**.controller.admin.** 包名自动添加;Controller 内 @RequestMapping 只写 /{模块},不含端前缀。

URL 格式:/{端前缀}/{模块}/{资源}/{动作}。示例(左列为含前缀的最终对外路径):

方法 + 路径 含义
POST /app-api/aigc/generate 创作者发起生成
GET /app-api/feed/list 游戏流列表
POST /app-api/feed/interaction 点赞/收藏
GET /app-api/project/my 我的项目
POST /admin-api/project/review 审核操作
GET /admin-api/telemetry/dashboard 运营看板

权限在网关 +注解双重校验;/app-api/** 走用户 Token + DataPermission(创作者只见自己数据),/admin-api/** 走 RBAC。前端不可作为唯一边界,详见 security-and-reliability.md。


5. API 契约与版本管理

维度 规则
URL 版本 URL Path 版本 /api/v1/...,大版本不兼容才升 v2
兼容判定 新增字段不算 breaking;删除/重命名字段 = 新版本
并行期 新版本上线后,旧版本保留 ≥ 3 个月;废弃用 Header Deprecation: true + Sunset: <date>
服务间契约 每个模块 -api 包声明 Feign 接口 + DTO,消费方引用该包;API 变更必须在 PR 描述标注受影响的消费方
契约对齐 后端先写 -api 的 VO/DTO,前端据此定义 TS 类型;联调前锁定契约(见 ../skills/contract-first-development.md)

5.1 事件 Schema 版本(telemetry / MQ 事件)

规则 说明
带版本号 每个事件类型带 schema_version(如 game_play_start.v2)
向后兼容 新增字段给默认值;老消费者忽略未知字段
不兼容变更 用新事件名(如 game_play_start_v3),新老并行消费直到老版本下线

6. Git 协作规范

6.1 分支策略

main          ← 始终可部署,保护分支(禁直推)
  └── develop ← 集成分支,CI 通过才能合入
       ├── feature/{module}-{brief}   ← 功能开发(MVP 期可用 feature/{ws}-{module}-{brief})
       ├── fix/{module}-{brief}       ← Bug 修复
       └── release/x.y.z              ← 发版(冻结后只修 bug)

6.2 Commit 规范(Conventional Commits)

<type>(<scope>): <subject>
type:    feat / fix / refactor / docs / test / chore / perf
scope:   模块名(aigc / project / feed / studio / admin / sdk ...)
subject: 动词开头,简明描述(中英文均可)

示例:feat(aigc): integrate Dify workflow API for game generation、fix(feed): cursor pagination returns duplicate games。

6.3 PR 规范

  • 单次 < 500 行变更,超过必须拆分。
  • 至少 1 人 review + CI 通过(main 强制)才能合入。
  • PR 描述模板要点:
区块 必填内容
变更内容 新功能 / Bug 修复 / 重构
影响范围 影响的模块 / 影响的 API(如变更)/ 数据库迁移(如有)
测试 单元测试通过 / 集成测试通过(涉及 DB/MQ)/ 本地手工验证
截图 UI 变更附截图或录屏

7. 测试规范(测试金字塔)

层级 覆盖范围 工具 运行时机 目标覆盖率
单元 Service / Util / Validator JUnit 5 + Mockito 每次 push 核心逻辑 > 80%
集成 Controller + DB + MQ + 外部 API Testcontainers(MySQL/Redis/RocketMQ) PR merge 核心链路 100%
E2E 前端→后端→DB 全链路 Playwright(前端)+ RestAssured(API) 部署 staging 后 核心 happy path
性能 API 吞吐/延迟/并发 k6 / wrk Phase 3 末 + 上线前 满足性能指标
安全 OWASP Top 10 / 渗透 ZAP + 人工渗透 上线前 + 季度 无 Critical/High

硬约束:

  • 测试文件命名:单元测试 XxxServiceTest.java,集成测试 XxxServiceIntegrationTest.java。
  • 测试基类:继承 game-spring-boot-starter-test 的 BaseDbUnitTest / BaseDbAndRedisUnitTest。
  • 单测应 Mock 外部依赖;需要真 DB 的场景一律用集成测试(Testcontainers),不要让单测连真库。

8. 数据库迁移规范(Flyway)

规则 硬要求
命名 V{版本号}__{描述}.sql,如 V1.0.0__create_game_project.sql
只增不回滚 已合入的迁移文件禁止修改;需回滚则写新的补偿迁移
DDL/DML 分开 结构变更与数据变更拆成不同迁移文件
CI 阻断 CI 阶段执行 flyway validate,不通过则阻断合入
大表变更 用 gh-ost / pt-online-schema-change 不锁表

9. 模块开发 Checklist

新增一个业务模块时按下列清单逐项完成(完整 playbook 见 ../skills/add-business-module.md):

  • 创建 game-module-{name}-api + game-module-{name}-server 两个 Maven 模块(结构对齐 huijing-cloud fork)
  • -api 中定义 VO / DTO / 枚举 / Feign 接口 / 错误码段
  • -server 中创建 controller/admin/ + controller/app/ + service/ + dal/ + convert/
  • 编写 Flyway 迁移脚本 V{x.y.z}__{desc}.sql
  • huijing-server(聚合器,B 路线保留原名)的 pom.xml 引入新模块依赖;并在 HuijingServerApplication 扫描 + application.yaml 类型别名纳入 com.wanxiang.huijing.game.module;Nacos 添加模块配置(如有)
  • 编写单元测试(Service 层)+ 集成测试(Controller 层含 DB)
  • Swagger(Knife4j)验证 API 文档自动生成
  • 更新模块速查表,并通知前端接口就绪(附 Swagger 地址 + 示例 curl)

10. agent-specs 文档目录规范(命名 / 状态 / 分层)

由来:2026-06-16 docs/agent-specs/ 治理审计——9 天堆 88 顶层 md + 21M(其中 ~17M 是塞进文档树的 spike 代码/证据/模型原始输出),废弃选型无状态标记被当真照建。根因 = 收口缺「退役 + 分层」、命名词表发散到 10+ 种后缀。本节为硬规范;配套退役动作见 ../skills/wave-close-checklist.md 第 8 步、活地图见 docs/agent-specs/_index.md。

10.1 命名词表(封闭,禁新增后缀)

文件名 YYYY-MM-DD-<topic>-<type>.md,<type> 仅限三类:

type 用途 旧后缀归并
review 决策/评审版("为什么这么设计",结论先行供人拍板) 评审纪要 并入 review 正文「整改纪要」段,不再单独成档
execution agent 实施脚手架(一次性,收口后留桩) edit-plan / codex执行单 / plan 归此
report 收口/验收/烟测/量化(事实快照 + commit 账本,收口 SoT) 收口报告 / e2e报告 / 量化报告 / L1报告 / brief / dossier 归此

一个 topic 至多 {review, execution, report} 三件;超出即拆 topic 或并档。

10.2 状态横幅(每个 spec 顶部第一行)

> 状态: ACTIVE | SHIPPED(→memory/commit) | SUPERSEDED(→替代档) | SPIKE-DONE   ·   更新: YYYY-MM-DD
  • ACTIVE=仍管当前/未来工作;SHIPPED=已落地已蒸馏;SUPERSEDED=被推翻(必须指向替代档);SPIKE-DONE=一次性探针已结论。
  • 决策被推翻时先打 SUPERSEDED 横幅、再按退役步处理——「打过时标」不替代「退役」(堆积主因:只打标不归档)。

10.3 存储分层(doc 树只放 doc)

  • docs/agent-specs/ 只放文档(*.md)。spike 代码、批跑证据(hash 目录/jsonl/截图)、模型评估原始输出、node_modules/__pycache__/dist/build 等可重生成产物一律不入文档树。
  • 结论留同目录 *.md 或收口报告;确需留原始件 → 移仓级 spikes/<wave>/ 单独评估,不混入 spec 堆。
  • 机器噪声(__pycache__/*.pyc/node_modules)已在根 .gitignore 拦截;新 spike 原始 json/png 默认 untracked,勿 git add 批量产物。
  • 活工具箱(如 agent-loop-v1/orchestrator/,被多 skill 引用)与在飞 spike(如 channel-spike/)例外保留,但建议长期迁出至仓级 tools/。

10.4 一题一活档(演进就地修订,禁「一 pivot 一文件」)

由来:2026-06-17 一会话内同一设计(生成主线)随 4 次 reframe 产出 4 份 review/execution,且过期 v1(前提已被评审证伪)被连同新档一起推上 origin。§10.2「supersede 即归档」已存在但被违反,且缺「不一 pivot 一文件 + commit 前自检 + 终稿自洽」。本节补这道预防(doc-organizer 轴①是事后兜底,本节是事前根治)。

  • 同一设计主题演进 = 就地修订一份活档(改现有 review),禁为每次 pivot/reframe 新建文件;演进轨迹靠 git history,不靠堆并列文件。工作树只呈现当前真相。
  • review/execution 拆分仅当两者同时为活(review=决策、execution=实现);execution 定稿后 review 可归档。
  • 终稿自洽:活档不需回读被取代的前身才能懂;若需,则前身内容未折入(补折入)。
  • 同一提交内删/归档被取代者(强化 §10.2):commit 设计档前自检——「本次提交/工作树里有无被本档取代的旧档?」有则同提交 git rm(过期且错)或 git mv 到 _archive/(过期但留参考)+ tombstone 横幅;绝不把过期档单独连推上去。
  • 收口按 wave-close 第 8 步把本任务设计档收敛成最小自洽集(典型 1 review + 1 execution)。

10.5 canonical 活档(子系统 SoT · 无日期主题名 · 2026-06-17 深度重构立)

由来:2026-06-17 创始人要求 agent-specs 从「按时间堆 review/execution/verdict 流水」改为「每子系统一份 canonical 活档」——dated spec 是某波次过程产物,子系统的「现行架构+目标+现状」应收敛成一份持续更新的活档。本节是 §10.4「一题一活档」在子系统粒度的落地。是 §10.1 dated 命名词表之外另立的一类活档形态(不违反 §10.1,互补)。

  • 形态:<主题>.md(无日期前缀、无 type 后缀,如 引擎与运行时.md/agentic编排-SAA.md/战略与合规.md);顶部第一行标 # <主题> · canonical(子系统 SoT),随附 类型=canonical 活档 · 更新 YYYY-MM-DD / 取代=N 份历史 spec / 读法。一子系统一份,≤150 行。
  • 装什么:一页结论 → 目标/非目标 → 现行架构(含必要 Mermaid) → 现状(done/在飞/待办) → 关键指针(commit/skill/契约)。砍掉:演进流水/逐轮评审 transcript/逐 commit 过程/取证日志/已 supersede 旧方案(留 git + _archive/)。
  • 与 dated spec 的关系:dated review/execution/report(§10.1)= 某波次工作期过程档;波次收口时把活内容折进对应子系统 canonical(wave-close 第 8 步),dated 源档随即 git rm(已折入)或 git mv _archive/(账本/取证类留参考 + tombstone)。canonical 之外不再久留同主题 dated 流水。
  • 分层(不双写):canonical(子系统 SoT·深)> .agents/knowledge/*(AI 速查一句话·浅)> docs/architecture/ Doc A/B/C + 技术决策版(基线 WHAT/HOW)> docs/mvp/MVP进度总账.md(跨线状态)。重叠处 canonical 是 SoT,其余留速查 + 指针。
  • 导航:docs/agent-specs/_index.md 列全部 canonical(一域一档)+ 生成域设计链 + KEEP + 归档指针。维护见记忆 agent-specs-canonical-structure。