arkgate 4.6.3 → 4.6.5

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 (54) hide show
  1. package/CHANGELOG.md +64 -5
  2. package/README.md +7 -5
  3. package/bin/ark-check-runtime.mjs +98 -14
  4. package/bin/ark-mcp-runtime.mjs +54 -33
  5. package/bin/ark.mjs +1 -0
  6. package/bin/lib/adapter-contract.mjs +13 -9
  7. package/bin/lib/agent-projection-command.mjs +18 -0
  8. package/bin/lib/agent-projection.mjs +2 -2
  9. package/bin/lib/analysis-engine.mjs +5 -5
  10. package/bin/lib/ci-and-commands.mjs +3 -3
  11. package/bin/lib/ci-merge-boundary.mjs +89 -0
  12. package/bin/lib/config-contract.mjs +2 -0
  13. package/bin/lib/diagnostic-catalog.mjs +5 -4
  14. package/bin/lib/doctor-next-actions.mjs +17 -5
  15. package/bin/lib/doctor-plan.mjs +14 -0
  16. package/bin/lib/enforcement-honesty.mjs +2 -0
  17. package/bin/lib/graph-blind.mjs +15 -6
  18. package/bin/lib/install-migrate.mjs +10 -0
  19. package/bin/lib/invariant-coverage.mjs +6 -2
  20. package/bin/lib/managed-upgrade.mjs +9 -4
  21. package/bin/lib/presets.mjs +22 -0
  22. package/bin/lib/remediation.mjs +74 -10
  23. package/bin/lib/skill-install.mjs +2 -0
  24. package/bin/lib/snippet-analysis.mjs +40 -8
  25. package/bin/lib/upgrade-command.mjs +37 -4
  26. package/bin/lib/upgrade-whats-new.mjs +19 -1
  27. package/dist/{configTypes-B8uIcLaG.d.ts → configTypes-l6XiwiC1.d.ts} +7 -0
  28. package/dist/eslint/index.cjs +3 -3
  29. package/dist/eslint/index.d.ts +1 -1
  30. package/dist/eslint/index.js +3 -3
  31. package/dist/index.cjs +26 -26
  32. package/dist/index.d.ts +11 -2
  33. package/dist/index.js +29 -29
  34. package/docs/README.md +5 -4
  35. package/docs/agent-guide.md +12 -1
  36. package/docs/ai-gates.md +5 -0
  37. package/docs/brownfield-adoption.md +7 -1
  38. package/docs/configuration.md +2 -1
  39. package/docs/develop.md +5 -2
  40. package/docs/diagnostics.md +15 -5
  41. package/docs/package-surface.md +6 -5
  42. package/docs/threat-model.md +1 -1
  43. package/package.json +1 -1
  44. package/schemas/ark.config.schema.json +6 -0
  45. package/server.json +2 -2
  46. package/templates/agent-skills/README.md +1 -1
  47. package/templates/agent-skills/ark-adopt/SKILL.md +7 -0
  48. package/templates/agent-skills/ark-explore/SKILL.md +6 -0
  49. package/templates/agent-skills/ark-place/SKILL.md +11 -4
  50. package/templates/agent-skills/ark-upgrade/SKILL.md +22 -4
  51. package/templates/skills/ark-adopt.md +7 -0
  52. package/templates/skills/ark-explore.md +6 -0
  53. package/templates/skills/ark-place.md +11 -4
  54. package/templates/skills/ark-upgrade.md +22 -4
package/docs/README.md CHANGED
@@ -58,10 +58,11 @@ These are **not** the day-to-day product path. They stay in the repo for evidenc
58
58
  | Field adoption kit (scaffolding, not closed) | [field/](field/) |
59
59
  | Runtime hardening (experimental) | [production-hardening.md](production-hardening.md) |
60
60
 
61
- Current published: [releases/4.6.2.md](releases/4.6.2.md) (`arkgate@4.6.2` on npm `latest`).
62
- Prepared: [releases/4.6.3.md](releases/4.6.3.md) (Codex operation-scoped hard write; not yet published).
63
- Prior: [releases/4.6.1.md](releases/4.6.1.md) (`arkgate@4.6.1`).
64
- Previous: [releases/4.6.0.md](releases/4.6.0.md) · [releases/4.5.7.md](releases/4.5.7.md) · [releases/4.5.6.md](releases/4.5.6.md) · [releases/4.5.5.md](releases/4.5.5.md) · [releases/4.5.0.md](releases/4.5.0.md) · [releases/4.4.0.md](releases/4.4.0.md) · [releases/4.3.0.md](releases/4.3.0.md) · [releases/4.2.1.md](releases/4.2.1.md) · [releases/4.2.0.md](releases/4.2.0.md) · [releases/4.1.1.md](releases/4.1.1.md).
61
+ Current: [releases/4.6.5.md](releases/4.6.5.md) (`arkgate@4.6.5`).
62
+ Prior published: [releases/4.6.4.md](releases/4.6.4.md) (`arkgate@4.6.4` on npm `latest` until 4.6.5 lands).
63
+ Prior published: [releases/4.6.3.md](releases/4.6.3.md) (`arkgate@4.6.3`).
64
+ Prior: [releases/4.6.2.md](releases/4.6.2.md) (`arkgate@4.6.2`).
65
+ Previous: [releases/4.6.1.md](releases/4.6.1.md) · [releases/4.6.0.md](releases/4.6.0.md) · [releases/4.5.7.md](releases/4.5.7.md) · [releases/4.5.6.md](releases/4.5.6.md) · [releases/4.5.5.md](releases/4.5.5.md) · [releases/4.5.0.md](releases/4.5.0.md) · [releases/4.4.0.md](releases/4.4.0.md) · [releases/4.3.0.md](releases/4.3.0.md) · [releases/4.2.1.md](releases/4.2.1.md) · [releases/4.2.0.md](releases/4.2.0.md) · [releases/4.1.1.md](releases/4.1.1.md).
65
66
  Previous major: [releases/4.0.0.md](releases/4.0.0.md) (`arkgate@4.0.0`).
66
67
  Config: [configuration.md](configuration.md) · Agent skills dual-plane: [agent-guide.md](agent-guide.md).
67
68
 
@@ -86,6 +86,16 @@ npx ark status --json --expected-root /abs/project/root
86
86
  npx ark-check --doctor --json
87
87
  ```
88
88
 
89
+ `--doctor --json` is a stable envelope (4.6.5+): `{ "schemaVersion": "1.0", "envelope": "doctor", "ok": boolean, "doctor": { … } }`.
90
+ Payload lives only under `doctor`. Do not parse sibling root keys as the doctor object.
91
+
92
+ Doctor also writes `.ark/ci-merge-boundary.json` (hook configured-not-fired, per-host writePath,
93
+ CI present-but-not-required, GitHub Free cannot require). Read that file — do not grep `node_modules`.
94
+ Hook green is not tree green (scripted edits bypass PreToolUse).
95
+
96
+ CLI-first: if the local CLI already resolved the project root, identity handshake is optional.
97
+ Do not wait on MCP “still connecting”. The same projection schema is merged into `AGENTS.md` and `CLAUDE.md`.
98
+
89
99
  Product path: [use.md — Session recipe](use.md#session-recipe-agent-turn).
90
100
 
91
101
  ### Multi-project MCP and upgrade honesty (4.5.6)
@@ -97,7 +107,8 @@ One human often has **N checkouts** and **N package pins**. Product rules:
97
107
  | One checkout = one `project.expectedRoot` | Identity (WI01) fail-closes cross-project evidence when used correctly |
98
108
  | After `npm install arkgate@…`, restart/retarget Ark MCP | Process `arkgateVersion` is startup-loaded; long-lived MCP can lag install |
99
109
  | Read `processPackage` on every tool response | `processPackageMismatch` / `processStale` + `nextAction` when process ≠ project install |
100
- | Prefer project-local CLI until versions align | CLI always available; MCP analysis is not “fully current” while process is stale |
110
+ | Stale MCP in 4.6.4+ | `ark_identity` stays diagnostic; project tools return `PROCESS_PACKAGE_STALE` and top-level `authoritative:false` until restart |
111
+ | Prefer project-local CLI until versions align | A modern stale global `ark upgrade` hands off automatically; pre-4.6.4 globals need one `npx arkgate upgrade` entry |
101
112
  | Upgrade each package that pins arkgate | Monorepo “done” is not one package’s pin |
102
113
  | Registry-aware `ark upgrade --apply` | Does not false-skip when CLI == pin but registry is ahead; skip JSON has `reasonCode` + `suggestedInstallCmd` |
103
114
  | Skills: `skillDrift` + optional `--refresh-skills` | Customized skill bodies stay preserved unless you opt in; never silent overwrite of true edits |
package/docs/ai-gates.md CHANGED
@@ -416,6 +416,11 @@ observe a later MCP conversation from files alone. The matched `ark_identity` re
416
416
  runtime observation for that caller and live process; it does not mutate the setup JSON.
417
417
  `.codex/config.toml` by itself never upgrades `runtimeObserved` or `active`.
418
418
 
419
+ After a package bump, a long-lived Ark MCP whose package version no longer matches the project is
420
+ non-authoritative. `ark_identity` reports `processPackage.processStale`; project tools return
421
+ `PROCESS_PACKAGE_STALE` until Codex/local Desktop restarts or retargets the server. A modern
422
+ outside-tree/global `ark upgrade` hands the original invocation to the project-local CLI.
423
+
419
424
  Codex uses an operation-scoped hard local patch hook plus advisory MCP for discovery/validation
420
425
  and `ark-check` as the all-path hard merge backstop. Register all three as soon as the repo is
421
426
  adopted.
@@ -41,10 +41,16 @@ regenerate it unasked.
41
41
  | `app/api/**`, `src/app/api/**` | **ApplicationOrchestration** (orchestration shell) |
42
42
  | `pages/api/**`, `src/pages/api/**` | **ApplicationOrchestration** |
43
43
  | UI routes (`app/(…)`, `page.tsx`, `components/**`) | **PresentationAdapters** |
44
+ | Types / constants (`src/**/types/**`, `src/**/constants/**`) | **SharedKernel** |
45
+ | Wiring (`src/**/composition/**`, `src/**/factories/**`, `bootstrap.ts`) | **CompositionRoot** |
46
+ | `src/**/domain/**` | **DomainModel** |
47
+ | Flattened `src/lib/**` bag | **Not** Application as a whole — classify interiors (use-cases → Application; types → SharedKernel). Adopt never dumps bare `src/lib/**` into Application. |
44
48
 
45
49
  Without this split, broad `**/app/**` Presentation patterns push every API handler into UI and
46
50
  create a Presentation→Persistence tsunami. Specificity still wins: more-specific Application
47
- globs beat Presentation. ArkRules stay **opt-in** (not forced on by start/adopt).
51
+ globs beat Presentation. Adopt writes `.ark/golden-pattern.json` (load-bearing for `/ark-place`).
52
+ `ark_place` requires `filePath` (fail-closed — never invents `components/*.tsx` or defaults to Presentation).
53
+ ArkRules stay **opt-in** (not forced on by start/adopt).
48
54
 
49
55
  ### Composition-root / factory modules (optional Application-only)
50
56
 
@@ -90,6 +90,7 @@ Layer fields:
90
90
 
91
91
  - `name`, `patterns`, `exclude`, `description`
92
92
  - `intentPrefixes`, `forbiddenGlobals`, `mayImportInfrastructure`, `optional`
93
+ - `reserved` / `allowEmpty` — future houses whose globs match nothing yet. `--strict-config` does not fail; `CONFIG_LAYER_PATTERN_NO_MATCHES` (typo warning) is skipped. A typo warning fires only when the glob is not reserved.
93
94
  - `capabilities: { deny: [...] }` — opt-in effect walls over the seven capability ids
94
95
  (`network`, `filesystem`, `clock`, `randomness`, `environment`, `process`, `persistence`);
95
96
  `pure: true` is the shorthand that denies all seven. Absence changes no verdict.
@@ -254,7 +255,7 @@ now shows more authors, it shows the **gap** and asks whether to update. `/ark-a
254
255
  writes only after you confirm — it does not invent names or remove entries.
255
256
 
256
257
  ```json
257
- "stewards": ["pedroknigge", "Amarilla-David"]
258
+ "stewards": ["you", "your-co-steward"]
258
259
  ```
259
260
 
260
261
  Law files (`ark.config.json`, `arkrules/*`, `.ark-baseline.json`) are a different change
package/docs/develop.md CHANGED
@@ -75,6 +75,7 @@ can show `runtimeObserved: true` even when branch-protection policy is plan-unav
75
75
  | Session / project status snapshot | `ark status --json` · MCP `ark_status` · [session recipe](agent-guide.md#session-recipe-agent-turn) · schema `arkgate/schema/status-manifest` |
76
76
  | Status compass honesty | `improvementCompass.mode`: `full` \| `subset` \| `unavailable` · residual ⊆ doctor when `full` · [package-surface](package-surface.md) |
77
77
  | Managed upgrade self-service | `ark upgrade --json` → `selfService` (activation labels + customized preserve) · [package-surface](package-surface.md) |
78
+ | Stale MCP/global CLI recovery | `processPackage.processStale` → non-authoritative + `PROCESS_PACKAGE_STALE`; modern outside-tree `ark upgrade` hands off to project-local CLI |
78
79
  | Version-matched AGENTS projection | `ark agents-md` · [agent-guide](agent-guide.md) · **non-authoritative** (never enforces) |
79
80
  | Stable finding refs (`findingRef` / `targetKey`) | analysis-result schema **1.5** · [agent-guide](agent-guide.md) · [package-surface](package-surface.md) |
80
81
  | Agent Skills layout (same 13 names) | `templates/agent-skills/` · [agent-guide](agent-guide.md#install-skills-ark-and-ecosystem) · `npx skills add …` |
@@ -105,10 +106,12 @@ Sensors:
105
106
  ```bash
106
107
  npx arkgate-check --plan
107
108
  npx arkgate-check --coverage
108
- npx arkgate-check --doctor --json # improvementCompass (notAScore lenses) + status light
109
+ npx arkgate-check --doctor --json # stable envelope { schemaVersion, envelope:"doctor", ok, doctor }
109
110
  ```
110
111
 
111
- Doctor residual lenses never flip `valid` / strict-merge alone. Product path:
112
+ `--doctor --json` payload lives only under `doctor`. Doctor also writes `.ark/ci-merge-boundary.json`
113
+ (writePath per host, hook configured-not-fired, CI present-but-not-required, GitHub Free cannot
114
+ require). Hook green is not tree green. Doctor residual lenses never flip `valid` / strict-merge alone. Product path:
112
115
  [use.md — Improvement compass](use.md#improvement-compass-not-a-score).
113
116
 
114
117
  Agent reference (tools, skills, dual path): [agent-guide.md](agent-guide.md).
@@ -56,6 +56,7 @@ Link form for agents: `docs/diagnostics.md#RULE_ID` (exact-case HTML anchors bel
56
56
  | [`ATOMIC_PREFLIGHT_UNAVAILABLE`](#ATOMIC_PREFLIGHT_UNAVAILABLE) | preflight | Atomic preflight unavailable |
57
57
  | [`DESIGN_SMELL_REGRESSION`](#DESIGN_SMELL_REGRESSION) | preflight | Design smell regression on base-relative ratchet |
58
58
  | [`ANALYSIS_PARSE_INCOMPLETE`](#ANALYSIS_PARSE_INCOMPLETE) | analysis | Parse incomplete |
59
+ | [`LEXICAL_EVIDENCE_INCOMPLETE`](#LEXICAL_EVIDENCE_INCOMPLETE) | analysis | Lexical evidence incomplete |
59
60
  | [`ANALYSIS_HOST_UNAVAILABLE`](#ANALYSIS_HOST_UNAVAILABLE) | analysis | Analysis host unavailable |
60
61
  | [`ADAPTER_NOT_ALLOWED_FOR_PORT`](#ADAPTER_NOT_ALLOWED_FOR_PORT) | adapter | Adapter not allowed for port |
61
62
  | [`FORBIDDEN_PATTERN`](#FORBIDDEN_PATTERN) | snippet-policy | Forbidden regex pattern |
@@ -89,7 +90,7 @@ Link form for agents: `docs/diagnostics.md#RULE_ID` (exact-case HTML anchors bel
89
90
  **Layer import not allowed**
90
91
 
91
92
  - **Why:** A module import (or re-export) crosses a layer edge that ark.config.json does not allow. The architecture contract forbids that dependency direction so outer infrastructure cannot leak into pure or inner layers.
92
- - **Fix:** Define a port in the source layer, inject the outer-layer implementation, or move/share the type with `import type` when the edge is type-only then preflight again. Do not weaken the layer rule without a hash-bound policy acknowledgement.
93
+ - **Fix:** Branch by import kind: constants/types/pure → adopt into DomainModel or SharedKernel (do not invent a port); kernel/events/bootstrap from Persistence inject a port or move the map to SharedTypes (Persistence must not emit); define a port only when the target is a real use-case. Type-only edges use `import type`. Then preflight again. Do not weaken the layer rule without a hash-bound policy acknowledgement.
93
94
 
94
95
  <a id="LAYER_INTENT_REFERENCE_VIOLATION"></a>
95
96
 
@@ -267,8 +268,8 @@ Link form for agents: `docs/diagnostics.md#RULE_ID` (exact-case HTML anchors bel
267
268
 
268
269
  **Invariant without coverage evidence**
269
270
 
270
- - **Why:** An ArkRules invariant is under contract but no covering test title or declared symbol evidence was found (or coverage is partial).
271
- - **Fix:** Add a test title or declared symbol covering the arkruleId, then preflight again. Missing test globs report partial — never fake green.
271
+ - **Why:** An ArkRules invariant is under contract but no covering test title or declared symbol evidence was found (or coverage is partial). Kind is `never-had-tests` (adopt residual) vs `tests-disappeared` (suite exists).
272
+ - **Fix:** Add a test title or declared symbol covering the arkruleId, then preflight again. Treat never-had-tests as adopt residual; treat tests-disappeared as a regression. Missing test globs report partial — never fake green.
272
273
 
273
274
  ## Atomic preflight and change sets
274
275
 
@@ -379,8 +380,17 @@ Link form for agents: `docs/diagnostics.md#RULE_ID` (exact-case HTML anchors bel
379
380
 
380
381
  **Parse incomplete**
381
382
 
382
- - **Why:** Governed source could not be fully parsed; analysis is partial and must not paint green.
383
- - **Fix:** Fix syntax/parse errors in governed files (or restore a usable TypeScript host), then re-run. Partial never means pass.
383
+ - **Why:** Governed source could not be fully parsed; evidence includes the TypeScript diagnostic (line + message). Incremental mid-edit parse is normal for agents. Contract `exclude` paths skip the write hook.
384
+ - **Fix:** Finish the source or fix the reported syntax error, then re-run `npx arkgate-check`. The write hook does not deny solely on mid-edit parse. Partial never means pass.
385
+
386
+ <a id="LEXICAL_EVIDENCE_INCOMPLETE"></a>
387
+
388
+ ### `LEXICAL_EVIDENCE_INCOMPLETE`
389
+
390
+ **Lexical evidence incomplete**
391
+
392
+ - **Why:** Single-file validation cannot prove project module resolution. The write hook is already the verdict.
393
+ - **Fix:** Re-run `npx arkgate-check --root . --config ark.config.json`, or treat the hook deny as final. Do not call `ark_prepare_change` from a hook deny.
384
394
 
385
395
  <a id="ANALYSIS_HOST_UNAVAILABLE"></a>
386
396
 
@@ -21,9 +21,9 @@ hardening guide remains repository-hosted rather than duplicated in the gate tar
21
21
  | **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. |
22
22
  | **Improvement compass (4.4; status honesty 4.5)** | `ark-check --doctor --json` → `doctor.improvementCompass`; human doctor section **Improvement compass (not a score)**; HTML report `data-advisory="improvementCompass"`. **`ark status --json` / MCP `ark_status`** project a thin `improvementCompass` residual map with explicit honesty **`mode`**: `full` \| `subset` \| `unavailable` (always `notAScore: true`). When `mode` is `full`, status residual lens **ids** are a **subset of** doctor residual for the same facts (report snapshot stores the thin slice after `--report`). Incomplete or missing session facts → `subset` / `unavailable` + `reasonCode` / `reason` — **never invent green residual**. Residual never flips `valid` / strict-merge / `goal.met`. When status mode ≠ full, run doctor for full 15-lens detail. | Additive schema `1.0`. Closed **15** lens ids (`soc`, `cohesion`, `coupling`, `srp`, `dip`, `ocp`, `encapsulation`, `modularity`, `scalability`, `resilience`, `security`, `maintainability`, `testability`, `domain`, `stack`) with status `ok` \| `residual` \| `not-instrumented` \| `out-of-scope`, evidence refs, optional `nextAction`, capped `topResidual`, always **`notAScore: true`**. Projection from existing smells / walls / cohesion / ArkRules / design-weak only — **never** a gate input. Out-of-scope locked for scalability, resilience, and app security (no residual invent from missing SAST/APM). Root API: `buildImprovementCompass` / `IMPROVEMENT_LENS_IDS`; status: `projectStatusImprovementCompass` / `STATUS_COMPASS_MODES`. |
23
23
  | **Deep-module coach (post-4.5 advisory)** | `ark-check --doctor --json` → `doctor.deepModuleCoach`; human doctor section **Deep-module coach (advisory — not a score)** always when doctor runs (empty candidates / hot-path `unavailable` are honesty, not omission); HTML `data-advisory="deepModuleCoach"`. | Additive schema `1.0`. Always **`notAScore: true`**. **`hotPaths`**: recent-churn heuristic from bounded git log; `available` + `status` `ok` \| `unavailable`; empty `paths` when history missing/incomplete — **never invent**. **`deepeningCandidates`**: cards projected only from existing design smells / physical cohesion / reshape pilot / pilotLoop / residual compass lenses — **empty when no evidence** (no fake candidates). Never flips `valid`, strict-merge, completeness green, or `goal.met`. Prefer deep modules / named seams / test-at-public-interface process language in skills. Domain pure + CLI gen mirror (`deepeningCoach.ts` / `bin/lib/deepening-coach.mjs`); **not** a root package export — consume via `doctor.deepModuleCoach` (or the gen mirror in Tooling). |
24
- | **Upgrade what’s new (4.5.6+)** | `ark upgrade --json` → `whatsNew` (+ human **Suggested improvements** block; also on preview). | Always **`notAScore: true`**, **`neverGateInput: true`**. Closed try/inspect list: deep-module coach, improvement compass, session/status honesty, two-axis done, self-service honesty, registry-aware upgrade, skill drift/refresh, multi-project MCP. Never invents residual or flips gates. |
24
+ | **Upgrade what’s new (4.5.6+)** | `ark upgrade --json` → `whatsNew` (+ human **Suggested improvements** block; also on preview). | Always **`notAScore: true`**, **`neverGateInput: true`**. Closed try/inspect list: deep-module coach, improvement compass, session/status honesty, two-axis done, self-service honesty, registry-aware upgrade, skill drift/refresh, multi-project MCP, Codex hard-write refresh/trust/restart/verify, stale MCP/global CLI recovery. Never invents residual or flips gates. |
25
25
  | **Field upgrade truth (4.5.6)** | `ark upgrade` registry-aware install; JSON `reasonCode` / `suggestedInstallCmd`; `skillDrift`; `--refresh-skills`; `postUpgradeChecks`; `hostSelection`. | No false-skip when registry ahead; offline honesty; customized skills preserved unless opt-in refresh; checks are advisory only. |
26
- | **MCP process package honesty (4.5.6)** | Every MCP tool context → `processPackage` (`processPackageMismatch` / `processStale`, versions, `nextAction`). | Multi-checkout users: restart MCP after pin bump; prefer project-local CLI until identity matched and versions align. Fail-closed identity (WI01) unchanged. |
26
+ | **MCP process package honesty (4.5.6; fail-closed in 4.6.4)** | Every MCP tool context → `processPackage` (`processPackageMismatch` / `processStale`, versions, `nextAction`). | Multi-checkout users: restart MCP after pin bump. From 4.6.4, stale process context is non-authoritative; `ark_identity` remains diagnostic and project tools return `PROCESS_PACKAGE_STALE` until restart/retarget. Prefer project-local CLI until identity matched and versions align. |
27
27
  | **Doctor design fitness** | `ark-check --doctor --json` → `doctor.designFitness`, `doctor.designSmells[]` | Additive. Stable smell `id`s: `io-under-application`, `handler-in-persistence`, `god-module`, `domain-logic-in-ui`, `facade-sql-in-routes`, `mixed-pattern-cluster`, `soft-contract`. `handler-in-persistence` covers static ES imports/re-exports of framework HTTP surfaces (`next/server`), `defineRoute` calls, and existing handler bodies inside Persistence-role layers or specific persistence paths; `require()` and dynamic `import()` are outside this narrow advisory, and a generic `Infrastructure` role alone is not Persistence. Persistence candidates are filtered and sorted before the bounded content scan so large application prefixes cannot hide the advisory. The detector inspects the first 800 sorted Persistence candidates; later candidates are uninspected, so **absence of a smell is not full-tree proof** above that envelope (incomplete/`partial` analysis also never proves “no smells”). **4.2 feedback hardening:** mode labels preserve the observed SUGGEST/ADAPT/ENFORCE state; a local permission/UI-state `canEdit` name alone is not a domain smell; real UI business rules route Domain → Application → UI; seed/fixture/demo/migration/generated files are not god-module pilots. Each smell has `evidence[]`, `fix`, technical `message`, and plain-language **`outcome`**. Does **not** fail the gate by itself. |
28
28
  | **Post-green Shape door** | `doctor.postGreenPath`, `doctor.primaryNextAction`, `doctor.healthyFinishedForbidden` | Additive when `designFitness.designWeak`. Single Shape door (`id: clarify-for-ai`): explore shape-focus → dual-plan B → autopilot only with OK. Never empty plan A = healthy finished. |
29
29
  | **Golden pattern (new code)** | Optional `.ark/golden-pattern.json`; doctor JSON `doctor.goldenPattern`; MCP `ark_place` / `ark_prepare_write` → `goldenPattern` | Additive, **advisory for NEW code only**. Required fields: `name`, `norm`; optional `newCodeHome`, `examplePath`, `schemaVersion`. **Absent is normal** (no claim). Never ENFORCE; never clears design-weak. Malformed → `invalid: true`, not silent guidance. |
@@ -211,9 +211,10 @@ production deployment would need to satisfy; it is not a readiness certification
211
211
  ## Release notes (maintainers)
212
212
 
213
213
  Ship notes for a version live under [releases/](https://github.com/pedroknigge/arkgate/tree/main/docs/releases)
214
- (prepared: [4.6.3.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.3.md);
215
- current published: [4.6.2.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.2.md);
216
- prior published: [4.6.1.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.1.md), [4.6.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.0.md), [4.5.7.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.5.7.md), [4.5.6.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.5.6.md), [4.5.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.5.0.md), [4.4.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.4.0.md), [4.3.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.3.0.md),
214
+ (current: [4.6.5.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.5.md);
215
+ prior published: [4.6.4.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.4.md);
216
+ prior published: [4.6.3.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.3.md);
217
+ prior published: [4.6.2.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.2.md), [4.6.1.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.1.md), [4.6.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.6.0.md), [4.5.7.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.5.7.md), [4.5.6.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.5.6.md), [4.5.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.5.0.md), [4.4.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.4.0.md), [4.3.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.3.0.md),
217
218
  [4.2.1.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.2.1.md);
218
219
  previous: [4.2.0.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.2.0.md),
219
220
  [4.1.1.md](https://github.com/pedroknigge/arkgate/blob/main/docs/releases/4.1.1.md),
@@ -32,7 +32,7 @@ infrastructure beyond how this package is published.
32
32
  | T3 | CI job missing / not required | Merge green without architecture | doctor `enforcement-ci-*` gaps; `--strict-merge`; required-status remains locally `unverified` |
33
33
  | T4 | Config weakened (`peerIsolation: false`, empty rules) | False green | semantic policy-delta guard in strict merge; hash-bound explicit acknowledgement; present-state safety diagnostics |
34
34
  | T5 | Baseline ratcheted open | Debt reintroduced | baseline unused/stale signals; occurrence keys |
35
- | T6 | Dual MCP bin / wrong root | Gate points at wrong tree | migrate-commands; Codex fail-closed temp roots |
35
+ | T6 | Stale MCP/global CLI or wrong root | Gate points at old package / wrong tree | project identity binding; stale process non-authoritative + `PROCESS_PACKAGE_STALE`; project-local upgrade handoff |
36
36
  | T7 | Malicious dependency in publish | Compromised gate | signed tags, npm provenance, dependency-review, CodeQL, Semgrep, `verify-package-files` |
37
37
  | T8 | Path traversal in hooks/check | Read/write outside project | root resolution + under-root import resolve |
38
38
  | T9 | Runtime InMemory mistaken for durable | Data loss | durability stance docs + safety InMemory production detector |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkgate",
3
- "version": "4.6.3",
3
+ "version": "4.6.5",
4
4
  "description": "One architecture config. One check. One coach.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -723,6 +723,12 @@
723
723
  },
724
724
  "optional": {
725
725
  "type": "boolean"
726
+ },
727
+ "reserved": {
728
+ "type": "boolean"
729
+ },
730
+ "allowEmpty": {
731
+ "type": "boolean"
726
732
  }
727
733
  }
728
734
  },
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.6.3",
9
+ "version": "4.6.5",
10
10
  "packages": [
11
11
  {
12
12
  "registryType": "npm",
13
13
  "identifier": "arkgate",
14
- "version": "4.6.3",
14
+ "version": "4.6.5",
15
15
  "runtimeHint": "npx",
16
16
  "transport": {
17
17
  "type": "stdio"
@@ -7,7 +7,7 @@
7
7
  This directory is the **Agent Skills–compatible** packaging of the same **13**
8
8
  `/ark-*` skills shipped as flat templates for Ark install. **No new skill names.**
9
9
 
10
- Package version when last generated context: **arkgate@4.6.2**
10
+ Package version when last generated context: **arkgate@4.6.5**
11
11
  Schema: agent-skills package contract `1.0`
12
12
 
13
13
  ## Skills (frozen catalog)
@@ -14,6 +14,13 @@ description: Session 0 — mark the Ark path. Greenfield scaffold or brownfield
14
14
  2. Write `ark.config.json` (and a baseline only for genuine debt) in this turn.
15
15
  3. Re-run doctor. Day-to-day new files: `/ark-place`.
16
16
 
17
+ ## Checklist
18
+
19
+ - Existing tree: propose **SharedKernel** (types/constants) + **CompositionRoot** (wiring) + `src/**/domain/**`. Never dump bare `src/lib/**` into Application.
20
+ - Generate `.ark/golden-pattern.json` (load-bearing for `/ark-place`).
21
+ - Future houses: mark unused layer globs `reserved` / `allowEmpty` so `--strict-config` does not fail.
22
+ - CLI-first: if `arkgate-check` already resolved the root, do not wait on MCP.
23
+
17
24
  Invoking this skill **is** the approval. Write the architecture config in this turn.
18
25
  Greenfield: scaffold like `--recommend`. Brownfield: match **product
19
26
  reality**, freeze only genuine debt. A green check over a wrong config is a **false green**.
@@ -14,6 +14,12 @@ description: Map skill — decision-grade recon of layers + ArkRules opportuniti
14
14
  2. Open the real tree (≥12 files across ≥4 dirs). CLI JSON alone is incomplete.
15
15
  3. Rank leftover work. Hand off to `/ark-autopilot` to apply one refactor. Do not write config or product code here.
16
16
 
17
+ ## Checklist
18
+
19
+ - Doctor #1: if ENFORCE + empty plan A and gates are already installed → **Shape** (`/ark-explore` then `/ark-autopilot`). Do not say install-agent-gates.
20
+ - Distinguish **missing** skills vs **stale** catalog. Installed ≠ stale.
21
+ - Hook green is not tree green (scripted edits bypass PreToolUse).
22
+
17
23
  ## Autonomy contract
18
24
 
19
25
  Invoking this skill **is** the approval to **map**. Open the real tree. CLI JSON alone is
@@ -10,16 +10,23 @@ description: "Where does new code go? Names the layer, directory, and naming for
10
10
 
11
11
  ## Steps
12
12
 
13
- 1. Bind identity if using MCP (`ark_identity` with the exact project root).
14
- 2. Place the file (`ark_place` or read `ark.config.json`).
13
+ 1. CLI-first: if the local CLI already resolved the root, skip waiting on MCP. Identity is optional then.
14
+ 2. Place with **filePath required** (`ark_place` or read `ark.config.json` + `.ark/golden-pattern.json`). Fail-closed without a path — never invent `components/*.tsx` or default to Presentation.
15
15
  3. Write it there. Then `arkgate-check`.
16
16
 
17
+ ## Checklist
18
+
19
+ - `filePath` is known before the call. Description alone is not a path.
20
+ - Golden pattern is load-bearing when present. Adopt generates it.
21
+ - Do not default a repository to Presentation.
22
+
17
23
  ## Autonomy contract
18
24
 
19
25
  Invoking this skill **is** the approval. If the user described an artifact, **write the
20
26
  files** in this turn (prepare-write + scaffold). A path table alone is incomplete.
21
- The CLI is a **sensor and gate**. **CLI budget:** `ark_identity` then `ark_place` (or
22
- read `ark.config.json`); write; `ark-check`. Do not ask which layer they prefer.
27
+ The CLI is a **sensor and gate**. **CLI budget:** `ark_identity` then `ark_place` when using MCP
28
+ (or skip identity if the CLI already resolved the root); otherwise read `ark.config.json`; write;
29
+ `ark-check`. Do not ask which layer they prefer.
23
30
 
24
31
  **Still never:** weaken `ark.config.json`; invent `mechanical-safe` kinds; claim leftover
25
32
  design work is finished because one file landed.
@@ -10,10 +10,17 @@ description: Upgrade ArkGate through a content-identity preview, preserve custom
10
10
 
11
11
  ## Steps
12
12
 
13
- 1. Preview: `arkgate upgrade` (no writes).
14
- 2. Apply in this turn: `arkgate upgrade --apply` (needs `--plan-digest` when applying managed files).
13
+ 1. Preview: `arkgate upgrade` (no writes). Default is **hosts keep** — do not retire other hosts’ skills.
14
+ 2. Apply in this turn: `arkgate upgrade --apply` (installs the bumped package unless `--no-install`). Needs `--plan-digest` when applying managed files.
15
15
  3. Re-run `arkgate-check --doctor`. Customized files stay unless you pass `--accept-conflicts` / `--refresh-skills`.
16
16
 
17
+ ## Checklist
18
+
19
+ - Preview unions `--tools` with hosts already in the repo. Multi-agent trees keep every host.
20
+ - Apply must run the package install of the new pin. Do not skip `npm install` unless `--no-install` is explicit.
21
+ - Refresh AGENTS.md **and** CLAUDE.md (same projection schema).
22
+ - Prefer project `.agents/skills`. Do not duplicate the catalog into `~/.codex/skills`.
23
+
17
24
  The preview is the source of truth. Do not treat a filename or package version as proof of ownership.
18
25
 
19
26
  ## Autonomy contract
@@ -58,6 +65,15 @@ line (advisory only — not a score):
58
65
  6. **Registry-aware upgrade** — `reasonCode` / `suggestedInstallCmd` when package install is skipped or needed
59
66
  7. **Skill drift + refresh** — `skillDrift`; opt-in `--refresh-skills` for customized skill rewrite
60
67
  8. **Multi-project MCP** — `processPackage` mismatch/stale on every MCP tool; restart after package bump
68
+ 9. **Codex hard write refresh** — run
69
+ `npx arkgate-check --install-agent-gates --tools codex --force`, restart Codex/local Desktop,
70
+ review and trust the exact hook, then inspect `doctor.writePath` after a governed
71
+ `apply_patch`. Only a complete runtime-observed local patch is hard; every other path still
72
+ relies on required CI.
73
+ 10. **Stale process recovery** — a stale Ark MCP is non-authoritative and project tools return
74
+ `PROCESS_PACKAGE_STALE` until restart/retarget. If a modern global `ark upgrade` is older than
75
+ the project install, it hands the same invocation to the project-local CLI instead of managing
76
+ the project from the stale PATH binary.
61
77
 
62
78
  Never invent gate verdicts from these suggestions. Missing residual is honest empty, not green.
63
79
 
@@ -95,8 +111,10 @@ restart/retargeting is required. `ark://manifest` never satisfies this preflight
95
111
 
96
112
  **Process package honesty:** every tool response includes `processPackage` (`processArkgateVersion`,
97
113
  `projectInstalledVersion`, `processPackageMismatch` / `processStale`, `nextAction`). After
98
- `npm install arkgate@…`, **restart/retarget MCP** so process version matches install. Until then,
99
- prefer project-local CLI and do not treat MCP analysis as fully current.
114
+ `npm install arkgate@…`, **restart/retarget MCP** so process version matches install. From 4.6.4,
115
+ a stale MCP is non-authoritative: `ark_identity` diagnoses it and project tools return
116
+ `PROCESS_PACKAGE_STALE` until restart. Prefer project-local CLI meanwhile. A modern stale global
117
+ `ark upgrade` hands off automatically; pre-4.6.4 globals need one `npx arkgate upgrade` entry.
100
118
 
101
119
  ## Dual plane — layers + ArkRules (mandatory, except /ark-runtime)
102
120
 
@@ -14,6 +14,13 @@ description: Session 0 — mark the Ark path. Greenfield scaffold or brownfield
14
14
  2. Write `ark.config.json` (and a baseline only for genuine debt) in this turn.
15
15
  3. Re-run doctor. Day-to-day new files: `/ark-place`.
16
16
 
17
+ ## Checklist
18
+
19
+ - Existing tree: propose **SharedKernel** (types/constants) + **CompositionRoot** (wiring) + `src/**/domain/**`. Never dump bare `src/lib/**` into Application.
20
+ - Generate `.ark/golden-pattern.json` (load-bearing for `/ark-place`).
21
+ - Future houses: mark unused layer globs `reserved` / `allowEmpty` so `--strict-config` does not fail.
22
+ - CLI-first: if `arkgate-check` already resolved the root, do not wait on MCP.
23
+
17
24
  Invoking this skill **is** the approval. Write the architecture config in this turn.
18
25
  Greenfield: scaffold like `--recommend`. Brownfield: match **product
19
26
  reality**, freeze only genuine debt. A green check over a wrong config is a **false green**.
@@ -14,6 +14,12 @@ description: Map skill — decision-grade recon of layers + ArkRules opportuniti
14
14
  2. Open the real tree (≥12 files across ≥4 dirs). CLI JSON alone is incomplete.
15
15
  3. Rank leftover work. Hand off to `/ark-autopilot` to apply one refactor. Do not write config or product code here.
16
16
 
17
+ ## Checklist
18
+
19
+ - Doctor #1: if ENFORCE + empty plan A and gates are already installed → **Shape** (`/ark-explore` then `/ark-autopilot`). Do not say install-agent-gates.
20
+ - Distinguish **missing** skills vs **stale** catalog. Installed ≠ stale.
21
+ - Hook green is not tree green (scripted edits bypass PreToolUse).
22
+
17
23
  ## Autonomy contract
18
24
 
19
25
  Invoking this skill **is** the approval to **map**. Open the real tree. CLI JSON alone is
@@ -10,16 +10,23 @@ description: "Where does new code go? Names the layer, directory, and naming for
10
10
 
11
11
  ## Steps
12
12
 
13
- 1. Bind identity if using MCP (`ark_identity` with the exact project root).
14
- 2. Place the file (`ark_place` or read `ark.config.json`).
13
+ 1. CLI-first: if the local CLI already resolved the root, skip waiting on MCP. Identity is optional then.
14
+ 2. Place with **filePath required** (`ark_place` or read `ark.config.json` + `.ark/golden-pattern.json`). Fail-closed without a path — never invent `components/*.tsx` or default to Presentation.
15
15
  3. Write it there. Then `arkgate-check`.
16
16
 
17
+ ## Checklist
18
+
19
+ - `filePath` is known before the call. Description alone is not a path.
20
+ - Golden pattern is load-bearing when present. Adopt generates it.
21
+ - Do not default a repository to Presentation.
22
+
17
23
  ## Autonomy contract
18
24
 
19
25
  Invoking this skill **is** the approval. If the user described an artifact, **write the
20
26
  files** in this turn (prepare-write + scaffold). A path table alone is incomplete.
21
- The CLI is a **sensor and gate**. **CLI budget:** `ark_identity` then `ark_place` (or
22
- read `ark.config.json`); write; `ark-check`. Do not ask which layer they prefer.
27
+ The CLI is a **sensor and gate**. **CLI budget:** `ark_identity` then `ark_place` when using MCP
28
+ (or skip identity if the CLI already resolved the root); otherwise read `ark.config.json`; write;
29
+ `ark-check`. Do not ask which layer they prefer.
23
30
 
24
31
  **Still never:** weaken `ark.config.json`; invent `mechanical-safe` kinds; claim leftover
25
32
  design work is finished because one file landed.
@@ -10,10 +10,17 @@ description: Upgrade ArkGate through a content-identity preview, preserve custom
10
10
 
11
11
  ## Steps
12
12
 
13
- 1. Preview: `arkgate upgrade` (no writes).
14
- 2. Apply in this turn: `arkgate upgrade --apply` (needs `--plan-digest` when applying managed files).
13
+ 1. Preview: `arkgate upgrade` (no writes). Default is **hosts keep** — do not retire other hosts’ skills.
14
+ 2. Apply in this turn: `arkgate upgrade --apply` (installs the bumped package unless `--no-install`). Needs `--plan-digest` when applying managed files.
15
15
  3. Re-run `arkgate-check --doctor`. Customized files stay unless you pass `--accept-conflicts` / `--refresh-skills`.
16
16
 
17
+ ## Checklist
18
+
19
+ - Preview unions `--tools` with hosts already in the repo. Multi-agent trees keep every host.
20
+ - Apply must run the package install of the new pin. Do not skip `npm install` unless `--no-install` is explicit.
21
+ - Refresh AGENTS.md **and** CLAUDE.md (same projection schema).
22
+ - Prefer project `.agents/skills`. Do not duplicate the catalog into `~/.codex/skills`.
23
+
17
24
  The preview is the source of truth. Do not treat a filename or package version as proof of ownership.
18
25
 
19
26
  ## Autonomy contract
@@ -58,6 +65,15 @@ line (advisory only — not a score):
58
65
  6. **Registry-aware upgrade** — `reasonCode` / `suggestedInstallCmd` when package install is skipped or needed
59
66
  7. **Skill drift + refresh** — `skillDrift`; opt-in `--refresh-skills` for customized skill rewrite
60
67
  8. **Multi-project MCP** — `processPackage` mismatch/stale on every MCP tool; restart after package bump
68
+ 9. **Codex hard write refresh** — run
69
+ `npx arkgate-check --install-agent-gates --tools codex --force`, restart Codex/local Desktop,
70
+ review and trust the exact hook, then inspect `doctor.writePath` after a governed
71
+ `apply_patch`. Only a complete runtime-observed local patch is hard; every other path still
72
+ relies on required CI.
73
+ 10. **Stale process recovery** — a stale Ark MCP is non-authoritative and project tools return
74
+ `PROCESS_PACKAGE_STALE` until restart/retarget. If a modern global `ark upgrade` is older than
75
+ the project install, it hands the same invocation to the project-local CLI instead of managing
76
+ the project from the stale PATH binary.
61
77
 
62
78
  Never invent gate verdicts from these suggestions. Missing residual is honest empty, not green.
63
79
 
@@ -95,8 +111,10 @@ restart/retargeting is required. `ark://manifest` never satisfies this preflight
95
111
 
96
112
  **Process package honesty:** every tool response includes `processPackage` (`processArkgateVersion`,
97
113
  `projectInstalledVersion`, `processPackageMismatch` / `processStale`, `nextAction`). After
98
- `npm install arkgate@…`, **restart/retarget MCP** so process version matches install. Until then,
99
- prefer project-local CLI and do not treat MCP analysis as fully current.
114
+ `npm install arkgate@…`, **restart/retarget MCP** so process version matches install. From 4.6.4,
115
+ a stale MCP is non-authoritative: `ark_identity` diagnoses it and project tools return
116
+ `PROCESS_PACKAGE_STALE` until restart. Prefer project-local CLI meanwhile. A modern stale global
117
+ `ark upgrade` hands off automatically; pre-4.6.4 globals need one `npx arkgate upgrade` entry.
100
118
 
101
119
  ## Dual plane — layers + ArkRules (mandatory, except /ark-runtime)
102
120