arkgate 4.8.14 → 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 (103) hide show
  1. package/CHANGELOG.md +172 -0
  2. package/README.md +17 -7
  3. package/bin/ark-check-runtime.mjs +17 -49
  4. package/bin/ark-mcp-runtime.mjs +111 -2
  5. package/bin/ark-shared.mjs +142 -11
  6. package/bin/ark.mjs +24 -33
  7. package/bin/lib/adr-presence.mjs +97 -0
  8. package/bin/lib/agent-skills-package.mjs +179 -1
  9. package/bin/lib/analysis-completeness.mjs +38 -2
  10. package/bin/lib/analysis-engine.mjs +6 -6
  11. package/bin/lib/architecture-scan.mjs +43 -4
  12. package/bin/lib/ark-run-doctor.mjs +6 -0
  13. package/bin/lib/ark-run-report.mjs +6 -2
  14. package/bin/lib/arkrules-sensors.mjs +81 -0
  15. package/bin/lib/baseline-key.mjs +6 -1
  16. package/bin/lib/check-args.mjs +52 -2
  17. package/bin/lib/config-contract.mjs +65 -2
  18. package/bin/lib/diagnostic-catalog.mjs +5 -1
  19. package/bin/lib/doctor-advisories.mjs +120 -10
  20. package/bin/lib/doctor-green-cite.mjs +139 -0
  21. package/bin/lib/doctor-human.mjs +115 -67
  22. package/bin/lib/doctor-next-actions.mjs +23 -0
  23. package/bin/lib/doctor-plan.mjs +35 -2
  24. package/bin/lib/enforcement-honesty.mjs +47 -2
  25. package/bin/lib/field-install.mjs +47 -7
  26. package/bin/lib/first-run-help.mjs +9 -1
  27. package/bin/lib/host-support-matrix.mjs +9 -1
  28. package/bin/lib/html-report-depth.mjs +2 -0
  29. package/bin/lib/html-report.mjs +13 -2
  30. package/bin/lib/import-resolve.mjs +74 -13
  31. package/bin/lib/improvement-compass-doctor.mjs +8 -1
  32. package/bin/lib/improvement-compass-map.mjs +5 -1
  33. package/bin/lib/invariant-coverage.mjs +121 -0
  34. package/bin/lib/invariant-tests-path.mjs +212 -0
  35. package/bin/lib/layer-description.mjs +90 -8
  36. package/bin/lib/mcp-hook-payload.mjs +56 -0
  37. package/bin/lib/no-domain-frontend.mjs +91 -0
  38. package/bin/lib/package-manager.mjs +8 -0
  39. package/bin/lib/presets.mjs +3 -4
  40. package/bin/lib/product-copy.mjs +15 -0
  41. package/bin/lib/projected-governed-coverage.mjs +114 -0
  42. package/bin/lib/prototype-shortcuts.mjs +224 -0
  43. package/bin/lib/recommend-cli.mjs +54 -0
  44. package/bin/lib/remediation.mjs +15 -0
  45. package/bin/lib/resolved-candidate-facts.mjs +83 -66
  46. package/bin/lib/rules-under-contract.mjs +117 -2
  47. package/bin/lib/snippet-analysis.mjs +14 -8
  48. package/bin/lib/start-preview.mjs +24 -2
  49. package/bin/lib/states-transitions-presence.mjs +212 -0
  50. package/bin/lib/status-command.mjs +2 -0
  51. package/bin/lib/status-transition-catalog.mjs +410 -0
  52. package/bin/lib/team-parliament-io.mjs +10 -0
  53. package/bin/lib/violations.mjs +13 -1
  54. package/bin/lib/write-path-capabilities.mjs +20 -5
  55. package/bin/lib/write-path-detect.mjs +27 -2
  56. package/dist/{configTypes-j7so8B4O.d.ts → configTypes-VD0qcubY.d.ts} +21 -1
  57. package/dist/{diagnosticCatalog-DVx_2RmF.d.ts → diagnosticCatalog-KWvGLI1U.d.ts} +24 -3
  58. package/dist/eslint/index.cjs +4 -4
  59. package/dist/eslint/index.d.ts +1 -1
  60. package/dist/eslint/index.js +4 -4
  61. package/dist/index.cjs +34 -34
  62. package/dist/index.d.ts +71 -10
  63. package/dist/index.js +34 -34
  64. package/dist/nestjs/index.cjs +5 -5
  65. package/dist/nestjs/index.d.ts +3 -3
  66. package/dist/nestjs/index.js +5 -5
  67. package/dist/runtime/index.cjs +15 -15
  68. package/dist/runtime/index.d.ts +6 -6
  69. package/dist/runtime/index.js +15 -15
  70. package/dist/{types-tGhZUiGX.d.ts → types-BSzRy2X1.d.ts} +1 -1
  71. package/dist/{types-Djbs3KjE.d.ts → types-D5GT5ZT8.d.ts} +3 -1
  72. package/docs/README.md +1 -1
  73. package/docs/agent-guide.md +8 -4
  74. package/docs/ai-gates.md +10 -3
  75. package/docs/brownfield-adoption.md +4 -1
  76. package/docs/configuration.md +66 -10
  77. package/docs/develop.md +4 -1
  78. package/docs/diagnostics.md +48 -4
  79. package/docs/enthusiast/how-to-agent-gates.md +5 -0
  80. package/docs/enthusiast/how-to-pick-shape.md +1 -1
  81. package/docs/package-surface.md +7 -5
  82. package/docs/use.md +10 -3
  83. package/package.json +1 -1
  84. package/schemas/ark.config.schema.json +24 -3
  85. package/server.json +2 -2
  86. package/templates/agent-skills/README.md +1 -1
  87. package/templates/agent-skills/ark-adopt/SKILL.md +97 -1
  88. package/templates/agent-skills/ark-autopilot/SKILL.md +12 -3
  89. package/templates/agent-skills/ark-coverage/SKILL.md +2 -2
  90. package/templates/agent-skills/ark-explain/SKILL.md +6 -3
  91. package/templates/agent-skills/ark-explore/SKILL.md +33 -1
  92. package/templates/agent-skills/ark-place/SKILL.md +42 -3
  93. package/templates/agent-skills/ark-runtime/SKILL.md +4 -2
  94. package/templates/agent-skills/ark-upgrade/SKILL.md +1 -1
  95. package/templates/arkrules/DomainModel.json +14 -1
  96. package/templates/skills/ark-adopt.md +97 -1
  97. package/templates/skills/ark-autopilot.md +12 -3
  98. package/templates/skills/ark-coverage.md +2 -2
  99. package/templates/skills/ark-explain.md +6 -3
  100. package/templates/skills/ark-explore.md +33 -1
  101. package/templates/skills/ark-place.md +42 -3
  102. package/templates/skills/ark-runtime.md +4 -2
  103. package/templates/skills/ark-upgrade.md +1 -1
@@ -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.14**
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)
@@ -21,11 +21,48 @@ has honest houses. Skills never enforce — CLI / hooks / CI do.
21
21
  ## Checklist
22
22
 
23
23
  - Existing tree: propose **SharedKernel** (types/constants) + **CompositionRoot** (wiring) + `src/**/domain/**`. Never dump bare `src/lib/**` into Application.
24
+ - Every `include` path must land in a layer. Include that classifies no file is the
25
+ same as an empty check — not a pass. Fix globs here; do not leave a loose gap.
24
26
  - Generate `.ark/golden-pattern.json` (load-bearing for `/ark-place`).
25
27
  - Future houses: mark unused layer globs `reserved` / `allowEmpty` so `--strict-config` does not fail.
26
28
  - When the product map or glossary names a house, write `layers[].description` as
27
29
  app-context copy (what this folder is *in the product*). Compact starter may omit.
28
30
  Do not invent captions. Do not invent `/ark-describe`.
31
+ - When the product map names who a folder is for, write `layers[].trustBoundary`
32
+ (`public` | `auth` | `admin` | `internal`). Compact starter may omit. Do not
33
+ invent tags. Absence is silent. No `/ark-trust`.
34
+ - When the product map names who owns a folder, write `layers[].owners`
35
+ (GitHub handle or email). Compact starter may omit. Do not invent people.
36
+ Absence is silent unless the user asked for required owners — then write
37
+ `requireLayerOwners: true` after the live houses have names. No `/ark-owners`.
38
+ - When the user wants required gates (`--require-gates` / `--strict-merge` /
39
+ required GitHub check) and there is no `docs/adr/` (or `docs/decisions/`),
40
+ leave a short decision note there — only if they loosen a rule or add a real
41
+ gate. Not every change. Doctor residual is soft. No `/ark-adr`.
42
+ - When a product-domain doc is already in play (`docs/domain.md` or a sibling)
43
+ and doctor JSON has `statesTransitions` or `statusTransitionCatalog`, add a
44
+ short states → transitions table (or one link) there. Use catalog names when
45
+ present. No flag soup. Soft residual. Silent when that doc is absent or
46
+ Domain has no status vocabulary. No `/ark-states`.
47
+ - When doctor JSON has `noDomainFrontend`, keep the empty Domain house — do not
48
+ delete it to “clean” empty layers. Next is one Domain file (`/ark-place`), not
49
+ a weaker contract. Soft. Silent when there is no frontend or Domain already
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.
29
66
  - CLI-first: if `arkgate-check` already resolved the root, do not wait on MCP.
30
67
  - Do not add `arkRun` or `arkOrder` unless the user wants that extra. When they do, write
31
68
  **advisory** extra in this turn (`arkRun` schema `1.2+`; `arkOrder` schema `1.3+`).
@@ -106,6 +143,46 @@ received."), not architecture jargon. Compact starter / `ark start` may omit the
106
143
  field. Absence is silent — never fail `--strict-config` for a missing caption.
107
144
  Do **not** invent captions. Do not invent `/ark-describe`.
108
145
 
146
+ ## Layer trust (process)
147
+
148
+ Optional `layers[].trustBoundary`: `public` | `auth` | `admin` | `internal`.
149
+ Marks who this folder is for (anyone, signed-in users, operators, or only
150
+ other code). Write it when the product map already names that door. Compact
151
+ starter / `ark start` may omit it. Absence is silent — never fail
152
+ `--strict-config`, never invent a doctor residual. Do **not** invent tags.
153
+ This is not host/CI TLS and does not add import-rule teeth. No `/ark-trust`.
154
+
155
+ ## Layer owners (process)
156
+
157
+ Optional `layers[].owners`: GitHub handles or emails (same identity as
158
+ `stewards` — not a display name). Write them when the product map already
159
+ names who owns the house. Compact starter / `ark start` may omit. Absence is
160
+ silent unless the user asked for required owners. Then write
161
+ `requireLayerOwners: true` only after every live (non-reserved) layer has
162
+ at least one owner. Do **not** invent people. No `/ark-owners`. The require
163
+ flag is the fail-closed switch; owners themselves are metadata.
164
+
165
+ ## Decision notes (process)
166
+
167
+ When gates are required (`--require-gates` / `--strict-merge` / required merge
168
+ status) and there is no short decision-note home yet, doctor may ask for one
169
+ under `docs/adr/` or `docs/decisions/`. Write a note when you loosen a rule or
170
+ add a real gate — not on every file. Absence is silent unless that demand is
171
+ on. The hint does not fail the check. Do **not** invent `/ark-adr`. Policy
172
+ weaken still uses `--policy-ack`; this is only a place to write the why.
173
+
174
+ ## States and transitions (process)
175
+
176
+ When a product-domain / domain-model doc is already on disk (`docs/domain.md`,
177
+ `docs/data-model.md`, or a dedicated `docs/states.md`) and there is no short
178
+ states → transitions table (or one link), doctor may ask for one. Write the
179
+ table on that home — entity · states · allowed from → to. Names from the
180
+ code or the captain. When doctor JSON has `statusTransitionCatalog`, use those
181
+ entity · states names — Domain already opted in by having that vocabulary.
182
+ Do **not** invent states or flag soup. Absence of the domain doc, or Domain
183
+ with no status union/enum, stays silent. The hint does not fail the check.
184
+ Do **not** invent `/ark-states`. Do not walk the tree to invent a roster.
185
+
109
186
  ## When / not when
110
187
 
111
188
  | Use `/ark-adopt` when… | Do **not** use it when… |
@@ -151,7 +228,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
151
228
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
152
229
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
153
230
  4. Editing `arkrules/*` or promoting modes is **this skill** (session 0) or **`/ark-autopilot`** later; never invent `mechanical-safe`.
154
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` with `evidence.arkruleId`.
231
+ 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
155
232
  6. Absence of `arkRun` is **valid**. Write it only when the user wants the extra. Skills never enforce.
156
233
  7. Absence of `arkOrder` is **valid**. Write it only when the user wants the extra. After the extra is honest: handoff **`/ark-order`** to wire one candidate. Skills never enforce.
157
234
 
@@ -159,6 +236,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
159
236
  ### Adopt + ArkRules
160
237
  - After classify: emit or refresh `arkRules` for matched layers (exact names; generic mold for unknowns).
161
238
  - Mine rules → inventory + write advisory invariants/structure into `arkrules/<Layer>.json` **in this turn**.
239
+ - Empty `invariants[]` on a populated Domain while `arkRules` is on is residual (`INVARIANT_CATALOG_EMPTY`), not done. Fill 1–2 short phrases. Advisory until a domain structure rule is `enforced`.
162
240
  - Application / Features templates include advisory `writes-via-aggregate`: driver import + write token in a use case is the skip. Do not copy `Externals/` / `admission.ts` folder religion.
163
241
  - Freeze baseline is **[Layer]** debt; inventory residual is **[ArkRules]** — report both.
164
242
 
@@ -222,6 +300,9 @@ feature dirs, plan clusters), you **may** dispatch **subagents**:
222
300
  - **Brownfield:** this skill — match config to reality; do not force a starter preset.
223
301
  - **Deep map only:** `/ark-explore`.
224
302
  - **Default path:** `ark start` → **`/ark-adopt`** → `/ark-place` / `/ark-autopilot`.
303
+ `start --apply` may refuse (coverage below 50% or weak shape) — that lock is
304
+ deliberate. Lock the shape with `--archetype`, `--preset`, or `--force`, or
305
+ inspect ranked shapes with `ark-check --recommend`.
225
306
 
226
307
  ## Anti-wrapper rule (mandatory)
227
308
 
@@ -248,6 +329,9 @@ Ark protects the **boundary around** a framework, not its internals. Nest/DI pub
248
329
  If `src/contexts` or `src/bounded-contexts` exists, prefer `ddd-bounded-contexts`.
249
330
  **Next.js:** `app/api/**` / `pages/api/**` (and route-group `app/(…)/api/**`) default to
250
331
  **ApplicationOrchestration**, not Presentation — do not reclassify API shells as UI.
332
+ Write Next-flavored `layers[].description` only when Next is actually present
333
+ (`next` dependency, `next.config.*`, or `app/page` / `pages/*` routes). Library and
334
+ package monorepos keep framework-free captions — `ark start` already does this.
251
335
  User wants the ArkRun extra → write **advisory** `arkRun` (schema `1.2+`, real
252
336
  `kernelRoots` preferred — `compositionRoots` alias, existing `managedLayers`) **in this turn**.
253
337
  User wants the ArkOrder extra → write **advisory** `arkOrder` (schema `1.3+`, real
@@ -255,6 +339,12 @@ Ark protects the **boundary around** a framework, not its internals. Nest/DI pub
255
339
  to a compact starter. Do not promote to enforced as the session-0 default.
256
340
  When the product map or glossary names a house, write `layers[].description` on that
257
341
  layer (app-context sentence). Compact starter may omit. Do not invent captions.
342
+ When the product map names who a folder is for, write `layers[].trustBoundary`
343
+ (`public` | `auth` | `admin` | `internal`). Do not invent tags.
344
+ When the product map names who owns a folder, write `layers[].owners`
345
+ (GitHub handle or email). Do not invent people. Write `requireLayerOwners`
346
+ only when the user asked for required owners and the live houses already
347
+ have names.
258
348
  2. **Check + diagnose** — `summary.concentrated` / dominant edge → fix contract first, don’t freeze.
259
349
  Cross-slice / cross-context `peerIsolation` hits are judgment: extract shared or events.
260
350
  The denial names its reason. `unclassifiable path` in bulk means shared code lives outside
@@ -268,6 +358,8 @@ Ark protects the **boundary around** a framework, not its internals. Nest/DI pub
268
358
  3. **Classify ungoverned** — use coverage `suggestions` **plus** dirs you discovered by reading;
269
359
  add layers/patterns **here** (write `ark.config.json`). When adding a layer the product map
270
360
  or glossary already names, write `layers[].description` on it (do not invent filler).
361
+ Write `layers[].trustBoundary` only when the product map already names that door.
362
+ Write `layers[].owners` only when the product map already names who owns the house.
271
363
  4. **Mine business rules → manifiesto** (model job — this is why the skill exists):
272
364
  - Scan for loose domain: validators, pricing/policy functions, `can*`/`calculate*`, magic business constants, publish/intent strings, logic in UI/hooks that belongs in Domain.
273
365
  - **ArkRules inventory (AR13):** run `ark-check --rules-inventory --json` for deterministic candidates
@@ -307,6 +399,10 @@ proposals applied or deferred, **phase**, **top Shape / design-weak opportunitie
307
399
  - Claim in-memory kernel stores are production durability.
308
400
  - Invent `/ark-run`. Use `/ark-order` after this door turns the extra on.
309
401
  - Invent `layers[].description` filler or a `/ark-describe` skill.
402
+ - Invent `layers[].trustBoundary` tags or a `/ark-trust` skill.
403
+ - Invent `layers[].owners` names or a `/ark-owners` skill.
404
+ - Invent `/ark-adr` or require a decision note on every change.
405
+ - Invent `/ark-states` or invent entity states / flag soup.
310
406
  - Claim Enforce while governed% is low, cores empty with I/O in Application, or core bags ungoverned.
311
407
  - End adopt with only “baseline written” when design-weak residual is visible in files you opened.
312
408
 
@@ -16,6 +16,11 @@ imports, one small change at a time. Skills never enforce — CLI / hooks / CI d
16
16
 
17
17
  1. Read `arkgate-check --doctor` (do #1).
18
18
  2. Fix import-rule debt; if leftover design remains, apply **one** small refactor.
19
+ When doctor JSON has `noDomainFrontend`, that refactor is one pure rule into
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.
19
24
  3. Re-run doctor. Never weaken `ark.config.json`.
20
25
 
21
26
  **This is the apply door.** Invoking it **is** the approval. Run `arkgate-check --doctor` for the next step.
@@ -32,7 +37,9 @@ Apply plan A (`mechanical-safe` **and** judgment). If leftover design work remai
32
37
  Composes **explore → sensors → dual plan → write**. Validate with ark-check; never weaken the gate.
33
38
  **Team lock:** do not edit `ark.config.json`, `arkrules/*`, or `.ark-baseline.json` in this
34
39
  turn unless the user invoked a steward contract session. Feature diffs use
35
- `ark-check --changed --base <merge-ref>`. Growing the baseline is steward-only.
40
+ `ark-check --local --base <merge-ref>` or `ark-check --changed --base <merge-ref>`.
41
+ `--local` is the optional cheap path for many worktrees; it cannot combine with
42
+ `--strict-merge`. Growing the baseline is steward-only.
36
43
 
37
44
  **Not a plan grinder.** Empty `--plan` does **not** mean “architecture is healthy” without
38
45
  the explore pass and dual-plan section B (pattern / Shape bets).
@@ -131,7 +138,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
131
138
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
132
139
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
133
140
  4. Editing `arkrules/*` or promoting modes and fixing structure sensors is **this skill** (judgment, never invent `mechanical-safe`).
134
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` with `evidence.arkruleId`.
141
+ 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
135
142
  6. Absence of extras is **valid**. Extra skip clusters grind **here** after the extra is on. Evaluate one bus → `/ark-runtime`; evaluate one order-plane candidate → `/ark-order`. Do not invent `/ark-run`. Skills never enforce.
136
143
 
137
144
 
@@ -139,7 +146,9 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
139
146
  - After explore/doctor: if inventory has high-confidence candidates **or** user wants domain rules, include **[ArkRules] plan A/B**:
140
147
  - A: mechanical-safe remains inter-layer only; structure/invariant fixes are **judgment**.
141
148
  - B: one pilot = one rule (declare in `arkrules/<Layer>.json` → implement → test title/symbol → re-doctor).
142
- - 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.
143
152
  - End report must list what was **layer-edge** work vs **intra-layer rule** work.
144
153
 
145
154
  ### Autopilot + ArkRun
@@ -95,8 +95,8 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
95
95
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
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
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` 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.
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. 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).
@@ -79,7 +80,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
79
80
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
80
81
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
81
82
  4. Editing `arkrules/*` or applying structure fixes is **`/ark-adopt`** / **`/ark-autopilot`** (never invent `mechanical-safe`).
82
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` with `evidence.arkruleId`.
83
+ 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
83
84
  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`.
84
85
 
85
86
 
@@ -87,7 +88,9 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
87
88
  - HTML/plain tour: section **Layers** and section **Rules under contract (ArkRules)** —
88
89
  when `arkRules` is active the showcase lists **per-layer counts**, **structure sensors**
89
90
  (id / sensor / mode), **uncovered** invariants (call them out), and a **covered sample**.
90
- Inactive map stays a short opt-in note. Counts are never a score.
91
+ Compact doctor names ArkRules only when the map is on; absence stays silent.
92
+ Empty `invariants[]` on a populated Domain is residual (`INVARIANT_CATALOG_EMPTY`), not “all covered”.
93
+ Inactive HTML map stays a short opt-in note. Counts are never a score.
91
94
  - Spoken tour: name 2–4 real invariant IDs and one structure sensor from this repo’s
92
95
  `arkrules/*` (open the files — do not invent). Residual candidates → `--rules-inventory`.
93
96
  - **Teach the product model (required when arkRules is active):**
@@ -22,6 +22,37 @@ one bounded decision needs 2–3 enforceable options.
22
22
  ## Checklist
23
23
 
24
24
  - Doctor #1: if ENFORCE + empty plan A and gates are already installed → **Shape** (`/ark-explore` then `/ark-autopilot`). Do not say install-agent-gates.
25
+ - When `--require-gates` / adopted-strict is on and doctor JSON has `adrPresence`,
26
+ the next step is a short note under `docs/adr/` (or `docs/decisions/`). Soft.
27
+ Not every change. Off when require-gates is off. No `/ark-adr`.
28
+ - When doctor JSON has `statesTransitions` or `statusTransitionCatalog`, the
29
+ next step is a short states → transitions table (or one link) on the domain
30
+ doc already in play. Use catalog names when present. Soft. Silent when that
31
+ doc is absent or Domain has no status vocabulary. No `/ark-states`. Do not
32
+ invent states.
33
+ - When doctor JSON has `noDomainFrontend`, Domain is empty and the UI holds the
34
+ rules. Next: one Domain file (`/ark-place`) then one small refactor
35
+ (`/ark-autopilot`). Soft. Silent when there is no frontend or Domain already
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`.
25
56
  - Distinguish **missing** skills vs **stale** catalog. Installed ≠ stale.
26
57
  - Hook green is not tree green (scripted edits bypass PreToolUse).
27
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.
@@ -179,13 +210,14 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
179
210
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
180
211
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
181
212
  4. Editing `arkrules/*` or applying structure fixes is **`/ark-adopt`** / **`/ark-autopilot`** — explore does not write (never invent `mechanical-safe`).
182
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` with `evidence.arkruleId`.
213
+ 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
183
214
  6. Never write `arkRun` or `arkOrder` from this skill. When extras are present, label residual **`[ArkRun]`** / **`[ArkOrder]`**. Wire one kernel candidate via `/ark-runtime`; one order-plane candidate via `/ark-order`. Do not invent `/ark-run`.
184
215
 
185
216
 
186
217
  ### Explore + ArkRules
187
218
  - Always run sensors for **both** planes when present: coverage/doctor **and** `--rules-inventory` if `arkRules` exists or brownfield may hide spaghetti rules.
188
219
  - Ranked table kinds may include `arkrules-opportunity` and `invariant-gap`.
220
+ - Empty `invariants[]` on a populated Domain while `arkRules` is on is residual (`INVARIANT_CATALOG_EMPTY`), not done. Point at `arkrules/<Domain>.json`.
189
221
  - Dual-plan **B** may include: place advisory structure rules, extract one inventory candidate to Domain + `arkrules` entry, promote one covered invariant.
190
222
  - Field path: note whether starters emit `arkrules/*`.
191
223
 
@@ -22,9 +22,25 @@ right house. Skills never enforce — CLI / hooks / CI do.
22
22
 
23
23
  - `filePath` is known before the call. Description alone is not a path.
24
24
  - Golden pattern is load-bearing when present. Adopt generates it.
25
+ - An included file that matches no layer is not a pass. The write gate denies it
26
+ (`CONFIG_UNCLASSIFIED_FILES`). Place it in a layer folder, or send include/layer
27
+ drift to `/ark-adopt`. Do not write into a loose include gap.
25
28
  - Do not default a repository to Presentation.
29
+ - When doctor JSON has `noDomainFrontend`, the new file is a Domain rule — not
30
+ another UI helper. Soft. Silent when Domain already has files or there is no
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`.
26
36
  - When the matched layer has `layers[].description`, print that caption next to the
27
37
  layer name and globs. Omit when absent — do not invent a caption or `/ark-describe`.
38
+ - When the matched layer has `layers[].trustBoundary`, print `trust: <tag>` next
39
+ to the layer name and globs. Omit when absent — do not invent a tag or `/ark-trust`.
40
+ - When the matched layer has `layers[].owners`, print `owner: @handle` next
41
+ to the layer name and globs. Omit when absent — do not invent a person or `/ark-owners`.
42
+ When `requireLayerOwners` is on and the house has no owners, send that gap to
43
+ `/ark-adopt` before writing.
28
44
  - When `arkRun` is on: scaffold through the kernel (no `new` of managed types; declare
29
45
  `uses` / `reactsTo` / `raises` / `sends`; factory only in `arkRun.kernelRoots`,
30
46
  `compositionRoots` alias). Extra off → do not introduce the kernel. Enable it
@@ -69,6 +85,21 @@ When `ark_place` / the contract includes `layers[].description`, print that capt
69
85
  next to the layer name and globs. Omit it when the field is absent. Do **not** invent
70
86
  a caption or `/ark-describe`.
71
87
 
88
+ ## Layer trust (process)
89
+
90
+ When the matched layer has `layers[].trustBoundary` (`public` | `auth` |
91
+ `admin` | `internal`), print `trust: <tag>` next to the layer name and globs.
92
+ Omit it when the field is absent. Do **not** invent a tag or `/ark-trust`.
93
+ The tag is guidance, not an import-rule deny.
94
+
95
+ ## Layer owners (process)
96
+
97
+ When the matched layer has `layers[].owners`, print `owner: @handle` (or
98
+ `owner: name@host`) next to the layer name and globs. Omit when absent.
99
+ Do **not** invent a person or `/ark-owners`. When `requireLayerOwners` is
100
+ on and this house has no owners, do not write — hand off `/ark-adopt` to
101
+ name who owns the folder.
102
+
72
103
  ## Deep modules (process)
73
104
 
74
105
  - Place so new code stays **deep**: one small public surface per concern; hide implementation details.
@@ -92,7 +123,9 @@ and — if they asked to build it — scaffold it there correctly.
92
123
  **No artifact given?** If the skill is invoked with nothing to place, don't error
93
124
  and don't guess — the artifact is the one thing only the user knows. Read the
94
125
  contract (step 1) and print the placement map from it: one row per declared layer
95
- with layer name, globs, and `layers[].description` when present (omit when absent),
126
+ with layer name, globs, `layers[].description` when present,
127
+ `layers[].trustBoundary` when present, and `layers[].owners` when present
128
+ (omit any when absent),
96
129
  what belongs there, its directory, and which layers it may/may not import,
97
130
  plus the not-yet-adopted `suggestedLayers` as a footnote. Then ask what they want
98
131
  to place. That map is derived entirely from the repo, so producing it is real work,
@@ -134,7 +167,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
134
167
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
135
168
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
136
169
  4. Missing layer home: add it via **`/ark-adopt`** in this session if needed, then write the file; never invent `mechanical-safe`.
137
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` with `evidence.arkruleId`.
170
+ 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
138
171
  6. Absence of `arkRun` is **valid**. Do not introduce the kernel speculatively. Skills never enforce this extra.
139
172
  7. Absence of `arkOrder` is **valid**. When on: Domain stays plane-free; first freeze ξ with `release()`; later ξ is `proposeRelease` then `apply`; never `update`/`patch`/`set` the pattern. Import `createOrderPlane` from `arkgate/order` (same npm package). Evaluate / wire one candidate via **`/ark-order`**.
140
173
 
@@ -180,7 +213,11 @@ the same files or weaken the gate.
180
213
  its forbidden globals, and exactly which layers the file may / must not import,
181
214
  straight from the contract (no guessing). When the matched layer has
182
215
  `layers[].description`, print that caption next to the layer name and globs;
183
- omit it when absent. When present, also honor optional
216
+ omit it when absent. When the matched layer has `layers[].trustBoundary`,
217
+ print `trust: <tag>` next to the layer name and globs; omit it when absent.
218
+ When the matched layer has `layers[].owners`, print `owner: @handle`; omit
219
+ when absent.
220
+ When present, also honor optional
184
221
  **`goldenPattern`** (from `.ark/golden-pattern.json`) for **NEW code only** —
185
222
  advisory layout norm; never overrides the gate and never clears design-weak.
186
223
  Absent golden is normal. Otherwise load `ark.config.json`; after the matched preflight,
@@ -215,6 +252,8 @@ the same files or weaken the gate.
215
252
  `patterns`), intent-name prefix if the layer declares `intentPrefixes`, and
216
253
  which layers it may/may not import (from `rules`). When present, print
217
254
  `layers[].description` next to the layer name and globs; omit when absent.
255
+ Print `layers[].trustBoundary` as `trust: <tag>` when present; omit when absent.
256
+ Print `layers[].owners` as `owner: @handle` when present; omit when absent.
218
257
  4. **If the layer isn't adopted yet** (suggested but no directory): write the
219
258
  layer into `ark.config.json` (session-0 honesty — same as `/ark-adopt` for
220
259
  that glob) **then** write the file. Don't silently drop the code into a
@@ -34,8 +34,10 @@ grind (`/ark-autopilot`); wire the order plane (`/ark-order`).
34
34
  | **ArkRun extra** (`arkRun` on `ark.config.json`, schema `1.2+`) | Gate contract: kernel usage + complete declarations | A score; Layers / ArkRules replacement; merge teeth while `advisory` |
35
35
  | **Kernel** `arkgate/runtime` | Kernel you construct with `createStrictArkKernel` (one instance per call) | A process-wide `getKernel()`; shipped cloud broker SDKs; production durability |
36
36
 
37
- Absence of the extra is **silent** — Layers and ArkRules verdicts stay identical. Doctor / status
38
- `arkRun` is always `notAScore`. Never invent 0–10 scores or pass/fail from this skill.
37
+ Absence of the extra is **silent** — Layers and ArkRules verdicts stay identical. Compact
38
+ doctor names ArkRun only when the extra is on (experimental, in-memory, not Postgres;
39
+ `/ark-runtime` when residual remains). Doctor / status `arkRun` is always `notAScore`.
40
+ Never invent 0–10 scores or pass/fail from this skill.
39
41
 
40
42
  ## Improvement compass note
41
43
 
@@ -143,7 +143,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
143
143
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
144
144
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
145
145
  4. After upgrade, leftover architecture work is **`/ark-autopilot`** (never invent `mechanical-safe`).
146
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` with `evidence.arkruleId`.
146
+ 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
147
147
  6. Schema `1.3` extras stay off unless already on. Pin teaches `arkgate/runtime` and `arkgate/order` (same tarball), not a second install. Wire after upgrade via `/ark-runtime` / `/ark-order`. Do not invent `/ark-run`.
148
148
 
149
149
 
@@ -28,5 +28,18 @@
28
28
  "description": "Prefer rich domain types over data-only bags (advisory only)."
29
29
  }
30
30
  ],
31
- "invariants": []
31
+ "invariants": [
32
+ {
33
+ "id": "INV-ALWAYS-VALID",
34
+ "description": "A domain object is never stored in an invalid state",
35
+ "mode": "advisory",
36
+ "coverage": { "test": false }
37
+ },
38
+ {
39
+ "id": "INV-ONE-DECISION",
40
+ "description": "Each business fact has one place that decides it",
41
+ "mode": "advisory",
42
+ "coverage": { "test": false }
43
+ }
44
+ ]
32
45
  }
@@ -21,11 +21,48 @@ has honest houses. Skills never enforce — CLI / hooks / CI do.
21
21
  ## Checklist
22
22
 
23
23
  - Existing tree: propose **SharedKernel** (types/constants) + **CompositionRoot** (wiring) + `src/**/domain/**`. Never dump bare `src/lib/**` into Application.
24
+ - Every `include` path must land in a layer. Include that classifies no file is the
25
+ same as an empty check — not a pass. Fix globs here; do not leave a loose gap.
24
26
  - Generate `.ark/golden-pattern.json` (load-bearing for `/ark-place`).
25
27
  - Future houses: mark unused layer globs `reserved` / `allowEmpty` so `--strict-config` does not fail.
26
28
  - When the product map or glossary names a house, write `layers[].description` as
27
29
  app-context copy (what this folder is *in the product*). Compact starter may omit.
28
30
  Do not invent captions. Do not invent `/ark-describe`.
31
+ - When the product map names who a folder is for, write `layers[].trustBoundary`
32
+ (`public` | `auth` | `admin` | `internal`). Compact starter may omit. Do not
33
+ invent tags. Absence is silent. No `/ark-trust`.
34
+ - When the product map names who owns a folder, write `layers[].owners`
35
+ (GitHub handle or email). Compact starter may omit. Do not invent people.
36
+ Absence is silent unless the user asked for required owners — then write
37
+ `requireLayerOwners: true` after the live houses have names. No `/ark-owners`.
38
+ - When the user wants required gates (`--require-gates` / `--strict-merge` /
39
+ required GitHub check) and there is no `docs/adr/` (or `docs/decisions/`),
40
+ leave a short decision note there — only if they loosen a rule or add a real
41
+ gate. Not every change. Doctor residual is soft. No `/ark-adr`.
42
+ - When a product-domain doc is already in play (`docs/domain.md` or a sibling)
43
+ and doctor JSON has `statesTransitions` or `statusTransitionCatalog`, add a
44
+ short states → transitions table (or one link) there. Use catalog names when
45
+ present. No flag soup. Soft residual. Silent when that doc is absent or
46
+ Domain has no status vocabulary. No `/ark-states`.
47
+ - When doctor JSON has `noDomainFrontend`, keep the empty Domain house — do not
48
+ delete it to “clean” empty layers. Next is one Domain file (`/ark-place`), not
49
+ a weaker contract. Soft. Silent when there is no frontend or Domain already
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.
29
66
  - CLI-first: if `arkgate-check` already resolved the root, do not wait on MCP.
30
67
  - Do not add `arkRun` or `arkOrder` unless the user wants that extra. When they do, write
31
68
  **advisory** extra in this turn (`arkRun` schema `1.2+`; `arkOrder` schema `1.3+`).
@@ -106,6 +143,46 @@ received."), not architecture jargon. Compact starter / `ark start` may omit the
106
143
  field. Absence is silent — never fail `--strict-config` for a missing caption.
107
144
  Do **not** invent captions. Do not invent `/ark-describe`.
108
145
 
146
+ ## Layer trust (process)
147
+
148
+ Optional `layers[].trustBoundary`: `public` | `auth` | `admin` | `internal`.
149
+ Marks who this folder is for (anyone, signed-in users, operators, or only
150
+ other code). Write it when the product map already names that door. Compact
151
+ starter / `ark start` may omit it. Absence is silent — never fail
152
+ `--strict-config`, never invent a doctor residual. Do **not** invent tags.
153
+ This is not host/CI TLS and does not add import-rule teeth. No `/ark-trust`.
154
+
155
+ ## Layer owners (process)
156
+
157
+ Optional `layers[].owners`: GitHub handles or emails (same identity as
158
+ `stewards` — not a display name). Write them when the product map already
159
+ names who owns the house. Compact starter / `ark start` may omit. Absence is
160
+ silent unless the user asked for required owners. Then write
161
+ `requireLayerOwners: true` only after every live (non-reserved) layer has
162
+ at least one owner. Do **not** invent people. No `/ark-owners`. The require
163
+ flag is the fail-closed switch; owners themselves are metadata.
164
+
165
+ ## Decision notes (process)
166
+
167
+ When gates are required (`--require-gates` / `--strict-merge` / required merge
168
+ status) and there is no short decision-note home yet, doctor may ask for one
169
+ under `docs/adr/` or `docs/decisions/`. Write a note when you loosen a rule or
170
+ add a real gate — not on every file. Absence is silent unless that demand is
171
+ on. The hint does not fail the check. Do **not** invent `/ark-adr`. Policy
172
+ weaken still uses `--policy-ack`; this is only a place to write the why.
173
+
174
+ ## States and transitions (process)
175
+
176
+ When a product-domain / domain-model doc is already on disk (`docs/domain.md`,
177
+ `docs/data-model.md`, or a dedicated `docs/states.md`) and there is no short
178
+ states → transitions table (or one link), doctor may ask for one. Write the
179
+ table on that home — entity · states · allowed from → to. Names from the
180
+ code or the captain. When doctor JSON has `statusTransitionCatalog`, use those
181
+ entity · states names — Domain already opted in by having that vocabulary.
182
+ Do **not** invent states or flag soup. Absence of the domain doc, or Domain
183
+ with no status union/enum, stays silent. The hint does not fail the check.
184
+ Do **not** invent `/ark-states`. Do not walk the tree to invent a roster.
185
+
109
186
  ## When / not when
110
187
 
111
188
  | Use `/ark-adopt` when… | Do **not** use it when… |
@@ -151,7 +228,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
151
228
  2. Never call an import-edge violation an “invariant” or an aggregate sensor a “layer deny.”
152
229
  3. Absence of `arkRules` is **valid** — do not force ArkRules unless the user wants them or residual inventory clearly wants a pilot.
153
230
  4. Editing `arkrules/*` or promoting modes is **this skill** (session 0) or **`/ark-autopilot`** later; never invent `mechanical-safe`.
154
- 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` with `evidence.arkruleId`.
231
+ 5. CLI helpers: `ark-check --rules-inventory --json`, doctor JSON `rulesUnderContract`, sensors emit `ARKRULE_*` / `INVARIANT_UNCOVERED` / `INVARIANT_CATALOG_EMPTY` with `evidence.arkruleId`.
155
232
  6. Absence of `arkRun` is **valid**. Write it only when the user wants the extra. Skills never enforce.
156
233
  7. Absence of `arkOrder` is **valid**. Write it only when the user wants the extra. After the extra is honest: handoff **`/ark-order`** to wire one candidate. Skills never enforce.
157
234
 
@@ -159,6 +236,7 @@ ArkGate has **always-on Layers** plus opt-in extras. The user chooses extras; yo
159
236
  ### Adopt + ArkRules
160
237
  - After classify: emit or refresh `arkRules` for matched layers (exact names; generic mold for unknowns).
161
238
  - Mine rules → inventory + write advisory invariants/structure into `arkrules/<Layer>.json` **in this turn**.
239
+ - Empty `invariants[]` on a populated Domain while `arkRules` is on is residual (`INVARIANT_CATALOG_EMPTY`), not done. Fill 1–2 short phrases. Advisory until a domain structure rule is `enforced`.
162
240
  - Application / Features templates include advisory `writes-via-aggregate`: driver import + write token in a use case is the skip. Do not copy `Externals/` / `admission.ts` folder religion.
163
241
  - Freeze baseline is **[Layer]** debt; inventory residual is **[ArkRules]** — report both.
164
242
 
@@ -222,6 +300,9 @@ feature dirs, plan clusters), you **may** dispatch **subagents**:
222
300
  - **Brownfield:** this skill — match config to reality; do not force a starter preset.
223
301
  - **Deep map only:** `/ark-explore`.
224
302
  - **Default path:** `ark start` → **`/ark-adopt`** → `/ark-place` / `/ark-autopilot`.
303
+ `start --apply` may refuse (coverage below 50% or weak shape) — that lock is
304
+ deliberate. Lock the shape with `--archetype`, `--preset`, or `--force`, or
305
+ inspect ranked shapes with `ark-check --recommend`.
225
306
 
226
307
  ## Anti-wrapper rule (mandatory)
227
308
 
@@ -248,6 +329,9 @@ Ark protects the **boundary around** a framework, not its internals. Nest/DI pub
248
329
  If `src/contexts` or `src/bounded-contexts` exists, prefer `ddd-bounded-contexts`.
249
330
  **Next.js:** `app/api/**` / `pages/api/**` (and route-group `app/(…)/api/**`) default to
250
331
  **ApplicationOrchestration**, not Presentation — do not reclassify API shells as UI.
332
+ Write Next-flavored `layers[].description` only when Next is actually present
333
+ (`next` dependency, `next.config.*`, or `app/page` / `pages/*` routes). Library and
334
+ package monorepos keep framework-free captions — `ark start` already does this.
251
335
  User wants the ArkRun extra → write **advisory** `arkRun` (schema `1.2+`, real
252
336
  `kernelRoots` preferred — `compositionRoots` alias, existing `managedLayers`) **in this turn**.
253
337
  User wants the ArkOrder extra → write **advisory** `arkOrder` (schema `1.3+`, real
@@ -255,6 +339,12 @@ Ark protects the **boundary around** a framework, not its internals. Nest/DI pub
255
339
  to a compact starter. Do not promote to enforced as the session-0 default.
256
340
  When the product map or glossary names a house, write `layers[].description` on that
257
341
  layer (app-context sentence). Compact starter may omit. Do not invent captions.
342
+ When the product map names who a folder is for, write `layers[].trustBoundary`
343
+ (`public` | `auth` | `admin` | `internal`). Do not invent tags.
344
+ When the product map names who owns a folder, write `layers[].owners`
345
+ (GitHub handle or email). Do not invent people. Write `requireLayerOwners`
346
+ only when the user asked for required owners and the live houses already
347
+ have names.
258
348
  2. **Check + diagnose** — `summary.concentrated` / dominant edge → fix contract first, don’t freeze.
259
349
  Cross-slice / cross-context `peerIsolation` hits are judgment: extract shared or events.
260
350
  The denial names its reason. `unclassifiable path` in bulk means shared code lives outside
@@ -268,6 +358,8 @@ Ark protects the **boundary around** a framework, not its internals. Nest/DI pub
268
358
  3. **Classify ungoverned** — use coverage `suggestions` **plus** dirs you discovered by reading;
269
359
  add layers/patterns **here** (write `ark.config.json`). When adding a layer the product map
270
360
  or glossary already names, write `layers[].description` on it (do not invent filler).
361
+ Write `layers[].trustBoundary` only when the product map already names that door.
362
+ Write `layers[].owners` only when the product map already names who owns the house.
271
363
  4. **Mine business rules → manifiesto** (model job — this is why the skill exists):
272
364
  - Scan for loose domain: validators, pricing/policy functions, `can*`/`calculate*`, magic business constants, publish/intent strings, logic in UI/hooks that belongs in Domain.
273
365
  - **ArkRules inventory (AR13):** run `ark-check --rules-inventory --json` for deterministic candidates
@@ -307,6 +399,10 @@ proposals applied or deferred, **phase**, **top Shape / design-weak opportunitie
307
399
  - Claim in-memory kernel stores are production durability.
308
400
  - Invent `/ark-run`. Use `/ark-order` after this door turns the extra on.
309
401
  - Invent `layers[].description` filler or a `/ark-describe` skill.
402
+ - Invent `layers[].trustBoundary` tags or a `/ark-trust` skill.
403
+ - Invent `layers[].owners` names or a `/ark-owners` skill.
404
+ - Invent `/ark-adr` or require a decision note on every change.
405
+ - Invent `/ark-states` or invent entity states / flag soup.
310
406
  - Claim Enforce while governed% is low, cores empty with I/O in Application, or core bags ungoverned.
311
407
  - End adopt with only “baseline written” when design-weak residual is visible in files you opened.
312
408