背景
来自 ADR-007(codeindex 保持无状态 — 持久化图谱归属 loomgraph)。
当前 codeindex 是线性 2-phase:scan_directory() → parse_file() → SmartWriter.write_readme()。问题:
parse_file() 一次性提取符号/调用/继承/路由,加新能力(K8s、similarity 等)要改 parser
- 没有中间表示,提取结果直接变 markdown,拿不到全局调用图(单文件视角,"谁调用了 authenticate()" 跨文件答不出)
- 不可组合(不能"跑 definitions 跳过 calls")
范围(仅内存 IR,不含持久化)
引入 GraphBuffer 内存中间表示 + 可组合 pass。纯内部重构,每 run 重建,不引入任何持久化状态(持久化归 loomgraph,见 ADR-007)。
GraphBuffer: add_node / add_edge / find_by_qn / find_edges_by_type(内存 dict + list)
Pass 协议: run(graph, files) / should_skip(mode)
- 把现有提取拆成 pass:
pass_discover / pass_definitions / pass_calls / pass_inheritance / pass_routes / pass_tech_debt
SmartWriter 改为从 GraphBuffer 读,而非直接从 parse 结果
明确不做(ADR-007 边界)
- ❌ 持久化 SQLite 图谱 / file_hashes 状态表 / 增量回读 / 损坏恢复
- ❌ sqlite-vec 向量表
- ❌ 图查询接口
- ❌ 不把全局调用图渲染进 README_AI.md(严格零输出变化;全局图只进 GraphBuffer/export)
门控
不门控——IR 有独立的内部解耦价值,与消费侧 thesis 无关,可直接开工(ADR-007 验证门控节)。
等价定义(重要)
README_AI.md 含 AI 生成描述,非确定(master 上连跑两次都不逐字节一致)。因此「README 逐字节不变」不成立。#101 的等价保证是:「确定性的一切」+「喂给 AI 的输入」逐字节不变,AI 的随机输出不在保证范围内。
等价网分三层(全是硬门):
| 产物 |
怎么测 |
PROJECT_SYMBOLS.md(纯结构) |
直接 golden 逐字节 diff |
README_AI.md 结构骨架 |
mock invoker(AI 描述→固定 stub)→ 整篇逐字节 diff |
| 喂给 AI 的 prompt |
snapshot prompt 字符串,前后逐字节 diff(防 #94-class 静默质量回归:GraphBuffer 改了喂给 AI 的 context → 结构骨架绿、AI 描述悄悄变差) |
真实 AI 跑出的 README 不纳入等价门(预期变化)。
策略:strangler(GraphBuffer 寄生在老路径旁、对拍全绿才翻转),非 big-bang。
Fixture / 验证目标
语言优先级:Python + TS(其余 php/java/swift/objc/js 不纳入 #101 等价门,但必须不崩,留后续)。
性能预算
- 峰值内存(peak RSS):≤ baseline 的 5×(上限/绊线,非目标;全局图驻留 RAM 是新增项,超 5× 说明构造有病态放大,需重想 GraphBuffer scope)
- parse 墙钟:宽松(design-philosophy:AI 占 99%,parse 非瓶颈),慢 10-20% 可接受;明显劣化才查
验收
关联
- ADR-007
docs/architecture/adr/007-codeindex-stateless-graph-ownership.md
- absorption-plan B1(N-pass pipeline)
背景
来自 ADR-007(codeindex 保持无状态 — 持久化图谱归属 loomgraph)。
当前 codeindex 是线性 2-phase:
scan_directory() → parse_file() → SmartWriter.write_readme()。问题:parse_file()一次性提取符号/调用/继承/路由,加新能力(K8s、similarity 等)要改 parser范围(仅内存 IR,不含持久化)
引入
GraphBuffer内存中间表示 + 可组合 pass。纯内部重构,每 run 重建,不引入任何持久化状态(持久化归 loomgraph,见 ADR-007)。GraphBuffer:add_node/add_edge/find_by_qn/find_edges_by_type(内存 dict + list)Pass协议:run(graph, files)/should_skip(mode)pass_discover/pass_definitions/pass_calls/pass_inheritance/pass_routes/pass_tech_debtSmartWriter改为从GraphBuffer读,而非直接从 parse 结果明确不做(ADR-007 边界)
门控
不门控——IR 有独立的内部解耦价值,与消费侧 thesis 无关,可直接开工(ADR-007 验证门控节)。
等价定义(重要)
README_AI.md 含 AI 生成描述,非确定(master 上连跑两次都不逐字节一致)。因此「README 逐字节不变」不成立。#101 的等价保证是:「确定性的一切」+「喂给 AI 的输入」逐字节不变,AI 的随机输出不在保证范围内。
等价网分三层(全是硬门):
PROJECT_SYMBOLS.md(纯结构)README_AI.md结构骨架真实 AI 跑出的 README 不纳入等价门(预期变化)。
策略:strangler(GraphBuffer 寄生在老路径旁、对拍全绿才翻转),非 big-bang。
Fixture / 验证目标
语言优先级:Python + TS(其余 php/java/swift/objc/js 不纳入 #101 等价门,但必须不崩,留后续)。
性能预算
验收
GraphBuffer+Pass协议 +Pipeline(TDD,单模块闭环)PROJECT_SYMBOLS.md逐字节不变(直接 golden)README_AI.md逐字节不变(mock invoker,Python + TS fixture)GraphBuffer查出(跨文件 CALLS 边)IndexMode.FAST可跳过指定 pass关联
docs/architecture/adr/007-codeindex-stateless-graph-ownership.md