mcpField
D
deterministic

deterministic

本地服务
github.com/archradhq开发工具18 周前更新

关于 deterministic

deterministic 是通过 IR 描述软件架构,并按固定规则验证结构与规范的命令行工具。它面向希望在 CI 中发现设计及实现偏差的团队,也支持扫描仓库和从源码重建架构。

主要功能

  1. 01确定性 IR 验证与 lint
  2. 02生成带来源信息的仓库 IR 草稿
  3. 03对比设计 IR 与重建代码
  4. 04导入 OpenAPI 和 Backstage 目录
  5. 05将 IR 导出为 FastAPI 或 Express

适用场景

  1. 01在 CI 中设置架构检查门禁
  2. 02审阅从仓库生成的架构草稿
  3. 03发现设计与实际代码的差异

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"archradhq-deterministic": {
"command": "npx",
"args": [
"-y",
"@archrad/deterministic"
]
}
}
}
启动命令npx -y @archrad/deterministic

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@archrad/deterministic0.4.1

工具

6

收录的工具列表 · 更新于 3 周前

参数类型必填说明
irany否作为 JSON 对象内联提供的 IR 图。仅适用于小型图。
irPathstring否IR JSON 文件的绝对路径或相对路径。大型图建议使用此参数。
policiesDirectorystring否包含 PolicyPack YAML/JSON 文件的目录路径。可选——没有自定义规则时可省略。

详细介绍

@archrad/deterministic

ArchRAD 0.7.2 运行零配置确定性演示,并将仓库扫描为带引用的草稿 IR

Apache-2.0 no LLM no account

在你写下一行代码之前,架构就已经开始偏离。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图结构 + 架构 LintIR-STRUCT-* IR-LINT-*
archrad lint仅架构 Lint(快速内循环;跳过结构检查)IR-LINT-*
archrad explain <code>不运行检查,提供规范的规则说明—
archrad policies-sha256 --dir <policies>为已签名的 PolicyPack 生成 archrad-policy-pack.sha256 清单—
archrad validate-driftIR 与磁盘上生成的代码DRIFT-*
archrad scan从仓库生成 IR 草稿——拓扑、OpenAPI、清单、代码;每个节点都带有引用,并按置信度评分—
archrad reconstruct仅从源代码生成 IR 草稿(scan 的四种信号来源之一,可独立使用)—
archrad ingest openapi从 OpenAPI 派生 IR(--spec 支持本地路径或 https URL;使用 -H 设置 URL 身份验证标头)—
archrad ingest backstageBackstage 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 时,管道会运行三个阶段:

  1. 对编写版 IR 进行 IR-STRUCT-* 结构验证
  2. 对编写版 IR 进行 IR-LINT-* 架构检查
  3. 比较编写版 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-000warning无法解析编写版 IR 以进行漂移比较(请先修复结构问题)
IR-DRIFT-IMPL-001warningIR 声明了类似 HTTP 的入口节点,但重建过程在 --codebase 中检测到的产物为零
IR-DRIFT-IMPL-002warning代码中存在 HTTP / 健康检查路由,但编写版 IR 中没有类似 HTTP 的节点
IR-DRIFT-IMPL-003error代码中存在直接数据库连接,但编写版 IR 中没有数据库边
IR-DRIFT-IMPL-004error代码中的 HTTP 路由未出现在编写版 IR 中
IR-DRIFT-IMPL-005warning代码中存在服务间调用,但编写版 IR 中没有相应的边
IR-DRIFT-IMPL-006info代码中存在身份验证中间件,但编写版 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 / TypeScriptExpress、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
PythonFlask、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 和缓存节点使用最容易被用户识别的可用名称:

  1. 环境变量名称 — process.env.REDIS_URL → 节点名为 "redis",process.env.SESSION_REDIS_URL → "session-redis"
  2. 连接变量名称 — const userDb = new Pool(…) → 节点名为 "userDb"(用于变量名唯一的情况)
  3. 库 / 驱动名称 — 无法检测到环境变量或命名变量时的回退名称

节点 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" 节点
明确的范围限制

重建结果是尽力检测到的信号,而非确定结论:

  1. 动态模式 — 不会检测 eval、反射、元编程和生成的代码。
  2. 运行时配置 — 无法静态分析在运行时做出的拓扑决策(功能标志、由配置驱动的路由)。
  3. 跨语言服务 — 单个代码库包含多种语言运行时会降低准确性。
  4. 重度抽象 — 基于宏或大量使用注解处理器的框架可能会隐藏路由或连接。
  5. 共享数据访问层 — 当 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)
验证级别(快速概览)
  1. JSON Schema 验证 — 根据 schemas/archrad-ir-graph-v1.schema.json 验证 IR 文档结构(编辑器/CI;运行时可选)。
  2. IR 结构验证 — validateIrStructural:数组、ID、HTTP config、边引用、循环(IR-STRUCT-*)。使用内部规范化图(参见 docs/IR_CONTRACT.md)。
  3. 导出时生成的 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 修复修复循环、建议的编辑
  1. **IR 结构验证:**重复/缺失的节点 ID、错误的 HTTP config.url / config.method、未知的边端点、有向循环。
  2. 架构 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 validate CLI 必须输出你的代码,则可派生分支并将规则追加到 LINT_RULE_REGISTRY。CLI archrad 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)。
  3. 生成器 → openapi.yaml、处理程序、依赖项。
  4. 黄金路径 → make run / docker compose up --build。
  5. 对包中的 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 生成 JSONarchrad 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 validateCI / 提交前检查: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。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。