arkgate 3.0.4 → 3.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.
- package/CHANGELOG.md +82 -1
- package/README.md +29 -9
- package/bin/ark-check.mjs +69 -54
- package/bin/ark-mcp.mjs +267 -26
- package/bin/ark.mjs +50 -3
- package/bin/lib/adapter-contract.mjs +27 -1
- package/bin/lib/agent-gates.mjs +9 -0
- package/bin/lib/analysis-engine.mjs +7 -1169
- package/bin/lib/ci-and-commands.mjs +4 -0
- package/bin/lib/codex-home.mjs +10 -1
- package/bin/lib/doctor-plan.mjs +37 -9
- package/bin/lib/host-support-matrix.mjs +6 -2
- package/bin/lib/install-migrate.mjs +81 -25
- package/bin/lib/mcp-adoption.mjs +8 -0
- package/bin/lib/policy-delta-io.mjs +161 -0
- package/bin/lib/prepare-change.mjs +186 -0
- package/bin/lib/remediation.mjs +24 -0
- package/bin/lib/skill-install.mjs +302 -22
- package/bin/lib/violations.mjs +2 -2
- package/bin/lib/weakest-link.mjs +61 -12
- package/bin/lib/write-path-capabilities.mjs +70 -2
- package/bin/lib/write-path-detect.mjs +18 -11
- package/dist/eslint/index.cjs +3 -977
- package/dist/eslint/index.js +3 -931
- package/dist/index.cjs +6 -1960
- package/dist/index.d.cts +152 -5
- package/dist/index.d.ts +152 -5
- package/dist/index.js +6 -1908
- package/docs/agent-guide.md +16 -2
- package/docs/ai-gates.md +35 -3
- package/docs/configuration.md +44 -0
- package/docs/package-surface.md +8 -1
- package/docs/threat-model.md +7 -4
- package/package.json +6 -5
- package/schemas/ark.analysis-result.schema.json +5 -1
- package/schemas/ark.change-map.schema.json +77 -0
- package/server.json +2 -2
- package/templates/skills/ark-upgrade.md +9 -5
- package/docs/ark-check-example.json +0 -87
- package/docs/demos/03-copilot-autopilot.md +0 -93
- package/docs/migrate-from-ark-runtime-kernel.md +0 -174
- package/docs/production-hardening.md +0 -100
package/docs/agent-guide.md
CHANGED
|
@@ -281,14 +281,21 @@ Prefer preparing the write before the host commits it to disk:
|
|
|
281
281
|
| Surface | Role |
|
|
282
282
|
|---------|------|
|
|
283
283
|
| MCP **`ark_prepare_write`** | Place + constrain + validate + optional `autoPatch` + `judgmentBrief` + contentHash + optional `goldenPattern` in one call |
|
|
284
|
+
| MCP **`ark_prepare_change`** | Validate one complete create/update/delete batch in memory; optional `changeMap` also returns structural convergence; never writes |
|
|
285
|
+
| CLI **`ark preflight --changes <file> --json`** | Same atomic verdict and map convergence for hosts/scripts that do not call MCP |
|
|
284
286
|
| Write-gate **`autoPatch`** | Mechanical-safe **import type** rewrites only; post-patch revalidation green or discarded |
|
|
285
287
|
| PreToolUse **`--hook-repair`** | On deny: `ARK_REPAIR_JSON` / `ARK_AUTOPATCH_JSON` on stderr (still exit 2 — never silent write) |
|
|
286
|
-
| Doctor **`writePath`** | Reports `
|
|
288
|
+
| Doctor **`writePath`** | Reports installed mode plus `enforcementLadder` (`supported` / `installed` / `active` / `bypassable`, evidence, operation coverage, required-status honesty) |
|
|
287
289
|
| Doctor **`goldenPattern`** | Optional Q03 advisory summary (`present` / `invalid`); never clears design-weak |
|
|
288
290
|
|
|
289
291
|
Port-proof inject binding is **judgment** for auto-apply (signature/arity change), not write-path autoPatch.
|
|
290
292
|
Full reference: [ai-gates.md](ai-gates.md). Loop-cost harness: `npm run eval:loop-cost`.
|
|
291
293
|
|
|
294
|
+
Blocking diagnostics carry one deterministic `nextAction` in both human and JSON output. Complete
|
|
295
|
+
Codex `ApplyPatch` payloads use the same atomic batch engine as CLI/MCP before single-file safety
|
|
296
|
+
checks; this improves early feedback without upgrading Codex's bypassable hook to a universal hard
|
|
297
|
+
boundary. Removing `AGENTS.md`, skills, or session context never changes the contract verdict.
|
|
298
|
+
|
|
292
299
|
Do not invent layers outside the 11-layer profile or named presets. Unrecognized
|
|
293
300
|
directories (`utils/`, `lib/`) must be classified explicitly via `/ark-contract`.
|
|
294
301
|
|
|
@@ -307,7 +314,7 @@ npx arkgate-check --install-agent-gates --tools claude,cursor,codex,grok
|
|
|
307
314
|
|------|-----------------|-------------|
|
|
308
315
|
| Claude Code | `.claude/settings.json` hook + `.mcp.json` / `claude mcp add` | `.claude/skills/<name>/SKILL.md` |
|
|
309
316
|
| Cursor | `.cursor/mcp.json` + `.cursor/rules/ark.mdc` | `.cursor/commands/` |
|
|
310
|
-
| OpenAI Codex | `$CODEX_HOME/config.toml` (global; absolute `--root`; multi-project → secondary `ark_<slug>` unless `--force`; doctor defers non-temp home gaps when session host ≠ Codex — see [ai-gates.md](ai-gates.md)) | `$CODEX_HOME/
|
|
317
|
+
| OpenAI Codex | `$CODEX_HOME/config.toml` (global; absolute `--root`; multi-project → secondary `ark_<slug>` unless `--force`; doctor defers non-temp home gaps when session host ≠ Codex — see [ai-gates.md](ai-gates.md)) | **Repo:** `.agents/skills/<name>/SKILL.md`; **home:** `$CODEX_HOME/skills/<name>/SKILL.md` (`--codex-home`) |
|
|
311
318
|
| **Grok Build** | `.grok/hooks/ark-write-gate.json` + `.grok/config.toml` / `.mcp.json` | `.grok/skills/<name>/SKILL.md` |
|
|
312
319
|
|
|
313
320
|
This is a path reference, not a guarantee table. Full copy-paste setups:
|
|
@@ -672,6 +679,13 @@ The strongest place to constrain an AI agent is the moment it writes a file, not
|
|
|
672
679
|
JS-API TypeScript — nested or project) so a host can gate
|
|
673
680
|
the write path:
|
|
674
681
|
|
|
682
|
+
For a complete multi-file candidate, use `ark preflight --changes changes.json --json` or MCP
|
|
683
|
+
`ark_prepare_change`. Add `--change-map map.json` (or MCP `changeMap`) only for an explicit schema
|
|
684
|
+
`1.0` structural plan. Ark binds its normalized `changeMapHash` and compares the full candidate
|
|
685
|
+
against the current supplied base. `convergence.findings` separates satisfied, missing,
|
|
686
|
+
contradictory, and unplanned paths/edges; any structural mismatch rejects the batch. No map is
|
|
687
|
+
required, and `behavioralCompletion` remains `not-evaluated` even when structure converges.
|
|
688
|
+
|
|
675
689
|
```bash
|
|
676
690
|
npx ark-mcp --root . --config ark.config.json [--manifest ark.manifest.json]
|
|
677
691
|
```
|
package/docs/ai-gates.md
CHANGED
|
@@ -48,7 +48,11 @@ you pass `--force`, so review and commit only the templates that match your proj
|
|
|
48
48
|
**Doctor (W5):** `ark-check --doctor --json` includes `doctor.writePath`
|
|
49
49
|
(`mode`: `repair` | `reject-only` | `mcp-only` | `none`, plus `prepareWrite` /
|
|
50
50
|
`autoPatch` flags), the supported profile for the active host, and the evidence actually found.
|
|
51
|
-
|
|
51
|
+
`writePath.enforcementLadder` separates `supported`, `installed`, `active`, and `bypassable` for
|
|
52
|
+
local hooks, advisory MCP, and CI. Doctor leaves hook trust and required-status policy
|
|
53
|
+
`unverified`; an actual covered PreToolUse denial can report operation-scoped activity. Codex
|
|
54
|
+
`apply_patch` can expose a complete patch to the shared atomic preflight, but the host remains
|
|
55
|
+
bypassable/advisory because some Code Mode paths do not dispatch the project hook.
|
|
52
56
|
|
|
53
57
|
**Design fitness (3.0.1+):** the same doctor JSON may include `doctor.designFitness` and
|
|
54
58
|
`doctor.designSmells[]` (path evidence). Edge-clean `operatingMode: enforce` can still set
|
|
@@ -182,6 +186,9 @@ The MCP server exposes a resource and tools agents can use proactively (not an e
|
|
|
182
186
|
- **`ark://manifest`** (resource) — the machine-readable architecture contract (layers + rules), so the agent can read the architecture before generating code.
|
|
183
187
|
- **`validate_code`** (tool) — validates a snippet against the architecture on demand (the write-path gate). May return additive **`autoPatch`** (W1) for mechanical-safe import-type rewrites.
|
|
184
188
|
- **`ark_prepare_write`** (tool) — **W2:** place + constrain + validate + optional autoPatch + judgmentBrief + contentHash in one call (composes `ark_place` + write gate).
|
|
189
|
+
- **`ark_prepare_change`** (tool) — **T02–T05:** read-only atomic create/update/delete preflight with cross-file edge/cycle findings and candidate fingerprints. Optional `changeMap` accepts strict schema `1.0` intent and returns its hash plus satisfied/missing/contradictory/unplanned structural convergence; behavioral completion is not evaluated. Omission is supported. MCP registration remains advisory unless the host makes invocation non-bypassable.
|
|
190
|
+
- Blocking CLI/MCP/hook diagnostics include the same deterministic `nextAction`. `AGENTS.md`, skill
|
|
191
|
+
catalogs, session prose, and live LLM calls are not inputs to the enforcement verdict.
|
|
185
192
|
- **`ark_place`** (tool) — given a target file path, returns its layer, forbidden globals, and which layers it may / must not import. Call it *before* writing a new file so generated code lands in a governed location.
|
|
186
193
|
- **`ark_check`** (tool) — runs the full architecture check and returns structured violations (applies the baseline automatically when one exists).
|
|
187
194
|
- **`ark_coverage`** (tool) — per-layer file counts, the full unclassified-file list, and layers whose patterns match nothing.
|
|
@@ -268,7 +275,7 @@ Hand-editing with relative `--root .` is wrong: Codex does not use the project a
|
|
|
268
275
|
|
|
269
276
|
```bash
|
|
270
277
|
npx ark-check --install-agent-gates --tools codex
|
|
271
|
-
# optional: install /ark-*
|
|
278
|
+
# optional: install /ark-* skills into $CODEX_HOME/skills/<name>/SKILL.md
|
|
272
279
|
npx ark-check --install-agent-gates --codex-home
|
|
273
280
|
```
|
|
274
281
|
|
|
@@ -309,11 +316,36 @@ primary A. It writes a **scoped secondary** table:
|
|
|
309
316
|
|
|
310
317
|
`ark-check --doctor` surfaces the multi-project state so you are not left thinking B owns
|
|
311
318
|
`ark://manifest` when only a secondary table exists. **Deferred (fix when using Codex):**
|
|
312
|
-
non-temp Codex-home gaps (`codex-home-multi-project`, stale `$CODEX_HOME/
|
|
319
|
+
non-temp Codex-home gaps (`codex-home-multi-project`, stale `$CODEX_HOME/skills`) are
|
|
313
320
|
severity **info**, marked `deferred: true`, and omitted from Top actions when the session
|
|
314
321
|
host is known and not Codex — `/ark-upgrade` on Grok/Claude is not Incomplete because of
|
|
315
322
|
them. **Temp/upgrade primary roots** stay fail-closed urgent (rewritten, not multi-project).
|
|
316
323
|
|
|
324
|
+
### Codex skill catalog (SKILL.md, not flat prompts)
|
|
325
|
+
|
|
326
|
+
Codex discovers skills as directories containing `SKILL.md` (Agent Skills standard):
|
|
327
|
+
|
|
328
|
+
| Scope | Path |
|
|
329
|
+
|-------|------|
|
|
330
|
+
| **Repo** (written by `--tools codex`) | `.agents/skills/<name>/SKILL.md` |
|
|
331
|
+
| **Home** (optional `--codex-home`) | `$CODEX_HOME/skills/<name>/SKILL.md` |
|
|
332
|
+
|
|
333
|
+
Flat `.codex/prompts/*.md` files are **not** the invocable skill catalog. Install writes the
|
|
334
|
+
repo catalog above so AGENTS.md `/ark-*` references match what Codex can load. After install,
|
|
335
|
+
Ark verifies those references against each selected host catalog.
|
|
336
|
+
|
|
337
|
+
**Parity & honesty (doctor / install):**
|
|
338
|
+
|
|
339
|
+
- Doctor distinguishes **missing / stale / legacy-prompts-only** for repo (`.agents/skills`) and
|
|
340
|
+
home (`$CODEX_HOME/skills`). Home debt is **deferred** when the session host is not Codex.
|
|
341
|
+
- Legacy flat prompts alone are reported as non-loadable skill debt with a
|
|
342
|
+
`--skills-only --tools codex --force` (repo) or `--codex-home --force` (home) fix.
|
|
343
|
+
- Codex **write path is advisory**: MCP + best-effort `.codex/hooks.json` is **not** a hard
|
|
344
|
+
write boundary and is **not** equivalent to Claude/Grok PreToolUse hard-write + repair.
|
|
345
|
+
The hard merge backstop is CI `--strict-merge` (or `--strict`) plus a required status check.
|
|
346
|
+
- CI workflows that run ark-check without the fail-closed profile (or with only
|
|
347
|
+
`--strict-config`) surface gap `enforcement-ci-not-fail-closed`.
|
|
348
|
+
|
|
317
349
|
## Grok Build (xAI)
|
|
318
350
|
|
|
319
351
|
Grok reads project rules from **`AGENTS.md`**, project MCP from **`.grok/config.toml`**
|
package/docs/configuration.md
CHANGED
|
@@ -95,3 +95,47 @@ Safety fields:
|
|
|
95
95
|
|
|
96
96
|
The packaged JSON Schema is authoritative for types, constraints, defaults, and the unknown-key
|
|
97
97
|
policy.
|
|
98
|
+
|
|
99
|
+
## Contract transitions
|
|
100
|
+
|
|
101
|
+
`ark-check --strict-merge` protects the transition into a new contract, not only the resulting
|
|
102
|
+
file. In a Git checkout it compares the candidate `ark.config.json` with the merge base when that
|
|
103
|
+
base is available. CI can bind the comparison explicitly:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
ARK_POLICY_BASE_REF="$BASE_SHA" npx ark-check --strict-merge
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
For local or non-Git automation, supply a committed config file or Git ref:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npx ark-check --strict-config --policy-base ./before.ark.config.json --json
|
|
113
|
+
npx ark-check --strict-merge --policy-base-ref origin/main
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The additive JSON result includes `policyDelta`: both policy hashes, the overall classification,
|
|
117
|
+
stable findings, and `blockingFindingIds`. Supported comparisons cover governed include/exclude
|
|
118
|
+
roots, layer patterns/exclusions/forbidden globals, deny rules, same-layer peer isolation,
|
|
119
|
+
cycle policy, dynamic-import allowlists, and safety thresholds. Ambiguous ownership changes are
|
|
120
|
+
`judgment-required` rather than guessed.
|
|
121
|
+
|
|
122
|
+
Weakening and judgment-required transitions fail closed. An intentional exception is an explicit
|
|
123
|
+
JSON artifact passed with `--policy-ack`:
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"schemaVersion": "1.0",
|
|
128
|
+
"basePolicyHash": "fnv1a-...",
|
|
129
|
+
"candidatePolicyHash": "fnv1a-...",
|
|
130
|
+
"findingIds": ["weakening:$.dynamicImportAllowlist:added"],
|
|
131
|
+
"reason": "Temporary loader while the static registry is migrated."
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
The acknowledgement must list every blocking finding exactly. It is not a permanent allowlist:
|
|
136
|
+
changing either contract changes its hash and invalidates the acknowledgement.
|
|
137
|
+
|
|
138
|
+
MCP clients can call `ark_policy_delta` with the previous `baseConfig`, an optional candidate
|
|
139
|
+
contract (the current project contract is the default), and the same optional acknowledgement.
|
|
140
|
+
It invokes the public classifier directly, is read-only, and marks a blocking result as an MCP
|
|
141
|
+
error without maintaining separate adapter policy.
|
package/docs/package-surface.md
CHANGED
|
@@ -7,6 +7,8 @@
|
|
|
7
7
|
In-repo `docs/` remains the package/agent reference. Source: GitHub; distribution: npm.
|
|
8
8
|
|
|
9
9
|
This document is the consumer contract for **what is stable** vs **what is experimental**.
|
|
10
|
+
It ships as the consumer contract linked from the npm README. The separate experimental-runtime
|
|
11
|
+
hardening guide remains repository-hosted rather than duplicated in the gate tarball.
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
@@ -23,7 +25,12 @@ This document is the consumer contract for **what is stable** vs **what is exper
|
|
|
23
25
|
| **AI-velocity eval (Q05)** | `npm run eval:ai-velocity` → `eval/ai-velocity-report.json` | Fixture-measured (no live LLM). Same feature scenario on design-weak vs golden-path arms; metric **`placementTurns`** (agent-equivalent). Golden must be strictly better. Method string lives next to the number. Does not weaken the gate. |
|
|
24
26
|
| **MCP tools** | `arkgate-mcp` / `ark://…` resources | Tool names and primary argument shapes are stable within a major. |
|
|
25
27
|
| **`ark.config.json`** | Layer globs, rules, include/exclude, forbiddenGlobals, intent prefixes, `peerIsolation`, `dynamicImportAllowlist`, `safety` thresholds | Versioned by `schemaVersion`; unknown fields fail closed and migrations preserve the previous supported major. |
|
|
26
|
-
|
|
|
28
|
+
| **Policy transition analysis (T01, 3.1.0)** | `analyzePolicyDelta(...)`; MCP `ark_policy_delta`; CLI `--policy-base` / `--policy-base-ref` / `--policy-ack`; check JSON `policyDelta` | Additive schema `1.0`. Classifications and finding ids are deterministic. Weakening/judgment requires an acknowledgement bound to both policy hashes and the exact blocking finding set. |
|
|
29
|
+
| **Atomic change preflight (T02, 3.1.0)** | `preflightChange(...)`; CLI `ark preflight --changes <file> --json`; MCP `ark_prepare_change` | Additive schema `1.0`. One complete governed production-source `{path,content}` / `{path,delete:true}` batch; read-only; returns operation, content/tree/policy/compiler fingerprints and stable graph findings. MCP availability alone is advisory. |
|
|
30
|
+
| **Architecture change map (T03, 3.1.0)** | `arkgate/schema/change-map`; CLI `ark preflight --change-map <file>`; MCP `ark_prepare_change.changeMap` | Optional strict schema `1.0`. Canonical planned paths + operations + resolved Ark layers + dependencies between planned files. Preflight returns `changeMapHash`; absence is normal and adds no project file. Structural intent only, never behavioral completion. |
|
|
31
|
+
| **Structural convergence (T04, 3.1.0)** | `analyzeArchitectureConvergence(...)`; map-enabled `preflightChange(...)`; existing CLI/MCP preflight adapters | Additive `convergence` result with stable `satisfied`, `missing`, `contradictory`, and `unplanned` findings. Uses the supplied/current project tree as base and the explicit complete change set as candidate; no implicit Git or LLM input. `readOnly: true`; `behavioralCompletion: "not-evaluated"`. Structural mismatch makes preflight invalid. |
|
|
32
|
+
| **Enforcement ladder + fixed journey (T05, 3.1.0)** | `doctor.writePath.enforcementLadder`; hook repair `enforcement`; `npm run eval:change-integrity` | Additive schema `1.0` separates supported/installed/active/bypassable state and evidence. Hard is operation-scoped only for a supported covered hook; MCP is advisory; required CI status stays unverified locally. Fixed no-context fixture proves CLI/MCP/hook/final parity, one casual denial, acceptance behavior, and strict Ark. |
|
|
33
|
+
| **`arkgate/schema/analysis-result`** | Public CLI/MCP/hook diagnostic envelope (`schemaVersion`, `valid`, `diagnostics`) | Schema `1.1` adds optional `nextAction`; the `1.0` fixture and consumer-owned TypeScript diagnostics remain valid. |
|
|
27
34
|
| **Config JSON Schema** | `arkgate/schema` or `arkgate/schema/ark.config.schema.json` | Stable package resource subpaths for editor completion and contract tooling. |
|
|
28
35
|
| **Agent skills** | `/ark-*` templates installed by `--install-agent-gates` | Skill *names* and “default flow” are stable; internal skill prose may evolve (e.g. When/not when, explore Shape dual-plan seed, extraction cards, day-zero origin order). |
|
|
29
36
|
| **ESLint subpath** | `arkgate/eslint` | Config-driven layer/import rules; loads consumer `ark.config.json`. |
|
package/docs/threat-model.md
CHANGED
|
@@ -27,21 +27,24 @@ infrastructure beyond how this package is published.
|
|
|
27
27
|
|
|
28
28
|
| ID | Threat | Impact | Mitigations (shipped) |
|
|
29
29
|
|----|--------|--------|------------------------|
|
|
30
|
-
| T1 | Agent bypasses hook (direct `fs` / alternate tool) | Ungoverned code lands | CI gate; optional pre-commit (Q3); doctor
|
|
30
|
+
| T1 | Agent bypasses hook (direct `fs` / alternate tool) | Ungoverned code lands | CI gate; optional pre-commit (Q3); doctor ladder never upgrades installed files to active/hard proof |
|
|
31
31
|
| T2 | Human commits without agent path | Same as T1 | `templates/hooks/pre-commit-ark`; branch protection + required check (Q3 external) |
|
|
32
|
-
| T3 | CI job missing / not required | Merge green without architecture | doctor `enforcement-ci-*` gaps; `--strict-merge`
|
|
33
|
-
| T4 | Config weakened (`peerIsolation: false`, empty rules) | False green |
|
|
32
|
+
| T3 | CI job missing / not required | Merge green without architecture | doctor `enforcement-ci-*` gaps; `--strict-merge`; required-status remains locally `unverified` |
|
|
33
|
+
| T4 | Config weakened (`peerIsolation: false`, empty rules) | False green | semantic policy-delta guard in strict merge; hash-bound explicit acknowledgement; present-state safety diagnostics |
|
|
34
34
|
| T5 | Baseline ratcheted open | Debt reintroduced | baseline unused/stale signals; occurrence keys |
|
|
35
35
|
| T6 | Dual MCP bin / wrong root | Gate points at wrong tree | migrate-commands; Codex fail-closed temp roots |
|
|
36
36
|
| T7 | Malicious dependency in publish | Compromised gate | signed tags, npm provenance, dependency-review, CodeQL, Semgrep, `verify-package-files` |
|
|
37
37
|
| T8 | Path traversal in hooks/check | Read/write outside project | root resolution + under-root import resolve |
|
|
38
38
|
| T9 | Runtime InMemory mistaken for durable | Data loss | durability stance docs + safety InMemory production detector |
|
|
39
39
|
| T10 | Repair payload silently applied | Unexpected rewrites | repair never writes; host must re-inject; exit 2 on deny |
|
|
40
|
+
| T11 | Prompt context is mistaken for enforcement | Verdict changes after compaction or missing skills | contract/tree inputs only; no-context eval compares hashes and adapter evidence |
|
|
41
|
+
| T12 | Partial multi-file hook validation misses a cross-file edge | Invalid batch reaches disk | complete `apply_patch` events use atomic preflight; incomplete/bypassable paths rely on CI |
|
|
40
42
|
|
|
41
43
|
## Trust boundaries
|
|
42
44
|
|
|
43
45
|
```
|
|
44
|
-
Claude/Grok host --PreToolUse--> arkgate-mcp (hard
|
|
46
|
+
Claude/Grok host --PreToolUse--> arkgate-mcp (hard only for observed covered operation)
|
|
47
|
+
Codex ApplyPatch --PreToolUse--> arkgate-mcp (atomic feedback; bypassable/non-hard host profile)
|
|
45
48
|
Any MCP host --tool call----> arkgate-mcp (advisory validation)
|
|
46
49
|
Human IDE --disk/git-----> working tree
|
|
47
50
|
working tree --PR-----------> CI ark-check --strict-merge
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arkgate",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "ArkGate — architecture co-pilot for AI TypeScript (write gate, CI gate, plan/loop)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -26,6 +26,8 @@
|
|
|
26
26
|
"./schema/ark.config.schema.json": "./schemas/ark.config.schema.json",
|
|
27
27
|
"./schema/analysis-result": "./schemas/ark.analysis-result.schema.json",
|
|
28
28
|
"./schema/ark.analysis-result.schema.json": "./schemas/ark.analysis-result.schema.json",
|
|
29
|
+
"./schema/change-map": "./schemas/ark.change-map.schema.json",
|
|
30
|
+
"./schema/ark.change-map.schema.json": "./schemas/ark.change-map.schema.json",
|
|
29
31
|
"./nestjs": {
|
|
30
32
|
"types": "./compat/nestjs.d.ts",
|
|
31
33
|
"import": "./compat/nestjs.js",
|
|
@@ -50,16 +52,14 @@
|
|
|
50
52
|
"schemas",
|
|
51
53
|
"docs/agent-guide.md",
|
|
52
54
|
"docs/enthusiast",
|
|
53
|
-
"docs/demos",
|
|
55
|
+
"docs/demos/01-write-gate-self-correction.md",
|
|
56
|
+
"docs/demos/02-brownfield-baseline-adoption.md",
|
|
54
57
|
"docs/ai-gates.md",
|
|
55
|
-
"docs/migrate-from-ark-runtime-kernel.md",
|
|
56
58
|
"docs/typescript-support.md",
|
|
57
|
-
"docs/ark-check-example.json",
|
|
58
59
|
"docs/assets",
|
|
59
60
|
"docs/brownfield-adoption.md",
|
|
60
61
|
"docs/configuration.md",
|
|
61
62
|
"docs/package-surface.md",
|
|
62
|
-
"docs/production-hardening.md",
|
|
63
63
|
"docs/threat-model.md",
|
|
64
64
|
"tests/fixtures/ts-consumer",
|
|
65
65
|
"templates",
|
|
@@ -105,6 +105,7 @@
|
|
|
105
105
|
"eval:comparative": "node eval/comparative-run.mjs",
|
|
106
106
|
"eval:loop-cost": "node eval/loop-cost-run.mjs",
|
|
107
107
|
"eval:ai-velocity": "node eval/ai-velocity-run.mjs",
|
|
108
|
+
"eval:change-integrity": "node eval/change-integrity-run.mjs",
|
|
108
109
|
"eval:adoption": "node eval/adoption-run.mjs",
|
|
109
110
|
"test:adoption-harness": "vitest run tests/unit/eval/adoptionHarness.test.ts",
|
|
110
111
|
"bench:scale": "node scripts/ark-scale-bench.mjs",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
],
|
|
12
12
|
"properties": {
|
|
13
13
|
"schemaVersion": {
|
|
14
|
-
"const": "1.
|
|
14
|
+
"const": "1.1"
|
|
15
15
|
},
|
|
16
16
|
"valid": {
|
|
17
17
|
"type": "boolean"
|
|
@@ -83,6 +83,10 @@
|
|
|
83
83
|
"type": "boolean"
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
+
},
|
|
87
|
+
"nextAction": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"minLength": 1
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
92
|
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://unpkg.com/arkgate@3/schemas/ark.change-map.schema.json",
|
|
4
|
+
"title": "ArkGate architecture change map",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": [
|
|
8
|
+
"$schema",
|
|
9
|
+
"schemaVersion",
|
|
10
|
+
"files"
|
|
11
|
+
],
|
|
12
|
+
"properties": {
|
|
13
|
+
"$schema": {
|
|
14
|
+
"type": "string",
|
|
15
|
+
"minLength": 1,
|
|
16
|
+
"default": "https://unpkg.com/arkgate@3/schemas/ark.change-map.schema.json"
|
|
17
|
+
},
|
|
18
|
+
"schemaVersion": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"const": "1.0",
|
|
21
|
+
"default": "1.0"
|
|
22
|
+
},
|
|
23
|
+
"files": {
|
|
24
|
+
"type": "array",
|
|
25
|
+
"minItems": 1,
|
|
26
|
+
"items": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"required": [
|
|
30
|
+
"path",
|
|
31
|
+
"operation",
|
|
32
|
+
"layer"
|
|
33
|
+
],
|
|
34
|
+
"properties": {
|
|
35
|
+
"path": {
|
|
36
|
+
"type": "string",
|
|
37
|
+
"minLength": 1
|
|
38
|
+
},
|
|
39
|
+
"operation": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"enum": [
|
|
42
|
+
"create",
|
|
43
|
+
"update",
|
|
44
|
+
"delete"
|
|
45
|
+
]
|
|
46
|
+
},
|
|
47
|
+
"layer": {
|
|
48
|
+
"type": "string",
|
|
49
|
+
"minLength": 1
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"type": "array",
|
|
56
|
+
"default": [],
|
|
57
|
+
"items": {
|
|
58
|
+
"type": "object",
|
|
59
|
+
"additionalProperties": false,
|
|
60
|
+
"required": [
|
|
61
|
+
"from",
|
|
62
|
+
"to"
|
|
63
|
+
],
|
|
64
|
+
"properties": {
|
|
65
|
+
"from": {
|
|
66
|
+
"type": "string",
|
|
67
|
+
"minLength": 1
|
|
68
|
+
},
|
|
69
|
+
"to": {
|
|
70
|
+
"type": "string",
|
|
71
|
+
"minLength": 1
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/pedroknigge/arkgate",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "3.0
|
|
9
|
+
"version": "3.1.0",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "arkgate",
|
|
14
|
-
"version": "3.0
|
|
14
|
+
"version": "3.1.0",
|
|
15
15
|
"runtimeHint": "npx",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
@@ -123,11 +123,15 @@ npx arkgate-check --install-agent-gates --skills-only --force
|
|
|
123
123
|
**Active host first.** Refresh skills for the host running this skill (e.g.
|
|
124
124
|
`.grok/skills/`, `.claude/skills/`, `.cursor/commands/`). Repo-local copies for
|
|
125
125
|
other detected hosts are fine to refresh in the same pass when cheap.
|
|
126
|
-
**Codex is deferred when you are not on Codex.**
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
**Codex is deferred when you are not on Codex.** Repo skills live in
|
|
127
|
+
`.agents/skills/<name>/SKILL.md`; optional home skills in
|
|
128
|
+
`$CODEX_HOME/skills/<name>/SKILL.md` (not legacy flat `$CODEX_HOME/prompts`).
|
|
129
|
+
When **on Codex**, refresh **both** repo catalog and home if doctor reports
|
|
130
|
+
missing/stale/legacy-prompts-only parity gaps. `ark upgrade` may best-effort
|
|
131
|
+
refresh home when it exists; still list Codex under **Deferred hosts** when
|
|
132
|
+
not on Codex and do **not** chase MCP multi-project / stale home skills until
|
|
133
|
+
the user is on Codex (or asks). Fix when needed:
|
|
134
|
+
`ark-check --install-agent-gates --skills-only --tools codex --force` and/or
|
|
131
135
|
`ark-check --install-agent-gates --skills-only --codex-home --force`
|
|
132
136
|
(and `--tools codex` / `--force` for primary MCP rebind). Exception: temp or
|
|
133
137
|
`ark-upgrade` MCP `--root` paths — leave fail-closed rewrite to the CLI; do not
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"include": ["src"],
|
|
3
|
-
"layers": [
|
|
4
|
-
{
|
|
5
|
-
"name": "DomainModel",
|
|
6
|
-
"patterns": ["src/domain/**"],
|
|
7
|
-
"intentPrefixes": ["Domain."]
|
|
8
|
-
},
|
|
9
|
-
{
|
|
10
|
-
"name": "ApplicationOrchestration",
|
|
11
|
-
"patterns": ["src/application/**"],
|
|
12
|
-
"intentPrefixes": ["Application."]
|
|
13
|
-
},
|
|
14
|
-
{
|
|
15
|
-
"name": "PersistenceAdapters",
|
|
16
|
-
"patterns": ["src/adapters/persistence/**"],
|
|
17
|
-
"intentPrefixes": ["Adapter.Persistence."]
|
|
18
|
-
},
|
|
19
|
-
{
|
|
20
|
-
"name": "IntegrationAdapters",
|
|
21
|
-
"patterns": ["src/adapters/integration/**"],
|
|
22
|
-
"intentPrefixes": ["Adapter.Integration."]
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"name": "WorkflowSagaEngine",
|
|
26
|
-
"patterns": ["src/workflows/**"],
|
|
27
|
-
"intentPrefixes": ["Workflow."]
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"name": "BackgroundJobsScheduling",
|
|
31
|
-
"patterns": ["src/jobs/**"],
|
|
32
|
-
"intentPrefixes": ["Job."]
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
"name": "PresentationAdapters",
|
|
36
|
-
"patterns": ["src/presentation/**"],
|
|
37
|
-
"intentPrefixes": ["Presentation."]
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
"name": "ReportingReadModels",
|
|
41
|
-
"patterns": ["src/reporting/**"],
|
|
42
|
-
"intentPrefixes": ["Reporting."]
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"name": "ExtensibilityMetadata",
|
|
46
|
-
"patterns": ["src/metadata/**"],
|
|
47
|
-
"intentPrefixes": ["Metadata."]
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
"name": "SecurityAuditObservability",
|
|
51
|
-
"patterns": ["src/security/**", "src/audit/**", "src/observability/**"],
|
|
52
|
-
"intentPrefixes": ["Security.", "Audit.", "Observability."]
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
"name": "Kernel",
|
|
56
|
-
"patterns": ["src/kernel/**"],
|
|
57
|
-
"intentPrefixes": ["Kernel."]
|
|
58
|
-
}
|
|
59
|
-
],
|
|
60
|
-
"rules": [
|
|
61
|
-
{
|
|
62
|
-
"from": "DomainModel",
|
|
63
|
-
"to": "PersistenceAdapters",
|
|
64
|
-
"allowed": false
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
"from": "DomainModel",
|
|
68
|
-
"to": "IntegrationAdapters",
|
|
69
|
-
"allowed": false
|
|
70
|
-
},
|
|
71
|
-
{
|
|
72
|
-
"from": "DomainModel",
|
|
73
|
-
"to": "PresentationAdapters",
|
|
74
|
-
"allowed": false
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"from": "PresentationAdapters",
|
|
78
|
-
"to": "PersistenceAdapters",
|
|
79
|
-
"allowed": false
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
"from": "ReportingReadModels",
|
|
83
|
-
"to": "PersistenceAdapters",
|
|
84
|
-
"allowed": false
|
|
85
|
-
}
|
|
86
|
-
]
|
|
87
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
# Demo: the co-pilot autopilot, end to end
|
|
2
|
-
|
|
3
|
-
Take a project from "no guardrails" to "governed, cleaned up, and enforced" — the way a
|
|
4
|
-
non-developer would, driving an agent. This is the Phase F→G→H→I flow (plan · guided setup ·
|
|
5
|
-
loop · autopilot) in one sitting.
|
|
6
|
-
|
|
7
|
-
## In one line
|
|
8
|
-
|
|
9
|
-
`npx ark start` sets it up and shows a plan; **`/ark-autopilot`** (in your agent) carries the
|
|
10
|
-
plan out — applying the safe fixes and proposing the rest, always validated by `ark-check`.
|
|
11
|
-
|
|
12
|
-
## Prerequisites
|
|
13
|
-
|
|
14
|
-
- Ark built or installed from this repository
|
|
15
|
-
- An agent CLI (Claude, Cursor, Codex, Grok, …) for the `/ark-autopilot` and `/ark-loop` steps
|
|
16
|
-
|
|
17
|
-
## Steps
|
|
18
|
-
|
|
19
|
-
### 1. Guided setup (no architecture knowledge needed)
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
TMP=$(mktemp -d); cd "$TMP"
|
|
23
|
-
git init -q # the loop works in a discardable worktree
|
|
24
|
-
npm init -y >/dev/null
|
|
25
|
-
npx ark start --yes
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
Ark describes the project's shape in plain language, writes `ark.config.json` + agent/CI gates,
|
|
29
|
-
and prints the **plan** — how many fixes are _safe to auto-apply_ vs _need your decision_ —
|
|
30
|
-
plus which **operating mode** applies: **suggest**, **adapt**, or **enforce**.
|
|
31
|
-
|
|
32
|
-
On Nest/Next/express/library projects, init also merges framework filename conventions into
|
|
33
|
-
the layer globs so day-one **governed%** is real (not a false-green empty contract).
|
|
34
|
-
|
|
35
|
-
### 2. See the plan yourself (optional)
|
|
36
|
-
|
|
37
|
-
```bash
|
|
38
|
-
npx ark-check --plan # human view (includes Governed: N%; pattern bets when design-weak)
|
|
39
|
-
npx ark-check --plan --json # { ok, plan: { goal, counts, steps, patternBets?, designSmells? } }
|
|
40
|
-
npx ark-check --doctor --json # designFitness / designSmells when residual is design-weak
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Each **A** step is tagged `mechanical-safe` / `judgment` / `deferred` with a `confidence`,
|
|
44
|
-
`rationale`, and often `remediationKind`. Auto-safe kinds: type-only type move, pure-type **file**
|
|
45
|
-
relocate, `import type` of pure-type modules, and named type-export imports from mixed modules
|
|
46
|
-
(`import-type-of-type-exports`). `goal.met` is true only when
|
|
47
|
-
there are no active violations **and** governed coverage is meaningful — so a clean plan that
|
|
48
|
-
checks almost nothing is not "done."
|
|
49
|
-
|
|
50
|
-
When edges are clean but design residual remains, JSON also sets `goal.designWeak` and
|
|
51
|
-
`patternBets[]` (each with `neverMechanicalSafe: true`). Those are **B** (Shape) bets — not
|
|
52
|
-
auto-applied. Extraction cards: [brownfield-adoption.md](../brownfield-adoption.md) §6.
|
|
53
|
-
|
|
54
|
-
### 3. Carry the plan out — the autopilot
|
|
55
|
-
|
|
56
|
-
In your agent, run:
|
|
57
|
-
|
|
58
|
-
```
|
|
59
|
-
/ark-autopilot
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
It runs the whole flow (newbie tier): **explore first** (map + dual plan), hands off to
|
|
63
|
-
`/ark-loop` for plan **A** `mechanical-safe` steps one at a time — **validating each with
|
|
64
|
-
`ark-check` and rolling back any regression** — proposes each A `judgment` and each B
|
|
65
|
-
pattern/Shape bet for a yes/no, and reports what was auto-applied vs proposed vs deferred.
|
|
66
|
-
Nothing lands until you review the diff. Empty A with open B is **not** “architecture healthy
|
|
67
|
-
finished.”
|
|
68
|
-
|
|
69
|
-
Expert entry: skip the autopilot and use the pieces — `ark init` / `/ark-contract` to shape the
|
|
70
|
-
contract, `ark-check --plan` for the work, `/ark-fix` for targeted fixes, `ark-check
|
|
71
|
-
--strict-config` as the gate. Same contract, same gates; same suggest/adapt/enforce modes.
|
|
72
|
-
|
|
73
|
-
### 4. It stays clean
|
|
74
|
-
|
|
75
|
-
The gates installed in step 1 keep enforcing the architecture from now on — in CI, and at write
|
|
76
|
-
time if the MCP hook is wired. Verify:
|
|
77
|
-
|
|
78
|
-
```bash
|
|
79
|
-
npx ark-check --root . --config ark.config.json --strict-config
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## What this proves
|
|
83
|
-
|
|
84
|
-
- **plan + goal** (Phase F): `ark-check --plan` classifies the work and defines "done" (with
|
|
85
|
-
governed% honesty).
|
|
86
|
-
- **guided setup** (Phase G): `ark start` — no preset or skill name required; modes
|
|
87
|
-
suggest / adapt / enforce.
|
|
88
|
-
- **loop** (Phase H): `/ark-loop` — safe, reversible, validated apply.
|
|
89
|
-
- **autopilot** (Phase I): `/ark-autopilot` — the whole thing, with newbie/expert entry styles.
|
|
90
|
-
- **field honesty** (2.0): framework overlays + no false-green at 0% governed.
|
|
91
|
-
|
|
92
|
-
The classifier's precision (only provably-safe changes are ever `mechanical-safe`) is guarded
|
|
93
|
-
by the classifier corpus test in `tests/unit/static-check/arkCheck.test.ts`.
|