arkgate 2.11.0 → 2.12.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 +64 -0
- package/README.md +15 -10
- package/bin/ark.mjs +52 -19
- package/bin/lib/agent-gates.mjs +68 -2094
- package/bin/lib/ci-and-commands.mjs +386 -0
- package/bin/lib/deploy-path.mjs +205 -0
- package/bin/lib/gate-files.mjs +223 -0
- package/bin/lib/hook-templates.mjs +99 -0
- package/bin/lib/install-migrate.mjs +442 -0
- package/bin/lib/mcp-adoption.mjs +423 -0
- package/bin/lib/presets.mjs +3 -0
- package/bin/lib/skill-install.mjs +259 -0
- package/bin/lib/typescript-host.mjs +88 -0
- package/bin/lib/write-path-detect.mjs +138 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.cjs +1 -1
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +1 -1
- package/dist/nestjs/index.js.map +1 -1
- package/dist/runtime/index.cjs +1 -1
- package/dist/runtime/index.cjs.map +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/docs/agent-guide.md +11 -1
- package/docs/package-surface.md +8 -1
- package/package.json +1 -1
- package/server.json +2 -2
- package/templates/skills/ark-autopilot.md +77 -45
- package/templates/skills/ark-explain.md +2 -1
- package/templates/skills/ark-explore.md +135 -34
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,70 @@ All notable changes to ArkGate (`arkgate`; formerly `ark-runtime-kernel`) are do
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 2.12.0 — 2026-07-10
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **Install agent gates on temp roots:** skip rewriting the developer's real
|
|
12
|
+
`~/.codex/config.toml` when the project root is a temp/upgrade scratch and
|
|
13
|
+
`CODEX_HOME` is unset. Home MCP wire failures no longer fail an otherwise
|
|
14
|
+
successful repo gate install (sandbox/EPERM). Explicit `CODEX_HOME` and
|
|
15
|
+
`--codex-home` still wire as before.
|
|
16
|
+
- **Q1 coverage floors (broad include, 80/85/95):** Vitest thresholds statements/lines **≥80%**,
|
|
17
|
+
branches/functions **≥85%** on the **full product unit surface** (`src/**` + `bin/lib/**` +
|
|
18
|
+
`bin/ark-shared.mjs`; only process-entry shells excluded — no cherry-picked enforcement-core
|
|
19
|
+
include). Per-path critical floors: write-path-detect / auto-patch / prepare-write /
|
|
20
|
+
safety-diagnostics / baseline-key / graph-cycles at **≥95%** branch. Real branch-driving tests
|
|
21
|
+
under `tests/unit/static-check/` (critical + surface/topup/seam suites). Two consecutive
|
|
22
|
+
green `npm run test:coverage` captures (stmts/lines **92.71%**, branches **85%**, functions
|
|
23
|
+
**94.76%**; critical modules all **≥95%** branch).
|
|
24
|
+
- **agent-gates modularization:** thin facade (`bin/lib/agent-gates.mjs` ~100 LOC) re-exports
|
|
25
|
+
`gate-files`, `skill-install`, `ci-and-commands`, `mcp-adoption`, `install-migrate`,
|
|
26
|
+
`typescript-host`, `hook-templates`, `write-path-detect`, plus field/codex helpers.
|
|
27
|
+
`detectDeployPathQuality` extracted to `bin/lib/deploy-path.mjs` so `mcp-adoption.mjs` stays
|
|
28
|
+
under the 600 LOC module budget. Import hygiene on extract modules; `loadTypeScript` uses
|
|
29
|
+
`__arkCheckCli` for the nested arkgate TypeScript fallback.
|
|
30
|
+
- **Deny→repair CI proof:** `tests/unit/static-check/writePathDetect.test.ts` drives
|
|
31
|
+
shipped `bin/ark-mcp.mjs --hook --hook-repair` and asserts `ARK_REPAIR_JSON` /
|
|
32
|
+
`ARK_AUTOPATCH_JSON` on deny (exit 2); reject-only without repair flag still supported.
|
|
33
|
+
- **Dogfood write path repair:** local Claude/Grok hooks use `--hook-repair`; doctor
|
|
34
|
+
reports `writePath.mode = repair` on this tree.
|
|
35
|
+
- **Self-hosted AGENTS.md:** `--install-agent-gates --force` no longer overwrites library
|
|
36
|
+
mother-repo Identity (`skipped-self-hosted`).
|
|
37
|
+
- **hexagonal-order-api:** `safety.allowInMemory` for ephemeral demo kernel; prefer
|
|
38
|
+
`arkgate/runtime` imports; `npm run check` green under `--strict-config`.
|
|
39
|
+
- **multi-app / monorepo rules:** deny App→Persistence, Presentation→Domain, and
|
|
40
|
+
Persistence→Presentation (parity with crud-product starter).
|
|
41
|
+
- **Generated CI Node default lags local npm (again):** when a project had no
|
|
42
|
+
`.nvmrc` / `engines.node`, the Ark architecture gate workflow defaulted to
|
|
43
|
+
Node 22. Lockfiles written on Node 24/26 then failed `npm ci` with
|
|
44
|
+
"Missing: … from lock file" before `ark-check` ran — CI green, Ark red.
|
|
45
|
+
Detection order is now `.nvmrc` / `.node-version` → `engines.node` → **highest
|
|
46
|
+
`node-version` from sibling workflows** (excludes `ark-check.yml` so a stale
|
|
47
|
+
gate cannot re-pin itself) → default **24**. Refresh existing gates with
|
|
48
|
+
`ark-check --install-agent-gates --force` (or edit `node-version` in
|
|
49
|
+
`.github/workflows/ark-check.yml`).
|
|
50
|
+
|
|
51
|
+
### Changed
|
|
52
|
+
|
|
53
|
+
- **Hook templates extracted** to `bin/lib/hook-templates.mjs` (agent-gates seam).
|
|
54
|
+
- **Write-path detect extracted** to `bin/lib/write-path-detect.mjs` (doctor W5; re-exported
|
|
55
|
+
from agent-gates).
|
|
56
|
+
- **Coverage thresholds** raised to Q1 floors on the broad include set: statements/lines **≥80**,
|
|
57
|
+
branches/functions **≥85**, critical write/safety modules **≥95%** branch (see Fixed above).
|
|
58
|
+
- **`/ark-explore` skill:** decision-grade recon — field path (run starters/checks),
|
|
59
|
+
installed hooks vs install templates, coupling via fan-in/exports (not LOC alone),
|
|
60
|
+
ranked “así te lo re-soluciono” rows only when residual changes action; ENFORCE /
|
|
61
|
+
empty plan treated as baseline, not the story. **v2.1:** output modes (recon vs
|
|
62
|
+
dual-plan seed, no multi-week roadmaps by default); path-correct vs design-correct
|
|
63
|
+
+ semantic false-green; success signals and kill-switches on bets (anti-vanity).
|
|
64
|
+
- **`/ark-autopilot` skill:** explore-first (decision-grade), **dual plan** —
|
|
65
|
+
A remediation from `--plan` + B pattern/evolution bets (never auto-apply B as
|
|
66
|
+
mechanical-safe); empty plan no longer means “healthy” without explore/B.
|
|
67
|
+
- **Day-zero origin first:** `ark start` / `ark init` freeze `.ark/reports/origin.*`
|
|
68
|
+
immediately after `ark.config.json` exists and **before** agent docs, skills, and CI
|
|
69
|
+
templates. Later `--report` still shows evolution vs that snapshot.
|
|
70
|
+
|
|
7
71
|
## 2.11.0 — 2026-07-10
|
|
8
72
|
|
|
9
73
|
Fail-closed enforcement hardening: `--strict` now combines contract coverage, installed-gate
|
package/README.md
CHANGED
|
@@ -23,8 +23,8 @@ and makes sure a “green” check means something real.
|
|
|
23
23
|
If you remember nothing else:
|
|
24
24
|
|
|
25
25
|
```text
|
|
26
|
-
1. npx arkgate start ←
|
|
27
|
-
2. /ark-autopilot ←
|
|
26
|
+
1. npx arkgate start ← walk tree → contract → **day-zero origin** → gates
|
|
27
|
+
2. /ark-autopilot ← explore first, dual plan, safe fixes, leave gates on
|
|
28
28
|
3. npx arkgate-check --doctor ← “where am I?” anytime (one status screen)
|
|
29
29
|
```
|
|
30
30
|
|
|
@@ -106,7 +106,7 @@ Full checklist (CI, MCP, Codex, imports): **[docs/migrate-from-ark-runtime-kerne
|
|
|
106
106
|
|
|
107
107
|
```bash
|
|
108
108
|
npm install -D arkgate typescript
|
|
109
|
-
npx arkgate start #
|
|
109
|
+
npx arkgate start # contract → day-zero origin → gates + plan
|
|
110
110
|
# in agent:
|
|
111
111
|
# /ark-autopilot
|
|
112
112
|
npx arkgate-check --doctor # status light + next action
|
|
@@ -117,11 +117,13 @@ Aliases `ark` / `ark-check` / `ark-mcp` still work. **npm / pnpm / yarn**. No in
|
|
|
117
117
|
<details>
|
|
118
118
|
<summary>What <code>/ark-autopilot</code> does under the hood (optional detail)</summary>
|
|
119
119
|
|
|
120
|
-
1. Setup if needed (`ark start`).
|
|
121
|
-
2.
|
|
122
|
-
3.
|
|
123
|
-
4.
|
|
124
|
-
5. Gates on +
|
|
120
|
+
1. Setup if needed (`ark start` — contract, then **day-zero origin**, then gates).
|
|
121
|
+
2. **Explore pass** (decision-grade map of *this* product; field path when demos exist).
|
|
122
|
+
3. **Dual plan:** **A** remediation from `--plan` (mechanical-safe only by default); **B** pattern/evolution bets (never auto-applied as mechanical-safe). Empty plan ≠ “healthy” without explore/B.
|
|
123
|
+
4. Apply A → re-check; judgment only when you ask for full apply.
|
|
124
|
+
5. Gates on + latest report (evolution vs frozen origin).
|
|
125
|
+
|
|
126
|
+
Standalone recon without applying: `/ark-explore`.
|
|
125
127
|
|
|
126
128
|
</details>
|
|
127
129
|
|
|
@@ -188,11 +190,14 @@ ark.config.json
|
|
|
188
190
|
- **Presets:** hexagonal, layered, feature-sliced, monorepo, ui-surface, vertical-slice, ddd-bounded-contexts (+ aliases clean-architecture / onion-architecture). Layers start optional; doctor suggests tightening populated cores. Cross-slice / cross-context bans use optional `peerIsolation` rules.
|
|
189
191
|
- **Frameworks:** Nest / Next / express / library layouts get sensible globs on init so day-one coverage is real.
|
|
190
192
|
- **Brownfield:** baseline ratchet, refuse to freeze a wrong contract, `/ark-adopt` for mature trees.
|
|
191
|
-
- **Agents:** skills install into Claude / Cursor / Codex / Grok; `ark start` freezes
|
|
193
|
+
- **Agents:** skills install into Claude / Cursor / Codex / Grok; `ark start` freezes **day-zero origin** under `.ark/reports/` **before** agent docs/CI templates.
|
|
192
194
|
- **Write protocol (2.10 / Track W):** mechanical-safe **autoPatch** on the write gate (`import type`); MCP **`ark_prepare_write`** (place + validate + patch + judgmentBrief); opt-in hook **`--hook-repair`** (`ARK_REPAIR_JSON`); doctor **`writePath`** (repair vs reject-only); loop-cost eval (`npm run eval:loop-cost`). Port-proof inject is **judgment** (arity change), not silent auto-apply.
|
|
193
195
|
- **Fail-closed CI (2.11):** `--strict` combines config coverage, required CI/MCP/write gates,
|
|
194
196
|
PreToolUse hook presence, and bypass diagnostics for dynamic imports, TypeScript suppressions,
|
|
195
197
|
explicit `any` casts, InMemory runtime defaults, and disabled peer isolation.
|
|
198
|
+
- **Trust / coverage (2.12):** package unit-test floors on the broad product surface
|
|
199
|
+
(statements/lines **≥80%**, branches/functions **≥85%**; enforcement-critical modules **≥95%**
|
|
200
|
+
branch). Explore dual-plan + day-zero origin first (see above). Roadmap next: Q2 repair dogfood matrix.
|
|
196
201
|
- **TypeScript:** project compilers 5.x / 6.x / 7.x — gate falls back to a nested JS-API TypeScript when TS 7’s main export is version-only ([docs/typescript-support.md](docs/typescript-support.md)).
|
|
197
202
|
|
|
198
203
|
### Why not only ESLint / dependency-cruiser / Nx?
|
|
@@ -214,7 +219,7 @@ ark.config.json
|
|
|
214
219
|
## Common commands
|
|
215
220
|
|
|
216
221
|
```bash
|
|
217
|
-
npx arkgate start # guided setup
|
|
222
|
+
npx arkgate start # guided setup: contract → origin → gates → plan
|
|
218
223
|
npx arkgate-check --doctor # health + Adoption gaps (not just fitness)
|
|
219
224
|
npx arkgate-check --doctor --json # machine-readable doctor.adoption
|
|
220
225
|
npx arkgate-check --strict # fail-closed CI + installed-gate/safety checks
|
package/bin/ark.mjs
CHANGED
|
@@ -23,6 +23,32 @@ import { pinArkgateDevDependency, FALSE_GREEN_GAP_ID } from './lib/field-install
|
|
|
23
23
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
24
24
|
const arkCheck = path.join(here, 'ark-check.mjs');
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Day-zero architecture picture: freeze origin under `.ark/reports/` as soon as
|
|
28
|
+
* `ark.config.json` exists — **before** agent docs, skills, CI templates, or cleanups.
|
|
29
|
+
* Idempotent: origin is written only once (`--report` archive semantics).
|
|
30
|
+
*/
|
|
31
|
+
function freezeDayZeroOrigin(root) {
|
|
32
|
+
const configPath = path.join(root, 'ark.config.json');
|
|
33
|
+
if (!fs.existsSync(configPath)) {
|
|
34
|
+
console.log(
|
|
35
|
+
` Skip origin freeze — no ark.config.json yet. After init: ${arkCommand(root, 'ark-check', '--report ark-report.html')}`
|
|
36
|
+
);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const originJson = path.join(root, '.ark', 'reports', 'origin.json');
|
|
40
|
+
const already = fs.existsSync(originJson);
|
|
41
|
+
console.log(
|
|
42
|
+
already
|
|
43
|
+
? 'Architecture origin already frozen (.ark/reports/origin.*) — leaving it untouched.'
|
|
44
|
+
: 'Freezing day-zero architecture picture (origin) before agent docs / gates…'
|
|
45
|
+
);
|
|
46
|
+
runArkCheck(
|
|
47
|
+
['--root', root, '--config', 'ark.config.json', '--report', 'ark-report.html'],
|
|
48
|
+
{ cwd: root }
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
26
52
|
function parseArgs(argv) {
|
|
27
53
|
const args = {
|
|
28
54
|
command: undefined,
|
|
@@ -330,6 +356,10 @@ async function init(args) {
|
|
|
330
356
|
console.log('Skipped ark.config.json generation.');
|
|
331
357
|
}
|
|
332
358
|
|
|
359
|
+
// Origin first: contract-on-tree picture before AGENTS.md / skills / CI templates.
|
|
360
|
+
console.log('');
|
|
361
|
+
freezeDayZeroOrigin(root);
|
|
362
|
+
|
|
333
363
|
const installGates =
|
|
334
364
|
nonInteractive || (await askYesNo(rl, 'Configure agent and CI gate templates?', true));
|
|
335
365
|
if (installGates) {
|
|
@@ -357,7 +387,7 @@ async function init(args) {
|
|
|
357
387
|
console.log(`Shape: ${archetype}. Plan: ${arkCommand(root, 'ark-check', '--recommend')}`);
|
|
358
388
|
}
|
|
359
389
|
console.log(
|
|
360
|
-
`
|
|
390
|
+
`Day-zero origin: .ark/reports/origin.* (frozen once; later --report shows evolution vs origin).`
|
|
361
391
|
);
|
|
362
392
|
console.log(`Adoption health: ${arkCommand(root, 'ark-check', '--doctor')}`);
|
|
363
393
|
return 0;
|
|
@@ -381,9 +411,11 @@ async function start(args) {
|
|
|
381
411
|
try {
|
|
382
412
|
console.log("Let's set up Ark for your project.");
|
|
383
413
|
console.log(
|
|
384
|
-
"I'll
|
|
414
|
+
"I'll walk the tree, freeze a day-zero architecture picture, then set up guardrails and show a plan."
|
|
415
|
+
);
|
|
416
|
+
console.log(
|
|
417
|
+
'Nothing in your product code is changed — only Ark config, then origin snapshot, then agent/CI templates.'
|
|
385
418
|
);
|
|
386
|
-
console.log('Nothing in your code is changed — this only adds Ark configuration.');
|
|
387
419
|
if (nonInteractive && !args.yes) {
|
|
388
420
|
console.log(
|
|
389
421
|
'Non-interactive session (no TTY) — using guided defaults (same as --yes). Pass flags to override.'
|
|
@@ -440,10 +472,10 @@ async function start(args) {
|
|
|
440
472
|
console.log(' Skipping arkgate package pin (--no-install).');
|
|
441
473
|
}
|
|
442
474
|
|
|
443
|
-
// 3)
|
|
444
|
-
// so the contract anchors to
|
|
475
|
+
// 3) Contract first (config only). Greenfield → shape preset; established repo → detection,
|
|
476
|
+
// so the contract anchors to directories you already have instead of aspirational globs.
|
|
445
477
|
console.log('');
|
|
446
|
-
console.log('Setting up Ark…');
|
|
478
|
+
console.log('Setting up Ark contract…');
|
|
447
479
|
const configPath = path.join(root, 'ark.config.json');
|
|
448
480
|
if (!fs.existsSync(configPath)) {
|
|
449
481
|
const initArgs = ['--root', root, '--init'];
|
|
@@ -482,6 +514,15 @@ async function start(args) {
|
|
|
482
514
|
} else {
|
|
483
515
|
console.log(' Found an existing ark.config.json — keeping it.');
|
|
484
516
|
}
|
|
517
|
+
|
|
518
|
+
// 4) Day-zero origin — freeze the architecture picture *before* agent docs / CI / skills.
|
|
519
|
+
// Later --report runs show evolution vs this snapshot. Idempotent (origin once).
|
|
520
|
+
console.log('');
|
|
521
|
+
freezeDayZeroOrigin(root);
|
|
522
|
+
|
|
523
|
+
// 5) Agent + CI gate templates (docs, hooks, skills) — after origin is frozen.
|
|
524
|
+
console.log('');
|
|
525
|
+
console.log('Installing agent and CI gate templates…');
|
|
485
526
|
{
|
|
486
527
|
const gateArgs = ['--root', root, '--install-agent-gates'];
|
|
487
528
|
if (args.tools) gateArgs.push('--tools', args.tools);
|
|
@@ -489,7 +530,7 @@ async function start(args) {
|
|
|
489
530
|
runArkCheck(gateArgs, { cwd: root });
|
|
490
531
|
}
|
|
491
532
|
|
|
492
|
-
//
|
|
533
|
+
// 6) Show the plan: what's safe to auto-fix vs what needs a decision.
|
|
493
534
|
console.log('');
|
|
494
535
|
console.log('Your architecture plan:');
|
|
495
536
|
runArkCheck(['--root', root, '--config', 'ark.config.json', '--plan'], { cwd: root });
|
|
@@ -571,7 +612,7 @@ async function start(args) {
|
|
|
571
612
|
planOk = false;
|
|
572
613
|
}
|
|
573
614
|
|
|
574
|
-
//
|
|
615
|
+
// 7) Plain-language wrap-up — one next step, status light only.
|
|
575
616
|
// Modes are detected (Suggest/Adapt/Enforce), not user-picked settings.
|
|
576
617
|
// Soft-block false-green using the same doctor adoption gap (no second detector).
|
|
577
618
|
let falseGreenGap = null;
|
|
@@ -620,7 +661,7 @@ async function start(args) {
|
|
|
620
661
|
console.log(' → reclassify I/O dirs out of Application; then /ark-autopilot for residual debt.');
|
|
621
662
|
} else {
|
|
622
663
|
console.log(' 1. In your agent: /ark-autopilot');
|
|
623
|
-
console.log(' →
|
|
664
|
+
console.log(' → explore first, dual plan (remediation + pattern bets), safe fixes, leave gates on.');
|
|
624
665
|
}
|
|
625
666
|
console.log(` 2. Status anytime: ${arkCommand(root, 'ark-check', '--doctor')}`);
|
|
626
667
|
console.log(` 3. After edits: ${arkCommand(root, 'ark-check', '--root . --config ark.config.json --strict-config')}`);
|
|
@@ -630,16 +671,8 @@ async function start(args) {
|
|
|
630
671
|
);
|
|
631
672
|
}
|
|
632
673
|
console.log('');
|
|
633
|
-
console.log('
|
|
634
|
-
|
|
635
|
-
// 6) First architecture report — freezes an origin snapshot under .ark/reports/
|
|
636
|
-
// so later --report runs can show evolution. Idempotent: origin is written only once.
|
|
637
|
-
console.log('');
|
|
638
|
-
console.log('Capturing architecture report (origin snapshot on first run)…');
|
|
639
|
-
runArkCheck(
|
|
640
|
-
['--root', root, '--config', 'ark.config.json', '--report', 'ark-report.html'],
|
|
641
|
-
{ cwd: root }
|
|
642
|
-
);
|
|
674
|
+
console.log('Day-zero origin is under .ark/reports/origin.* — re-run --report later for evolution.');
|
|
675
|
+
console.log('Optional later: --plan · --coverage · /ark-explore · /ark-fix · /ark-place · ark upgrade');
|
|
643
676
|
return 0;
|
|
644
677
|
} finally {
|
|
645
678
|
rl?.close();
|