本文件是 docs/ 全树的治理总则:文档怎么放、怎么改、怎么同步、怎么核验。
四根因教训来自 WIP-236 复验退回(小冈两批文档治理)与本轮 WIP-237 实测,固化为可执行规矩。
配套阅读:docs/NOW.md第三节「十三条纪律」、docs/receipts/README.md(回执制度)、AGENTS.md§4.4(文档铁律)。
docs/
├── *.md / *.html 根目录=现行有效的主文档(设计/方案/契约/决议/规范)
├── archive/ 已废止/已被取代的旧文档(头部必挂 ⛔ 横幅)
├── plans/ 施工计划、派工清单、接口规格、验收计划(按日期或 WIP 号命名)
├── reports/ 一次性交付报告、自测报告、交叉核验(按日期+人+主题命名)
├── receipts/ 每人一份工作回执(见 receipts/README.md,独立制度)
├── precheck/ astra 预审实录(纪律 8 留痕)
├── tools/ 文档治理工具(verify-c.sh 等)
├── _handwritten/ 手写展示页留档区(无对应 md,rsync 不删)
├── TASKS.md / NOW.md 台账与当前口径(派工岗维护,长行改动须脚本化=纪律 11)
├── 时效索引.md 自动生成的时效索引(工具重算·勿手改)——查文档是否过期看这里
└── index.html 文档站入口(md2html 派生,分类卡片)
唯一权威源:仓库 docs/*.md(git main)。docs/*.html 一律由 scripts/md2html.py 派生,禁止手改 html;线上静态站 nginx/html/docs/ 是再次派生产物,禁止在服务器上直接编辑。
问题:文档里写 file.py:123 这类行号引用,代码一演进就失效,但结论可能仍"看起来对"——
读者照行号跳过去看到无关代码,却不会怀疑,比直接写错更危险。
实测案例(2026-09-28 核查):
| 文档 | 引用 | 实际 | 性质 |
|---|---|---|---|
NOW.md §四 | miniapp_orders.py:534 = 「券款强制线下」 | 该行已是福钥冻结逻辑,且代码已演进为 1P/3P 双轨 | 🔴 语义也变了 |
contracts/api-v1.md | miniapp_orders.py:690 = 「list_orders LIMIT 100」 | 实际在 :728(漂 38 行) | 🟡 行号漂移,结论仍对 |
纪律:
list_orders()、LIMIT 100 常量),行号只作辅助,并注明「行号为当时快照」。
python3 docs/tools/check_doc_line_refs.py --file <文档>,按关键词重叠做启发式判断,低分项人工复核(低分≠必然失效)。
适用范围说明:
docs/contracts/、docs/plans/*规格*):必须保持行号或改函数名引用。docs/TASKS.md、docs/receipts/、docs/reports/):属历史记录,不改——当时的引用就是当时的真相,改了反而篡改历史。
| 规矩 | 说明 |
|---|---|
| md 为唯一真源 | 一切内容改动只改 .md;.html 永远由 md2html.py 重新生成,不手改 |
| 改 md 必同批改 html | 铁律(AGENTS.md §4.4):双版本必须一致。改了 md 不同步 html=读者打开 html 看不到改动=口径分裂 |
| 同名版本分离 | 存档版与现行版不得同名(防误读)。存档版改名带版本号,如 archive/项目总纲-v0.x-存档.md |
| 废止挂横幅 | 任何被取代的文档头部加一行 > ⛔ 已废止/存档(YYYY-MM-DD),现行以 \docs/精确路径.md\ 为准 |
事故留痕:WIP-236 改 41 份 md、0 份 html,22 份有配对 html 未重生成 ⇒ 读者打开 html 看不到横幅,正是该批要治的病本身。
| 规矩 | 说明 | |
|---|---|---|
| 批量同步后逐份核产物 | 核 mtime / 份数 / 哈希,不看 while read 循环回显的「成功 N 份」 | |
| 末行陷阱 | while read -r f; do …; done < 清单 会漏读无换行符的最后一行;清单末尾必须留换行,或改 `find -print0 | xargs -0` |
| 幂等判据 | md2html.py 页脚嵌生成时间 ⇒ 跨分钟必不幂等,直接比哈希是假阴性;要比「剔除页脚时间戳后幂等」 |
# 单个同步
python3 scripts/md2html.py docs/xxx.md
# 全量同步
python3 scripts/md2html.py --all docs/
# 逐份核验产物(核 mtime,不信回显计数)
for f in $(cat /tmp/html_todo.txt); do stat -f "%Sm %N" "${f%.md}.html"; done
事故留痕:小齐代补 22 份失步 html 时,while read 漏读末行,首跑只成 21/22,靠逐份核 mtime 才发现第 22 份 603407 秒未更新。
| 规矩 | 说明 |
|---|---|
| 先对齐 HEAD 再判定 | 任何「未做/零命中/已实现」结论前:git fetch → 在 origin/main 提交树上扫,不扫工作区 |
| 宣称落地比 blob 哈希 | 验「某文件已改」用 git rev-parse <旧rev>:<path> vs <新rev>:<path> 两值必须不同;禁看 --stat 的 files changed 总数(它对未变文件根本不报) |
| 数产物份数 | 宣称「批量改 N 份」就数出 N 份产物,不采信自报 |
| 中文路径加参数 | 凡含中文路径的 git ls-tree/git grep/git show 一律显式加 -c core.quotepath=false(否则被转义成八进制 ⇒ grep 字面量与 .endswith(".md") 双双假阴性) |
| 规则本身也要被证伪 | 校验脚本的路径/判据若写错,会静默输出假绿 ⇒ 扫描器须自带「路径不存在即报规则失效」自检 |
# 树上扫(不扫工作区)
git fetch origin main
git -c core.quotepath=false grep -aiE "关键词" origin/main -- docs/
# 比 blob 哈希验「已改」
git rev-parse 9791937:docs/tools/verify-c.sh # 改前
git rev-parse origin/main:docs/tools/verify-c.sh # 改后,两值须不同
事故留痕:①WIP-236 宣称「五项落地」,实测verify-c.shblob 哈希与改前相同、零实现 ⇒ 宣称 5 实落 4。②本轮 WIP-237 实测verify-c.sh③b 两条规则的 code 路径写成单层miniprogram/pages/(实际是 devtools 双层miniprogram/miniprogram/pages/)⇒os.path.exists恒 False ⇒ 永不命中 ⇒ 输出「✅ 无状态倒挂」是假绿。两者同族:宣称/默认「已生效」但树上无实现。
| 规矩 | 说明 | ||
|---|---|---|---|
| 自领须登记 WIP 号 | 纪律 2:自领提交可以,但必须在 TASKS.md 登记 WIP 号;未登记=违例记档 | ||
| 建单前置三步 | ①git fetch origin main ②`git show origin/main:docs/TASKS.md \ | grep -aoE "WIP-2[0-9]{2}" \ | sort -u` 取已占号 ③取最小未占号(先到先得) |
| 不抢占 P0 | 自领任务不得挤占当前最高优先级单(如 WIP-230 批 1 重修) | ||
| 派工岗批注当批推送 | 派工岗批注写完必须当批 push,不得留工作区过夜(否则对方按旧版本施工、又互相覆盖) |
事故留痕:①WIP-236 两批自领提交均未登记 WIP 号(纪律 2 违例)。②派工岗建单用 WIP-231,但扣子一号已先自领 231 ⇒ 同号不同事,让号 233。③长行批注整行替换两次截断覆盖事故(纪律 11:改长行须脚本化「读全文→定位行→行尾追加→写回」+ 三方合并 + 逐段 assert)。
什么是状态倒挂:文档头部标「待派工/待评审/草案」,但对应代码已实现、台账已验收 ⇒ 文档状态滞后于事实,误导后来者。
扫描器:docs/tools/verify-c.sh 第 ③b 段,规则集随批扩展(WIP-237 已从 2 条扩至 5 条倒挂 + 1 条已砍除特例):
| # | 文档 | 倒挂证据 |
|---|---|---|
| 1 | 场景引擎实施细则-v1.0场景引擎实施细则 | WIP-139 M0-M4 已验收(419ceaf)+ WIP-151 仍标待派工 |
| 2 | 藏家乐预留位设计规格-v0.1藏家乐预留位设计规格 | WIP-128 M1-M3 已验收(6835569/2e5a2e8) |
| 3 | 需求域商户侧设计方案-v1.0需求域商户侧设计方案 | WIP-133 M1-M3 已验收(df1fbdd) |
| 4 | 主理人组包工作台设计方案-v1.0主理人组包工作台设计方案 | WIP-134 M1-M3 已验收(46bd3ae) |
| 5 | B端工作台实施细则-v1.1B端工作台实施细则 | WIP-131 已验收 + WIP-140 G1 账单页已交付(101586e) |
| 特例 | 会员与留存体系设计 | 决议 23 已砍除该体系 ⇒ 属「状态失真」非倒挂,应改标「已砍除」 |
退出口径:1=规则失效(code 路径不存在,工具坏了,硬失败);2=扫出倒挂(文档头部待修,警告不阻断);0=干净。扫出倒挂不得报「全绿」(WIP-237 修正:原二态把警告吞成假绿)。
# 1. markdown 语法体检(只报相对 HEAD 新引入的问题,历史债不返工)
python3 scripts/check_md_syntax.py --diff-head docs/改动的文件.md
# 2. 台账表格校验(改了 TASKS.md 必跑)
python3 scripts/check_tasks_table.py --diff-head
# 3. C 端接线 + 状态倒挂扫描
bash docs/tools/verify-c.sh .
# 4. md → html 同步(改了几份 md 就同步几份,逐份核 mtime)
python3 scripts/md2html.py docs/改动的文件.md
# 5. 冲突标记扫描(禁把 <<<<<<< 提交进库)
grep -rnE "^(<<<<<<< |=======|>>>>>>> )" docs/改动的文件.md
纯文档批提交信息加 [no-deploy](不触发 staging 部署)。