研发协作
新增抽象、引入文件格式/I/O 边界、修复涉及 3+…
在代码新增抽象、新文件格式/I/O 边界、同一修复触及多文件、出现 guard/skip、出现意外文件系统错误或提取跨包共享代码后,用 indexion 做文本/结构/概念三级重复检测、修复、SoT 合并与验证。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
新增抽象、引入文件格式/I/O 边界、修特定
解决思路
- 按三级重复分类:文本级用 plan refactor 找复制粘贴代码块和相同函数;结构级用 plan solid 找跨包抽取候选、用 plan unwrap 找 trivial wrappers;概念级用 explore 加人工分析找同一领域概念被独立实现。
- 记住难度:文本级重复容易发现和修复;概念级重复最难也最危险,因为它没有复制粘贴匹配,但改一个概念需要更新所有分散实现。
- Phase 1:从高置信度文本重复开始。运行 indexion plan refactor --threshold=0.9 --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' cmd/indexion/,再对 src/ 运行同样命令。
- 读取 plan refactor 输出的三段:Similar Files 表示整体高度相似文件,调查是否可做结构整合;Duplicate Code Blocks 表示文件间行级相同代码,抽取到 @common 或共享模块;Function-Level Duplicates 表示基于函数体 TF-IDF 的结构相似函数,统一为单一 SoT function。
- 优先处理同文件重复:一个文件内函数相似度 90%+ 是最高价值目标,最容易修、收益最清晰;例如 get_global_data_dir 和 get_global_cache_dir 共享 95% 结构,抽取为 resolve_os_dir。
- 合并前用 grep 追踪引用:indexion grep "TypeIdent:TfidfEmbeddingProvider" src/;indexion grep --semantic=name:is_whitespace src/。
- 修复后重跑同一阈值确认重复消失:indexion plan refactor --threshold=0.9 --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/ cmd/indexion/。
- 降低阈值继续迭代:indexion plan refactor --threshold=0.85 --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/。
- plan refactor 可用选项:--threshold=FLOAT 默认 0.7,最小相似度;--strategy=NAME 默认 hybrid,可选 hybrid、tfidf、bm25、jsd、ncd;--fdr=FLOAT 默认 0,FDR 校正;--style=STYLE 默认 raw,可选 raw、structured;--format=FORMAT 默认 md,可选 md、json、text、github-issue;--name=NAME 项目名(structured style 用);--include=PATTERN 可重复;--exclude=PATTERN 可重复;-o, --output=FILE 输出文件,默认 stdout;--specs-dir=DIR 默认 kgfs。
- 清理后仍保留的停止信号:平台 stubs(native.mbt / stub.mbt)是有意的平台分支;类型方法相似(不同类型上的 to_string)是不同型同模式;CLI 命令样板(command() 函数)是 @argparse API 模式,不是重复;语义不同函数(is_disqualifying_keyword vs is_skip_token)目的不同。
- Phase 2:清理各目录内部重复后,查找应跨包共享的代码。运行 indexion plan solid --from=src/a,src/b;可指定抽取目标 --to=src/common;可用 --strategy=apted 做精确函数级树编辑距离匹配;可用 --threshold=0.95 更严格;可用 --include='*.mbt' --exclude='*_test.mbt' 过滤文件。
- 区分 plan refactor 与 plan solid:plan refactor 范围是目录内部重复,目标是在代码库内合并,输入 <path>;plan solid 范围是跨目录重叠,目标是抽取共享代码到新包,输入 --from=dirA,dirB。
- plan solid 可用选项:--from=DIRS 必需,源目录(逗号分隔或可重复);--to=DIR 抽取目标目录;--rules=FILE 规则文件 .solidrc;--rule=RULE 内联规则(可重复);--threshold=FLOAT 默认 0.9,最小相似度;--strategy=NAME 默认 tfidf,可选 tfidf、apted、tsed;--include=PATTERN 可重复;--exclude=PATTERN 可重复;--format=FORMAT 默认 md,可选 md、json、github-issue;-o, --output=FILE 输出文件,默认 stdout;--specs-dir=DIR 默认 kgfs。
- 跨包抽取流程:先对每个目录单独跑 plan refactor 清理内部重复;再跑 plan solid --from=dirA,dirB 找跨目录抽取候选;按 plan 的建议抽取共享代码;用 indexion grep "TypeIdent:SharedType" 验证所有引用都已更新。
- Phase 3:合并后清理无价值的简单委托函数。先用 indexion grep --semantic=proxy src/ 快速检查;再用 indexion plan unwrap --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/ 生成详细报告。
- 用 plan unwrap 预览改动:indexion plan unwrap --dry-run --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/,此模式安全且不修改文件。
- 用 plan unwrap 应用修复:indexion plan unwrap --fix --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/,然后运行 moon test --target native。
- plan unwrap 检测对象:函数体是单次函数调用,且所有参数作为简单标识符转发,没有控制流、没有转换。例如 fn matches_pattern(text : String, pat : String) -> Bool { @glob.glob_match(text, pat) }。
- plan unwrap 默认排除:self-delegation,如 fn length(self : MyList) -> Int { self.items.length() };bare constructor,如 fn emit(value : String) -> Action { Emit(value) };用 --all 可包含这些。
- plan unwrap 模式:Report(默认)列出找到的 wrappers;Preview(--dry-run)显示所有编辑但不修改文件;Fix(--fix)应用编辑。
- plan unwrap 可用选项:--dry-run 预览编辑;--fix 应用编辑;--all 包含 self-delegation 和 bare constructor wrappers;--include-self 包含 self.field.method 模式;--include-bare 包含 bare constructor wrappers;--include=PATTERN 可重复;--exclude=PATTERN 可重复;--format=FORMAT 默认 md,可选 md、json、text;-o, --output=FILE 输出文件,默认 stdout;--specs-dir=DIR 默认 kgfs。
- 删除 wrapper 前审查:平台 wrappers(FFI、@osenv_path)是抽象层,不是意外间接;公共 API wrappers 若被外部包使用,删除是破坏性变更;始终先 --dry-run。
- Phase 4:检测概念级重复。运行 indexion explore --threshold=0.4 --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/ cmd/,找出共享词汇的文件(同一概念领域)。
- 40-60% 相似但没有结构重复的文件是概念邻居:它们使用相同术语,因为处理同一领域。对每个高相似 pair 问:“它们共享什么概念,谁拥有它?”
- 检查共享词汇与树结构:indexion explore file_a.mbt file_b.mbt --threshold=0 --strategy=apted。
- 概念泄漏常见模式与修法:若两个文件都先调用 is_X(spec) 再 Y::from_spec(spec),说明“判断 X 并配置 Y”泄漏,抽取 try_do_X(path, spec) 到拥有 X 的模块;若两个文件在内容已加载时仍 @fs.read_file_to_string(path),说明“读取文件内容”泄漏,改为把 content 作为参数传入,不要重读;若两个文件都 parent_dir(path) 再 @fs.read_dir(dir),说明“列出兄弟文件”泄漏,把目录遍历集中到 pipeline;若多个 if is_virtual_path(x) { skip } guards 出现,说明“真实 vs 虚拟路径”泄漏,用类型系统阻止 virtual paths 到达这里;若两个文件都 buf.write_string("\n"); buf.write_string(x),说明“拼接文本条目”泄漏,抽取 join_text_entries() 到拥有模块。
- Phase 5:合并到 SoT。规则 1:One concept, one module, one function。若“extract text from archive”出现在 vfs.mbt、discover.mbt 和 args.mbt,它只应属于 vfs.mbt。
- 规则 2:调用方接收结果,而不是原料。不要分别导出 is_archive_spec + ArchiveSpec::from_spec + expand_archive;导出 try_extract_archive_text(path, spec) -> String?。
- 规则 3:Guards 是症状,不是修复。if is_virtual_path(x) { skip } 意味着 virtual paths 根本不应到达这里;修源头,不修汇点。
- 规则 4:重新从磁盘读取已在内存中的内容是概念泄漏。如果 SupportedFile.content 持有文本,下游代码不应调用 @fs.read_file_to_string(file.path)。
- Phase 6:验证。重跑 indexion plan refactor --threshold=0.9 --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/ cmd/indexion/ 确认文本重复消失。
- 验证概念相似降低:indexion explore file_a.mbt file_b.mbt --threshold=0。
- 验证 wrappers 清理:indexion plan unwrap --include='*.mbt' --exclude='*_wbtest.mbt' --exclude='*moon.pkg*' --exclude='*pkg.generated*' src/。
- 运行 moon test --target native。
- SoT 合并后的预期:概念拥有者与调用者之间的文本相似度下降;调用者变短(一次 API 调用代替多步逻辑);概念拥有者可能变大,但它是唯一需要修改的地方。
- Phase 7:用测试证明不会复发。写一个从结构上阻止旧模式复发的测试,例如 test "SoT: SupportedFile.path is always a real filesystem path" { // 创建 archive,运行 load_supported_file_info;// 断言 no path contains "!/";// 断言 every path passes @fs.path_exists }。
- 该测试不检查行为,而检查 SoT invariant。
- Red flag:“I need to add a guard here”:如果给一个本不应接收特殊值的函数加 if is_special_case(x) { skip },问题在上游,调用者不应传该值。
- Red flag:“It works but prints errors to stderr”:C runtime 的 stderr 消息(如 opendir: No such file or directory)表示无效数据到达系统调用;catch 吸收错误,但 perror() 已经打印;唯一修复是阻止无效数据到达调用。
- Red flag:“I'll fix it in each command separately”:如果 explore、search、grep、reconcile、plan documentation 都需要同样修复,修复属于共享 pipeline,而不是每个命令。
- Red flag:“The similarity is just shared vocabulary, not real duplication”:在不应共享概念的模块之间出现 40-60% TF-IDF 相似度是警告;词汇匹配就是信号。
- 快速参考:问“What files are similar?”用 explore --format=list;问“What exactly is duplicated?”用 plan refactor --threshold=0.9;问“What code overlaps between packages A and B?”用 plan solid --from=A,B;问“Which functions are trivial wrappers?”用 plan unwrap 或 grep --semantic=proxy;问“What concept do these files share?”用 explore file_a file_b --threshold=0 --strategy=apted;问“Has the duplication been fixed?”则以相同阈值重跑 plan refactor。
适用边界 · 注意事项
- 未安装 indexion 或无法运行 plan/explore/grep 等 indexion 命令时,不适用。
- 只是一次性小改动、不值得引入完整三级重复分析与 SoT 合并流程时,不适用。
- 涉及公共 API 包装器、平台/FFI 抽象层或外部依赖契约时,不要按普通 wrapper 直接删除,必须先人工审查。