| name | code-odor |
| description | 检测不健康代码与工作过程的特征信号:大量/深层嵌套的 if-else 与分支;兼容/fallback/兜底/混合方案/快速实现等字样;反射/能力探测隐蔽变体(异常做能力判定、getattr 私有穿透、dir() 枚举、字符串嗅探)。在代码与智能体工作过程双维度扫描,命中即触发自我质询协议,快速定位可能的代码异味/架构缺陷/设计缺陷,并区分可自主修复与必须上报。与 code-quality(判定与处置基准)、self-grill(面向不清晰项的质询)、grilling(对用户质询)配合。Triggers on "代码异味", "不健康代码", "特征扫描", "异味检测", "工作过程自查", "冗余分支", "嵌套if", "反射扫描", "能力探测", "code smell", "smell scan", "红旗扫描". |
不健康特征检测(Code Odor Scan)
检测"可能藏有代码异味 / 架构缺陷 / 设计缺陷"的特征信号——不仅在代码里,也在智能体自己的工作过程中。命中信号只意味着"这里值得停下来审问",不代表一定有缺陷;判定交给 code-quality,修复交给 code-workflow。
一、特征信号清单
A. 代码维度(结构 / 命名 / 注释)
控制流复杂度:
- 深层嵌套 if-else(3 层及以上、且内层重复相似判断)
- 过多平铺 if-else 分支(分支数远超可穷举的有限状态,且无数据驱动 / 分派表)
- 用分支模拟"类型/能力/协议分派"(本应由多态 / 协议 / 分派表承载)
- if 分支内套 try/except 或相反,异常被当控制流用
措辞信号(命名、注释、文档字符串):
- 兼容类:
compat / shim / legacy / backward / 兼容 / 过渡 / 历史遗留
- 兜底类:
fallback / 兜底 / 回退 / 备选 / 默认路径 / 保底
- 取舍类:
混合方案 / 混用 / 双轨 / 两套并存
- 仓促类:
快速实现 / 简单起见 / 暂时绕过 / 先这样 / 临时 / TODO(fix later) / workaround
- 防御类:
hasattr 探测能力 / getattr(..., <默认>) / 静默 except
反射/能力探测信号(隐蔽变体,命中只是信号,非结论):
- 用
except AttributeError/KeyError 做能力判定(真实错误被吞 → 误报)
getattr(obj, '_私有', default) 跨对象穿透私有属性(同类内部访问自己不违规)
dir(obj) 全量枚举绕过分派表/白名单
in str(exception) 字符串嗅探分类错误
type(x) is X 替代 isinstance(子类失配)
- 对已知类型实例上基类恒有成员做 hasattr(恒真死守卫)
B. 工作过程维度(智能体自己的产物)
在工作计划、方案陈述、决策记录、commit message、文档、对用户的回复中自查以下字样或等价意图:
- "为了兼容旧……" / "保持向后兼容" / "作为过渡" / "先兼容"
- "fallback 到……" / "兜底为……" / "回退到默认"
- "快速实现" / "简单起见" / "暂时绕过" / "先这样,后续再修" / "临时方案"
- "混合方案" / "新旧并存" / "两套都保留"
- "避免破坏现有……"(为迁就现状而非架构理由)
这些字样出现在工作过程中,往往意味着当时做了一个未审视的妥协——复查时回到该处审问。
二、扫描方法
- 代码扫描:对目标代码(或全仓改动范围)执行特征 grep:
grep -rnE "compat|shim|legacy|backward|兼容|过渡|历史遗留|fallback|兜底|回退|混合|双轨|快速实现|简单起见|暂时绕过|先这样|workaround|TODO" --include=实现文件
grep -rnE "except *:|hasattr\(|getattr\([^,]+,[^,]+," --include=实现文件
- 工作过程自查:回读本会话 / 本任务的方案、决策、commit message、文档与对用户的回复,逐条对照 §一.B 的措辞信号。
- 记录命中点:每个命中记
file:line(代码)或「决策/commit/文档 位置」(工作过程),不立即判定。
三、自我质询协议(命中信号时强制执行)
对每个命中点,逐条自问并记录结论:
"这里是不是有什么架构或设计缺陷?该方案是不是某种 tricky 方案或兼容性解决方案?目前的限制是什么——只是架构/功能设计上不足(可修复),还是无法修复的缺陷,还是某种绝对充足合理的技术方案选择?"
判定分界:
- 允许:功能上合理、且从设计上就明确需要一条 fallback 失败链路的(如协议声明的可选能力、显式降级路径)。
- 禁止:为了规避检测到的架构问题而做的 fallback / 兼容 / 兜底。遇到此类,首先考虑修复架构问题本身,而不是用 fallback 绕开。
追问清单(辅助质询):
- 根因是什么?是底层数据结构缺陷、层边界错误,还是设计未统一?
- 这个分支/兜底是"语义上必需"还是"掩盖了某个更早的坏决定"?
- 如果从零设计,还会有这个兼容路径 / 混合方案吗?
- 放弃它,会让哪个调用方 / 哪个测试 / 哪个文档失效?那是真依赖还是惯性?
四、处置:区分自主 vs 上报
- 可自主修复:确认是掩盖型兜底 / 双通道 / 过时结构,且修复根因不涉及对外契约或重大取舍 → 按
code-quality 判定、code-workflow 执行。
- 必须上报:无法判断"是否合理技术选择",或修复涉及架构取舍 / 破坏性变更 / 需要用户意图的 → 记入待决项,交给用户(可用
self-grill 整理后经 grilling 或直接上报)。
五、与相关 skill 的分工
code-quality:对命中信号的判定与处置基准(三条红线、分类速查、兜底判定分界)。
self-grill:面向"不清晰 / 未决断"项的完整自我质询(不限于异味信号)。
grilling:对用户的质询(用户要求被拷问计划/设计时)。
- 本 skill 只管发现与初步定位,不产终局判定。