项目文档治理方案形成全过程(证据审计版)
项目文档治理方案形成全过程(证据审计版)
- 研究范围:
zhangrh.shop、ShotMarker、frontend-observability-server,两段 Codex 讨论,以及最终规范文件 - 可证实的形成区间:2026-07-29 至 2026-08-20(Asia/Shanghai,UTC+8)
- 研究日期:2026-08-20
- 最终方案快照:
PROJECT_DOCUMENT_GOVERNANCE.md,文件内标注版本 1.5、制定日期 2026-08-19 - 最终方案快照 SHA-256:
425823d0c893c4894bdc04abcdc5d9efcfc6be1251180e5137cb06b7ffd3e8bf - 最终方案快照规模:338 行、15,440 字节;文件修改时间为 2026-08-20 12:10:07 +08:00
重要说明:本报告把“项目和对话中的可观察记录”与“对这些记录的解释”分开。凡是无法从给定对话、最终文件或本地 Git 历史支持的内容,一律不写成事实。
1. 结论先行
这套方案不是一次性从抽象原则推导出来的,而是在一连串真实问题、一次明显偏重的治理实验、两轮有取舍的讨论,以及一次真实误读事故中逐步收敛出来的。
它解决的核心矛盾可以概括为:既要让人和 Agent 很快知道“项目现在是什么”,又要保留变更为什么发生、如何执行、如何验证的上下文;同时不能让历史、过程和治理机制反过来淹没当前结论。
最终得到的不是单纯的三个目录,而是四种不同职责:
current 负责清楚地说明现在;
changes 负责承载尚未结束的变更材料;
archive 负责保存已经结束且仍值得查阅的过程;
Git 负责保存文件本身逐版本如何变化。
整个形成过程存在两条彼此交织的反馈链:
- 项目实践链:文档堆积、重复和过时 → 尝试复杂治理 → 发现治理本身过重 → 用目录表达生命周期 → 压缩 current → 使用稳定文件名 → 在三个项目中统一落地。
- 规则反馈链:审查初稿 → 用户明确接受或否决建议 → 修改规范 → 在项目中传播 → Agent 发生真实误读 → 增加作用域防线 → 再次传播并独立复核。
三个项目分别提供了不同的压力测试:
| 项目 | 可观察到的主要压力 | 对最终方案形成的贡献 |
|---|---|---|
zhangrh.shop |
文档数量大、部署说明重复、旧事实残留、公开与私有事实分散、跨项目 Track 信息 | 证明需要入口、当前事实提炼、Git 与 archive 分工、公开/私有和跨仓库单一事实源 |
frontend-observability-server |
候选方案与当前结论混杂、接口命名冲突;随后又出现元数据、目录、校验脚本过多;current 技术正文膨胀 | 提供了从复杂治理到简单治理的完整反例与修正轨迹,并直接支撑 current 边界、稳定文件名、事实与决定分离 |
ShotMarker |
单一状态页承担过多职责;存在一个 563 行仍活跃的 spec;大量已结束 spec/plan;外部发布状态会变化 | 证明需要按主题拆分 current、区分 active Change 与历史、不能把 current 的行数规则套到 spec、外部状态必须带验证日期 |
最值得注意的是:最终规范中若干看起来像“预防性设计”的条款,其实来自已经发生的问题。例如,“300 行只适用于单份 current”不是凭空补充,而是 2026-08-20 一个 Agent 已经把该限制错误套用到 spec 之后才被强化;“archive 按月”也不是预先假设,而是用户在实际铺开 archive 后直接反馈目录太大。
2. 证据方法与可信度标记
2.1 三类证据
本报告使用以下标记:
- [A|直接陈述]:用户在对话中明确说明问题、意图、接受项或否决项。这类证据最能说明用户当时的判断。
- [B|可观察事实]:最终文件内容、对话中的实际补丁、Git 提交、文件规模、目录结构、测试结果等。这类证据能证明“发生了什么”,但单独不能证明用户内心的因果动机。
- [C|受限推断]:多个 A/B 证据共同支持的解释。报告会明确写成“说明”“与……一致”“可合理推断”,不会伪装成用户原话。
2.2 时间与版本口径
- 两段 Codex 原始会话日志使用 UTC;本报告全部换算为 Asia/Shanghai(UTC+8)。
- Git 时间采用提交中记录的
+08:00时间。 - 第一段对话开始时,规范已经是 1.1;因此本报告可以还原 1.1 之后每次修改,也能从项目 Git 历史追溯更早前因,但不能证明 1.0/1.1 最初草拟时每一个想法的准确心理顺序。
- 文件在 2026-08-19 14:04 已被标为 1.5,但 2026-08-19 15:11—15:13 和 2026-08-20 12:10 仍继续加入重要澄清而没有再次升级版本号。故本文把最终交付称为 “1.5 标签下的 2026-08-20 12:10 文件快照”,并用 SHA-256 消除同名版本歧义。
2.3 研究边界
- Git 分析基于本机当时可见的提交和引用,没有执行远端 fetch;因此“全部历史”指本地可见历史。
- 只把用户消息、公开的 Assistant 回复、实际工具补丁、文件和 Git 对象当作证据;不使用模型隐藏推理作为证据。
ShotMarker在最终核对时有两个未跟踪的截图目录;它们与文档治理历史无关,未纳入因果分析。frontend-observability-server在最终核对时本地master比origin/master领先 1 个提交;报告以本地可见的治理提交为准,不据此推断远端状态。- 对话中曾短暂观察到 frontend 主工作区有未提交材料,随后执行前再次核验时已经消失;历史执行记录明确没有伪造 stash/恢复步骤。本报告只将这一点作为并行落地时的安全边界,不把短暂工作区状态解释为方案来源。
3. 可以被证实的总时间线
| 时间(UTC+8) | 事件 | 证据类型 | 对方案的意义 |
|---|---|---|---|
| 2026-07-29 15:13—15:41 | zhangrh.shop 合并重复项目/部署文档,修正文档事实边界,删除 30 份旧设计/计划并依赖 Git 恢复 |
B | 最早可见的“当前说明、历史过程和 Git 分工”实践前因 |
| 2026-08-11 17:09—18:06 | frontend 建立六类目录、三维元数据、状态头、晋升流程和 Ruby 校验脚本 | B | 形成一个可完整观察的复杂治理实验 |
| 2026-08-13 17:26 | frontend 删除多维元数据、空目录、入口占位和校验脚本,只保留 current/archive 业务语义 | B | 明确发生“治理机制瘦身”,目录本身成为状态表达 |
| 2026-08-16 | ShotMarker 设计单一状态页;最终状态快照达到 247 行 | B | 验证“当前状态入口”价值,也暴露单页职责过多的趋势 |
| 2026-08-18 15:38—16:24 | frontend 将三份 current 技术正文从 1,464 行大幅精简,并把 current 日期名改为稳定语义名 | B | 直接支撑 current 简洁、单一事实源、按边界拆分、无日期命名 |
| 2026-08-19 10:24—11:26 | 三个项目先后迁移到共同的 current/changes/archive 基线;补充公开/私有及跨仓库边界 | B | 通用方案首次在三个不同项目上系统落地 |
| 2026-08-19 11:30—14:05 | 第一段对话审查并形成 1.2—1.5:可信度分流、中文 AGENTS、按月 archive、current 300 行 | A+B | 用户直接取舍和规范版本演进最完整的一段 |
| 2026-08-19 14:32—15:57 | 三个项目继续对齐按月归档、可信度和跨仓库边界 | B | 规则从通用文档反向传播到项目实践 |
| 2026-08-19 14:55—15:14 | 第二段对话否决审批/元数据/自动化等过重建议;明确 Prompt 确认即决定;澄清 spec/plan 非强制 | A+B | 把方案的“轻量、按需、用户确认”边界写实 |
| 2026-08-20 12:07—12:10 | 用户报告 Agent 把 300 行错误套到 spec;规范加入目录作用域原则和显式反向约束 | A+B | 从真实误读中补上“规则不得跨目录类推” |
| 2026-08-20 13:13—14:28 | 审计三个项目的入口文档;六份入口需要补强;三项目隔离修改、合并、测试并由独立 reviewer 复核 | A+B | 最终规则完成跨项目传播和可执行性验证 |
4. 第一阶段:问题先于方案——zhangrh.shop 的文档堆积与清理
4.1 2026-07-29 的可观察问题
zhangrh.shop 的 2026-07-29-project-cleanup-spec.md 记录了当时的仓库审计结果:
- 仓库没有顶层
README.md; - 日常说明、部署台账和项目内临时文档存在重复;
- 部署文档仍把已经退役的
/legacy-h5/写成当前服务; docs/superpowers中已有 30 份历史设计和计划,共 10,499 行。
这是直接的 Git 文档事实,位置为 docs/archive/2026-07/2026-07-29-project-cleanup-spec.md:3-20。[B|可观察事实]
当天三个提交显示了实际处理方式:
5f737a7(15:13,docs: 重整项目与部署文档)修改 11 个文件,319 行新增、812 行删除;把三份重复部署文档合并为一个入口,并整理项目说明。6ed9087(15:23,docs: 修正文档事实边界)继续纠正文档中什么属于当前事实。846cba2(15:41,chore: 删除废弃脚本与历史过程文档)修改 34 个文件,删除 11,073 行,其中包括前述 30 份历史过程文档;设计明确说明这些文件仍可由 Git 历史恢复,见同一 spec 的 115—120 行。[B|可观察事实]
4.2 这一步说明了什么,又不能说明什么
能够确定的是:在最终规范形成前,项目已经真实经历过“当前入口缺失、重复文档、过时事实、历史过程大量堆积”的问题,也已经使用“删去工作树中的历史文件、依赖 Git 恢复”的办法减负。[B]
可以合理推断,这段实践构成了最终规则“Git 保存逐版本变化”“current 不保存提交日志和逐版本变化”的经验前因;二者解决的是同一类负担。[C|受限推断]
但不能据此断言:用户在 7 月 29 日已经完整想出了 current / changes / archive 三态模型。Git 只能证明做过什么,不能证明当时尚未写下的完整方案已经存在。最终规范后来又修正了 7 月做法:迁移时应优先移动和提炼,不能为了干净删除仍有历史价值的材料;也就是说,最终方案不是简单复刻“全部删除、交给 Git”,而是进一步区分了两类历史:
- 文件内容每一次怎么变,由 Git 保存;
- 已结束但仍值得直接阅读的讨论、计划、排查和验证,进入 archive。
5. 第二阶段:frontend-observability-server 的复杂治理实验
5.1 原始问题很具体,不只是“文档很多”
2026-08-11 的 document-governance-transition-spec 记录了六份设计/决策/评价文档中的冲突:
- 当前有效结论与历史候选方案混合;
- 同一接口出现
/v1/metrics、/v1/web-vitals、/v1/reports三种名称; - 健康检查出现
/livez、/readyz、/healthz、/health/live、/health/ready五套表达; - 有的材料已经形成决定,有的仍是讨论或验证草稿,但没有统一状态和权威范围;
- 团队开发和个人 TDC 复盘需要同一批事实,却需要不同阅读路径;
- 服务尚未实现,部分实现内容还没定义,不能把现有材料包装为完整现行规范。
这些内容可直接定位到 docs/archive/2026-08/2026-08-11-document-governance-transition-spec.md:3-14。[B]
这里首次清楚呈现了最终方案要解决的几个核心问题:当前与历史混写、多个事实源互相矛盾、尚未实现的设计被误读为现状、读者不知道先读什么。[C,基于上述 B]
5.2 最初采取的是重型方案
这份过渡设计没有立刻走向最终三态,而是建立了一个更复杂的体系:
current / working / decisions / archive / tdc / evidence
并要求每份文档同时声明三个维度:
type:discussion、spec、adr、validation、retrospective、evidence、governance;status:draft、proposed、accepted、superseded、archived;authority:implementation、decision、informative。
它还规定标准状态头、四阶段迁移、晋升 current 的条件、未决项结构、旧路径迁移说明和独立 Git 提交。目录与元数据可见于该 spec 的 84—170 行。[B]
随后从 c6327e8、0a29f60、9439881、fcea58e 到 c43e56d,仓库分阶段建立了这套体系;最终还有 scripts/check-docs.rb、治理头、结构化示例和归档正文哈希检查。c43e56d 单次增加 444 行。[B]
这一步非常重要,因为后来的“不要元数据、不要空占位、不要治理脚本”不是抽象的 YAGNI 口号,而是对一套已经实际建立过的机制进行回撤。[C]
5.3 2026-08-13:明确撤回复杂度
34e5085(docs: 精简项目文档为当前与归档结构)修改 30 个文件,只新增 69 行却删除 860 行。对应 spec 明确写道:
- 项目文档只保留
current/和archive/两种业务语义; - 目录位置是文档状态的唯一表达;
- 不再使用
type、status、authority或审阅/执行状态元数据; - 删除没有独立正文价值的入口、空 evidence 占位和其他 README;
- 删除依赖旧多维模型的
scripts/check-docs.rb; - 没有实际内容时不创建目录、模板或占位文件。
证据位于 docs/archive/2026-08/2026-08-13-simplify-document-structure-spec.md:3-12,67-93。[B]
这次精简还不是最终方案:当时仍保留工具专属的 superpowers/,current 中甚至包含“现行实施计划”,普通文档仍使用日期前缀,也还没有 changes。但它确立了最终方案的一个关键方向:优先让目录本身表达生命周期,不再给每份文档附加一套治理状态机。[C]
6. 第三阶段:从“有 current”走向“current 真正可读”
6.1 目录整理之后,正文仍然过重
2026-08-18 的 simplify-current-document-content-spec 开头明确记录:三份 current 技术文档仍有 1,464 行,并同时描述当前协议、浏览器 SDK、未来多应用平台、Histogram 迁移、测试实现、容量目标、Dashboard、告警和验证记录,当前事实与未来预案仍然混在一起。证据位于 docs/archive/2026-08/2026-08-18-simplify-current-document-content-spec.md:3-7。[B]
这说明“把文件移进 current”本身不能保证 current 清晰;必须继续约束内容边界。[C]
6.2 选择“按事实源重构”,拒绝两个极端
该设计比较了三种做法:
- 不采用局部删句,因为无法解决同一规则在多文档重复定义;
- 采用按事实源重构,让每项现行行为只在一份文档完整定义;
- 不采用合并为单一技术文档,因为会重新混合架构、HTTP 契约和运维要求。
对应证据为同一 spec 的 34—59 行。[B]
三个连续提交显示了实际压缩规模:
| 提交 | 文档 | 变更规模 |
|---|---|---|
15eaaa4 |
架构与范围 | 56 行新增、193 行删除 |
2877060 |
指标上报协议 | 106 行新增、525 行删除 |
84a2427 |
验证与运维 | 96 行新增、490 行删除 |
压缩不是把内容挤成长段落,而是删除无现行业务需求或无实证支撑的未来平台、通用迁移框架、accepted/observed 状态机、SDK 固定算法、精确但未验证的运行阈值,以及重复的协议/流程说明;spec 的 110—169 行逐项列出了这些删除与写作规则。[B]
这一实践直接解释了最终规范为何同时规定:current 只保留理解现状所需的信息;一段一个主题;详细背景链接 changes/archive;按变化节奏、证据来源和兼容边界拆分;不能靠长段落绕过行数限制。[C]
6.3 current 文件名从日期快照改为稳定主题
2026-08-18 16:24 的 1ebd1b8 移除了 current 文档日期前缀。对应设计的理由非常明确:
docs/current/是持续更新的现行事实,不是按日期冻结的快照;- 日期前缀会让读者误以为内容停留在创建日;
- Git 已保存 current 的变更历史;
- 需要时间识别的历史讨论、spec、plan 和证据仍保留日期。
证据位于 docs/archive/2026-08/2026-08-18-use-stable-current-document-names-spec.md:3-19,28-37。[B]
这与最终规范的“current 使用稳定、无日期、简短清晰的名称;changes/archive 使用日期”几乎形成一一对应的实践来源。[C]
6.4 ShotMarker 的单一状态页:有价值但不够
2026-08-16,ShotMarker 曾设计把 docs/current-codebase-status.md 作为唯一内部状态页:顶部写当前结论,底部只保留少量最近进展,更早历史交给 Git。该设计明确说状态页不替代 PRD、设计、计划或提交历史。证据位于 docs/archive/2026-08/2026-08-16-project-status-document-spec.md:5-26。[B]
这份设计已经包含最终方案的若干思想:单一当前入口、当前结论优先、少量历史、变化外部状态要标日期、Git 承担旧历史。但实际形成的状态快照有 247 行,固定十个部分,同时覆盖总体状态、功能、进行中工作、测试、风险、下一步、发布检查和最近进展。[B]
三天后的治理迁移没有继续维护一份包办所有内容的状态页,而是把它归档,并拆出 status.md、product.md、architecture.md、quality.md、release.md 等稳定主题。可合理推断,这次变化不是否定“状态入口”,而是把状态入口降为摘要和导航,把不同证据来源、变化节奏和兼容边界交给不同 current 文件。[C]
7. 第四阶段:2026-08-19 上午,通用基线进入三个项目
7.1 一个必须保留的断点
第一段指定对话在 2026-08-19 11:30 才开始,Assistant 读取到的文件已经是 1.1;而三个项目的迁移最早从当天 10:24 开始。因此,通用规范 1.0/1.1 的最初草拟和当天上午迁移所依赖的另一段会话,不在用户本次给出的两段对话中。[B]
我们仍能从 1.1 快照和 Git 产物确定它当时已经包含什么:
current / changes / archive三态;- Git 保存逐版本变化、archive 不复制每个版本;
- 可见性与生命周期分开;
- 多仓库单一事实源、公开/私有边界;
AGENTS.md与docs/README.md的入口职责;- current 允许/禁止内容、稳定主题和验证日期;
- changes 中的 spec/plan 与 archive;
- 生命周期、可信度、迁移、日常维护和可复用 AGENTS 规则。
第一段会话的原始工具输出完整捕获了这份 314 行的 1.1。[B]
因此可以说,最终方案的骨架在 11:30 前已经存在;但不能从现有材料声称“某一条具体讨论直接产生了三态模型”。本报告只把三个项目更早的实践写成可验证前因。[证据边界]
7.2 zhangrh.shop:公开/私有和跨仓库边界
a789241(10:24,docs: 重整项目文档治理)建立了 AGENTS.md、docs/README.md 和三份 current 文档,把 9 份 spec、6 份 plan 移到 archive,并建立 changes。提交规模为 472 行新增、212 行删除。[B]
其迁移计划把“生命周期”和“可见性”明确分开:公开仓库维护代码、产品、质量和部署契约;私有仓库维护基础设施、生产配置和外部验证;凭据不进入任何仓库。计划还要求保留有价值的事实和历史,不以清理为由删除;见 docs/archive/2026-08/2026-08-19-project-document-governance-migration-plan.md:5-19。[B]
这一设计明显回应了 zhangrh.shop 的现实结构:同一项目事实分布在公开代码仓库和 docs/private.local 独立 Git 仓库中。它最终演化为规范 2.1 节的几条规则:生命周期不表示可见性、每个仓库只维护权限边界内的三态、每项事实只有一个当前来源、公开文档在私有仓库不可用时仍应可读。[C]
985ea14(11:10)继续把 automation、backend、track 等当前主题纳入 current,并删除重复入口;f89c1ae(ShotMarker,11:22)记录私有文档仓库边界,2537486(11:23)从公开 archive 收敛私有运维细节。[B]
这些提交说明,公开/私有规则不是只写在通用规范中的假设,它已经用于迁移真实文件和缩减公开历史内容。[B]
7.3 ShotMarker:active Change 与历史材料分开
ef5bde0(10:35,docs: 统一项目文档治理并补充埋点事实)修改 40 个文件,建立文档入口和多份 current 主题,把 247 行旧状态快照、PRD、已结束的 spec/plan 归档;同时把仍未实现的语音口令设计保留为 docs/changes/2026-07-29-ios-voice-command-marking-spec.md。[B]
对应治理 spec 明确写道:“当前没有对应 plan,不创建空计划”,见 docs/archive/2026-08/2026-08-19-document-governance-spec.md:65-74。这说明“一个 Change 可以只有 spec,不能为满足模板创建空 plan”在第二段对话正式澄清“并非每个变更都强制 spec+plan”之前,就已经有项目实践。[B]
这也是后来“current 不规定固定文档清单”“不为满足模板创建空文件”“如果同一个 Change 生成 spec 和 plan,则共享日期/topic”等规则的直接实践背景之一。[C]
7.4 frontend:把先前的二态继续迁移为三态
5d87879(11:26,docs: 完成项目文档治理迁移)建立 AGENTS.md、统一的 docs/README.md、changes/.gitkeep,并把工具专属目录里的 7 份设计/记录和 2 份计划迁到 archive。[B]
其对齐记录列出的迁移前差异包括:入口仍在 docs/current/README.md、缺少 Agent 读取顺序、结束材料还在工具专属目录、跨仓库权威范围不清、尚未实现的契约容易被现在时误读。见 docs/archive/2026-08/2026-08-19-document-governance-alignment.md:3-22。[B]
值得注意的是,这次迁移没有为了匹配模板新增 current 文件,也没有创建虚假 spec/plan,只用 .gitkeep 保持空 changes 目录。它把 8 月 13 日的“current/archive”简单化继续推进为最终的“current/changes/archive”,其中 changes 只承载真实存在且未结束的材料。[C]
8. 第五阶段:第一段讨论把骨架改造成 1.5
第一段对话原始日志共有 470 个 JSONL 事件、11 个用户消息;任务 ID 为 01a01811-7b6a-75b3-b079-d7b644796aa1。以下时间均为 UTC+8。
8.1 11:30—11:46:只接受“事实与决定分开取证”
11:30,用户要求审查规范。Assistant 在 11:31 提出七类问题,其中包括:
- 当前统一可信度顺序混合“实现事实”和“规范性决定”;
- 缺少负责人、批准状态、生效日期、复审周期和例外流程;
- spec/plan 生命周期太绝对;
- 安全条款可更广;
- 可增加状态元数据;
- 多仓库冲突和扁平 archive 可能有问题。
这些是 Assistant 的审查意见,不等于用户认可。[B|对话事实]
11:44,用户逐项取舍:
- 确认只修改可信度区分;
- 明确拒绝负责人、批准状态、生效日期、复审周期、修改流程和例外审批,理由是文档修改已有 Git 历史;
- 认为无效或未完成文档也可以进入 archive,不会污染 current;
- 拒绝更复杂的安全审查,私有内容由
private.local承担; - 认为跨仓库事实冲突就是缺陷,应直接展示;
- 对 archive 扩展性采取“实际遇到问题再改”的态度。[A|直接陈述]
11:45 的补丁把版本从 1.1 升到 1.2:
- 实现、构建、发布和外部状态以代码、测试、构建和当次验证取证;
- 已生效决定、契约和政策以 current 为规范来源;
- 代码只能证明实现,不能自动推翻决定;
- 二者冲突时,在 current 同时展示决定和实现差距,并把差距视为缺陷;
- 同步修改可复用 AGENTS 规则。[B|实际补丁]
这一步不是简单调整“证据优先级”,而是承认项目同时存在两类不同真相:描述“已经实现什么”的经验事实,和描述“当前必须以什么为准”的规范决定。最终规范第 7 节完整保留了这个分流。[C]
8.2 11:58—12:02:AGENTS 规则改为中文
11:58,用户询问能否把 AGENT.md 规则改为中文。Assistant 核对后说明正文可以中文,但标准文件名应是复数 AGENTS.md。12:01 用户要求执行;第 11 节可复用规则被完整翻译为中文,路径、文件名和语义保持不变。[A+B]
这一修改没有改变治理模型,但影响了方案的可迁移性:最终规范不仅描述原则,还附带一段可以直接复制到项目中的中文 Agent 工作规则。[B]
8.3 13:45—13:49:扁平 archive 在实践中变大,改为按月
13:45,用户直接反馈:如果全部放入 archive,文件铺开非常大,并提出使用 2026-07、2026-08 月份目录。[A]
Assistant 比较了继续扁平、按年和按月三种方式,推荐:
- changes 继续扁平;
- archive 只增加
YYYY-MM一层; - 月份取文件原始日期,而不是归档移动日期;
- 月份目录按需创建;
- 不再按 topic 或记录类型增加更深目录。
用户在一次输入纠正后于 13:47 明确确认。13:48—13:49 的补丁把版本 1.2 升到 1.3,并同步修改标准结构、README 职责、changes 完成规则、archive 职责、命名、生命周期、迁移、日常检查和 AGENTS 示例。[A+B]
这条规则具有非常清晰的形成因果:问题和候选方案由用户直接提出,确认后立即进入规范。它是本次材料中最强的一类来源证据。[A+B]
8.4 13:56—14:01:为 current 增加人类可读性和 500 行上限
13:56,用户提出三项 current 要求:
- 单个文档简洁,事实和决定清晰、准确、可靠,适合人类阅读;
- 单个文档以 500 行为限制;
- 文件名简洁清晰,不使用复杂单词。[A]
13:58,用户进一步指定:超过 500 行时应考虑如何合理拆分,不能通过合并长段落规避。[A]
13:59—14:01 的补丁形成 1.4,把这些要求同时写入 current 定义、边界原则、简洁性章节、维护检查和 AGENTS 示例。[B]
这里的重点不只是数字,而是规则意图:行数是推动合理边界的信号,不是压缩排版的目标。这一意图后来继续保留在 300 行版本中。[A+B]
8.5 14:02—14:05:500 与 300 比较,用户确认 300
14:02,用户追问 500 行还是 300 行更合理。Assistant 推荐 300,理由是 current 是快速了解现状的入口;300 行已经足够表达较完整的事实、决定、风险和证据;接近 500 时往往混入多个独立主题;规范允许多份 current,因此不需要设置“建议 300、上限 500”双层规则。[B|Assistant 建议]
14:04,用户明确确认 300 行。[A]
随后补丁把版本升到 1.5,并在正文、维护检查和 AGENTS 示例三处把 500 统一为 300。[B]
因此,300 不是从某个外部标准抄来的强制数字,而是在用户先提出 500、要求合理拆分、再比较 300/500 后做出的明确选择。[A+B]
9. 第六阶段:规则立即回流到三个项目
通用规范变化后,三个项目在 8 月 19 日下午继续对齐:
9.1 zhangrh.shop
295c3ca(14:32)把 16 个归档文件迁入月份目录;dd83c10(15:57)更新中文治理规则和入口;1c24f38(15:57)区分当前事实与有效决定;a0470f7(15:57)明确 Track 跨仓库权威边界,把 ShotMarker 客户端埋点细节指向 ShotMarker 自己的 current。[B]
这组提交把规范中的三个抽象原则变成项目事实:按月 archive、事实/决定分流、跨仓库一个权威来源。[B]
9.2 frontend-observability-server
9dee37a(14:40,docs: 对齐项目文档治理规范 v1.5)把 24 份 archive 文件迁入 2026-07/2026-08 月份目录,并更新入口与可信度规则。对应 spec 还记录:
- 当前代码已经实现工具链、可隔离 Fastify 实例和
/livez; /readyz、指标接收/导出、Registry、生产保护、CI、容器和部署仍未实现;- V1 文档中的决定仍然有效,未实现内容属于实现差距,不是决定失效。
证据位于 docs/archive/2026-08/2026-08-19-document-governance-v1-5-spec.md:76-84。[B]
这正是“实现事实”和“有效决定”分流在真实项目中的示范:current 不需要在二者之间二选一,而应同时说清楚已实现部分、仍有效的契约和实际差距。[B]
9.3 ShotMarker
41bfda2(15:48)按新版规范把 archive 改为月份目录,并更新事实/决定规则;提交修改 34 个文件。[B]
项目中仍活跃的语音口令 spec 有 563 行,却合理保留在 changes。这个事实后来成为验证“300 行只属于 current”时最直观的反例:长 spec 不等于违反 current 简洁性规则。[B]
10. 第七阶段:第二段讨论收回过度设计,并修正两个歧义
第二段对话原始日志共有 930 个 JSONL 事件、9 个用户消息;任务 ID 为 01a018cd-eeb6-7de0-a626-e3f6e45c484f。该会话跨越 2026-08-19 和 2026-08-20。
10.1 14:55—15:08:第二次审查再次提出重型建议,用户要求回到实际协作模式
14:55,用户再次要求审查。Assistant 最初给出约 8/10,并再次建议批准权、状态流转、文档元数据、自动检查和全局 Change ID。[B|对话事实]
15:05,用户逐项质疑:
- 所有修改本来都通过 Prompt 进行,不理解为什么还需要额外的“让决定生效”权力;
- 认可 spec/plan 分类有价值,但质疑 Superpowers 是否真的要求任何需求、任何变动都生成两份文件;
- 明确认为文档元数据、自动检查及后续建议过度设计。[A]
15:08,Assistant 纠正了自己的评审尺度:在“用户 + Agent”的协作里,用户在 Prompt 中的确认本身就是授权/确认;Superpowers 并不要求每个变更都产出 spec 和 plan;之前提出的审批、元数据、状态机、CI、全局 ID 等建议应撤回。[B]
这段对话使最终方案的简洁性不再只是 frontend 8 月 13 日的一次项目实践,而成为用户明确表达的治理原则:不为假想的组织流程添加额外层级,当前协作中由用户明确确认决定即可。[A+B]
10.2 15:11:把“用户明确确认”写入规范
用户要求原句加入:
用户在任务中明确确认的决定视为已经作出;Agent 不得将提议、推测或未确认方案写成有效决定。
15:11 的补丁把这句话加入 current 规则。[A+B]
这句话补上了“决定何时成立”的最小闭环,同时避免引入 owner、approver、状态字段或审批系统:决定的有效性来自用户在任务中的明确确认,Agent 只能记录,不能自行把建议升级为决定。[C]
10.3 15:11—15:14:发现规范确实容易被读成“每项变更必须 spec+plan”
用户随即追问:现有文档是不是要求所有变动都在 changes 生成 spec 和 plan?其真实意图只是“如果变动过程中生成了这些文件,就放到 changes”。[A]
Assistant 复查后确认:4.4 节接近本意,但 6.1 节的无条件流程确实容易被读成强制每次创建 spec 和 plan。[B]
用户确认最小修改,15:13 补丁完成三处澄清:
- 规范只管理已生成变更材料的存放和归档,不规定什么变更必须生成文件;
- “同一个 Change 如果生成了 spec 和 plan”,二者才共享日期和 topic;
- 生命周期改为“如任务产生 spec、plan 等材料,则保存到 changes;结束后移动已有材料”。[A+B]
这不是放弃 spec/plan,而是把“材料类型”和“生成义务”分开:有 spec/plan 时必须按统一生命周期治理,没有生成时不补造空文件或事后伪造过程。[C]
这一点也与三个项目已有事实一致:ShotMarker 的 active Change 只有 spec;frontend 的对齐 spec 明确拒绝为已经结束的测试改动倒填事前 spec/plan;空 changes 只保留 .gitkeep。[B]
11. 第八阶段:一次真实误读促成最终作用域防线
11.1 2026-08-20 12:07:问题不是假设,而是已经发生
用户在第二段对话中贴出一个实际错误:Agent 把“单份 current 不超过 300 行”误读为 spec 也要控制在 300 行内;用户还说明,有的项目执行时把 300 行套到了 archive/changes 的 spec 和 plan,而这不是原意。[A]
Assistant 诊断为:原文只用正向措辞说明 current 的限制,却没有同时写出目录专属规则不能向其他目录类推;Agent 仍可能把一个醒目的数字扩展成全局文档规则。[B]
11.2 12:10:四层澄清进入最终文件快照
用户要求修改后,实际补丁加入四层防线:
- 核心模型新增通用作用域原则:某一目录的内容、长度、维护要求不得类推到其他目录;
- changes 明确写出 spec、plan 和 changes/archive 其他材料不受 current 的 300 行限制;
- 第 8 节标题从“简洁性要求”改为“current 的简洁性要求”;
- 正文和可复用 AGENTS 规则都使用“仅对单份 current 文档设置 300 行上限”,并显式否定对 changes/archive 的适用。[A+B]
同时,spec/plan 的拆分标准被明确为“变更范围和内容边界”,不是行数;质量标准是完整、无歧义、足以支持实施与验证。[B]
这一步揭示了最终规范写法上的一个重要演进:只写“某规则适用于 A”不一定足够;对于很容易被 Agent 泛化的规则,还要写“不得用于 B/C”,并在入口规则中重复关键反向约束。[C]
11.3 13:13:全项目审计确认“没有硬写错,但入口缺反向约束”
用户要求按最新规则核对三个项目,尤其是 AGENTS.md、根 README 和 docs/README.md。[A]
审计结果是:没有任何文件明确写成“spec/plan 不得超过 300 行”,所以当时不存在已经写错的硬规则;但三个项目各自的 AGENTS.md 和 docs/README.md 共 6 个入口文件都缺少最新版的显式反向约束,仍有再次误读的风险;三个根 README 无需修改。[B]
行数核对还提供了现实验证:
zhangrh.shop的 current 最大 124 行;- ShotMarker 的 current 最大 75 行,但 active spec 为 563 行;
- frontend 的 current 最大 235 行,但 active plan 为 1,434 行。
后两项尤其证明:若把 300 行全局化,会把本来合法、需要完整支持实施的变更材料错误判为违规。[B]
11.4 14:01—14:28:规则传播、合并和独立复核
用户要求三个项目分别用隔离 worktree 修改、合并到 main/master,并再用三名独立 reviewer 检查。[A|历史执行授权]
最终本地合并提交为:
| 项目 | 分支 | 提交 | 结果 |
|---|---|---|---|
zhangrh.shop |
main |
be6864c |
两份入口补充目录作用域、current-only 300、spec/plan 非强制等规则 |
ShotMarker |
main |
4c64ca2 |
同上;保留 563 行 active spec 的合法性 |
frontend-observability-server |
master |
9301ca7 |
同上;治理提交在新的 metrics-registry 基线上安全重放 |
执行中还有两项有据可循的安全处理:
- frontend 的基线被外部流程推进,治理提交没有强行合并旧基线,而是核对新 master 后重放;
- ShotMarker 的 Watch 基线最初因两个同名模拟器造成 destination 歧义,随后改用唯一 UDID,确认不是测试失败。[B]
三名未参与实现的 reviewer 都报告无 Critical、Important 或 Minor 问题。历史会话记录的验证结果为:
zhangrh.shop:194 项测试通过;- ShotMarker:iPhone 164/164、Watch 30/30、Release Simulator build 通过;
- frontend:类型检查、构建、31 项测试和文档链接检查通过。[B]
这些测试不能证明治理思想“绝对正确”,但可以证明最终澄清已被一致写入三个项目入口,且落地没有破坏当时的项目基线。[证据边界]
12. 最终方案各核心思想是怎样收敛出来的
12.1 三态不是三种文件格式,而是生命周期
最终模型只问一个问题:这份材料现在处于什么生命周期?
- 仍然有效的事实和决定 → current;
- 正在讨论、准备或执行的变更材料 → changes;
- 已经完成、取消、替代或结束,但仍值得回看的材料 → archive。
frontend 的复杂实验曾用“类型、状态、权威”三个维度同时分类,后来明确删除;ShotMarker 的迁移则证明产品、架构、质量、发布等只是 current 的项目内主题,不是全局固定分类;changes/archive 也不再按 spec、decision、incident、topic 等继续建目录。[B]
因此,最终方案选择“少量稳定语义 + 项目自行决定主题”,而不是建立一个覆盖所有文档种类的分类学。[C]
12.2 Git 与 archive 的职责最终被拆开
形成过程中出现过两个看似矛盾的实践:
- 7 月 29 日,
zhangrh.shop删除 30 份历史设计/计划,理由是 Git 可恢复; - 8 月 19 日三个项目迁移时,又把已结束但有价值的 spec、plan、讨论和验证移入 archive,而不是全部删除。
最终规范把这两者统一起来:
- 不在 archive 复制同一个文件的每次修改版本,因为 Git 已经保存 diff;
- 但一份已结束材料本身如果包含值得直接查阅的背景、取舍、排查或验证,仍作为一个历史文档进入 archive;
- current 被改写时,旧正文通常不用再复制一份快照到 archive;Git 已保存旧版本,只有具有独立历史阅读价值的材料才归档。
这是一种“版本历史”和“知识材料”分工,而不是“Git 或 archive 二选一”。[C,基于多个 B]
12.3 current 从“权威目录”进一步变成“可维护的结论层”
最终 current 规则来自多轮实践叠加:
- frontend 的接口/健康路径冲突说明需要单一当前来源;
- frontend 的 1,464 行 current 说明权威目录也可能过度膨胀;
- ShotMarker 的 247 行综合状态页说明单一入口不能包办所有主题;
- 8 月 18 日按事实源重构说明文档应按职责、变化节奏、证据来源拆分;
- 稳定文件名实验说明 current 是持续维护的结论,不是日期快照;
- 用户在第一段讨论中明确增加简洁、准确、可靠、人类可读、常用词命名和 300 行规则;
- 8 月 20 日误读又把 300 行严格限定在 current。
因此,300 行只是完整 current 设计中的一个护栏。它不能脱离“完整、可独立维护的当前结论”“不靠长段落规避”“按范围与证据合理拆分”单独使用。[C]
12.4 事实与决定需要两套证据逻辑
最初的统一优先级把代码放在 current 之前,适合判断实现事实,却会产生一个危险推论:只要代码没实现,已经确认的决定就自动无效。
用户接受的 1.2 修正把问题拆开:
| 要回答的问题 | 最高依据 | 冲突如何处理 |
|---|---|---|
| 现在实际实现、构建、发布或上线了什么? | 当前代码、测试、构建、当次外部验证 | 重新核验并修正 current 中的实现事实 |
| 当前已经生效的决定、契约或政策是什么? | current 中明确记录且仍有效的内容 | 代码不一致时保留决定,同时展示实现差距并作为缺陷 |
frontend 在 9dee37a 中把 /readyz、指标接口和部署等“仍未实现”与“V1 决定仍有效”同时写入 current,是这一原则最具体的项目实例。[B]
第二段对话再补充决定来源:用户在任务中明确确认即视为已经作出;Agent 不得把建议、猜测或未确认方案升级为决定。这以最小规则解决了“谁让决定生效”,没有引入审批系统。[A+B]
12.5 spec/plan 被保留为有价值的材料,但不被制度化为每次必产物
项目历史同时显示两件事:
- 大型、需要设计与执行步骤的 Change 确实通过 spec/plan 获得了完整上下文;
- 真实项目也存在只有 spec、没有 plan的 active Change,存在完成后只有诚实记录而没有事前 spec/plan 的小变更,也存在完全不需要文档材料的格式修改。
最终规范因此规定“如果生成,就放 changes 并在结束后归档”,而不是“每次必须生成”。同一个 Change 同时有两份材料时才要求共享日期/topic。是否拆分依据内容和范围,不依据 300 行。[A+B]
这也解释了为什么 changes 必须保持简单和扁平:它是活动材料集合,不是一个强制工作流状态数据库。[C]
12.6 archive 的组织方式来自规模反馈,而不是预设分类
flat archive 在初始模型中是为了避免每个 topic 建小目录;用户实际铺开后发现文件太多,才提出月份层。最后选用 YYYY-MM,是对两种需求的折中:
- 比完全扁平更容易浏览;
- 比按 topic/type 建多层目录简单;
- 文件的原始日期和月份目录天然一致;
- changes 仍扁平,活跃材料不会被时间层级分散。
“按需建月份、不建更深目录”保留了 8 月 13 日精简实验中的克制原则。[A+B+C]
12.7 可见性与生命周期被有意正交化
current / changes / archive 不等于“公开/内部/机密”。zhangrh.shop 和 ShotMarker 的真实资料跨公开仓库与 private.local 独立仓库,促使规范明确:每个权限边界内都可以有自己的三态,但每项事实只能有一个当前权威来源。
最终规则既防止把私有基础设施值复制到公开文档,也要求公开仓库在私有仓库不可用时仍能说明公开代码、接口和部署契约。这不是把公开文档写成空壳,而是用摘要和引用控制重复。[B+C]
12.8 “简单”最终成为经过试错的约束
“简单”在这里不等于没有规则,而是只保留已被真实问题证明必要的规则:
- 复杂元数据和状态机实际建立过,随后被删除;
- 自动校验脚本实际存在过,随后因依赖过时治理模型而被删除;
- 审批、owner、review cycle 在两轮评审中被提出,又被用户明确否决;
- flat archive 起初保留,直到实际规模问题出现才改;
- 300 行作用域起初只正向声明,直到真实误读发生才增加反向约束。
所以最终方案的简洁不是“少想一步”,而是把规则增长绑定到已发生的问题,并要求新增规则能通过项目实践说明其价值。[C]
13. 被讨论、试用或建议过,但最终没有采用的方案
| 未采用方案 | 出现位置 | 没有采用的直接依据 | 最终替代 |
|---|---|---|---|
| 负责人、批准状态、生效日期、复审周期、修改流程、例外审批 | 第一段初审;第二段初审再次出现 | 用户明确认为过于复杂,当前修改均通过 Prompt 且 Git 有历史 | 用户在任务中明确确认即为决定;Git 记录修改 |
文档 type/status/authority 三维元数据 |
frontend 8 月 11 日实际实施;第二段初审又被建议 | frontend 8 月 13 日明确删除;用户再次称元数据过度设计 | 目录位置表达生命周期;current 内文字区分事实与决定 |
working/decisions/tdc/evidence 多业务目录 |
frontend 8 月 11 日 | 8 月 13 日精简提交删除空目录、占位入口和多维结构 | current/changes/archive;项目真实需要的资料按内容放置 |
| 全局 Change ID、完整状态流转 | 第二段初审 | 用户认为后续建议过度设计;Assistant 收回 | 日期 + topic;同一跨仓库 Change 各仓库分别闭环 |
| 文档 CI 自动检查作为默认要求 | frontend 曾有 scripts/check-docs.rb;第二段初审再建议 |
8 月 13 日删除;用户称自动检查过度设计 | 每次任务做与风险相称的链接、格式、工作区和测试核验 |
| 每个需求/变动必须生成 spec 和 plan | 原 6.1 无条件流程容易造成该解读 | 用户明确说明只治理已生成材料;实际项目存在只有 spec 或无文件的 Change | 条件式生成;有文件则放 changes,结束后归档 |
| 为没有 plan 的 Change 创建空 plan | 模板化结构可能诱发 | ShotMarker 治理 spec 明确“当前没有对应 plan,不创建空计划” | 不为满足模板创建空文件 |
| archive 完全扁平 | 1.1/1.2 初始方案和最初项目迁移 | 用户实际反馈文件铺开太大 | 只增加 YYYY-MM 一层,按需创建 |
| archive 只按年份 | 第一段 13:45 的比较候选 | 按年仍可能在一个目录堆积过多,用户确认按月 | YYYY-MM |
| archive 按 topic/type 建更深层目录 | 早期复杂体系和常见分类候选 | 用户希望保持简单;按月方案明确禁止 | 月份目录 + 可检索文件名 |
| current 单份 500 行 | 用户最初提议,1.4 实际写入 | 用户比较后明确确认 300 | 单份 current 300 行,并按边界合理拆分 |
| “建议 300、硬上限 500”双层规则 | 第一段比较时的可能做法 | Assistant建议避免双层复杂度,用户确认统一 300 | 单一 300 行护栏 |
| 把 300 行用于所有文档 | Agent 的真实误读 | 用户明确指出错误并要求修改 | 目录作用域原则 + explicit negative;spec/plan 按内容完整性拆分 |
| current 使用日期前缀 | frontend 8 月 13 日精简后仍保留 | 8 月 18 日设计说明持续更新文档不是日期快照 | 稳定、无日期、语义化文件名 |
| 所有技术 current 合成一个大文档 | frontend 8 月 18 日比较候选 | 会混合架构、协议和运维,变化时误触无关内容 | 按事实源、变化节奏和证据边界拆分 |
| 只做局部删句 | frontend 8 月 18 日比较候选 | 不能消除同一规则在多处重复定义 | 按事实源重构,每条规则一处完整定义 |
| 单一 ShotMarker 状态页包办全部当前信息 | ShotMarker 8 月 16 日实践 | 8 月 19 日迁移将快照归档并拆成多个主题 | status.md 做摘要入口,其余 current 分责 |
| 为已结束改动倒填事前 spec/plan | frontend v1.5 对齐时明确列为范围外 | 会伪造形成过程 | 只补诚实的历史完成记录 |
| archive 中保存 current 的每个历史版本 | 可能的历史保留做法 | 规范从一开始就把逐版本变化交给 Git | archive 保存独立历史材料,Git 保存逐版本 diff |
14. 最终规范逐节来源矩阵
以下“来源”不是声称每一行都由某一条证据机械生成,而是列出该章节最直接的可追溯前因、明确讨论或实际修正。
| 最终规范位置 | 最终规则主题 | 主要可追溯来源 | 证据强度 |
|---|---|---|---|
| 1—5 | 名称、1.5 标签、日期、适用范围 | 第一段 1.1→1.5 补丁;最终文件 | B;注意 8 月 20 日继续修改但未升版 |
| 7—16 | 目标:快速回答现在、决定、活动变更、历史;文档不替代代码/测试/Git | 三项目问题与迁移入口;1.1 已存在 | B+C;最初文字形成对话缺失 |
| 18—28 | 三态模型;Git 保存逐版本变化 | 1.1 快照;zhang 7 月清理;frontend 8 月结构精简;三项目迁移 | B+C |
| 30 | 目录专属规则不得跨目录类推 | 8 月 20 日用户报告 300 行真实误读及实际补丁 | A+B,直接因果最强 |
| 32—43 | 生命周期与可见性分开;多仓库、公开/私有、单一事实源 | zhang 8 月 19 日迁移计划;ShotMarker 私有边界提交;Track 跨仓库提交 | B+C |
| 45—65 | 标准结构;changes 扁平;archive 按月且无更深层 | 1.1 骨架;第一段 13:45 用户提出月份并确认 | A+B |
| 67 | current 不预设数量/主题,不建空文件 | frontend 8 月 13 日删除模板/占位;ShotMarker 无空 plan;三项目主题不同 | B+C |
| 71—81 | AGENTS 职责 | 三项目迁移时新增入口;第一段中文化 | B |
| 83—91 | docs/README 简短入口职责 | 三项目迁移和对齐记录 | B |
| 93—113 | current 允许/禁止内容;事实/决定清晰可靠;实现差距 | frontend 冲突与内容精简;第一段 1.2 和 1.4 补丁 | A+B |
| 115 | 用户明确确认即为决定;Agent 不得升级提议 | 第二段 15:11 用户原句和实际补丁 | A+B |
| 117—133 | current 边界、稳定无日期/常用词、证据和验证日期 | frontend 8 月 18 日按事实源重构和稳定命名;ShotMarker 外部状态;第一段 current 要求 | A+B+C |
| 135—152 | changes 保存活动材料;spec/plan 条件式生成;相同日期/topic | ShotMarker 只有 spec;第二段 15:11—15:14 用户澄清和补丁 | A+B |
| 154 | spec/plan 不受 300 行限制;按内容和范围拆分 | 8 月 20 日真实误读和补丁;项目中 563 行 spec、1,434 行 plan | A+B |
| 156 | Change 结束后不留在 changes,按文件日期归档 | 1.1 生命周期;第一段按月修改;三项目迁移实践 | A+B |
| 158—171 | archive 内容类型、月份、非当前事实源 | 三项目历史迁移;第一段按月讨论;frontend 简化 | A+B+C |
| 173—192 | 日期/topic/后缀/工具无关命名 | 三项目迁移映射;frontend stable names;第一段月目录 | B+C |
| 194—220 | 代码/产品变更及非代码讨论生命周期 | 1.1 已有;第二段改为条件式材料;第一段按月路径 | A+B |
| 222—248 | 实现事实与有效决定分别取证,冲突为缺陷 | 第一段首轮审查、用户只接受此项、1.2 补丁;frontend 实际 gap 记录 | A+B |
| 250—267 | current 人类可读、300 行、合理拆分、历史判定问题 | frontend 1,464 行精简;第一段 500→300;8 月 20 日 scope 加固 | A+B+C |
| 269—283 | 迁移步骤;优先移动和提炼,不删除有价值历史 | 三项目 8 月 19 日迁移;对 zhang 7 月大规模删除实践的进一步修正 | B+C |
| 285—303 | 日常开始/完成检查 | 三项目迁移计划和实际验证;第一段/第二段同步补丁 | B |
| 305—329 | 可复用中文 AGENTS 规则 | 第一段 12:01 翻译;每轮规则同步;8 月 20 日三项目传播 | A+B |
| 331—338 | 四句最终原则 | 1.1 已存在,最终文件保留 | B;其首次创作过程不在所给对话中 |
15. 三个项目在方案中的不同角色
15.1 zhangrh.shop:规模、重复、可见性和跨仓库
它不是最清楚展示治理过度设计的项目,却是最能说明为什么需要治理的项目。7 月已经出现 30 份、10,499 行历史设计/计划,部署文档重复且包含过时服务;8 月又必须同时处理公开产品文档、私有基础设施台账和跨项目 Track 事实。
因此,它主要支撑:
- current 作为统一当前入口;
- archive 与 Git 分工;
- 公开/私有边界;
- 多仓库单一权威来源;
- 跨仓库 Change 同步日期/topic;
- 删除重复组件文档,把跨组件事实放入 current。
15.2 frontend-observability-server:复杂度的完整摆动轨迹
它对最终方案的影响最系统,因为同一个仓库先后展示了:
候选与当前混写
→ 多目录、多元数据、多阶段晋升、自动校验
→ 治理结构本身过重
→ current/archive 简化
→ current 正文仍膨胀
→ 按事实源重构并删除预设计
→ current 稳定命名
→ 引入 changes 形成三态
→ 事实与决定分流
→ 300 行作用域澄清
因此,它主要支撑:
- 不使用文档元数据状态机;
- 不建空 evidence/working/tdc/decision 体系;
- 不默认维护专用文档校验脚本;
- current 必须按唯一事实源和职责边界精简;
- 未实现契约不能写成能力,但仍可作为有效决定;
- current 无日期稳定命名;
- spec/plan 的历史要诚实,不能事后伪造。
15.3 ShotMarker:状态摘要、真实 active Change 和外部验证
ShotMarker 的价值在于它是一款包含 iPhone、Watch、发布流程和外部服务的产品项目,文档不只描述代码。单一状态页曾试图容纳整个项目,后来被拆成 status、product、architecture、quality、release;一个很长但仍活跃的语音命令 spec 与大量结束材料同时存在。
因此,它主要支撑:
- current 可以有多个项目特有主题,不使用固定清单;
- status 是摘要入口而不是所有事实的唯一大文件;
- active Change 与结束历史必须分开;
- 只有 spec 没有 plan 是合法状态;
- spec 长度不受 current 300 行限制;
- App Store、TestFlight、真机、Analytics、GlitchTip 等变化状态必须记录验证日期或标未确认;
- 公开 archive 不应保留私有运维实值。
16. 哪些事情不能从现有证据证明
为了避免把完整叙事写成“完整想象”,以下内容必须明确留白:
- 无法还原 1.0/1.1 最初草拟的逐句过程。 两段指定对话开始时 1.1 已经存在;只知道它的内容和当天上午的迁移产物。
- 无法证明某一个项目是三态模型的唯一来源。 三个项目和 frontend 的二态精简都与它一致,但没有用户原话说“三态就是从某项目的某次提交得出”。
- 无法把所有时间先后都写成心理因果。 例如 frontend 先精简元数据、用户后在第二段对话否决元数据,二者明显一致,但没有直接陈述“我因为 8 月 13 日这次提交而否决”。
- 无法证明 300 是普适最优数字。 能证明的是用户在 500/300 比较后确认 300,并把它定位为 current 的扫描与拆分护栏。
- 无法证明所有未来项目都不需要自动化。 能证明的是当前阶段曾经建立又删除过校验脚本,用户拒绝把自动化变成通用规范;最终规则允许按真实风险做当次验证。
- 无法证明三名 reviewer 的完整独立内部思考。 能证明的是历史会话公开记录了分工、运行命令、结果和最终无问题结论。
- 无法根据本地分支状态断言远端仓库的绝对最新状态。 本次没有 fetch。
- 最终文件的“1.5”标签不足以唯一标识内容。 8 月 20 日补丁仍沿用 1.5;因此必须使用本报告记录的 SHA-256 指向精确快照。
17. 证据索引
17.1 最终文件与对话
| ID | 证据 | 定位 |
|---|---|---|
D-FINAL |
最终规范快照 | /Users/runhaozhang/Desktop/PROJECT_DOCUMENT_GOVERNANCE.md;338 行;SHA-256 如文首 |
T1 |
第一段 Codex 原始会话 | task 01a01811-7b6a-75b3-b079-d7b644796aa1;本地 JSONL /Users/runhaozhang/.codex/sessions/2026/08/19/rollout-2026-08-19T11-29-54-01a01811-7b6a-75b3-b079-d7b644796aa1.jsonl |
T2 |
第二段 Codex 原始会话 | task 01a018cd-eeb6-7de0-a626-e3f6e45c484f;本地 JSONL /Users/runhaozhang/.codex/sessions/2026/08/19/rollout-2026-08-19T14-55-44-01a018cd-eeb6-7de0-a626-e3f6e45c484f.jsonl |
17.2 zhangrh.shop
仓库:/Users/runhaozhang/Documents/project/zhangrh.shop
| ID | 提交/文件 | 证明内容 |
|---|---|---|
GZ-01 |
5f737a7 |
合并重复项目/部署说明;319+/812- |
GZ-02 |
6ed9087 |
修正文档事实边界 |
GZ-03 |
846cba2 |
删除旧脚本和 30 份历史过程文档;11,073 行删除 |
GZ-04 |
docs/archive/2026-07/2026-07-29-project-cleanup-spec.md:3-20,77-120 |
缺入口、重复、过时事实、30 份/10,499 行历史材料及 Git 恢复策略 |
GZ-05 |
a789241 |
建立共同三态入口,迁移 9 spec + 6 plan |
GZ-06 |
docs/archive/2026-08/2026-08-19-project-document-governance-migration-plan.md:5-19,73-157 |
生命周期/可见性、公开/私有、安全边界和迁移步骤 |
GZ-07 |
985ea14 |
统一更多 current 主题并删除重复组件入口 |
GZ-08 |
295c3ca |
archive 改为月份目录 |
GZ-09 |
dd83c10, 1c24f38, a0470f7 |
中文治理、事实/决定分流、Track 跨仓库权威边界 |
GZ-10 |
be6864c |
300 行 current-only、spec/plan 条件式等最终澄清进入项目 |
17.3 ShotMarker
仓库:/Users/runhaozhang/Documents/project/ShotMarker
| ID | 提交/文件 | 证明内容 |
|---|---|---|
GS-01 |
docs/archive/2026-08/2026-08-16-project-status-document-spec.md:5-83 |
单一状态页、当前结论、少量最近历史、验证日期与固定十部分 |
GS-02 |
docs/archive/2026-08/2026-08-16-project-status-snapshot.md |
实际综合状态快照 247 行 |
GS-03 |
ef5bde0 |
current 多主题、active spec、历史 archive 的整体迁移 |
GS-04 |
docs/archive/2026-08/2026-08-19-document-governance-spec.md:10-18,43-74,75-108,121-148 |
三态、主题职责、只有 spec 不建空 plan、完整迁移和验收 |
GS-05 |
f89c1ae, 2537486 |
私有独立仓库边界、公开 archive 收敛私有运维细节 |
GS-06 |
41bfda2 |
月份 archive、事实/决定对齐 |
GS-07 |
4c64ca2 |
current-only 300、条件式 spec/plan、目录作用域澄清 |
17.4 frontend-observability-server
仓库:/Users/runhaozhang/Documents/project/frontend-observability-server
| ID | 提交/文件 | 证明内容 |
|---|---|---|
GF-01 |
docs/archive/2026-08/2026-08-11-document-governance-transition-spec.md:3-14,40-170 |
原始冲突、多目录、三维元数据、状态头 |
GF-02 |
c6327e8, 0a29f60, 9439881, fcea58e, c43e56d |
复杂治理分阶段实际建立 |
GF-03 |
docs/archive/2026-08/2026-08-13-simplify-document-structure-spec.md:3-12,14-93 |
删除元数据、空目录和校验脚本;目录表达状态 |
GF-04 |
34e5085 |
精简提交,30 文件,69+/860- |
GF-05 |
docs/archive/2026-08/2026-08-18-simplify-current-document-content-spec.md:3-59,110-205 |
1,464 行 current、方案比较、事实源重构、删除预设计、写作规则 |
GF-06 |
15eaaa4, 2877060, 84a2427 |
三份 current 技术正文的实际大幅压缩 |
GF-07 |
docs/archive/2026-08/2026-08-18-use-stable-current-document-names-spec.md:3-37;1ebd1b8 |
current 稳定无日期名称;历史材料保留日期 |
GF-08 |
docs/archive/2026-08/2026-08-19-document-governance-alignment.md:3-36;5d87879 |
从二态/工具目录对齐到统一三态和跨仓库边界 |
GF-09 |
docs/archive/2026-08/2026-08-19-document-governance-v1-5-spec.md:5-19,35-63,76-100;9dee37a |
按月归档、事实/决定分流、实现差距和验证 |
GF-10 |
5946095 |
用户确认决定和条件式 spec/plan 进入项目 |
GF-11 |
9301ca7 |
current-only 300 和 spec/plan 内容边界进入项目 |
18. 对最终方案的准确概括
如果只用一句话概括,这套方案不是“把文档分到三个文件夹”,而是:
用最少的生命周期语义,把当前结论、活动变更和已结束上下文分开;让代码/验证、current、archive 和 Git 各自只承担自己擅长的职责,并用真实问题而不是假想流程决定何时增加规则。
它最终形成的关键取舍是:
- 当前结论要短、稳定、可证实,但不能把决定降格为实现快照;
- 变更材料要完整,但不是每次变更都强制产出;
- 历史要能回看,但不复制 Git 已经保存的每个版本;
- archive 要可浏览,但只增加一层月份目录;
- 多仓库可以各自维护三态,但一项事实只能有一个 current 权威来源;
- Agent 需要清楚的显式边界,尤其要防止把某一目录的规则跨目录泛化;
- 治理机制只有在真实问题出现后才增长,并应保持能被人类直接读懂。
附录 A:最终方案全文
以下为用户提供的最终文件快照全文。为了精确对应,本附录保留原始标题、版本标识、章节顺序和措辞;其 SHA-256 见文首。
项目文档治理规范
- 版本:1.5
- 制定日期:2026-08-19
- 适用范围:使用 Git 管理、由开发者与编码 Agent 共同维护的项目
1. 目标
本规范用于建立一套简单、清晰、可迁移的项目文档体系,使项目参与者能够快速回答:
- 项目当前是什么状态;
- 当前有哪些已经成立的事实和已经作出的决定;
- 正在准备或执行哪些变更;
- 过去讨论、执行和验证过什么。
文档体系不代替代码、测试或 Git 历史。它负责提炼结论、提供入口,并保存值得查阅的上下文。
2. 核心模型
文档只分为三种语义:
current = 当前仍然有效的事实和决定
changes = 正在讨论、准备或执行的变更
archive = 已经结束的过程、材料和历史记录
Git 负责保存文件的逐版本变化,不在 archive 中复制每一次历史版本。
除非条款明确说明适用于多个目录,针对 current、changes 或 archive 中某一目录的内容、长度或维护要求,不得类推到其他目录。
2.1 可见性与多仓库
current、changes、archive 描述文档生命周期,不表示可见性。
项目资料分布在多个仓库时:
- 每个仓库只维护其权限边界内的 current、changes 和 archive;
- 每项事实只有一个当前事实来源,其他仓库只保留必要摘要或引用;
- 公开文档必须在私有仓库不可用时仍能说明公开代码、接口和部署契约;
- 私有文档可以记录基础设施、生产配置和外部验证,不得保存密码、私钥、Token、AccessKey、数据库凭据或
.env实际值; - 跨仓库 Change 使用相同日期和 topic,各仓库分别更新 current、归档和提交;
- 文档专用或多项目仓库可以使用
、/current 和/changes ,实际路径写入 README 和 AGENTS.md。/archive
3. 标准目录结构
AGENTS.md
docs/
├── README.md
├── current/
│ ├── .md
│ └── ...
├── changes/
│ ├── YYYY-MM-DD-topic-spec.md
│ └── YYYY-MM-DD-topic-plan.md
└── archive/
├── YYYY-MM/
│ ├── YYYY-MM-DD-topic-spec.md
│ ├── YYYY-MM-DD-topic-plan.md
│ └── YYYY-MM-DD-topic.md
└── ...
changes 使用扁平目录。archive 只按 YYYY-MM 月份建立一层目录,不再按 topic 或记录类型建立更深层目录;月份目录仅在需要归档文件时创建。
current 不规定文档数量、固定主题或统一命名清单。项目只为确实需要独立维护的当前主题创建文档,不为满足模板创建空文件。
4. 各文件与目录的职责
4.1 AGENTS.md
AGENTS.md 是 Agent 的工作入口,记录:
- 文档目录及读取顺序;
- 文档可信度规则;
- spec 和 plan 的生成位置;
- 完成变更后的 current 更新与归档要求;
- 项目特有的验证和安全规则。
AGENTS.md 不承担完整项目说明或历史记录的职责。
4.2 docs/README.md
docs/README.md 是面向人和 Agent 的文档入口,内容应保持简短,包括:
- 三个目录的用途;
- current 文档的链接及内容边界;
- changes 与 archive 的命名和目录规则;
- 当前存在的 Change 链接;
- 文档维护流程。
4.3 docs/current
current 是读取项目现状的首要入口,必须简洁、清晰、有效,并适合人类阅读。
允许记录:
- 已通过代码、测试、构建或当前验证确认的事实;
- 已经作出且当前仍然有效的决定;
- 当前版本、风险、限制和外部状态;
- 为理解当前项目所必需的少量背景。
不得记录:
- 开发流水账或提交日志;
- 完整讨论过程;
- 已被放弃的方案;
- 详细排查步骤和原始日志;
- 已失效的旧行为;
- 可以直接从 Git 历史获得的逐版本变化。
current 中记录的事实和决定必须清晰、准确、可靠,并且明确区分。尚未实现的决定不得被写成已经实现的能力;如果决定已经生效而实现尚未符合,current 应同时明确记录有效决定和实现差距,不能把实现现状当成对决定的自动推翻。详细设计和执行计划仍应保留在 changes。
用户在任务中明确确认的决定视为已经作出;Agent 不得将提议、推测或未确认方案写成有效决定。
current 不预设文档数量、名称、组织职能或工程领域。文档可以覆盖一个主题,也可以覆盖若干紧密相关的主题;边界以能否形成完整、可独立维护的当前结论为准。
定义一份 current 文档时,应先明确:
- 它需要持续回答哪些关于项目现状的问题;
- 它完整定义哪些当前事实和有效决定;
- 哪些讨论、过程、计划和历史不在其内容边界内;
- 它依赖哪些代码、测试、构建或外部验证证据;
- 哪些内容通常被一起阅读、修改和验证。
文档边界按以下原则确定:
- 经常一起阅读、变化并使用同类证据验证的内容,可以放在同一文件;
- 变化节奏、证据来源或兼容边界明显不同的内容,应拆分为不同文件;
- 不足以形成独立当前结论的零散内容,应并入最相关的文件;
- 文件使用稳定、无日期、简短清晰且能表达实际内容的名称,使用常见、易懂的单词,不使用复杂单词、冗长组合或不必要的缩写,也不以预设分类套用项目结构;
- 容易变化的事实必须注明最后验证日期;没有在当前任务核验的外部状态必须标为未确认或保留明确的历史验证日期。
4.4 docs/changes
changes 保存尚未结束的变更材料。本规范规定变更材料的存放和归档方式,不规定哪些变更必须生成 spec、plan 或其他文件;如果任务过程中生成了这些文件,在 Change 结束前应保存在 changes。
这些材料包括:
- 已提出或已确认的设计;
- 待执行或执行中的实施计划;
- 因阻塞、暂停等原因尚未结束的 Change。
同一个 Change 如果生成了 spec 和 plan,两者使用相同的日期与 topic:
YYYY-MM-DD-topic-spec.md
YYYY-MM-DD-topic-plan.md
spec 说明要改变什么、为什么改变、范围和验收标准。plan 说明如何实施和验证。
spec、plan 以及 changes 或 archive 中的其他材料不受 current 文档的 300 行限制。spec 和 plan 应以内容完整、无歧义并足以支持实施和验证为准;是否拆分依据变更范围和内容边界,不依据行数。
Change 完成或取消后,changes 中不继续保留对应文件;文件应移动到与文件名日期对应的 archive/YYYY-MM 目录。
4.5 docs/archive
archive 是按月份组织的历史资料目录,可以保存:
- 已完成、取消或被替代的 spec 与 plan;
- 已结束的架构或产品讨论;
- 重要决定的形成过程和理由;
- 问题排查过程、根本原因和验证结论;
- 历史发布、外部服务验证或迁移记录;
- 被当前文档替代但仍值得保留的旧文档。
archive 不限制记录类型。每个文件放入与文件名日期前七位一致的 YYYY-MM 月份目录;月份目录按需创建,不再按 changes、decisions、incidents、topic 等建立更深层目录。
归档内容不是当前事实来源。仍然有效的结论必须提炼到 current;archive 只负责保存形成结论的过程和上下文。
5. 文件与目录命名
统一使用:
YYYY-MM-DD-topic.md
YYYY-MM-DD-topic-spec.md
YYYY-MM-DD-topic-plan.md
规则如下:
- 日期采用 YYYY-MM-DD;
- topic 使用简短、可检索的 kebab-case;
- 同一个 Change 的 spec 和 plan 使用相同日期与 topic;
- 日期表示事件或变更首次形成的日期,而不是移动到 archive 的日期;
- archive 的月份目录采用 YYYY-MM,并与其中每个文件名的日期前七位一致;
- 普通讨论、调查、复盘或验证记录不需要额外的 summary 后缀;
- 只有确实同时存在独立原始记录和独立摘要时,才使用 summary 后缀;
- 文件名应表达内容,不包含生成工具名称。
6. 文档生命周期
6.1 代码或产品变更
提出变更
→ 如任务产生 spec、plan 等变更材料,将其保存到 changes
→ 修改与验证
→ 将最终事实和有效决定提炼进 current
→ 将已有变更材料移入 archive/YYYY-MM
归档前必须先更新 current,避免历史材料已经移走而当前事实仍然缺失。
如果 Change 被取消:
- 在已有 spec 或 plan 中写明取消结论及原因;
- 更新受影响的 current 决定或风险;
- 将已有材料移入与文件名日期对应的 archive/YYYY-MM 目录。
6.2 非代码讨论、决定或调查
讨论或调查结束后:
- 将完整过程整理为 archive/YYYY-MM/YYYY-MM-DD-topic.md;
- 如果产生了当前仍然有效的事实或决定,将简洁结论同步写入相应的 current 文件;
- 不把原始讨论全文直接复制进 current。
7. 事实与决定的可信度
实现事实与有效决定使用不同的可信度规则,不使用同一条顺序处理。
判断当前实现、构建、发布或外部状态时,按以下顺序取证:
当前代码、测试、构建和当次外部验证
> docs/current 中对实现事实的描述
> docs/changes
> docs/archive
> 未经重新核验的旧描述
判断已经生效的决定、契约或政策时,以 docs/current 中明确记录且当前仍然有效的对应内容为规范来源。代码、测试和构建只能证明当前实现,不自动推翻有效决定。
如果当前实现与有效决定冲突,该冲突本身就是需要展示的当前事实。核验冲突后,应在 current 中同时保留有效决定并明确标注实现差距;相关修复设计和计划保留在 changes,完成后再更新 current。
维护要求:
- 不得仅根据决定、计划或旧文档推断当前实现;
- 不得仅根据当前实现推断有效决定已经失效;
- 测试、构建、发布和外部服务结果必须有实际证据;
- App Store、TestFlight、生产服务等变化状态必须标注验证日期;
- current 中的实现事实与代码冲突时,应先重新核验,再修正实现事实;
- current 中的有效决定与实现冲突时,应核验并明确展示该差距,将其作为缺陷处理;
- archive 中的历史结论不得覆盖 current。
8. current 的简洁性要求
current 中的每份文档都应适合人类阅读,并满足:
- 文件开头直接给出当前结论;
- 一个段落只表达一个主题;
- 仅对单份 current 文档设置 300 行上限;超过 300 行时,应根据 current 文档边界原则考虑如何合理拆分,不得通过合并长段落规避限制。该限制不得用于 changes 或 archive 中的 spec、plan 及其他材料;
- 能用列表说明时不使用长篇叙事;
- 只保留理解当前状态所需的信息;
- 详细背景通过链接指向 changes 或 archive;
- 删除已经失效的描述,不在正文中保留新旧两套说法;
- 历史进展最多保留极少量必要上下文,其余交给 archive 和 Git。
判断一段内容是否属于 current 时,使用以下问题:
删除这段历史过程后,读者是否仍能准确理解项目现在是什么、为什么必须这样做?
如果答案是“能”,该过程不应留在 current。
9. 迁移现有项目
首次采用本规范时:
- 盘点全部现有文档、代码事实和当前验证结果;
- 建立 docs/README.md、current、changes 和 archive;
- 从代码与验证证据提炼 current,不直接复制旧文档;
- 将仍未完成的 spec 和 plan 放入 changes;
- 按统一格式重命名日期、主题、spec 和 plan;
- 将其余已完成、已替代或纯历史材料按文件名月份迁入 archive/YYYY-MM;
- 更新内部链接以及 AGENTS.md 的文档规则;
- 检查没有丢失仍有价值的事实、决定和证据;
- 验证工作区只包含预期变更。
迁移时优先移动和提炼,不为了“干净”而删除仍有历史价值的资料。
10. 日常维护检查
开始任务前:
- 阅读 AGENTS.md、docs/README.md 和相关 current 文档;
- 确认 current 是否与代码及当前环境一致;
- 检查 changes 中是否已有同主题 Change。
完成重要功能或 Bug 修复后:
- 运行与风险相称的测试和验证;
- 更新受影响的 current 文档;
- 确认事实与决定没有混写;
- 确认受影响的 current 文档不超过 300 行;超过时按文档边界原则合理拆分;
- 将完成的 spec 和 plan 移入与文件名日期对应的 archive/YYYY-MM 目录;
- 修复移动产生的内部链接;
- 确认 archive 月份目录与文件名日期一致,且文件名符合日期与主题规则。
纯格式、注释等不改变项目状态的修改,不要求更新 current。
11. AGENTS.md 可复用规则
可将下面内容复制到其他项目的 AGENTS.md,并按项目需要补充:
## 文档治理
- 将 `docs/current` 作为当前项目事实和有效决定的简洁来源。
- 保持 current 文档简洁并适合人类阅读;事实和决定必须清晰、准确、可靠并且明确区分。
- 仅对单份 current 文档设置 300 行上限;超过 300 行时,应根据 current 文档边界原则考虑如何合理拆分,不得通过合并长段落规避限制。该限制不得用于 changes 或 archive 中的 spec、plan 及其他材料。
- current 文件名应简短清晰,使用常见、易懂的单词,不使用日期、复杂单词、冗长组合或不必要的缩写。
- 将未结束变更的 spec 和 plan 以扁平文件形式保存在 `docs/changes`,命名如下:
- YYYY-MM-DD-topic-spec.md
- YYYY-MM-DD-topic-plan.md
- 变更实施并验证后,先更新受影响的 `docs/current` 文件,再将其 spec 和 plan 移入与文件名日期对应的 `docs/archive/YYYY-MM` 目录。
- 将已完成的讨论、调查、根本原因、历史验证、被替代文档及其他已结束记录,保存为对应 `docs/archive/YYYY-MM` 月份目录中的带日期文件。
- archive 月份目录应与其中每个文件名的日期前七位一致,并且仅在需要时创建;不要按 topic 或记录类型建立更深层目录。
- 每项当前事实只在一个仓库中保留权威来源;其他仓库仅保留摘要或链接。
- 不要将私有基础设施值复制到公开文档中。
- 不得在文档中保存密码、私钥、Token、AccessKey、数据库凭据或 `.env` 实际值。
- 判断实现事实时,以当前代码、测试、构建和当次验证为准。
- 将 `docs/current` 中记录的有效决定、契约和政策作为规范性来源。
- 实现与有效决定冲突时,将冲突视为缺陷,并明确记录该决定和实现差距。
- 除非在当前任务中完成验证,否则不得将变化中的外部状态表述为当前状态;应标注最后验证日期或标记为未验证。
12. 最终原则
current 负责清楚地说明现在。
changes 负责推动下一次改变。
archive 负责保存已经结束的过程。
Git 负责保存每个文件如何变化。
原文地址: https://www.cveoy.top/t/topic/qHnM 著作权归作者所有。请勿转载和采集!