ark-runtime-kernel 1.0.0 โ 1.2.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/README.md +133 -219
- package/bin/ark-check.mjs +316 -20
- package/bin/ark-mcp.mjs +0 -0
- package/bin/ark-postinstall.mjs +12 -0
- package/bin/ark.mjs +129 -0
- package/dist/index.cjs +26 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -958
- package/dist/index.d.ts +5 -958
- package/dist/index.js +26 -1
- package/dist/index.js.map +1 -1
- package/dist/nestjs/index.cjs +2301 -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 +2298 -0
- package/dist/nestjs/index.js.map +1 -0
- package/dist/types-7K_KQCgS.d.cts +991 -0
- package/dist/types-7K_KQCgS.d.ts +991 -0
- package/docs/agent-guide.md +344 -0
- package/docs/ai-gates.md +169 -0
- package/docs/ark-check-example.json +87 -0
- package/docs/assets/ark-write-gate.svg +28 -0
- package/docs/blog/how-i-stopped-claude-from-breaking-my-architecture.md +85 -0
- package/docs/production-hardening.md +59 -0
- package/package.json +46 -8
- package/server.json +31 -0
package/README.md
CHANGED
|
@@ -2,126 +2,160 @@
|
|
|
2
2
|
|
|
3
3
|
# ๐๏ธ Ark โ Architectural Runtime Kernel
|
|
4
4
|
|
|
5
|
-
**
|
|
6
|
-
|
|
5
|
+
**Stop AI agents (and humans) from quietly breaking your architecture.**<br/>
|
|
6
|
+
One machine-readable contract โ enforced at write time, merge time, and (optionally) runtime.
|
|
7
7
|
|
|
8
|
-
[](https://github.com/pedroknigge/ark/actions/workflows/ci.yml)
|
|
8
|
+
[](https://github.com/pedroknigge/ark-runtime-kernel/actions/workflows/ci.yml)
|
|
9
9
|
[](https://www.npmjs.com/package/ark-runtime-kernel)
|
|
10
10
|
[](LICENSE)
|
|
11
11
|

|
|
12
12
|

|
|
13
13
|

|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
[Quick Start](#60-second-setup) ยท [The Three Gates](#the-three-gates-visual) ยท [AI Write Gate](#ai-write-path-gate-ark-mcp) ยท [CI Gate](#ark-check--the-ci-gate) ยท [Docs](#documentation)
|
|
15
|
+
[2-Minute Setup](#2-minute-setup) ยท [Why Ark](#why-ark-and-not-just-a-linter) ยท [AI Write Gate](#the-ai-write-gate) ยท [CI Gate](#ark-check--the-ci-gate) ยท [Runtime Kernel](#the-runtime-kernel-opt-in) ยท [Docs](#documentation)
|
|
18
16
|
|
|
19
17
|
</div>
|
|
20
18
|
|
|
21
19
|
---
|
|
22
20
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
```mermaid
|
|
26
|
-
flowchart LR
|
|
27
|
-
A["โ๏ธ Write Time<br/>AI Agents"] -->|ark-mcp + validate_code| B["๐ซ Blocked"]
|
|
28
|
-
A -->|valid| C["๐พ Disk"]
|
|
21
|
+
This is what happens when an agent tries to import a persistence adapter into your domain layer with Ark's write gate active:
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
D -->|valid| F["โ
Merge"]
|
|
23
|
+

|
|
32
24
|
|
|
33
|
-
|
|
34
|
-
G --> I["๐ Observability<br/>+ Manifest"]
|
|
35
|
-
|
|
36
|
-
style A fill:#e0f2fe,color:#0c4a6e
|
|
37
|
-
style D fill:#fef3c7,color:#92400e
|
|
38
|
-
style G fill:#dcfce7,color:#166534
|
|
39
|
-
```
|
|
25
|
+
The agent doesn't just get blocked โ it gets the violation as feedback, reads the architecture contract, and **fixes its own approach**. No review round-trip.
|
|
40
26
|
|
|
41
|
-
|
|
27
|
+
## 2-Minute Setup
|
|
42
28
|
|
|
43
|
-
|
|
44
|
-
|--------------|---------------|-------------------------------|-----------------------------------------------|
|
|
45
|
-
| **Write** | `ark-mcp` | Agent PreToolUse (Write/Edit) | Layer rules, unknown intents, forbidden patterns |
|
|
46
|
-
| **Merge** | `ark-check` | CI (GitHub Actions etc.) | Cross-layer imports + intent references (real TS resolver) |
|
|
47
|
-
| **Runtime** | `createArkKernel()` | Running process | Intent registry, event contracts, observed layer flow, policies |
|
|
48
|
-
|
|
49
|
-
---
|
|
50
|
-
|
|
51
|
-
## 60-Second Setup
|
|
29
|
+
No code changes. No new runtime. Just a config and a CI line.
|
|
52
30
|
|
|
53
31
|
```bash
|
|
54
32
|
npm install -D ark-runtime-kernel typescript
|
|
33
|
+
npx ark init # asks before generating config, agent gates, and CI templates
|
|
34
|
+
npx ark-check # done: cross-layer imports now fail the check
|
|
55
35
|
```
|
|
56
36
|
|
|
57
|
-
|
|
37
|
+
Adopting on a codebase that already has violations? Freeze them and ratchet down:
|
|
58
38
|
|
|
59
39
|
```bash
|
|
60
|
-
npx ark-check --
|
|
40
|
+
npx ark-check --update-baseline # writes .ark-baseline.json โ commit it
|
|
41
|
+
npx ark-check --baseline # only NEW violations fail from now on
|
|
61
42
|
```
|
|
62
43
|
|
|
63
|
-
|
|
44
|
+
Then gate your agents (Claude Code shown; [Cursor / Codex / others](docs/ai-gates.md)):
|
|
64
45
|
|
|
65
|
-
```
|
|
66
|
-
|
|
46
|
+
```json
|
|
47
|
+
// .claude/settings.json
|
|
48
|
+
{
|
|
49
|
+
"hooks": {
|
|
50
|
+
"PreToolUse": [{
|
|
51
|
+
"matcher": "Write|Edit|MultiEdit",
|
|
52
|
+
"hooks": [{ "type": "command",
|
|
53
|
+
"command": "npx ark-mcp --hook --root \"$CLAUDE_PROJECT_DIR\" --config ark.config.json" }]
|
|
54
|
+
}]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
67
57
|
```
|
|
68
58
|
|
|
69
|
-
|
|
59
|
+
> The same `ark.config.json` powers every gate.
|
|
60
|
+
|
|
61
|
+
Or generate the starter agent and CI gate files:
|
|
70
62
|
|
|
71
63
|
```bash
|
|
72
|
-
npx ark-
|
|
64
|
+
npx ark-check --install-agent-gates
|
|
73
65
|
```
|
|
74
66
|
|
|
75
|
-
|
|
67
|
+
This writes opt-in templates for MCP discovery, Claude/Cursor rules, Codex config notes,
|
|
68
|
+
GitHub Actions, and agent instructions. Existing files are skipped unless you pass
|
|
69
|
+
`--force`.
|
|
76
70
|
|
|
77
|
-
|
|
71
|
+
The package `postinstall` only prints the next command; it never prompts or writes files
|
|
72
|
+
during `npm install`. Use `npx ark init --yes` for non-interactive setup.
|
|
78
73
|
|
|
79
|
-
|
|
74
|
+
## Why Ark (and not just a linter)?
|
|
80
75
|
|
|
81
|
-
|
|
76
|
+
If you only need import-boundary linting in CI, [dependency-cruiser](https://github.com/sverweij/dependency-cruiser), [eslint-plugin-boundaries](https://github.com/javierbrea/eslint-plugin-boundaries), and Nx module boundaries are solid tools. Ark's reason to exist is the **write-time, agent-native half** they don't cover:
|
|
82
77
|
|
|
83
|
-
Ark
|
|
78
|
+
| | Ark | dependency-cruiser | eslint-plugin-boundaries | Nx boundaries |
|
|
79
|
+
|-----------------------------------------|:---:|:---:|:---:|:---:|
|
|
80
|
+
| Cross-layer import checks in CI | โ
(TS resolver) | โ
| โ
| โ
|
|
|
81
|
+
| Blocks AI agents **before** code lands (MCP + hook) | โ
| โ | โ | โ |
|
|
82
|
+
| Machine-readable contract for agents (`ark://manifest`) | โ
| โ | โ | โ |
|
|
83
|
+
| Event/intent governance (who may publish what) | โ
| โ | โ | โ |
|
|
84
|
+
| Baseline ratchet for existing codebases | โ
| โ | โ (via ESLint) | โ |
|
|
85
|
+
| Optional runtime enforcement | โ
| โ | โ | โ |
|
|
86
|
+
| Runtime dependencies | 0 | many | many | Nx |
|
|
84
87
|
|
|
85
|
-
|
|
88
|
+
**One config. Three enforcement moments:**
|
|
86
89
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
- **11-Layer Profile** โ First-class support for proper Hexagonal/Event-Driven boundaries.
|
|
93
|
-
- **Manifest** โ `ark.manifest().toJSON()` โ complete machine-readable contract for agents and tools.
|
|
94
|
-
- **Observability & Drift** โ Declared vs observed flow reports.
|
|
95
|
-
- **Audit / Outbox / Projections / Workflow (Saga)** โ Pluggable in-memory defaults + interfaces.
|
|
96
|
-
- **Static + AI Gates** โ `ark-check` (deep) + `ark-mcp` + ESLint plugin.
|
|
90
|
+
| Gate | Tool | When it runs | What it enforces |
|
|
91
|
+
|--------------|---------------|-------------------------------|-----------------------------------------------|
|
|
92
|
+
| **Write** | `ark-mcp` | Agent PreToolUse (Write/Edit) | Layer rules, unknown intents, forbidden patterns |
|
|
93
|
+
| **Merge** | `ark-check` | CI (GitHub Actions etc.) | Cross-layer imports + intent references (real TS resolver) |
|
|
94
|
+
| **Runtime** | `createArkKernel()` | Running process (opt-in) | Intent registry, event contracts, observed layer flow, policies |
|
|
97
95
|
|
|
98
|
-
|
|
96
|
+
## The AI Write Gate
|
|
99
97
|
|
|
100
|
-
|
|
101
|
-
- Unregistered intents / bad names
|
|
102
|
-
- Unknown sources
|
|
103
|
-
- Contract violations
|
|
104
|
-
- Hard policy violations
|
|
105
|
-
- Observed layer flow violations (when `hard`)
|
|
98
|
+
`ark-mcp` is a zero-dependency MCP server + one-shot hook:
|
|
106
99
|
|
|
107
|
-
**
|
|
108
|
-
-
|
|
109
|
-
-
|
|
110
|
-
- Raw `publish()` calls
|
|
111
|
-
- Missing `source` on strict publishes
|
|
100
|
+
- **`ark-mcp --hook`** โ PreToolUse gate: computes the **post-edit** file content, validates it against your layers, exits 2 with the violations when the write must be blocked. The agent self-corrects.
|
|
101
|
+
- **`validate_code` tool** โ on-demand validation of a snippet, for runtimes without hooks.
|
|
102
|
+
- **`ark://manifest` resource** โ the architecture as JSON, so agents read the rules *before* generating code instead of learning by rejection.
|
|
112
103
|
|
|
113
|
-
|
|
104
|
+
Copy-paste setups for **Claude Code, Cursor, and OpenAI Codex**: [docs/ai-gates.md](docs/ai-gates.md).
|
|
114
105
|
|
|
115
|
-
|
|
106
|
+
## `ark-check` โ The CI Gate
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
npx ark-check --root . --config ark.config.json --strict-config # fail on coverage gaps too
|
|
110
|
+
npx ark-check --json # machine-readable
|
|
111
|
+
npx ark-check --baseline # ratchet mode
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
**What it catches (via real TypeScript module resolution โ path aliases included):**
|
|
115
|
+
|
|
116
|
+
- Import/export violations (relative, aliases, packages, dynamic `import()`, `require`)
|
|
117
|
+
- String intent references across forbidden layers
|
|
118
|
+
- Raw `publish()` calls that bypass registered intent creators
|
|
119
|
+
- Missing / mismatched publish `source` metadata
|
|
120
|
+
|
|
121
|
+
Violations come with the layer edge, the resolved target, and a fix hint:
|
|
116
122
|
|
|
117
|
-
|
|
123
|
+
```
|
|
124
|
+
โ LAYER_IMPORT_VIOLATION src/domain/order.ts:3
|
|
125
|
+
DomainModel โ PersistenceAdapters (src/adapters/persistence/pg-order-repository.ts)
|
|
126
|
+
DomainModel must not import PersistenceAdapters.
|
|
127
|
+
fix: Depend on a port/interface owned by an inner layer instead, or move this code.
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### GitHub Action
|
|
131
|
+
|
|
132
|
+
```yaml
|
|
133
|
+
- uses: pedroknigge/ark-runtime-kernel@main
|
|
134
|
+
with:
|
|
135
|
+
github-token: ${{ secrets.GITHUB_TOKEN }} # comments violations on the PR
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Inputs: `root`, `config`, `strict-config`, `baseline`, `version`.
|
|
139
|
+
|
|
140
|
+
### ESLint plugin (in-editor feedback)
|
|
141
|
+
|
|
142
|
+
```js
|
|
143
|
+
// eslint.config.js
|
|
144
|
+
import ark from 'ark-runtime-kernel/eslint';
|
|
145
|
+
export default [ark.configs.recommended];
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Rules: `ark/no-domain-infra-imports`, `ark/no-raw-event-publish`, `ark/require-publish-source`.
|
|
149
|
+
|
|
150
|
+
## The Runtime Kernel (opt-in)
|
|
151
|
+
|
|
152
|
+
The gates above need **zero changes to your code**. When you also want *runtime* guarantees โ registered intents only, payload contracts, observed producerโevent layer flows โ route your events through the kernel:
|
|
118
153
|
|
|
119
154
|
```ts
|
|
120
155
|
import { createArkKernel } from 'ark-runtime-kernel';
|
|
121
156
|
|
|
122
|
-
const ark = createArkKernel(); //
|
|
157
|
+
const ark = createArkKernel(); // strict defaults
|
|
123
158
|
|
|
124
|
-
// 1. Define intents
|
|
125
159
|
const OrderPlaced = ark.registry.define<
|
|
126
160
|
'Domain.Order.OrderPlaced',
|
|
127
161
|
{ orderId: string; amount: number }
|
|
@@ -132,7 +166,8 @@ ark.registry.define<'Application.PlaceOrder', { orderId: string }>(
|
|
|
132
166
|
{ produces: ['Domain.Order.OrderPlaced'] }
|
|
133
167
|
);
|
|
134
168
|
|
|
135
|
-
//
|
|
169
|
+
// Payload contracts: Ark's own schema format, or any Standard Schema
|
|
170
|
+
// validator (zod, valibot, arktype) via `standardSchema`.
|
|
136
171
|
ark.eventContracts.register({
|
|
137
172
|
intent: 'Domain.Order.OrderPlaced',
|
|
138
173
|
version: '1',
|
|
@@ -143,179 +178,60 @@ ark.eventContracts.register({
|
|
|
143
178
|
},
|
|
144
179
|
});
|
|
145
180
|
|
|
146
|
-
// 3. Projections (read models)
|
|
147
181
|
ark.projections.register({
|
|
148
182
|
name: 'OrderIds',
|
|
149
183
|
sourceIntents: ['Domain.Order.OrderPlaced'],
|
|
150
184
|
initialState: { ids: [] as string[] },
|
|
151
|
-
project: (event, state) => ({
|
|
152
|
-
ids: [...state.ids, event.payload.orderId as string],
|
|
153
|
-
}),
|
|
185
|
+
project: (event, state) => ({ ids: [...state.ids, event.payload.orderId as string] }),
|
|
154
186
|
});
|
|
155
187
|
|
|
156
|
-
// 4. Publish through source-bound publisher (recommended)
|
|
157
188
|
const publisher = ark.publisher('Application.PlaceOrder');
|
|
189
|
+
await publisher.publish(OrderPlaced, { orderId: 'o1', amount: 129 }, { eventVersion: '1' });
|
|
158
190
|
|
|
159
|
-
|
|
160
|
-
eventVersion: '1',
|
|
161
|
-
correlationId: 'corr-xyz',
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
console.log(await ark.projections.getState('OrderIds'));
|
|
165
|
-
console.log(ark.observability.report());
|
|
166
|
-
console.log(JSON.stringify(ark.manifest().toJSON(), null, 2));
|
|
191
|
+
ark.manifest().toJSON(); // the complete machine-readable contract
|
|
167
192
|
```
|
|
168
193
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
---
|
|
194
|
+
What it gives you: intent registry with produces/dependsOn, strict event bus (registered intents only, known sources), event contracts, hard/soft policies, observed layer-flow enforcement (`'hard' | 'soft' | 'off'`), projections, observability/drift reports, and pluggable audit/outbox/workflow interfaces (in-memory defaults โ see [production hardening](docs/production-hardening.md)).
|
|
172
195
|
|
|
173
|
-
|
|
196
|
+
**Honest scope:** runtime enforcement covers governed paths only โ what you route through Ark. Everything else is covered by the static gates.
|
|
174
197
|
|
|
175
|
-
|
|
198
|
+
### NestJS
|
|
176
199
|
|
|
177
|
-
|
|
200
|
+
```ts
|
|
201
|
+
import { ArkModule, InjectArk } from 'ark-runtime-kernel/nestjs';
|
|
202
|
+
import type { ArkKernel } from 'ark-runtime-kernel';
|
|
178
203
|
|
|
179
|
-
|
|
204
|
+
@Module({ imports: [ArkModule.forRoot()] })
|
|
205
|
+
export class AppModule {}
|
|
180
206
|
|
|
181
|
-
|
|
182
|
-
{
|
|
183
|
-
|
|
184
|
-
"PreToolUse": [{
|
|
185
|
-
"matcher": "Write|Edit|MultiEdit",
|
|
186
|
-
"hooks": [{
|
|
187
|
-
"type": "command",
|
|
188
|
-
"command": "npx ark-mcp --hook --root \"$CLAUDE_PROJECT_DIR\""
|
|
189
|
-
}]
|
|
190
|
-
}]
|
|
191
|
-
}
|
|
207
|
+
@Injectable()
|
|
208
|
+
export class PlaceOrderService {
|
|
209
|
+
constructor(@InjectArk() private readonly ark: ArkKernel) {}
|
|
192
210
|
}
|
|
193
211
|
```
|
|
194
212
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
### Full MCP server
|
|
198
|
-
|
|
199
|
-
```bash
|
|
200
|
-
npx ark-mcp --root . --config ark.config.json
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
Exposes:
|
|
204
|
-
- Resource: `ark://manifest`
|
|
205
|
-
- Tool: `validate_code(source, layer?, filePath?)`
|
|
206
|
-
|
|
207
|
-
Register in `.mcp.json`.
|
|
208
|
-
|
|
209
|
-
---
|
|
210
|
-
|
|
211
|
-
## `ark-check` โ The CI Gate
|
|
212
|
-
|
|
213
|
-
```bash
|
|
214
|
-
# Basic
|
|
215
|
-
npx ark-check --root . --config ark.config.json
|
|
216
|
-
|
|
217
|
-
# Fail on coverage gaps too
|
|
218
|
-
npx ark-check --root . --config ark.config.json --strict-config
|
|
219
|
-
|
|
220
|
-
# JSON for tools
|
|
221
|
-
npx ark-check --json
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
**What it catches (via real TypeScript resolution):**
|
|
225
|
-
- Import/export violations (relative, aliases, packages, dynamic import, require)
|
|
226
|
-
- String intent references across forbidden layers
|
|
227
|
-
- Raw publish calls
|
|
228
|
-
- Missing source metadata
|
|
229
|
-
- Source-layer mismatch
|
|
230
|
-
|
|
231
|
-
`--init` generates a real config from the directories that *actually exist* in your project.
|
|
232
|
-
|
|
233
|
-
---
|
|
234
|
-
|
|
235
|
-
## ESLint Plugin (dev guardrails)
|
|
236
|
-
|
|
237
|
-
```js
|
|
238
|
-
// eslint.config.js
|
|
239
|
-
import ark from 'ark-runtime-kernel/eslint';
|
|
240
|
-
|
|
241
|
-
export default [
|
|
242
|
-
ark.configs.recommended,
|
|
243
|
-
];
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
Rules:
|
|
247
|
-
- `ark/no-domain-infra-imports`
|
|
248
|
-
- `ark/no-raw-event-publish`
|
|
249
|
-
- `ark/require-publish-source`
|
|
250
|
-
|
|
251
|
-
---
|
|
252
|
-
|
|
253
|
-
## What Ark Is / Is Not
|
|
254
|
-
|
|
255
|
-
| โ
Ark is | โ Ark is not |
|
|
256
|
-
|---------------------------------------|-------------------------------------------|
|
|
257
|
-
| Runtime + CI + AI governance kernel | Database or queue |
|
|
258
|
-
| Enforceable architectural contract | Full distributed workflow engine |
|
|
259
|
-
| Machine-readable manifest for agents | Replacement for your domain logic |
|
|
260
|
-
| Zero-dependency TypeScript library | Complete semantic / type analyzer |
|
|
261
|
-
| Observable drift + history | OpenTelemetry implementation |
|
|
262
|
-
| Focused, explicit, pluggable | Magic that covers code you never route |
|
|
263
|
-
|
|
264
|
-
---
|
|
265
|
-
|
|
266
|
-
## Architecture Profile (11 Layers)
|
|
267
|
-
|
|
268
|
-
The built-in profile + `ark.config.json` give you a sane default taxonomy:
|
|
269
|
-
|
|
270
|
-
`DomainModel โ ApplicationOrchestration โ PersistenceAdapters โ ...` (and 8 more)
|
|
271
|
-
|
|
272
|
-
You can customize freely. Rules are deny-by-default except for a few explicitly allowed flows.
|
|
273
|
-
|
|
274
|
-
---
|
|
275
|
-
|
|
276
|
-
## Production Notes
|
|
277
|
-
|
|
278
|
-
All stores (`Audit`, `Outbox`, `Projections`, `Workflow`) default to in-memory.
|
|
279
|
-
|
|
280
|
-
See [docs/production-hardening.md](./docs/production-hardening.md) for the interface contracts you must implement for durability.
|
|
281
|
-
|
|
282
|
-
---
|
|
213
|
+
`@nestjs/common` is an optional peer dependency โ the core stays zero-dependency.
|
|
283
214
|
|
|
284
215
|
## Documentation
|
|
285
216
|
|
|
286
|
-
- [
|
|
287
|
-
- [
|
|
288
|
-
- [
|
|
289
|
-
- [
|
|
290
|
-
- [
|
|
291
|
-
|
|
292
|
-
---
|
|
217
|
+
- [AI Gates](docs/ai-gates.md) โ copy-paste setups for Claude Code, Cursor, Codex, and any hook-capable runtime
|
|
218
|
+
- [Agent Integration Guide](docs/agent-guide.md) โ manifest discovery and validation flows for agents
|
|
219
|
+
- [Production Hardening](docs/production-hardening.md) โ durable store interfaces (`AuditStore`, `OutboxStore`, โฆ)
|
|
220
|
+
- [Example Config](docs/ark-check-example.json) โ a hand-curated `ark.config.json`
|
|
221
|
+
- [Runnable Examples](examples/) โ including `examples/hexagonal-order-api/`, a full hexagonal API you can break on purpose
|
|
222
|
+
- [Roadmap](ROADMAP.md) ยท [Contributing](CONTRIBUTING.md) ยท [Changelog](CHANGELOG.md)
|
|
293
223
|
|
|
294
224
|
## Development
|
|
295
225
|
|
|
296
226
|
```bash
|
|
297
|
-
npm
|
|
227
|
+
npm ci
|
|
228
|
+
npm run build # ark-mcp loads dist/
|
|
229
|
+
npx vitest run
|
|
298
230
|
npm run typecheck
|
|
299
|
-
npm run check:architecture
|
|
300
|
-
npm test
|
|
301
|
-
npm run build
|
|
231
|
+
npm run check:architecture # Ark gates itself in CI
|
|
302
232
|
```
|
|
303
233
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
```bash
|
|
307
|
-
npm run release:npm # full verify + publish
|
|
308
|
-
npm run release:npm -- --dry # dry run
|
|
309
|
-
```
|
|
310
|
-
|
|
311
|
-
The release script:
|
|
312
|
-
1. Typechecks + runs all tests + self architecture check
|
|
313
|
-
2. Builds
|
|
314
|
-
3. Temporarily swaps in the minimal publish manifest
|
|
315
|
-
4. Publishes
|
|
316
|
-
5. Restores dev manifest
|
|
317
|
-
|
|
318
|
-
---
|
|
234
|
+
Release: `npm run release:npm` (verifies typecheck + tests + architecture gate, then publishes; `-- --dry` for a dry run).
|
|
319
235
|
|
|
320
236
|
## License
|
|
321
237
|
|
|
@@ -324,5 +240,3 @@ MIT ยฉ Pedro Knigge
|
|
|
324
240
|
---
|
|
325
241
|
|
|
326
242
|
**Ark doesn't generate architecture. It protects the architecture you already have โ at the exact moments it matters most.**
|
|
327
|
-
|
|
328
|
-
Built for teams that use AI heavily and refuse to let entropy win.
|