arkgate 4.1.1 → 4.2.1

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 (58) hide show
  1. package/CHANGELOG.md +107 -3
  2. package/README.md +16 -4
  3. package/bin/ark-check-runtime.mjs +16 -5
  4. package/bin/ark-mcp-runtime.mjs +766 -64
  5. package/bin/ark-shared.mjs +16 -4
  6. package/bin/lib/agent-gates.mjs +1 -0
  7. package/bin/lib/ci-and-commands.mjs +16 -7
  8. package/bin/lib/codex-home.mjs +90 -8
  9. package/bin/lib/design-smells.mjs +71 -9
  10. package/bin/lib/doctor-plan.mjs +36 -36
  11. package/bin/lib/effective-contract-load.mjs +73 -9
  12. package/bin/lib/enforcement-state.mjs +1 -1
  13. package/bin/lib/gate-files.mjs +441 -9
  14. package/bin/lib/github-enforcement.mjs +16 -3
  15. package/bin/lib/hook-templates.mjs +12 -11
  16. package/bin/lib/html-report-evolution.mjs +114 -0
  17. package/bin/lib/html-report.mjs +11 -89
  18. package/bin/lib/import-resolve.mjs +33 -11
  19. package/bin/lib/install-activation.mjs +87 -0
  20. package/bin/lib/install-migrate.mjs +66 -50
  21. package/bin/lib/managed-upgrade.mjs +10 -41
  22. package/bin/lib/mcp-adoption.mjs +15 -5
  23. package/bin/lib/physical-cohesion.mjs +2 -1
  24. package/bin/lib/pilot-loop.mjs +25 -8
  25. package/bin/lib/project-identity.mjs +103 -0
  26. package/bin/lib/report-snapshot-context.mjs +28 -0
  27. package/bin/lib/resident-hook.mjs +33 -9
  28. package/bin/lib/rules-inventory.mjs +100 -8
  29. package/bin/lib/skill-install.mjs +272 -22
  30. package/bin/lib/skill-write.mjs +899 -0
  31. package/bin/lib/start-preview.mjs +84 -1
  32. package/bin/lib/upgrade-command.mjs +2 -5
  33. package/dist/index.cjs +13 -13
  34. package/dist/index.d.ts +194 -2
  35. package/dist/index.js +13 -13
  36. package/docs/README.md +5 -3
  37. package/docs/agent-guide.md +110 -14
  38. package/docs/ai-gates.md +103 -18
  39. package/docs/assets/ark-write-gate.svg +2 -2
  40. package/docs/enthusiast/how-to-agent-gates.md +6 -0
  41. package/docs/package-surface.md +15 -9
  42. package/docs/product-voice.md +13 -1
  43. package/package.json +7 -1
  44. package/schemas/ark.project-identity.schema.json +116 -0
  45. package/server.json +2 -2
  46. package/templates/skills/ark-adopt.md +9 -0
  47. package/templates/skills/ark-architect.md +12 -2
  48. package/templates/skills/ark-autopilot.md +9 -0
  49. package/templates/skills/ark-contract.md +11 -1
  50. package/templates/skills/ark-coverage.md +9 -0
  51. package/templates/skills/ark-explain.md +13 -1
  52. package/templates/skills/ark-explore.md +9 -0
  53. package/templates/skills/ark-fix.md +10 -1
  54. package/templates/skills/ark-loop.md +11 -2
  55. package/templates/skills/ark-place.md +17 -6
  56. package/templates/skills/ark-runtime.md +8 -0
  57. package/templates/skills/ark-think.md +14 -2
  58. package/templates/skills/ark-upgrade.md +9 -0
package/CHANGELOG.md CHANGED
@@ -5,13 +5,117 @@ in the immutable pre-2.0 archive linked below.
5
5
 
6
6
  ## Unreleased
7
7
 
8
- ## 4.1.1 — 2026-07-25 (prepared)
8
+ ## 4.2.1 — 2026-08-08 (prepared)
9
+
10
+ **Patch** over 4.2.0. Next.js **16.3** field compatibility: root `proxy.ts` (Next 16 network-boundary
11
+ rename of middleware) is scanned and classified; eval fixtures and release-surface pins track
12
+ `next@16.3.0`. **No required config migration.** Codex remains advisory at write time.
13
+ **Status: prepared** (`arkgate@4.2.1` not published yet).
14
+
15
+ ### Fixed
16
+
17
+ - **Next 16 root `proxy.ts` include:** Next overlay adds existing root (and `src/`)
18
+ `proxy.ts` / `proxy.js` / classic `middleware.ts` / `middleware.js` to `include` so layer
19
+ patterns actually scan them. Patterns alone left package-root `proxy.ts` outside
20
+ `include: ['src','app']` and therefore ungoverned on typical App Router trees.
21
+ - **Physical-cohesion framework names:** treat `proxy` like `middleware` / `route` / `page` as
22
+ framework-owned (Next 16 rename).
23
+
24
+ ### Changed
25
+
26
+ - **Eval Next pins:** `eval/cases/next-core-imports-db` and monorepo frontend fixture use
27
+ **next@16.3.0** (was 15.5.21); q06 release-surface pin accepts 16.x or patched 15.5.21+.
28
+
29
+ ### Security (carried from main)
30
+
31
+ - Transitive overrides remain: `fast-uri` **3.1.5**, `brace-expansion` **2.1.4** / **5.0.9**,
32
+ `nanoid` **3.3.18**.
33
+
34
+ ## 4.2.0 — 2026-07-31 (published)
35
+
36
+ **Minor** over 4.1.1. Phase WI — workspace identity, activation truth, and safe multi-repository
37
+ skill installation. Adds a stable MCP project-identity contract, exact-root `ark_identity`
38
+ handshake, and project-bound `ark_manifest`; cross-project/config paths fail before Layers or
39
+ ArkRules analysis; Codex setup distinguishes files configured on disk from a runtime observed
40
+ after restart. **No required config migration.** Legacy MCP calls remain callable but explicitly
41
+ non-authoritative until bound. Codex remains advisory at write time. **Status: published**
42
+ (`arkgate@4.2.0` on npm `latest`).
43
+
44
+ ### Added
45
+
46
+ - **Project identity contract:** public `ark.project-identity` JSON schema, root API exports,
47
+ stable `projectId`, independent contract/runtime identities, and package-isolation coverage.
48
+ - **MCP handshake and manifest:** `ark_identity` plus shared `project.expectedRoot` /
49
+ `expectedProjectId` input on every tool. The initial handshake requires the exact project root;
50
+ descendants require the matching project id. Project-bound `ark_manifest` is authoritative
51
+ after binding; compatibility `ark://manifest` reads are always unverified/non-authoritative.
52
+ Project-bound results and errors carry identity, binding state, and `authoritative`.
53
+ - **Verdict facets:** `ark_check.verdict` separates identity, analysis completeness, graph,
54
+ coverage, active gates, and overall result without removing legacy `ok`.
55
+ - **Portable evidence:** focused Linux, macOS, and Windows CI for native canonical paths,
56
+ activation, and multi-repo skill behavior.
57
+ - **Report provenance:** architecture snapshots record the Git `HEAD`, branch when attached, and
58
+ dirty-worktree state with a shell-free, best-effort probe.
59
+
60
+ ### Fixed
61
+
62
+ - **Wrong-project MCP reuse:** a process bound to project A rejects project B, config/manifest/
63
+ tsconfig escapes, nested Ark roots, and external write/change paths before returning placement,
64
+ golden-pattern, Layers, or ArkRules analysis.
65
+ - **Skill MCP ordering:** every shipped `/ark-*` skill now requires a matched `ark_identity`
66
+ preflight before consuming any MCP analysis and carries the exact root plus returned project id
67
+ on each later call; stale/mismatched hosts fall back to the workspace-local CLI.
68
+ - **Codex activation truth:** install/start/doctor say configured + restart required until a live
69
+ identity match; compact setup reports partial installs and removes only exact ArkGate-owned
70
+ project TOML.
71
+ - **Gate-presence false green:** `--require-gates` now implies strict config validation and checks
72
+ semantic Ark content in AGENTS, project-rooted MCP/Codex compact registrations, and fail-closed
73
+ CI instead of accepting placeholder files. Backgrounded `ark-check ... &` is not accepted as
74
+ merge enforcement. Native Windows launcher paths are recognized.
75
+ - **Same-machine skill churn:** managed upgrades no longer rewrite an unchanged skill only to
76
+ refresh `arkVersion`; repo catalogs remain isolated.
77
+ - **Shared Codex downgrade:** ArkGate 4.2.0+ installers cannot replace a newer managed
78
+ `$CODEX_HOME/skills` entry with an older bundle, including with `--force`; identical installs
79
+ are idempotent and report why they were skipped. Pre-4.2 binaries do not understand this
80
+ protocol, so legacy repos must be upgraded before they write the optional home catalog.
81
+ Versioned catalog metadata + an install lock prevent
82
+ reintroducing retired skills and serialize concurrent repos. A durable pending-catalog journal
83
+ preserves that version floor across interrupted writes; same/newer retries recover it, while
84
+ corrupt metadata fails safe before skill mutation.
85
+ - **Path aliases and junctions:** hook paths retain the caller spelling while MCP/resident
86
+ identities canonicalize root, config, manifest, tsconfig, launcher, and missing-tail import
87
+ paths. macOS `/var` → `/private/var` aliases and Windows junctions therefore reach the same
88
+ resident endpoint without turning in-project writes into external paths or losing import edges.
89
+ Windows cross-drive import targets are rejected as external even though `path.relative()`
90
+ returns an absolute drive-qualified path for them.
91
+ - **ArkRules inventory noise:** actual governed layer, generated/test/fixture context, technical
92
+ constants, and error-constructor metadata suppress false business-rule pilots while preserving
93
+ eligible Domain/controller candidates.
94
+ - **Design guidance truth:** UI business-rule pilots now route Domain → Application → UI; local
95
+ permission/UI-state `canEdit` helpers are not flagged by name alone; god-module pilots exclude
96
+ seed/fixture/demo/migration/generated files; design-weak labels retain the observed
97
+ SUGGEST/ADAPT/ENFORCE mode.
98
+ - **Cross-version report deltas:** evolution reports no longer present an Ark score delta when the
99
+ origin and current snapshots were produced by different ArkGate versions. Raw coverage, file,
100
+ violation, layer, rule, and gate facts remain visible.
101
+
102
+ ### Compatibility
103
+
104
+ - No required `ark.config.json` migration and no new ArkRules sensor family.
105
+ - Existing MCP clients continue to work with `binding.status = "unverified"` and
106
+ `authoritative = false`; generated instructions require `ark_identity` followed by
107
+ `ark_manifest`. Standard `ark://manifest` resource reads remain compatibility-only and
108
+ non-authoritative.
109
+ - `projectId` is stable for one canonical local checkout across process restarts and contract
110
+ edits. It is intentionally not a cross-machine or cross-operating-system content id.
111
+
112
+ ## 4.1.1 — 2026-07-25 (published)
9
113
 
10
114
  **Patch** over 4.1.0. Phase EH — enforcement evidence modeling + documentation truth (field Codex
11
115
  feedback + public-lane claims audit). Honesty and doctor/CI evidence taxonomy; first-push-safe CI
12
116
  base-ref; report `.gitignore` coverage without defeating `!` exceptions. **No required config
13
117
  migration.** Does not invent hard-write for Codex/Cursor/OpenCode. Does not close Z09 / RB-11.
14
- **Status: prepared** (not on npm until publish).
118
+ **Status: published** (`arkgate@4.1.1`; superseded by 4.2.0 on `latest`).
15
119
 
16
120
  ### Added
17
121
 
@@ -59,7 +163,7 @@ write-root split, SPA/lib classification vacuum fixes, ESLint path-alias parity,
59
163
  false-positive tuning, ArkRules merge-plane honesty, type-edge placement debt, rules-inventory
60
164
  UI noise reduction, migrate-contract retrofit, and config write containment.
61
165
  **No required config migration.** Does not weaken write gate or CI value edges. Does not close
62
- Z09 / RB-11 field claims. **Status: published** (`arkgate@4.1.0` on npm `latest` at ship time).
166
+ Z09 / RB-11 field claims. **Status: published** (`arkgate@4.1.0`; superseded by 4.1.1 on `latest`).
63
167
 
64
168
  ### Added
65
169
 
package/README.md CHANGED
@@ -16,8 +16,9 @@ and makes sure a “green” check means something real.
16
16
 
17
17
  </div>
18
18
 
19
- > **ArkGate 4.1.0** is on npm `latest`. Tree prepares **4.1.1** (Phase EH honesty + CI/report fixes) — [4.1.1 notes](docs/releases/4.1.1.md) (**prepared**, not on npm until publish).
20
- > [4.1.0 notes](docs/releases/4.1.0.md) · [4.0.1](docs/releases/4.0.1.md) · [Docs hub](docs/README.md) · [Product voice](docs/product-voice.md)
19
+ > **ArkGate 4.2.1** is prepared (Next.js 16.3 root `proxy.ts` scan + fixture pins);
20
+ > **4.2.0** remains on npm `latest` until publication.
21
+ > [4.2.1 candidate](docs/releases/4.2.1.md) · [4.2.0](docs/releases/4.2.0.md) · [4.1.1](docs/releases/4.1.1.md) · [Docs hub](docs/README.md) · [Product voice](docs/product-voice.md)
21
22
 
22
23
  ---
23
24
 
@@ -110,6 +111,7 @@ GitHub **status context** that runs the CLI — not “CI file present,” and n
110
111
  Cursor/Codex/OpenCode never get a fake hard write claim.
111
112
 
112
113
  This table describes the supported profile **after its files are installed and the host loads/trusts them**. A hard local boundary covers only the listed hook operations; alternate tools, direct filesystem writes, and human edits still rely on CI. MCP validation is advisory because the agent must call it. The CI check blocks a merge only when the repository makes that status required. Repair **envelopes** may be emitted without reinjection being guaranteed; silent auto-apply never happens. Run `arkgate-check --doctor` (or `ark-check --doctor`) for the evidence actually detected in the current repository.
114
+
113
115
  <!-- arkgate-host-support:end -->
114
116
 
115
117
  #### Why the hard guarantee lives at the merge gate
@@ -130,6 +132,12 @@ the gate.
130
132
 
131
133
  Setup per host: [docs/ai-gates.md](docs/ai-gates.md) · Develop path: [docs/develop.md](docs/develop.md)
132
134
 
135
+ For authoritative MCP contract evidence, call `ark_identity` with the exact project root, then
136
+ call `ark_manifest` with that root plus the returned project id. A contained descendant requires
137
+ the matching id. The legacy `ark://manifest` resource remains compatibility-only and always
138
+ unverified/non-authoritative because standard `resources/read` cannot portably carry that
139
+ expectation.
140
+
133
141
  ---
134
142
 
135
143
  ## Why not only ESLint / Nx / cruiser?
@@ -138,7 +146,7 @@ Setup per host: [docs/ai-gates.md](docs/ai-gates.md) · Develop path: [docs/deve
138
146
  |--|:---:|:---:|
139
147
  | CI import rules | ✅ | ✅ |
140
148
  | Hard-block AI writes on supported hosts | ✅ | ❌ |
141
- | Contract agents can read (`ark://manifest`) | ✅ | ❌ |
149
+ | Project-bound contract agents can read (`ark_manifest`) | ✅ | ❌ |
142
150
  | Placement + preflight for multi-file changes | ✅ | ❌ |
143
151
  | Honest governed % + dual plan (edges vs shape) | ✅ | ❌ |
144
152
  | Opt-in intra-layer ArkRules (structure + invariants) | ✅ | ❌ |
@@ -186,7 +194,11 @@ for real systems. Details: [docs/production-hardening.md](docs/production-harden
186
194
  | Config · package surface · TS | [configuration](docs/configuration.md) · [package-surface](docs/package-surface.md) · [typescript-support](docs/typescript-support.md) |
187
195
  | Brownfield | [docs/brownfield-adoption.md](docs/brownfield-adoption.md) |
188
196
  | Security | [SECURITY.md](SECURITY.md) |
189
- | Current published (4.1.0) | [docs/releases/4.1.0.md](docs/releases/4.1.0.md) · [CHANGELOG](CHANGELOG.md) |
197
+ | Prepared candidate (4.2.1) | [docs/releases/4.2.1.md](docs/releases/4.2.1.md) · [CHANGELOG](CHANGELOG.md) |
198
+ | Current published (4.2.0) | [docs/releases/4.2.0.md](docs/releases/4.2.0.md) |
199
+ | Previous (4.1.1) | [docs/releases/4.1.1.md](docs/releases/4.1.1.md) |
200
+ | Previous (4.1.0) | [docs/releases/4.1.0.md](docs/releases/4.1.0.md) |
201
+ | Previous patch (4.0.1) | [docs/releases/4.0.1.md](docs/releases/4.0.1.md) |
190
202
  | Previous (4.0.0) | [docs/releases/4.0.0.md](docs/releases/4.0.0.md) |
191
203
  | Previous (3.9.2) | [docs/releases/3.9.2.md](docs/releases/3.9.2.md) |
192
204
  | History / maintainer evidence | [docs/archive/](docs/archive/README.md) |
@@ -169,7 +169,10 @@ function parseArgs(argv) {
169
169
  args.strictMerge = true;
170
170
  }
171
171
  else if (arg === '--strict-config') args.strictConfig = true;
172
- else if (arg === '--require-gates') args.requireGates = true;
172
+ else if (arg === '--require-gates') {
173
+ args.requireGates = true;
174
+ args.strictConfig = true;
175
+ }
173
176
  else if (arg === '--require-write-hook') {
174
177
  args.requireWriteHook = requireValue(arg, i++).trim().toLowerCase();
175
178
  }
@@ -323,9 +326,9 @@ function usage() {
323
326
  'specific host. Cursor and Codex expose advisory MCP tools plus the shared CI check;',
324
327
  'merge blocking requires repository policy to make that status required.',
325
328
  '',
326
- '--require-gates fails the check when AGENTS.md, .mcp.json, or the generated CI',
327
- 'workflow is missing, so "installed but never configured" is a red CI. Combine it',
328
- 'with --strict-config to enforce gate presence and architecture in one run.',
329
+ '--require-gates implies --strict-config and fails when the Ark contract in AGENTS.md,',
330
+ 'the project-rooted Ark server in .mcp.json, or fail-closed CI is missing/invalid.',
331
+ 'Included but unclassified source files therefore stay red instead of false-green.',
329
332
  '',
330
333
  '--install-agent-gates writes AGENTS.md, .mcp.json, and the CI workflow for every',
331
334
  'project, plus tool-specific templates. Known tools: claude, cursor, codex, grok',
@@ -1255,7 +1258,7 @@ async function main() {
1255
1258
  if (args.requireGates) {
1256
1259
  const compactHost = compactRouterHost(args.root);
1257
1260
  console.log(
1258
- 'Ark gates present (merge profile): ' +
1261
+ 'Ark gate artifacts found on disk (merge profile; runtime activation not implied): ' +
1259
1262
  (compactHost
1260
1263
  ? `AGENTS.md, compact host registration (${compactHost})`
1261
1264
  : REQUIRED_GATE_FILES.join(', '))
@@ -1467,10 +1470,13 @@ async function main() {
1467
1470
  if (args.rulesInventory) {
1468
1471
  const { buildRulesInventory, inventoryToExtractionCard } = await import('./lib/rules-inventory.mjs');
1469
1472
  const fileContents = {};
1473
+ const fileLayers = {};
1470
1474
  for (const file of files.slice(0, 400)) {
1471
1475
  const rel = normalize(path.relative(root, file));
1472
1476
  try {
1473
1477
  fileContents[rel] = fs.readFileSync(file, 'utf8');
1478
+ const layer = layerForFile(root, file, config.layers);
1479
+ if (layer) fileLayers[rel] = layer;
1474
1480
  } catch {
1475
1481
  /* skip unreadable */
1476
1482
  }
@@ -1488,6 +1494,11 @@ async function main() {
1488
1494
  }
1489
1495
  const inventory = buildRulesInventory({
1490
1496
  fileContents,
1497
+ fileLayers,
1498
+ layerContexts: (config.layers ?? []).map((layer) => ({
1499
+ name: layer.name,
1500
+ intentPrefixes: layer.intentPrefixes ?? [],
1501
+ })),
1491
1502
  contractedRuleIds: contracted,
1492
1503
  });
1493
1504
  const nextPilot =