关于 deterministic
deterministic 是通过 IR 描述软件架构,并按固定规则验证结构与规范的命令行工具。它面向希望在 CI 中发现设计及实现偏差的团队,也支持扫描仓库和从源码重建架构。
主要功能
- 01确定性 IR 验证与 lint
- 02生成带来源信息的仓库 IR 草稿
- 03对比设计 IR 与重建代码
- 04导入 OpenAPI 和 Backstage 目录
- 05将 IR 导出为 FastAPI 或 Express
适用场景
- 01在 CI 中设置架构检查门禁
- 02审阅从仓库生成的架构草稿
- 03发现设计与实际代码的差异
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
6收录的工具列表 · 更新于 3 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| ir | any | 否 | 作为 JSON 对象内联提供的 IR 图。仅适用于小型图。 |
| irPath | string | 否 | IR JSON 文件的绝对路径或相对路径。大型图建议使用此参数。 |
| policiesDirectory | string | 否 | 包含 PolicyPack YAML/JSON 文件的目录路径。可选——没有自定义规则时可省略。 |
详细介绍
@archrad/deterministic

在你写下一行代码之前,架构就已经开始偏离。archrad validate 能在 PR 合并前,于 CI 中确定性地捕获这些问题。
将系统定义为图。ArchRAD 会编译它,根据架构规则进行检查,并通过规则代码而非主观意见,准确指出问题所在。
0.7.x 新功能 —
archrad demo无需任何配置即可运行完整示例,而archrad scan会从任意仓库生成 IR 草稿,并为每个节点标注file:line引用。本次发布中,Lint 发现只会 减少;在 0.6.x 中通过检查的内容不会因此开始失败。 请参阅变更日志。
快速开始(60 秒)
npm install -g @archrad/deterministic
archrad demo
无需 IR 文件、标志或配置——可从任意目录运行。它会检查内置示例并 展示发现的问题:
orders-api (http) ──▶ orders-db (postgres)
⚠️ IR-LINT-DIRECT-DB-ACCESS-002: API node "orders-api" connects directly to datastore node "orders-db"
Fix: Introduce a service or domain layer between HTTP handlers and persistence.
⚠️ IR-LINT-MISSING-AUTH-010: HTTP entry node "orders-api" has no auth node or auth config …
⚠️ IR-LINT-NO-HEALTHCHECK-003: No HTTP node exposes a typical health/readiness path …
接下来,在你自己的仓库上运行
archrad scan . --out draft.ir.json # draft an IR — every node cited to file:line
archrad validate --ir draft.ir.json # lint it
scan 会读取你的 Docker Compose、Kubernetes 清单、Terraform、OpenAPI、软件包清单和源
代码,然后按置信度为每个节点评分,让你了解哪些内容是解析得出的,哪些是推测的。输出是一个
标准 IR 文件——检查它、编辑它,然后提交。
已经有 OpenAPI 规范或 Backstage 目录?跳过扫描:
archrad ingest openapi --spec ./openapi.yaml --out ./graph.json
archrad ingest backstage --catalog . --out ./graph.json
提交图之后,archrad validate 就是你的 CI 门禁——退出码为 1 时会阻止合并。
功能介绍
ArchRAD 是一个蓝图编译器和治理层。你将架构定义为 IR——节点、边和允许的连接——ArchRAD 会使用确定性规则引擎对其进行验证。相同的 IR、相同的规则和相同的输入始终会产生相同的发现结果。
| 命令 | 检查内容 | 代码 |
|---|---|---|
archrad validate | 图结构 + 架构 Lint | IR-STRUCT-* IR-LINT-* |
archrad lint | 仅架构 Lint(快速内循环;跳过结构检查) | IR-LINT-* |
archrad explain <code> | 不运行检查,提供规范的规则说明 | — |
archrad policies-sha256 --dir <policies> | 为已签名的 PolicyPack 生成 archrad-policy-pack.sha256 清单 | — |
archrad validate-drift | IR 与磁盘上生成的代码 | DRIFT-* |
archrad scan | 从仓库生成 IR 草稿——拓扑、OpenAPI、清单、代码;每个节点都带有引用,并按置信度评分 | — |
archrad reconstruct | 仅从源代码生成 IR 草稿(scan 的四种信号来源之一,可独立使用) | — |
archrad ingest openapi | 从 OpenAPI 派生 IR(--spec 支持本地路径或 https URL;使用 -H 设置 URL 身份验证标头) | — |
archrad ingest backstage | Backstage catalog-info.yaml → IR(Component、Resource、API、System;Location 文件目标) | — |
archrad fragment merge | 合并 2 个或更多 IR 文件——按 node.id 取并集(冲突 → stderr);使用 --prefix-fragments 生成互不相交的并集 | — |
archrad export | 将 IR 编译为 FastAPI 或 Express + Docker | — |
导入 + 合并工作流: docs/INGEST.md。所有命令 / 标志: docs/CLI_REFERENCE.md。代码生成(export): docs/EXPORT.md。
从真实代码仓库生成 IR 草稿(archrad scan)
archrad scan 接收一个代码仓库路径,并生成IR 草稿——它绝不是最终答案,始终需要审查和编辑。该命令运行六个提取器,按需要猜测的程度分级:
| 来源 | 信号 | 置信度 |
|---|---|---|
| 拓扑结构 | docker-compose.yml、Kubernetes 清单 | 高——基于真实声明并解析得出 |
| 接口 | OpenAPI / Swagger | 中——描述了真实接口,但仅限于文档中记录的内容 |
| 基础设施即代码 | Terraform(*.tf) | 中——基于真实声明,但通过正则表达式读取,而非真正解析 HCL |
| 清单 | package.json、requirements.txt、go.mod、pom.xml | 低——驱动程序依赖关系意味着存在边,但不能证明实际使用了它 |
| 代码 | 源代码模式扫描(Node.js/TS、Python、C#) | 低——对文本进行正则表达式扫描,不理解语义 |
每个节点和边都带有 config.provenance[]——inferred_from: "file:line"、一个 confidence 值,以及发现它的提取器——因此无需盲目信任任何内容。当两个提取器描述同一事物时,scan 会将其合并(保留置信度最高的主体,并合并所有来源信息),而不是重复生成或报错。
archrad scan . --dry-run # print the draft, write nothing
archrad scan ./server --out draft.ir.json # write it
archrad scan . --extractors compose,manifest # only run specific extractors
archrad scan . --scope all # include tests, examples, docs, and demos
CLI 扫描默认使用 --scope production,因此夹具、文档示例、Storybook 故事和仅用于测试的清单不会被识别为生产环境发现项。审查对象包含这些产物时,请使用 --scope all。库调用方仍保留向后兼容的 scope: 'all' 默认值。
输出是一个常规 IR 文件——审查完成后,可以直接通过管道传给 archrad validate。完整标志列表:docs/CLI_REFERENCE.md。
实现治理(archrad reconstruct + --codebase)
“IR 看起来很干净——但实际交付的内容真是这样吗?”
上述验证管道会检查你的编写版 IR(设计契约)。--codebase 标志通过从源代码重建 IR 并进行比较,弥合它与真实代码库之间的差距。
“虚假 IR”攻击——以及如何发现它
开发者可以编写一个合规的 IR(通过所有 IR-STRUCT-* 和 IR-LINT-* 规则),但实际代码却绕过文档中描述的架构。最危险的模式是:IR 展示了干净的服务层,而代码却直接查询数据库。
# Catch discrepancies between the authored design and the shipped code
archrad validate --ir authored-ir.json --codebase ./src --report findings.html
提供 --codebase 时,管道会运行三个阶段:
- 对编写版 IR 进行 IR-STRUCT-* 结构验证
- 对编写版 IR 进行 IR-LINT-* 架构检查
- 比较编写版 IR 与重建的代码库 IR,执行 IR-DRIFT-IMPL-*
IR-DRIFT-IMPL-* 规则
实现漂移使用单独的退出阈值:--fail-on、--fail-on-warning 和 --max-warnings 仅适用于 IR-STRUCT-、IR-LINT- 和合并后的 PolicyPack 发现项。IR-DRIFT-IMPL-* 仅由 --impl-drift-fail-on 控制(默认值:漂移严重性为 error 时,命令失败)。
| 代码 | 严重性 | 检查内容 |
|---|---|---|
IR-DRIFT-IMPL-000 | warning | 无法解析编写版 IR 以进行漂移比较(请先修复结构问题) |
IR-DRIFT-IMPL-001 | warning | IR 声明了类似 HTTP 的入口节点,但重建过程在 --codebase 中检测到的产物为零 |
IR-DRIFT-IMPL-002 | warning | 代码中存在 HTTP / 健康检查路由,但编写版 IR 中没有类似 HTTP 的节点 |
IR-DRIFT-IMPL-003 | error | 代码中存在直接数据库连接,但编写版 IR 中没有数据库边 |
IR-DRIFT-IMPL-004 | error | 代码中的 HTTP 路由未出现在编写版 IR 中 |
IR-DRIFT-IMPL-005 | warning | 代码中存在服务间调用,但编写版 IR 中没有相应的边 |
IR-DRIFT-IMPL-006 | info | 代码中存在身份验证中间件,但编写版 IR 中没有身份验证节点 |
IR-DRIFT-IMPL-003 是关键规则。出现错误意味着编写版 IR 隐藏了直接的数据库依赖。
独立重建
# Just reconstruct — write the IR without comparing
archrad reconstruct --from ./src --output reconstructed-ir.json
# Force language detection
archrad reconstruct --from ./src --language python --output py-ir.json
# Print to stdout (dry-run)
archrad reconstruct --from ./src --dry-run
# Show every detected artifact
archrad reconstruct --from ./src --verbose
支持的语言
| 语言 | 检测到的模式 |
|---|---|
| Node.js / TypeScript | Express、Fastify、NestJS 路由 + 控制器;BullMQ worker、Agenda 任务、cron 计划;pg、Prisma、TypeORM、Sequelize、Mongoose、Redis、BullMQ、Firebase;Passport、express-jwt、NestJS guards、Auth0、Okta、Keycloak、Cognito;axios、got、node-fetch、gRPC;按目标提取出站 HTTP URL |
| Python | Flask、FastAPI、Django URL、DRF @action;SQLAlchemy、psycopg2、asyncpg、PyMongo、motor、redis-py;login_required、jwt_required、FastAPI OAuth2;requests、httpx、aiohttp、gRPC |
| C# | Minimal API MapGet/MapPost;ASP.NET Core [HttpGet]/[ApiController];EF Core DbContext、Npgsql、Dapper;[Authorize]、AddAuthentication、JWT bearer;HttpClient、gRPC、RestSharp |
服务拆分(Node.js)
重建器会检测服务边界,并为每个服务创建一个节点,而不是把所有内容合并到单个网关中:
| 布局 | 检测信号 | 结果 |
|---|---|---|
routes/ 或 controllers/ 目录中的文件 | 专用文件中的 router.get/post/… | 每个文件对应一个 service 节点 |
| NestJS 控制器 | @Controller 装饰器 / *.controller.ts 命名 | 每个控制器文件对应一个 service 节点 |
含有 app.listen() 的入口文件 | 挂载其他路由器 | gateway 节点 |
| BullMQ / Agenda / cron 文件 | new Worker(…)、agenda.define(…) | worker 节点 |
| 单体文件(所有路由都在一个文件中) | 单个文件,没有 routes/ 目录 | 单个 gateway 节点——不会强行拆分 |
节点之间的边反映了重建器发现的内容:
- 对所有拆分出的服务添加 gateway → service 边。
- 仅当路由文件本身包含 DB 导入或环境变量引用时,才会出现 service → database 边(如果 DB 访问被隐藏在共享实用模块后面,则不会出现)。
节点命名
DB 和缓存节点使用最容易被用户识别的可用名称:
- 环境变量名称 —
process.env.REDIS_URL→ 节点名为"redis",process.env.SESSION_REDIS_URL→"session-redis" - 连接变量名称 —
const userDb = new Pool(…)→ 节点名为"userDb"(用于变量名唯一的情况) - 库 / 驱动名称 — 无法检测到环境变量或命名变量时的回退名称
节点 ID 和名称中不会包含 env_var 或其他检测方法元数据。
外部服务识别
出站 HTTP/gRPC 调用会为每个目标创建独立的外部节点:
axios.post('https://api.stripe.com/…')→ 节点"stripe"fetch('https://auth0.com/oauth/token')→ 节点"auth0"new PaymentServiceClient('payments-svc:50051')→ 节点"payment"(gRPC)- 无法检测到 URL 的客户端使用通用回退节点:共享的
"external-service"节点
明确的范围限制
重建结果是尽力检测到的信号,而非确定结论:
- 动态模式 — 不会检测
eval、反射、元编程和生成的代码。 - 运行时配置 — 无法静态分析在运行时做出的拓扑决策(功能标志、由配置驱动的路由)。
- 跨语言服务 — 单个代码库包含多种语言运行时会降低准确性。
- 重度抽象 — 基于宏或大量使用注解处理器的框架可能会隐藏路由或连接。
- 共享数据访问层 — 当 DB 连接位于共享实用文件(例如
db.ts、firebaseAdmin.ts)中,而非路由文件本身时,这些连接不会关联到各个服务节点。重建出的 IR 会如实省略无法静态追踪的边。
解读重建 IR 中的 lint 发现
在重建的 IR 上运行 archrad validate,你可能会看到:
| 发现 | 在重建的 IR 上 | 解读 |
|---|---|---|
IR-LINT-DEAD-NODE-011(服务节点,没有出边) | 服务使用共享数据访问层时属于预期情况 | 并非实际问题;路由文件没有直接检测到的下游边 |
网关上的 IR-LINT-HIGH-FANOUT-004 | 大型单体仓库中属于预期情况 | 网关→服务边的数量反映了路由文件的数量 |
网关上的 IR-LINT-DIRECT-DB-ACCESS-002 | 确实存在的问题 | 入口文件中的某条路由绕过服务层,直接访问了数据库 |
IR-LINT-NO-HEALTHCHECK-003 | 如果健康检查端点位于单独的 routes/health.ts 服务节点中,可能会触发 | 检查健康检查路由是否能从入口点访问 |
在重建的 IR 上,IR-LINT-DIRECT-DB-ACCESS-002 是最有参考价值的规则:如果它在 gateway 节点上触发,就表示入口文件本身直接访问了数据库(没有委托给服务层)。如果分解正确识别了网关与数据库之间的服务节点,此规则就不应触发。
将重建的 IR 视为供人工审查的草稿,而非真实依据。 用它发现架构文档与实际代码之间的明显偏差,而不要将其视为系统的权威描述。
将 IR-DRIFT-IMPL-* 发现视为**“需要审查”**,而非绝对事实。重建的 IR 提供的是信号,并非确定结论。
示例演练——发现“虚假 IR”
已编写的 IR(authored.json)展示了清晰的分层架构:
{ "graph": { "nodes": [
{ "id": "api", "type": "gateway", "name": "API" },
{ "id": "svc", "type": "service", "name": "Order Service" },
{ "id": "db", "type": "postgres", "name": "Orders DB" }
], "edges": [
{ "from": "api", "to": "svc" },
{ "from": "svc", "to": "db" }
]}}
但 src/api/routes.ts 中包含:
import { Pool } from 'pg';
const db = new Pool({ connectionString: process.env.DATABASE_URL });
// direct DB query in the route handler — bypasses the service layer
app.get('/orders', async (req, res) => res.json(await db.query('SELECT * FROM orders')));
运行 archrad validate --ir authored.json --codebase ./src:
❌ IR-DRIFT-IMPL-003: Direct database connection(s) detected in code (pg (PostgreSQL) → postgres) but no DB edges exist in the authored IR
Fix: Either add the missing DB edges to the authored IR, or confirm the codebase points to the correct service.
Suggestion: This discrepancy is a governance red flag: the authored IR could be masking a direct DB dependency.
Impact: CRITICAL — this pattern is exploited in "dummy IR" attacks where clean design docs conceal direct database access in shipped code.
IR 表示没有直接访问数据库。代码却显示并非如此。IR-DRIFT-IMPL-003 发现了这一差异。
项目配置(archrad.yml)
在仓库根目录放置 archrad.yml,即可免去重复输入标志:
# archrad.yml
ir: ./archrad-graph.json
target: python
output: ./generated
failOn: warning
policies: ./policies
archrad validate # uses ir, failOn, policies
archrad export # uses ir, target, output
archrad validate-drift # uses ir, target, output
archrad 会从当前工作目录(CWD)开始向上查找 archrad.yml(或
archrad.yaml)。显式 CLI 标志始终优先于配置。使用
--no-config 忽略找到的配置文件,或使用 --config <path> 指定
非标准位置。完整的架构:docs/CONFIG.md。
快速迭代:archrad lint + archrad explain
# Iterate on lint without re-checking IR structure every run:
archrad lint --ir ./graph.json
# Focus on a single rule while fixing it:
archrad lint --ir ./graph.json --rule IR-LINT-MISSING-AUTH-010
# Understand a rule code without running a pass:
archrad explain IR-LINT-DIRECT-DB-ACCESS-002
archrad explain --list # every known rule code
archrad lint 用于快速迭代;在 CI 门禁之前运行一次 archrad validate,还能检查 IR 的结构是否符合要求。在仓库根目录放置 archrad.yml 后,运行这两条命令都无需添加标志。
CI 集成
# Fail on any structural error (default):
archrad validate --ir ./graph.json
# Also fail on lint warnings:
archrad validate --ir ./graph.json --fail-on-warning
# Machine-readable output for GitHub Actions:
archrad validate --ir ./graph.json --json
MCP 服务(Cursor / Claude Desktop)
安装后,archrad-mcp 会位于你的 PATH 中。将其添加到 IDE:
{
"mcpServers": {
"archrad": { "command": "archrad-mcp" }
}
}
你的 Agent 可以通过 六个 MCP 工具调用与 CLI 相同的引擎(例如 archrad_validate_ir、archrad_lint_summary、archrad_validate_drift、archrad_policy_packs_load、archrad_list_rule_codes、archrad_suggest_fix)。参数和本地测试请参阅 docs/MCP.md。
工作原理(架构)
IR (nodes/edges) → validateIrStructural (IR-STRUCT-*) → errors block export
↓
validateIrLint (IR-LINT-*) → warnings (CI: --fail-on-warning / --max-warnings)
↓
pythonFastAPI | nodeExpress generators
↓
openapi.yaml + app code + package metadata
↓
golden layer (Dockerfile, docker-compose.yml, Makefile, README; host→container e.g. 8080:8080)
↓
validateOpenApiInBundleStructural(openapi.yaml) → document-shape warnings (not full API lint)
↓
{ files, openApiStructuralWarnings, irStructuralFindings, irLintFindings }
Optional CI: archrad validate-drift → re-export IR in-memory, diff vs existing ./out → DRIFT-MISSING / DRIFT-MODIFIED (thin deterministic gate)
验证级别(快速概览)
- JSON Schema 验证 — 根据
schemas/archrad-ir-graph-v1.schema.json验证 IR 文档结构(编辑器/CI;运行时可选)。 - IR 结构验证 —
validateIrStructural:数组、ID、HTTPconfig、边引用、循环(IR-STRUCT-*)。使用内部规范化图(参见docs/IR_CONTRACT.md)。 - 导出时生成的 OpenAPI 结构验证 — 解析生成的
openapi.yaml并检查必填字段(文档结构,而非 Spectral)。
架构 lint(IR-LINT-*)在结构检查之后执行:对解析后的图运行规则访问器(基于启发式,而非 Schema)。
验证层(命名)
| 层(OSS) | 含义 | 代码 |
|---|---|---|
| IR 结构验证 | 图结构正确性:ID、边、循环、HTTP 路径/方法 | IR-STRUCT-* |
| 架构 lint(基础) | 仅使用确定性启发式规则(无 AI、无组织策略) | IR-LINT-* |
| OpenAPI 结构验证(文档形状) | 解析 + 检查生成的规范中必需的 OpenAPI 顶层字段 | (字符串警告,不是 IR 代码) |
| 层(Cloud — 不属于此软件包) | 示例 |
|---|---|
| 策略引擎 | SOC2、组织规则、授权 |
| 架构智能 | 更深入的 NFR / 成本 / 安全推理 |
| AI 修复 | 修复循环、建议的编辑 |
- **IR 结构验证:**重复/缺失的节点 ID、错误的 HTTP
config.url/config.method、未知的边端点、有向循环。 - 架构 lint:实现为解析后图上的访问器函数注册表(
buildParsedLintGraph→src/lint-rules.ts中的LINT_RULE_REGISTRY)。如果无法解析 IR,buildParsedLintGraph会返回{ findings }(IR-STRUCT-),而不是null;请使用isParsedLintGraph()或调用validateIrLint,后者会转发这些发现项。每条规则都会返回IrStructuralFinding[];runArchitectureLinting/validateIrLint会将它们合并。自定义组织规则:在 CI 中将runArchitectureLinting与你自己的(g) => findings组合使用(可运行示例:docs/CUSTOM_RULES.md);如果标准archrad validateCLI 必须输出你的代码,则可派生分支并将规则追加到LINT_RULE_REGISTRY。CLIarchrad validate/archrad export会在 **Architecture lint (IR-LINT-)** 下输出 lint 结果(与结构验证分组显示)。代码包括 IR-LINT-DIRECT-DB-ACCESS-002、IR-LINT-SYNC-CHAIN-001、IR-LINT-NO-HEALTHCHECK-003、IR-LINT-HIGH-FANOUT-004、IR-LINT-ISOLATED-NODE-005、IR-LINT-DUPLICATE-EDGE-006、IR-LINT-HTTP-MISSING-NAME-007、IR-LINT-DATASTORE-NO-INCOMING-008、IR-LINT-MULTIPLE-HTTP-ENTRIES-009、IR-LINT-MISSING-AUTH-010、IR-LINT-DEAD-NODE-011。同步链深度仅统计同步边;请通过edge.metadata.protocol/config.async标记消息/队列/异步跳转(参见lint-graph.ts中的edgeRepresentsAsyncBoundary和docs/ENGINEERING_NOTES.md)。 - 生成器 →
openapi.yaml、处理程序、依赖项。 - 黄金路径 →
make run/docker compose up --build。 - 对包中的 OpenAPI 文档形状进行验证——不是 Spectral 级别的 lint。问题 →
openApiStructuralWarnings。
IR 契约: schemas/archrad-ir-graph-v1.schema.json。解析器边界 + 规范化形状: docs/IR_CONTRACT.md(normalizeIrGraph → materializeNormalizedGraph)。
可信构建: IR-STRUCT-* 错误会阻止导出;IR-LINT-* 警告会显示出来,并可通过 --fail-on-warning / --max-warnings 阻止 CI;OpenAPI 形状问题会作为导出警告显示。
参考(OSS): docs/DRIFT.md(确定性的 validate-drift)、docs/RULE_CODES.md(发现项代码;MCP docsUrl 指向 GitHub 锚点)、docs/MCP.md(MCP 工具 + 本地测试)。
代码生成与验证(重试、超时、策略)
当 IR 携带匹配的边或节点配置(例如 retryPolicy)时,生成器可能会生成重试/超时/熔断器代码。这属于代码生成,并非保证。OSS 目前不会要求或lint“每个外部调用都必须设置超时/重试”——这类规则属于语义 / 策略范畴,适合由 ArchRad Cloud 或基于 IR 的自定义 linter 处理。
使用方式
| 模式 | 最适合 | 示例 |
|---|---|---|
| CLI | 快速本地脚手架、CI、“无 Node 项目”用法 | archrad export --ir graph.json --target python --out ./out |
| YAML → IR | 使用 YAML 编写图,为 validate/export 生成 JSON | archrad yaml-to-ir -y graph.yaml -o graph.json |
| OpenAPI → IR | 根据 OpenAPI 3.x 派生 HTTP 节点(IR 结构与 YAML 路径相同);ArchRad Cloud 合并使用相同的库 | archrad ingest openapi --spec openapi.yaml -o graph.json |
| CLI validate | CI / 提交前检查:IR 结构校验 + 架构 lint,不进行代码生成 | archrad validate --ir graph.json |
| CLI validate-drift | 导出或合并后:磁盘上的目录树与使用相同 IR 进行的新确定性导出结果进行比较 | archrad validate-drift -i graph.json -t python -o ./out |
库(@archrad/deterministic) | IDP / 流水线 | runDeterministicExport → 文件 + 检查结果;使用 runValidateDrift / runDriftCheckAgainstFiles 检查漂移 |
MCP(archrad-mcp) | Cursor / Claude Desktop / 其他 MCP 宿主 | stdio 服务:校验 IR、lint 摘要、漂移、策略包、静态 archrad_suggest_fix — 参见 docs/MCP.md |
MCP(Cursor 示例):执行 npm i -g @archrad/deterministic(或使用 npx)后,添加一个命令为 archrad-mcp 且不带参数的服务(stdio)。对于大型图,将 ir 内联传入,或使用 irPath 指向 JSON 文件。archrad_suggest_fix 会针对某个检查代码(例如 IR-LINT-MISSING-AUTH-010)返回精选文本,而不是机器生成的 IR 补丁。分步测试(冒烟脚本、MCP Inspector、Cursor 聊天提示词):参见 docs/MCP.md 中的 Local testing 章节。
CLI
输入是结构化 IR(JSON),而非自然语言。 没有 archrad export --prompt "..."。请传入图文件(节点/边)。
测试样例(位于此仓库中):fixtures/minimal-graph.json(小型);fixtures/demo-direct-db-violation.json/fixtures/demo-direct-db-layered.json(IR-LINT-DIRECT-DB-ACCESS-002 的前后对比);fixtures/ecommerce-with-warnings.json(包含许多 lint 规则);fixtures/payment-retry-demo.json(导出时与重试相关的代码生成)。--target python 是 FastAPI 包;没有单独的 fastapi 目标。如需从普通英语 → IR,请使用 ArchRad Cloud 或自行执行 LLM 步骤;此软件包只负责 IR → 文件。
录制演示和 GIF(VHS、分镜、漂移回放):仅需查看 scripts/README_DEMO_RECORDING.md——使用 CLI 无需此步骤。
OpenAPI → JSON(以规范为事实来源):paths 下的每个操作都会变成一个 http 节点(config.url + config.method)。然后像处理其他 IR 一样进行验证和导出:
archrad ingest openapi --spec ./openapi.yaml --out ./graph.json
archrad validate --ir ./graph.json
archrad export --ir ./graph.json --target python --out ./out
OpenAPI 安全设置 → IR → lint:导入会将全局和每个操作的 security 要求名称复制到各个 HTTP 节点的 config.security 中(排序确定)。显式设置 security: [] 的操作会变为 config.authRequired: false(有意公开)。如果规范在任何级别都未声明安全设置,则节点不会包含这些字段——此时 archrad validate 可能会在类 HTTP 入口节点上提示 IR-LINT-MISSING-AUTH-010(仅从规范产物来看存在合规缺口)。
**YAML → JSON(更轻量的编写方式):**编辑 fixtures/minimal-graph.yaml(或自己的文件)并编译为 IR JSON,然后进行验证或导出:
archrad yaml-to-ir --yaml fixtures/minimal-graph.yaml --out ./graph.json
archrad validate --ir ./graph.json
# or pipe: archrad yaml-to-ir -y fixtures/minimal-graph.yaml | archrad validate --ir /dev/stdin # on Unix; on Windows use --out then validate
YAML 必须包含顶层 graph:(对象)或顶层 nodes:(数组);裸图会自动封装为 { "graph": { ... } }。
执行 npm install -g 或使用 npx 后(典型用法):
archrad export --ir ./graph.json --target node --out ./my-express-api
# Validate IR (structural + architecture lint). Pretty output; exit 1 on structural errors by default:
archrad validate --ir ./graph.json
# Machine-readable + CI gates:
archrad validate --ir ./graph.json --json
archrad validate --ir ./graph.json --fail-on-warning
archrad validate --ir ./graph.json --max-warnings 0
# Structural only (skip IR-LINT-*):
archrad validate --ir ./graph.json --skip-lint
# Declarative PolicyPack YAML/JSON in a directory (after IR-LINT-*; skipped with --skip-lint):
archrad validate --ir ./graph.json --policies ./policy-packs
从 git 克隆开始(贡献者):在软件包根目录运行 npm ci && npm run build(没有 prepare 钩子——参见 docs/ENGINEERING_NOTES.md),然后像使用 archrad 一样使用 node dist/cli.js(例如 node dist/cli.js validate --ir fixtures/minimal-graph.json)。
确定性漂移(轻量、开源):将磁盘上现有的导出目录树与同一 IR 的全新导出结果进行比较。可检测缺失或已更改的生成文件(会对行结束符进行规范化)。可选的 --strict-extra 会标记磁盘上存在但参考导出中没有的文件。这并非语义层面的“代码是否符合意图”检查——ArchRad Cloud 还提供构建器/UI 漂移检查和更广泛的治理功能。
archrad export -i ./graph.json -t python -o ./out
# …edit files under ./out…
archrad validate-drift -i ./graph.json -t python -o ./out --skip-host-port-check
# CI-friendly:
archrad validate-drift -i ./graph.json -t python -o ./out --skip-host-port-check --json
# Fail if the tree has extra files not in the reference export:
archrad validate-drift -i ./graph.json -t python -o ./out --strict-extra
示例:验证架构
archrad validate --ir fixtures/minimal-graph.json
示例输出(stderr):
archrad validate:
⚠️ IR-LINT-NO-HEALTHCHECK-003: No HTTP node exposes a typical health/readiness path (...)
Fix: Add a GET route such as /health for orchestrators and load balancers.
Suggestion: Expose liveness vs readiness separately if your platform distinguishes them.
Impact: Weaker deploy/rollback safety and harder operations automation.
结构错误的格式类似 ❌ IR-STRUCT-...,并附有 Fix: 行。使用 --json 可在 GitHub Actions 或其他 CI 中处理检查结果。
--ir— JSON:{ "graph": { "nodes", "edges", "metadata" } }或原始图(CLI 会对其进行封装)。--target—python|node|nodejs--out— 输出目录(如有需要会自动创建)--host-port <n>— Docker 发布到主机的端口(默认为 8080;容器内部仍监听 8080)。等同于环境变量ARCHRAD_HOST_PORT。--skip-host-port-check— 导出前不探测127.0.0.1。--strict-host-port— 如果主机端口看起来正在使用,则退出并报错(适用于 CI)。--danger-skip-ir-structural-validation— 不安全:导出前跳过validateIrStructural(切勿在 CI 中使用)。仍会通过validateIrLint检测解析/规范化失败(根节点无效、图为空),并将其记录在irStructuralFindings中的IR-STRUCT-*下,阻止导出。隐藏选项--skip-ir-structural-validation仍作为已弃用的别名保留。--skip-ir-lint— 导出时跳过validateIrLint。--fail-on-warning/--max-warnings <n>— 如果设置了这些选项,当 IR 结构检查和 lint 发现的问题违反策略时,不会写入任何文件(语义与validate相同)。
默认情况下,如果 localhost 上的 8080(或你指定的 --host-port)看起来繁忙,CLI 会发出警告,以便你在 docker compose 因端口绑定错误而失败之前更改端口。
导出会先运行 IR 结构验证,然后进行架构 lint,最后生成代码。结构错误会中止导出,且不会写入任何文件。irLintFindings 仅包含 IR-LINT-*;解析失败产生的 IR-STRUCT-* 始终会显示在 irStructuralFindings 下(包括跳过结构验证时)。默认会打印 lint 警告;使用 --fail-on-warning / --max-warnings 可在 CI 中阻止写入。
库
import {
runDeterministicExport,
runValidateDrift,
validateIrStructural,
validateIrLint,
sortFindings,
shouldFailFromFindings,
} from '@archrad/deterministic';
const { files, openApiStructuralWarnings, irStructuralFindings, irLintFindings } =
await runDeterministicExport(ir, 'python', {
hostPort: 8080,
skipIrLint: false, // default
});
// Structural errors → empty files (unless skipIrStructuralValidation). Lint is non-blocking for export unless you check policy in your pipeline.
const drift = await runValidateDrift(ir, 'python', '/path/to/existing-export', {
skipIrLint: false, // set true to match CLI --skip-ir-lint on reference export
});
// drift.ok, drift.driftFindings, drift.exportResult — same core semantics as CLI validate-drift (CLI also probes host port before calling the library)
const all = sortFindings([...validateIrStructural(ir), ...validateIrLint(ir)]);
if (shouldFailFromFindings(all, { failOnWarning: true })) {
/* gate your CI */
}
可选:如果你想自行执行预检,可以从同一软件包使用 isLocalHostPortFree / normalizeGoldenHostPort。
黄金路径(贡献者 — 本地克隆)
此路径假设你已克隆仓库,并在软件包根目录运行了 npm ci && npm run build。如果你只是通过 npm install -g @archrad/deterministic 安装,请使用 archrad 代替 node dist/cli.js(标志相同)。
node dist/cli.js export --ir fixtures/minimal-graph.json --target python --out ./out
cd ./out
make run
# In another terminal, once the API is up:
curl -sS -X POST http://localhost:8080/signup -H "Content-Type: application/json" -d '{}'
你应该会看到 422 Unprocessable Entity(FastAPI/Pydantic)或带有明确响应正文的 400 — 这证明服务栈已启动,且验证符合规范,而不是悄无声息地返回 500。
克隆后的快速检查:cd packages/deterministic && npm ci && npm run build && npm test,然后导出到 ./tmp-out,再运行 cd tmp-out && make run,并像上面那样运行 curl。如果 8080 正忙,请使用 --host-port 18080(或 node dist/cli.js export ... --host-port 18080)。
可选:运行 bash scripts/golden-path-demo.sh 可执行相同流程。演示录制(GIF、录制文件、漂移回放):scripts/README_DEMO_RECORDING.md。
开源版与 ArchRad Cloud
此仓库仅包含确定性引擎——本地运行、离线使用,不会向外发送数据。
| 此处(OSS) | ArchRad Cloud(商业产品) |
|---|---|
IR 结构校验与架构 lint(validate、IR-STRUCT-*、IR-LINT-*)、编译器(export)、validate-drift(对比磁盘上的内容与新导出的内容)、OpenAPI 文档结构警告、标准 Docker/Makefile | 策略引擎、更深入的架构智能、AI 修复、构建器中更完善的漂移/同步体验 |
archrad CLI 永久可用,此软件包无需账户 | 身份验证、组织、配额、账单 |
| 不包含专有的 LLM 编排或“修复”循环 | LLM 生成、修复、多模型路由 |
| 此仓库不包含 Git 同步或企业策略注入 | Git 推送、治理、合规性仪表板 |
你可以不依赖 ArchRad Cloud,直接使用此 CLI 和库。云产品在相同的确定性契约之上,增加了协作和 AI 功能。
贡献
请参阅 CONTRIBUTING.md。
许可证
Apache-2.0——请参阅 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。