arkgate 4.8.15 → 4.8.16

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 (63) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +7 -5
  3. package/bin/ark-shared.mjs +2 -0
  4. package/bin/ark.mjs +17 -8
  5. package/bin/lib/analysis-engine.mjs +5 -5
  6. package/bin/lib/architecture-scan.mjs +17 -0
  7. package/bin/lib/baseline-key.mjs +2 -0
  8. package/bin/lib/config-contract.mjs +1 -1
  9. package/bin/lib/diagnostic-catalog.mjs +2 -0
  10. package/bin/lib/doctor-advisories.mjs +26 -0
  11. package/bin/lib/doctor-green-cite.mjs +139 -0
  12. package/bin/lib/doctor-human.mjs +98 -63
  13. package/bin/lib/doctor-next-actions.mjs +9 -0
  14. package/bin/lib/doctor-plan.mjs +6 -3
  15. package/bin/lib/field-install.mjs +47 -7
  16. package/bin/lib/first-run-help.mjs +1 -0
  17. package/bin/lib/improvement-compass-doctor.mjs +3 -1
  18. package/bin/lib/improvement-compass-map.mjs +3 -1
  19. package/bin/lib/invariant-coverage.mjs +121 -0
  20. package/bin/lib/invariant-tests-path.mjs +212 -0
  21. package/bin/lib/package-manager.mjs +8 -0
  22. package/bin/lib/prototype-shortcuts.mjs +224 -0
  23. package/bin/lib/remediation.mjs +11 -0
  24. package/bin/lib/start-preview.mjs +20 -1
  25. package/dist/{configTypes-Dt3DpVbd.d.ts → configTypes-VD0qcubY.d.ts} +2 -1
  26. package/dist/{diagnosticCatalog-BEg85XlE.d.ts → diagnosticCatalog-KWvGLI1U.d.ts} +24 -3
  27. package/dist/eslint/index.cjs +4 -4
  28. package/dist/eslint/index.d.ts +1 -1
  29. package/dist/eslint/index.js +4 -4
  30. package/dist/index.cjs +31 -31
  31. package/dist/index.d.ts +5 -5
  32. package/dist/index.js +31 -31
  33. package/dist/nestjs/index.cjs +1 -1
  34. package/dist/nestjs/index.d.ts +3 -3
  35. package/dist/nestjs/index.js +1 -1
  36. package/dist/runtime/index.cjs +10 -10
  37. package/dist/runtime/index.d.ts +6 -6
  38. package/dist/runtime/index.js +10 -10
  39. package/dist/{types-TBiv0WHL.d.ts → types-BSzRy2X1.d.ts} +1 -1
  40. package/dist/{types-CN9tVMPz.d.ts → types-D5GT5ZT8.d.ts} +1 -1
  41. package/docs/README.md +1 -1
  42. package/docs/agent-guide.md +2 -0
  43. package/docs/configuration.md +11 -3
  44. package/docs/develop.md +3 -1
  45. package/docs/diagnostics.md +25 -1
  46. package/docs/package-surface.md +1 -1
  47. package/docs/use.md +5 -3
  48. package/package.json +1 -1
  49. package/schemas/ark.config.schema.json +1 -1
  50. package/server.json +2 -2
  51. package/templates/agent-skills/README.md +1 -1
  52. package/templates/agent-skills/ark-adopt/SKILL.md +15 -0
  53. package/templates/agent-skills/ark-autopilot/SKILL.md +6 -1
  54. package/templates/agent-skills/ark-coverage/SKILL.md +1 -1
  55. package/templates/agent-skills/ark-explain/SKILL.md +2 -1
  56. package/templates/agent-skills/ark-explore/SKILL.md +19 -0
  57. package/templates/agent-skills/ark-place/SKILL.md +4 -0
  58. package/templates/skills/ark-adopt.md +15 -0
  59. package/templates/skills/ark-autopilot.md +6 -1
  60. package/templates/skills/ark-coverage.md +1 -1
  61. package/templates/skills/ark-explain.md +2 -1
  62. package/templates/skills/ark-explore.md +19 -0
  63. package/templates/skills/ark-place.md +4 -0
@@ -1,4 +1,4 @@
1
- import { i as Policy, P as PolicyViolation, I as IntentName, j as IntentCreator, k as IntentRelationship, b as ArchitectureProfile, D as DomainEvent, E as EventMetadata, h as PolicyEnforcementMode, A as ArchitectureLayer, c as ArchitectureRule, d as ArkCheckConfig } from './types-CN9tVMPz.js';
1
+ import { i as Policy, P as PolicyViolation, I as IntentName, j as IntentCreator, k as IntentRelationship, b as ArchitectureProfile, D as DomainEvent, E as EventMetadata, h as PolicyEnforcementMode, A as ArchitectureLayer, c as ArchitectureRule, d as ArkCheckConfig } from './types-D5GT5ZT8.js';
2
2
 
3
3
  /**
4
4
  * PolicyEngine
@@ -1,4 +1,4 @@
1
- import { a as ArkConfigRule, f as ArkConfigLayer, A as ArkConfig } from './configTypes-Dt3DpVbd.js';
1
+ import { a as ArkConfigRule, f as ArkConfigLayer, A as ArkConfig } from './configTypes-VD0qcubY.js';
2
2
 
3
3
  /**
4
4
  * Policy types for the Ark kernel.
package/docs/README.md CHANGED
@@ -73,7 +73,7 @@ These are **not** the day-to-day product path. They stay in the repo for evidenc
73
73
  | Field adoption kit (scaffolding, not closed) | [field/](field/) |
74
74
  | Runtime hardening (experimental) | [production-hardening.md](production-hardening.md) |
75
75
 
76
- Prepared: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.15`; not published until `publish-npm` for `v4.8.15`).
76
+ Prepared: [CHANGELOG](../CHANGELOG.md) (`arkgate@4.8.16`; not published until `publish-npm` for `v4.8.16`).
77
77
  Current published: [releases/4.8.11.md](releases/4.8.11.md) (`arkgate@4.8.11` on npm `latest`; does not close `K01`).
78
78
  Prior published: [releases/4.8.10.md](releases/4.8.10.md) (`arkgate@4.8.10`).
79
79
  Prior published: [releases/4.8.9.md](releases/4.8.9.md) (`arkgate@4.8.9`).
@@ -120,6 +120,8 @@ npx ark report --submit --i-confirm-submit
120
120
 
121
121
  `--doctor --json` is a stable envelope (4.6.5+): `{ "schemaVersion": "1.0", "envelope": "doctor", "ok": boolean, "doctor": { … } }`.
122
122
  Payload lives only under `doctor`. Do not parse sibling root keys as the doctor object.
123
+ A green or Healthy line names a file, config key, or test so a stranger can
124
+ check it in about a minute. Uncited green is not honest — treat it as unfinished.
123
125
 
124
126
  Doctor also writes `.ark/ci-merge-boundary.json` (hook configured-not-fired, per-host writePath,
125
127
  CI present-but-not-required, GitHub Free cannot require). Read that file — do not grep `node_modules`.
@@ -89,7 +89,14 @@ Top-level fields:
89
89
  - **`coverage`** (optional) — invariant-coverage scan controls: `testGlobs` (globs that decide
90
90
  which files count as tests, replacing the built-in `*.test.*` / `tests/` name heuristic),
91
91
  `maxFiles` (evidence file budget, default `400`) and `coverageRoots` (path prefixes where the
92
- project declares its runner actually executes tests). Absence is silent and changes no verdict.
92
+ project declares its runner actually executes tests). Absence is silent unless the tree is
93
+ **adopted** (required CI or `.ark/adoption-stance.json` advisory-only) **and** the catalog
94
+ has domain invariants that want test evidence (`coverage.test` is not `false`) —
95
+ then a missing or empty tests path fails closed
96
+ (`INVARIANT_TESTS_PATH_MISSING`). Either `testGlobs` or `coverageRoots` satisfies the path.
97
+ When any catalogued invariant is **enforced**, `coverage.coverageRoots` is required
98
+ (`INVARIANT_COVERAGE_ROOTS_MISSING`) — `testGlobs` alone is not enough. Silent when no
99
+ invariant is enforced.
93
100
  Unknown keys fail closed. **`maxFiles` also bounds structural-hint preload** for
94
101
  `orchestration-only`, `thin-adapter`, and `writes-via-aggregate` (the hint loader reuses
95
102
  coverage contents when present). There is no separate `arkrules.hintBudget`. When eligible
@@ -117,8 +124,9 @@ Top-level fields:
117
124
  the invariant just as well as one that runs. Declaring `coverageRoots` gives ArkGate a second
118
125
  declaration to compare the first against: when the only covering test falls outside them, it
119
126
  reports `INVARIANT_COVERAGE_OUTSIDE_ROOTS` (advisory) and refuses to promote that invariant to
120
- `enforced`. Declaring nothing keeps the old silence — without a declaration there is nothing to
121
- compare, and ArkGate makes no claim about where tests run.
127
+ `enforced`. Declaring nothing stays silent unless any invariant is already enforced — then
128
+ missing roots fail closed (`INVARIANT_COVERAGE_ROOTS_MISSING`), because otherwise coverage can
129
+ certify a test the project never declared a runner root for.
122
130
  - **`arkRules`** (optional, schema `1.1+`) — map of layer name → project-relative path to an
123
131
  ArkRules file (e.g. `"DomainModel": "arkrules/DomainModel.json"`). Keys must match a declared
124
132
  layer. Missing/invalid referenced files **fail closed**.
package/docs/develop.md CHANGED
@@ -37,9 +37,11 @@ ArkGate solves this by shifting the check to the exact moment of writing. By int
37
37
  ```bash
38
38
  npm install -D arkgate typescript
39
39
  npx arkgate start --apply
40
- npx arkgate-check --doctor
40
+ npx --package=arkgate arkgate-check --doctor
41
41
  ```
42
42
 
43
+ `arkgate-check` is a command in the `arkgate` package. After a local install, `npx arkgate-check --doctor` also works.
44
+
43
45
  Make the import-rules check a **required** merge **status context** (GitHub/GitLab/etc.). The CLI
44
46
  command is `arkgate-check --strict-merge` / `ark-check --strict-merge` — the hard boundary is
45
47
  requiring that job’s status, not merely adding a workflow file:
@@ -47,6 +47,8 @@ Link form for agents: `docs/diagnostics.md#RULE_ID` (exact-case HTML anchors bel
47
47
  | [`INVARIANT_CATALOG_EMPTY`](#INVARIANT_CATALOG_EMPTY) | arkrules | Domain invariant catalog is empty |
48
48
  | [`INVARIANT_UNCOVERED`](#INVARIANT_UNCOVERED) | arkrules | Invariant without coverage evidence |
49
49
  | [`INVARIANT_COVERAGE_OUTSIDE_ROOTS`](#INVARIANT_COVERAGE_OUTSIDE_ROOTS) | arkrules | Covering test outside the declared coverage roots |
50
+ | [`INVARIANT_COVERAGE_ROOTS_MISSING`](#INVARIANT_COVERAGE_ROOTS_MISSING) | arkrules | Coverage roots missing while an invariant is enforced |
51
+ | [`INVARIANT_TESTS_PATH_MISSING`](#INVARIANT_TESTS_PATH_MISSING) | arkrules | Domain-invariant tests path missing under adopted |
50
52
  | [`ARKRUN_MISSING_ROOT`](#ARKRUN_MISSING_ROOT) | arkrun | No kernel factory in composition roots |
51
53
  | [`ARKRUN_KERNEL_IN_DOMAIN`](#ARKRUN_KERNEL_IN_DOMAIN) | arkrun | Domain-role layer imports the kernel |
52
54
  | [`ARKRUN_DIRECT_NEW`](#ARKRUN_DIRECT_NEW) | arkrun | Managed type constructed with new |
@@ -318,7 +320,29 @@ Link form for agents: `docs/diagnostics.md#RULE_ID` (exact-case HTML anchors bel
318
320
  - **Why:** The only test naming this invariant sits outside `coverage.coverageRoots` — the places the project declares its runner executes. ArkGate matches declared text and never executes tests, so it cannot tell whether that file is ever run: coverage there is a test that *exists*, not a test that *runs*.
319
321
  - **Fix:** Move the test under a declared coverage root, or add its root to `coverage.coverageRoots` in ark.config.json. Advisory: it never fails strict, but promotion to enforced refuses on it.
320
322
 
321
- Declaring nothing is silent — without `coverage.coverageRoots` there is no second declaration to compare against, and ArkGate makes no claim about where tests run.
323
+ Declaring nothing is silent unless any catalogued invariant is enforced — then missing roots fail closed (`INVARIANT_COVERAGE_ROOTS_MISSING`). Without `coverage.coverageRoots` there is no second declaration to compare against, and ArkGate makes no claim about where tests run.
324
+
325
+ <a id="INVARIANT_COVERAGE_ROOTS_MISSING"></a>
326
+
327
+ ### `INVARIANT_COVERAGE_ROOTS_MISSING`
328
+
329
+ **Coverage roots missing while an invariant is enforced**
330
+
331
+ - **Why:** A catalogued domain invariant is enforced, but `ark.config.json` does not name `coverage.coverageRoots` — the folders where the project says its test runner actually goes. Without that declaration, `INVARIANT_COVERAGE_OUTSIDE_ROOTS` cannot fire and coverage can certify a test no runner runs.
332
+ - **Fix:** Add `coverage.coverageRoots` in `ark.config.json` pointing at the folder the test runner uses, then re-run. `testGlobs` alone is not enough. Fail-closed until that path is present. Not freezable.
333
+
334
+ No enforced invariant, or roots already declared, stays silent. This is not a new config key. Promotion to enforced also refuses without roots.
335
+
336
+ <a id="INVARIANT_TESTS_PATH_MISSING"></a>
337
+
338
+ ### `INVARIANT_TESTS_PATH_MISSING`
339
+
340
+ **Domain-invariant tests path missing under adopted**
341
+
342
+ - **Why:** The project is adopted (required CI or explicit advisory) and has domain invariants that want test evidence, but `ark.config.json` does not name where those tests live. Green coverage without a real tests path is an empty checkbox.
343
+ - **Fix:** Add `coverage.testGlobs` or `coverage.coverageRoots` in `ark.config.json` pointing at a real tests folder, then re-run. Adopted mode fails closed until that path is present. Not freezable.
344
+
345
+ Not adopted, no catalogued invariants, or every invariant sets `coverage.test: false`, stays silent. This is not a new config key.
322
346
 
323
347
  ## ArkRun (opt-in extra)
324
348
 
@@ -39,7 +39,7 @@ hardening guide remains repository-hosted rather than duplicated in the gate tar
39
39
 
40
40
  | Surface | How you use it | Stability notes |
41
41
  |---------|----------------|-----------------|
42
- | **CLI** | `arkgate` / `arkgate-check` (aliases `ark` / `ark-check`); optional ArkRun **`ark-dashboard`** / **`arkgate-dashboard`** | Flags and human text may improve; **JSON output shapes** for `--json` (check, doctor, plan, coverage, recommend, **status**, **agents-md**, **report**) are stable within a major. Additive fields OK; removals/renames are major. From 4.2, `--require-gates` implies strict config and verifies semantic Ark AGENTS, project-rooted MCP/compact Codex registration, and fail-closed CI rather than file presence alone. Soft ADR presence: when that demand (or doctor `required-merge`) is on and `docs/adr/` / `docs/decisions/` is missing, doctor JSON may add `adrPresence` and human copy points at a short decision note — never a fail, omitted when the demand is off. Soft states/transitions: when a conventional domain doc is already in play and the map is missing or heading-only, doctor JSON may add `statesTransitions` and human copy points at a short table (or one link) — never a fail, omitted when that doc is absent. Narrow status/transition catalog: when Domain-role code already names a closed status/state vocabulary and that map is still thin, doctor JSON may add `statusTransitionCatalog` with those names — never a fail, omitted when Domain has no such vocabulary, the domain doc is absent, or the map is already present. Soft no-Domain / UI-logic residual: when a Domain-role layer is declared but empty and presentation holds the tree (or `domain-logic-in-ui` is already present), doctor JSON may add `noDomainFrontend` and human copy points at one Domain file — never a fail, omitted when there is no frontend, Domain already has files, or the UI bag is too thin. `ark status --json` is the unified status snapshot. `ark agents-md` is the version-matched agent projection (non-authoritative). **`arkgate report` / `ark report`** drafts an upstream GitHub issue for `pedroknigge/arkgate` (`package.json` `bugs.url`) — never the consumer repo. **Dashboard bins** poll an ArkRun inspector snapshot (ANSI + interval polling; `--url` / `--interval`); they are not a gate verdict. The main CLI also accepts `ark dashboard` / `arkgate dashboard` as a passthrough to those bins. |
42
+ | **CLI** | `arkgate` / `arkgate-check` (aliases `ark` / `ark-check`); optional ArkRun **`ark-dashboard`** / **`arkgate-dashboard`** | Flags and human text may improve; **JSON output shapes** for `--json` (check, doctor, plan, coverage, recommend, **status**, **agents-md**, **report**) are stable within a major. Additive fields OK; removals/renames are major. From 4.2, `--require-gates` implies strict config and verifies semantic Ark AGENTS, project-rooted MCP/compact Codex registration, and fail-closed CI rather than file presence alone. Soft ADR presence: when that demand (or doctor `required-merge`) is on and `docs/adr/` / `docs/decisions/` is missing, doctor JSON may add `adrPresence` and human copy points at a short decision note — never a fail, omitted when the demand is off. Soft states/transitions: when a conventional domain doc is already in play and the map is missing or heading-only, doctor JSON may add `statesTransitions` and human copy points at a short table (or one link) — never a fail, omitted when that doc is absent. Narrow status/transition catalog: when Domain-role code already names a closed status/state vocabulary and that map is still thin, doctor JSON may add `statusTransitionCatalog` with those names — never a fail, omitted when Domain has no such vocabulary, the domain doc is absent, or the map is already present. Soft no-Domain / UI-logic residual: when a Domain-role layer is declared but empty and presentation holds the tree (or `domain-logic-in-ui` is already present), doctor JSON may add `noDomainFrontend` and human copy points at one Domain file — never a fail, omitted when there is no frontend, Domain already has files, or the UI bag is too thin. Soft prototype-shortcut residual: when a Persistence-role layer is declared and SQLite or a JSON-file store lives outside it, or Domain / an auth tag is declared and admin / god-mode literals sit outside that house, doctor JSON may add `prototypeShortcuts` and human copy points at one Persistence adapter or Domain policy file — never a fail, omitted when those houses are absent, the shortcut is already in the right house, or there are no such markers. `ark status --json` is the unified status snapshot. `ark agents-md` is the version-matched agent projection (non-authoritative). **`arkgate report` / `ark report`** drafts an upstream GitHub issue for `pedroknigge/arkgate` (`package.json` `bugs.url`) — never the consumer repo. **Dashboard bins** poll an ArkRun inspector snapshot (ANSI + interval polling; `--url` / `--interval`); they are not a gate verdict. The main CLI also accepts `ark dashboard` / `arkgate dashboard` as a passthrough to those bins. |
43
43
  | **Upstream report CLI (4.8.10)** | `arkgate report` / `ark report` on the existing dual bins (no new bin, no new skill) | Default prints a draft for **upstream** `pedroknigge/arkgate` (`package.json` `bugs.url`) with the arkgate version and optional last-check snippet. Create only with `--submit` **and** `--i-confirm-submit` (after HITL) or TTY `Type submit to send`. `--yes` does not submit. Missing/unauthenticated `gh`: print the draft plus the exact `gh issue create --repo pedroknigge/arkgate` command, exit 2. Never files against the consumer repo. Not `ark-check --report` (HTML architecture report). |
44
44
  | **Host write boundaries** | Generated trusted PreToolUse/preToolUse hooks + `ark-mcp --hook`; inspect with doctor/status | Hard is always operation-scoped and runtime-evidenced. From 4.6.3, Codex CLI and local ChatGPT Desktop/App Server can hard-block a complete `apply_patch` sent as `tool_input.command`; `.codex/hooks.json` on disk remains unverified until a fresh covered invocation. Hosted tools, specialized hook opt-outs, shell/direct writes, incomplete reconstruction, and humans rely on required CI. Repair envelopes may emit, but Codex reinjection is not guaranteed. |
45
45
  | **Programmatic gate API** | `import { analyzeProject, loadContract, createAICodeGate, ... } from 'arkgate'` | The root export is the static gate/config/analysis contract listed below. It intentionally contains no runtime-kernel implementation. |
package/docs/use.md CHANGED
@@ -27,10 +27,12 @@ For **anyone** shipping TypeScript with an AI coding agent.
27
27
  npm install -D arkgate typescript
28
28
  npx arkgate start # preview what will change
29
29
  npx arkgate start --apply # install compact config + host router + CI; merge write-path gates into existing AGENTS.md / .mcp.json
30
- npx arkgate-check --doctor # status — one next step
31
- npx arkgate-check --doctor --all # full details
30
+ npx --package=arkgate arkgate-check --doctor # status — one next step
31
+ npx --package=arkgate arkgate-check --doctor --all # full details
32
32
  ```
33
33
 
34
+ `arkgate-check` is a command in the `arkgate` package, not its own npm package. After a local install, `npx arkgate-check --doctor` also works.
35
+
34
36
  `start --apply` refuses when projected governed coverage is below 50% or
35
37
  shape confidence is weak (below 0.6 with coverage under 80%). That lock is
36
38
  deliberate. Lock the shape with `--archetype <id>`, `--preset <name>`, or
@@ -40,7 +42,7 @@ Then keep working with your agent. Stuck? Run `--doctor` and do action **#1**. C
40
42
 
41
43
  | Stuck on… | Do this |
42
44
  |-----------|---------|
43
- | Unsure | `npx arkgate-check --doctor` |
45
+ | Unsure | `npx --package=arkgate arkgate-check --doctor` |
44
46
  | Agent broke architecture | Fix the edge doctor names (or re-run check) |
45
47
  | Code is green but still a mess | Leftover design work — see below |
46
48
  | New ArkGate version | Follow doctor / upgrade guidance |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkgate",
3
- "version": "4.8.15",
3
+ "version": "4.8.16",
4
4
  "description": "When the agent writes a bad import, the write doesn’t land. The same check fails the pull request.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -858,7 +858,7 @@
858
858
  "coverage": {
859
859
  "type": "object",
860
860
  "additionalProperties": false,
861
- "description": "Invariant coverage scan controls. testGlobs replaces the built-in test-name heuristic; maxFiles raises or lowers the evidence file budget and also bounds structural-hint preload for orchestration-only, thin-adapter, and writes-via-aggregate (default 400; there is no arkrules.hintBudget); coverageRoots declares where the project runs its tests, so a covering test found outside them is reported instead of silently certifying an invariant.",
861
+ "description": "Invariant coverage scan controls. testGlobs replaces the built-in test-name heuristic; maxFiles raises or lowers the evidence file budget and also bounds structural-hint preload for orchestration-only, thin-adapter, and writes-via-aggregate (default 400; there is no arkrules.hintBudget); coverageRoots declares where the project runs its tests, so a covering test found outside them is reported instead of silently certifying an invariant. When any invariant is enforced, missing coverageRoots fails closed.",
862
862
  "properties": {
863
863
  "testGlobs": {
864
864
  "type": "array",
package/server.json CHANGED
@@ -6,12 +6,12 @@
6
6
  "url": "https://github.com/pedroknigge/arkgate",
7
7
  "source": "github"
8
8
  },
9
- "version": "4.8.15",
9
+ "version": "4.8.16",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "arkgate",
14
- "version": "4.8.15",
14
+ "version": "4.8.16",
15
15
  "runtimeHint": "npx",
16
16
  "transport": {
17
17
  "type": "stdio"
@@ -9,7 +9,7 @@ closed `/ark-*` catalog shipped as flat templates for Ark install.
9
9
  **Closed catalog** (`ARK_SKILL_NAMES`) — first-class doors plus one-release
10
10
  redirect stubs. Add a name only with a live ROADMAP item.
11
11
 
12
- Package version when last generated context: **arkgate@4.8.15**
12
+ Package version when last generated context: **arkgate@4.8.16**
13
13
  Schema: agent-skills package contract `1.0`
14
14
 
15
15
  ## Skills (closed catalog)
@@ -48,6 +48,21 @@ has honest houses. Skills never enforce — CLI / hooks / CI do.
48
48
  delete it to “clean” empty layers. Next is one Domain file (`/ark-place`), not
49
49
  a weaker contract. Soft. Silent when there is no frontend or Domain already
50
50
  has files. No `/ark-domain`.
51
+ - When doctor JSON has `prototypeShortcuts`, keep the Persistence / Domain
52
+ house — do not delete it to “clean” empty layers. Next is one Persistence
53
+ adapter or Domain policy file (`/ark-place`), not a weaker contract. Soft.
54
+ Silent when those houses are absent or the shortcut is already in the right
55
+ house. No `/ark-prototype`.
56
+ - When the tree is adopted and doctor JSON has `invariantTestsPath` (or the
57
+ check names `INVARIANT_TESTS_PATH_MISSING`), write `coverage.testGlobs` or
58
+ `coverage.coverageRoots` to a real tests folder. Fail-closed until that path
59
+ exists. Silent when not adopted, the catalog is empty, or every invariant
60
+ sets coverage.test false. No new skill.
61
+ - When any invariant is enforced and doctor JSON has `invariantCoverageRoots`
62
+ (or the check names `INVARIANT_COVERAGE_ROOTS_MISSING`), write
63
+ `coverage.coverageRoots` to the folder the test runner uses. Fail-closed
64
+ until that path exists. `coverage.testGlobs` alone is not enough. Silent
65
+ when no invariant is enforced. No new skill.
51
66
  - CLI-first: if `arkgate-check` already resolved the root, do not wait on MCP.
52
67
  - Do not add `arkRun` or `arkOrder` unless the user wants that extra. When they do, write
53
68
  **advisory** extra in this turn (`arkRun` schema `1.2+`; `arkOrder` schema `1.3+`).
@@ -18,6 +18,9 @@ imports, one small change at a time. Skills never enforce — CLI / hooks / CI d
18
18
  2. Fix import-rule debt; if leftover design remains, apply **one** small refactor.
19
19
  When doctor JSON has `noDomainFrontend`, that refactor is one pure rule into
20
20
  Domain — not another UI helper. Soft. Silent when Domain already has files.
21
+ When doctor JSON has `prototypeShortcuts`, that refactor is one file-store
22
+ move into Persistence, or one admin literal behind Domain / an auth tag.
23
+ Soft. Silent when those houses are absent or the shortcut is already home.
21
24
  3. Re-run doctor. Never weaken `ark.config.json`.
22
25
 
23
26
  **This is the apply door.** Invoking it **is** the approval. Run `arkgate-check --doctor` for the next step.
@@ -143,7 +146,9 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
143
146
  - After explore/doctor: if inventory has high-confidence candidates **or** user wants domain rules, include **[ArkRules] plan A/B**:
144
147
  - A: mechanical-safe remains inter-layer only; structure/invariant fixes are **judgment**.
145
148
  - B: one pilot = one rule (declare in `arkrules/<Layer>.json` → implement → test title/symbol → re-doctor).
146
- - Never promote advisory→enforced without coverage evidence (`canPromoteInvariant` / policy-delta).
149
+ - Never promote advisory→enforced without coverage evidence and declared
150
+ `coverage.coverageRoots` (`canPromoteInvariant` / policy-delta). Missing
151
+ roots refuse promotion — otherwise OUTSIDE_ROOTS stays silent.
147
152
  - End report must list what was **layer-edge** work vs **intra-layer rule** work.
148
153
 
149
154
  ### Autopilot + ArkRun
@@ -96,7 +96,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
96
96
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
97
97
  4. Editing `arkrules/*` or promoting modes is **`/ark-adopt`**; fixing code under a structure sensor is **`/ark-autopilot`** (judgment, never invent mechanical-safe).
98
98
  5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
99
- 5b. Invariant coverage is a **text match, never an execution**: a file walk plus the invariant id in a `describe`/`it` title. Never report `INVARIANT_UNCOVERED: 0` as “the tests pass” or “the tests run” — ArkGate does not run tests and reads no runner config. When the project declares `coverage.coverageRoots`, a covering test found outside them raises the advisory `INVARIANT_COVERAGE_OUTSIDE_ROOTS`; without that declaration ArkGate makes no claim about where tests run.
99
+ 5b. Invariant coverage is a **text match, never an execution**: a file walk plus the invariant id in a `describe`/`it` title. Never report `INVARIANT_UNCOVERED: 0` as “the tests pass” or “the tests run” — ArkGate does not run tests and reads no runner config. When the project declares `coverage.coverageRoots`, a covering test found outside them raises the advisory `INVARIANT_COVERAGE_OUTSIDE_ROOTS`; without that declaration ArkGate makes no claim about where tests run. Adopted + catalogued invariants without `coverage.testGlobs` or `coverage.coverageRoots` fails closed (`INVARIANT_TESTS_PATH_MISSING`) — write the path (`/ark-adopt`). When any invariant is enforced, missing `coverage.coverageRoots` fails closed (`INVARIANT_COVERAGE_ROOTS_MISSING`) — write the runner roots (`/ark-adopt`). `testGlobs` alone is not enough.
100
100
  6. Extras silent when off. Doctor `arkRun` / `arkOrder` is `notAScore`. Do not force extras. Wire one kernel candidate via `/ark-runtime`; one order-plane candidate via `/ark-order`. Do not invent `/ark-run`.
101
101
 
102
102
 
@@ -24,7 +24,8 @@ Name 1–3 **residual** lenses in plain language before skill-shopping. Always `
24
24
  **What the user should feel next:** fewer blocked AI writes, clearer folders, safer domain — then jargon.
25
25
 
26
26
  **Anti false-done:** empty plan A + residual lenses / design-weak → **Incomplete? yes**. Green edges alone
27
- are not “architecture finished.”
27
+ are not “architecture finished.” A doctor green / Healthy line must name a
28
+ file, config key, or test; uncited green is unfinished.
28
29
 
29
30
  **AI-easy architecture:** ports over concrete I/O in domain; one concern per module; golden pattern for
30
31
  new files; place before write (`/ark-place` / prepare-write).
@@ -34,6 +34,25 @@ one bounded decision needs 2–3 enforceable options.
34
34
  rules. Next: one Domain file (`/ark-place`) then one small refactor
35
35
  (`/ark-autopilot`). Soft. Silent when there is no frontend or Domain already
36
36
  has files. No `/ark-domain`. Do not invent a Domain house.
37
+ - When doctor JSON has `prototypeShortcuts`, SQLite / a JSON-file store is
38
+ standing in for Persistence, or admin / god-mode literals sit outside Domain
39
+ (or an auth tag). Next: one Persistence adapter or Domain policy file
40
+ (`/ark-place`) then one small refactor (`/ark-autopilot`). Soft. Silent when
41
+ those houses are absent, the shortcut is already in the right house, or there
42
+ are no such markers. No `/ark-prototype`. Do not invent a Persistence house.
43
+ - When the tree is adopted and doctor JSON has `invariantTestsPath` (or the
44
+ check names `INVARIANT_TESTS_PATH_MISSING`), the next step is
45
+ `coverage.testGlobs` or `coverage.coverageRoots` on a real tests folder.
46
+ Fail-closed. Silent when not adopted, the catalog is empty, or every
47
+ invariant sets coverage.test false. Handoff
48
+ `/ark-adopt` to write the path. No new skill.
49
+ - When any invariant is enforced and doctor JSON has `invariantCoverageRoots`
50
+ (or the check names `INVARIANT_COVERAGE_ROOTS_MISSING`), the next step is
51
+ `coverage.coverageRoots` on the folder the test runner uses. Fail-closed.
52
+ `testGlobs` alone is not enough. Silent when no invariant is enforced.
53
+ Handoff `/ark-adopt` to write the roots. No new skill.
54
+ - A doctor green / Healthy line must name a file, config key, or test.
55
+ Uncited green is a lie — treat it as unfinished. No `/ark-cite`.
37
56
  - Distinguish **missing** skills vs **stale** catalog. Installed ≠ stale.
38
57
  - Hook green is not tree green (scripted edits bypass PreToolUse).
39
58
  - Bug / false green / false red / missing doc / improvable behavior **in ArkGate itself** → draft one upstream GitHub issue (`pedroknigge/arkgate` or the installed package `repository.url`), **ask the human to confirm send**, then `gh issue create`. Never auto-file. Never file ArkGate defects on the consumer product repo.
@@ -29,6 +29,10 @@ right house. Skills never enforce — CLI / hooks / CI do.
29
29
  - When doctor JSON has `noDomainFrontend`, the new file is a Domain rule — not
30
30
  another UI helper. Soft. Silent when Domain already has files or there is no
31
31
  frontend. No `/ark-domain`.
32
+ - When doctor JSON has `prototypeShortcuts`, the new file is a Persistence
33
+ adapter or a Domain / auth-tag policy — not another SQLite / JSON-file store
34
+ or admin literal in the page. Soft. Silent when those houses are absent or
35
+ the shortcut is already in the right house. No `/ark-prototype`.
32
36
  - When the matched layer has `layers[].description`, print that caption next to the
33
37
  layer name and globs. Omit when absent — do not invent a caption or `/ark-describe`.
34
38
  - When the matched layer has `layers[].trustBoundary`, print `trust: <tag>` next
@@ -48,6 +48,21 @@ has honest houses. Skills never enforce — CLI / hooks / CI do.
48
48
  delete it to “clean” empty layers. Next is one Domain file (`/ark-place`), not
49
49
  a weaker contract. Soft. Silent when there is no frontend or Domain already
50
50
  has files. No `/ark-domain`.
51
+ - When doctor JSON has `prototypeShortcuts`, keep the Persistence / Domain
52
+ house — do not delete it to “clean” empty layers. Next is one Persistence
53
+ adapter or Domain policy file (`/ark-place`), not a weaker contract. Soft.
54
+ Silent when those houses are absent or the shortcut is already in the right
55
+ house. No `/ark-prototype`.
56
+ - When the tree is adopted and doctor JSON has `invariantTestsPath` (or the
57
+ check names `INVARIANT_TESTS_PATH_MISSING`), write `coverage.testGlobs` or
58
+ `coverage.coverageRoots` to a real tests folder. Fail-closed until that path
59
+ exists. Silent when not adopted, the catalog is empty, or every invariant
60
+ sets coverage.test false. No new skill.
61
+ - When any invariant is enforced and doctor JSON has `invariantCoverageRoots`
62
+ (or the check names `INVARIANT_COVERAGE_ROOTS_MISSING`), write
63
+ `coverage.coverageRoots` to the folder the test runner uses. Fail-closed
64
+ until that path exists. `coverage.testGlobs` alone is not enough. Silent
65
+ when no invariant is enforced. No new skill.
51
66
  - CLI-first: if `arkgate-check` already resolved the root, do not wait on MCP.
52
67
  - Do not add `arkRun` or `arkOrder` unless the user wants that extra. When they do, write
53
68
  **advisory** extra in this turn (`arkRun` schema `1.2+`; `arkOrder` schema `1.3+`).
@@ -18,6 +18,9 @@ imports, one small change at a time. Skills never enforce — CLI / hooks / CI d
18
18
  2. Fix import-rule debt; if leftover design remains, apply **one** small refactor.
19
19
  When doctor JSON has `noDomainFrontend`, that refactor is one pure rule into
20
20
  Domain — not another UI helper. Soft. Silent when Domain already has files.
21
+ When doctor JSON has `prototypeShortcuts`, that refactor is one file-store
22
+ move into Persistence, or one admin literal behind Domain / an auth tag.
23
+ Soft. Silent when those houses are absent or the shortcut is already home.
21
24
  3. Re-run doctor. Never weaken `ark.config.json`.
22
25
 
23
26
  **This is the apply door.** Invoking it **is** the approval. Run `arkgate-check --doctor` for the next step.
@@ -143,7 +146,9 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
143
146
  - After explore/doctor: if inventory has high-confidence candidates **or** user wants domain rules, include **[ArkRules] plan A/B**:
144
147
  - A: mechanical-safe remains inter-layer only; structure/invariant fixes are **judgment**.
145
148
  - B: one pilot = one rule (declare in `arkrules/<Layer>.json` → implement → test title/symbol → re-doctor).
146
- - Never promote advisory→enforced without coverage evidence (`canPromoteInvariant` / policy-delta).
149
+ - Never promote advisory→enforced without coverage evidence and declared
150
+ `coverage.coverageRoots` (`canPromoteInvariant` / policy-delta). Missing
151
+ roots refuse promotion — otherwise OUTSIDE_ROOTS stays silent.
147
152
  - End report must list what was **layer-edge** work vs **intra-layer rule** work.
148
153
 
149
154
  ### Autopilot + ArkRun
@@ -96,7 +96,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
96
96
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
97
97
  4. Editing `arkrules/*` or promoting modes is **`/ark-adopt`**; fixing code under a structure sensor is **`/ark-autopilot`** (judgment, never invent mechanical-safe).
98
98
  5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
99
- 5b. Invariant coverage is a **text match, never an execution**: a file walk plus the invariant id in a `describe`/`it` title. Never report `INVARIANT_UNCOVERED: 0` as “the tests pass” or “the tests run” — ArkGate does not run tests and reads no runner config. When the project declares `coverage.coverageRoots`, a covering test found outside them raises the advisory `INVARIANT_COVERAGE_OUTSIDE_ROOTS`; without that declaration ArkGate makes no claim about where tests run.
99
+ 5b. Invariant coverage is a **text match, never an execution**: a file walk plus the invariant id in a `describe`/`it` title. Never report `INVARIANT_UNCOVERED: 0` as “the tests pass” or “the tests run” — ArkGate does not run tests and reads no runner config. When the project declares `coverage.coverageRoots`, a covering test found outside them raises the advisory `INVARIANT_COVERAGE_OUTSIDE_ROOTS`; without that declaration ArkGate makes no claim about where tests run. Adopted + catalogued invariants without `coverage.testGlobs` or `coverage.coverageRoots` fails closed (`INVARIANT_TESTS_PATH_MISSING`) — write the path (`/ark-adopt`). When any invariant is enforced, missing `coverage.coverageRoots` fails closed (`INVARIANT_COVERAGE_ROOTS_MISSING`) — write the runner roots (`/ark-adopt`). `testGlobs` alone is not enough.
100
100
  6. Extras silent when off. Doctor `arkRun` / `arkOrder` is `notAScore`. Do not force extras. Wire one kernel candidate via `/ark-runtime`; one order-plane candidate via `/ark-order`. Do not invent `/ark-run`.
101
101
 
102
102
 
@@ -24,7 +24,8 @@ Name 1–3 **residual** lenses in plain language before skill-shopping. Always `
24
24
  **What the user should feel next:** fewer blocked AI writes, clearer folders, safer domain — then jargon.
25
25
 
26
26
  **Anti false-done:** empty plan A + residual lenses / design-weak → **Incomplete? yes**. Green edges alone
27
- are not “architecture finished.”
27
+ are not “architecture finished.” A doctor green / Healthy line must name a
28
+ file, config key, or test; uncited green is unfinished.
28
29
 
29
30
  **AI-easy architecture:** ports over concrete I/O in domain; one concern per module; golden pattern for
30
31
  new files; place before write (`/ark-place` / prepare-write).
@@ -34,6 +34,25 @@ one bounded decision needs 2–3 enforceable options.
34
34
  rules. Next: one Domain file (`/ark-place`) then one small refactor
35
35
  (`/ark-autopilot`). Soft. Silent when there is no frontend or Domain already
36
36
  has files. No `/ark-domain`. Do not invent a Domain house.
37
+ - When doctor JSON has `prototypeShortcuts`, SQLite / a JSON-file store is
38
+ standing in for Persistence, or admin / god-mode literals sit outside Domain
39
+ (or an auth tag). Next: one Persistence adapter or Domain policy file
40
+ (`/ark-place`) then one small refactor (`/ark-autopilot`). Soft. Silent when
41
+ those houses are absent, the shortcut is already in the right house, or there
42
+ are no such markers. No `/ark-prototype`. Do not invent a Persistence house.
43
+ - When the tree is adopted and doctor JSON has `invariantTestsPath` (or the
44
+ check names `INVARIANT_TESTS_PATH_MISSING`), the next step is
45
+ `coverage.testGlobs` or `coverage.coverageRoots` on a real tests folder.
46
+ Fail-closed. Silent when not adopted, the catalog is empty, or every
47
+ invariant sets coverage.test false. Handoff
48
+ `/ark-adopt` to write the path. No new skill.
49
+ - When any invariant is enforced and doctor JSON has `invariantCoverageRoots`
50
+ (or the check names `INVARIANT_COVERAGE_ROOTS_MISSING`), the next step is
51
+ `coverage.coverageRoots` on the folder the test runner uses. Fail-closed.
52
+ `testGlobs` alone is not enough. Silent when no invariant is enforced.
53
+ Handoff `/ark-adopt` to write the roots. No new skill.
54
+ - A doctor green / Healthy line must name a file, config key, or test.
55
+ Uncited green is a lie — treat it as unfinished. No `/ark-cite`.
37
56
  - Distinguish **missing** skills vs **stale** catalog. Installed ≠ stale.
38
57
  - Hook green is not tree green (scripted edits bypass PreToolUse).
39
58
  - Bug / false green / false red / missing doc / improvable behavior **in ArkGate itself** → draft one upstream GitHub issue (`pedroknigge/arkgate` or the installed package `repository.url`), **ask the human to confirm send**, then `gh issue create`. Never auto-file. Never file ArkGate defects on the consumer product repo.
@@ -29,6 +29,10 @@ right house. Skills never enforce — CLI / hooks / CI do.
29
29
  - When doctor JSON has `noDomainFrontend`, the new file is a Domain rule — not
30
30
  another UI helper. Soft. Silent when Domain already has files or there is no
31
31
  frontend. No `/ark-domain`.
32
+ - When doctor JSON has `prototypeShortcuts`, the new file is a Persistence
33
+ adapter or a Domain / auth-tag policy — not another SQLite / JSON-file store
34
+ or admin literal in the page. Soft. Silent when those houses are absent or
35
+ the shortcut is already in the right house. No `/ark-prototype`.
32
36
  - When the matched layer has `layers[].description`, print that caption next to the
33
37
  layer name and globs. Omit when absent — do not invent a caption or `/ark-describe`.
34
38
  - When the matched layer has `layers[].trustBoundary`, print `trust: <tag>` next