cochange-churn
静态切面看不到的架构问题,往往在**版本历史**里暴露。这是来自代码审查 git-history lens 的高信号视角。仅当处于 git 仓库时启用。
这是本 skill 最独特、最能抓**真实结构性 bug** 的 lens:职责归属、机制/策略分离、因果与不变量(并发/状态契约)、属性三分。
$ npx -y skills add AgentsMesh/AgentsMesh --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
Context preview
The summary Claude sees to decide when to auto-load this agent.
这是本 skill 最独特、最能抓**真实结构性 bug** 的 lens:职责归属、机制/策略分离、因果与不变量(并发/状态契约)、属性三分。
这是本 skill 最独特、最能抓**真实结构性 bug** 的 lens:职责归属、机制/策略分离、因果与不变量(并发/状态契约)、属性三分。
**检查项:**
**职责分配的优先顺序(GRASP 升级版):**
1. 信息专家:拥有数据的对象先承担相关行为 2. 创建者:B 包含/聚合 A 时,由 B 创建 A 3. 控制器:用例的协调由 facade-controller 承担 4. 纯虚构:当 1-3 都导致破坏内聚时,引入服务/工厂
**违规模式:**
**反例 → 修复:**
❌ class Order: # 贫血
items: List
class OrderService:
def total(o): sum(i.price * i.qty for i in o.items)
def discount(o, code): ...
def freeze(o): ...
✅ class Order:
def total() -> Money: ... # 信息专家:拥有 items 就拥有计算
def apply_discount(code): ... # 领域规则
def freeze(): ... # 状态转换
class OrderApplicationService:
def place_order(...): # 仅编排:调用 Order 行为**核心原则:机制提供「能怎么做」(how-to),策略决定「该不该做、用哪种」(what / when)。** 变更频率不同的代码不应耦合在同一层:机制稳定,策略易变。
**检查项:**
**典型分离场景:**
机制(mechanism / capability) 策略(policy / decision) ───────────────────────────────── ────────────────────────── HTTP client (能发请求) ↔ 重试 3 次 + 指数退避 文件系统 (能读写) ↔ 权限决策、路径白名单 TokenBucket 限流 (能发令牌) ↔ 每秒 100 个 / 突发 50 的配额 Process spawn (能拉子进程) ↔ 超时 30s、SIGTERM grace 500ms Background task store (能登记) ↔ evict_terminal 保留 1h 后清理
**违规模式:**
**反例 → 修复:**
❌ struct HttpClient {
fn fetch(url) { # 机制 + 策略混杂
for _ in 0..3 { ... } # 重试次数硬编码
}
}
✅ struct HttpClient { fn fetch(url) -> Result<...> } # 纯机制
struct RetryPolicy { attempts: u32, backoff: Duration }
fn fetch_with_retry(client, policy, url) { ... } # 策略 + 机制组合**核心原则:每一次状态变化都应该有明确的因(trigger)、清晰的传播路径、可枚举的后果。**
**检查项:**
**因果分析的关键问题(对每个 mutable state X):**
1. 谁能写 X?(唯一写者 vs 多写者) 2. 写 X 的 trigger 是什么?(事件 / 调用 / 定时器) 3. X 变化后谁需要感知?通过什么机制? 4. 如果传播链中断(emit 失败、消费者掉线),系统会进入什么状态? 5. X 的「合法」取值范围是什么?这个范围由什么代码保护?
**不变量分类:** | 类型 | 例子 | 保护方式 | |---|---|---| | 结构不变量 | List 永远有序 | 私有字段 + 控制写入方法 | | 顺序不变量 | status_tx.send 必须先于 ack.send | 单一 actor 写入顺序固化 | | 资源不变量 | log file 内容是 reader 可见的超集 | write_all 先于 in-memory push | | 因果不变量 | 子进程退出 ⇒ 监督者收到 | wait() 主导,禁止旁路 kill |
**违规模式:**
**反例 → 修复:**
❌ struct Task {
status: AtomicEnum, # 谁都能 store()
}
// 各处零散 task.status.store(...)
✅ struct Task {
status_tx: watch::Sender<Status>, # 单一写者
status_watch: watch::Receiver<Status>, # 多读者
}
// 只有 monitor actor 持 status_tx,外部只能 borrow_and_update> 这类问题(多写者、race、传播链断裂)几乎都是 75–100 分的真 bug,应优先报告。
**核心原则:每个属性应被归类为 identity / value / derived 中的一种,并据此选择存储与同步策略。**
| 类型 | 特征 | 存储 | 同步策略 | |---|---|---|---| | **Identity** | 用于标识对象,creation 时确定,永不变 | 不可变字段(`id: Uuid`)| 无需同步 | | **Value** | 业务真实状态 | 可变字段 + 写入控制 | single-writer | | **Derived** | 由其他属性推导 | 优先即时计算;缓存仅在测量到瓶颈时 | 缓存需绑定 invalidation 信号 |
**检查项:**
**违规模式:**
**反例 → 修复:**
❌ struct Task {
pub id: u64, # identity,但 pub mut 可改 ❌
pub status_code: i32, # 多语义混塞
pub cached_summary: String, # derived,无 invalidation
}
✅ struct Task {
id: TaskId, # newtype + 不可变(无 setter)
status: TaskStatus, # enum,三态分明
fn summary(&self) -> String { format!(...) } # derived on demand
}**与因果关系的联动:**
The AI Agent Workforce Platform. Run a hundred AI coding agents across your own machines — schedule, isolate, and steer them all from one console.
Repo: AgentsMesh/AgentsMesh
静态切面看不到的架构问题,往往在**版本历史**里暴露。这是来自代码审查 git-history lens 的高信号视角。仅当处于 git 仓库时启用。
LLM 架构审查的头号失败模式:**凭空断言结构**——声称"A 依赖 B""这里有循环""X 被多处写",却没真去查。本文件给出强制接地原则 + 各语言的实际探测命令。
经典原则做交叉验证。**这一 lens 最容易产出假阳性(教科书式建议)——严格用置信度门控,不报"理论上更优雅但无实际危害"的项。**