arkgate 2.1.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 (64) hide show
  1. package/CHANGELOG.md +1249 -0
  2. package/LICENSE +21 -0
  3. package/README.md +218 -0
  4. package/SECURITY.md +39 -0
  5. package/bin/ark-check.mjs +5204 -0
  6. package/bin/ark-mcp.mjs +898 -0
  7. package/bin/ark-shared.mjs +1520 -0
  8. package/bin/ark.mjs +491 -0
  9. package/dist/eslint/index.cjs +222 -0
  10. package/dist/eslint/index.cjs.map +1 -0
  11. package/dist/eslint/index.d.cts +42 -0
  12. package/dist/eslint/index.d.ts +40 -0
  13. package/dist/eslint/index.js +193 -0
  14. package/dist/eslint/index.js.map +1 -0
  15. package/dist/index.cjs +3080 -0
  16. package/dist/index.cjs.map +1 -0
  17. package/dist/index.d.cts +577 -0
  18. package/dist/index.d.ts +577 -0
  19. package/dist/index.js +2998 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/nestjs/index.cjs +2332 -0
  22. package/dist/nestjs/index.cjs.map +1 -0
  23. package/dist/nestjs/index.d.cts +22 -0
  24. package/dist/nestjs/index.d.ts +22 -0
  25. package/dist/nestjs/index.js +2308 -0
  26. package/dist/nestjs/index.js.map +1 -0
  27. package/dist/types-DpdVN7Lm.d.cts +1023 -0
  28. package/dist/types-DpdVN7Lm.d.ts +1023 -0
  29. package/docs/agent-guide.md +490 -0
  30. package/docs/ai-gates.md +337 -0
  31. package/docs/ark-check-example.json +87 -0
  32. package/docs/assets/ark-write-gate.svg +28 -0
  33. package/docs/brownfield-adoption.md +87 -0
  34. package/docs/demos/01-write-gate-self-correction.md +74 -0
  35. package/docs/demos/02-brownfield-baseline-adoption.md +71 -0
  36. package/docs/demos/03-copilot-autopilot.md +83 -0
  37. package/docs/enthusiast/README.md +62 -0
  38. package/docs/enthusiast/explanation-application-shape.md +29 -0
  39. package/docs/enthusiast/how-to-agent-gates.md +36 -0
  40. package/docs/enthusiast/how-to-gallery-starter.md +27 -0
  41. package/docs/enthusiast/how-to-pick-shape.md +45 -0
  42. package/docs/enthusiast/how-to-policy-pack.md +37 -0
  43. package/docs/enthusiast/reference-archetypes.md +36 -0
  44. package/docs/enthusiast/reference-commands.md +50 -0
  45. package/docs/enthusiast/tutorial-first-project.md +86 -0
  46. package/docs/production-hardening.md +59 -0
  47. package/package.json +125 -0
  48. package/server.json +39 -0
  49. package/templates/architecture-playbook.json +339 -0
  50. package/templates/policy-packs/enthusiast-feature-sliced.json +20 -0
  51. package/templates/policy-packs/enthusiast-hexagonal.json +18 -0
  52. package/templates/policy-packs/enthusiast-layered.json +18 -0
  53. package/templates/policy-packs/enthusiast-monorepo.json +18 -0
  54. package/templates/skills/ark-adopt.md +103 -0
  55. package/templates/skills/ark-architect.md +90 -0
  56. package/templates/skills/ark-autopilot.md +95 -0
  57. package/templates/skills/ark-contract.md +98 -0
  58. package/templates/skills/ark-coverage.md +96 -0
  59. package/templates/skills/ark-explain.md +78 -0
  60. package/templates/skills/ark-fix.md +96 -0
  61. package/templates/skills/ark-loop.md +69 -0
  62. package/templates/skills/ark-place.md +68 -0
  63. package/templates/skills/ark-runtime.md +62 -0
  64. package/templates/skills/ark-upgrade.md +109 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,1249 @@
1
+ # Changelog
2
+
3
+ All notable changes to ArkGate (`arkgate`; formerly `ark-runtime-kernel`) are documented here.
4
+
5
+ ## 2.1.0 — 2026-07-08
6
+
7
+ **Identity: ArkGate.** Same product and codebase; honest package name.
8
+
9
+ ### Changed
10
+
11
+ - **npm package renamed to [`arkgate`](https://www.npmjs.com/package/arkgate)** (was
12
+ `ark-runtime-kernel`). Product name: **ArkGate** — architecture co-pilot / gate for AI
13
+ TypeScript. The optional runtime API is not the product.
14
+ - **CLI bins:** primary `arkgate`, `arkgate-check`, `arkgate-mcp`. Compat aliases
15
+ `ark` / `ark-check` / `ark-mcp` remain for one major.
16
+ - **MCP / server.json:** identifier `arkgate`, MCP name `io.github.pedroknigge/arkgate`.
17
+ - **GitHub Action** and docs/examples install paths point at `arkgate`.
18
+ - Config file remains `ark.config.json`; skills remain `/ark-*` (contract family).
19
+
20
+ ### Migration
21
+
22
+ ```bash
23
+ npm uninstall ark-runtime-kernel
24
+ npm install -D arkgate typescript
25
+ # bins: npx arkgate-check … (or still npx ark-check …)
26
+ ```
27
+
28
+ Predecessor package will be **deprecated** on npm with a pointer here after publish.
29
+
30
+ ## 2.0.1 — 2026-07-08
31
+
32
+ Docs + agent-host polish on top of the 2.0.0 co-pilot release.
33
+
34
+ ### Added
35
+
36
+ - **Grok Build as a first-class agent host** — `ark-check --install-agent-gates --tools grok`
37
+ writes `.grok/config.toml` (MCP), `.grok/hooks/ark-write-gate.json` (SessionStart + PreToolUse),
38
+ and `/ark-*` skills under `.grok/skills/<name>/SKILL.md`. Auto-detected from a project `.grok/` dir.
39
+ - **`ark-mcp --hook` Grok payloads** — accepts camelCase `toolName`/`toolInput` and
40
+ `write`/`search_replace`; emits `{ "decision": "deny", "reason": "…" }` on stdout for Grok.
41
+ - **README skill inventory** — table of all eleven `/ark-*` skills with a one-line summary each.
42
+
43
+ ### Documentation / positioning
44
+
45
+ - Public title and framing: **Ark — Architecture Co-pilot for AI TypeScript** (write gate · CI ·
46
+ co-pilot). npm name `ark-runtime-kernel` called out as historical; product is not the optional
47
+ runtime kernel.
48
+ - [docs/ai-gates.md](docs/ai-gates.md), [docs/agent-guide.md](docs/agent-guide.md), enthusiast
49
+ how-to, demos, roadmaps, and hexagonal example updated for Grok + skill list.
50
+
51
+ ### Also in this train (from the showcase field branch)
52
+
53
+ - Showcase HTML architecture report + origin/latest/history snapshots under `.ark/reports/`
54
+ - Autopilot before/after report steps; empty-scope false-green fix; monorepo/start TS7 hardening
55
+ - Unit/e2e `*.spec.ts` / `*.test.ts` excluded from architecture scope
56
+
57
+ ## 2.0.0 — 2026-07-08
58
+
59
+ **The architecture co-pilot.** This major completes the Gate → Guide → **Co-pilot** arc: Ark can
60
+ now take a non-developer from "I have a project" to "governed, cleaned up, and enforced," with an
61
+ agent doing the work and Ark keeping it honest. It's built on the three primitives every modern
62
+ agent harness uses — **plan**, **goal**, **loop** — composed into a guided, tiered flow.
63
+
64
+ This is a **milestone** major, not an API break: everything from 1.x keeps working, and the two
65
+ aliases previously earmarked for 2.0 removal (`AIGateViolation.code`, `layeredArchitectureRules()`)
66
+ are **retained** to avoid surprising consumers. Upgrade with `npx ark upgrade`.
67
+
68
+ ### Added — Phase I (autopilot + tiers)
69
+
70
+ - **`/ark-autopilot` skill** — the end-to-end co-pilot for non-developers. One flow: guided setup
71
+ (`ark start`) → show the plan (`ark-check --plan`) → drive the fixes (`/ark-loop`) → confirm the
72
+ gates are enforcing → report, all in plain language with approvals. It auto-applies only
73
+ `mechanical-safe` changes (validated, with rollback) and PROPOSES the rest; the agent edits, Ark
74
+ validates; code only, never weakening the gate.
75
+ - **Two tiers, one contract** — documented in `/ark-autopilot`: newbie = the autopilot flow;
76
+ expert = the pieces directly (`ark init` / `/ark-contract` / `ark-check --plan` / `/ark-fix` /
77
+ the gate). `ark start` now points newcomers at the autopilot as the next step.
78
+
79
+ ### Added — Phase J (proof)
80
+
81
+ - **Classifier-precision corpus test** — a labeled set (type-only / value / forbidden-global /
82
+ circular) asserting the classifier matches every label and NEVER marks anything but a type-only
83
+ import move as `mechanical-safe` (the zero-false-safe guarantee the autopilot depends on).
84
+ - **End-to-end demo** — `docs/demos/03-copilot-autopilot.md`.
85
+ - **Enforcement-handoff test** — verifies the guided path leaves config + AGENTS.md + the CI gate
86
+ active ("and stays that way").
87
+
88
+ ### Added — Field-hardened co-pilot (honesty · detection · frameworks)
89
+
90
+ - **Three operating modes** on one contract: **suggest** (greenfield shape), **adapt** (raise
91
+ coverage / match real layout), **enforce** (gates honestly hold the line). Surfaced by
92
+ `ark start`, `--plan`, and `--doctor` — not just "newbie vs expert" entry styles.
93
+ - **False-green closed.** `ark-check --plan` embeds `governedPercent` and sets `goal.met` only
94
+ when violations are clear *and* coverage is meaningful (≥50%). A 0% governed repo no longer
95
+ prints "meets contract / Done — guards your architecture."
96
+ - **Shape-signal hygiene.** Dot-directories (`.github`, `.claude`, `.codex`, …) are skipped when
97
+ scoring archetypes — CI YAML and Ark's own gates no longer flip recommend to
98
+ "event-coordinator."
99
+ - **Framework layout overlays** on init/start presets: Nest (`*.controller.ts` /
100
+ `*.service.ts` / `*.module.ts`), Next (app/pages/components), express, and library
101
+ conventions are merged into hexagonal/layered globs so starters get real governed% on day one.
102
+ - **Stronger detection:** `@nestjs/*`, Nest filename conventions, `next`, express-like HTTP
103
+ frameworks weighted in the architecture playbook.
104
+ - **pnpm runner reliability:** emitted commands use
105
+ `pnpm --config.verify-deps-before-run=false exec …` so `ERR_PNPM_IGNORED_BUILDS` (sharp,
106
+ esbuild, tailwind oxide, …) no longer blocks Ark on common pnpm apps.
107
+ - **TypeScript resolution:** load TS from the project, then Ark; `--plan` still reports coverage
108
+ honesty when TS is missing (instead of a hard crash mid-start).
109
+
110
+ ### Note
111
+
112
+ - The intermittent CI "onTaskUpdate" vitest flake is fixed (single-fork test run).
113
+ - Field matrix harness (not shipped in the package): `../beta-field-test/run-matrix.mjs`.
114
+
115
+ ## 1.19.0 — 2026-07-08
116
+
117
+ Co-pilot Phase H — the safe apply loop (the `loop` primitive).
118
+
119
+ ### Added
120
+
121
+ - **`/ark-loop` skill** — drives the remediation plan toward the goal, one step at a time, in a
122
+ discardable git worktree: auto-applies only the changes Ark classed `mechanical-safe`
123
+ (validating each with `ark-check` and rolling back any regression), PROPOSES the `judgment`
124
+ ones for a human decision, and never weakens the gate. Loops until the goal is met or a round
125
+ makes no progress, then reports what was auto-applied vs proposed vs deferred. Honors the
126
+ principle: the agent edits, Ark validates — code only, never DB/schema. Installed for every
127
+ detected agent CLI like the other `/ark-*` skills.
128
+ - **`goal.met`** in `ark-check --plan --json` — the loop's termination signal (true when there
129
+ are no active violations left). **Note (2.0.0):** `goal.met` was tightened to also require
130
+ meaningful governed coverage — see 2.0 field-hardening above.
131
+
132
+ ## 1.18.0 — 2026-07-08
133
+
134
+ Co-pilot Phase G — a guided front door for newcomers (`ark start`).
135
+
136
+ ### Added
137
+
138
+ - **`ark start`** — one guided command that takes a newcomer from "I have a project" to
139
+ "governed, with a plan," in plain language and without knowing any preset or skill name. It
140
+ looks at the repo and describes the shape in everyday terms, sets up the config + agent/CI
141
+ gates, and finishes with the classified plan (`safe to auto-fix` vs `your call`) plus plain
142
+ next steps. On an established codebase (≥150 files) it adopts your real structure via
143
+ detection instead of imposing a preset; on a fresh project it uses the recommended shape.
144
+ Interactive by default; `--yes` runs non-interactively. It only orchestrates existing steps
145
+ (recommend → init → `--plan`) and changes no source code. This is the co-pilot's guided-entry
146
+ and plain-language layer (Phase G).
147
+
148
+ ## 1.17.0 — 2026-07-08
149
+
150
+ Co-pilot Phase F — a classified remediation plan (the `plan` + `goal` primitives).
151
+
152
+ ### Added
153
+
154
+ - **`ark-check --plan [--json]`** — reads your active violations and sorts each into
155
+ `mechanical-safe` (behavior-preserving and gate-verifiable — safe for an agent to auto-apply),
156
+ `judgment` (real coupling or a design choice — Ark proposes, you decide), or `deferred`, with a
157
+ `confidence` and a plain-language `rationale`, ordered auto-first, wrapped in a `goal` block
158
+ (active violations → 0 without weakening the contract). Report-only — it changes no files.
159
+ This is the **plan** primitive of Ark's co-pilot; the coming worktree-safe apply-loop consumes
160
+ it. The classifier (`classifyRemediation`) is shared in `ark-shared.mjs` so the CLI, the MCP
161
+ gate, and the future loop classify identically. `--doctor` now points at it. The v1 classifier
162
+ is biased toward `judgment` — only a provably-safe type-only import move earns `mechanical-safe`.
163
+
164
+ ## 1.16.0 — 2026-07-08
165
+
166
+ One command to update Ark.
167
+
168
+ ### Added
169
+
170
+ - **`ark upgrade`** (alias **`ark update`**) — a single command that replaces the multi-step
171
+ update chain: bumps the package to `@latest` (via the detected package manager), refreshes
172
+ gate templates + `/ark-*` skills (and Codex home prompts when `~/.codex` exists), migrates
173
+ command runners to the project's package manager, and runs the strict architecture check.
174
+ `--no-install` refreshes gates/skills against the installed version; `--no-strict` skips the
175
+ final check. Each step reruns as a fresh process, so the refresh runs from the freshly
176
+ installed version. The `/ark-upgrade` skill and README now point at it.
177
+
178
+ ## 1.15.1 — 2026-07-08
179
+
180
+ Fix package-manager detection so a stray lockfile can't hijack a project's commands.
181
+
182
+ ### Fixed
183
+
184
+ - **A leftover `pnpm-lock.yaml` (or `yarn.lock`) no longer hijacks an npm project.** Detection
185
+ now honors the `package.json` `packageManager` field first, and on a lockfile conflict a
186
+ present `package-lock.json` wins — because `npx` runs fine in a pnpm/yarn repo, but
187
+ `pnpm exec` / `yarn` in an npm repo breaks (`ERR_PNPM_OUTDATED_LOCKFILE`,
188
+ `ERR_PNPM_ABORTED_REMOVE_MODULES_DIR_NO_TTY`, a spurious pnpm lock). Previously any
189
+ `pnpm-lock.yaml` was preferred over `package-lock.json`, so `--migrate-commands` rewrote the
190
+ `check:architecture` script (and every emitted command) to `pnpm exec`, and `npm run
191
+ check:architecture` then failed. All emitted commands, the CI workflow, the install hints,
192
+ and the stale-runner advisory share the one detector.
193
+ - **Multiple-lockfile warning.** `--install-agent-gates` and `--migrate-commands` now say which
194
+ package manager they picked when more than one lockfile is present, and how to override it
195
+ (set `packageManager`, or remove the stray lockfile).
196
+
197
+ ## 1.15.0 — 2026-07-08
198
+
199
+ Brownfield install & onboarding hardening + layer `exclude` — from a real install session
200
+ on a mature repo.
201
+
202
+ ### Changed
203
+
204
+ - **No install lifecycle scripts.** Removed the `postinstall` banner (and `bin/ark-postinstall.mjs`).
205
+ It was a pure `console.log`, but its mere presence tripped pnpm's build-script approval gate;
206
+ in a hardened repo (blocked build scripts + `minimumReleaseAge`) that left `pnpm install` at
207
+ exit 1 and could take down a dev server. Ark now installs with zero prompts and never runs code
208
+ on install. The "run `ark init`" guidance lives in the README and npm page instead.
209
+ - **`ark init` / `ark-check --recommend` route mature repos to adoption.** On an established
210
+ codebase (≥150 source files) where a starter contract governs a thin slice, both now steer to
211
+ `ark-check --recommend --write-plan` + `/ark-adopt` — which align the contract to the repo's
212
+ real structure — instead of leaving a thin or false-red gate from aspirational DDD wildcards.
213
+
214
+ ### Fixed
215
+
216
+ - **`ark --help` / `ark -h` / `ark help`** now print usage and exit 0 (a flag in the command
217
+ position was reported as `Unknown command: --help`).
218
+ - **Generated CI** enables corepack **before** `actions/setup-node`, so `cache: pnpm|yarn` can
219
+ resolve the package manager on a fresh runner instead of failing.
220
+
221
+ ### Added
222
+
223
+ - **Layer `exclude` globs.** A layer may declare `exclude: [...]` to carve subtrees out of a
224
+ broad `patterns` glob. An excluded file is ungoverned by that layer — removed from its rules
225
+ and `forbiddenGlobals` too. Resolved in the single `layerForFile` matcher shared by the
226
+ ark-check CI gate and the ark-mcp write gate, so both classify identically. The wildcard
227
+ starter presets (hexagonal, layered) now ship `"exclude": ["**/kernel/**"]` on every layer,
228
+ so `src/**/domain/**` no longer mis-flags framework internals under `src/kernel/domain/`.
229
+ - **`"./package.json"` export** — tooling can read the installed version without an exports error.
230
+
231
+ ## 1.14.0 — 2026-07-07
232
+
233
+ Architect onboarding Phases A–E: enthusiast-first path from application shape to gated adoption.
234
+
235
+ ### Added
236
+
237
+ - **`templates/architecture-playbook.json`** — ten tool-agnostic application archetypes.
238
+ - **`ark-check --recommend`** (+ `--json`, **`--write-plan`** → `ark-adoption-plan.json`).
239
+ - **`ark init` enthusiast wizard** and **`ark init --archetype <id> --yes`**.
240
+ - **MCP `ark_recommend`**, skill **`/ark-architect`**, session-context enthusiast hint.
241
+ - **Terminal UX**: doctor "New here?", fix-class / `enthusiastHint`, `--watch`, `--report --beginner`.
242
+ - **Example gallery** (`examples/*-starter/`), comparative eval (30 prompts), nightly workflow, three public demo scripts.
243
+ - **Enthusiast policy packs** — `ark-check --list-policy-packs`, `--apply-policy-pack enthusiast-<preset>`.
244
+ - **Diátaxis enthusiast track** — `docs/enthusiast/`.
245
+
246
+ ### Fixed
247
+
248
+ - **`collectRepoShapeSignals`** — skip unreadable directories instead of crashing `--recommend`.
249
+ - **Policy pack ids** — reject path-like ids; only canonical `templates/policy-packs/` entries apply.
250
+
251
+ ## 1.13.0 — 2026-07-06
252
+
253
+ ### Added
254
+
255
+ - **`ark-check --doctor`** — one consolidated adoption health view: governed %, ungoverned
256
+ directories, empty layers, weak rule coverage, the violation summary (value vs type-only +
257
+ concentration verdict), installed gates, installed skills, baseline health, and stale command
258
+ runners — each with the exact fix command, plus a ranked "Top actions" list. `--doctor --json`
259
+ for tooling.
260
+ - **Brownfield burn-down playbook** ([docs/brownfield-adoption.md](docs/brownfield-adoption.md))
261
+ — the end-to-end sequence for a large pre-existing codebase (diagnose → classify → facade
262
+ split → freeze only real debt → burn down), plus a matching `/ark-fix` fix class for
263
+ relocating raw infrastructure access (SQL or a DB client imported into a route) **verbatim**
264
+ into a repository/adapter — the value-import counterpart to the type-only inversion pattern.
265
+
266
+ ### Changed
267
+
268
+ - `/ark-upgrade` now handles the pnpm `minimumReleaseAge` cooling-off: when a freshly-cut
269
+ version is inside the window, add it to `minimumReleaseAgeExclude` before installing so a
270
+ loose-mode `pnpm add` can't leave a lockfile that `--frozen-lockfile` (CI) rejects.
271
+
272
+ ## 1.12.0 — 2026-07-06
273
+
274
+ Makes `ark.config.json` authoritative on BOTH gates, and closes the upgrade gap where the
275
+ package-manager-aware commands didn't reach a repo's existing gate files.
276
+
277
+ ### Changed
278
+
279
+ - **The AI write gate honors the contract over its infra heuristic.** A cross-layer import
280
+ that resolves to a declared layer is now judged by the config's layer RULES — exactly like
281
+ `ark-check` — so the write gate and CI can't disagree on a governed edge. An edge the
282
+ contract allows (a route calling a repository, a repository importing the DB) is no longer
283
+ blocked, and a denied edge is reported as `LAYER_IMPORT_VIOLATION`. The infrastructure
284
+ path-heuristic (and `mayImportInfrastructure`) now applies only to **ungoverned** targets —
285
+ external packages, or paths no declared layer covers. `ark-mcp` resolves the target layer
286
+ from the config's layer globs + tsconfig path aliases (a barrel import is classified by its
287
+ directory). Backward-compatible: with no resolver supplied, the gate's behavior is unchanged.
288
+
289
+ ### Added
290
+
291
+ - **`ark-check --install-agent-gates --migrate-commands`** — rewrites only the Ark command
292
+ runner (`npx` / `pnpm exec` / `yarn`) in existing gate files (`.claude/settings.json`,
293
+ `.mcp.json`, `AGENTS.md`, rule files, the `check:architecture` script) to match the
294
+ project's package manager, preserving every customization (no `--force` clobber). For repos
295
+ that adopted Ark before its emitted commands became package-manager-aware. A normal
296
+ `ark-check` now advises when a gate file's runner doesn't match the package manager, and
297
+ `/ark-upgrade` runs the migration as part of its refresh flow.
298
+
299
+ ## 1.11.0 — 2026-07-06
300
+
301
+ Sharpens Ark from "enforce a clean architecture" to **helping a team organize a messy,
302
+ pre-existing codebase — without presenting a false-green.** The tool now reports what it
303
+ actually governs, separates real debt from false positives, and guides the cleanup in order.
304
+
305
+ ### Added
306
+
307
+ - **Package-manager-aware commands.** Every command Ark emits — the AGENTS.md contract,
308
+ `.mcp.json`, the Claude/Codex hooks, the `check:architecture` script, the postinstall hints,
309
+ the "install TypeScript" hint — now follows the project's package manager
310
+ (`pnpm exec` / `yarn` / `npx`), not just the CI workflow. A pnpm/yarn repo is never handed
311
+ an `npx` instruction.
312
+ - **Honest coverage + layer proposals.** `ark-check --coverage` leads with `Governed: N%`,
313
+ warns loudly when Ark governs a minority of the tree, and proposes a canonical layer for
314
+ each ungoverned directory (harvested from the 11-layer profile and the named presets;
315
+ unrecognized directories are flagged, never guessed). `--init` prints the same proposals.
316
+ New additive `governed` and `suggestions` fields in `--coverage --json`.
317
+ - **Violation diagnosis.** `ark-check` groups violations by layer edge and target subtree,
318
+ ranked (the burn-down order), with a concentration verdict. New additive `summary` field in
319
+ the check `--json`.
320
+ - **Type-only vs value violations.** Each `LAYER_IMPORT_VIOLATION` is tagged `typeOnly`
321
+ (via the TypeScript AST); the summary splits `valueCount` (real runtime coupling) from
322
+ `typeOnlyCount` (type placement), so a burn-down attacks real coupling first.
323
+ - **`/ark-*` skills reoriented to organize** around the "protect the border around a
324
+ framework, not its internals" principle: the facade split (surface/internals + re-export
325
+ barrel) in `/ark-contract`, the type-only inversion pattern in `/ark-fix`, and honest
326
+ coverage in `/ark-coverage` and `/ark-explain`.
327
+
328
+ ### Changed
329
+
330
+ - **`--update-baseline` refuses a lopsided freeze.** When a single edge dominates the
331
+ violations (a likely contract bug, not debt), the freeze is refused with a diagnosis and a
332
+ pointer to the fix, unless `--force` is passed — so adoption can't bury a wrong contract as
333
+ frozen "debt".
334
+ - **Overlapping layer globs resolve by most-specific pattern**, not declaration order, so a
335
+ facade split (`kernel/app/**` as a public surface over a `kernel/**` catch-all) resolves
336
+ correctly regardless of layer order. A new `CONFIG_AMBIGUOUS_LAYERS` warning flags genuine
337
+ equal-specificity overlaps.
338
+
339
+ ### Fixed
340
+
341
+ - **Scan cache invalidates when the cached shape changes** (schema tag v1 → v2). A warm cache
342
+ written by an older Ark was reused by the new binary, so `typeOnly` reported false for every
343
+ violation after an upgrade until files changed; the cache now invalidates exactly once on
344
+ upgrade and re-populates.
345
+
346
+ ## 1.10.1 — 2026-07-06
347
+
348
+ ### Fixed — Codex MCP wiring
349
+
350
+ - `ark-check --install-agent-gates` now auto-merges the `[mcp_servers.ark]` table into
351
+ Codex's `$CODEX_HOME/config.toml` (default `~/.codex/config.toml`) whenever Codex is a
352
+ target (`--tools codex` or `--codex-home`), so `ark://manifest` and the AI write gate are
353
+ live from the first edit. Previously Codex only received a copy-me sample at
354
+ `docs/ark-codex-config.toml` — unlike Claude and Cursor, which got machine-readable
355
+ registrations — so an agent that never hand-merged it fell back to the static
356
+ `ark.config.json` and the MCP server never started. The merge is idempotent (an existing
357
+ `ark` table is left untouched unless `--force` replaces it) and preserves other tables.
358
+ - The Codex `[mcp_servers.ark]` block now uses **absolute** `--root`/`--config` paths
359
+ (properly escaped for TOML). Because `config.toml` is a global file loaded without the
360
+ project as the working directory, a relative `--root .` would resolve against Codex's
361
+ launch directory — this also fixes projects whose path contains spaces. The install
362
+ output now states the required Codex restart and the expected result (`ark://manifest`
363
+ plus the `validate_code`, `ark_check`, `ark_coverage`, `ark_place` tools).
364
+
365
+ ## 1.10.0 — 2026-07-06
366
+
367
+ ### Added — GitHub-first release hardening
368
+
369
+ - Added a manual `Publish npm` GitHub workflow that verifies a signed annotated
370
+ `vX.Y.Z` tag, requires the GitHub Release to exist first, runs the full release
371
+ verification suite, publishes to npm with provenance, and uploads the npm tarball
372
+ SHA-256 checksum back to the GitHub Release.
373
+ - Added `scripts/verify-release-tag.mjs` so release automation fails before npm when
374
+ the tag does not match `package.json` or is not annotated; signed-tag enforcement can
375
+ be enabled with `ARK_REQUIRE_SIGNED_RELEASE_TAG=true` once release signing is configured.
376
+ - Local `npm run release:npm` now defaults to dry-run/local verification. Real local
377
+ publish requires `--allow-local`; the normal release path is GitHub Actions provenance.
378
+
379
+ ### Added — security scanning gates
380
+
381
+ - Added a dedicated `Security` workflow with CodeQL, Dependabot dependency review on
382
+ pull requests, and Semgrep CE scanning on push, PR, schedule, and manual dispatch.
383
+ - Fixed the CodeQL alerts surfaced by that workflow: removed vulnerable built-in regex
384
+ heuristics from the AI write gate and replaced shell-interpolated pack test commands
385
+ with argument-vector process execution.
386
+
387
+ ### Added — runtime profile from `ark.config.json`
388
+
389
+ - Added `createArchitectureProfileFromArkConfig` plus `createArkKernelFromConfig`,
390
+ `createStrictArkKernelFromConfig`, and `createLenientArkKernelFromConfig` so runtime
391
+ observed layer-flow enforcement can use the same layer prefixes and rules as the
392
+ static architecture gate.
393
+ - `ArchitectureLayerConfig.intentPrefixes` is now optional in the public type, matching
394
+ real Ark configs where file-only layers do not participate in runtime intent naming.
395
+
396
+ ### Changed — packaging polish
397
+
398
+ - Repositioned package metadata and README around Ark as an AI architecture gate for
399
+ TypeScript, with the runtime presented as optional.
400
+ - Removed the CJS build warning for the ESLint subpath while preserving its existing
401
+ default and named exports.
402
+
403
+ ## 1.9.1 — 2026-07-06
404
+
405
+ ### Fixed — custom CI workflows count as installed gates
406
+
407
+ - `ark-check --require-gates` no longer requires the generated workflow filename
408
+ `.github/workflows/ark-check.yml`. It now accepts any GitHub Actions workflow that
409
+ runs `ark-check` or the `check:architecture` npm script, so projects can keep their
410
+ existing `ci.yml` while still enforcing gate presence.
411
+
412
+ ### Added — security policy and runtime audit gate
413
+
414
+ - Added `SECURITY.md` with private vulnerability reporting guidance and release
415
+ verification notes.
416
+ - Added `npm run security:audit`, currently scoped to the published/runtime surface via
417
+ `npm audit --omit=dev --audit-level=high`, and wired it into CI.
418
+
419
+ ### Changed — public roadmap and npm package contents
420
+
421
+ - Reworked `ROADMAP.md` into a public `Now / Next / Later` roadmap focused on Ark as an
422
+ AI architecture gate for TypeScript.
423
+ - Narrowed the npm `files` list for docs so internal planning notes cannot be packed
424
+ accidentally, while explicitly including `SECURITY.md`.
425
+
426
+ ## 1.9.0 — 2026-07-05
427
+
428
+ ### Added — read-side MCP tools for AI agents
429
+
430
+ The MCP server (`ark-mcp`) now exposes three read-side tools alongside `validate_code`,
431
+ so an agent can query the contract instead of shelling out and parsing:
432
+
433
+ - **`ark_place`** — given a target file path, returns its layer, forbidden globals, and
434
+ which layers it may / must not import. Call it before writing a new file so generated
435
+ code lands in a governed location. Computed in-process from the contract.
436
+ - **`ark_check`** — the full architecture check as structured JSON (baseline-aware; a
437
+ `strict` argument toggles config-warning failures).
438
+ - **`ark_coverage`** — per-layer file counts, the full list of unclassified (ungoverned)
439
+ files, layers whose patterns match nothing, and layers with no rule edge.
440
+
441
+ `ark_check` and `ark_coverage` reuse the canonical `ark-check` engine (no duplicated
442
+ logic). Tools appear in the agent's tool list automatically — no skill or doc-reading
443
+ needed. `/ark-place` and `/ark-coverage` skills now reference the tools (with a CLI fallback).
444
+
445
+ ### Added — `ark-check --coverage`
446
+
447
+ New report mode: per-layer matched-file counts plus the **full** unclassified-file list
448
+ (vs the 5-sample cap on the config warning), `emptyLayers` (patterns matching nothing),
449
+ and `layersWithoutRules`. Human-readable, or `--json`. Report-only — always exits 0.
450
+
451
+ ### Added — monorepo-aware `ark init`
452
+
453
+ `ark init` now auto-detects workspace monorepos (npm/yarn/bun `workspaces` and
454
+ `pnpm-workspace.yaml`) and writes a cross-package profile anchored at the real workspace
455
+ roots, instead of the `src/**` 11-layer starter that matches nothing in a monorepo. A
456
+ new `--preset monorepo` does the same explicitly; its layer patterns match by directory
457
+ name in any package (`**/domain/**`, …).
458
+
459
+ ### Added — three more agent gates
460
+
461
+ `--install-agent-gates` now knows **Roo Code** (`.roo/rules/ark.md`), **Continue**
462
+ (`.continue/rules/ark.md`), and **Gemini CLI** (`GEMINI.md`), auto-detected from their
463
+ config dirs — instruction-tier rule files derived from the same contract. `ark init`
464
+ gained a `--tools` passthrough, and gate installation now prints which tools it targeted
465
+ and why (detected / from --tools / default).
466
+
467
+ ### Added — ESLint flat-config recipe
468
+
469
+ `docs/ai-gates.md` now documents `ark.configs.recommended` plus a domain-scoped block for
470
+ `ark/no-forbidden-globals` (which `recommended` deliberately omits, since it needs
471
+ per-path scoping).
472
+
473
+ ## 1.8.3 — 2026-07-05
474
+
475
+ ### Fixed — Codex-home refresh guidance no longer clobbers customized gate files
476
+
477
+ - 1.8.2's stale-skill advisory and the `/ark-upgrade` skill recommended
478
+ `--install-agent-gates --codex-home --force`. Without `--skills-only`, that `--force`
479
+ also rewrites customized gate files (AGENTS.md, CI workflow, settings, rules) — the exact
480
+ clobbering `--skills-only` exists to prevent. Both now recommend
481
+ `--install-agent-gates --skills-only --codex-home --force`, which refreshes the repo skills
482
+ and the Codex-home prompts while leaving customized gate files untouched. The flag behavior
483
+ is unchanged; only the recommended command (and skill guidance) is corrected.
484
+
485
+ ## 1.8.2 — 2026-07-05
486
+
487
+ ### Added — refresh `/ark-*` skills in the Codex home dir
488
+
489
+ - Codex loads slash-command prompts from `$CODEX_HOME/prompts` (`~/.codex/prompts`), not the
490
+ repo, so a repo refresh never updated them and they silently drifted behind. New:
491
+ `ark-check --install-agent-gates --codex-home` writes the skills there directly (works even
492
+ when the repo has no `.codex/`), and a normal `ark-check` now flags stale/missing skills in
493
+ the Codex home dir by their `arkVersion` stamp — but only when copies already exist, so it
494
+ never introduces Codex to someone who doesn't use it. `--json` gains `codexHomeGap`.
495
+
496
+ ### Improved — richer, clearer HTML report
497
+
498
+ - `--report` was reworked: layers are ordered innermost → outermost with a **purpose** column
499
+ and per-layer tags; a readable **dependency-direction** view (what each layer may import)
500
+ sits above the precise matrix (now in a collapsible `<details>`); violations are grouped by
501
+ rule with a fix hint each; enforcement points name the file they found; and a stats band and
502
+ footer show layer/rule counts, gate coverage, the Ark version, and the config path.
503
+ - Layers accept an optional `"description"` in `ark.config.json`, surfaced as the report's
504
+ purpose column. The named presets seed sensible descriptions so `ark init --preset` produces
505
+ a self-documenting config.
506
+ - After writing a report, ark-check reminds you to add it to `.gitignore` (only when a
507
+ `.gitignore` exists and doesn't already list it) — it's a generated artifact.
508
+
509
+ ### Docs — architectural security invariants
510
+
511
+ - New README section on using layer rules + `forbiddenGlobals` to enforce security invariants
512
+ that are architectural (confining secret/env access, outbound network, and weak randomness to
513
+ the right layers) — without pretending to be a security scanner.
514
+
515
+ ## 1.8.1 — 2026-07-05
516
+
517
+ ### Changed — tighter `/ark-*` skill descriptions
518
+
519
+ - The eight skill descriptions were trimmed (~30 → ~20 words each), leading with the
520
+ skill's key concept. Skill descriptions load into an agent's context budget; on
521
+ hosts with many installed skills the longer descriptions could push some skills out
522
+ of the model-visible list. Behavior is unchanged — only the frontmatter descriptions.
523
+ Refresh installed copies with `npx ark-check --install-agent-gates --skills-only --force`.
524
+
525
+ ## 1.8.0 — 2026-07-05
526
+
527
+ ### Added — circular dependency detection
528
+
529
+ - `ark-check` now reports `CIRCULAR_DEPENDENCY`: files that transitively import each
530
+ other. The check runs over the import graph Ark already resolves, so it costs
531
+ almost nothing. One violation per cycle (anchored at the alphabetically-first
532
+ member, so the baseline key is stable), with a fix hint. Cycles participate in the
533
+ `--baseline` ratchet like every other rule and appear in the HTML report.
534
+
535
+ ### Added — named architecture presets
536
+
537
+ - `ark init --preset hexagonal|layered|feature-sliced` writes a canonical
538
+ `ark.config.json` for a known architecture instead of relying on directory
539
+ detection. Globs use `**` so they fit flat (`src/domain/**`) and modular
540
+ (`src/modules/x/domain/**`) layouts; every layer is `optional`, so the strict check
541
+ passes on a greenfield repo and each layer switches on as its directory gains files.
542
+ `hexagonal` inverts the domain→persistence dependency; `layered` is a relaxed n-tier
543
+ stack; `feature-sliced` is the FSD import ladder.
544
+
545
+ ### Added — HTML architecture report
546
+
547
+ - `ark-check --report [file.html]` writes a self-contained HTML report (no external
548
+ assets, works offline, light/dark): the layer map with a real example file per
549
+ layer, a who-may-import-whom matrix, current violations with fix hints, and which
550
+ gates are live. A shareable artifact for PRs and onboarding.
551
+
552
+ ### Added — agent-behavior eval harness
553
+
554
+ - `eval/` (dev-only, not shipped in the npm package): runs a live coding agent against
555
+ seeded architecture violations using Ark's own gate messages, and grades whether the
556
+ agent resolves the violation *without weakening the contract* (editing config,
557
+ baseline, CI, or deleting the feature counts as a failure). Run with
558
+ `npm run eval:agent`.
559
+
560
+ ## 1.7.6 — 2026-07-05
561
+
562
+ _From downstream consumer feedback after a real upgrade + CI-failure session._
563
+
564
+ ### Changed — generated CI follows the project's Node version
565
+
566
+ - The generated GitHub workflow hard-coded `node-version: 20`. If a developer's
567
+ local npm is newer than the npm that Node ships (e.g. Node 24 / npm 11), CI's
568
+ `npm ci` fails with "missing from lock file" — the lockfile was written by a
569
+ newer npm — a red CI unrelated to architecture that blocks the gate before
570
+ `ark-check` even runs. The workflow now picks the Node version in order:
571
+ `node-version-file: .nvmrc`/`.node-version` when the project pins one (CI locks
572
+ to the dev's exact toolchain), else the major from `package.json` `engines.node`,
573
+ else a current-LTS default (bumped `20` → `22`; defaulting high avoids the
574
+ "CI npm older than the lockfile" class). Survives regeneration like `--baseline`.
575
+
576
+ ### Changed — CI steps are named so install failures read correctly
577
+
578
+ - The generated workflow's steps were unnamed, so an `npm ci` failure surfaced
579
+ under the "Ark architecture gate" job with no clear cause — it looked like an
580
+ architecture violation when it was a dependency/lockfile problem. Steps are now
581
+ named (`Checkout`, `Setup Node`, `Install dependencies`, `Ark architecture
582
+ check`), so a red lands on `Install dependencies` and points at the real cause.
583
+
584
+ ### Changed — `--install-agent-gates` says WHY a skill was skipped
585
+
586
+ - A skipped skill printed a bare `skipped <path>`, indistinguishable from "up to
587
+ date". Skipped skills are now annotated `(up to date)` or `(stale: <old> <
588
+ <current>)`, and a trailing note gives the exact safe refresh command
589
+ (`--install-agent-gates --skills-only --force`) — so the user isn't left
590
+ guessing or reaching for a bare `--force` that would clobber customized gates.
591
+
592
+ ## 1.7.5 — 2026-07-05
593
+
594
+ ### Added — outdated-skill detection (version-stamped skills)
595
+
596
+ - `--install-agent-gates` now stamps each installed `/ark-*` skill with an
597
+ `arkVersion:` line in its frontmatter. A normal `ark-check` run then flags
598
+ skills left behind by an older Ark (stamp behind the current version, or no
599
+ stamp at all) and points at the refresh command below — distinct from the
600
+ "not installed" notice, which uses a plain install. The stamp moves with the
601
+ package, so editing a skill's body does not make it look outdated; only a
602
+ version gap does. `--json` `skillGaps` entries now carry `{ tool, missing, stale }`.
603
+ - New `--skills-only` flag for `--install-agent-gates`: restricts the write to
604
+ just the canonical `/ark-*` skills, so `--install-agent-gates --skills-only
605
+ --force` refreshes skills to the current version WITHOUT overwriting a
606
+ customized `AGENTS.md`, `.claude/settings.json`, or CI workflow — which a bare
607
+ `--force` clobbers with the generic templates. The stale-skill notice and
608
+ `/ark-upgrade` now recommend this scoped command.
609
+
610
+ ### Changed — /ark-contract verifies a file move before recommending it
611
+
612
+ - `/ark-contract` could suggest moving a file to a more fitting layer (e.g. an
613
+ HTTP client into an integration layer) without checking that the file's own
614
+ imports are legal there. If the file also imports a layer the target may not
615
+ (a client that reads a persistence-layer cache, `Integration → Persistence`
616
+ denied), the "clean config change" actually breaks the contract. The skill now
617
+ resolves the file's imports against the target layer's rules first and, when
618
+ they don't fit, reports it as a refactor (split the file), not a config edit.
619
+
620
+ ### Fixed — regenerating CI keeps `--baseline`
621
+
622
+ - The generated GitHub workflow (and the `--require-gates` command it runs)
623
+ hard-coded `--strict-config --require-gates`. Re-running `--install-agent-gates
624
+ --force` on a project that had added `--baseline .ark-baseline.json` silently
625
+ dropped the flag, so CI would start failing on frozen violations instead of
626
+ ratcheting. The workflow now includes `--baseline .ark-baseline.json` whenever
627
+ the project has a baseline file, so regeneration preserves the ratchet.
628
+
629
+ ## 1.7.4 — 2026-07-05
630
+
631
+ ### Fixed — `include` accepts single files, not just directories
632
+
633
+ - `ark-check` walked every `include` entry with `scandir`, so listing a
634
+ root-level source file (e.g. Next.js `middleware.ts`, `instrumentation.ts`)
635
+ crashed with `ENOTDIR: not a directory`. `walk()` now governs a file entry
636
+ directly (subject to the same source-extension filter) and still recurses into
637
+ directory entries. This makes `/ark-coverage`'s "govern middleware.ts"
638
+ recommendation actually applicable.
639
+
640
+ ### Changed — skill polish
641
+
642
+ - `/ark-coverage` now instructs reading files with the Read tool and targeted
643
+ commands instead of `cat`-ing whole configs to the terminal, so the audit run
644
+ stays readable.
645
+ - `/ark-place` and `/ark-contract` document their no-argument path: when invoked
646
+ with nothing to place / no change described, print the placement map or the
647
+ contract snapshot + evolution options (derived from the live config) and ask,
648
+ instead of erroring or guessing. Makes the helpful behavior guaranteed, not
649
+ emergent.
650
+
651
+ ## 1.7.3 — 2026-07-05
652
+
653
+ ### Fixed — /ark-upgrade now checks the registry, and the package ships its CHANGELOG
654
+
655
+ - The `/ark-upgrade` skill only read the version already in `node_modules`, so a
656
+ repo with a pinned lockfile reported "no update available" while a newer
657
+ version was published. It now checks `npm view ark-runtime-kernel version`,
658
+ updates the dependency (`npm install -D …@latest` or the project's package
659
+ manager) so the lockfile moves too, and still refreshes gates/skills when
660
+ already on the latest (a prior version may have shipped skills the repo never
661
+ installed).
662
+ - `CHANGELOG.md` is now included in the published package (`files`). The
663
+ `/ark-upgrade` changelog-triage step referenced it, but it wasn't shipped, so
664
+ consumers had to `npm pack` and diff tarballs to see what changed. The skill
665
+ falls back to `npm view` / GitHub release notes if an older release is missing it.
666
+
667
+ ## 1.7.2 — 2026-07-05
668
+
669
+ ### Changed — blocked infra imports point at the exemption
670
+
671
+ - When the write-gate blocks an infrastructure import and the file has a known
672
+ layer, the fix hint now names the escape hatch: mark the layer in
673
+ `ark.config.json` with `"mayImportInfrastructure": true` (or name it with an
674
+ infra token). Previously the message only said "remove the import", so a
675
+ legitimately-infra layer with an unconventional name looked like a hard block
676
+ and required reading internals to discover the exemption. Zero-config
677
+ projects (no layer context) keep the plain hint — the flag doesn't apply there.
678
+ - The PreToolUse hook (`ark-mcp --hook`) now prints the gate's fix hints under a
679
+ `fix:` block. It was building the block message from the rule id and message
680
+ only, silently dropping every `suggestion` — so the port/adapter guidance and
681
+ the new infra-layer escape hatch never reached the agent. Hints are deduped.
682
+
683
+ ### Added — `ark-check` surfaces uninstalled skills
684
+
685
+ - A normal `ark-check` run now advises when a project that has adopted Ark agent
686
+ gates (`AGENTS.md` present) is missing `/ark-*` skills this version ships for a
687
+ detected tool (`.claude/`, `.cursor/`, `.codex/`, `.windsurf/`, `.clinerules/`),
688
+ pointing at `--install-agent-gates`. The `--json` output gains a `skillGaps`
689
+ field. Rationale: the postinstall message was the only discovery path for new
690
+ skills, and modern npm blocks postinstall scripts by default — so the most
691
+ careful users (and CI) never saw it. `ark-check` runs everywhere, so the notice
692
+ now actually lands. Advisory only; never affects the exit code.
693
+
694
+ ## 1.7.1 — 2026-07-05
695
+
696
+ ### Fixed — write-gate infra heuristics now respect the layer's role
697
+
698
+ - The AI write-gate's built-in infrastructure-import heuristics
699
+ (`FORBIDDEN_PATTERN` / `FORBIDDEN_IMPORT` for `/infra`, `/adapters`,
700
+ `/persistence`, `/db`, and ORMs) fired on **every** file regardless of its
701
+ layer. A persistence- or adapter-layer file that legitimately imports the
702
+ database was blocked by the PreToolUse hook even though `ark-check` (CI)
703
+ passed it — the gate contradicted the project's own `ark.config.json`.
704
+ - The heuristics are now suppressed for layers whose name declares an
705
+ infrastructure role (`adapter`, `infra`, `persistence`, `repository`,
706
+ `integration`, `database`), so those layers may import infrastructure as the
707
+ contract intends. The pure core (domain/application) and zero-config projects
708
+ (no layer context) are unchanged — infra imports there are still blocked.
709
+ User-supplied `forbiddenPatterns` are an explicit opt-in and always apply,
710
+ in every layer.
711
+ - For an infrastructure layer with an unconventional name (`Storage`, `Gateway`,
712
+ …), flag it in `ark.config.json` with `"mayImportInfrastructure": true` and the
713
+ gate exempts it too. `createAICodeGate` gained an `infrastructureLayers` option
714
+ carrying these names. This makes the fix universal: any project, any layer
715
+ naming, without losing domain-purity protection.
716
+
717
+ ## 1.7.0 — 2026-07-05
718
+
719
+ ### Added — /ark-* agent skills, installed for every detected CLI
720
+
721
+ - New `templates/skills/` set of eight autonomous slash-command skills:
722
+ `ark-coverage` (audit which Ark capabilities the project is NOT using, ranked
723
+ with the exact command to enable each), `ark-fix` (resolve violations at the
724
+ root cause — ports/moves, never weaken the contract), `ark-adopt` (baseline
725
+ freeze + ratchet onboarding), `ark-place` ("where does X go?" answered from
726
+ the contract), `ark-contract` (safe `ark.config.json` evolution), `ark-explain`
727
+ (plain-language architecture tour for newcomers), `ark-runtime` (migrate
728
+ hand-rolled event bus/outbox/sagas to the runtime kernel), and `ark-upgrade`
729
+ (refresh gates + skills after a package update).
730
+ - `ark-check --install-agent-gates` now installs the skills into each detected
731
+ tool's command location: `.claude/skills/<name>/SKILL.md`,
732
+ `.cursor/commands/`, `.codex/prompts/`, `.windsurf/workflows/`, and
733
+ `.clinerules/workflows/` (plus `.github/prompts/` for Copilot, which is
734
+ explicit-only via `--tools copilot`). Kiro has no command mechanism, so it
735
+ keeps only its steering rule file. One canonical markdown per skill; existing
736
+ files are never overwritten without `--force`, so re-running after an update
737
+ only adds what's missing.
738
+ - The skills are written to work unattended: they gather everything from the
739
+ repo, take documented defaults instead of asking, finish with a strict
740
+ `ark-check`, and report what they did — usable both by advanced users and by
741
+ developers new to architecture governance (plain-language explanations are
742
+ part of each skill's contract).
743
+ - Postinstall message now tells existing Ark projects to re-run
744
+ `npx ark-check --install-agent-gates` after updating, so new templates and
745
+ skills reach every configured agent CLI, not just one.
746
+
747
+ ## 1.6.0 — 2026-07-04
748
+
749
+ ### Changed — bounded in-memory retention by default
750
+
751
+ - `createArkKernel` now defaults `maxHistorySize` to `DEFAULT_MAX_HISTORY_SIZE`
752
+ (1000), capping event history, trace, and audit records with oldest-first
753
+ eviction. Previously these grew without bound in long-running processes.
754
+ Pass `maxHistorySize: Infinity` to restore the old unbounded behavior.
755
+
756
+ ### Added — custom layer matchers
757
+
758
+ - `ArchitectureLayer` accepts an optional `match: (name) => boolean` for teams
759
+ whose intent names don't follow prefix conventions. Matchers are checked
760
+ before prefixes, in layer declaration order, and can be combined with or
761
+ replace `prefixes` (use `prefixes: []` for match-only layers).
762
+
763
+ ## 1.5.0 — 2026-07-04
764
+
765
+ ### Added — ark-check scan cache
766
+
767
+ - `ark-check` caches per-file scan results in `node_modules/.cache/ark-check.json`,
768
+ keyed by each file's mtime+size and the config/manifest contents. Only unchanged
769
+ files skip the TypeScript parse; import edges are ALWAYS re-resolved against the
770
+ live filesystem, so the cache can never hide a violation introduced by adding,
771
+ moving, or deleting other files. `--no-cache` disables it.
772
+
773
+ ### Added — monorepo per-package tsconfig resolution
774
+
775
+ - Without `--tsconfig`, `ark-check` now resolves each file's path aliases against the
776
+ NEAREST `tsconfig.json` above it (like `tsc`), so a monorepo can run under a single
777
+ `--root` with per-package alias maps. `--tsconfig` still forces one config for all files.
778
+
779
+ ### Deprecations (removal planned for 2.0)
780
+
781
+ - `AIGateViolation.code` (`src/kernel/ai-gate/types.ts`) — use `ruleId`.
782
+ - `layeredArchitectureRules()` (`src/kernel/policy/builtins.ts`) — use `cleanArchitectureMatrix()`.
783
+
784
+ ## 1.4.0 — 2026-07-03
785
+
786
+ ### Changed — the write gate now ratchets like the CI gate
787
+
788
+ - `ark-mcp --hook` blocks an edit only when it ADDS violations relative to the file's
789
+ current on-disk state. Previously any pre-existing violation (frozen in a baseline or
790
+ predating Ark adoption) made every subsequent edit to that file un-writable while CI
791
+ passed — with the new auto-seeded `forbiddenGlobals`, that would have hit ordinary
792
+ brownfield upgrades. New files still block on every violation.
793
+
794
+ ### Added — SessionStart contract injection (`ark-mcp --session-context`)
795
+
796
+ - `ark-mcp --session-context` prints a compact contract summary — layers, forbidden
797
+ globals, denied-edge count, baseline state, and the check command — for a Claude Code
798
+ `SessionStart` hook, so the agent knows the architecture from the first token instead
799
+ of learning it by rejection. `--install-agent-gates` now includes the hook in the
800
+ generated `.claude/settings.json`.
801
+ - Project-scoped by design and safe even in global settings: without an
802
+ `ark.config.json`, `--session-context` prints nothing and exits 0 (before loading
803
+ `dist/`), so non-Ark projects are untouched.
804
+
805
+ ### Added — instruction-tier agent gates (Windsurf, Cline, Copilot, Kiro)
806
+
807
+ - `ark-check --install-agent-gates` now knows four more tools: `windsurf`
808
+ (`.windsurf/rules/ark.md`), `cline` (`.clinerules/ark.md`), `copilot`
809
+ (`.github/copilot-instructions.md`), and `kiro` (`.kiro/steering/ark.md`).
810
+ All derive from the same canonical agent contract as `AGENTS.md` and the
811
+ Cursor rule, so the steps cannot drift between hosts.
812
+ - Windsurf, Cline, and Kiro are auto-detected from their config directories;
813
+ Copilot is explicit-only via `--tools` (`.github/` is too weak a signal).
814
+ Gemini CLI needs no template — it reads the generated `AGENTS.md`.
815
+
816
+ ### Added — forbidden ambient globals per layer (`forbiddenGlobals`)
817
+
818
+ - Layers in `ark.config.json` can declare `forbiddenGlobals` (e.g.
819
+ `["fetch", "process", "Date.now", "Math.random"]`). Import rules can't see code that
820
+ reaches for an ambient global; this closes that hole for domain purity.
821
+ - Enforced identically at all three moments: `ark-check` reports `FORBIDDEN_GLOBAL`
822
+ in CI (baseline-ratchet compatible), the `ark-mcp` write gate blocks the write, and
823
+ the new `ark/no-forbidden-globals` ESLint rule gives in-editor feedback (scope it to
824
+ layer directories via `files`; it takes a `{ globals: [...] }` option).
825
+ - Detection is positional, not scope-aware: dotted entries (`"Date.now"`) flag that
826
+ property access; bare entries (`"console"`) flag member access, calls, and
827
+ constructions. Types, import names, and shadowed locals are never flagged.
828
+ - `ark init` and `ark-check --init` seed the DomainModel layer with
829
+ `["fetch", "process", "Date.now", "Math.random"]`.
830
+ - The `ark://manifest` MCP resource now exposes the configured `forbiddenGlobals`
831
+ map so agents see the constraint before generating code.
832
+ - `createAICodeGate` accepts a `forbiddenGlobals` option (layer → globals), checked
833
+ when a `typescript` module is provided.
834
+
835
+ ## 1.3.0 — 2026-07-03
836
+
837
+ ### Added — the 11-layer division is now suggested, to humans and agents
838
+
839
+ - `ark-check --init` on a project with no conventional layer directories now generates
840
+ the complete 11-layer starter profile (all layers `optional`) instead of failing:
841
+ the strict check passes immediately and each layer starts being enforced as soon as
842
+ its directory gains source files.
843
+ - `ark-check --init` on a partially-layered project prints the undetected profile
844
+ layers with their conventional directories, so the full division is visible before
845
+ deciding what to adopt.
846
+ - The `ark://manifest` MCP resource now includes `suggestedLayers` (undeclared default
847
+ layers with intent prefixes and conventional directories), so agents know where a
848
+ new saga, job, or read model belongs before improvising an ungoverned location.
849
+ - The generated `AGENTS.md` includes a "Where new code belongs" placement table for
850
+ the same purpose in runtimes without MCP.
851
+
852
+ ### Added — gate presence enforcement (`ark-check --require-gates`)
853
+
854
+ - `ark-check --require-gates` fails the check when `AGENTS.md`, `.mcp.json`, or the
855
+ generated CI workflow is missing, so "installed but never configured" is a red CI.
856
+ JSON mode reports `{ ok: false, error: 'missing-gates', missing: [...] }`.
857
+ - `--install-agent-gates --tools claude,cursor,codex` selects which tool templates to
858
+ write; without the flag, tools are auto-detected from `.claude/`, `.cursor/`, and
859
+ `.codex/` (all templates are written when nothing is detected).
860
+
861
+ ### Changed
862
+
863
+ - The generated CI workflow now runs `ark-check` with `--require-gates`.
864
+ - AGENTS.md and the Cursor rule derive from a single agent contract, so the
865
+ enforcement steps can no longer drift between the two files.
866
+
867
+ ### Fixed
868
+
869
+ - `--install-agent-gates` now reports failed template writes and exits non-zero
870
+ instead of always claiming success.
871
+ - `--tools` no longer swallows a following flag as a tool name (`--tools --force`),
872
+ and rejects empty or unknown tool names with exit 2 instead of silently ignoring them.
873
+ - `suggestedLayers` skips default layers whose intent prefixes the project already
874
+ claims under another name (e.g. a `core` layer owning `Domain.`), so agents are never
875
+ told to create a second layer for an already-governed prefix.
876
+ - Greenfield `--init` warns when existing source files live outside `src/` (and are
877
+ therefore not governed by the generated starter config) instead of staying silent.
878
+ - The suggested `check:architecture` npm alias now uses `npx ark-check` (the previous
879
+ snippet only worked inside Ark's own repository).
880
+ - `createElevenLayerArkConfig({ rootDir: '.' })` no longer emits broken `./`-prefixed
881
+ patterns that matched nothing.
882
+
883
+ ## 1.2.0 — 2026-07-03
884
+
885
+ ### Added — agent gate installer (`ark-check --install-agent-gates`)
886
+
887
+ - One command writes the agent-enforcement starter set: `AGENTS.md`, `.mcp.json`,
888
+ Cursor rule + MCP config, Claude settings, a Codex config snippet, and a GitHub
889
+ Actions workflow that runs `ark-check --strict-config`. Existing files are
890
+ skipped unless `--force` is passed.
891
+ - The generated workflow detects the project's package manager (npm / pnpm / yarn)
892
+ from its lockfile and uses matching setup, cache, and run commands.
893
+
894
+ ### CI
895
+
896
+ - Workflows updated to the node24 runtime; MCP tests isolated from concurrent builds.
897
+
898
+ ## 1.1.0
899
+
900
+ ### Added — baseline ratchet for existing codebases (`ark-check --baseline`)
901
+
902
+ - `ark-check --update-baseline [file]` freezes the current violations into
903
+ `.ark-baseline.json` (line-insensitive keys, so unrelated edits don't resurrect them).
904
+ - `ark-check --baseline [file]` suppresses frozen violations: only NEW violations fail,
905
+ and stale baseline entries are reported so the ratchet can be tightened with a re-run
906
+ of `--update-baseline`. JSON output gains `suppressedViolations` and `staleBaselineKeys`.
907
+
908
+ ### Added — Standard Schema support in event contracts
909
+
910
+ - `EventContract.standardSchema` accepts any [Standard Schema](https://standardschema.dev)
911
+ validator (zod, valibot, arktype, ...) alongside — or instead of — Ark's own schema
912
+ format. Issues (including paths) map to regular contract issues. Validation stays
913
+ synchronous; async validators produce an explicit contract issue. Ark remains
914
+ zero-dependency: the spec interface is vendored as types only.
915
+
916
+ ### Added — NestJS adapter (`ark-runtime-kernel/nestjs`)
917
+
918
+ - `ArkModule.forRoot()` / `forRoot(kernel | options)` / `forRootAsync({ useFactory })`
919
+ register a global kernel under the `ARK_KERNEL` token; `@InjectArk()` injects it.
920
+ - `@nestjs/common` is an optional peer dependency; the core stays zero-dependency.
921
+
922
+ ### Added — GitHub Action
923
+
924
+ - Composite action at the repo root: `uses: pedroknigge/ark-runtime-kernel@main` runs
925
+ `ark-check`, writes the result to the step summary, and (with `github-token`) comments
926
+ violations on the PR. Inputs: `root`, `config`, `strict-config`, `baseline`, `version`.
927
+
928
+ ### Added — docs, examples, and distribution
929
+
930
+ - `docs/ai-gates.md`: copy-paste write-gate setups for Claude Code (hook + MCP), Cursor,
931
+ OpenAI Codex, any hook-capable runtime, plus the CI backstop.
932
+ - `examples/hexagonal-order-api/`: a full hexagonal order API governed by Ark with a
933
+ "break it on purpose" walkthrough.
934
+ - `server.json` for the official MCP registry; `CONTRIBUTING.md`; `ROADMAP.md`.
935
+ - README rewritten adoption-first: 2-minute CI setup, honest comparison vs
936
+ dependency-cruiser / eslint-plugin-boundaries / Nx boundaries, write-gate demo, and the
937
+ runtime kernel repositioned as the opt-in layer.
938
+
939
+ ### Changed — actionable ark-check output
940
+
941
+ - Human output now shows the rule, `file:line`, the layer edge with the resolved target,
942
+ and a fix hint per rule, with color when attached to a TTY (`NO_COLOR` respected).
943
+ `--json` output is unchanged (plus the new baseline fields).
944
+
945
+ ### Changed — single package.json
946
+
947
+ - Removed the `package.dev.json` / `package.publish.json` swap workflow and its scripts;
948
+ the checked-in `package.json` is the only manifest and `npm publish` ships it as-is
949
+ (`prepack` builds). Internal working documents removed from `docs/`.
950
+
951
+ ## 1.0.0 — 2026-07-02 (as published to npm)
952
+
953
+ ### Added — working pre-write hook mode (`ark-mcp --hook`)
954
+
955
+ - `ark-mcp --hook` runs one-shot instead of serving: it reads a Claude Code PreToolUse
956
+ payload from stdin, validates the file content a Write/Edit/MultiEdit is about to
957
+ produce, and exits `2` with the violations on stderr to block the write (`0` to allow).
958
+ - Edits are validated against the post-edit file state (current file with the edit applied
959
+ in memory), not the edit snippet in isolation.
960
+ - Fail-open plumbing: non-source files, other tools, files outside `--root`, and malformed
961
+ payloads never block the agent.
962
+ - Fixed the Claude Code integration examples in README and the agent guide: they showed a
963
+ hook `"type": "mcp"` that does not exist in Claude Code. The documented configuration now
964
+ uses a real `"type": "command"` hook running `ark-mcp --hook`, plus `.mcp.json` for the
965
+ manifest resource and `validate_code` tool.
966
+
967
+ ### Added — one-command onboarding (`ark-check --init`)
968
+
969
+ - `ark-check --init` scans the project for the built-in layer directory conventions
970
+ (`src/domain`, `src/application`, `src/adapters/persistence`, ...) and writes an
971
+ `ark.config.json` covering only the layers that actually contain source files, with the
972
+ default rule matrix filtered to those layers.
973
+ - The generated config passes `--strict-config` out of the box; `--init` also lists the
974
+ top-level directories left uncovered so governance gaps are explicit from day one.
975
+ - `--init` refuses to overwrite an existing config unless `--force` is passed, and fails
976
+ with guidance (instead of writing a useless config) when no conventional directories
977
+ are found.
978
+
979
+ ### Changed — real dogfooding and less warning noise
980
+
981
+ - Ark's own `ark.config.json` now classifies 100% of `src/` (DomainModel, Kernel, and
982
+ Tooling layers with real boundary rules) instead of a symbolic two-layer config, and
983
+ `npm run check:architecture` / CI run with `--strict-config` so coverage can never
984
+ silently rot.
985
+ - Removed the `CONFIG_PARTIAL_LAYER_MAP` warning: it flagged every project with fewer
986
+ than 11 layers even at 100% file coverage. `CONFIG_UNCLASSIFIED_FILES` already reports
987
+ the real coverage gap.
988
+
989
+ ### Added — broader static governance checks
990
+
991
+ - `ark-check` now checks dynamic `import()` and `require()` module edges against configured
992
+ layer rules.
993
+ - `ark-check` now flags raw `publish()` calls that pass an intent string or raw event
994
+ object.
995
+ - `ark-check` now flags publish calls missing `metadata.source`.
996
+ - `ark-check` now flags source intent literals whose resolved layer does not match the
997
+ publishing file's configured layer.
998
+
999
+ ### Added — source-bound publishers
1000
+
1001
+ - Event buses now expose `createPublisher(sourceIntent)` to create a source-bound
1002
+ publishing capability.
1003
+ - Ark kernels expose `ark.publisher(sourceIntent)` as the recommended strict runtime path.
1004
+ - Source-bound publishers stamp `metadata.source` internally and throw
1005
+ `SourceMetadataOverrideError` when callers try to publish as a different source.
1006
+
1007
+ ### Added — operational 11-layer profile config
1008
+
1009
+ - Added `createElevenLayerArkConfig()` to generate an `ark-check` configuration from the
1010
+ built-in runtime 11-layer profile.
1011
+ - Added `ark-check --print-config eleven-layer` for CLI bootstrap of `ark.config.json`.
1012
+ - Generated layers are optional by default so teams can adopt the full profile
1013
+ incrementally without warnings for unused folders.
1014
+
1015
+ ### Added — AST-backed AI publish checks
1016
+
1017
+ - `createAICodeGate()` can now run built-in TypeScript AST checks when the caller passes
1018
+ the `typescript` module.
1019
+ - AST checks flag raw publish calls, publish calls missing `metadata.source`, and source
1020
+ intent literals whose layer differs from the target file layer.
1021
+ - `ark-mcp` passes TypeScript into AICodeGate when available so the write-path gate blocks
1022
+ the same publish misuse patterns earlier.
1023
+
1024
+ ### Added — ports and adapters governance metadata
1025
+
1026
+ - `definePort()` now accepts optional ownership metadata, intent identity, and an
1027
+ `allowedAdapters` list.
1028
+ - `createAdapter()` accepts adapter metadata and rejects adapters that are not allowed by
1029
+ the port.
1030
+ - Added `checkAdapterGovernance()` for non-throwing adapter allowlist checks.
1031
+
1032
+ ### Added — production hardening
1033
+
1034
+ - Event contracts now support nested object fields, typed array items, and enum values.
1035
+ - Added `docs/production-hardening.md` with store-interface guidance for durable audit,
1036
+ outbox, projection, and workflow implementations.
1037
+
1038
+ ## 1.0.0 — 2026-07-01
1039
+
1040
+ ### Changed — strict runtime baseline and governance roadmap
1041
+
1042
+ - `createArkKernel()` now uses hardened defaults: strict event contracts, known-source
1043
+ enforcement, and hard observed layer-flow enforcement unless explicitly relaxed.
1044
+ - Added `createLenientArkKernel()` for migration and legacy paths that need the previous
1045
+ relaxed behavior.
1046
+ - The built-in 11-layer profile now uses a strict cross-layer deny matrix with explicit
1047
+ allowed flows.
1048
+ - `ark-check` reports advisory config warnings for missing/partial layer maps,
1049
+ unclassified included files, unmatched layer patterns, duplicate layers, and rules that
1050
+ reference unknown layers. `--strict-config` turns those warnings into a failing check.
1051
+ - Documentation now states the runtime/static/AI governance boundaries explicitly and
1052
+ tracks the seven-phase roadmap for expanding Ark's enforcement scope.
1053
+
1054
+ ## 0.8.4 — 2026-07-01
1055
+
1056
+ ### Fixed — CI/MCP intent-classification parity
1057
+
1058
+ `ark-check` classified intent names with declaration-order first-match + raw `startsWith`,
1059
+ while the MCP write-gate classifies via the library's `ArchitectureProfile.resolveLayer`
1060
+ (longest-prefix-first + prefixes normalized to a trailing `.`). For configs with
1061
+ overlapping prefixes (`Adapter.` vs `Adapter.Persistence.`) or dotless prefixes (`Domain`),
1062
+ the two gates disagreed. Both now share `resolveIntentLayer` (in `bin/ark-shared.mjs`),
1063
+ which mirrors the library semantics exactly — a regression test asserts the shared resolver
1064
+ and `profile.resolveLayer` return identical results across overlapping/dotless configs.
1065
+
1066
+ ## 0.8.3 — 2026-07-01
1067
+
1068
+ ### Fixed — third code-review pass (glob robustness + latent fallback bug)
1069
+
1070
+ - **Unbalanced-brace crash.** A glob with an unbalanced `{` produced an invalid regex, so
1071
+ `new RegExp` threw — crashing the CI gate (exit 2) and every MCP `validate_code` call.
1072
+ `globToRegExp` now only treats braces as alternation when they're balanced, otherwise
1073
+ literal; it also honors backslash-escaped braces (`\{` → literal).
1074
+ - **`layerForIntent` default fallback (latent since v0.4).** The `DEFAULT_INTENT_PREFIXES`
1075
+ fallback read `item.prefix` (singular) off `{ layer, prefixes: [...] }` entries, so it
1076
+ matched nothing — a project with layers but no `intentPrefixes` got no intent-reference
1077
+ enforcement in CI while the MCP gate blocked the same reference. Now flattened to the
1078
+ right shape; the two gates agree.
1079
+ - **Out-of-root over-reach.** After dropping the hard root boundary in 0.8.1, a relative
1080
+ import escaping `--root` (`../../…`) could be classified by a catch-all pattern and
1081
+ false-flagged. `resolveImport` now skips targets whose root-relative path leads with `..`
1082
+ (and still skips `node_modules` segments) — projects under a `node_modules` segment stay
1083
+ governed; monorepos should run ark-check per package.
1084
+ - **Accurate MCP warning.** The "no layers configured" stderr note no longer claims layer
1085
+ checks are disabled; with no config layers the gate uses the default 11-layer profile and
1086
+ layer-reference checks still run when the caller passes an explicit `layer`.
1087
+
1088
+ ## 0.8.2 — 2026-07-01
1089
+
1090
+ ### Fixed — second code-review pass (parity + glob correctness)
1091
+
1092
+ A re-review of the v0.8.1 fixes found that a couple of them introduced new divergences.
1093
+ This closes them and unifies the two gates so they provably can't disagree:
1094
+
1095
+ - **ark-mcp / ark-check rule parity.** The write-path gate built its profile with
1096
+ `rules: config.rules ?? []`, so a config that declared layers but omitted `rules` got
1097
+ zero enforcement while CI still applied the default matrix. Both CLIs now share
1098
+ `DEFAULT_RULES` + `DEFAULT_INTENT_PREFIXES` (in `bin/ark-shared.mjs`) and the gate uses
1099
+ `config.rules ?? DEFAULT_RULES` with the same intent-prefix fallback ark-check uses. No
1100
+ layer is built with empty prefixes (which had made it unresolvable).
1101
+ - **node_modules exclusion, done right.** `ark-check` now excludes a resolved target only
1102
+ when its path *relative to root* contains a `node_modules` segment — so a broad catch-all
1103
+ pattern (`**`) no longer false-flags third-party imports, while projects living under a
1104
+ `node_modules` segment and monorepo siblings are still governed.
1105
+ - **Resolver directory shadowing.** The `.mts`/`.cts` relative fallback now requires the
1106
+ candidate to be a file (`statSync().isFile()`), so a directory named like the specifier
1107
+ can't shadow the real module file.
1108
+ - **Brace globs.** `globToRegExp` now supports `{ts,tsx}` alternation (previously treated
1109
+ as literals, silently matching nothing) and caches each compiled pattern.
1110
+ - **Docs/CI polish.** Corrected the observed-flow enforcement comment (edge is recorded
1111
+ *after* the check now); scoped the CI `push` trigger to `main` so PR branches don't run
1112
+ the job twice (all PRs are still gated via `pull_request`, any base branch).
1113
+
1114
+ ## 0.8.1 — 2026-07-01
1115
+
1116
+ ### Fixed — enforcement-defeating bugs found in the v0.8 code review
1117
+
1118
+ A workflow-backed review of v0.6–v0.8 surfaced a cluster of bugs that silently defeated the
1119
+ very gates they added. All fixed with regression tests (including a nested-directory fixture
1120
+ so the gate can never be vacuously green again):
1121
+
1122
+ - **Broken `**` glob (critical).** A chained `.replace()` corrupted `**` into `.[^/]*`, so
1123
+ `src/kernel/**` stopped matching nested paths — every file in a subdirectory was silently
1124
+ unclassified and skipped. This neutered both `ark-check` (CI) and `ark-mcp` layer
1125
+ inference for any real project. Fixed with a single-pass glob compiler shared by both
1126
+ CLIs (`bin/ark-shared.mjs`), removing the duplicated (and independently buggy) copies.
1127
+ - **`ark-check` import filters.** Replaced the `node_modules` path-substring test (which
1128
+ discarded an entire project living under a `node_modules` segment) with TS's own
1129
+ `isExternalLibraryImport` flag; removed the out-of-root filter so monorepo cross-package
1130
+ imports are governed; restored `.mts`/`.cts` extensionless resolution via a relative
1131
+ fallback.
1132
+ - **`ark-mcp` write-path gate.** It now builds the enforcement profile from the project's
1133
+ `ark.config.json` (layer names **and** rules), so it agrees with `ark-check` instead of
1134
+ always using the built-in `elevenLayerProfile` — projects with custom layer names/rules
1135
+ were getting zero layer enforcement. Malformed config now throws instead of silently
1136
+ falling back to a no-op; empty-layer configs warn on stderr. Manifest resource reflects
1137
+ the effective profile. Guarded a null-intent crash and gave a clear message on broken
1138
+ builds. Notifications never receive a response.
1139
+ - **EventBus phantom edge.** In `enforceObservedLayerFlow: 'hard'`, a rejected event no
1140
+ longer records an `observed` graph edge (the check now runs before `registerEventFlow`),
1141
+ so drift/manifest/observability reports don't show flows that never happened.
1142
+ - **CI gate coverage.** The workflow now triggers on every push and pull request, not only
1143
+ those based on `main`, so non-main PR topologies can't bypass the gate.
1144
+
1145
+ ## 0.8.0 — 2026-07-01
1146
+
1147
+ ### Added — mandatory CI architecture gate + AI write-path gate (MCP)
1148
+
1149
+ Two chokepoints that make Ark's enforcement unavoidable where it matters, closing the last
1150
+ two "kernel-earning" gaps from the strategic audit.
1151
+
1152
+ **1. Mandatory CI gate.**
1153
+ - `.github/workflows/ci.yml` runs typecheck, tests, build, and `ark-check` on every push/PR.
1154
+ `ark-check` exits non-zero on any layer violation, so a violation **fails the job and
1155
+ blocks the merge** — the honest architecture chokepoint for TypeScript.
1156
+ - `ark.config.json` dogfoods Ark on itself: `src/domain/**` must not import the kernel
1157
+ (a real, currently-green invariant — Ark's domain types are dependency-free).
1158
+ - `check:architecture` script now runs the gate explicitly with the config.
1159
+
1160
+ **2. AI write-path gate — `ark-mcp` MCP server (new `bin`).**
1161
+ - A **zero-dependency** MCP server (hand-rolled JSON-RPC 2.0 over stdio — no SDK dependency,
1162
+ honoring the zero-dep rule) exposing:
1163
+ - resource `ark://manifest` — the architectural contract (layers + rules, or a project
1164
+ manifest via `--manifest`) for agent contract discovery.
1165
+ - tool `validate_code` — runs Ark's AI code gate on a source snippet and returns
1166
+ `{ valid, violations }`, setting `isError` when invalid.
1167
+ - Designed to bind to `PreToolUse` on Write/Edit so architecturally-invalid generated code
1168
+ is blocked **before it lands** — turning the manifest + AI gate from an ignorable library
1169
+ into an enforced checkpoint on the operation that matters for AI agents.
1170
+ - Run with `npx ark-mcp` (or `npm run mcp`). See `docs/agent-guide.md` for wiring.
1171
+
1172
+ ## 0.7.0 — 2026-07-01
1173
+
1174
+ ### Changed — `ark-check` resolves all imports, not just relative ones
1175
+
1176
+ `ark-check` previously resolved only relative (`./`, `../`) import specifiers, so
1177
+ path-alias and package imports — the majority in real TypeScript repos — were invisible
1178
+ to it. It now resolves every import specifier through the TypeScript module resolver
1179
+ (`ts.resolveModuleName`) using the project's `tsconfig.json`, so:
1180
+
1181
+ - **tsconfig path aliases** (e.g. `@domain/*`, `@infra/db`) resolve to their real files and
1182
+ cross-layer violations through aliases are now caught.
1183
+ - **package/absolute imports** resolve via node resolution; external `node_modules` and
1184
+ `.d.ts`-only targets are correctly ignored.
1185
+ - **relative imports** keep working exactly as before.
1186
+
1187
+ New `--tsconfig <path>` flag (defaults to the nearest `tsconfig.json` from `--root`). When
1188
+ no tsconfig is found, aliases are unavailable but relative/package imports still resolve.
1189
+ Layer identity is still derived from file location (glob `patterns`), per the audit's
1190
+ "derive layer from code, not just the intent-name prefix" recommendation.
1191
+
1192
+ This closes the top-ranked remaining gap from both the v0.5 strategic audit and the
1193
+ external v0.6 review: the honest chokepoint for TypeScript architecture enforcement is the
1194
+ CI merge gate, and it must see the imports that actually exist.
1195
+
1196
+ ## 0.6.0 — 2026-07-01
1197
+
1198
+ ### Added — runtime enforcement of observed layer flows
1199
+
1200
+ Ark now enforces architecture over **what the system actually does**, not only over what
1201
+ was declared. On every publish, the event bus already recorded the real producer→event
1202
+ flow (`metadata.source → intent`); v0.6 wires that observed edge into enforcement.
1203
+
1204
+ - `EventBusOptions.enforceObservedLayerFlow: 'off' | 'soft' | 'hard'` (with
1205
+ `architectureProfile`) checks the resolved producer layer → event layer against the
1206
+ profile's rule matrix at publish time.
1207
+ - `hard` throws `ObservedLayerFlowViolationError` **before** the event reaches history,
1208
+ outbox, or subscribers.
1209
+ - `soft` records a `layer.observedViolation` trace + audit record and proceeds.
1210
+ - `off` (default for `createEventBus`/`createArkKernel`) preserves prior behavior.
1211
+ - `createStrictArkKernel()` defaults `enforceObservedLayerFlow` to `hard`. The recommended
1212
+ strict path now rejects, e.g., a persistence adapter driving a Domain event
1213
+ (PersistenceAdapters → DomainModel) or a Domain source emitting an Application event.
1214
+ - New exports: `ObservedLayerFlowViolationError`, `ObservedLayerFlowMode`.
1215
+ - New trace/audit record type: `layer.observedViolation`.
1216
+
1217
+ This closes the highest-leverage gap identified in the v0.5 strategic audit: the observed
1218
+ flow was previously collected only for the drift *report*, never for enforcement — making
1219
+ "runtime layer governance" a check over the declared model rather than the running system.
1220
+
1221
+ ### Docs
1222
+
1223
+ - README now states the enforcement scope explicitly (hard-failed / observable / out of
1224
+ runtime scope) and frames Ark as the runtime kernel for the event/intent layer plus a
1225
+ machine-readable contract, not an OS-style choke point over all code.
1226
+
1227
+ ## 0.5.0
1228
+
1229
+ Add-only event interceptors, interceptor audit/trace records, contract-safe interceptor
1230
+ failure behavior, kernel instance id stamping, observability drift report (declared vs
1231
+ observed), runtime graph observed flows, `createArkTestHarness()`, and the
1232
+ `ark-runtime-kernel/eslint` plugin.
1233
+
1234
+ ## 0.4.0
1235
+
1236
+ `createStrictArkKernel()`, event contract registry, known-source enforcement, basic
1237
+ outbox store, `ark-check` CLI (AST import + intent-string checks), and policy lifecycle
1238
+ metadata.
1239
+
1240
+ ## 0.3.0
1241
+
1242
+ 11-layer architecture profile, `createArkKernel()`, native audit trail, workflow/saga
1243
+ engine, projection/read-model registry, metadata validation, and layer-grouped graph views.
1244
+
1245
+ ## 0.2.0
1246
+
1247
+ `ArkManifest` export, `syncRegistryToGraph`, `PolicyViolationError` + observability hooks,
1248
+ bounded history + trace format, layer policies, strict registry publish/subscribe
1249
+ validation, and the package rename to `ark-runtime-kernel`.