@archrad/deterministic 0.1.4 → 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/CI.md ADDED
@@ -0,0 +1,122 @@
1
+ # CI integration — `archrad validate`
2
+
3
+ `archrad validate` is the usual gate for **architecture-as-code** in pipelines. It reads an IR JSON file and runs structural validation (IR-STRUCT-*) plus architecture lint (IR-LINT-*).
4
+
5
+ ## Exit codes
6
+
7
+ | Situation | Default exit code |
8
+ |-----------|-------------------|
9
+ | No findings | **0** |
10
+ | Any finding with severity **`error`** (structural / blocking) | **1** |
11
+ | **Warnings only** (e.g. many IR-LINT-* rules) | **0** |
12
+
13
+ Optional stricter gates:
14
+
15
+ - **`--fail-on-warning`** — exit **1** if any warning exists.
16
+ - **`--max-warnings <n>`** — exit **1** if the warning count is **greater than** `n` (e.g. **`--max-warnings 0`** allows no warnings).
17
+
18
+ JSON output: add **`--json`** (findings array on stdout).
19
+
20
+ Policy packs: **`--policies <dir>`** (directory of PolicyPack YAML/JSON), merged after built-in IR-LINT-* (omit **`--skip-lint`** if you want lint + policies).
21
+
22
+ Example:
23
+
24
+ ```bash
25
+ npx archrad validate --ir ./graph.json
26
+ npx archrad validate --ir ./graph.json --fail-on-warning
27
+ npx archrad validate --ir ./graph.json --max-warnings 0 --json
28
+ ```
29
+
30
+ Install **`@archrad/deterministic`** as a dev dependency so `npx archrad` resolves locally, or invoke **`node node_modules/@archrad/deterministic/dist/cli.js`** explicitly.
31
+
32
+ ---
33
+
34
+ ## GitHub Actions
35
+
36
+ ```yaml
37
+ jobs:
38
+ archrad:
39
+ runs-on: ubuntu-latest
40
+ steps:
41
+ - uses: actions/checkout@v4
42
+ - uses: actions/setup-node@v4
43
+ with:
44
+ node-version: '20'
45
+ cache: 'npm'
46
+ - run: npm ci
47
+ - run: npx archrad validate --ir ./path/to/graph.json
48
+ ```
49
+
50
+ With warnings as failures:
51
+
52
+ ```yaml
53
+ - run: npx archrad validate --ir ./path/to/graph.json --fail-on-warning
54
+ ```
55
+
56
+ ---
57
+
58
+ ## GitLab CI
59
+
60
+ ```yaml
61
+ archrad-validate:
62
+ image: node:20-bookworm
63
+ script:
64
+ - npm ci
65
+ - npx archrad validate --ir ./path/to/graph.json
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Bitbucket Pipelines
71
+
72
+ ```yaml
73
+ pipelines:
74
+ default:
75
+ - step:
76
+ name: ArchRad validate
77
+ image: node:20
78
+ script:
79
+ - npm ci
80
+ - npx archrad validate --ir ./path/to/graph.json
81
+ ```
82
+
83
+ ---
84
+
85
+ ## Jenkins (Declarative)
86
+
87
+ ```groovy
88
+ pipeline {
89
+ agent any
90
+ stages {
91
+ stage('ArchRad') {
92
+ steps {
93
+ sh 'npm ci'
94
+ sh 'npx archrad validate --ir ./path/to/graph.json'
95
+ }
96
+ }
97
+ }
98
+ }
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Azure DevOps
104
+
105
+ ```yaml
106
+ steps:
107
+ - task: NodeTool@0
108
+ inputs:
109
+ versionSpec: '20.x'
110
+ - script: npm ci
111
+ displayName: npm ci
112
+ - script: npx archrad validate --ir ./path/to/graph.json
113
+ displayName: archrad validate
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Notes
119
+
120
+ - Replace **`./path/to/graph.json`** with your IR path (repo-relative in CI).
121
+ - Ensure the job installs the same **`@archrad/deterministic`** version you use locally (`package.json` / lockfile).
122
+ - Drift checks use **`archrad validate-drift`** (separate command); see **`docs/DRIFT.md`**.
package/docs/DRIFT.md ADDED
@@ -0,0 +1,52 @@
1
+ # Deterministic drift (`validate-drift`)
2
+
3
+ **Canonical OSS description** — versioned with **`@archrad/deterministic`**.
4
+ **Not** semantic “does this code match business intent?” — that class of analysis is out of scope for this layer (see **`STRUCTURAL_VS_SEMANTIC_VALIDATION.md`**).
5
+
6
+ ## What it is
7
+
8
+ **Drift** here means: you already have an **on-disk tree** (usually from `archrad export`), and you want to know whether it still matches what the **deterministic exporter would produce today** from the **same IR**.
9
+
10
+ The engine:
11
+
12
+ 1. Runs a **fresh export** from your IR in memory (same pipeline as `archrad export`).
13
+ 2. Compares the **expected file set + contents** to what is on disk (paths normalized, line endings normalized to `\n`).
14
+ 3. Emits **DRIFT-*** findings when something is missing, changed, or (optionally) extra.
15
+
16
+ So: **regen vs reality** — a thin gate for CI and pre-merge checks.
17
+
18
+ ## What it is not
19
+
20
+ - **Not** diffing IR to arbitrary hand-written code semantics.
21
+ - **Not** proving runtime behavior or security — use tests, review, and (where applicable) **ArchRad Cloud** governance.
22
+
23
+ ## CLI
24
+
25
+ ```bash
26
+ archrad validate-drift -i ./graph.json -t python -o ./out
27
+ ```
28
+
29
+ Use **`--json`** in CI. **`--strict-extra`** treats unexpected files in the output directory as findings. **`--skip-ir-lint`** / **`--policies`** follow the same semantics as **`export`** (see **`README.md`**).
30
+
31
+ ## Library
32
+
33
+ **`runValidateDrift`**, **`diffExpectedExportAgainstFiles`**, **`readDirectoryAsExportMap`** — see **`src/validate-drift.ts`**.
34
+
35
+ ## MCP
36
+
37
+ **`archrad_validate_drift`** — same semantics: IR (inline or **`irPath`**) + **`target`** + **`exportDir`**. See **`MCP.md`**.
38
+
39
+ ## DRIFT-* codes
40
+
41
+ | Code | Meaning |
42
+ |------|--------|
43
+ | **DRIFT-MISSING** | A file the exporter would emit is missing on disk. |
44
+ | **DRIFT-MODIFIED** | File exists but content differs from the deterministic export. |
45
+ | **DRIFT-EXTRA** | File exists on disk but is not in the reference export (with **`--strict-extra`**). |
46
+ | **DRIFT-NO-EXPORT** | Exporter produced no file map (often blocked by structural/lint errors or empty target output). |
47
+
48
+ Remediation text for each code (aligned with MCP **`archrad_suggest_fix`**) lives in **`RULE_CODES.md`** and **`src/static-rule-guidance.ts`**.
49
+
50
+ ## Product site
51
+
52
+ **archrad.com** may host narrative pages (e.g. `/docs/drift`) for onboarding; **definitions and CLI/MCP behavior** are maintained **here** in the OSS repo so they ship with the engine.
package/docs/MCP.md ADDED
@@ -0,0 +1,153 @@
1
+ # ArchRad MCP server — specification
2
+
3
+ **Status:** **0.1.x** — `archrad-mcp` ships in **`@archrad/deterministic`** (stdio MCP, same engine as CLI).
4
+ **Audience:** Engineering + launch narrative (Show HN / registry listing).
5
+
6
+ ## 1. Problem statement
7
+
8
+ | Mode | Behavior |
9
+ |------|------------|
10
+ | **Reactive** | CI runs `archrad` after code exists → catches drift late. |
11
+ | **Proactive** | An MCP server answers **before** edits land: “Is this edge allowed?”, “What does IR-LINT say about this sketch?” |
12
+
13
+ Agents optimize for *working code*; ArchRad supplies **deterministic constraints** so the loop can ask the engine *before* violating architecture.
14
+
15
+ ## 2. OSS vs product boundary
16
+
17
+ Aligned with **`STRUCTURAL_VS_SEMANTIC_VALIDATION.md`** (this folder) and your org’s OSS/product split docs.
18
+
19
+ | Surface | Ships in **OSS** (`@archrad/deterministic`, binary **`archrad-mcp`**) | Stays in **product / Cloud** |
20
+ |---------|------------------------------------------------------------------------|------------------------------|
21
+ | IR structural validation (`IR-STRUCT-*`) | Yes | — |
22
+ | Architecture lint (`IR-LINT-*`) + PolicyPack YAML from **local dir** | Yes | — |
23
+ | `validate_drift` vs on-disk export (local paths) | Yes | — |
24
+ | Static remediation text per **built-in** code (`archrad_suggest_fix`) | Yes | — |
25
+ | Org **`settings.archPolicyPacks`**, Firestore, membership | — | Yes |
26
+ | Semantic “is this business-correct?” reasoning | — | Yes (future assisted tools) |
27
+
28
+ **Rule of thumb:** If the tool only needs **IR JSON + local files**, it can live in the public MCP server. If it needs **tenant identity, billing, or org policy from Cloud**, expose a **separate** “ArchRad Cloud” MCP connector (private or authenticated) — do not move Cloud policy enforcement into OSS without an explicit product decision.
29
+
30
+ ## 3. Transport and packaging
31
+
32
+ - **Protocol:** [Model Context Protocol](https://modelcontextprotocol.io/) over **stdio** (default for Cursor, Claude Desktop, Copilot agent adapters).
33
+ - **Package:** **`@archrad/deterministic`** publishes two binaries: **`archrad`** (CLI) and **`archrad-mcp`** (MCP). One implementation backs CLI + MCP.
34
+ - **Registry:** Optional `server.json` / manifest for MCP Registry; document install for Cursor “Add MCP server”.
35
+
36
+ ## 4. IR payload size and `ir` vs `irPath`
37
+
38
+ | Concern | Guidance |
39
+ |---------|----------|
40
+ | **Inline `ir`** | Fine for small/medium graphs. Large JSON in a single tool call still stresses **host message limits** and **model context** — prefer **`irPath`** when the IR is big. |
41
+ | **`irPath`** | Absolute or relative path to a **single JSON file** (same shape as CLI `--ir`). Enforced **max file size 25 MiB** in the server (hard cap); if you exceed it, split validation or trim fixtures. |
42
+ | **Soft ceiling** | Below ~**5k–10k nodes**, inline JSON is usually workable if the host allows; above that, **`irPath` is recommended**. This is not a graph semantics limit — only practical transport/memory. |
43
+ | **Exactly one** | Provide **`ir`** **or** **`irPath`**, not both, not neither (for tools that need IR). |
44
+
45
+ **Privacy:** The OSS server does **not** add analytics or tracking parameters to tool responses. Optional product docs URLs use a stable path only (see **`archrad_suggest_fix`**).
46
+
47
+ ## 5. Local testing
48
+
49
+ ### 5.1 Smoke script (npm)
50
+
51
+ From the **`@archrad/deterministic`** package root (where **`package.json`** lives):
52
+
53
+ ```bash
54
+ npm run build
55
+ npm run smoke:mcp
56
+ ```
57
+
58
+ Exit code **0** means the MCP server spawned **`dist/mcp-server.js`**, listed tools, and successfully called **`archrad_suggest_fix`**.
59
+
60
+ ### 5.2 MCP Inspector (browser UI)
61
+
62
+ ```bash
63
+ npx @modelcontextprotocol/inspector node dist/mcp-server.js
64
+ ```
65
+
66
+ Open the URL Inspector prints (often **http://localhost:6274**). Under **Tools**, run **`archrad_list_rule_codes`** (no args), then **`archrad_validate_ir`** with **`irPath`** set to **`fixtures/minimal-graph.json`** (relative paths work if the process was started with **cwd** set to the package root).
67
+
68
+ ### 5.3 Cursor (MCP config + chat)
69
+
70
+ 1. **Build** so **`dist/mcp-server.js`** exists (`npm run build`).
71
+ 2. In Cursor **Settings → MCP**, add a server (exact JSON shape depends on Cursor version):
72
+ - **Command:** `node` (or full path to `node.exe` on Windows).
73
+ - **Args:** full path to **`dist/mcp-server.js`**.
74
+ - **Cwd (recommended):** the deterministic package root (directory containing **`package.json`**). Relative **`irPath`** values like **`fixtures/minimal-graph.json`** resolve from this directory.
75
+ 3. **Chat:** Cursor does not always show a “run tool” button for every server. Use **Agent** mode (or another mode that supports **tool use**) and ask explicitly, for example:
76
+
77
+ **List codes:**
78
+
79
+ > Use the MCP tool **`archrad_list_rule_codes`** (no arguments) and show me the raw JSON result.
80
+
81
+ **Validate via file:**
82
+
83
+ > Use the MCP tool **`archrad_validate_ir`** with **`irPath`** set to **`fixtures/minimal-graph.json`** (relative to the deterministic package). Show the full tool result.
84
+
85
+ If the model says it cannot find the tool, the MCP server failed to start or the configured server name does not match — check Cursor’s MCP panel for errors.
86
+
87
+ 4. **If `irPath` fails** with “file not found”, use the **absolute path** to **`fixtures/minimal-graph.json`**.
88
+
89
+ ### 5.4 Success criteria
90
+
91
+ - **`archrad_list_rule_codes`:** JSON with a **`codes`** array.
92
+ - **`archrad_validate_ir`:** JSON with **`irStructuralFindings`**, **`irLintFindings`**, **`combined`**, **`ok`** — not a connection or file error.
93
+
94
+ ## 6. Tools (0.1.6)
95
+
96
+ Tools are **idempotent** and **deterministic** where stated.
97
+
98
+ ### 6.1 Core
99
+
100
+ | Tool | Input | Output | Notes |
101
+ |------|--------|--------|-------|
102
+ | **`archrad_validate_ir`** | `ir` **or** `irPath`; optional `policiesDirectory` | `{ ok, irStructuralFindings, irLintFindings, combined }` | Same as CLI validate. |
103
+ | **`archrad_lint_summary`** | `ir` **or** `irPath`; optional `policiesDirectory` | Short summary + counts | Agent-friendly. |
104
+ | **`archrad_validate_drift`** | `ir` **or** `irPath`; `target`; `exportDir`; optional policies, `skipIrLint` | Drift + export findings | Same engine as CLI `validate-drift`. **MCP `target` values:** `python` or `nodejs` only (not `node`). The CLI `validate-drift` / `export` may still accept `node` as an alias for Node exports. |
105
+ | **`archrad_policy_packs_load`** | `directory` or `files[]` | `{ ok, ruleCount }` or errors | Compiles packs; does not return visitor functions over MCP. |
106
+
107
+ ### 6.2 Static guidance (no generated architecture)
108
+
109
+ | Tool | Input | Output | Notes |
110
+ |------|--------|--------|-------|
111
+ | **`archrad_suggest_fix`** | `findingCode` (e.g. `IR-LINT-MISSING-AUTH-010`) | `{ ok, findingCode, title, remediation, docsUrl }` or `{ ok: false, error }` | **Curated text only** — not JSON Patch, not IR edits, not LLM output. **`docsUrl`** points to the **[`RULE_CODES.md`](https://github.com/archradhq/arch-deterministic/blob/main/docs/RULE_CODES.md)** section for that code on **GitHub** (canonical OSS; no query strings). Unknown built-in codes and **PolicyPack/org** ids return `ok: false` with a short explanation. |
112
+ | **`archrad_list_rule_codes`** | _(none)_ | `{ codes: string[] }` | Sorted list of built-in codes with static guidance. |
113
+
114
+ **Explicit non-goal:** **`archrad_suggest_fix` must not** return machine-generated graph edits or “patches” that invent services — that would be **generative** and would break the deterministic OSS contract.
115
+
116
+ ### 6.3 Explicit non-goals (MVP)
117
+
118
+ - No automatic **code** generation inside MCP (keep **`export`** as CLI/CI).
119
+ - No remote calls to ArchRad Cloud unless a **separate authenticated** server is defined.
120
+ - No **tracking** query parameters in MCP tool payloads.
121
+
122
+ ## 7. Resources (optional)
123
+
124
+ | Resource URI | Content |
125
+ |--------------|---------|
126
+ | `archrad://docs/ir-contract` | Pointer to bundled `IR_CONTRACT.md` snippet or link. |
127
+ | `archrad://schemas/ir-graph-v1` | JSON Schema for IR graph validation. |
128
+
129
+ ## 8. Security
130
+
131
+ - **Local-only by default:** IR and paths stay on the user machine; **no telemetry** in the OSS server unless explicitly documented elsewhere.
132
+ - **Path sandbox:** Validate `exportDir` / `irPath` against workspace roots if the host passes a `workspaceRoot` (host-dependent).
133
+ - **Cloud MCP (future):** OAuth or API keys; never embed product secrets in OSS.
134
+
135
+ ## 9. Launch narrative (copy bank)
136
+
137
+ - **One-liner:** *AI agents write code fast but drift from your architecture; ArchRad MCP gives them the same deterministic IR checks as CI, inside the agent loop.*
138
+ - **Show HN angle:** *Architectural conscience for Copilot / Cursor — IR-LINT before you merge.*
139
+
140
+ ## 10. Related repo tasks
141
+
142
+ - **Quality:** Keep graph/lint work responsive so MCP tools stay usable on mid-size IRs.
143
+
144
+ ## 11. Implementation checklist
145
+
146
+ 1. ~~Node MCP server (`@modelcontextprotocol/sdk`), stdio transport.~~
147
+ 2. ~~`archrad_validate_ir` + `archrad_validate_drift` + policy load + static `archrad_suggest_fix`.~~
148
+ 3. README + **`docs/MCP.md`**: Cursor config, `ir` / `irPath`, local testing (smoke, Inspector, chat prompts).
149
+ 4. Publish **`@archrad/deterministic`** to npm; subtree to public repo per release process.
150
+
151
+ ---
152
+
153
+ *This document aligns OSS MCP scope with product strategy; update when adding Cloud-only tools.*
@@ -0,0 +1,208 @@
1
+ # Built-in finding codes (IR-STRUCT, IR-LINT, DRIFT)
2
+
3
+ **Canonical OSS reference** — ships in **`@archrad/deterministic`**.
4
+ **MCP** **`archrad_suggest_fix`** returns **`title`**, **`remediation`**, and a **`docsUrl`** pointing at the matching section below. **PolicyPack / org** rules use custom ids (e.g. `ORG-*`) — not listed here.
5
+
6
+ **Product / marketing** copy may live on **archrad.com**; **deterministic semantics** are defined in this repo.
7
+
8
+ ---
9
+
10
+ ## DRIFT-EXTRA
11
+
12
+ Extra file not in deterministic export. **Remediation:** Remove stray files from the export directory or add them to the model if they should be generated. Use **`--strict-extra`** semantics as documented for your CI gate.
13
+
14
+ ---
15
+
16
+ ## DRIFT-MISSING
17
+
18
+ Exported file missing on disk. **Remediation:** Regenerate the export (**`archrad export`**) or restore the missing file so the tree matches the deterministic output for this IR.
19
+
20
+ ---
21
+
22
+ ## DRIFT-MODIFIED
23
+
24
+ File differs from deterministic export. **Remediation:** Revert manual edits to generated files or update the IR and re-export so the on-disk tree matches the compiler output.
25
+
26
+ ---
27
+
28
+ ## DRIFT-NO-EXPORT
29
+
30
+ No export produced for drift comparison. **Remediation:** Fix IR structural/lint errors blocking export, or verify **`--target`** and IR content so the exporter emits files.
31
+
32
+ ---
33
+
34
+ ## IR-LINT-DATASTORE-NO-INCOMING-008
35
+
36
+ Datastore has no incoming edges. **Remediation:** Connect a service or data path to this datastore, or remove it if unused.
37
+
38
+ ---
39
+
40
+ ## IR-LINT-DEAD-NODE-011
41
+
42
+ Non-sink node with incoming edges but no outgoing edges. **Remediation:** Add an outgoing edge to a downstream consumer, or remove the node if it is obsolete.
43
+
44
+ ---
45
+
46
+ ## IR-LINT-DIRECT-DB-ACCESS-002
47
+
48
+ HTTP-like node connects directly to a datastore. **Remediation:** Introduce a service or domain layer between HTTP handlers and persistence.
49
+
50
+ ---
51
+
52
+ ## IR-LINT-DUPLICATE-EDGE-006
53
+
54
+ Duplicate from→to edge. **Remediation:** Collapse duplicate edges or distinguish them with metadata if your model allows.
55
+
56
+ ---
57
+
58
+ ## IR-LINT-HIGH-FANOUT-004
59
+
60
+ High outgoing dependency count. **Remediation:** Reduce fan-out: split responsibilities, add a facade, batch calls, or use async handoff.
61
+
62
+ ---
63
+
64
+ ## IR-LINT-HTTP-MISSING-NAME-007
65
+
66
+ HTTP-like node missing display name. **Remediation:** Set a short human-readable **`name`** on the node.
67
+
68
+ ---
69
+
70
+ ## IR-LINT-ISOLATED-NODE-005
71
+
72
+ Node has no incident edges. **Remediation:** Remove the orphan or connect it with edges.
73
+
74
+ ---
75
+
76
+ ## IR-LINT-MISSING-AUTH-010
77
+
78
+ HTTP entry missing auth coverage. **Remediation:** Add an auth boundary (auth/middleware/oauth/jwt node or **`config.authRequired: false`** for public endpoints).
79
+
80
+ ---
81
+
82
+ ## IR-LINT-MULTIPLE-HTTP-ENTRIES-009
83
+
84
+ Multiple HTTP entry nodes without incoming edges. **Remediation:** Prefer a single API gateway or BFF unless multiple public surfaces are intentional.
85
+
86
+ ---
87
+
88
+ ## IR-LINT-NO-HEALTHCHECK-003
89
+
90
+ No typical health/readiness route on HTTP nodes. **Remediation:** Add a GET route such as **`/health`** or **`/ready`**.
91
+
92
+ ---
93
+
94
+ ## IR-LINT-SYNC-CHAIN-001
95
+
96
+ Long synchronous chain from HTTP entry. **Remediation:** Shorten the graph or mark non-blocking hops as async in edge metadata.
97
+
98
+ ---
99
+
100
+ ## IR-STRUCT-CYCLE
101
+
102
+ Directed cycle in the graph. **Remediation:** Remove or break cyclic edges unless your tooling explicitly allows execution loops.
103
+
104
+ ---
105
+
106
+ ## IR-STRUCT-DUP_NODE_ID
107
+
108
+ Duplicate node id. **Remediation:** Ensure node ids are unique.
109
+
110
+ ---
111
+
112
+ ## IR-STRUCT-EDGE_AMBIGUOUS_FROM
113
+
114
+ Edge references duplicate source id. **Remediation:** Resolve duplicate node ids first.
115
+
116
+ ---
117
+
118
+ ## IR-STRUCT-EDGE_AMBIGUOUS_TO
119
+
120
+ Edge references duplicate target id. **Remediation:** Resolve duplicate node ids first.
121
+
122
+ ---
123
+
124
+ ## IR-STRUCT-EDGE_INVALID
125
+
126
+ Edge is not an object. **Remediation:** Each edge must be an object with **`from`**/**`to`** (or **`source`**/**`target`**).
127
+
128
+ ---
129
+
130
+ ## IR-STRUCT-EDGE_NO_ENDPOINTS
131
+
132
+ Edge missing endpoints. **Remediation:** Set **`from`** and **`to`** to existing node ids.
133
+
134
+ ---
135
+
136
+ ## IR-STRUCT-EDGE_UNKNOWN_FROM
137
+
138
+ Edge references unknown source node. **Remediation:** Add a node with the referenced id or correct **`from`**.
139
+
140
+ ---
141
+
142
+ ## IR-STRUCT-EDGE_UNKNOWN_TO
143
+
144
+ Edge references unknown target node. **Remediation:** Add a node with the referenced id or correct **`to`**.
145
+
146
+ ---
147
+
148
+ ## IR-STRUCT-EDGES_NOT_ARRAY
149
+
150
+ **`edges`** is present but not an array. **Remediation:** Set **`edges`** to an array of edge objects (or omit **`edges`**).
151
+
152
+ ---
153
+
154
+ ## IR-STRUCT-EMPTY_GRAPH
155
+
156
+ Graph has no nodes. **Remediation:** Add at least one node before validation or export.
157
+
158
+ ---
159
+
160
+ ## IR-STRUCT-HTTP_METHOD
161
+
162
+ HTTP method not supported. **Remediation:** Use GET, POST, PUT, PATCH, DELETE, HEAD, or OPTIONS.
163
+
164
+ ---
165
+
166
+ ## IR-STRUCT-HTTP_PATH
167
+
168
+ HTTP endpoint path invalid. **Remediation:** Set **`config.url`** or **`config.route`** to a path starting with **`/`**.
169
+
170
+ ---
171
+
172
+ ## IR-STRUCT-INVALID_ROOT
173
+
174
+ IR root is not a JSON object. **Remediation:** Pass a single JSON object with **`graph`** or top-level **`nodes`**.
175
+
176
+ ---
177
+
178
+ ## IR-STRUCT-NO_GRAPH
179
+
180
+ Missing graph shape. **Remediation:** Include **`.graph`** with **`nodes`** or a top-level **`nodes`** array.
181
+
182
+ ---
183
+
184
+ ## IR-STRUCT-NODE_INVALID
185
+
186
+ Node entry is not an object. **Remediation:** Each **`nodes`** entry must be a JSON object with **`id`** and type information.
187
+
188
+ ---
189
+
190
+ ## IR-STRUCT-NODE_INVALID_CONFIG
191
+
192
+ Node **`config`** is not a plain object. **Remediation:** Use a plain object for **`config`**.
193
+
194
+ ---
195
+
196
+ ## IR-STRUCT-NODE_NO_ID
197
+
198
+ Node missing non-empty id. **Remediation:** Assign a stable string **`id`** to every node.
199
+
200
+ ---
201
+
202
+ ## IR-STRUCT-NODES_NOT_ARRAY
203
+
204
+ **`nodes`** is not an array. **Remediation:** Set **`nodes`** to an array of node objects.
205
+
206
+ ---
207
+
208
+ *Full strings in MCP/CLI mirror **`src/static-rule-guidance.ts`** (single implementation).*
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archrad/deterministic",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "description": "A deterministic compiler and linter for system architecture. Validate your architecture before you write code. OSS: structural validation + basic architecture lint (rule-based); FastAPI/Express export; OpenAPI document-shape; golden Docker/Makefile — no LLM.",
5
5
  "keywords": [
6
6
  "archrad",
@@ -14,7 +14,9 @@
14
14
  "deterministic",
15
15
  "codegen",
16
16
  "docker",
17
- "cli"
17
+ "cli",
18
+ "mcp",
19
+ "model-context-protocol"
18
20
  ],
19
21
  "homepage": "https://github.com/archradhq/arch-deterministic#readme",
20
22
  "bugs": {
@@ -39,7 +41,8 @@
39
41
  }
40
42
  },
41
43
  "bin": {
42
- "archrad": "./dist/cli.js"
44
+ "archrad": "./dist/cli.js",
45
+ "archrad-mcp": "./dist/mcp-server.js"
43
46
  },
44
47
  "files": [
45
48
  "dist",
@@ -61,22 +64,26 @@
61
64
  "scripts": {
62
65
  "build": "tsc -p tsconfig.build.json",
63
66
  "prepublishOnly": "npm run build",
64
- "test": "tsc -p tsconfig.build.json --noEmit && vitest run",
67
+ "test": "tsc -p tsconfig.build.json --noEmit && npm run build && vitest run",
65
68
  "lint": "biome check ./src",
66
69
  "typecheck": "tsc -p tsconfig.build.json --noEmit",
70
+ "generate-corpus": "node scripts/generate-corpus.mjs",
71
+ "smoke:mcp": "node scripts/smoke-mcp.mjs",
67
72
  "record:demo:payment-retry": "vhs scripts/record-demo-payment-retry.tape",
68
73
  "record:demo:drift": "vhs scripts/record-demo-drift.tape"
69
74
  },
70
75
  "dependencies": {
71
- "commander": "^12.1.0",
72
- "js-yaml": "^4.1.0"
76
+ "@modelcontextprotocol/sdk": "^1.29.0",
77
+ "commander": "^14.0.3",
78
+ "js-yaml": "^4.1.0",
79
+ "zod": "^4.3.6"
73
80
  },
74
81
  "devDependencies": {
75
- "@biomejs/biome": "^1.9.4",
82
+ "@biomejs/biome": "^2.4.9",
76
83
  "@types/js-yaml": "^4.0.9",
77
- "@types/node": "^20.19.0",
78
- "typescript": "^5.9.3",
79
- "vitest": "^4.0.15"
84
+ "@types/node": "^25.5.0",
85
+ "typescript": "^6.0.2",
86
+ "vitest": "^4.1.2"
80
87
  },
81
88
  "engines": {
82
89
  "node": ">=20"