arkgate 2.1.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.
- package/CHANGELOG.md +1249 -0
- package/LICENSE +21 -0
- package/README.md +218 -0
- package/SECURITY.md +39 -0
- package/bin/ark-check.mjs +5204 -0
- package/bin/ark-mcp.mjs +898 -0
- package/bin/ark-shared.mjs +1520 -0
- package/bin/ark.mjs +491 -0
- package/dist/eslint/index.cjs +222 -0
- package/dist/eslint/index.cjs.map +1 -0
- package/dist/eslint/index.d.cts +42 -0
- package/dist/eslint/index.d.ts +40 -0
- package/dist/eslint/index.js +193 -0
- package/dist/eslint/index.js.map +1 -0
- package/dist/index.cjs +3080 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +577 -0
- package/dist/index.d.ts +577 -0
- package/dist/index.js +2998 -0
- package/dist/index.js.map +1 -0
- package/dist/nestjs/index.cjs +2332 -0
- package/dist/nestjs/index.cjs.map +1 -0
- package/dist/nestjs/index.d.cts +22 -0
- package/dist/nestjs/index.d.ts +22 -0
- package/dist/nestjs/index.js +2308 -0
- package/dist/nestjs/index.js.map +1 -0
- package/dist/types-DpdVN7Lm.d.cts +1023 -0
- package/dist/types-DpdVN7Lm.d.ts +1023 -0
- package/docs/agent-guide.md +490 -0
- package/docs/ai-gates.md +337 -0
- package/docs/ark-check-example.json +87 -0
- package/docs/assets/ark-write-gate.svg +28 -0
- package/docs/brownfield-adoption.md +87 -0
- package/docs/demos/01-write-gate-self-correction.md +74 -0
- package/docs/demos/02-brownfield-baseline-adoption.md +71 -0
- package/docs/demos/03-copilot-autopilot.md +83 -0
- package/docs/enthusiast/README.md +62 -0
- package/docs/enthusiast/explanation-application-shape.md +29 -0
- package/docs/enthusiast/how-to-agent-gates.md +36 -0
- package/docs/enthusiast/how-to-gallery-starter.md +27 -0
- package/docs/enthusiast/how-to-pick-shape.md +45 -0
- package/docs/enthusiast/how-to-policy-pack.md +37 -0
- package/docs/enthusiast/reference-archetypes.md +36 -0
- package/docs/enthusiast/reference-commands.md +50 -0
- package/docs/enthusiast/tutorial-first-project.md +86 -0
- package/docs/production-hardening.md +59 -0
- package/package.json +125 -0
- package/server.json +39 -0
- package/templates/architecture-playbook.json +339 -0
- package/templates/policy-packs/enthusiast-feature-sliced.json +20 -0
- package/templates/policy-packs/enthusiast-hexagonal.json +18 -0
- package/templates/policy-packs/enthusiast-layered.json +18 -0
- package/templates/policy-packs/enthusiast-monorepo.json +18 -0
- package/templates/skills/ark-adopt.md +103 -0
- package/templates/skills/ark-architect.md +90 -0
- package/templates/skills/ark-autopilot.md +95 -0
- package/templates/skills/ark-contract.md +98 -0
- package/templates/skills/ark-coverage.md +96 -0
- package/templates/skills/ark-explain.md +78 -0
- package/templates/skills/ark-fix.md +96 -0
- package/templates/skills/ark-loop.md +69 -0
- package/templates/skills/ark-place.md +68 -0
- package/templates/skills/ark-runtime.md +62 -0
- package/templates/skills/ark-upgrade.md +109 -0
package/server.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.pedroknigge/arkgate",
|
|
4
|
+
"description": "ArkGate \u2014 architecture co-pilot for AI TypeScript (write gate, CI, plan/loop)",
|
|
5
|
+
"repository": {
|
|
6
|
+
"url": "https://github.com/pedroknigge/ark-runtime-kernel",
|
|
7
|
+
"source": "github"
|
|
8
|
+
},
|
|
9
|
+
"version": "2.1.0",
|
|
10
|
+
"packages": [
|
|
11
|
+
{
|
|
12
|
+
"registryType": "npm",
|
|
13
|
+
"identifier": "arkgate",
|
|
14
|
+
"version": "2.1.0",
|
|
15
|
+
"runtimeHint": "npx",
|
|
16
|
+
"transport": {
|
|
17
|
+
"type": "stdio"
|
|
18
|
+
},
|
|
19
|
+
"packageArguments": [
|
|
20
|
+
{
|
|
21
|
+
"type": "positional",
|
|
22
|
+
"value": "arkgate-mcp"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"type": "named",
|
|
26
|
+
"name": "--root",
|
|
27
|
+
"value": ".",
|
|
28
|
+
"description": "Project root"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"type": "named",
|
|
32
|
+
"name": "--config",
|
|
33
|
+
"value": "ark.config.json",
|
|
34
|
+
"description": "Path to the ArkGate architecture config"
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "1",
|
|
3
|
+
"locale": "en",
|
|
4
|
+
"localeNote": "Canonical user-facing copy is English. Future translations must not alter archetype ids, preset names, or layer names.",
|
|
5
|
+
"frontendSurfacePresetRule": "feature-sliced when src/app, src/pages, src/features, src/entities, or src/shared exists; otherwise layered",
|
|
6
|
+
"archetypes": {
|
|
7
|
+
"crud-product": {
|
|
8
|
+
"label": "Product with UI and stored data",
|
|
9
|
+
"preset": "hexagonal",
|
|
10
|
+
"phases": {
|
|
11
|
+
"1": [
|
|
12
|
+
"DomainModel",
|
|
13
|
+
"ApplicationOrchestration",
|
|
14
|
+
"PresentationAdapters",
|
|
15
|
+
"PersistenceAdapters"
|
|
16
|
+
],
|
|
17
|
+
"2": ["IntegrationAdapters"],
|
|
18
|
+
"3": ["WorkflowSagaEngine", "BackgroundJobsScheduling"]
|
|
19
|
+
},
|
|
20
|
+
"analogy": "A restaurant: recipes (domain), kitchen coordinator (application), waiters (presentation), suppliers (adapters).",
|
|
21
|
+
"antiPatterns": [
|
|
22
|
+
"Database client or ORM imports inside domain/",
|
|
23
|
+
"HTTP or fetch calls inside business rules"
|
|
24
|
+
],
|
|
25
|
+
"books": [
|
|
26
|
+
{
|
|
27
|
+
"title": "Clean Architecture",
|
|
28
|
+
"author": "Martin",
|
|
29
|
+
"for": "why business rules stay independent of UI and database"
|
|
30
|
+
}
|
|
31
|
+
],
|
|
32
|
+
"detectionSignals": {
|
|
33
|
+
"ui": 5,
|
|
34
|
+
"persistence": 5,
|
|
35
|
+
"fullStackProduct": 4,
|
|
36
|
+
"domain": 1
|
|
37
|
+
},
|
|
38
|
+
"negativeSignals": {
|
|
39
|
+
"workspaces": 4,
|
|
40
|
+
"cli": 5,
|
|
41
|
+
"jobsOnly": 3,
|
|
42
|
+
"tinyTree": 2
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"api-backend": {
|
|
46
|
+
"label": "API server without UI in this repository",
|
|
47
|
+
"preset": "hexagonal",
|
|
48
|
+
"phases": {
|
|
49
|
+
"1": [
|
|
50
|
+
"DomainModel",
|
|
51
|
+
"ApplicationOrchestration",
|
|
52
|
+
"PresentationAdapters",
|
|
53
|
+
"PersistenceAdapters"
|
|
54
|
+
],
|
|
55
|
+
"2": ["IntegrationAdapters"],
|
|
56
|
+
"3": ["SecurityAuditObservability"]
|
|
57
|
+
},
|
|
58
|
+
"analogy": "A kitchen that only serves through a window: rules and coordination inside, orders in and out through adapters.",
|
|
59
|
+
"antiPatterns": [
|
|
60
|
+
"SQL or ORM calls mixed into route handlers without a repository layer",
|
|
61
|
+
"Domain rules that know HTTP status codes"
|
|
62
|
+
],
|
|
63
|
+
"books": [
|
|
64
|
+
{
|
|
65
|
+
"title": "Implementing Domain-Driven Design",
|
|
66
|
+
"author": "Vernon",
|
|
67
|
+
"for": "application services and repository boundaries"
|
|
68
|
+
}
|
|
69
|
+
],
|
|
70
|
+
"detectionSignals": {
|
|
71
|
+
"apiSurface": 6,
|
|
72
|
+
"persistence": 4,
|
|
73
|
+
"application": 2,
|
|
74
|
+
"nestFramework": 8,
|
|
75
|
+
"expressLike": 8
|
|
76
|
+
},
|
|
77
|
+
"negativeSignals": {
|
|
78
|
+
"uiHeavy": 5,
|
|
79
|
+
"workspaces": 3,
|
|
80
|
+
"cli": 5,
|
|
81
|
+
"tinyTree": 2,
|
|
82
|
+
"nextFramework": 4
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"frontend-surface": {
|
|
86
|
+
"label": "UI-focused repository; backend lives elsewhere or is thin",
|
|
87
|
+
"preset": "layered",
|
|
88
|
+
"presetAlternatives": {
|
|
89
|
+
"feature-sliced": {
|
|
90
|
+
"whenSignal": "featureSlicedLayout"
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"phases": {
|
|
94
|
+
"1": ["PresentationAdapters", "ApplicationOrchestration"],
|
|
95
|
+
"2": ["DomainModel"],
|
|
96
|
+
"3": ["IntegrationAdapters"]
|
|
97
|
+
},
|
|
98
|
+
"analogy": "A storefront display: what users see and click; inventory and payments happen behind the counter elsewhere.",
|
|
99
|
+
"antiPatterns": [
|
|
100
|
+
"Embedding database access in UI components",
|
|
101
|
+
"Business rules scattered across page files"
|
|
102
|
+
],
|
|
103
|
+
"books": [
|
|
104
|
+
{
|
|
105
|
+
"title": "Feature-Sliced Design",
|
|
106
|
+
"author": "FSD community",
|
|
107
|
+
"for": "scaling a large UI codebase by feature slices"
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
"detectionSignals": {
|
|
111
|
+
"ui": 6,
|
|
112
|
+
"featureSlicedLayout": 4,
|
|
113
|
+
"nextFramework": 5
|
|
114
|
+
},
|
|
115
|
+
"negativeSignals": {
|
|
116
|
+
"persistence": 5,
|
|
117
|
+
"apiSurfaceOnly": 3,
|
|
118
|
+
"workspaces": 2,
|
|
119
|
+
"cli": 5,
|
|
120
|
+
"tinyTree": 1,
|
|
121
|
+
"nestFramework": 6
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
"library-sdk": {
|
|
125
|
+
"label": "Publishable package others import",
|
|
126
|
+
"preset": "layered",
|
|
127
|
+
"phases": {
|
|
128
|
+
"1": ["DomainModel", "ApplicationOrchestration"],
|
|
129
|
+
"2": ["PersistenceAdapters"],
|
|
130
|
+
"3": ["IntegrationAdapters"]
|
|
131
|
+
},
|
|
132
|
+
"analogy": "A toolbox: clear public tools on top, internal parts hidden, no storefront of its own.",
|
|
133
|
+
"antiPatterns": [
|
|
134
|
+
"Leaking framework-specific types as the only public API",
|
|
135
|
+
"Hidden global state initialized on import"
|
|
136
|
+
],
|
|
137
|
+
"books": [
|
|
138
|
+
{
|
|
139
|
+
"title": "Clean Architecture",
|
|
140
|
+
"author": "Martin",
|
|
141
|
+
"for": "stable boundaries for reusable modules"
|
|
142
|
+
}
|
|
143
|
+
],
|
|
144
|
+
"detectionSignals": {
|
|
145
|
+
"library": 8,
|
|
146
|
+
"domain": 1
|
|
147
|
+
},
|
|
148
|
+
"negativeSignals": {
|
|
149
|
+
"ui": 4,
|
|
150
|
+
"cli": 3,
|
|
151
|
+
"workspaces": 3,
|
|
152
|
+
"persistenceHeavy": 2,
|
|
153
|
+
"nestFramework": 8,
|
|
154
|
+
"nextFramework": 8,
|
|
155
|
+
"apiSurface": 4
|
|
156
|
+
}
|
|
157
|
+
},
|
|
158
|
+
"cli-utility": {
|
|
159
|
+
"label": "Command-line tool",
|
|
160
|
+
"preset": "layered",
|
|
161
|
+
"phases": {
|
|
162
|
+
"1": ["ApplicationOrchestration"],
|
|
163
|
+
"2": ["PersistenceAdapters"],
|
|
164
|
+
"3": ["IntegrationAdapters"]
|
|
165
|
+
},
|
|
166
|
+
"analogy": "A vending machine panel: commands in, results out; storage and network are plug-ins behind the panel.",
|
|
167
|
+
"antiPatterns": [
|
|
168
|
+
"Business logic tangled with argv parsing and console output",
|
|
169
|
+
"Direct filesystem or network calls without a testable core"
|
|
170
|
+
],
|
|
171
|
+
"books": [
|
|
172
|
+
{
|
|
173
|
+
"title": "Clean Architecture",
|
|
174
|
+
"author": "Martin",
|
|
175
|
+
"for": "separating use cases from delivery mechanisms"
|
|
176
|
+
}
|
|
177
|
+
],
|
|
178
|
+
"detectionSignals": {
|
|
179
|
+
"cli": 10
|
|
180
|
+
},
|
|
181
|
+
"negativeSignals": {
|
|
182
|
+
"ui": 4,
|
|
183
|
+
"workspaces": 3,
|
|
184
|
+
"libraryOnly": 2,
|
|
185
|
+
"apiSurface": 6,
|
|
186
|
+
"expressLike": 6,
|
|
187
|
+
"nestFramework": 8,
|
|
188
|
+
"nextFramework": 8
|
|
189
|
+
}
|
|
190
|
+
},
|
|
191
|
+
"worker-pipeline": {
|
|
192
|
+
"label": "Background jobs and queues without a user-facing UI",
|
|
193
|
+
"preset": "hexagonal",
|
|
194
|
+
"phases": {
|
|
195
|
+
"1": ["ApplicationOrchestration", "PersistenceAdapters", "BackgroundJobsScheduling"],
|
|
196
|
+
"2": ["IntegrationAdapters"],
|
|
197
|
+
"3": ["ReportingReadModels"]
|
|
198
|
+
},
|
|
199
|
+
"analogy": "A night shift factory line: triggers arrive, work gets done, results stored — no shop floor for customers.",
|
|
200
|
+
"antiPatterns": [
|
|
201
|
+
"Job handlers that duplicate use-case logic from HTTP routes",
|
|
202
|
+
"Unbounded retries without idempotency at the domain boundary"
|
|
203
|
+
],
|
|
204
|
+
"books": [
|
|
205
|
+
{
|
|
206
|
+
"title": "Building Microservices",
|
|
207
|
+
"author": "Newman",
|
|
208
|
+
"for": "async processing and integration boundaries"
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
"detectionSignals": {
|
|
212
|
+
"jobs": 8,
|
|
213
|
+
"persistence": 2
|
|
214
|
+
},
|
|
215
|
+
"negativeSignals": {
|
|
216
|
+
"uiHeavy": 5,
|
|
217
|
+
"cli": 3,
|
|
218
|
+
"workspaces": 2
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"event-coordinator": {
|
|
222
|
+
"label": "Long-running or multi-step business processes",
|
|
223
|
+
"preset": "hexagonal",
|
|
224
|
+
"phases": {
|
|
225
|
+
"1": ["DomainModel", "ApplicationOrchestration", "WorkflowSagaEngine"],
|
|
226
|
+
"2": ["IntegrationAdapters", "PersistenceAdapters"],
|
|
227
|
+
"3": ["ReportingReadModels"]
|
|
228
|
+
},
|
|
229
|
+
"analogy": "A wedding planner: many steps, compensations when something fails, state tracked across days.",
|
|
230
|
+
"antiPatterns": [
|
|
231
|
+
"Saga logic spread across unrelated HTTP handlers",
|
|
232
|
+
"Missing compensation when an external step fails"
|
|
233
|
+
],
|
|
234
|
+
"books": [
|
|
235
|
+
{
|
|
236
|
+
"title": "Implementing Domain-Driven Design",
|
|
237
|
+
"author": "Vernon",
|
|
238
|
+
"for": "sagas and process managers"
|
|
239
|
+
}
|
|
240
|
+
],
|
|
241
|
+
"detectionSignals": {
|
|
242
|
+
"workflows": 10,
|
|
243
|
+
"domain": 2
|
|
244
|
+
},
|
|
245
|
+
"negativeSignals": {
|
|
246
|
+
"cli": 4,
|
|
247
|
+
"tinyTree": 2,
|
|
248
|
+
"uiOnly": 3
|
|
249
|
+
}
|
|
250
|
+
},
|
|
251
|
+
"integration-bridge": {
|
|
252
|
+
"label": "Connects external systems with thin domain logic",
|
|
253
|
+
"preset": "hexagonal",
|
|
254
|
+
"phases": {
|
|
255
|
+
"1": ["IntegrationAdapters", "ApplicationOrchestration"],
|
|
256
|
+
"2": ["PersistenceAdapters"],
|
|
257
|
+
"3": ["BackgroundJobsScheduling"]
|
|
258
|
+
},
|
|
259
|
+
"analogy": "A translator at a border: messages in, messages out, minimal local rules.",
|
|
260
|
+
"antiPatterns": [
|
|
261
|
+
"Copy-paste integration code per webhook instead of shared adapters",
|
|
262
|
+
"Secrets and env access outside a dedicated config surface"
|
|
263
|
+
],
|
|
264
|
+
"books": [
|
|
265
|
+
{
|
|
266
|
+
"title": "Building Microservices",
|
|
267
|
+
"author": "Newman",
|
|
268
|
+
"for": "integration patterns and boundaries"
|
|
269
|
+
}
|
|
270
|
+
],
|
|
271
|
+
"detectionSignals": {
|
|
272
|
+
"integration": 8,
|
|
273
|
+
"apiSurface": 2
|
|
274
|
+
},
|
|
275
|
+
"negativeSignals": {
|
|
276
|
+
"uiHeavy": 4,
|
|
277
|
+
"domainHeavy": 3,
|
|
278
|
+
"workspaces": 2
|
|
279
|
+
}
|
|
280
|
+
},
|
|
281
|
+
"multi-app-workspace": {
|
|
282
|
+
"label": "Several deployable units in one repository",
|
|
283
|
+
"preset": "monorepo",
|
|
284
|
+
"phases": {
|
|
285
|
+
"1": ["DomainModel", "ApplicationOrchestration"],
|
|
286
|
+
"2": ["PresentationAdapters", "PersistenceAdapters"],
|
|
287
|
+
"3": ["IntegrationAdapters"]
|
|
288
|
+
},
|
|
289
|
+
"analogy": "A mall with separate shops sharing a parking lot: each app is a tenant, shared packages are utilities.",
|
|
290
|
+
"antiPatterns": [
|
|
291
|
+
"One package importing another app's internal directories",
|
|
292
|
+
"A single catch-all layer that hides cross-package coupling"
|
|
293
|
+
],
|
|
294
|
+
"books": [
|
|
295
|
+
{
|
|
296
|
+
"title": "Monorepo.tools",
|
|
297
|
+
"author": "community",
|
|
298
|
+
"for": "workspace layout and dependency boundaries"
|
|
299
|
+
}
|
|
300
|
+
],
|
|
301
|
+
"detectionSignals": {
|
|
302
|
+
"workspaces": 10
|
|
303
|
+
},
|
|
304
|
+
"negativeSignals": {
|
|
305
|
+
"cli": 2,
|
|
306
|
+
"tinyTree": 3
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
"prototype-spike": {
|
|
310
|
+
"label": "Fast experiment or learning project",
|
|
311
|
+
"preset": "layered",
|
|
312
|
+
"phases": {
|
|
313
|
+
"1": ["ApplicationOrchestration", "PersistenceAdapters"],
|
|
314
|
+
"2": ["DomainModel", "PresentationAdapters"],
|
|
315
|
+
"3": ["IntegrationAdapters"]
|
|
316
|
+
},
|
|
317
|
+
"analogy": "A sketch before the painting: enough structure to learn, expand when the idea stabilizes.",
|
|
318
|
+
"antiPatterns": [
|
|
319
|
+
"Adopting every layer on day one before the product shape is known",
|
|
320
|
+
"Skipping governance entirely because the repo is small"
|
|
321
|
+
],
|
|
322
|
+
"books": [
|
|
323
|
+
{
|
|
324
|
+
"title": "Clean Architecture",
|
|
325
|
+
"author": "Martin",
|
|
326
|
+
"for": "growing structure as complexity appears"
|
|
327
|
+
}
|
|
328
|
+
],
|
|
329
|
+
"detectionSignals": {
|
|
330
|
+
"tinyTree": 8
|
|
331
|
+
},
|
|
332
|
+
"negativeSignals": {
|
|
333
|
+
"workspaces": 5,
|
|
334
|
+
"workflows": 4,
|
|
335
|
+
"jobs": 3
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "enthusiast-feature-sliced",
|
|
3
|
+
"preset": "feature-sliced",
|
|
4
|
+
"variant": "enthusiast",
|
|
5
|
+
"label": "Feature-sliced — enthusiast",
|
|
6
|
+
"summary": "Organize by feature slices (App → Pages → Features → Entities → Shared). Start with App, Pages, and Features.",
|
|
7
|
+
"phases": {
|
|
8
|
+
"1": ["App", "Pages", "Features", "Shared"],
|
|
9
|
+
"2": ["Entities"],
|
|
10
|
+
"3": ["Widgets"]
|
|
11
|
+
},
|
|
12
|
+
"layerDescriptions": {
|
|
13
|
+
"App": "App shell — providers, routing, global styles.",
|
|
14
|
+
"Pages": "Full screens composed from features.",
|
|
15
|
+
"Widgets": "Large UI blocks built from features and entities.",
|
|
16
|
+
"Features": "User-facing actions (login, checkout, …).",
|
|
17
|
+
"Entities": "Business nouns shared across features.",
|
|
18
|
+
"Shared": "Buttons, utils, and UI kit with no business knowledge."
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "enthusiast-hexagonal",
|
|
3
|
+
"preset": "hexagonal",
|
|
4
|
+
"variant": "enthusiast",
|
|
5
|
+
"label": "Hexagonal — enthusiast",
|
|
6
|
+
"summary": "Start with domain, application, presentation, and persistence. Add integrations and workflows when you need them.",
|
|
7
|
+
"phases": {
|
|
8
|
+
"1": ["DomainModel", "ApplicationOrchestration", "PresentationAdapters", "PersistenceAdapters"],
|
|
9
|
+
"2": ["IntegrationAdapters"],
|
|
10
|
+
"3": ["WorkflowSagaEngine", "BackgroundJobsScheduling"]
|
|
11
|
+
},
|
|
12
|
+
"layerDescriptions": {
|
|
13
|
+
"DomainModel": "Recipes — pure business rules and ports. No database, HTTP, or ambient globals.",
|
|
14
|
+
"ApplicationOrchestration": "Kitchen coordinator — use cases that call domain through ports only.",
|
|
15
|
+
"PresentationAdapters": "Waiters — UI, routes, and controllers that drive use cases.",
|
|
16
|
+
"PersistenceAdapters": "Suppliers — database, files, and external APIs implementing ports."
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "enthusiast-layered",
|
|
3
|
+
"preset": "layered",
|
|
4
|
+
"variant": "enthusiast",
|
|
5
|
+
"label": "Layered — enthusiast",
|
|
6
|
+
"summary": "Classic top-down layers: presentation → application → domain, with persistence at the bottom.",
|
|
7
|
+
"phases": {
|
|
8
|
+
"1": ["PresentationAdapters", "ApplicationOrchestration", "DomainModel", "PersistenceAdapters"],
|
|
9
|
+
"2": ["IntegrationAdapters"],
|
|
10
|
+
"3": ["BackgroundJobsScheduling"]
|
|
11
|
+
},
|
|
12
|
+
"layerDescriptions": {
|
|
13
|
+
"PresentationAdapters": "What users see and click — pages, components, HTTP handlers.",
|
|
14
|
+
"ApplicationOrchestration": "Business services and use-case coordination.",
|
|
15
|
+
"DomainModel": "Core rules and types — no I/O.",
|
|
16
|
+
"PersistenceAdapters": "Data access and infrastructure implementations."
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "enthusiast-monorepo",
|
|
3
|
+
"preset": "monorepo",
|
|
4
|
+
"variant": "enthusiast",
|
|
5
|
+
"label": "Monorepo — enthusiast",
|
|
6
|
+
"summary": "Several apps and packages in one repo. Match domain/application/presentation/persistence folder names in any package.",
|
|
7
|
+
"phases": {
|
|
8
|
+
"1": ["DomainModel", "ApplicationOrchestration"],
|
|
9
|
+
"2": ["PresentationAdapters", "PersistenceAdapters"],
|
|
10
|
+
"3": ["IntegrationAdapters"]
|
|
11
|
+
},
|
|
12
|
+
"layerDescriptions": {
|
|
13
|
+
"DomainModel": "Shared business types in packages — no I/O.",
|
|
14
|
+
"ApplicationOrchestration": "Shared use cases and services across apps.",
|
|
15
|
+
"PresentationAdapters": "Per-app entrypoints (pages, routes, components).",
|
|
16
|
+
"PersistenceAdapters": "Per-app or shared adapters for storage and APIs."
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ark-adopt
|
|
3
|
+
description: Onboard an existing codebase onto Ark — get the contract to reflect reality, classify ungoverned code, then freeze only genuine debt with a plan. Autonomous.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ark-adopt — Bring Ark into an existing codebase
|
|
7
|
+
|
|
8
|
+
You are onboarding this repository onto Ark. The goal is NOT "make the check
|
|
9
|
+
green" — it is to leave the project with a contract that reflects its real
|
|
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.
|
|
13
|
+
|
|
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
|
+
|
|
19
|
+
## The guiding principle
|
|
20
|
+
|
|
21
|
+
**Ark protects the boundary AROUND a framework, not its internals.** If the repo
|
|
22
|
+
uses a DI/kernel framework (dcouplr, NestJS, a custom kernel), do NOT try to govern
|
|
23
|
+
its inside — declare its PUBLIC SURFACE (the entrypoints app code is meant to
|
|
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.
|
|
26
|
+
|
|
27
|
+
## Steps
|
|
28
|
+
|
|
29
|
+
1. **Config** — if `ark.config.json` is missing, run `ark-check --init`. It detects
|
|
30
|
+
the layer directories that exist, writes a config for them, and PROPOSES a layer
|
|
31
|
+
for every ungoverned directory (sourced from the 11-layer profile + presets),
|
|
32
|
+
flagging the ones it cannot place. If a config exists, keep it — don't regenerate
|
|
33
|
+
unasked.
|
|
34
|
+
|
|
35
|
+
2. **Check + DIAGNOSE — before you freeze anything** — run
|
|
36
|
+
`ark-check --root . --config ark.config.json --json` and read `summary`: it groups
|
|
37
|
+
violations by edge, ranked. The critical signal is `summary.concentrated` /
|
|
38
|
+
`dominantShare`: **when most violations are a single edge, the CONTRACT is almost
|
|
39
|
+
always wrong, not the code.** (Real case: hundreds of API routes "violating"
|
|
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.
|
|
89
|
+
|
|
90
|
+
## Related onboarding
|
|
91
|
+
|
|
92
|
+
- **This skill is for brownfield** — existing messy repos. Do **not** use `/ark-architect` here.
|
|
93
|
+
- Greenfield users: `/ark-architect`, `ark-check --recommend`, gallery starters (`examples/README.md`).
|
|
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.
|
|
96
|
+
|
|
97
|
+
## Verify and report
|
|
98
|
+
|
|
99
|
+
Finish with `ark-check --root . --config ark.config.json --strict-config
|
|
100
|
+
--baseline .ark-baseline.json` (omit `--baseline` if none) — it must pass. Report:
|
|
101
|
+
governed % before/after, files written, violations frozen (and how many false
|
|
102
|
+
positives you AVOIDED freezing by fixing the contract), the ratchet plan, and the
|
|
103
|
+
commands the team needs (`check`, `/ark-fix`, `/ark-coverage`).
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ark-architect
|
|
3
|
+
description: Choose the application shape, adopt phase-1 layers, scaffold directories, and verify honestly — for enthusiasts before codegen. Autonomous.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /ark-architect — Choose your application shape and adopt Ark
|
|
7
|
+
|
|
8
|
+
The user is building something new or early in Ark adoption. They may not know
|
|
9
|
+
layered architecture jargon. Your job: translate **what they want to build**
|
|
10
|
+
(application shape, not framework name) into an Ark preset, a phase-1 layer plan,
|
|
11
|
+
conventional directories, and a passing honest check — without weakening the gate.
|
|
12
|
+
|
|
13
|
+
Commands below are written as `ark-check` / `ark`; run each through the project's
|
|
14
|
+
package manager (`pnpm exec`, `yarn`, `npx`) — match the lockfile.
|
|
15
|
+
|
|
16
|
+
## Relationship to other skills
|
|
17
|
+
|
|
18
|
+
| Skill | When |
|
|
19
|
+
|-------|------|
|
|
20
|
+
| **/ark-architect** | **Before** — greenfield or fresh config; pick shape + phase 1 |
|
|
21
|
+
| /ark-adopt | **After** — messy existing repo |
|
|
22
|
+
| /ark-contract | **During** — evolve config safely |
|
|
23
|
+
| /ark-place | **During** — one new file |
|
|
24
|
+
| /ark-explain | **After** — understand what exists |
|
|
25
|
+
|
|
26
|
+
## Steps
|
|
27
|
+
|
|
28
|
+
1. **Detect the shape** — call MCP tool **`ark_recommend`** (or run
|
|
29
|
+
`ark-check --recommend --json`). Read `archetype`, `preset`, `confidence`,
|
|
30
|
+
`adoptInOrder.phase1`, `analogy`, and `why`. Ask at most **two** questions only
|
|
31
|
+
if `confidence < 0.5`:
|
|
32
|
+
- "Will this app save data between sessions?"
|
|
33
|
+
- "Is this one app or several in one repository?"
|
|
34
|
+
|
|
35
|
+
2. **Present in plain English** — name the application shape (e.g. "product with
|
|
36
|
+
UI and stored data"), not the framework. One analogy. List **phase-1 layers only**.
|
|
37
|
+
|
|
38
|
+
3. **Map to Ark** — if `ark.config.json` is missing, run
|
|
39
|
+
`ark init --archetype <archetype> --yes` (maps playbook id → preset + gates),
|
|
40
|
+
or `ark-check --apply-policy-pack enthusiast-<preset>` for the enthusiast variant.
|
|
41
|
+
Optional team record: `ark-check --recommend --write-plan` → `ark-adoption-plan.json`.
|
|
42
|
+
If a config already exists, use `/ark-contract` to align it — do not regenerate
|
|
43
|
+
unasked.
|
|
44
|
+
|
|
45
|
+
4. **Scaffold phase 1** — create conventional directories from the preset/playbook
|
|
46
|
+
(`src/domain`, `src/application`, …). Add a one-line README per folder explaining
|
|
47
|
+
what belongs there. Match the nearest sibling file style if code already exists.
|
|
48
|
+
Flat layouts (`src/` + `lib/` + `api/` at the repo root) are common in Vite and
|
|
49
|
+
serverless projects — use `/ark-contract` to map them to layers instead of forcing
|
|
50
|
+
everything under `src/**/domain/**` only.
|
|
51
|
+
|
|
52
|
+
5. **Install gates** when the user uses AI coding tools and gates are missing:
|
|
53
|
+
`ark-check --install-agent-gates`.
|
|
54
|
+
|
|
55
|
+
6. **Verify honestly** — run `ark-check --doctor` and `ark-check --coverage --json`.
|
|
56
|
+
Report `governed.percent`. Say explicitly what is **not** governed yet
|
|
57
|
+
(ungoverned directories, empty layers).
|
|
58
|
+
|
|
59
|
+
7. **Deliver to the user**
|
|
60
|
+
- ASCII diagram (≤3 boxes for phase 1, inner → outer)
|
|
61
|
+
- Table: "when you build X, put it in Y"
|
|
62
|
+
- Three rules the agent must not break (no domain→database imports, no raw
|
|
63
|
+
`publish()`, no weakening `ark.config.json` to pass)
|
|
64
|
+
- Optional book refs from `books` in the recommendation JSON under "go deeper"
|
|
65
|
+
- **Gallery starter** — point the user at the matching clonable example:
|
|
66
|
+
|
|
67
|
+
| Archetype | Example directory |
|
|
68
|
+
|-----------|-------------------|
|
|
69
|
+
| `crud-product` | `examples/crud-product-starter/` |
|
|
70
|
+
| `api-backend` | `examples/api-backend-starter/` |
|
|
71
|
+
| `worker-pipeline` | `examples/worker-pipeline-starter/` |
|
|
72
|
+
| `multi-app-workspace` | `examples/multi-app-workspace-starter/` |
|
|
73
|
+
|
|
74
|
+
Say they can copy that folder as a baseline (`npm install && npm run check`).
|
|
75
|
+
For a runnable API with break exercises, mention `examples/hexagonal-order-api/`.
|
|
76
|
+
Full enthusiast track: `docs/enthusiast/README.md`.
|
|
77
|
+
|
|
78
|
+
## Operating rules
|
|
79
|
+
|
|
80
|
+
- Never weaken `ark.config.json`, the baseline, CI, or agent settings to pass.
|
|
81
|
+
- Never invent layers outside the 11-layer profile or named presets.
|
|
82
|
+
- Flag unrecognized dirs (`utils/`, `lib/`) — user must classify via `/ark-contract`.
|
|
83
|
+
- Default to smallest viable phase 1; unlock phase 2 only when the user describes need.
|
|
84
|
+
- All user-facing copy is **English**.
|
|
85
|
+
|
|
86
|
+
## Verify and report
|
|
87
|
+
|
|
88
|
+
End with `ark-check --root . --config ark.config.json --strict-config` when the
|
|
89
|
+
tree is ready. Report: archetype + preset, directories created, governed %, and
|
|
90
|
+
the next command if anything remains ungoverned.
|