pstack 架构设计红线清单:在合成之前筛查候选设计的四项模块缺陷(Shallow Module、信息泄漏、时间分解与 Pass-through)
【免费下载链接】pluginsCursor plugin specification and official plugins项目地址: https://gitcode.com/GitHub_Trending/plugins125/plugins
在设计落地之前,先筛掉会腐蚀模块边界的形状。pstack 的architect技能将设计流程划分为 Ground → Sketch → Agree → Implement → Scrap 五个阶段,其中 Phase B(Sketch)通过arena技能并行产出多个候选设计,而references/design-red-flags.md正是这一阶段唯一强制执行的筛查关卡:任何候选设计在进入合成(synthesis)之前,都必须先对照本清单逐条体检。命中任一红旗(red flag),就意味着该形状需要被修订或直接否决。
本文围绕这份红线清单展开,逐条拆解 Shallow module、Information leakage、Temporal decomposition、Pass-through method 四类模块级缺陷的判定标准、识别信号与修正方向,并结合 pstack 仓库中 architect、arena 及其底层原则技能的源码实现,说明为什么这些红线在 AI 辅助设计语境下尤其关键——因为候选设计由不同模型并行产出,如果不在合成前用统一标准筛查,错误形状就会被当作基座缝合进最终设计。
阅读这份清单之前:它在设计流程中的位置
红线清单不是一份孤立的风格指南,而是 architect 流程的强制闸门。architect/SKILL.md明确写道:在合成之前,必须用这份清单筛查每个候选设计,拒绝或修订浅模块、信息泄漏、时间分解和 pass-through 方法。
它的上游语境是两条设计纪律:
- 设计两次(design it twice):
principle-exhaust-the-design-space规定,当正确答案不显然时,必须产出 2~3 个结构上真正不同的候选方案并排对比,再决定提交哪个;"第二种同一形状的变体"不算数。arena 的 Phase D(Pick)正是在多个候选之间选择基座(base)。 - 按接口深度比较候选:
architect/SKILL.md要求对可行的候选方案比较接口深度,优先选择"用更小、更简单的公开表面隐藏更多复杂度"的设计。一份接口可以在保持调用链短的同时,通过集中能力而不是把能力散落在各层来实现。
红线清单是这两条纪律的具体裁判工具:在把任何候选放进合成之前,先用它回答"这个形状有没有结构性缺陷"。arena 的 Phase E(Graft)会把落选者中最强的部分手工嫁接到基座上,而 Phase F(Verify)会再次验证合成结果;但如果基座本身带着红旗,后续的嫁接与验证只是在错误形状上打补丁——这正是清单存在的意义。
Shallow module:接口大而能力薄
判定标准
浅模块暴露了庞大的公开接口,却只隐藏了极少的复杂度。评判深度的方式,是比较"藏在公开表面背后的能力与策略"相对于"该表面本身的大小"。正确形态是:一个简单接口,背后支撑着实质性的行为。
需要特别澄清一个常见误解:不要把深模块与深调用链混为一谈。
- 深调用链(deep call chain)把理解分散在各层之间,读者要穿越多层才能弄清一件事;
- 深模块(deep module)把能力集中在同一个接口后面,读者只需理解一层。
调用链深不等于模块深,恰恰相反,调用链深往往是浅模块叠加的结果——每一层只转发不隐藏,读者就必须逐层追读。
识别信号
清单给出了三条可操作的观察信号,命中任何一条都应当警惕:
- 调用者需要协调多个方法才能完成一个操作。说明能力没有被封装,而是被拆散成调用者必须亲自编排的步骤序列。
- 公开选项暴露了内部阶段或实现选择。调用者要理解"内部是怎么分步的"才能正确传参,接口就把实现泄漏给了使用方。
- 学会接口并不能让调用者免于学习实现。这是最核心的判据:如果接口的抽象程度不足以掩盖实现细节,那这个接口就没有起到压缩作用。
与仓库原则的印证
这一判据与 pstack 的多条原则技能同源:
principle-minimize-reader-load提出维护成本的两个轴向:要追踪的层数(从问题到答案之间的间接层数)和要记住的状态量(读者脑中需要保持的隐藏或可变上下文)。其中"demand interface compression"一条与浅模块完全对应:宽广的接口若只隐藏很少的复杂度,读者就不得不既学表面又学实现。architect/references/runner-prompt.md给每个候选 runner 的纪律中明确写着:比较"公开表面背后隐藏的能力相对于表面大小",偏好"把复杂度拉进被调用方"的简单接口,即使实现因此变得不那么简单。
修正方向
- 优先设计小接口 + 厚实现:把策略、不变式、编排逻辑收进模块内部,让调用方只面对一个能完成整件事的入口;
- 压缩公开面:把"多个方法才能完成一个操作"重构为单一高内聚操作;
- 隐藏内部阶段:公开选项应当是领域语义,而不是实现步骤的镜像。
Information leakage:同一内部决策被多处依赖
判定标准
信息泄漏使得多个模块依赖同一个内部决策。当一个表示(representation)、策略(policy)或协议细节出现在多个地方时,修改它就需要多处协同编辑——这正是耦合的经典形态。
最典型、也最该警惕的一类泄漏是:公开地再导出传输层或线上的类型(transport / wire types)。例如把 HTTP 请求/响应结构、数据库 schema、框架对象直接暴露在公开 API 上,调用方一旦依赖这些类型,内部更换协议或存储就变成破坏性变更。
修正方向
清单给出的修正是边界纪律式的:
- 在接口背后把外部数据解析成领域类型(parse external data into domain types behind the interface);
- 让存储 schema、框架对象、协议细节保持私有(keep storage schemas, framework objects, and protocol details private)。
这与principle-boundary-discipline的边界测试完全一致:系统边界(CLI 参数、配置文件、外部 API、网络协议)负责校验与解析,系统内部信任类型、不重复校验;并明确要求"不要通过公开表面再导出传输、存储、框架或线上的类型"(do not re-export transport, storage, framework, or wire types through the public surface)。runner-prompt 中同样有对应条款:不要把传输或线上的类型放到公开 API 上,在接口背后解析成领域类型。
识别信号
泄漏往往不以"同一常量出现两次"这种显眼方式出现,而藏在类型签名里:公开函数/方法的参数与返回值是否引用了 wire/schema/framework 类型。凡是在公开面看到这类类型,就是在向调用方预告"内部实现会变",应当就地修正为领域类型。
Temporal decomposition:按执行顺序而非知识归属切分模块
判定标准
时间分解是按执行顺序组织模块,而不是按它们所拥有的知识组织模块。典型形态是一组处理管线阶段被拆成独立的 load、validate、transform、save 模块——这四个阶段常常跨越多个边界重复同一个表示及其不变式(invariants)。
后果是双重性的:
- 同一份数据的不变式(比如"这个字段必须非空且格式合法")在 load 阶段检查一遍、validate 阶段又检查一遍,逻辑被复制;
- 数据形状(representation)被多个阶段模块共享,任何形状调整都要同步改动多个文件。
修正方向
- 围绕领域知识与所有权分组代码(group code around domain knowledge and ownership);
- 不同时间运行的方法仍可以属于同一个模块——只要它们保护的是同一个决策(protect the same decisions)。
换言之:判断归属的依据不是"什么时候执行",而是"它守护哪个不变式"。load 与 save 在时间上相隔很远,但只要它们都在保护同一份领域数据的不变式,就应当住在同一个模块里,而不是按生命周期阶段拆开。
与仓库原则的印证
这与principle-encode-lessons-in-structure的"单点固化"思想一致:不变式应当被结构性地保护一次(不可能是的类型、lint、运行时检查),而不是靠多阶段模块各自重复文本式检查。时间分解正是把"一次校验"变成"多处重复"的常见来源;principle-minimize-reader-load中"derive instead of sync"(推导而非同步)也指向同一结论:同一决策只允许有一个权威来源。
Pass-through method:无信息增量的转发层
判定标准
pass-through 方法把相同的参数原样转发给另一个形状相同的方法。它没有隐藏任何复杂度,只是多加了一层间接。判断要点是"形状相同":参数与返回值的形状没有改变,层与层之间没有发生抽象转换。
为什么有害
从最小化读者负担的角度看,这种层是纯粹的税负:principle-minimize-reader-load要求"让相邻的层改变抽象"——重复相同方法与参数的层只会增加读者负担,而不产生压缩,应当折叠掉(collapse pass-through layers)。在架构审查语境中,层层转发还会造成虚假的"分层感":看起来结构规整,实际上每一层都没有承担决策,读者必须逐层追读才能确认"它什么都没做"。
修正方向
- 删除它,或者把责任移动到能够完成该操作的模块(move responsibility to the module that can complete the operation);
- 仅在转发边界确实增加了策略(policy)、适配(adaptation)或独立抽象时,才保留它(keep a forwarding boundary only when it adds policy, adaptation, or a distinct abstraction)。
"增加了策略、适配或独立抽象"与"形状相同地转发"之间的区别,就是保留层与删层的分界线:如果转发时附加了权限判定、单位换算、协议适配或新的领域语义,它就是有信息增量的边界;如果只是把 A 的参数递给 B,它就是该删的 pass-through。
四类红旗速查
| 红旗 | 一句话判定 | 核心危害 | 修正方向 |
|---|---|---|---|
| Shallow module | 接口大而隐藏的复杂度少 | 调用者既学接口又学实现 | 小接口 + 厚实现,把策略与编排收进内部 |
| Information leakage | 同一内部决策(表示/策略/协议细节)出现在多处 | 修改需多处协同编辑 | 边界处解析为领域类型,schema/框架/协议细节保持私有 |
| Temporal decomposition | 按 load→validate→transform→save 执行顺序切模块 | 不变式与数据形状被跨边界重复 | 按知识归属分组,守护同一决策的方法归入同一模块 |
| Pass-through method | 相同形状参数原样转发 | 增加层数但不产生压缩 | 删除,或把责任下沉到能完成操作的模块;只有增加策略/适配/独立抽象时才保留边界 |
四条红旗共享同一条底层判据,可以归纳为一个自问:"删掉这一层、合并这两个模块、把这段逻辑挪到别处,读者理解系统的成本会下降还是上升?"回答会下降,就动手修;回答会上升,再看是否属于上面列出的合法保留理由。
这些红线如何在仓库的合成流程中生效
红线清单是静态文档,但它的效力来自被 architect 流程强制执行,并有多条原则技能作为理论支撑:
- 筛查时机:
architect/SKILL.md规定,在 arena 完成并行探索、进入合成之前,必须逐候选筛查本清单,拒绝或修订四类缺陷——筛查发生在 "design it twice" 与 "compare on interface depth" 之间,先排除缺陷形状,再比较剩余方案的接口深度。 - 候选纪律:
architect/references/runner-prompt.md在给每个并行 runner 的提示中预先注入同类约束(interface depth、不要外泄 wire 类型、验证放边界、信任内部类型、短调用链不超过三个文件等),使候选在产出阶段就尽量不踩线;红线清单则作为合成前的最后一道闸门兜底。 - 合成记录:最终设计随
architect/references/rationale-template.md一道交付,其中 "Shape" 一节要求显式陈述接口深度——公开面隐藏了什么复杂度、还有哪些暴露给调用者、接口为何不再更小——这正是把"红线筛查结果"落成可审计文字的地方;"Alternatives considered" 一节则要求至少记录一个被否决的备选形状及其落选原因,并按接口深度而非实现简单度评判。 - 失败后的重整:如果实现阶段(Phase D)反复产生草图吸收不了的摩擦,说明当初的红线筛查可能漏判,architect 的 Phase E 要求推翻草图、按
principle-redesign-from-first-principles以"新约束本就是第一天假设"为前提重做,再回到 Phase B 重新跑 arena——新一轮候选同样要再过一次红线清单。
对于 AI 辅助架构设计,这套机制的意义尤其具体:多个模型候选在形状上天然存在差异,如果不预先定义"什么形状不能要",合成很容易选择"看起来安全的中庸解"(runner-prompt 明确警告 converging on a safe-looking middle defeats the exploration)。红线清单给了合成一个结构化的否决集,让"修订或否决"成为可执行的流程动作,而不是主观偏好。
使用建议
- 将本清单作为architect Phase B 的强制 checklist逐条过筛,不要凭整体印象放行候选;四条红旗分别对应"接口深度、类型边界、模块归属、层间抽象"四个维度,一次筛查即完成四维体检;
- 审查既有代码时同样适用:四条红旗是反模式目录,命中即标记重构点;其中 pass-through 层是成本最低、收益最直接的清理对象,时间分解次之,信息泄漏的修复通常需要动公开 API 类型,涉及面最大;
- 结合
rationale-template.md使用:把每条红旗的判定与处置写进 "Shape" 与 "Alternatives considered",让设计决策可审计、可复盘; - 记住清单开头那句总纲——a red flag is a reason to revise or reject the shape:红线不是"扣分项",而是"该改形状"的硬信号,与修改代码库相比,在合成前修订草图是成本最低的纠错时机。
【免费下载链接】pluginsCursor plugin specification and official plugins项目地址: https://gitcode.com/GitHub_Trending/plugins125/plugins
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考