arkgate 2.6.0 → 2.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +61 -0
- package/README.md +90 -67
- package/bin/ark-check.mjs +264 -51
- package/bin/ark-layer-match.mjs +29 -0
- package/bin/ark-mcp.mjs +102 -5
- package/bin/ark-shared.mjs +295 -6
- package/bin/ark.mjs +44 -34
- package/bin/lib/agent-gates.mjs +448 -15
- package/bin/lib/doctor-plan.mjs +11 -4
- package/bin/lib/presets.mjs +75 -4
- package/dist/eslint/index.cjs.map +1 -1
- package/dist/eslint/index.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.cjs +1 -1
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +1 -1
- package/dist/nestjs/index.js.map +1 -1
- package/docs/agent-guide.md +63 -0
- package/package.json +1 -1
- package/server.json +2 -2
- package/templates/skills/ark-adopt.md +43 -87
- package/templates/skills/ark-autopilot.md +39 -77
- package/templates/skills/ark-contract.md +43 -84
- package/templates/skills/ark-coverage.md +62 -83
- package/templates/skills/ark-fix.md +45 -90
- package/templates/skills/ark-loop.md +44 -66
package/docs/agent-guide.md
CHANGED
|
@@ -64,6 +64,69 @@ npx ark-check --watch # debounced re-check when govern
|
|
|
64
64
|
`enthusiastHint` (plain English). `--doctor --json` exposes `doctor.newHere` with
|
|
65
65
|
`recommendCommand` and `initCommand` when the nudge applies.
|
|
66
66
|
|
|
67
|
+
### Deploy-path quality (lint/types before the host build)
|
|
68
|
+
|
|
69
|
+
Some frameworks run **ESLint and/or typecheck inside the production build** (Next.js by
|
|
70
|
+
default: “Linting and checking validity of types”). Architecture can be green while the
|
|
71
|
+
**deploy host** is the first place a `no-explicit-any` or unused-import error appears.
|
|
72
|
+
|
|
73
|
+
Ark does **not** reimplement general ESLint rules. `--doctor` / adoption gaps **do**
|
|
74
|
+
detect, for **any** consumer repo (framework signals only — deps, scripts, CI files):
|
|
75
|
+
|
|
76
|
+
| Gap id | When |
|
|
77
|
+
|--------|------|
|
|
78
|
+
| `deploy-path-lint-script-missing` | Build embeds ESLint; no `lint` / `eslint` script |
|
|
79
|
+
| `deploy-path-lint-not-in-ci` | Lint script exists; CI workflows never run it |
|
|
80
|
+
| `deploy-path-lint-no-ci` | Build embeds ESLint; no CI workflows at all |
|
|
81
|
+
| `deploy-path-typecheck-script-missing` | Build typechecks; no `typecheck` script |
|
|
82
|
+
| `deploy-path-typecheck-not-in-ci` | Typecheck script exists; CI never runs it |
|
|
83
|
+
|
|
84
|
+
Respects `eslint.ignoreDuringBuilds: true` in `next.config.*`. Recommended pre-merge
|
|
85
|
+
order (universal): `lint` → `typecheck` → `arkgate-check` / `check:architecture` → `build`.
|
|
86
|
+
|
|
87
|
+
### Empty scope, include roots, and contract adopt
|
|
88
|
+
|
|
89
|
+
When `include` matches **zero** TS/JS files, plan/doctor treat that as **not done**
|
|
90
|
+
(`goal.emptyScope`, adoption gap `empty-scope`) — never “clean architecture.”
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
npx ark-check --suggest-include --json # workspaces + nested package.json+TS roots
|
|
94
|
+
npx ark-check --adopt-contract --write # expand include + UI patterns (no rule weakening)
|
|
95
|
+
npx ark-check --coverage
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Polyglot repos: Ark only governs TypeScript/JS. Point include at package roots that have sources.
|
|
99
|
+
|
|
100
|
+
### Presets
|
|
101
|
+
|
|
102
|
+
- `hexagonal` / `layered` / `feature-sliced` / `monorepo` / **`ui-surface`** (UI/Vite/Remotion-style hooks+lib+routes+components)
|
|
103
|
+
|
|
104
|
+
### Cycle policy
|
|
105
|
+
|
|
106
|
+
```json
|
|
107
|
+
{ "cyclePolicy": "strict" }
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
- `strict` (default): value cycles fail the check
|
|
111
|
+
- `soft` / `framework-soft`: value cycles are **warnings** only
|
|
112
|
+
- `off`: skip cycle detection
|
|
113
|
+
|
|
114
|
+
Type-only edges never form cycles (codegen-safe).
|
|
115
|
+
|
|
116
|
+
### Generated files and type-only cycles
|
|
117
|
+
|
|
118
|
+
By default Ark **does not scan** common codegen paths:
|
|
119
|
+
|
|
120
|
+
- `**/*.gen.ts`, `**/*.gen.tsx`
|
|
121
|
+
- `**/*.generated.ts`, `**/*.generated.tsx`
|
|
122
|
+
|
|
123
|
+
Override with `"excludeGenerated": false` or extend with top-level `"exclude": ["**/vendor/**"]`
|
|
124
|
+
in `ark.config.json`.
|
|
125
|
+
|
|
126
|
+
**Circular dependencies** are computed on **value/runtime** import edges only. A cycle
|
|
127
|
+
closed solely by `import type` (common with generated route trees) is **not** reported as
|
|
128
|
+
`CIRCULAR_DEPENDENCY`. Value cycles still fail.
|
|
129
|
+
|
|
67
130
|
### MCP `ark_recommend` and `/ark-architect` (Phase C)
|
|
68
131
|
|
|
69
132
|
The `ark-mcp` server exposes **`ark_recommend`** — same JSON as
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/pedroknigge/arkgate",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "2.6.
|
|
9
|
+
"version": "2.6.1",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "arkgate",
|
|
14
|
-
"version": "2.6.
|
|
14
|
+
"version": "2.6.1",
|
|
15
15
|
"runtimeHint": "npx",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
@@ -1,103 +1,59 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ark-adopt
|
|
3
|
-
description:
|
|
3
|
+
description: Brownfield onboarding — match contract to real code, classify ungoverned dirs, mine loose business rules into the Ark manifest/intents, freeze only real debt. Deep source analysis required.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /ark-adopt — Bring Ark into an existing codebase
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
green
|
|
10
|
-
architecture, most of the code actually governed, and only genuine debt frozen
|
|
11
|
-
with a plan to burn it down. A green check over a wrong contract or an ungoverned
|
|
12
|
-
tree is a FALSE green — worse than no gate, because it looks safe. Work autonomously.
|
|
8
|
+
Goal: contract reflects reality, most code governed, only genuine debt frozen with a burn-down.
|
|
9
|
+
A green check over a wrong contract is a **false green**.
|
|
13
10
|
|
|
14
|
-
Commands below are written as `ark-check` / `ark`; run each through the project's
|
|
15
|
-
package manager — `pnpm exec ark-check …` in a pnpm repo, `yarn ark-check …` in a
|
|
16
|
-
yarn repo, `npx ark-check …` under npm. Match the lockfile; never hardcode `npx` in
|
|
17
|
-
a pnpm/yarn repo (AGENTS.md shows the exact runner for this project).
|
|
18
11
|
|
|
19
|
-
##
|
|
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:** only running `--init` / `--update-baseline` / coverage JSON without reading the tree.
|
|
21
|
+
|
|
22
|
+
**Required:**
|
|
23
|
+
1. CLI sensor: `--coverage --json`, check `--json` (`summary`), doctor.
|
|
24
|
+
2. **Read real source** in largest ungoverned dirs and top import edges (min **10 files**).
|
|
25
|
+
3. **“Así te lo re-soluciono”** — concrete layer globs, file moves, and manifest/intent proposals.
|
|
26
|
+
4. Never freeze a concentrated edge without investigating contract smell.
|
|
20
27
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
import) as one layer and treat the rest as a black box. Governing the internals
|
|
25
|
-
duplicates the framework's own wiring and fights it.
|
|
28
|
+
## Guiding principle
|
|
29
|
+
|
|
30
|
+
Ark protects the **boundary around** a framework, not its internals. Nest/DI public surface = one layer; internals black box.
|
|
26
31
|
|
|
27
32
|
## Steps
|
|
28
33
|
|
|
29
|
-
1. **Config** —
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
app→kernel because the framework's own `defineRoute` is the sanctioned entrypoint
|
|
41
|
-
— false positives, not debt.) Investigate the dominant edge:
|
|
42
|
-
- App-land reaching a framework/kernel through a legitimate entrypoint → fix the
|
|
43
|
-
contract (step 3), do NOT freeze it.
|
|
44
|
-
- Unrelated layers genuinely importing each other → real debt for the baseline.
|
|
45
|
-
|
|
46
|
-
3. **Make the contract reflect reality (via /ark-contract) BEFORE freezing:**
|
|
47
|
-
- **Classify the ungoverned tree.** Run `ark-check --coverage --json`; read
|
|
48
|
-
`governed.percent` and `suggestions`. If Ark governs a minority of the code, a
|
|
49
|
-
green check means almost nothing. Add the proposed layers for the recognized
|
|
50
|
-
directories; decide a layer for the ones flagged "unrecognized". Get `governed`
|
|
51
|
-
high before trusting any check.
|
|
52
|
-
- **Fix a concentrated edge at its source.** If the dominant edge is intended,
|
|
53
|
-
either allow it or — better — split the target layer into a PUBLIC SURFACE (the
|
|
54
|
-
entrypoints app code may import) and INTERNALS (denied). The breakdown's target
|
|
55
|
-
subtrees show where the surface is. This facade split turns a wall of false
|
|
56
|
-
positives into ~0 while still forbidding reach-arounds into internals.
|
|
57
|
-
Re-run the check; the remainder should now be the genuine minority.
|
|
58
|
-
|
|
59
|
-
4. **Freeze the genuine debt** — run `ark-check --update-baseline`. If the set is
|
|
60
|
-
still lopsided on one edge, Ark REFUSES and tells you the contract still looks
|
|
61
|
-
wrong — heed it and return to step 3; do NOT `--force` past it just to get green.
|
|
62
|
-
On success it writes `.ark-baseline.json`; tell the user to commit it (don't commit
|
|
63
|
-
for them). From now `ark-check --baseline` fails only on NEW violations — the
|
|
64
|
-
ratchet only moves toward zero (fixing a frozen violation shrinks the baseline).
|
|
65
|
-
|
|
66
|
-
5. **Gates + skills everywhere** — run `ark-check --install-agent-gates`. It
|
|
67
|
-
auto-detects the agent CLIs in the repo and writes the write gate, rule files,
|
|
68
|
-
package-manager-aware CI workflow, and the `/ark-*` skills for each (Kiro gets
|
|
69
|
-
only its steering rule; Copilot only via `--tools copilot`). If a baseline was
|
|
70
|
-
created, the generated CI already carries `--baseline`. For Codex, prompts load
|
|
71
|
-
from `$CODEX_HOME/prompts`, not the repo — install there too with
|
|
72
|
-
`ark-check --install-agent-gates --codex-home` (writes to their home dir; say so).
|
|
73
|
-
|
|
74
|
-
6. **Ratchet plan** — from `summary.edges` (ranked), write a short prioritized
|
|
75
|
-
burn-down: which edge/cluster to fix first (biggest, or the one on the
|
|
76
|
-
most actively-edited files per `git log`), that `/ark-fix` resolves each, and
|
|
77
|
-
which items are real debt vs. deferred contract decisions.
|
|
78
|
-
|
|
79
|
-
## Operating rules
|
|
80
|
-
|
|
81
|
-
- Explain each step's WHY in one plain sentence — this is often the user's first
|
|
82
|
-
contact with Ark. Define jargon inline ("baseline = the list of violations that
|
|
83
|
-
existed before Ark, frozen so they don't block you while you fix them over time").
|
|
84
|
-
- Do NOT chase green by freezing false positives or loosening the contract blindly.
|
|
85
|
-
The order is: contract reflects reality → classify → freeze only what's left.
|
|
86
|
-
Getting to green the wrong way is the exact failure this skill exists to prevent.
|
|
87
|
-
- Don't overwrite customized files (`--force`) unless asked. Don't adopt the runtime
|
|
88
|
-
kernel here (that's `/ark-runtime`) — a repo with its own DI framework should keep it.
|
|
34
|
+
1. **Config** — missing → `ark-check --init` (detection). Keep existing unless asked to regenerate.
|
|
35
|
+
2. **Check + diagnose** — `summary.concentrated` / dominant edge → fix contract first, don’t freeze.
|
|
36
|
+
3. **Classify ungoverned** — use coverage `suggestions`; add layers/patterns via `/ark-contract`.
|
|
37
|
+
4. **Mine business rules → manifiesto** (model job — this is why the skill exists):
|
|
38
|
+
- Scan for loose domain: validators, pricing/policy functions, `can*`/`calculate*`, magic business constants, publish/intent strings, logic in UI/hooks that belongs in Domain.
|
|
39
|
+
- Propose: Domain files, `intentPrefixes`, intent names (`Domain.*` / `Application.*`), kernel `defineIntent` stubs if runtime is used.
|
|
40
|
+
- Apply config through `/ark-contract` discipline; move pure rules into Domain when safe; validate with ark-check.
|
|
41
|
+
- Deliver section **“Así te lo re-soluciono en el manifiesto”** with before/after contract snippets.
|
|
42
|
+
5. **Freeze only real debt** — `--update-baseline` (zero debt → **no empty baseline file** left behind).
|
|
43
|
+
6. **Gates + skills** — `--install-agent-gates` (CI monorepo-aware when `frontend/package.json` exists).
|
|
44
|
+
7. **Ratchet plan** — ranked edges + which are false positives avoided.
|
|
89
45
|
|
|
90
|
-
##
|
|
46
|
+
## Operating modes
|
|
47
|
+
|
|
48
|
+
Explain modes as **detected stages** (Setup / Align / Guard), not user settings.
|
|
49
|
+
|
|
50
|
+
## Verify
|
|
91
51
|
|
|
92
|
-
-
|
|
93
|
-
|
|
94
|
-
- Demo: `docs/demos/02-brownfield-baseline-adoption.md`. Playbook: `docs/brownfield-adoption.md`.
|
|
95
|
-
- Violation JSON may include `fixClass`, `effort`, `enthusiastHint` for burn-down ordering.
|
|
52
|
+
`ark-check --root . --config ark.config.json --strict-config` (+ baseline only if non-empty file retained).
|
|
53
|
+
Report: governed% before/after, files written, frozen count, false positives avoided, manifest/intent proposals applied or deferred.
|
|
96
54
|
|
|
97
|
-
##
|
|
55
|
+
## Never
|
|
98
56
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
positives you AVOIDED freezing by fixing the contract), the ratchet plan, and the
|
|
103
|
-
commands the team needs (`check`, `/ark-fix`, `/ark-coverage`).
|
|
57
|
+
- Freeze false positives to get green.
|
|
58
|
+
- Force runtime kernel over existing Nest/DI.
|
|
59
|
+
- Claim Enforce while governed% is low or core bags ungoverned.
|
|
@@ -1,97 +1,59 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ark-autopilot
|
|
3
|
-
description:
|
|
3
|
+
description: End-to-end architecture co-pilot — setup, deep plan from real code, apply mechanical-safe fixes, design and apply judgment fixes when the user asks for full apply. CLI is a sensor; you remediate files.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# /ark-autopilot — Get to a sound architecture, end to end
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
the
|
|
10
|
-
|
|
8
|
+
Composes **setup + plan + loop**. Safe default: auto-apply only `mechanical-safe`;
|
|
9
|
+
when the user says full apply / “al mango” / apply everything, also execute
|
|
10
|
+
**judgment** fixes you design from reading source (still validate with ark-check,
|
|
11
|
+
never weaken the gate).
|
|
11
12
|
|
|
12
|
-
**The rule that keeps it safe:** you (the agent) make edits; **Ark decides what may land.** Only
|
|
13
|
-
`mechanical-safe` changes are auto-applied (validated, with rollback); everything `judgment` is
|
|
14
|
-
PROPOSED for a human decision. Code only — never DB/schema, never weakening the gate.
|
|
15
13
|
|
|
16
|
-
##
|
|
14
|
+
## Related onboarding
|
|
17
15
|
|
|
18
|
-
**
|
|
16
|
+
- **Greenfield:** `/ark-architect` or `ark-check --recommend` / `ark start`.
|
|
17
|
+
- **Brownfield:** `/ark-adopt` — match contract to reality; do not force a starter preset.
|
|
18
|
+
- **Default path:** `ark start` → `/ark-autopilot` → `ark-check --doctor`.
|
|
19
19
|
|
|
20
|
-
-
|
|
21
|
-
approval prompt before anything non-trivial. The user never needs to know a preset or a rule
|
|
22
|
-
name. This skill is that flow.
|
|
23
|
-
- **Expert:** skip the autopilot and use the pieces directly — `ark init` / `/ark-contract` to
|
|
24
|
-
shape the contract, `ark-check --plan` to see the work, `/ark-fix` for targeted fixes,
|
|
25
|
-
`ark-check --strict-config` as the gate. Point them there and stop.
|
|
20
|
+
## Anti-wrapper rule (mandatory)
|
|
26
21
|
|
|
27
|
-
**
|
|
22
|
+
**Forbidden:** only printing `--plan` JSON or “4 safe / 4 judgment — approve?” without reading the violating files.
|
|
28
23
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
24
|
+
**Required:**
|
|
25
|
+
1. CLI sensor: `ark-check --plan --json`, coverage/doctor as needed.
|
|
26
|
+
2. **Open every file** in the plan’s `steps[]` (and its `target` if present) before classifying a fix.
|
|
27
|
+
3. **“Así te lo re-soluciono”** for each cluster of steps: exact moves (extract type, relocate file, invert dependency).
|
|
28
|
+
4. Apply → re-run ark-check → rollback on regression.
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
`governedPercent` is low.
|
|
30
|
+
## Operating modes (detected, not picked)
|
|
36
31
|
|
|
37
|
-
|
|
32
|
+
- **Setup (Suggest):** no config → `ark start` / recommend shape.
|
|
33
|
+
- **Align (Adapt):** open debt or low honesty → drive loop; do not claim “guarded”.
|
|
34
|
+
- **Guard (Enforce):** `goal.met` and solid governed% → install/confirm gates and stop.
|
|
38
35
|
|
|
39
|
-
|
|
40
|
-
(which itself uses `ark-check --recommend` to suggest a shape in plain language, then writes
|
|
41
|
-
the config + agent/CI gates, and captures the **origin** architecture report under
|
|
42
|
-
`.ark/reports/`). On an established codebase it adopts the real structure. If
|
|
43
|
-
Ark is already set up, skip to step 2.
|
|
36
|
+
## Flow
|
|
44
37
|
|
|
45
|
-
|
|
38
|
+
1. **Setup if needed** — `ark start` if no `ark.config.json`.
|
|
39
|
+
2. **Origin report** — `ark-check --report ark-report.html` (do not `--reset-origin` unless asked).
|
|
40
|
+
3. **Plan + code read** — `--plan --json`; read each step’s source/target; group by edge.
|
|
41
|
+
4. **Concentrated edge?** — if one edge dominates, route to `/ark-contract` with a **source-based** diagnosis (not freeze).
|
|
42
|
+
5. **Worktree preferred** — discardable git worktree when possible.
|
|
43
|
+
6. **Mechanical-safe** — only kinds from `/ark-loop` table; one step, validate, rollback.
|
|
44
|
+
7. **Judgment** — default: propose with full “así te lo re-soluciono”. If user authorized full apply: implement the designed fix, validate, rollback on fail.
|
|
45
|
+
8. **Manifiesto** — if loose business rules surface (domain logic in UI/core), propose Domain placement + `intentPrefixes` / intents; apply config only via `/ark-contract` discipline (strict check after).
|
|
46
|
+
9. **Final report** — `--report` again; evolution vs origin; honest summary of auto vs judgment vs deferred.
|
|
47
|
+
10. **Strict check** — `ark-check --strict-config` (dead preset globs are advisory; real violations still fail).
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
npx ark-check --root . --config ark.config.json --report ark-report.html
|
|
49
|
-
```
|
|
49
|
+
## Never
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
- This is the “before” picture the autopilot will improve against.
|
|
51
|
+
- Disable rules, broaden allows, or baseline **new** debt to “finish”.
|
|
52
|
+
- Claim clean while judgment steps were skipped without user decision.
|
|
53
|
+
- Replace host Nest/DI with the runtime kernel unasked.
|
|
55
54
|
|
|
56
|
-
|
|
57
|
-
_safe to auto-apply_ vs _need your decision_ vs _deferred_, and what the goal is (a clean,
|
|
58
|
-
enforced architecture). Safe auto steps are only the three `mechanical-safe` kinds:
|
|
59
|
-
type-only type move, pure-type **file** relocate, and converting static imports of pure-type
|
|
60
|
-
modules to `import type` (see `/ark-loop`). Confirm before changing anything.
|
|
55
|
+
## Done criteria
|
|
61
56
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
a yes/no. Loop until the plan's `goal.met` is true or a round makes no progress.
|
|
66
|
-
|
|
67
|
-
5. **Confirm it stays clean.** Verify the gates are installed and active so the architecture is
|
|
68
|
-
enforced from now on (in CI, and at write time if the MCP hook is wired) — the
|
|
69
|
-
"and stays that way" half of the promise. Run the final `ark-check --strict-config`.
|
|
70
|
-
|
|
71
|
-
6. **Close with the after report + evolution.** Run again:
|
|
72
|
-
|
|
73
|
-
```bash
|
|
74
|
-
npx ark-check --root . --config ark.config.json --report ark-report.html
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
The HTML now includes **Evolution vs origin** (score, governed%, violations, files per layer)
|
|
78
|
-
when origin already existed. Point the user at:
|
|
79
|
-
- `ark-report.html` / `.ark/reports/latest.html` — **after**
|
|
80
|
-
- `.ark/reports/origin.html` — **before** (frozen)
|
|
81
|
-
- `.ark/reports/history/` — optional JSON trail
|
|
82
|
-
|
|
83
|
-
7. **Report honestly, in plain language.** Summarize what was auto-applied, what you proposed
|
|
84
|
-
and the user decided, and what's deferred (and why). Tie the narrative to the before/after
|
|
85
|
-
report numbers. Show the diff. Only merge the worktree back after the user reviews. Never
|
|
86
|
-
report "done / clean" while steps were skipped.
|
|
87
|
-
|
|
88
|
-
## Operating rules
|
|
89
|
-
|
|
90
|
-
- Never weaken the gate to finish: no disabling rules, editing `ark.config.json` to allow a bad
|
|
91
|
-
edge, or baselining a fresh violation. Fix the code, or propose a contract change via
|
|
92
|
-
`/ark-contract` with its before/after impact.
|
|
93
|
-
- If most violations concentrate on one edge, that's a contract smell — stop and route to
|
|
94
|
-
`/ark-contract`, don't grind N fixes.
|
|
95
|
-
- Bias to proposing: when unsure a change preserves behavior, treat it as `judgment`.
|
|
96
|
-
- Everything traces to Ark's own outputs (`ark-check --plan --json`, `--recommend`) — never
|
|
97
|
-
invent architecture advice.
|
|
57
|
+
- Every applied step validated by real `ark-check`.
|
|
58
|
+
- Final plan `goal.met` true **or** remaining steps listed with file-level proposals and why blocked.
|
|
59
|
+
- Report cites paths you changed and reports HTML paths.
|
|
@@ -1,98 +1,57 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ark-contract
|
|
3
|
-
description: Safely edit ark.config.json (layers, rules, forbiddenGlobals, intent prefixes)
|
|
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 —
|
|
6
|
+
# /ark-contract — Change the architecture contract (safely)
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
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
|
-
##
|
|
12
|
+
## Related onboarding
|
|
25
13
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
78
|
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
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
|
|
49
|
+
## Operating modes
|
|
83
50
|
|
|
84
|
-
|
|
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
|
-
##
|
|
53
|
+
## Done
|
|
95
54
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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.
|