arkgate 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +97 -0
  2. package/README.md +98 -70
  3. package/bin/ark-check.mjs +240 -1001
  4. package/bin/ark-layer-match.mjs +153 -147
  5. package/bin/ark-mcp.mjs +102 -5
  6. package/bin/ark-shared.mjs +304 -165
  7. package/bin/ark.mjs +44 -34
  8. package/bin/lib/agent-gates.mjs +448 -15
  9. package/bin/lib/architecture-scan.mjs +279 -0
  10. package/bin/lib/ast-scan.mjs +199 -0
  11. package/bin/lib/baseline-key.mjs +23 -0
  12. package/bin/lib/config-warnings.mjs +228 -0
  13. package/bin/lib/doctor-plan.mjs +11 -4
  14. package/bin/lib/graph-cycles.mjs +56 -0
  15. package/bin/lib/presets.mjs +75 -4
  16. package/bin/lib/remediation.mjs +150 -0
  17. package/bin/lib/scan-files.mjs +69 -0
  18. package/bin/lib/ts-resolve.mjs +215 -0
  19. package/bin/lib/violations.mjs +3 -9
  20. package/dist/eslint/index.cjs +21 -3
  21. package/dist/eslint/index.cjs.map +1 -1
  22. package/dist/eslint/index.d.cts +5 -3
  23. package/dist/eslint/index.d.ts +5 -3
  24. package/dist/eslint/index.js +21 -3
  25. package/dist/eslint/index.js.map +1 -1
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.cjs.map +1 -1
  28. package/dist/index.d.cts +3 -3
  29. package/dist/index.d.ts +3 -3
  30. package/dist/index.js +1 -1
  31. package/dist/index.js.map +1 -1
  32. package/dist/nestjs/index.cjs +1 -1
  33. package/dist/nestjs/index.cjs.map +1 -1
  34. package/dist/nestjs/index.d.cts +1 -1
  35. package/dist/nestjs/index.d.ts +1 -1
  36. package/dist/nestjs/index.js +1 -1
  37. package/dist/nestjs/index.js.map +1 -1
  38. package/dist/runtime/index.cjs +3080 -0
  39. package/dist/runtime/index.cjs.map +1 -0
  40. package/dist/runtime/index.d.cts +2 -0
  41. package/dist/runtime/index.d.ts +2 -0
  42. package/dist/runtime/index.js +2998 -0
  43. package/dist/runtime/index.js.map +1 -0
  44. package/dist/{types-DpdVN7Lm.d.cts → types-CP3KkwZt.d.cts} +1 -1
  45. package/dist/{types-DpdVN7Lm.d.ts → types-CP3KkwZt.d.ts} +1 -1
  46. package/docs/agent-guide.md +67 -1
  47. package/docs/migrate-from-ark-runtime-kernel.md +4 -2
  48. package/docs/package-surface.md +72 -0
  49. package/docs/production-hardening.md +3 -0
  50. package/package.json +11 -1
  51. package/server.json +2 -2
  52. package/templates/skills/ark-adopt.md +43 -87
  53. package/templates/skills/ark-autopilot.md +39 -77
  54. package/templates/skills/ark-contract.md +43 -84
  55. package/templates/skills/ark-coverage.md +62 -83
  56. package/templates/skills/ark-fix.md +45 -90
  57. package/templates/skills/ark-loop.md +44 -66
@@ -1,98 +1,57 @@
1
1
  ---
2
2
  name: ark-contract
3
- description: Safely edit ark.config.json (layers, rules, forbiddenGlobals, intent prefixes), validated with strict ark-check. The one sanctioned way to change the architecture contract.
3
+ description: Safely edit ark.config.json (layers, rules, forbiddenGlobals, intent prefixes) and land business rules into the Ark manifest. Validated with strict ark-check. Deep source evidence required.
4
4
  ---
5
5
 
6
- # /ark-contract — Evolve the architecture contract safely
6
+ # /ark-contract — Change the architecture contract (safely)
7
7
 
8
- You are editing `ark.config.json` the machine-readable contract every gate
9
- (write gate, CI, ESLint, runtime) enforces. Changes here alter what ALL agents
10
- and humans are allowed to write, so the bar is: smallest change, validated,
11
- explained.
8
+ The **one sanctioned way** to change layers/rules/`intentPrefixes`/includes.
9
+ Also used to **land mined business rules** into the executable manifest (`ark.config.json` + intent naming that `ark://manifest` exposes).
12
10
 
13
- **No change described?** If invoked with no specific edit, don't guess and don't
14
- edit anything — the intent is the user's to give. Take the snapshot (step 1) and
15
- present the evolution options grounded in THIS contract: adopt a `suggestedLayers`
16
- layer, tighten a permitted/implicit edge to denied, add `forbiddenGlobals` to a
17
- pure layer, or move a file between layers. While reading the config, surface any
18
- real classification inconsistency you notice (e.g. an HTTP-client file sitting in
19
- a non-integration layer via a fallback pattern) — but before calling a move a
20
- "clean config change", check the file's actual imports against the target layer's
21
- rules (see step 2's move bullet). Then ask which change to make. Reading the
22
- contract to produce that is real work, not a stalling question.
23
11
 
24
- ## Steps
12
+ ## Related onboarding
25
13
 
26
- 1. **Snapshot first** run `ark-check --root . --config ark.config.json
27
- --json` and save the result. You must be able to show what the change
28
- legalized or newly forbids.
29
- 2. **Make the smallest edit** that achieves the user's intent:
30
- - **New layer**: add `{ name, patterns }`; add `intentPrefixes` if the
31
- project uses intent naming; wire explicit `rules` edges to its neighbors —
32
- a layer with no rules is ungoverned, so default to denying edges that match
33
- the project's existing direction of dependencies.
34
- - **New rule**: prefer adding a DENIED edge (tightening). For an ALLOWED
35
- edge (loosening), first check whether any current code depends on it — if
36
- nothing needs it, don't add it (a permission nobody uses is future debt).
37
- - **Split a layer into a public surface + internals (the facade fix)**: when a
38
- check's `summary` shows most violations are ONE edge into a layer (e.g. all of
39
- app-land importing a kernel/framework), the contract — not the code — is wrong.
40
- Split the target layer in two: a `<Layer>Api` layer whose patterns cover the
41
- sanctioned entrypoints app code is meant to import (the target subtrees the
42
- breakdown points at, e.g. `kernel/app/**`, `kernel/events.ts`), and keep the rest
43
- as `<Layer>Internal`. Allow the edge into the surface, deny it into internals.
44
- This legalizes the intended dependency while still forbidding reach-arounds — it
45
- collapses a wall of false positives to ~0. This is how Ark stays compatible with a
46
- DI framework: it guards the border, not the framework's insides.
47
- The surface patterns overlap the internal catch-all, and that is fine: ark-check
48
- resolves the MOST SPECIFIC pattern per file, so `kernel/app/**` wins over
49
- `kernel/**` regardless of layer order. Where app code today reaches into internals
50
- for a legitimate entrypoint, do NOT rewrite every call site: add a barrel module
51
- inside the surface layer (e.g. `src/kernel/app/facade.ts`) that re-exports exactly
52
- those entrypoints, then repoint the reach-around imports to the barrel. It is
53
- behavior-preserving (verify with `tsc --noEmit`) and the imports are now legal.
54
- - **forbiddenGlobals**: adding one to a domain layer may reveal existing
55
- violations — run the check, and if there are hits, fix them (`/ark-fix`
56
- patterns). If they are too numerous to fix now, freezing them in the
57
- baseline is a valid stopgap but requires explicit user approval first (it
58
- silences the new violations); never skip the guard because the code is
59
- dirty today.
60
- - **Move a file to another layer**: only a config change if the file's
61
- imports are ALREADY legal under the target layer's rules. Read the file's
62
- imports, resolve each to its layer, and check the target may import that
63
- layer. If the file mixes concerns the target can't reach (e.g. an HTTP
64
- client that also reads a persistence-layer cache, where
65
- `Integration → Persistence` is denied), moving it BREAKS the contract —
66
- that's a refactor (split the file so the pure part moves), not a config
67
- edit. Say so instead of recommending the move; don't discover it only after
68
- editing the config.
69
- 3. **Validate** — `ark-check --root . --config ark.config.json
70
- --strict-config` (strict makes config warnings fail; that's intended here).
71
- 4. **Diff the impact** — compare violations before/after. New violations from a
72
- tightening are expected: list them and fix them now if the set is small; if
73
- it's large, the baseline stopgap from step 2 applies (approval required).
14
+ - **Greenfield:** `/ark-architect` or `ark-check --recommend` / `ark start`.
15
+ - **Brownfield:** `/ark-adopt` match contract to reality; do not force a starter preset.
16
+ - **Default path:** `ark start` → `/ark-autopilot` → `ark-check --doctor`.
74
17
 
75
- ## Related onboarding
18
+ ## Anti-wrapper rule (mandatory)
19
+
20
+ **Forbidden:** editing globs from vibes without reading the directories those globs claim to cover.
21
+
22
+ **Required:**
23
+ 1. Snapshot before using CLI as **sensor**: coverage + check JSON.
24
+ 2. **Read source** in dirs you reclassify (sample files).
25
+ 3. **“Así te lo re-soluciono”** — exact JSON fields + which files become governed/ungoverned.
26
+ 4. After write: `ark-check --strict-config` must be the validation gate (dead pattern noise is advisory; unclassified + real violations still matter).
27
+
28
+ ## What you may edit
29
+
30
+ - `include` / `exclude`
31
+ - `layers[]` (`name`, `patterns`, `optional`, `forbiddenGlobals`, `intentPrefixes`, layer `exclude`)
32
+ - `rules[]` (from/to/allowed)
33
+ - Never: disable the check, delete CI gates, or add blanket `allowed: true` for a bad edge without a facade design
34
+
35
+ ## Steps
76
36
 
77
- - Greenfield: adopt shape first via `/ark-architect`, `ark init --archetype`, or
78
- `ark-check --apply-policy-pack enthusiast-<preset>`.
79
- - `ark-check --recommend --write-plan` may suggest a `policyPack` in `ark-adoption-plan.json`.
80
- - Brownfield: prefer `/ark-adopt` before large contract edits.
37
+ 1. **Snapshot** coverage governed%, unclassified samples, current violations.
38
+ 2. **Smallest edit** for the user intent:
39
+ - New layer + neighbor rules
40
+ - Expand patterns for ungoverned dirs (`suggestions` from coverage)
41
+ - Facade: public surface patterns more specific than internals
42
+ - **Business rules → manifiesto:**
43
+ - Add/adjust `intentPrefixes` (`Domain.`, `Application.`, …)
44
+ - Point Domain patterns at real pure folders (`**/domain/**`, not bare `**/types.ts`)
45
+ - Document proposed intent names for the app to register (kernel) or for agents to use
46
+ 3. **Impact** — re-run coverage/check; report before/after governed% and violation delta.
47
+ 4. **Rollback** if strict fails for reasons other than pre-existing debt the user accepted.
81
48
 
82
- ## Operating rules
49
+ ## Operating modes
83
50
 
84
- - **Loosening the contract to silence a violation is refused by default.** If
85
- the user asks for an allowed-edge whose only motivation is one red check,
86
- explain the port/adapter alternative first (one plain-language paragraph) and
87
- only proceed if they confirm they want the architectural exception.
88
- - Keep rules explicit: when adding a layer, state in the report which edges you
89
- denied and why, so a novice reading it learns the dependency direction.
90
- - Update generated rule files if the contract summary embedded in them changed:
91
- re-run `ark-check --install-agent-gates` (no `--force`; mention any
92
- skipped-because-customized files).
51
+ Contract edits are most common in **Align (Adapt)**. In **Guard (Enforce)**, treat edits as high-risk product decisions.
93
52
 
94
- ## Verify and report
53
+ ## Done
95
54
 
96
- End with a passing strict check (or a committed baseline decision). Report:
97
- the exact config diff, before/after violation counts, what is now
98
- possible/forbidden in one sentence each, and any follow-ups.
55
+ - Diff of `ark.config.json` explained in plain language.
56
+ - **Así te lo re-soluciono en el manifiesto** when intents/Domain were part of the request.
57
+ - Strict check result captured.
@@ -1,96 +1,75 @@
1
1
  ---
2
2
  name: ark-coverage
3
- description: Audit which Ark capabilities this project isn't using and report how to close each gap, ranked by value. Autonomous reads the repo, decides, reports.
3
+ description: Deep-audit this project's real code + Ark adoption gaps. CLI is a sensor only you must read source, propose concrete remediations, and optional manifest/intent mining. Ranked report with "así te lo re-soluciono".
4
4
  ---
5
5
 
6
- # /ark-coverage — What Ark can do for you that you're not using
6
+ # /ark-coverage — Deep coverage + capability gaps
7
7
 
8
- You are auditing this project's use of the `arkgate` package. Work
9
- autonomously: read everything from the repo, never ask questions you can answer
10
- from files, and end with a ranked report.
8
+ You audit how this repo uses ArkGate **and** what the **real source tree** needs next.
9
+ Work autonomously. End with a ranked report that includes a concrete fix plan.
10
+
11
+ ## Anti-wrapper rule (mandatory)
12
+
13
+ **Forbidden:** reporting only `ark-check --coverage/--doctor/--json` paraphrase, gate checklists, or "unused capability" tables with no source evidence.
14
+
15
+ **Required before you finish:**
16
+ 1. Run CLI as **sensor** (`--coverage --json`, `--doctor`, normal `--json` for `summary`).
17
+ 2. **Read real source** in the top ungoverned / high-coupling clusters (minimum **8 files** across at least **3 directories** that matter). Prefer `src/core/**`, `domain/**`, adapters, etc.
18
+ 3. Deliver **“Así te lo re-soluciono”** — file-level moves, contract globs, intent/manifest proposals, not only “run /ark-contract”.
19
+
20
+ If you did not open source files, the skill is **not complete**.
21
+
22
+ ## Operating modes (detected — not user-picked)
23
+
24
+ | Mode | User meaning | What you tell them |
25
+ |------|----------------|--------------------|
26
+ | **Suggest / Setup** | Thin or new tree | “Ark will propose a starting shape — you don’t switch a mode.” |
27
+ | **Adapt / Align** | Contract ≠ folders or open debt | “Gates don’t fully protect you yet — classify + fix plan.” |
28
+ | **Enforce / Guard** | Coverage + clean edges | “You arrived here — keep CI/write gates on.” |
29
+
30
+ Never say “your architecture is guarded” while `goal.met` is false or governed% is low.
11
31
 
12
32
  ## Related onboarding
13
33
 
14
- - **Greenfield** (new or empty repo): low `governed.percent`suggest `/ark-architect` or
15
- `ark-check --recommend`; `ark-check --doctor` includes a "New here?" nudge with
16
- `recommendCommand` / `initCommand`. Enthusiast track: `docs/enthusiast/how-to-agent-gates.md`.
17
- - **Brownfield** (existing messy repo): use `/ark-adopt` and `docs/brownfield-adoption.md` —
18
- diagnose classify freeze only real debt. Do **not** send brownfield users to `/ark-architect`.
19
-
20
- ## Operating rules
21
-
22
- - Gather inputs yourself: `ark.config.json`, `package.json`, `.ark-baseline.json`,
23
- `.mcp.json`, `AGENTS.md`, agent config dirs (`.claude/`, `.cursor/`, `.codex/`,
24
- `.windsurf/`, `.clinerules/`, `.kiro/`, `.github/`), CI workflows, and the source tree.
25
- Read files with the Read tool and use targeted commands — do NOT `cat` whole
26
- configs or dump the full source tree to the terminal; the report is the output,
27
- not the raw files. Keep discovery quiet so the run stays readable.
28
- - This skill makes no changes to project files by default: produce the report,
29
- then offer to apply the top recommendations. Do not modify files unless the
30
- user then says yes. (Running `ark-check` may write its own scan cache under
31
- `node_modules/.cache/` that's fine; it never touches your source.)
32
- - Explain each gap in plain language a developer new to architecture governance
33
- can follow one sentence of "why this matters" per finding, no jargon without
34
- a one-line definition.
35
-
36
- ## Checklist to audit (compare repo reality against each capability)
37
-
38
- 1. **Config exists and is strict-clean** is there an `ark.config.json`? Does
39
- `ark-check --root . --config ark.config.json --strict-config` pass? Run it.
40
- 2. **Baseline ratchet** — if the check reports violations, is `.ark-baseline.json`
41
- in use (`--baseline`)? An adopting codebase without a baseline blocks CI or,
42
- worse, runs without the gate.
43
- 3. **AI write gate per tool** — for every agent config dir that exists, is the Ark
44
- gate wired? Claude: `PreToolUse` hook calling `ark-mcp --hook` in
45
- `.claude/settings.json`. Cursor: `.cursor/mcp.json` + `.cursor/rules/ark.mdc`.
46
- Codex: MCP server registered. Windsurf/Cline/Copilot/Kiro: rule file present.
47
- 4. **Ark skills installed per tool** — do the detected tools have the `/ark-*`
48
- skills (`.claude/skills/ark-*`, `.cursor/commands/ark-*.md`, etc.)? If not:
49
- `ark-check --install-agent-gates`.
50
- 5. **CI gate** — `.github/workflows/ark-check.yml` (or equivalent) present and
51
- running `ark-check`? Is `--require-gates` used so missing gates fail CI?
52
- 6. **ESLint plugin** — is `arkgate/eslint` configured for in-editor
53
- feedback? (Check eslint config files.)
54
- 7. **Domain purity** — do domain-model layers declare `forbiddenGlobals`
55
- (e.g. `fetch`, `process`, `Date.now`, `Math.random`)? If domain code calls these
56
- directly, recommend adding the guard.
57
- 8. **Governed fraction (the headline honesty number)** — call the **`ark_coverage`**
58
- MCP tool if the `ark` server is available, else run
59
- `ark-check --root . --config ark.config.json --coverage --json`. It returns
60
- `governed` (`{ classifiedFiles, totalFiles, percent }`), per-layer file counts, the
61
- FULL `unclassified` list, `emptyLayers` (patterns matching nothing — usually wrong
62
- globs, the #1 monorepo mistake), and `suggestions` (each ungoverned directory with a
63
- PROPOSED canonical layer, or flagged as unrecognized). Lead your report with
64
- `governed.percent`: **a green check over a low fraction is a false green — the
65
- codebase is mostly UNCHECKED, not clean.** For every ungoverned directory, give the
66
- `suggestions` layer as the fix ("classify `src/lib/repositories` → PersistenceAdapters
67
- via /ark-contract"); for `unrecognized` ones, say it's the user's call. Do NOT
68
- hand-roll this with `find`/`readdir`.
69
- 9. **Concentrated violations = a contract smell, not debt** — run a normal check
70
- (`ark-check … --json`) and read `summary`. If `summary.concentrated` is true (most
71
- violations on one edge), flag it: the contract is probably wrong, not the code — e.g.
72
- app-land reaching a framework/kernel through a sanctioned entrypoint. Recommend fixing
73
- the contract (allow the edge, or split the target layer into a public surface +
74
- internals — /ark-contract) over freezing the false positives.
75
- 10. **Rule coverage** — the `--coverage --json` output lists `layersWithoutRules`:
76
- layers with no rule edge at all can import anything. Flag those where the
77
- dependency direction is obvious (e.g. domain → adapters should be denied).
78
- 11. **Runtime kernel** — does the app hand-roll things the kernel ships? Grep for
79
- homemade event buses, outbox tables, audit logs, workflow/saga orchestration,
80
- projections. If found, point to the matching `arkgate` module
81
- (event-bus, outbox, audit, workflow, projections) and `/ark-runtime`. But if the
82
- repo already runs a DI/kernel framework (dcouplr, NestJS), do NOT recommend
83
- replacing it — Ark governs the border around it, it doesn't supplant it.
84
- 12. **NestJS adapters** — if `@nestjs/common` is a dependency and
85
- `arkgate/nestjs` is unused, flag it.
34
+ - **Greenfield:** low governed% → `/ark-architect` or `ark-check --recommend`.
35
+ - **Brownfield:** `/ark-adopt` + this skill’s deep map — **not** `/ark-architect`.
36
+ - **Business rules / intents loose in the tree:** also cover in **Así te lo re-soluciono** (mine → `intentPrefixes` / Domain placement / kernel `defineIntent` stubs). Full apply path is `/ark-adopt` or `/ark-contract` deep mode.
37
+
38
+ ## Checklist (sensor + code)
39
+
40
+ 1. Config + `ark-check --strict-config` (note: dead preset globs are advisory; unclassified files still fail strict).
41
+ 2. Baseline policy (orphan empty file? wire or delete).
42
+ 3. Write gates + `/ark-*` skills per detected agent.
43
+ 4. CI workflow + monorepo install reality (`frontend/package.json`?).
44
+ 5. ESLint `arkgate/eslint` if ESLint exists.
45
+ 6. Domain `forbiddenGlobals`.
46
+ 7. **Governed%** + full unclassified + `suggestions` from `--coverage --json`.
47
+ 8. Concentrated edges in check `summary` contract smell, not N freezes.
48
+ 9. `layersWithoutRules`.
49
+ 10. Runtime kernel / Nest only if deps prove it never force-fit Next+Python.
50
+
51
+ ## Deep code pass (the model job)
52
+
53
+ For each top cluster (e.g. `frontend/src/core/threads`, `components/workspace`):
54
+
55
+ - Who imports whom (App→Presentation? Domain→App?).
56
+ - Is “core” really application, UI, or mixed?
57
+ - Loose business logic: `calculate*`, `can*`, `validate*`, policy numbers, publish/intent strings without registry.
58
+ - Propose: layer home, `ark.config.json` patterns, optional Domain extract, intent names (`Domain.*` / `Application.*`).
86
59
 
87
60
  ## Output format
88
61
 
89
- A ranked table (highest value first), then a one-paragraph summary:
62
+ 1. **Headline honesty** governed%, mode, violations, false-green risk (one paragraph).
63
+ 2. **Code map** — clusters you read + what you found (paths).
64
+ 3. **Ranked table**
65
+
66
+ | # | Gap | Evidence (path or CLI) | Así te lo re-soluciono (concrete) |
67
+
68
+ 4. **Manifiesto / reglas de negocio** (if any candidates): list proposed intents / Domain files / config edits.
69
+ 5. Offer: “Apply top N?” — apply only if user agrees; then re-run strict check.
90
70
 
91
- | # | Unused capability | Evidence in this repo | How to enable (exact command or file) |
71
+ ## Done criteria
92
72
 
93
- Close with: "Want me to apply the top N? I'll run the commands/diffs and finish
94
- with a strict `ark-check`." Apply only what the user approves, then verify with
95
- `ark-check --root . --config ark.config.json --strict-config` and report the
96
- final state.
73
+ - ≥8 source files read and cited.
74
+ - At least one **Así te lo re-soluciono** block with real paths.
75
+ - CLI numbers used as evidence, not as the whole report.
@@ -1,100 +1,55 @@
1
1
  ---
2
2
  name: ark-fix
3
- description: Resolve Ark architecture violations at the root cause — fix the code (ports, adapters, moves), never weaken the contract. Runs ark-check, fixes, verifies.
3
+ description: Resolve Ark architecture violations at the root cause — ports, adapters, moves, intent/manifest alignment. Never weaken the contract. Read the real code; CLI only validates.
4
4
  ---
5
5
 
6
- # /ark-fix — Fix architecture violations properly
7
-
8
- You are resolving violations reported by `ark-check` or by the Ark write gate.
9
- Work autonomously end to end: diagnose, fix, verify. Do not ask the user to
10
- paste output you can generate yourself.
11
-
12
- ## Operating rules
13
-
14
- - First action: run `ark-check --root . --config ark.config.json --json`
15
- (add `--baseline .ark-baseline.json` if that file exists) to get the current
16
- violation list. If the user quoted a specific gate block, start from that one.
17
- - **Check `summary` before fixing code.** If `summary.concentrated` is true — most
18
- violations are ONE edge — the fix is almost certainly the CONTRACT, not N code
19
- changes: app-land is reaching a framework/kernel through a sanctioned entrypoint,
20
- or a layer needs splitting into a public surface + internals. Stop and hand off to
21
- `/ark-contract`; don't port-and-adapter your way through hundreds of false
22
- positives. Fix code only for the genuine, scattered minority.
23
- - **Fix value edges before type-only ones.** `summary` splits `valueCount` (real
24
- runtime coupling) from `typeOnlyCount` (`import type …` — erased at compile time, no
25
- runtime dependency). Prioritize the value edges; a `typeOnly: true` violation almost
26
- always just means a type lives in the wrong layer (see the type-only pattern below).
27
- - **Never weaken the gate.** Do not edit `ark.config.json`, add allowed edges,
28
- delete rules, or regenerate the baseline to make a violation disappear. The fix
29
- lives in the code. If you become convinced the contract itself is wrong, stop
30
- and say so with your reasoning — changing the contract is `/ark-contract` and a
31
- human decision.
32
- - Take defaults silently and list them at the end. Stop only for destructive
33
- moves (deleting files, rewriting public APIs).
34
-
35
- ## How to fix each violation class
36
-
37
- - **Forbidden cross-layer import** (e.g. domain imports a persistence adapter):
38
- invert the dependency. Define a port (interface) in the layer that needs the
39
- capability, implement it in the layer that has it, and inject the
40
- implementation at composition time. Read `ark://manifest` (MCP) or
41
- `ark.config.json` to see which layers may see which.
42
- - **File in the wrong layer**: if the import is legitimate but the file lives in
43
- the wrong directory, move the file to the layer it behaves like and update
44
- imports. Prefer the smallest move that makes the graph legal.
45
- - **Forbidden global in domain** (`fetch`, `process`, `Date.now`, `Math.random`, …):
46
- inject the capability. Add a port (e.g. `Clock`, `IdGenerator`, `HttpPort`)
47
- with the impure implementation outside the domain, and pass it in.
48
- - **Intent prefix mismatch**: rename the intent to the layer's declared prefix,
49
- or move the handler to the layer that owns that prefix.
50
- - **Type-only inversion** (`typeOnly: true` on a `LAYER_IMPORT_VIOLATION` — plan class
51
- `mechanical-safe`, `remediationKind: type-only-import-move`): a lower layer `import type`s
52
- something from an upper layer (e.g. domain importing a type that lives in a UI hook). Move the
53
- TYPE down to the layer that owns it and re-export for back-compat
54
- (`export type { X } from "@/lib/<domain>/types"`). Highest-volume safe fix — verify with the
55
- gate (and `tsc --noEmit` if present). Not mechanical if: (a) the type extends a persistence/ORM
56
- row — needs a domain-owned type/port; (b) the source mixes types with runtime logic — split
57
- first, then move (or use pure-type file relocate when the *whole file* is type-only).
58
- - **Pure-type file relocate** (`sourcePureTypeModule` + type-only edge —
59
- `remediationKind: pure-type-file-relocate`): the entire source file is type-surface only (no
60
- runtime statements). Relocate the **file** to the owning layer (or extract the type module
61
- there). Behavior-preserving; do not invent runtime ports.
62
- - **Value-syntax import of a pure type-only module** (`targetTypeOnlyExports` —
63
- `remediationKind: import-type-from-pure-type-module`): convert static `import { T } from …`
64
- to `import type { T } from …`. Never auto-apply for `require()` / dynamic `import()` (those stay
65
- judgment — they still execute the module).
66
- - **Raw infrastructure access in an orchestration/UI layer** (a route/handler or component
67
- that runs SQL or imports the DB client directly — e.g. `sqlClient\`SELECT …\`` or
68
- `import { db } from "@/lib/db"` inside `src/app/**`): this is the value-import counterpart
69
- to the type-only inversion, and the biggest brownfield cluster. Relocate the data-access
70
- VERBATIM into a repository/adapter layer: add a business-named method to the repository
71
- (`ordersRepository.listOpen(projectId)`) containing the SAME query byte-for-byte, and have
72
- the route call it. Same SQL = same behavior by construction — do NOT rewrite the query
73
- (`tsc` can't prove two queries return the same rows; a reworded `WHERE` silently changes
74
- results). Prefer extending an existing domain repository over creating a new one. Two
75
- cautions: (a) this edits the data layer, which many repos reserve to core maintainers —
76
- if a `CLAUDE.md`/CODEOWNERS rule restricts it, migrate one route as a demonstrated pattern
77
- and hand the bulk to a maintainer rather than sweeping hundreds autonomously; (b) a route
78
- with interleaved transactions / 10+ queries is not a pure relocation — flag it for review.
79
- See the brownfield burn-down playbook (`docs/brownfield-adoption.md`) for the full sequence.
80
-
81
- Fix ALL reported violations that share a root cause in one pass — one port in a
82
- shared module beats N per-file patches. Match the codebase's existing naming and
83
- port conventions before inventing new ones.
6
+ # /ark-fix — Fix architecture violations at the root
7
+
8
+ You fix violations Ark reports. Prefer structural fixes over silencing the gate.
9
+
84
10
 
85
11
  ## Related onboarding
86
12
 
87
- - Prefer `fixClass` / `enthusiastHint` from `ark-check --json` when present.
88
- - Brownfield burn-down: `/ark-adopt` first; demo `docs/demos/02-brownfield-baseline-adoption.md`.
89
- - Greenfield: `/ark-architect` prevents many violations before they exist.
13
+ - **Greenfield:** `/ark-architect` or `ark-check --recommend` / `ark start`.
14
+ - **Brownfield:** `/ark-adopt` — match contract to reality; do not force a starter preset.
15
+ - **Default path:** `ark start` → `/ark-autopilot` `ark-check --doctor`.
16
+
17
+ ## Anti-wrapper rule (mandatory)
18
+
19
+ **Forbidden:** only listing violations from JSON without reading importers/targets.
20
+
21
+ **Required:**
22
+ 1. Run `ark-check` as **sensor** (and `--plan --json` if multi-step) — CLI validates; you remediate.
23
+ 2. **Read** each violated file and its import target.
24
+ 3. **“Así te lo re-soluciono”** — concrete change before editing.
25
+ 4. After edits: `ark-check --strict-config` (and baseline if configured).
26
+
27
+ ## Common fix patterns
28
+
29
+ | Symptom | Fix |
30
+ |---------|-----|
31
+ | App → Presentation type-only | Extract type to application/core; re-export from UI |
32
+ | App → Presentation value (UI in core) | Move component wrappers to presentation |
33
+ | Domain → outer layer | Port/interface in Domain; adapter outside; or relocate false Domain file (`**/types.ts` trap) |
34
+ | Intent prefix mismatch | Rename intent to layer’s `intentPrefixes` or fix prefix in config via `/ark-contract` |
35
+ | Forbidden global in Domain | Inject a port (Clock, Id, Http) — don’t allow `Date.now` in Domain |
36
+ | Concentrated edge wall | Stop grinding; `/ark-contract` facade/surface split |
37
+
38
+ ## Manifiesto
39
+
40
+ If the “fix” is really a missing business intent or Domain home for a rule:
41
+
42
+ - Propose intent name + layer placement.
43
+ - Register / place code so `ark://manifest` / config can enforce it.
44
+ - Do not only delete the import.
45
+
46
+ ## Rules
90
47
 
91
- ## Verify and report
48
+ - No `ark-*-disable`, no allowing a bad edge “to finish”, no baselining a **new** violation you introduced.
49
+ - Prefer mechanical-safe kinds when the plan tags them; otherwise design judgment carefully.
50
+ - Code only — no DB migrations unless user asked.
92
51
 
93
- After edits, run `ark-check --root . --config ark.config.json --strict-config`
94
- (plus the project's test command if one exists in `package.json`). If the check
95
- still fails, keep fixing — do not end the turn with a red check unless you are
96
- blocked on a genuine contract question.
52
+ ## Done
97
53
 
98
- Report: violations fixed (before after count), what pattern you applied
99
- (in plain language assume the reader may not know what a "port" is: one line
100
- of definition), defaults taken, anything intentionally left for the user.
54
+ - Targeted violations gone; no new ones.
55
+ - Report: what moved, what was intentional default, what needs user decision.
@@ -1,79 +1,57 @@
1
1
  ---
2
2
  name: ark-loop
3
- description: Drive Ark's remediation plan to a clean architecture — a safe, reversible apply loop. Auto-applies only the changes Ark classes mechanical-safe (validating each with ark-check and rolling back regressions), proposes the judgment ones for your decision, and never weakens the gate. Autonomous within those limits.
3
+ description: Drive ark-check --plan to zero active violations. Auto-apply only mechanical-safe kinds; design judgment fixes from real source. CLI is the validator you edit code.
4
4
  ---
5
5
 
6
- # /ark-loop — Drive the plan to a clean architecture (safely)
6
+ # /ark-loop — Apply the plan safely
7
7
 
8
- This is the co-pilot's **loop** primitive: read Ark's classified **plan**, work toward the
9
- **goal** (zero active violations without weakening the contract), one small step at a time,
10
- validating every change with `ark-check` and rolling back anything that fails or regresses.
8
+ Read Arks classified **plan**, work toward **goal.met**, one small step at a time,
9
+ validating every change with `ark-check` and rolling back regressions.
11
10
 
12
- **The rule that makes this safe:** you (the agent) make edits; **Ark decides whether they're
13
- allowed to land.** Only changes Ark classed `mechanical-safe` are auto-applied. Everything
14
- `judgment` is PROPOSED for a human decision — never applied silently. Code only: never touch
15
- DB schemas, migrations, or generated files.
16
11
 
17
- If Ark isn't set up yet, run `ark start` (or `ark-check --recommend` then `ark init`) first.
12
+ ## Related onboarding
13
+
14
+ - **Greenfield:** `/ark-architect` or `ark-check --recommend` / `ark start`.
15
+ - **Brownfield:** `/ark-adopt` — match contract to reality; do not force a starter preset.
16
+ - **Default path:** `ark start` → `/ark-autopilot` → `ark-check --doctor`.
17
+
18
+ ## Anti-wrapper rule (mandatory)
19
+
20
+ **Forbidden:** re-printing plan JSON without opening sources, or inventing new “safe” kinds.
21
+
22
+ **Required:**
23
+ 1. `--plan --json` as sensor.
24
+ 2. For each step you touch: **read** `file` and `target` source.
25
+ 3. **“Así te lo re-soluciono”** — exact edit before applying.
26
+ 4. After each apply: full gate re-run; rollback if targeted violation remains or new ones appear.
27
+
28
+ ## mechanical-safe only (auto)
29
+
30
+ | `remediationKind` | What to do |
31
+ |-------------------|------------|
32
+ | `type-only-import-move` | Move type to owning layer; re-export for back-compat |
33
+ | `pure-type-file-relocate` | Relocate pure-type file to owning layer (or rename out of false Domain globs) |
34
+ | `import-type-from-pure-type-module` | Convert value import of pure-type module to `import type` |
35
+
36
+ Never auto: value imports, dynamic import/require, mixed modules, forbidden globals, cycles, infra moves.
18
37
 
19
38
  ## Steps
20
39
 
21
- 1. **Read the plan.** Run `ark-check --plan --json` (add `--baseline .ark-baseline.json` if the
22
- repo uses a baseline). It returns `goal` (with `met`, `activeViolations`, `autoApplicable`,
23
- `needsDecision`, `deferred`) and `steps[]`, each tagged `class` (`mechanical-safe` /
24
- `judgment` / `deferred`) with a `confidence`, plain-language `rationale`, and often
25
- `remediationKind`. If `goal.met` is already true, report "nothing to do" and stop.
26
-
27
- **`mechanical-safe` kinds you may auto-apply** (zero false-safe — never invent others):
28
-
29
- | `remediationKind` | What to do |
30
- |-------------------|------------|
31
- | `type-only-import-move` | Edge is already `import type` / type-only: move the **type** to the owning layer + re-export for back-compat |
32
- | `pure-type-file-relocate` | Whole **source file** is pure type-surface (`sourcePureTypeModule`) + type-only edge: relocate the file (or extract types) to the owning layer |
33
- | `import-type-from-pure-type-module` | Static value-syntax import of a pure type-only **target** module (`targetTypeOnlyExports`): convert to `import type` (and place type if needed) |
34
-
35
- Still **judgment** (never auto): value imports, `require()` / dynamic `import()`, mixed modules with side effects, forbidden globals, cycles, verbatim infra relocation.
36
-
37
- 2. **Work in a discardable git worktree.** Create one (`git worktree add`) so the entire run is
38
- reversible and never disturbs the user's working tree. Do all edits there. Nothing is
39
- permanent until the user reviews the final diff.
40
-
41
- 3. **Apply the `mechanical-safe` steps, one at a time, validated.** Match the step's
42
- `remediationKind` (table above) — do not expand the edit into a broader refactor:
43
- - Record the current active-violation count from the plan.
44
- - Make the edit at the SOURCE (fix the placement; don't add an `ark-*-disable` or edit the
45
- baseline/config to hide it).
46
- - Re-run the gate: `ark-check --root . --config ark.config.json --strict-config`
47
- (or `ark-check --baseline` in ratchet repos). **Keep** the change only if the targeted
48
- violation is gone AND no NEW violation appeared. Otherwise **roll it back**
49
- (`git checkout -- <files>`) and mark the step deferred with a one-line reason.
50
-
51
- 4. **Propose the `judgment` steps — do not auto-apply.** For each, present in plain language:
52
- what it is, the `rationale`, and a concrete proposed approach (e.g. "move this data access
53
- into a repository," "inject a Clock port"). Apply only the ones the user approves, each with
54
- the same validate-or-rollback discipline. Repository organization and cross-module refactors
55
- are the user's call.
56
-
57
- 5. **Loop until dry.** Re-read `ark-check --plan --json` after a round — fixing one edge can
58
- change others. Repeat step 3 while new `mechanical-safe` steps appear and progress is being
59
- made. Stop when `goal.met` is true, or when a round applies nothing new (no-progress), or
60
- when only `judgment`/`deferred` steps remain.
61
-
62
- 6. **Report honestly.** Show the final diff and a summary: what was AUTO-APPLIED (validated),
63
- what is PROPOSED (awaiting your decision), and what was DEFERRED (and why). Never report a
64
- clean/green result while steps were skipped. Only merge the worktree back after the user
65
- reviews. When invoked from **`/ark-autopilot`**, the parent skill already owns the
66
- before/after HTML reports (`--report` + `.ark/reports/` origin/latest). If you are running
67
- standalone and the user wants a visual close-out, end with
68
- `ark-check --report ark-report.html` so evolution vs origin is updated.
40
+ 1. **Plan** `ark-check --plan --json` (+ `--baseline` if used). If `goal.met`, stop.
41
+ 2. **Worktree** prefer discardable git worktree.
42
+ 3. **Apply mechanical-safe** one-by-one with validate/rollback.
43
+ 4. **Judgment** propose with source-based design; apply only if user approved (or parent autopilot said full apply).
44
+ 5. **Re-plan** after each round until dry, `goal.met`, or only judgment left without approval.
45
+ 6. **Report** — auto-applied / proposed / deferred with paths; never claim clean if skipped.
69
46
 
70
47
  ## Operating rules
71
48
 
72
- - Never weaken the gate to make the loop finish: no disabling rules, editing
73
- `ark.config.json` to allow a bad edge, or baselining a fresh violation. Fix the code, or
74
- propose a contract change via `/ark-contract` with its before/after impact.
75
- - If most violations concentrate on one edge, that's a contract smell, not N fixes — stop the
76
- loop and hand off to `/ark-contract` (a broad `--plan` will show the concentration).
77
- - `mechanical-safe` is deliberately narrow. When unsure whether a change preserves behavior,
78
- treat it as `judgment` and propose it. A wrong auto-apply costs more than an extra click.
79
- - Verify with the gate, not by eye: a step counts as done only when `ark-check` confirms it.
49
+ - Never weaken the gate (no rule disables, no fresh baselining of new debt).
50
+ - Concentrated single edge stop and hand to `/ark-contract` with code evidence.
51
+ - When unsure behavior preservation judgment, not mechanical-safe.
52
+
53
+ ## Done criteria
54
+
55
+ - Gate confirms each kept edit.
56
+ - Honest residual list with **Así te lo re-soluciono** for anything left.
57
+ - If residual steps hide domain/business rules in the wrong layer, call out **manifiesto** work (`intentPrefixes` / Domain placement) via `/ark-contract` or `/ark-adopt`.