反模式与不变量

wesgine 架构中严格禁止的编程模式——违反即为架构 Bug。


L0 级:违反公理

最严重的反模式,违反即 PR 直接拒绝。

L0-1:Hypervisor 调业务方法

// ❌ 禁止
hyp.Chat(...)
hyp.Run(...)
hyp.Memory().Save(...)

// ✅ 正确
cell, _ := hyp.Cells().Get("dept-legal")
cell.Runtime().Run(ctx, req)
cell.Memory().Save(ctx, entry)

L0-2:Actor 缺失

// ❌ 禁止 — 只传 Tags 不传 Actor
req := AppRunRequest{
    Tags: map[string]string{"actor": "alice"},
}

// ✅ 正确 — Actor 是一等必填字段
req := AppRunRequest{
    Actor: "alice",
    Tags:  map[string]string{"actor": "alice"}, // 自动同步
}

L0-7:SSE 断开取消 Run

SSE 连接断开 ≠ 取消 Run。Run 生命周期始终与传输层解耦。


L1 级:违反设计契约

L1-2:URL path 外传 Cell ID

❌ X-Cell-ID: dept-legal
✅ /cells/dept-legal/run

L1-7:在 Hypervisor 层挂外设

// ❌ 外设必须 per-cell
hyp.AttachChannel(...)

// ✅ 正确
cell.Channels().Register(...)

L1-9:OwnerID 残留

// ❌ v0.2 遗留
req.OwnerID = "user123"

// ✅ v1.0
req.Actor = "user123"

子进程安全

只有一个原语生成子进程

// ❌ 禁止裸 exec
cmd := exec.Command("go", "build")
cmd := exec.CommandContext(ctx, "npm", "test")

// ✅ 唯一原语
cmd := proc.Command(ctx, "go", "build")

proc.Command 自动建进程组、cancel 时 SIGKILL 整个组、WaitDelay 封顶。


行式输入安全

bufio.Scanner 超限 = 截断

// ❌ 危险 — 默认 64KB 上限,超限静默截断
scanner := bufio.NewScanner(reader)
for scanner.Scan() { ... }

// ✅ 使用 lineio
reader := lineio.NewReader(r, lineio.Config{...})

记忆安全

无主条目

// ❌ 写入不带 actor → 无主条目泄漏
store.Save(ctx, MemoryEntry{Content: "..."})

// ✅ saveCore 单点校验 actor
store.Save(ctx, MemoryEntry{
    Content: "...",
    Actor:   "alice",
})

页外过滤

// ❌ 先拿一页再按 actor 过滤
rows := list(limit=100)
filtered := filterByActor(rows, actor)

// ✅ 谓词下推到 SQL,在 LIMIT 之内
rows := list(limit=100, actor=actor)

验证标准

每一行 diff 都能直接追溯到用户请求。PR diff 里不应有"顺手改的"无关变更。