arkgate 2.13.0 → 3.0.0

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.
Files changed (72) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +37 -22
  3. package/bin/ark-check.mjs +62 -4
  4. package/bin/ark-mcp.mjs +108 -1
  5. package/bin/ark-shared.mjs +204 -149
  6. package/bin/ark.mjs +90 -25
  7. package/bin/lib/adapter-contract.mjs +93 -0
  8. package/bin/lib/agent-gates.mjs +1 -0
  9. package/bin/lib/analysis-engine.mjs +1171 -0
  10. package/bin/lib/architecture-scan.mjs +84 -135
  11. package/bin/lib/ci-and-commands.mjs +31 -0
  12. package/bin/lib/config-warnings.mjs +7 -205
  13. package/bin/lib/field-install.mjs +67 -10
  14. package/bin/lib/gate-files.mjs +42 -3
  15. package/bin/lib/graph-cycles.mjs +4 -54
  16. package/bin/lib/hook-templates.mjs +33 -1
  17. package/bin/lib/host-support-matrix.mjs +7 -1
  18. package/bin/lib/install-migrate.mjs +54 -16
  19. package/bin/lib/presets.mjs +42 -2
  20. package/bin/lib/safety-diagnostics.mjs +18 -17
  21. package/bin/lib/scan-files.mjs +12 -1
  22. package/bin/lib/skill-install.mjs +8 -1
  23. package/bin/lib/source-policy.mjs +36 -0
  24. package/bin/lib/start-preview.mjs +271 -0
  25. package/bin/lib/ts-resolve.mjs +11 -2
  26. package/bin/lib/write-path-capabilities.mjs +4 -0
  27. package/compat/nestjs.cjs +2 -0
  28. package/compat/nestjs.d.ts +2 -0
  29. package/compat/nestjs.js +1 -0
  30. package/compat/runtime.cjs +2 -0
  31. package/compat/runtime.d.ts +2 -0
  32. package/compat/runtime.js +1 -0
  33. package/dist/configContract-BxSIwVRo.d.cts +259 -0
  34. package/dist/configContract-BxSIwVRo.d.ts +259 -0
  35. package/dist/eslint/index.cjs +125 -48
  36. package/dist/eslint/index.d.cts +7 -1
  37. package/dist/eslint/index.d.ts +7 -1
  38. package/dist/eslint/index.js +125 -48
  39. package/dist/index.cjs +1248 -3302
  40. package/dist/index.d.cts +359 -483
  41. package/dist/index.d.ts +359 -483
  42. package/dist/index.js +1231 -3248
  43. package/docs/agent-guide.md +28 -16
  44. package/docs/ai-gates.md +30 -7
  45. package/docs/migrate-from-ark-runtime-kernel.md +2 -3
  46. package/docs/package-surface.md +8 -13
  47. package/docs/production-hardening.md +17 -4
  48. package/docs/typescript-support.md +27 -0
  49. package/package.json +33 -11
  50. package/schemas/ark.analysis-result.schema.json +91 -0
  51. package/server.json +2 -2
  52. package/templates/skills/ark-architect.md +3 -2
  53. package/dist/configContract-iBLxx5Tz.d.cts +0 -53
  54. package/dist/configContract-iBLxx5Tz.d.ts +0 -53
  55. package/dist/eslint/index.cjs.map +0 -1
  56. package/dist/eslint/index.js.map +0 -1
  57. package/dist/index.cjs.map +0 -1
  58. package/dist/index.js.map +0 -1
  59. package/dist/nestjs/index.cjs +0 -2606
  60. package/dist/nestjs/index.cjs.map +0 -1
  61. package/dist/nestjs/index.d.cts +0 -23
  62. package/dist/nestjs/index.d.ts +0 -23
  63. package/dist/nestjs/index.js +0 -2582
  64. package/dist/nestjs/index.js.map +0 -1
  65. package/dist/runtime/index.cjs +0 -4014
  66. package/dist/runtime/index.cjs.map +0 -1
  67. package/dist/runtime/index.d.cts +0 -3
  68. package/dist/runtime/index.d.ts +0 -3
  69. package/dist/runtime/index.js +0 -3925
  70. package/dist/runtime/index.js.map +0 -1
  71. package/dist/types-BxBwnBpC.d.cts +0 -1041
  72. package/dist/types-Wcs_l1_J.d.ts +0 -1041
@@ -25,10 +25,13 @@ Each of the twelve archetypes (`crud-product`, `api-backend`, `frontend-surface`
25
25
  - plain-language analogy and anti-patterns,
26
26
  - optional book references for depth only.
27
27
 
28
- Scoring is **deterministic**: repo shape signals (workspaces, UI dirs, API surface,
29
- persistence, jobs, workflows, CLI `bin`, source-file count, …) are matched against the
30
- playbook. Framework packages may appear as secondary `toolHints` in JSON output never as
31
- the primary archetype id.
28
+ Scoring is **deterministic** and source/graph-first. Ark discovers package units and roots from
29
+ workspace manifests, `tsconfig`/`jsconfig` references, package exports and entrypoints, plus
30
+ conventional `src`/`source` directories. Runtime and peer dependencies contribute framework
31
+ signals; dev-only dependencies are reported but do not determine the application shape. Docs,
32
+ examples, and test packages are reported separately and excluded from root-product inference.
33
+ Framework packages may appear as secondary `toolHints` in JSON output — never as the primary
34
+ archetype id.
32
35
 
33
36
  All playbook labels, analogies, anti-patterns, and `--recommend` prose are **English**
34
37
  (`locale: "en"` in the playbook). Agents should present them as-is unless a future locale
@@ -43,7 +46,10 @@ npx ark-check --recommend --json
43
46
 
44
47
  `--recommend` does not require `ark.config.json`. It exits `0` and prints a progressive
45
48
  adoption plan: archetype id, preset, `confidence`, `runnerUp`, `why` (shape signals),
49
+ structured positive/negative `evidence`, discovered `signals.packageUnits`,
46
50
  `adoptInOrder.phase1`, `firstCommand` (`ark init --archetype …`), and `checkCommand`.
51
+ When the top two shapes are close or projected governed coverage is below 90%, JSON sets
52
+ `requiresConfirmation: true` and explains why in `confirmationReasons`.
47
53
 
48
54
  Human output highlights phase-1 layers and the analogy; JSON is the stable contract for
49
55
  MCP `ark_recommend` and the `/ark-architect` skill.
@@ -51,7 +57,7 @@ MCP `ark_recommend` and the `/ark-architect` skill.
51
57
  ### Terminal onboarding (Phase B)
52
58
 
53
59
  ```bash
54
- npx ark start --yes # preferred: shape → contract → **day-zero origin**gates → plan
60
+ npx ark start --yes # preferred: shape → compact contract → active hostCI → plan
55
61
  npx ark init --archetype crud-product --yes # non-interactive: shape → preset → origin → gates
56
62
  npx ark init # TTY wizard: pick application shape (1–8), not a framework
57
63
  npx ark-check --doctor # includes "New here?" when coverage is low or config is fresh
@@ -59,14 +65,20 @@ npx ark-check --report beginner.html --beginner # simplified HTML for enthusiast
59
65
  npx ark-check --watch # debounced re-check when governed files change
60
66
  ```
61
67
 
62
- **Day-zero origin (2.12+):** as soon as `ark.config.json` exists, `ark start` / `ark init`
63
- freeze `.ark/reports/origin.*` **before** writing agent docs, skills, or CI templates.
64
- Later `--report` shows evolution vs that snapshot. Do not `--reset-origin` unless the user
65
- explicitly wants a new baseline.
68
+ **Day-zero origin (2.12+):** `ark init` freezes `.ark/reports/origin.*` before writing agent
69
+ docs or CI templates. Compact `ark start` keeps first-run setup under five project files and
70
+ 25 KB;
71
+ run `ark-check --report ark-report.html` explicitly when you want to establish an origin/evolution
72
+ baseline. Do not `--reset-origin` unless the user explicitly wants a new baseline.
66
73
 
67
- **Default agent co-pilot:** `/ark-autopilot` (explore-first, dual plan A remediation + B
68
- pattern bets). Recon without applying: `/ark-explore`. Never treat empty `--plan` as
69
- “architecture healthy” without the explore pass.
74
+ To remove a compact host integration, preview `ark start --remove-host <host>` and add `--apply`
75
+ only after review. Ark removes only its exact compact artifacts, leaves customized files untouched
76
+ as unresolved decisions, and restores the integration with `ark start --tools <host> --apply`.
77
+
78
+ **Full-skill agent co-pilot:** after explicitly installing the `/ark-*` pack, use
79
+ `/ark-autopilot` (explore-first, dual plan A remediation + B pattern bets). Recon without
80
+ applying: `/ark-explore`. The default compact router uses MCP/CLI directly. Never treat empty
81
+ `--plan` as “architecture healthy” without the explore pass.
70
82
 
71
83
  `ark init --archetype <id>` maps playbook ids to named presets (`hexagonal`, `layered`,
72
84
  `feature-sliced`, `monorepo`). With `--yes` and no archetype, Ark auto-selects from
@@ -211,7 +223,7 @@ directories (`utils/`, `lib/`) must be classified explicitly via `/ark-contract`
211
223
 
212
224
  ## Supported agent hosts
213
225
 
214
- Wire write-gate + MCP + `/ark-*` skills with:
226
+ Wire write-gate + MCP + the full `/ark-*` skill set with:
215
227
 
216
228
  ```bash
217
229
  npx arkgate-check --install-agent-gates --tools claude,cursor,codex,grok
@@ -239,7 +251,7 @@ projections, metadata, workflow engine, and 11-layer architecture profile:
239
251
  ```ts
240
252
  import {
241
253
  createStrictArkKernel,
242
- } from 'arkgate/runtime';
254
+ } from '@arkgate/runtime';
243
255
 
244
256
  const ark = createStrictArkKernel();
245
257
  // ... define intents, event contracts, metadata, projections, and workflows through ark.*
@@ -249,8 +261,8 @@ const contract = ark.manifest().toJSON();
249
261
  // contract.observability, projections
250
262
  ```
251
263
 
252
- Use `arkgate/runtime` when evaluating the experimental kernel (root `arkgate` still re-exports
253
- for compatibility). Package surface policy: [package-surface.md](package-surface.md).
264
+ Use `@arkgate/runtime` only when evaluating the experimental kernel. The stable `arkgate` gate
265
+ package contains no runtime implementation. Package surface policy: [package-surface.md](package-surface.md).
254
266
 
255
267
  Agents should read `contract` and `ark.observability.report()` before generating or modifying code.
256
268
 
package/docs/ai-gates.md CHANGED
@@ -3,7 +3,8 @@
3
3
  **ArkGate** (`arkgate`) is the architecture co-pilot for AI TypeScript (write gate · CI · plan/loop).
4
4
  On Claude Code and Grok Build, an installed and trusted PreToolUse hook can block matched writes
5
5
  before they land on disk. Cursor and OpenAI Codex use advisory MCP validation at write time; CI is
6
- their hard repository check. See the
6
+ their hard repository check. Codex 0.123+ dispatches hooks for its native `apply_patch` handler,
7
+ but Code Mode hosts can execute deferred nested writes without that project hook event. See the
7
8
  [canonical host support matrix](../README.md#host-enforcement-support) before installing.
8
9
 
9
10
  Everything below uses the same `ark.config.json` as `arkgate-check` / `ark-check` (CI) — one
@@ -21,6 +22,11 @@ npx arkgate start
21
22
  # or: npx ark init
22
23
  ```
23
24
 
25
+ `ark start` asks for the active agent on a TTY (or detects it otherwise) and applies a compact
26
+ router setup: at most five project files and no `package.json` change unless you pass `--install`.
27
+ Use `--tools <host>` to select the host explicitly. The broader command below remains the explicit
28
+ way to install the full per-host `/ark-*` skill inventory.
29
+
24
30
  For non-interactive defaults, use:
25
31
 
26
32
  ```bash
@@ -35,7 +41,7 @@ npx arkgate-check --install-agent-gates
35
41
  ```
36
42
 
37
43
  The command writes templates for `.mcp.json`, Claude hooks, Cursor MCP/rules,
38
- GitHub Actions, `AGENTS.md`, a Codex TOML snippet under `docs/`, and (when
44
+ GitHub Actions, `AGENTS.md`, Codex `.codex/hooks.json` plus a TOML snippet under `docs/`, and (when
39
45
  selected) Grok Build project files under `.grok/`. It skips existing files unless
40
46
  you pass `--force`, so review and commit only the templates that match your project.
41
47
 
@@ -89,7 +95,7 @@ When no mechanical-safe patch applies, `autoPatch` is `null` (host still re-reas
89
95
  `ark_prepare_write` / judgment). Grok deny JSON also includes `autoPatch` + `"repair": true`
90
96
  when repair mode is on.
91
97
 
92
- `--install-agent-gates` writes Claude/Grok PreToolUse commands with `--hook-repair` enabled.
98
+ `--install-agent-gates` writes Claude/Grok/Codex PreToolUse commands with `--hook-repair` enabled.
93
99
  Reject-only installs: drop `--hook-repair` (or unset `ARK_HOOK_REPAIR`).
94
100
 
95
101
  Add to your project's `.claude/settings.json`:
@@ -231,6 +237,23 @@ through. It blocks the merge only when that status is required by repository pol
231
237
 
232
238
  Recommended for Ark projects.
233
239
 
240
+ Codex 0.123+ dispatches `PreToolUse` for the native `apply_patch` handler. Ark installs
241
+ `.codex/hooks.json` with `ApplyPatch|apply_patch|Write|Edit|MultiEdit` aliases and reconstructs
242
+ every added or updated file in a multi-file patch before allowing it. The hook root uses
243
+ `${CODEX_PROJECT_DIR:-${PWD:-.}}`; it must not use Claude-only `CLAUDE_PROJECT_DIR`.
244
+
245
+ This hook is best-effort in Codex Code Mode: some hosts execute deferred nested `apply_patch`
246
+ calls without dispatching the project `PreToolUse` event. ArkGate therefore does not treat the
247
+ presence of `.codex/hooks.json` as a universal hard-write guarantee; MCP remains advisory and the
248
+ required CI status is the hard repository boundary.
249
+
250
+ ```bash
251
+ npx ark-check --install-agent-gates --tools codex
252
+ ```
253
+
254
+ The generated hook includes `--hook-repair`, so a rejected patch carries the same structured
255
+ repair envelope as Claude and Grok. Codex still needs hook trust enabled for the project.
256
+
234
257
  Unlike Claude/Cursor (project-local MCP files), **Codex loads MCP servers only from
235
258
  `$CODEX_HOME/config.toml`** (default `~/.codex/config.toml`) — a **global** home file.
236
259
  Hand-editing with relative `--root .` is wrong: Codex does not use the project as cwd, so
@@ -253,9 +276,8 @@ args = ["arkgate-mcp", "--root", "/absolute/path/to/project", "--config", "/abso
253
276
  Then **restart Codex** — it does not hot-load MCP servers. Expect resource `ark://manifest`
254
277
  and tools `validate_code`, `ark_check`, `ark_coverage`, `ark_place`.
255
278
 
256
- Same model as Cursor for enforcement: advisory MCP for discovery/validation and `ark-check` as
257
- the hard CI check. It becomes a merge block only when the status is required. Register the MCP
258
- server as soon as the repo is adopted.
279
+ Codex uses the best-effort local patch hook plus advisory MCP for discovery/validation and
280
+ `ark-check` as the hard merge backstop. Register all three as soon as the repo is adopted.
259
281
 
260
282
  ### Multi-project Codex (home config last-wins)
261
283
 
@@ -357,10 +379,11 @@ write). Keep `ark-check` in CI and require its status when it must block merges.
357
379
 
358
380
  ## Any other agent runtime with shell hooks
359
381
 
360
- If your runtime can run a shell command before file writes and pass the tool payload on stdin (Claude Code or Grok PreToolUse contracts), `ark-mcp --hook` works as-is. The contract:
382
+ If your runtime can run a shell command before file writes and pass the tool payload on stdin, `ark-mcp --hook` works as-is. The contract:
361
383
 
362
384
  - stdin (Claude): JSON `{ "tool_name": "Write|Edit|MultiEdit", "tool_input": { "file_path": ..., ... } }`
363
385
  - stdin (Grok): JSON `{ "toolName": "write|search_replace|…", "toolInput": { "file_path": ..., ... } }` (also accepts Claude names)
386
+ - stdin (Codex): JSON `{ "tool_name": "apply_patch", "tool_input": { "patch": "*** Begin Patch…" } }`
364
387
  - exit `0` → allow; exit `2` → block, human-readable violations on stderr
365
388
  - Grok payloads also get `{ "decision": "deny", "reason": "…" }` on stdout when blocked
366
389
  - plumbing problems (no stdin, non-source files, files outside `--root`) never block
@@ -134,11 +134,10 @@ require adopting them. Static CLI/MCP enforcement remains the supported product
134
134
 
135
135
  ```diff
136
136
  - import { createStrictArkKernelFromConfig } from 'ark-runtime-kernel';
137
- + import { createStrictArkKernelFromConfig } from 'arkgate/runtime';
138
- // root `arkgate` still re-exports kernel symbols this major (compat)
137
+ + import { createStrictArkKernelFromConfig } from '@arkgate/runtime';
139
138
 
140
139
  - import { ArkModule } from 'ark-runtime-kernel/nestjs';
141
- + import { ArkModule } from 'arkgate/nestjs';
140
+ + import { ArkModule } from '@arkgate/runtime/nestjs';
142
141
 
143
142
  - import ark from 'ark-runtime-kernel/eslint';
144
143
  + import ark from 'arkgate/eslint';
@@ -17,6 +17,7 @@ This document is the consumer contract for **what is stable** vs **what is exper
17
17
  | **CLI** | `arkgate` / `arkgate-check` (aliases `ark` / `ark-check`) | Flags and human text may improve; **JSON output shapes** for `--json` (check, doctor, plan, coverage, recommend) are stable within a major. Additive fields OK; removals/renames are major. |
18
18
  | **MCP tools** | `arkgate-mcp` / `ark://…` resources | Tool names and primary argument shapes are stable within a major. |
19
19
  | **`ark.config.json`** | Layer globs, rules, include/exclude, forbiddenGlobals, intent prefixes, `peerIsolation`, `dynamicImportAllowlist`, `safety` thresholds | Versioned by `schemaVersion`; unknown fields fail closed and migrations preserve the previous supported major. |
20
+ | **`arkgate/schema/analysis-result`** | Public CLI/MCP/hook diagnostic envelope (`schemaVersion`, `valid`, `diagnostics`) | Versioned JSON Schema; committed v1 compatibility fixture protects rule, severity, location, and evidence fields. |
20
21
  | **Config JSON Schema** | `arkgate/schema` or `arkgate/schema/ark.config.schema.json` | Stable package resource subpaths for editor completion and contract tooling. |
21
22
  | **Agent skills** | `/ark-*` templates installed by `--install-agent-gates` | Skill *names* and “default flow” are stable; internal skill prose may evolve (e.g. explore dual-plan seed, day-zero origin order). |
22
23
  | **ESLint subpath** | `arkgate/eslint` | Config-driven layer/import rules; loads consumer `ark.config.json`. |
@@ -33,9 +34,9 @@ product claims**. Static architecture enforcement does not depend on them.
33
34
 
34
35
  | Surface | Import path | Notes |
35
36
  |---------|-------------|--------|
36
- | **Runtime kernel** | **`arkgate/runtime`** (preferred) | Experimental event bus, intents, policies, sagas, outbox, projections, and strict helpers. Not required for architecture enforcement. Built-in stores are **InMemory reference only** (not production durability) — see [production-hardening.md](./production-hardening.md). |
37
- | **Root package barrel** | `arkgate` | Still re-exports the experimental runtime kernel for **compatibility**. Prefer `arkgate/runtime` when evaluating it. Root may be thinned in a future **major**. |
38
- | **NestJS adapter** | `arkgate/nestjs` | Experimental optional peer `@nestjs/common`; wires a kernel into Nest DI. |
37
+ | **Runtime kernel** | **`@arkgate/runtime`** | Separate 0.x package, published under the `experimental` tag. Event bus, intents, policies, sagas, event buffer, projections, and strict helpers. Built-in stores are **InMemory reference only**. |
38
+ | **Runtime migration shim** | `arkgate/runtime` | Deprecated forwarder to `@arkgate/runtime`; contains no implementation and is removed in ArkGate 4. |
39
+ | **NestJS adapter** | `@arkgate/runtime/nestjs` | Experimental optional peer `@nestjs/common`; the deprecated `arkgate/nestjs` path forwards here. |
39
40
 
40
41
  ---
41
42
 
@@ -43,16 +44,10 @@ product claims**. Static architecture enforcement does not depend on them.
43
44
 
44
45
  ```ts
45
46
  // Preferred path when evaluating the experimental runtime kernel
46
- import {
47
- createStrictArkKernel,
48
- createStrictArkKernelFromConfig,
49
- } from 'arkgate/runtime';
50
-
51
- // Still works this major (compat; not preferred for new code)
52
- import { createStrictArkKernel } from 'arkgate';
47
+ import { createStrictArkKernel, createStrictArkKernelFromConfig } from '@arkgate/runtime';
53
48
 
54
49
  // Nest adapter
55
- import { ArkModule, InjectArk } from 'arkgate/nestjs';
50
+ import { ArkModule, InjectArk } from '@arkgate/runtime/nestjs';
56
51
  ```
57
52
 
58
53
  See [production-hardening.md](./production-hardening.md) for requirements an eventual
@@ -76,8 +71,8 @@ production deployment would need to satisfy; it is not a readiness certification
76
71
  | Break CLI JSON field, MCP tool rename, or required `ark.config` field | **major** |
77
72
  | New optional config field, new CLI flag, additive JSON | **minor** |
78
73
  | Bugfix with no contract change | **patch** |
79
- | Prefer `arkgate/runtime` over root (docs only; root still exports) | **patch/minor** |
80
- | Remove root kernel re-exports | **major** (with migration notes) |
74
+ | Additive experimental runtime API | `@arkgate/runtime` prerelease/minor |
75
+ | Remove deprecated `arkgate/runtime` forwarding shim | ArkGate **4.0** |
81
76
 
82
77
  ---
83
78
 
@@ -1,7 +1,7 @@
1
1
  # Production Hardening
2
2
 
3
3
  The optional runtime kernel is currently **experimental**. This page is a requirements checklist
4
- for teams evaluating **`arkgate/runtime`**, not a claim that the runtime is production-ready.
4
+ for teams evaluating **`@arkgate/runtime`**, not a claim that the runtime is production-ready.
5
5
  Static ArkGate adoption does not require it. See [package-surface.md](package-surface.md).
6
6
 
7
7
  ## Durability stance (R9)
@@ -19,11 +19,11 @@ stores that match their durability, ordering, retention, and operational require
19
19
  These defaults do not survive process restarts:
20
20
 
21
21
  - `InMemoryAuditStore`
22
- - `InMemoryOutboxStore`
22
+ - `InMemoryEventBuffer` (`InMemoryOutboxStore` is a deprecated compatibility alias)
23
23
  - `InMemoryReadModelStore`
24
24
  - `InMemoryWorkflowStore`
25
25
 
26
- Use them only when losing state is acceptable. JSDoc on `OutboxStore`, `AuditStore`,
26
+ Use them only when losing state is acceptable. JSDoc on `EventBufferStore`, `AuditStore`,
27
27
  `ReadModelStore`, and `WorkflowStore` restates this stance at the type level.
28
28
 
29
29
  ## Production Store Checklist
@@ -55,12 +55,25 @@ completed steps are compensated when handlers exist, and the workflow ends faile
55
55
  effects and compensations must therefore be idempotent, and audit/snapshot stores must be
56
56
  operational dependencies rather than best-effort telemetry.
57
57
 
58
+ ### Required recovery semantics (not implemented by built-ins)
59
+
60
+ | Contract | Required definition before a production claim |
61
+ |----------|-----------------------------------------------|
62
+ | Workflow recovery | Persist the last committed step and effect id; restart resumes only from that checkpoint and never assumes an in-flight effect failed or succeeded without reconciliation. |
63
+ | Optimistic versioning | Every snapshot write carries the previously read version; conflicting writes fail without overwriting and the caller reloads before retrying. |
64
+ | Dispatcher leases | A claim records owner and expiry atomically; only the owner may acknowledge it, and takeover is allowed only after expiry. |
65
+ | Idempotent delivery | Every message/effect has a stable idempotency key retained for the full retry window; duplicate attempts return the prior outcome without repeating the effect. |
66
+ | Atomic handoff | Application state and dispatch record commit in one transaction. Without this guarantee the API must be called an event buffer, not an outbox. |
67
+
68
+ The experimental package supplies none of these persistence guarantees. Fault/restart matrices
69
+ must cover crashes before and after every transaction, effect, checkpoint, lease, and acknowledgement.
70
+
58
71
  ## Interface Targets
59
72
 
60
73
  | Concern | Interface |
61
74
  |---------|-----------|
62
75
  | Audit records | `AuditStore` |
63
- | Outbox dispatch handoff | `OutboxStore` |
76
+ | Non-atomic dispatch buffer | `EventBufferStore` |
64
77
  | Projection state | `ReadModelStore` |
65
78
  | Workflow snapshots | `WorkflowStore` |
66
79
 
@@ -131,6 +131,33 @@ node scripts/ts-compat-matrix.mjs 7.0.2
131
131
  | Gate uses native Go typechecker API exclusively | Not required; future if 7.1+ exposes a stable Node API we adopt |
132
132
  | User tsconfigs with removed options still “just work” | User must migrate tsconfig (TS6/7); Ark reports resolve/parse failures clearly |
133
133
 
134
+ ## Static-analysis soundness envelope
135
+
136
+ ArkGate uses the TypeScript compiler API to extract dependency and ambient-capability facts. The
137
+ same Kernel implementation feeds the library, CLI, MCP write gate, and AICodeGate bundle.
138
+
139
+ Dependency forms enforced when their module specifier is a string literal:
140
+
141
+ - ESM `import`, `import type`, side-effect imports, and `export ... from` / `export type ... from`;
142
+ - TypeScript `import x = require("...")`;
143
+ - unshadowed CommonJS `require("...")`;
144
+ - dynamic `import("...")`.
145
+
146
+ Non-literal `import(expr)` and unshadowed `require(expr)` are reported as unresolved. They are
147
+ advisory by default, fail with `--strict-config`, and may be reviewed at file granularity through
148
+ `dynamicImportAllowlist`. A locally declared `require` function is not treated as CommonJS.
149
+
150
+ Forbidden capabilities are resolved with single-file TypeScript symbols. Local variables,
151
+ parameters, and imports shadow ambient names; aliases such as `const Clock = Date`, explicit
152
+ `globalThis`, static bracket access, and object destructuring remain detectable. Resolution of
153
+ module paths then uses the nearest tsconfig/jsconfig compiler options, including path aliases,
154
+ project-local packages, workspaces, and symlinked workspace entries.
155
+
156
+ ArkGate intentionally does not claim soundness for runtime-generated module names, `eval`, custom
157
+ loader functions, proxy-based globals, dynamically computed property keys, or aliases mutated
158
+ after declaration. Those constructs must remain absent from governed pure layers or be handled by
159
+ an explicit project policy. Every newly discovered bypass is minimized into the adversarial corpus.
160
+
134
161
  ## Future (7.1+ programmatic API)
135
162
 
136
163
  When Microsoft ships a stable Node API for native TypeScript 7.1+:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkgate",
3
- "version": "2.13.0",
3
+ "version": "3.0.0",
4
4
  "description": "ArkGate — architecture co-pilot for AI TypeScript (write gate, CI gate, plan/loop)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -13,9 +13,9 @@
13
13
  "require": "./dist/index.cjs"
14
14
  },
15
15
  "./runtime": {
16
- "types": "./dist/runtime/index.d.ts",
17
- "import": "./dist/runtime/index.js",
18
- "require": "./dist/runtime/index.cjs"
16
+ "types": "./compat/runtime.d.ts",
17
+ "import": "./compat/runtime.js",
18
+ "require": "./compat/runtime.cjs"
19
19
  },
20
20
  "./eslint": {
21
21
  "types": "./dist/eslint/index.d.ts",
@@ -24,10 +24,12 @@
24
24
  },
25
25
  "./schema": "./schemas/ark.config.schema.json",
26
26
  "./schema/ark.config.schema.json": "./schemas/ark.config.schema.json",
27
+ "./schema/analysis-result": "./schemas/ark.analysis-result.schema.json",
28
+ "./schema/ark.analysis-result.schema.json": "./schemas/ark.analysis-result.schema.json",
27
29
  "./nestjs": {
28
- "types": "./dist/nestjs/index.d.ts",
29
- "import": "./dist/nestjs/index.js",
30
- "require": "./dist/nestjs/index.cjs"
30
+ "types": "./compat/nestjs.d.ts",
31
+ "import": "./compat/nestjs.js",
32
+ "require": "./compat/nestjs.cjs"
31
33
  },
32
34
  "./package.json": "./package.json"
33
35
  },
@@ -43,6 +45,7 @@
43
45
  "files": [
44
46
  "bin",
45
47
  "bin/lib",
48
+ "compat",
46
49
  "dist",
47
50
  "schemas",
48
51
  "docs/agent-guide.md",
@@ -67,13 +70,23 @@
67
70
  "LICENSE"
68
71
  ],
69
72
  "scripts": {
70
- "build": "tsup",
73
+ "build": "node scripts/clean-gate-dist.mjs && tsup",
74
+ "build:runtime": "tsup --config packages/runtime/tsup.config.ts",
71
75
  "dev": "tsup --watch",
72
76
  "test": "vitest",
73
77
  "test:run": "vitest run",
74
78
  "test:coverage": "npm run build && vitest run --coverage --coverage.reporter=text-summary --coverage.reporter=json-summary",
75
- "test:mutation": "npm run build && stryker run",
79
+ "test:mutation": "npm run build && stryker run && npm run check:mutation-groups",
80
+ "check:mutation-groups": "node scripts/check-mutation-groups.mjs",
81
+ "test:property": "vitest run tests/property",
82
+ "test:fuzz": "npm run build && ARK_FUZZ_CAMPAIGN=pr vitest run tests/fuzz",
83
+ "test:fuzz:extended": "npm run build && ARK_FUZZ_CAMPAIGN=extended vitest run tests/fuzz",
76
84
  "test:confidence": "npm run test:coverage && npm run test:mutation",
85
+ "test:adapter-parity": "vitest run tests/unit/adapters/adapterParity.test.ts tests/unit/eslint/parity.test.ts",
86
+ "test:onboarding-matrix": "for shard in library/small library/medium library/large api/small api/medium api/large frontend/small frontend/medium frontend/large monorepo/small monorepo/medium monorepo/large; do O04_SHARD=$shard npm run test:onboarding-matrix:shard; done",
87
+ "test:onboarding-matrix:shard": "vitest run tests/unit/static-check/o04OnboardingMatrix.test.ts",
88
+ "test:gate-only": "vitest run tests/unit/static-check/arkCheck.test.ts tests/unit/mcp/arkMcp.test.ts tests/unit/eslint",
89
+ "test:package-isolation": "node scripts/smoke-package-isolation.mjs",
77
90
  "typecheck": "tsc --noEmit",
78
91
  "security:audit": "npm audit --omit=dev --audit-level=high",
79
92
  "check:architecture": "node bin/ark-check.mjs --root . --config ark.config.json --strict",
@@ -82,6 +95,8 @@
82
95
  "check:layer-match": "node scripts/generate-layer-match.mjs --check",
83
96
  "generate:cli-pure": "node scripts/generate-cli-pure.mjs",
84
97
  "check:cli-pure": "node scripts/generate-cli-pure.mjs --check",
98
+ "generate:analysis-engine": "node scripts/generate-analysis-engine.mjs",
99
+ "check:analysis-engine": "node scripts/generate-analysis-engine.mjs --check",
85
100
  "check:gallery-starters": "node scripts/check-gallery-starters.mjs",
86
101
  "generate:gallery-starters": "node scripts/check-gallery-starters.mjs --write",
87
102
  "test:ts-compat": "node scripts/ts-compat-matrix.mjs 5.9.3 && node scripts/ts-compat-matrix.mjs 6.0.3 && node scripts/ts-compat-matrix.mjs 7.0.2",
@@ -89,9 +104,15 @@
89
104
  "eval:corpus": "node eval/validate-corpus.mjs",
90
105
  "eval:comparative": "node eval/comparative-run.mjs",
91
106
  "eval:loop-cost": "node eval/loop-cost-run.mjs",
107
+ "eval:adoption": "node eval/adoption-run.mjs",
108
+ "test:adoption-harness": "vitest run tests/unit/eval/adoptionHarness.test.ts",
92
109
  "bench:scale": "node scripts/ark-scale-bench.mjs",
110
+ "test:scale-bench": "npm run build && vitest run tests/unit/scripts/arkScaleBench.test.ts",
93
111
  "check:module-budgets": "node scripts/check-module-budgets.mjs",
94
112
  "check:package-files": "node scripts/verify-package-files.mjs",
113
+ "check:release-artifacts": "node scripts/verify-release-artifacts.mjs",
114
+ "test:release-artifacts": "vitest run tests/unit/scripts/verifyReleaseArtifacts.test.ts",
115
+ "audit:beta-exit": "node scripts/beta-exit-audit.mjs",
95
116
  "clean": "rm -rf dist",
96
117
  "release:npm": "node scripts/release-npm.mjs",
97
118
  "prepack": "npm run build"
@@ -100,11 +121,11 @@
100
121
  "typescript": "^5.9.3"
101
122
  },
102
123
  "peerDependencies": {
103
- "@nestjs/common": ">=9",
124
+ "@arkgate/runtime": ">=0.1.0-experimental.0 <1",
104
125
  "typescript": ">=5.0.0 <8"
105
126
  },
106
127
  "peerDependenciesMeta": {
107
- "@nestjs/common": {
128
+ "@arkgate/runtime": {
108
129
  "optional": true
109
130
  },
110
131
  "typescript": {
@@ -127,6 +148,7 @@
127
148
  "@stryker-mutator/vitest-runner": "^9.6.1",
128
149
  "@types/node": "^20.14.0",
129
150
  "@vitest/coverage-v8": "^3.2.6",
151
+ "fast-check": "^4.9.0",
130
152
  "reflect-metadata": "^0.2.2",
131
153
  "rxjs": "^7.8.2",
132
154
  "tsup": "^8.1.0",
@@ -0,0 +1,91 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://unpkg.com/arkgate@2/schemas/ark.analysis-result.schema.json",
4
+ "title": "ArkGate analysis result",
5
+ "type": "object",
6
+ "additionalProperties": false,
7
+ "required": [
8
+ "schemaVersion",
9
+ "valid",
10
+ "diagnostics"
11
+ ],
12
+ "properties": {
13
+ "schemaVersion": {
14
+ "const": "1.0"
15
+ },
16
+ "valid": {
17
+ "type": "boolean"
18
+ },
19
+ "diagnostics": {
20
+ "type": "array",
21
+ "items": {
22
+ "type": "object",
23
+ "additionalProperties": false,
24
+ "required": [
25
+ "ruleId",
26
+ "severity",
27
+ "message",
28
+ "location",
29
+ "evidence"
30
+ ],
31
+ "properties": {
32
+ "ruleId": {
33
+ "type": "string",
34
+ "minLength": 1
35
+ },
36
+ "severity": {
37
+ "enum": [
38
+ "error",
39
+ "warning"
40
+ ]
41
+ },
42
+ "message": {
43
+ "type": "string",
44
+ "minLength": 1
45
+ },
46
+ "location": {
47
+ "type": "object",
48
+ "additionalProperties": false,
49
+ "required": [
50
+ "file",
51
+ "line",
52
+ "column"
53
+ ],
54
+ "properties": {
55
+ "file": {
56
+ "type": "string",
57
+ "minLength": 1
58
+ },
59
+ "line": {
60
+ "type": "integer",
61
+ "minimum": 1
62
+ },
63
+ "column": {
64
+ "type": "integer",
65
+ "minimum": 1
66
+ }
67
+ }
68
+ },
69
+ "evidence": {
70
+ "type": "object",
71
+ "additionalProperties": false,
72
+ "properties": {
73
+ "target": {
74
+ "type": "string"
75
+ },
76
+ "fromLayer": {
77
+ "type": "string"
78
+ },
79
+ "toLayer": {
80
+ "type": "string"
81
+ },
82
+ "typeOnly": {
83
+ "type": "boolean"
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/pedroknigge/arkgate",
7
7
  "source": "github"
8
8
  },
9
- "version": "2.13.0",
9
+ "version": "3.0.0",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "arkgate",
14
- "version": "2.13.0",
14
+ "version": "3.0.0",
15
15
  "runtimeHint": "npx",
16
16
  "transport": {
17
17
  "type": "stdio"
@@ -44,8 +44,9 @@ the same files or weaken the gate.
44
44
 
45
45
  1. **Detect the shape** — call MCP tool **`ark_recommend`** (or run
46
46
  `ark-check --recommend --json`). Read `archetype`, `preset`, `confidence`,
47
- `adoptInOrder.phase1`, `analogy`, and `why`. Ask at most **two** questions only
48
- if `confidence < 0.5`:
47
+ `adoptInOrder.phase1`, `analogy`, `why`, `evidence`, and `requiresConfirmation`.
48
+ Ask at most **two** questions only if `requiresConfirmation` is true (or for compatibility
49
+ with older ArkGate output, `confidence < 0.5`):
49
50
  - "Will this app save data between sessions?"
50
51
  - "Is this one app or several in one repository?"
51
52
 
@@ -1,53 +0,0 @@
1
- /**
2
- * Canonical, pure contract for ark.config.json.
3
- *
4
- * Tooling adapters own filesystem I/O; this module owns JSON parsing, deterministic
5
- * migration, defaults, validation, diagnostics, and the published JSON Schema.
6
- * The standalone CLI artifact is generated into bin/lib/config-contract.mjs.
7
- */
8
- declare const ARK_CONFIG_SCHEMA_VERSION: "1.0";
9
- type ArkConfigCyclePolicy = 'strict' | 'soft' | 'framework-soft' | 'off';
10
- type ArkConfigLayer = {
11
- name: string;
12
- patterns: string[];
13
- exclude?: string[];
14
- intentPrefixes?: string[];
15
- description?: string;
16
- forbiddenGlobals?: string[];
17
- mayImportInfrastructure?: boolean;
18
- optional?: boolean;
19
- };
20
- type ArkConfigRule = {
21
- from: string;
22
- to: string;
23
- allowed: boolean;
24
- message?: string;
25
- peerIsolation?: boolean;
26
- sliceFolders?: string[];
27
- };
28
- type ArkConfigSafety = {
29
- maxTsSuppressions?: number;
30
- maxAnyCasts?: number;
31
- allowInMemory?: boolean;
32
- allowDisabledPeerIsolation?: boolean;
33
- };
34
- type ArkConfig = {
35
- $schema: string;
36
- schemaVersion: typeof ARK_CONFIG_SCHEMA_VERSION;
37
- name?: string;
38
- include: string[];
39
- exclude?: string[];
40
- excludeGenerated?: boolean;
41
- frameworkOverlay?: string;
42
- layers: ArkConfigLayer[];
43
- rules: ArkConfigRule[];
44
- cyclePolicy?: ArkConfigCyclePolicy;
45
- dynamicImportAllowlist?: string[];
46
- safety?: ArkConfigSafety;
47
- };
48
- type ArkConfigLoadResult = {
49
- config: ArkConfig;
50
- migratedFrom: 'unversioned' | null;
51
- };
52
-
53
- export type { ArkConfig as A, ArkConfigRule as a, ArkConfigLayer as b, ArkConfigLoadResult as c };