{"id":51450080,"url":"https://github.com/pedroknigge/ark-runtime-kernel","last_synced_at":"2026-07-05T20:00:15.034Z","repository":{"id":368974373,"uuid":"1286324673","full_name":"pedroknigge/ark-runtime-kernel","owner":"pedroknigge","description":"Architecture as a machine-readable contract that AI agents and CI must obey — write-time, merge-time, and runtime enforcement for TypeScript","archived":false,"fork":false,"pushed_at":"2026-07-03T02:05:43.000Z","size":368,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T04:10:38.159Z","etag":null,"topics":["ai-agents","architecture","claude-code","ddd","event-driven","governance","hexagonal-architecture","linter","mcp","typescript"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pedroknigge.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-07-01T16:57:47.000Z","updated_at":"2026-07-03T02:05:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pedroknigge/ark-runtime-kernel","commit_stats":null,"previous_names":["pedroknigge/ark-runtime-kernel"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/pedroknigge/ark-runtime-kernel","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedroknigge%2Fark-runtime-kernel","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedroknigge%2Fark-runtime-kernel/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedroknigge%2Fark-runtime-kernel/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedroknigge%2Fark-runtime-kernel/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pedroknigge","download_url":"https://codeload.github.com/pedroknigge/ark-runtime-kernel/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pedroknigge%2Fark-runtime-kernel/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35167259,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-05T02:00:06.290Z","response_time":100,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","architecture","claude-code","ddd","event-driven","governance","hexagonal-architecture","linter","mcp","typescript"],"created_at":"2026-07-05T20:00:14.168Z","updated_at":"2026-07-05T20:00:15.018Z","avatar_url":"https://github.com/pedroknigge.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# 🏛️ Ark — Architectural Runtime Kernel\n\n**Stop AI agents (and humans) from quietly breaking your architecture.**\u003cbr/\u003e\nOne machine-readable contract — enforced at write time, merge time, and (optionally) runtime.\u003cbr/\u003e\nShips a complete 11-layer architecture you can adopt one layer at a time.\nGates **Claude Code, Cursor, and Codex** natively — plus rule files for Windsurf, Cline, Copilot, Kiro, and Gemini CLI.\n\n[![CI](https://github.com/pedroknigge/ark-runtime-kernel/actions/workflows/ci.yml/badge.svg)](https://github.com/pedroknigge/ark-runtime-kernel/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/ark-runtime-kernel?color=cb3837\u0026label=npm)](https://www.npmjs.com/package/ark-runtime-kernel)\n[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)\n![Node](https://img.shields.io/badge/node-%3E%3D18-339933?logo=node.js)\n![TypeScript](https://img.shields.io/badge/TypeScript-first-3178c6?logo=typescript\u0026logoColor=white)\n![Zero deps](https://img.shields.io/badge/dependencies-0-success)\n\n[2-Minute Setup](#2-minute-setup) · [Why Ark](#why-ark-and-not-just-a-linter) · [11 Layers](#batteries-included-the-11-layer-profile-all-optional) · [AI Write Gate](#the-ai-write-gate) · [CI Gate](#ark-check--the-ci-gate) · [Runtime Kernel](#the-runtime-kernel-opt-in) · [Docs](#documentation)\n\n\u003c/div\u003e\n\n---\n\nThis is what happens when an agent tries to import a persistence adapter into your domain layer with Ark's write gate active:\n\n![An AI agent is blocked from importing a persistence adapter into the domain layer, then self-corrects by defining a port](docs/assets/ark-write-gate.svg)\n\nThe 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.\n\n## 2-Minute Setup\n\nNo code changes. No new runtime. Just a config and a CI line.\n\n```bash\nnpm install -D ark-runtime-kernel typescript\nnpx ark init                  # asks before generating config, agent gates, and CI templates\nnpx ark-check                 # done: cross-layer imports now fail the check\n```\n\n`ark init` detects your existing layer directories and suggests the missing ones from\nArk's default 11-layer profile (with their conventional directories), so you see the\nfull division before deciding what to adopt. On an empty project it generates the\ncomplete profile with every layer optional: the check passes immediately, and each\nlayer starts being enforced as soon as its directory gains source files. Agents get\nthe same guidance — the `ark://manifest` resource includes `suggestedLayers`, and the\ngenerated `AGENTS.md` carries the placement table, so an agent asked for a saga or a\nbackground job knows where it belongs before writing it.\n\nAdopting on a codebase that already has violations? Freeze them and ratchet down:\n\n```bash\nnpx ark-check --update-baseline   # writes .ark-baseline.json — commit it\nnpx ark-check --baseline          # only NEW violations fail from now on\n```\n\nThen gate your agents (Claude Code shown; [Cursor / Codex / others](docs/ai-gates.md)). If you use\nCodex in an Ark project, register the MCP server early so `ark://manifest` is available during\ngeneration:\n\n```json\n// .claude/settings.json\n{\n  \"hooks\": {\n    \"PreToolUse\": [{\n      \"matcher\": \"Write|Edit|MultiEdit\",\n      \"hooks\": [{ \"type\": \"command\",\n        \"command\": \"npx ark-mcp --hook --root \\\"$CLAUDE_PROJECT_DIR\\\" --config ark.config.json\" }]\n    }]\n  }\n}\n```\n\n\u003e The same `ark.config.json` powers every gate.\n\nOr generate the starter agent and CI gate files:\n\n```bash\nnpx ark-check --install-agent-gates\n```\n\nThis writes opt-in templates for MCP discovery, Claude/Cursor rules, Codex config notes,\nGitHub Actions, and agent instructions — plus the **`/ark-*` skills** (below) in each\ndetected tool's command location. Existing files are skipped unless you pass `--force`.\n\n### The /ark-* skills\n\nEight autonomous slash commands, installed for every agent CLI detected in the repo\n(Claude Code skills, Cursor commands, Codex prompts, Windsurf/Cline workflows; Copilot\nprompt files via `--tools copilot`, since `.github/` isn't a reliable signal). Each one gathers everything it needs from the repo, takes\nsensible defaults instead of asking, finishes with a strict `ark-check`, and explains\nitself in plain language — useful whether you know hexagonal architecture cold or are\njust trying to keep your code clean:\n\n| Skill | What invoking it does |\n|-------|-----------------------|\n| `/ark-coverage` | Audits which Ark capabilities this project is NOT using and ranks the gaps with the exact command to close each |\n| `/ark-fix` | Resolves current violations at the root cause (ports, moves) — never by weakening the contract |\n| `/ark-adopt` | Onboards an existing codebase: config, gates for every CLI, baseline freeze, ratchet plan |\n| `/ark-place` | Answers \"where does this new code go?\" from the contract, and scaffolds it there |\n| `/ark-contract` | Evolves `ark.config.json` safely, with before/after violation impact |\n| `/ark-explain` | Plain-language tour of this project's architecture and why each rule exists |\n| `/ark-runtime` | Migrates hand-rolled event buses/outboxes/sagas to the runtime kernel |\n| `/ark-upgrade` | After a package update, refreshes gates + skills across all detected CLIs |\n\n\u003e Codex reads slash-command prompts from `~/.codex/prompts`, not the repo, so the\n\u003e generated `.codex/prompts/*.md` need a one-time copy there:\n\u003e `mkdir -p ~/.codex/prompts \u0026\u0026 cp .codex/prompts/*.md ~/.codex/prompts/`. The\n\u003e installer prints this step, and `/ark-adopt` / `/ark-upgrade` offer to run it\n\u003e for you. Every other host loads the skills from the repo path directly.\n\nThe package `postinstall` only prints the next command; it never prompts or writes files\nduring `npm install`. Use `npx ark init --yes` for non-interactive setup.\n\n### Updating Ark\n\nFor projects that already use Ark:\n\n```bash\nnpm install -D ark-runtime-kernel@latest\nnpx ark-check --root . --config ark.config.json --strict-config\nnpm run check:architecture\n```\n\nThis updates the local `ark`, `ark-check`, and `ark-mcp` binaries used by npm scripts\nand CI. `npm run check:architecture` is the recommended alias, but it is optional:\nthe direct `npx ark-check --root . --config ark.config.json --strict-config` command\nis the real check and works even if the alias has not been added yet.\n\nThe lockfile controls the version CI gets, so commit the updated `package-lock.json`,\n`pnpm-lock.yaml`, or `yarn.lock`.\n\nGenerated setup files are intentionally not rewritten during package updates:\n`AGENTS.md`, MCP config, Claude/Cursor settings, Codex notes, and GitHub Actions\ntemplates stay under your project's control. To add any new starter templates:\n\n```bash\nnpx ark-check --install-agent-gates\n```\n\nExisting files are skipped. To regenerate them from the latest templates, review\nyour local changes first, then run:\n\n```bash\nnpx ark-check --install-agent-gates --force\n```\n\n## Why Ark (and not just a linter)?\n\nIf 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:\n\n|                                         | Ark | dependency-cruiser | eslint-plugin-boundaries | Nx boundaries |\n|-----------------------------------------|:---:|:---:|:---:|:---:|\n| Cross-layer import checks in CI         | ✅ (TS resolver) | ✅ | ✅ | ✅ |\n| Blocks AI agents **before** code lands (MCP + hook) | ✅ | ❌ | ❌ | ❌ |\n| Machine-readable contract for agents (`ark://manifest`) | ✅ | ❌ | ❌ | ❌ |\n| Injects the contract into agent context at session start | ✅ | ❌ | ❌ | ❌ |\n| Forbidden ambient globals per layer (`Date.now` in domain, ...) | ✅ | ❌ | ➖ (generic ESLint) | ❌ |\n| Event/intent governance (who may publish what) | ✅ | ❌ | ❌ | ❌ |\n| Baseline ratchet for existing codebases | ✅ | ❌ | ➖ (via ESLint) | ❌ |\n| Optional runtime enforcement            | ✅ | ❌ | ❌ | ❌ |\n| Runtime dependencies                    | 0 | many | many | Nx |\n\n**One config. Three enforcement moments:**\n\n| Gate         | Tool          | When it runs                  | What it enforces                              |\n|--------------|---------------|-------------------------------|-----------------------------------------------|\n| **Write**    | `ark-mcp`     | Agent PreToolUse (Write/Edit) | Layer rules, unknown intents, forbidden patterns + globals |\n| **Merge**    | `ark-check`   | CI (GitHub Actions etc.)      | Cross-layer imports + intent references (real TS resolver) + forbidden globals |\n| **Runtime**  | `createArkKernel()` | Running process (opt-in) | Intent registry, event contracts, observed layer flow, policies |\n\n## Batteries included: the 11-layer profile (all optional)\n\nYou don't have to design a layer model before adopting Ark — it ships a complete,\nproduction-shaped division for Hexagonal + Event-Driven + DDD systems. Every layer is\n**optional by design**: on a fresh project the strict check passes immediately, and each\nlayer starts being enforced the moment its directory gains source files. Adopt two\nlayers or all eleven; `ark.config.json` is always authoritative and you can rename,\nremove, or re-map any of it.\n\n| Layer | Conventional directories | Intent prefixes |\n|-------|--------------------------|-----------------|\n| DomainModel | `domain/` | `Domain.` |\n| ApplicationOrchestration | `application/`, `app/` | `Application.` |\n| PersistenceAdapters | `adapters/persistence/`, `repositories/`, ... | `Adapter.Persistence.`, `Adapter.Repository.` |\n| IntegrationAdapters | `adapters/integration/`, `integrations/`, ... | `Adapter.Integration.`, `Adapter.External.` |\n| WorkflowSagaEngine | `workflows/`, `sagas/` | `Workflow.` |\n| BackgroundJobsScheduling | `jobs/`, `schedules/` | `Job.` |\n| PresentationAdapters | `presentation/`, `adapters/api/`, ... | `Presentation.`, `Adapter.Api.`, ... |\n| ReportingReadModels | `reporting/`, `read-models/`, `projections/` | `Reporting.` |\n| ExtensibilityMetadata | `metadata/`, `extensions/` | `Metadata.` |\n| SecurityAuditObservability | `security/`, `audit/`, `observability/` | `Security.`, `Audit.`, `Observability.` |\n| Kernel | `kernel/` | `Kernel.` |\n\nThe default rule matrix is strict-deny: only the classic flows are open\n(Presentation→Application, Application→Domain, Workflow→Application/Domain,\nJobs→Application) and everything else is a violation until you allow it explicitly.\nThe profile isn't just for the linter — agents get it too: `ark://manifest` lists the\nlayers your project hasn't adopted yet as `suggestedLayers`, so when an agent needs to\ncreate its first saga or background job, it puts it in the conventional place and adds\nthe layer to the config instead of inventing an ungoverned location.\n\n```bash\nnpx ark-check --print-config eleven-layer \u003e ark.config.json   # the full profile, ready to edit\n```\n\n## The AI Write Gate\n\n`ark-mcp` is a zero-dependency MCP server + one-shot hook:\n\n- **`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.\n- **`ark-mcp --session-context`** — SessionStart injection: prints a compact contract summary (layers, forbidden globals, baseline state) into the agent's context, so it knows the architecture from the first token instead of learning by rejection. Silent no-op outside Ark projects, so it can't leak into other repos.\n- **`validate_code` tool** — on-demand validation of a snippet, for runtimes without hooks.\n- **`ark://manifest` resource** — the architecture as JSON, so agents read the rules *before* generating code.\n\nCopy-paste setups for **Claude Code, Cursor, and OpenAI Codex**, plus instruction-tier\nrule files for **Windsurf, Cline, GitHub Copilot, and Kiro** (Gemini CLI reads the\ngenerated `AGENTS.md` directly): [docs/ai-gates.md](docs/ai-gates.md).\n\n## `ark-check` — The CI Gate\n\n```bash\nnpx ark-check --root . --config ark.config.json --strict-config   # fail on coverage gaps too\nnpx ark-check --json                                              # machine-readable\nnpx ark-check --baseline                                          # ratchet mode\n```\n\n**What it catches (via real TypeScript module resolution — path aliases included):**\n\n- Import/export violations (relative, aliases, packages, dynamic `import()`, `require`)\n- String intent references across forbidden layers\n- Raw `publish()` calls that bypass registered intent creators\n- Missing / mismatched publish `source` metadata\n- Forbidden ambient globals per layer (`fetch`, `Date.now`, `Math.random`, ...) — see below\n\n**Fast on repeat runs, monorepo-ready:**\n\n- Per-file scan cache in `node_modules/.cache/ark-check.json` (keyed by mtime+size and\n  the config/manifest contents). Unchanged files skip the TypeScript parse; import edges\n  are always re-resolved against the live filesystem, so the cache can never hide a new\n  violation. Disable with `--no-cache`.\n- Path aliases resolve against the **nearest** `tsconfig.json` above each source file\n  (like `tsc`), so a monorepo with per-package alias maps runs under a single `--root`.\n  Pass `--tsconfig \u003cpath\u003e` to force one config for every file.\n\nViolations come with the layer edge, the resolved target, and a fix hint:\n\n```\n✖ LAYER_IMPORT_VIOLATION  src/domain/order.ts:3\n  DomainModel → PersistenceAdapters  (src/adapters/persistence/pg-order-repository.ts)\n  DomainModel must not import PersistenceAdapters.\n  fix: Depend on a port/interface owned by an inner layer instead, or move this code.\n```\n\n### Domain purity: `forbiddenGlobals`\n\nImport rules can't catch code that reaches for an ambient global — an agent can call\n`fetch()` or `Date.now()` in your domain layer without importing anything. Declare the\nglobals a layer must not touch and both the write gate and CI enforce it:\n\n```jsonc\n// ark.config.json\n{\n  \"name\": \"DomainModel\",\n  \"patterns\": [\"src/domain/**\"],\n  \"intentPrefixes\": [\"Domain.\"],\n  \"forbiddenGlobals\": [\"fetch\", \"process\", \"Date.now\", \"Math.random\"]\n}\n```\n\n```\n✖ FORBIDDEN_GLOBAL  src/domain/order.ts:12\n  DomainModel must not use the ambient global \"Date.now\".\n  fix: Inject the capability through a port (e.g. a Clock, IdGenerator, or HttpPort).\n```\n\nEntries are either dotted (`\"Date.now\"` flags exactly that property access) or bare\n(`\"console\"` flags `console.*`, `fetch(...)`, `new WebSocket(...)`). Detection is\npositional, not scope-aware: mentions in types or import names are never flagged.\n`npx ark init` seeds the domain layer with `[\"fetch\", \"process\", \"Date.now\", \"Math.random\"]`\n(a pure domain does no I/O and is deterministic); add `\"console\"` or any other global per\nproject. Violations participate in the `--baseline` ratchet like every other rule.\n\n### Infrastructure layers: `mayImportInfrastructure`\n\nThe write gate keeps a zero-config heuristic that blocks obvious infrastructure imports\n(`/infra`, `/adapters`, `/persistence`, `/db`, and ORMs like Prisma/TypeORM) so an agent\ncan't quietly wire the database into your pure core. It skips this for layers whose name\nalready signals an infra role (`PersistenceAdapters`, `FrameworkAdapters`, …) — those are\n*supposed* to touch infrastructure. If your infra layer has an unconventional name, opt it\nin so a persistence file isn't blocked for doing its job:\n\n```jsonc\n// ark.config.json\n{\n  \"name\": \"Storage\",\n  \"patterns\": [\"src/storage/**\"],\n  \"mayImportInfrastructure\": true\n}\n```\n\nThe pure core (domain/application) stays protected; `forbiddenPatterns` you add yourself\napply in every layer regardless. `ark-check` (CI) is unaffected — it already judges imports\nby your layer rules, not this heuristic.\n\n### GitHub Action\n\n```yaml\n- uses: pedroknigge/ark-runtime-kernel@main\n  with:\n    github-token: ${{ secrets.GITHUB_TOKEN }}   # comments violations on the PR\n```\n\nInputs: `root`, `config`, `strict-config`, `baseline`, `version`.\n\n### ESLint plugin (in-editor feedback)\n\n```js\n// eslint.config.js\nimport ark from 'ark-runtime-kernel/eslint';\nexport default [ark.configs.recommended];\n```\n\nRules: `ark/no-domain-infra-imports`, `ark/no-raw-event-publish`, `ark/require-publish-source`,\n`ark/no-forbidden-globals` (not in `recommended` — scope it to your layer directories):\n\n```js\n{\n  files: ['src/domain/**'],\n  rules: { 'ark/no-forbidden-globals': ['error', { globals: ['fetch', 'process', 'Date.now', 'Math.random'] }] },\n}\n```\n\n## The Runtime Kernel (opt-in)\n\nThe 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:\n\n```ts\nimport { createArkKernel } from 'ark-runtime-kernel';\n\nconst ark = createArkKernel(); // strict defaults\n\nconst OrderPlaced = ark.registry.define\u003c\n  'Domain.Order.OrderPlaced',\n  { orderId: string; amount: number }\n\u003e('Domain.Order.OrderPlaced');\n\nark.registry.define\u003c'Application.PlaceOrder', { orderId: string }\u003e(\n  'Application.PlaceOrder',\n  { produces: ['Domain.Order.OrderPlaced'] }\n);\n\n// Payload contracts: Ark's own schema format, or any Standard Schema\n// validator (zod, valibot, arktype) via `standardSchema`.\nark.eventContracts.register({\n  intent: 'Domain.Order.OrderPlaced',\n  version: '1',\n  allowAdditionalFields: false,\n  schema: {\n    orderId: { type: 'string', required: true },\n    amount: { type: 'number', required: true },\n  },\n});\n\nark.projections.register({\n  name: 'OrderIds',\n  sourceIntents: ['Domain.Order.OrderPlaced'],\n  initialState: { ids: [] as string[] },\n  project: (event, state) =\u003e ({ ids: [...state.ids, event.payload.orderId as string] }),\n});\n\nconst publisher = ark.publisher('Application.PlaceOrder');\nawait publisher.publish(OrderPlaced, { orderId: 'o1', amount: 129 }, { eventVersion: '1' });\n\nark.manifest().toJSON(); // the complete machine-readable contract\n```\n\nWhat 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)).\n\n**Honest scope:** runtime enforcement covers governed paths only — what you route through Ark. Everything else is covered by the static gates.\n\n### NestJS\n\n```ts\nimport { ArkModule, InjectArk } from 'ark-runtime-kernel/nestjs';\nimport type { ArkKernel } from 'ark-runtime-kernel';\n\n@Module({ imports: [ArkModule.forRoot()] })\nexport class AppModule {}\n\n@Injectable()\nexport class PlaceOrderService {\n  constructor(@InjectArk() private readonly ark: ArkKernel) {}\n}\n```\n\n`@nestjs/common` is an optional peer dependency — the core stays zero-dependency.\n\n## Documentation\n\n- [AI Gates](docs/ai-gates.md) — copy-paste setups for Claude Code, Cursor, Codex, and any hook-capable runtime\n- [Agent Integration Guide](docs/agent-guide.md) — manifest discovery and validation flows for agents\n- [Production Hardening](docs/production-hardening.md) — durable store interfaces (`AuditStore`, `OutboxStore`, …)\n- [Example Config](docs/ark-check-example.json) — a hand-curated `ark.config.json`\n- [Runnable Examples](examples/) — including `examples/hexagonal-order-api/`, a full hexagonal API you can break on purpose\n- [Roadmap](ROADMAP.md) · [Contributing](CONTRIBUTING.md) · [Changelog](CHANGELOG.md)\n\n## Development\n\n```bash\nnpm ci\nnpm run build              # ark-mcp loads dist/\nnpx vitest run\nnpm run typecheck\nnpm run check:architecture # Ark gates itself in CI\n```\n\nRelease: `npm run release:npm` (verifies typecheck + tests + architecture gate, then publishes; `-- --dry` for a dry run).\n\n## License\n\nMIT © Pedro Knigge\n\n---\n\n**Ark doesn't generate architecture. It protects the architecture you already have — at the exact moments it matters most.**\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedroknigge%2Fark-runtime-kernel","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpedroknigge%2Fark-runtime-kernel","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpedroknigge%2Fark-runtime-kernel/lists"}