ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ZCode 架构治理实践:基于 architecture-policy.yaml 的模块边界与分层检查工作流

ZCode 架构治理实践:基于 architecture-policy.yaml 的模块边界与分层检查工作流 【免费下载链接】ZCodeZ.ais coding agent harness. Powerful, intelligent, extensible.项目地址https://gitcode.com/gh_mirrors/zco/ZCode点击查看免费下载导读本文围绕 ZCode 仓库内置的architecture-governance技能系统讲解其架构治理工作流如何在写代码之前用模块上下文包、分层决策与有界上下文bounded context把架构意图显式化如何在写码后通过pnpm architecture:check把违规与基线分开报告以及architecture-policy.yaml中每个字段、每条规则的准确含义。读完本文你将掌握一套可直接复制的设计先行、检查兜底的编码流程理解 managed module 的四件套module.ts、contract.ts、contract.example.ts、CONTRACT.md该如何编写并能在自己的仓库中落地同款依赖治理方案。一、这是什么既是设计指南也是提交门禁ZCode 仓库在 .agents/skills/architecture-governance/SKILL.md 中定义了一个名为architecture-governance的 Agent 技能。它的定位有两点设计指南在生成代码之前先让预期架构变得显而易见让检查器去确认一个决策而不是第一次发现这个决策提交门禁任何代码改动都要经过可执行策略architecture-policy.yaml的校验报告分为新增违规与基线违规两类新增违规是阻塞性的。技能声明中明确该技能适用于任何代码改动Use for any code change仅文档类工作可以跳过skip for documentation-only work。整个治理体系由两层构成层载体职责人/Agent 可读的决策协议SKILL.md references/ai-guidance.md规定写码前必须回答的 8 个问题、必须拒绝的 7 类形状、补丁需附带的决策记录机器可执行策略architecture-policy.yaml scripts/architecture/ 下的解析器与检查器校验模块拓扑、分层方向、文件行数、契约规模、循环依赖等硬约束SKILL.md明确要求不要在技能文件或 AGENTS.md 里重复策略规则可执行规则只以architecture-policy.yaml为准避免两份事实漂移。二、写码前的三步准备2.1 用--changed定位影响面任何改动开始前先识别变更文件和它们所属的模块pnpm architecture:check --changed--changed的选择范围是工作区相对HEAD的差异加上未跟踪untracked文件如果你要评审的是已经提交的变更请运行全量检查见下文五。该行为在 references/troubleshooting.md 中有明确说明。2.2 用上下文包做有界阅读针对目标模块生成模块上下文包pnpm architecture:context module-id # 等价的可复用包装脚本 node .agents/skills/architecture-governance/scripts/context-package.mjs module-id # 也支持输出到文件 node .agents/skills/architecture-governance/scripts/context-package.mjs module-id --output context.mdcontext-package.mjs的源码很短核心逻辑只有一行调用scripts/architecture/index.mjs导出的generateContext({ cwd, moduleId })生成内容并写至 stdout 或--output指定文件见 .agents/skills/architecture-governance/scripts/context-package.mjs。拿到上下文包后按序阅读目标模块的契约contract它直接引用的其他模块契约已存在的相关 spec 与测试。要点不要急着打开大而全的实现文件不要假设文档或测试路径必然存在要在当前 checkout 里核实。技能强调有界上下文优先使用生成的阅读包只有契约或测试证明必须读实现时才继续深挖避免把整个实现复制进提示词。2.3 先写 spec再做设计决策技能要求实现之前先写/更新 spec必要时为它新建目录。spec 至少要写明五件事行为behavior做什么所有权ownership谁拥有状态不变量invariants什么永远为真失败语义failure semantics失败时怎么办迁移边界migration boundary与旧路径如何共存/切换。如果变更跨模块、或改变了状态所有权还要在 spec 中记录该决策并在实现前新增或更新模块契约。三、核心设计决策框架五个 One技能把编码前的设计浓缩为五个决策这是整份文档的灵魂3.1 One owner单一所有者为每一份可变状态命名唯一的组件所有者。其他层只能通过它的契约读取、通过命令command驱动它不得再维护一份第二接受队列accepted queue、缓存或派生真相。这是防止状态双写、事件乱序的根本手段。3.2 One path单一路径复用已经表达该行为的既有命令、服务、钩子、适配器或契约不要为同一职责新建平行 helper。重复路径是架构腐化的头号来源。3.3 Explicit boundaries显式边界为每个新文件选择所属层为每条跨模块边选择公开契约文件只能导入自身所在层或更底层的公开表面使用模块声明的layers与layerOrder。技能给出了一个非常实用的分层速查层约束快速判断domain纯逻辑无 IO、不对外部世界await需要await那就不是 domainapp通过端口port决定副作用编排用例、注入依赖adapters执行 IO 与进程边界知道它是 sqlite / MessagePort / 定时器adaptersui只依赖本模块的contract.ts不能 import 仓库/运行时/服务实现3.4 Explicit time显式时序对异步或远程行为实现前就要写清事件顺序event order所有者/租约owner/lease幂等键idempotency key过期结果规则stale-result rule重放/恢复边界replay/resume boundary交付形态桌面端desktop还是移动端mobile。3.5 Bounded context有界上下文回到 2.2 的阅读策略优先用生成的阅读包只有契约或测试证明必要时才读更多实现。3.6 两张设计草图进行有状态变更规划时技能提供了一张紧凑草图input → single owner → command admission → state transition → contract/event └── persistence / replay / projection are derived from the owner即输入 → 单一所有者 → 命令准入 → 状态迁移 → 契约/事件持久化、重放、投影都是从所有者派生的不另立真相源。对远程或流式变更交付边界要显式区分desktop: continuous ── direct live stream ──┐ ├─ same owner and sequence mobile: replayable ─ snapshot gap repair ┘桌面端是连续直连直播流移动端是可重放快照 间隙修复两者必须共享同一个所有者与同一套序号——绝不能在一次远程流改动里把两种语义混在一起。四、写码后把新增违规与基线违规分开报告编辑完成后pnpm architecture:check --changed再次运行检查并在报告/PR 描述中把新增违规与基线违规分开同时附上变更模块、测试、状态所有者、事件顺序假设、净行数变化net line changes。关键机制是基线baseline存量违规只能通过.architecture-baseline.json抑制新违规永远保持阻塞只有当一次经过评审的变更有意改变被接受的遗留基线时才允许运行pnpm architecture:baseline:updateCI 永远不会自动刷新基线——防止基线悄悄膨胀。五、可执行策略architecture-policy.yaml 逐字段解读5.1 顶层结构与字段解析器位于 scripts/architecture/policy.mjs。策略文件包含version、modules、全局阈值与可选exceptions字段含义详见 references/policy-schema.md字段含义version策略文件版本当前为1modules[].id模块唯一标识modules[].roots模块根目录可多个modules[].managed是否受管存量遗留模块可保持managed: false不强制modules[].requires允许依赖的其他模块 ID必须是已注册的模块 IDmodules[].publicEntrypoints模块对外公开的入口如contract.tsmodules[].layers层名 → 目录名映射modules[].layerOrder分层方向顺序决定导入方向modules[].owner状态所有者/业务负责方global.maxFileLines受管源码单文件行数上限global.maxContractLines契约文件行数上限global.maxPublicMethods契约公开方法数上限global.forbidCycles禁止受管模块依赖环global.forbidDeepImports禁止绕过公开入口的深导入global.managedOnly仅对受管模块强制控制循环检测等是否只看 managedexceptions带过期时间的例外清单注意层名与顺序来自每个模块自己的配置不要假设存在全局统一的分层表maxContractLines、maxPublicMethods等只对受管模块生效。5.2 仓库中的真实示例当前仓库的策略文件 architecture-policy.yaml 中storage是唯一的受管模块可直接作为学习样本- id: storage roots: [packages/services/src/storage] managed: true requires: [shared, rpc, services] publicEntrypoints: [packages/services/src/storage/contract.ts] layers: { domain: domain, app: app, adapters: adapters } layerOrder: [domain, app, adapters] owner: desktop-settings它声明了三层domain → app → adapters、三个依赖shared、rpc、services、唯一公开入口contract.ts所有者是desktop-settings。其余如rpc、shared、provider、services、ui、web、desktop、zcode-cli等模块目前标记为managed: false存量遗留不强约束。全局阈值maxFileLines: 400、maxContractLines: 300、maxPublicMethods: 12、forbidCycles: true、forbidDeepImports: true、managedOnly: trueexceptions为空数组。5.3 检查命令的入口根 package.json 暴露了四个命令命令底层调用pnpm architecture:checknode scripts/architecture/architecture-check.mjs checkpnpm architecture:reportnode scripts/architecture/architecture-check.mjs reportpnpm architecture:baseline:updatenode scripts/architecture/architecture-check.mjs baseline:updatepnpm architecture:contextnode scripts/architecture/architecture-check.mjs context它还被接入了发布前门禁verify:pre-push会先执行lint再执行pnpm run architecture:check -- --changed。从实现看scripts/architecture/index.mjs每条违规都会用rule file detail生成 sha256 指纹取前 16 位用于与基线比对循环检测用 DFS 染色法在受管依赖图上找环仅在managedOnly开启时跳过非受管节点。六、规则目录12 条可执行规则全解完整规则表见 references/rule-catalog.md这里逐条给出含义与典型修复规则含义典型修复module-dependency跨模块导入未列入requires增加公开契约或移动集成所有者deep-import导入绕过了模块公开入口改为导入契约/index 入口cycle受管依赖图出现环拆分所有者或通过端口反转依赖max-file-lines受管源码超过行数预算按职责拆分不要加 disablemax-contract-lines契约过宽拆分能力或缩减公开面max-public-methods契约公开方法过多拆分能力或引入更窄的读写契约layer-direction某层导入了更高层实现依赖更底层的端口或移动集成所有者domain-iodomain 代码导入进程/网络/文件系统/定时器 API把 IO 移到 adapter向 domain 注入类型化端口ui-implementation-importui层文件导入仓库/运行时/服务实现依赖contract.ts暴露的端口/读模型expired-exception配置的例外已过期解决违规并移除过期例外missing-module-artifact受管模块缺少清单或契约夹具补齐模块契约、示例、测试与CONTRACT.mddisable-count受管代码新增 lint 抑制修复底层违规或添加经过评审的限时例外两条通用规则需要特别记住存量违规只能通过.architecture-baseline.json抑制新增违规永远阻塞当前解析器只解析相对导入——workspace 包名、路径别名与动态导入需要单独检查--changed只覆盖工作树差异评审已提交变更时用全量检查。七、新建受管模块四件套与 golden-module 范例添加新源码时先确定它的归属模块如果需要新受管模块就要在architecture-policy.yaml中注册它的roots、requires、layers与公开入口并让本地 manifestmodule.ts与策略保持一致。运行时与持久化细节必须藏在契约后面。交互方式按语义选型一对一交互优先类型化服务调用typed service calls状态变更用命令commands广播事实用类型化事件typed events。一个受管模块需要四件套文件职责module.ts本地清单声明id、requires、provides、publicEntrypointscontract.ts唯一的公开入口品牌标识、schema、类型化命令/事件/错误与调用方所需语义contract.example.ts契约使用示例CONTRACT.md用类型表达不出来的不变量最小合规范例位于 references/golden-module/四份文件加起来只有十几行// module.ts —— 清单 export const goldenModule { id: golden, requires: [], provides: [golden-port], publicEntrypoints: [contract.ts], } as const;// contract.ts —— 窄端口 export interface GoldenPort { ping(): Promiseok; }// contract.example.ts —— 使用示例 import type { GoldenPort } from ./contract.js; export async function useGolden(port: GoldenPort): Promiseok { return port.ping(); }!-- CONTRACT.md -- # Golden module This fixture demonstrates the smallest managed module: a manifest, a narrow port, an example, and no implementation details in the public surface.注意示例中的导入写的是./contract.js编译产物扩展名这是仓库 TS 项目遵循的 ESM 导入惯例读者在自己的模块中应保持一致。八、AI 编码时的 8 个必答问题与 7 类必拒形状references/ai-guidance.md 把治理协议进一步操作化架构治理是一套写码前决策协议编码 Agent 在产出补丁前必须能回答 8 个问题决策必须回答Behavior哪个 spec 描述目标行为哪些验收用例在变化Owner哪个模块/服务拥有可变状态并接受写入Contract最小的类型化读/写/事件契约是什么哪些调用方被允许使用Layer新代码属于哪一层导入可以往哪个方向走Reuse哪条既有路径已承担部分工作为何必须新建路径Time事件顺序、幂等键、过期结果规则、重试边界是什么Remote是否分别保持了桌面端连续交付与移动端可重放恢复Context哪些契约、spec、测试足以让 Agent 不读整个实现就开工设计阶段必须拒绝的 7 类形状渲染器或 UI 组件直接写持久化、运行时状态或第二条队列两个服务接受同一条命令、或同时宣称拥有一块状态字段新建的缓存、事件总线、适配器或 helper 复制了既有路径domain 对象导入文件系统、进程、网络、定时器或平台 API只是为了逃避定义契约而增加的跨模块深导入把桌面端continuous与移动端replayable语义混在一起的远程流改动没有显式迁移边界却波及无关模块的宽泛重构。补丁描述中还应附带一段小型决策记录owner: single state owner command path: entrypoint → owner derived views: what is projected and from where ordering/idempotency: sequence and duplicate handling delivery: desktop-continuous | web-remote-replayable | both contracts/spec/tests: bounded reading and validation set这段记录与可执行规则互补检查器能证明导入与尺寸约束决策记录则把所有权、复用与时序语义在写码前显式化。九、常见问题排查速查references/troubleshooting.md 给出了按规则的修复速查症状修复module-dependency使用公开契约或在确认所有者后同时在本地 manifest 与策略中声明依赖deep-import改用目标模块声明的公开入口cycle把共享类型移入契约或通过端口反转依赖missing-module-artifact补齐检查报告所缺的清单、契约、示例或契约文档expired-exception解决底层违规并移除过期例外不要静默延期变更文件范围不对--changed只选HEAD差异加未跟踪文件全量扫描用pnpm architecture:check已提交变更不再属于脏工作树差异基线与预期不符先查失败本身只有经过显式评审的基线变更才运行pnpm architecture:baseline:update最后一条通用提醒当前检查只解析相对导入工作区别名与包级导入需另行核查检查通过并不证明每个依赖都被分析了。十、把整套流程串起来一份端到端清单综合SKILL.md与全部参考文档一次符合架构治理要求的代码改动遵循以下流程pnpm architecture:check --changed定位变更文件与所属模块pnpm architecture:context module-id生成上下文包按契约 → 直接引用契约 → 相关 spec/测试顺序有界阅读并在 checkout 中核实路径存在实现前编写/更新 spec行为、所有权、不变量、失败语义、迁移边界完成五个设计决策单一所有者、单一路径、显式边界、显式时序、有界上下文必要时附上状态迁移草图和桌面/移动交付边界跨模块或改状态所有权时更新 spec、先改模块契约编写代码遵守模块层方向跨模块边先加依赖或公开契约pnpm architecture:check --changed复查新增违规与基线违规分开报告附上变更模块、测试、状态所有者、事件顺序假设与净行数变化只有经评审的有意基线变更才运行pnpm architecture:baseline:updateCI 永不自动刷新基线。这套流程的实质是把架构决策从事后检查前移到写码之前——机器可执行策略负责证明导入与尺寸约束决策协议负责让所有权、复用与时序语义显式化二者共同构成 ZCode 持续演进的架构护栏。相关资源技能主文档.agents/skills/architecture-governance/SKILL.md策略文件architecture-policy.yaml策略 schemareferences/policy-schema.md契约规范references/module-contract.md规则目录references/rule-catalog.mdAI 编码指导与反模式references/ai-guidance.md排查指南references/troubleshooting.md最小合规范例references/golden-module/上下文包生成脚本scripts/context-package.mjs检查器实现scripts/architecture/index.mjs、scripts/architecture/policy.mjs赞分享【免费下载链接】ZCodeZ.ais coding agent harness. Powerful, intelligent, extensible.项目地址https://gitcode.com/gh_mirrors/zco/ZCode点击查看免费下载相关推荐Genshin Impact Model Importer深度技术架构解析3DMigoto定制化框架的工程实现Genshin Impact Model Importer深度技术架构解析3DMigoto定制化框架的工程实现 Genshin Impact Model Im数据库OLAP数据仓库大数据湖仓一体数据分析ZCode 架构治理策略 Schema 完全解析architecture-policy.yaml 的模块、阈值与规则体系ZCode 架构治理策略 Schema 完全解析architecture policy.yaml 的模块、阈值与规则体系 导读 ZCode 仓库Z.ai 的DBX Rust 工作区模块边界架构解析dbx-core 编排层与九大底层 Crate 的依赖治理实践DBX Rust 工作区模块边界架构解析dbx core 编排层与九大底层 Crate 的依赖治理实践 DBX 是一个轻量级跨平台数据库客户端覆盖 MySQ数据库客户端数据库桌面应用CLI后端MCP 服务AI 应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表