假设 AI 把一个 ActionModel 字段改名。
只修改定义文件,代码仍可能看起来完整;Workflow 的转换、接收方 StateModel、DSL 订阅和对应测试却可能继续使用旧字段。
这不是提示词是否足够详细的问题,而是架构规则有没有进入修改必然经过的入口:
- 类型是否允许;
- 事件能否解析;
- 组件是否注册;
- 修改后要经过哪些外部检查。
本文只讨论这些入口,不再重复展开多租户、业务图谱和验证状态语义。
文档规则缺少失败入口
README 可以写下正确原则:View 不访问数据层、组件不直接跨层调用、发送方按 DSL 业务名称匹配、修改后必须测试。但自然语言本身不会阻止悬空订阅,也不会在模型字段漂移时主动报错。
文档仍然有价值,它负责解释为什么;工程约束还需要回答“违反时在哪里失败”。
可以先把规则放进四类入口:
| 约束入口 | 示例 | 能发现什么 | 仍不能证明什么 |
|---|---|---|---|
| 目录与组件职责 | View、Logic、Workflow、DSL 分层 | 明显的跨层依赖 | 业务行为是否正确 |
| 类型与事件模型 | ActionModel、StateModel、事件键 | 字段漂移和引用不一致 | 运行时路径是否触发 |
| 注册与编排关系 | Env、DSL、Workflow | 未安装组件、悬空订阅 | 服务端权限是否正确 |
| 完成条件 | typecheck、单测、集成、浏览器检查 | 对应层级报告的失败 | 未覆盖路径是否安全 |
这些入口的共同点不是结构更多,而是错误获得了明确位置。
事件链只负责定位影响
MSCE 中的一条典型交互是:
View Action → Workflow → Logic State
Logic Action → Workflow → View State
View 采集动作,Logic 处理内容或外部调用,Workflow 转换事件,DSL 声明安装、业务名称与订阅关系。
这条链为修改提供了可追踪路径:
- 改 ActionModel 时,沿 Workflow 找接收方;
- 改 StateModel 时,回溯谁负责构造;
- 新增组件时,检查 Env 与 DSL 注册;
- 删除事件时,确认订阅是否仍然存在。
事件链能够定位影响,不会自动证明业务结果正确。类型通过也只说明类型层没有报告冲突;数据库、权限与页面行为仍需要各自的 oracle。
领域边界交给专门契约
多租户是可执行约束的一个领域实例,但本文不再重复账号域、模块开通、RBAC、Agent Scope 与数据隔离的完整层级。它们由《多租户隔离,不是给每张表加一个 tenantCode》负责。
组件、接口和数据关系怎样形成一次修改的影响面,由《从按钮事件到最小业务子图》负责。
规则进入代码后是否真正执行、应该在保存时还是任务结束时失败,则由《一条被 continue 绕过的 Kill 条件检查》负责。
本文只保留一个职责:领域规则必须落到类型、入口、数据访问或测试中的可检查位置,不能只存在于自然语言说明中。
验证也需要对应修改层级
“运行全部测试”听起来完整,却不一定对应这次变更。更有用的是把修改类型和最低证据配对:
| 修改 | 最低检查 | 还可能需要 |
|---|---|---|
| 事件键或模型字段 | TypeScript 编译 | 事件链回归 |
| 纯逻辑 | 单元测试 | 性质或边界输入 |
| 数据访问 | 集成检查 | 真实租户与负向路径 |
| 页面交互 | 浏览器动作 | 最终页面状态 |
| 架构治理 | 注册与引用检查 | 既有行为对照 |
这张表是完成条件的分类,不表示任何一项测试能够覆盖全部风险。外部结果本身怎样建模,则进入《passed=false 里混着六种结果》的问题范围。
一次修改的完成清单
AI 开始修改前,需要回答四个问题:
- 目标组件和业务身份是什么;
- 哪些事件、模型和注册关系会受影响;
- 哪些文件和领域不允许触碰;
- 修改后分别运行哪些检查。
这不要求 AI 一次读懂整个系统,而要求工程结构能提供可查询答案。
架构对 AI 的约束不是一句“请遵守现有规则”。它应该让越界修改在类型、注册、编排或验证阶段明确失败,并让失败能够回到具体关系。