Imported from LIANGJY1/Summary (
skills/project-decoder/SKILL.md). Install upstream withnpx skills add LIANGJY1/Summary --skill project-decoder. Copyright stays with the author.
Project Decoder(项目架构解码)
产出一份"三个月后只看文档也能上手项目"的架构解码文档:分层地图 → 主链路 → 模块与类职责 → 设计动机 → 阅读路径。学习导向:不改代码、不提重构建议(那是别的 skill 的事),只把"这个项目怎么设计的、为什么"讲清楚并落盘。
0. 铁律(先读)
- 只读代码,只写文档:唯一允许写入的是架构文档(及增量更新);绝不改代码、配置、注释,绝不执行改变仓库状态的 git 操作(log/blame/show 等只读检索除外)。
- 先定向,后判断:没完成 §1 定向、没写出心智模型假设之前,不得产出任何模块/类结论——没有心智模型的"发现"只是目录树复述。
- 证据强制:每条职责/动机结论锚定
file:line(读到的),或明确标[inferred](推出来的)——两者必居其一,混不得。无引用的结论是氛围,氛围教不了人。 - 动机考据有优先级:代码结构 > 测试名与断言 > git log/blame/commit message > ADR/README/docs > 外部资料。考据不到就老实标
[inferred],绝不编一个"听起来合理"的动机。"高内聚低耦合/为了解耦"式万金油是死结论:把类名换掉句子还成立的动机,不算动机。 - 范围先问,落盘固定:范围(全项目/子系统)未经用户确认不落盘。架构文档统一落盘
/home/liang/Project/MyProject/Summary/project/project-architecture/(固定路径,任何 workspace 都写这里;目录不存在先创建)。大项目分批(>100 个源码文件或 >10 个模块时),每批结束完整汇报,用户说"继续"才走下一批。
1. 定向(Orient,不可跳过)
目标:动手前先有一个可被推翻的心智模型假设。
- 事实面扫描:README、构建文件(pom.xml / build.gradle / package.json / go.mod / Cargo.toml / pyproject.toml…)、CI 配置、容器/部署描述——技术栈、构建方式、真实依赖(构建文件不会撒谎,README 会过时)。
- 热点定位:跑
scripts/repo_stats.sh <仓库根>(变更频次 Top、最大文件、语言分布),取 改动最频繁 × 体量最大 的交集——重点机制几乎总在交集中。 - 枢纽定位(Aider repo map 的降维近似):对候选枢纽标识符 grep 全仓引用次数,被引用最多的定义才进地图——地图放枢纽,不放全部。
- 入口点:main / Application 类 / 路由表 / 启动脚本 / 对外 API 声明处。
- 写出心智模型假设(1-2 段,落进草稿头部):分层猜想、主链猜想、3-5 个枢纽文件、与 README 矛盾的点(矛盾本身就是发现,单列)。
完成判据:假设已成文(分层猜想 + 主链 + 枢纽清单 + 矛盾点),且每个枢纽文件你都真实打开过而不是只看了文件名。
2. 验证(对照源码修正假设)
Reflexion 思路:假设是拿来被源码打脸的,不是拿来直接写进文档的。
- 主链追踪:从入口挑一条最常用用户场景(一条真实请求/一次典型调用)走到数据落地,记下途经模块。场景切入,不按目录顺序遍历。项目可构建时先跑通一次构建/测试(只读仓库状态,不算改动)——借一次真实运行穿针引线。
- 分层验证(Reflexion 三档标注):grep 统计模块间 import/include 方向,对照 §1 假设逐边标注——一致(convergent,假设成立)/ 不符(divergent,方向或形状与假设不符,修正假设)/ 缺失(absent,源码里真实存在但假设漏掉的依赖)。absent 是隐藏耦合,必须显式列出重点讲——它就是"看文档学不会、一动手就踩坑"的那类知识。
- 测试即规范:核心模块的测试名与断言是行为的可执行规格,读测试校准对职责的理解(测试名往往比注释诚实)。
- 动机考据:对疑似"有故事"的代码,按 git 考据流水线溯源——
git blame -w <文件>锁行 →git log -S"<符号>"溯源引入 →git log -L <行区间>:<文件>看演化 →git shortlog -sn -- <目录>找模块权威作者 →git log --diff-filter=A -- <文件>查诞生动机。有 ADR/RFC 的先读,按状态串决策链,被取代(superseded)的结论不引用。 - 约束先看(arc42 三分类——很多"奇怪设计"是约束的产物而非品味):组织约束(CI/发布流程/团队分工)、技术约束(锁文件/最低兼容版本/基镜像)、隐式约束(不成文的历史约定)。讲动机先排除"是不是约束逼的"。
完成判据:假设图上每条边要么有 import/调用证据(file:line),要么标记 [inferred];分层猜想被修正过的,注明修正原因;absent 依赖已列入文档的隐藏耦合节。
3. 逐模块解码
- 模块清单:按目录/构建单元列表,每个模块一行职责(一句话,EXTRACTED)。
- 核心模块出卡片(判定:主链途经、churn 高、枢纽、多实现):职责一句话 → 对外接口(caller 必须知道什么:入口方法、前置条件、错误模式)→ 关键协作(谁调它/它调谁,file:line)→ 设计动机(§2 考据结果或
[inferred])→ 雷区(易误解处)。 - 深度收口:一个模块追 3-5 条链路能预测下一条的样子即可收口——掌握系统语法后就停,防止无限下钻不交付。
完成判据:每张模块卡片 ≥3 处 file:line;所有动机有出处或标了 [inferred]。
4. 逐类职责(全覆盖 + 核心深挖)
"每一个类"的落地形态:全类一行表 + 核心类深卡片,不是每类一篇文章。
- 全类职责表:所有公共类入表——
类 | 一行职责 | 关键协作。一行职责也必须具体到"换掉类名句子就塌"(对照references/class-card.md的好坏对照)。 - 故意跳过清单:纯生成物、DTO/纯 getter、测试代码不进表,但在文档里列跳过范围与理由——覆盖率必须报实数。
- 核心类深卡片(判定:主链上、多实现接口、状态机/线程相关、churn 高):按
references/class-card.md模板(CRC 变体:职责/协作者/设计动机/不变量)。
完成判据:公共类覆盖率 100% 入表或列入跳过清单;抽 3 条一行职责做"换名测试"通过。
5. 落盘(架构文档)
- 落盘位置固定(铁律 5):
/home/liang/Project/MyProject/Summary/project/project-architecture/。命名:小项目单文件<项目名>.md;大项目(模块卡片总量 >400 行)建<项目名>/子目录——ARCHITECTURE.md只留地图 + 索引,模块/类详情进<模块>.md,主文档放条件式指针(写清何时读)。已存在同名文档 → 走增量模式并告知用户,另名需用户确认。 - 结构模板与图规范见
references/architecture-doc-template.md,动笔前必读;架构图按references/diagram-guide.md生成,随文档落盘。 - 头部锚点:源码 commit hash + 生成日期 + 范围声明——文档与代码分离存放,锚点是增量更新与信任判断的唯一依据。
- 增量模式:目标文档已存在 → 先读旧版,对照本轮发现逐节标 NEW / CHANGED / UNCHANGED,只展开前两类;不整篇重写。
完成判据:文档结构齐全(图/路径/模块/类表/开放问题)、头部有 commit 锚点、架构图过 references/diagram-guide.md 生成前检查(含 python3 scripts/check_mermaid.py <文档> 全绿)。
6. 收尾汇报(固定四段)
- 架构结论:分层与主链一段话 + 本轮学习点(2-4 条:这个项目教会你什么可带走的设计手法,带适用条件)——跨库可迁移的发现提示用户可按知识库
ROUTING.md分流沉淀; - 产出:文档路径(
Summary/project/project-architecture/下)、覆盖范围(模块数、类覆盖率实数)、证据规模(file:line 引用数)、架构图清单; - 矛盾与意外:与 README/流行说法冲突的发现、分层验证中的意外依赖方向与 absent 隐藏耦合;
- 开放问题:
[inferred]清单与需人确认的点——没有开放问题通常说明没看够,如实写"本轮未深挖"也是合格答案。
尾注:提醒用户 Summary 是 git 仓库,架构文档可 commit 固化(不自动 commit)。
7. Quality Gates(交付前自检)
- 只读验证:被分析仓库
git status --short零改动——文档一律写入 Summary 的project-architecture/,不碰源码仓。 - 证据抽查:随机抽 5 条结论,逐一验证 file:line 真实存在且内容相符;抽到的
[inferred]确认没被写成事实。 - 万金油测试:抽 3 条设计动机做换名测试——换掉类名/模块名句子仍成立的,重写或删。
- 防装懂:「看着糟但其实没问题」与「开放问题」两节非空(小项目至少有"本轮未深挖"清单);全文无"总体良好/结构清晰"式评价语。
- 覆盖实数:类职责表报告真实覆盖率,跳过清单有理由。
- 四段汇报齐全,学习点可带走。
- 架构图同源与语法:
python3 scripts/check_mermaid.py <文档>全绿;随机抽图上 3 个节点回正文 §3/§4/§7 找到对应、2 条边与 §2 分层验证方向一致(references/diagram-guide.md生成前检查)。
Quick Reference
| 情况 | 动作 |
|---|---|
| 要画哪些图 | references/diagram-guide.md 图类型表:一图流必画;主链 >5 环加时序图;部署图只认部署文件作事实源 |
| 项目巨大(>100 文件/>10 模块) | 分批按子系统,每批完整汇报;探索可派并行子代理(报告格式见 references/class-card.md 附录) |
| README 与代码矛盾 | 以代码为准,矛盾本身写入「矛盾与意外」 |
| 动机考据不到 | 标 [inferred],绝不编;多条同类推断集中列开放问题 |
| 文档已存在 | 增量模式:NEW/CHANGED/UNCHANGED,不重写 |
| 用户只要某子系统 | 范围收窄照常走 §1-§6,产出单模块深度解码 |
| 发现可迁移设计启示 | 汇报中列出,提示按知识库 ROUTING.md 分流(不主动写入) |
Common Mistakes
- ❌ 跳过定向直接按目录逐个讲 → ✅ 先成假设再验证,文档讲"验证后的理解"不讲"遍历的流水账"
- ❌ 动机全靠脑补("这显然是为了扩展性")→ ✅ 四级考据,考不到标
[inferred] - ❌ 地图塞满每个文件 → ✅ 只放枢纽与主链,5-12 个概念节点,其余靠索引
- ❌ 每类一段小作文 → ✅ 一行表全覆盖 + 核心类深卡片
- ❌ 结尾夸项目"结构清晰" → ✅ 讲矛盾、讲代价、讲开放问题
- ❌ 重跑时整篇重写文档 → ✅ 增量标记,保住历史判断