
Product
Socket Now Protects the Firefox Extension Ecosystem
Socket is bringing experimental protection to Firefox, scanning 97,000+ extensions in Mozilla's official directory for malware and risky updates.
ark-runtime-kernel
Advanced tools
Architectural Runtime Kernel — governance for Hexagonal + Event-Driven + DDD systems
Stop AI agents (and humans) from quietly breaking your architecture.
One machine-readable contract — enforced at write time, merge time, and (optionally) runtime.
2-Minute Setup · Why Ark · AI Write Gate · CI Gate · Runtime Kernel · Docs
This is what happens when an agent tries to import a persistence adapter into your domain layer with Ark's write gate active:
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.
No code changes. No new runtime. Just a config and a CI line.
npm install -D ark-runtime-kernel typescript
npx ark-check --init # infers layers from your existing folders → ark.config.json
npx ark-check # done: cross-layer imports now fail the check
Adopting on a codebase that already has violations? Freeze them and ratchet down:
npx ark-check --update-baseline # writes .ark-baseline.json — commit it
npx ark-check --baseline # only NEW violations fail from now on
Then gate your agents (Claude Code shown; Cursor / Codex / others):
// .claude/settings.json
{
"hooks": {
"PreToolUse": [{
"matcher": "Write|Edit|MultiEdit",
"hooks": [{ "type": "command",
"command": "npx ark-mcp --hook --root \"$CLAUDE_PROJECT_DIR\" --config ark.config.json" }]
}]
}
}
The same
ark.config.jsonpowers every gate.
If you only need import-boundary linting in CI, dependency-cruiser, 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:
| Ark | dependency-cruiser | eslint-plugin-boundaries | Nx boundaries | |
|---|---|---|---|---|
| Cross-layer import checks in CI | ✅ (TS resolver) | ✅ | ✅ | ✅ |
| Blocks AI agents before code lands (MCP + hook) | ✅ | ❌ | ❌ | ❌ |
Machine-readable contract for agents (ark://manifest) | ✅ | ❌ | ❌ | ❌ |
| Event/intent governance (who may publish what) | ✅ | ❌ | ❌ | ❌ |
| Baseline ratchet for existing codebases | ✅ | ❌ | ➖ (via ESLint) | ❌ |
| Optional runtime enforcement | ✅ | ❌ | ❌ | ❌ |
| Runtime dependencies | 0 | many | many | Nx |
One config. Three enforcement moments:
| Gate | Tool | When it runs | What it enforces |
|---|---|---|---|
| Write | ark-mcp | Agent PreToolUse (Write/Edit) | Layer rules, unknown intents, forbidden patterns |
| Merge | ark-check | CI (GitHub Actions etc.) | Cross-layer imports + intent references (real TS resolver) |
| Runtime | createArkKernel() | Running process (opt-in) | Intent registry, event contracts, observed layer flow, policies |
ark-mcp is a zero-dependency MCP server + one-shot hook:
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.validate_code tool — on-demand validation of a snippet, for runtimes without hooks.ark://manifest resource — the architecture as JSON, so agents read the rules before generating code instead of learning by rejection.Copy-paste setups for Claude Code, Cursor, and OpenAI Codex: docs/ai-gates.md.
ark-check — The CI Gatenpx ark-check --root . --config ark.config.json --strict-config # fail on coverage gaps too
npx ark-check --json # machine-readable
npx ark-check --baseline # ratchet mode
What it catches (via real TypeScript module resolution — path aliases included):
import(), require)publish() calls that bypass registered intent creatorssource metadataViolations come with the layer edge, the resolved target, and a fix hint:
✖ LAYER_IMPORT_VIOLATION src/domain/order.ts:3
DomainModel → PersistenceAdapters (src/adapters/persistence/pg-order-repository.ts)
DomainModel must not import PersistenceAdapters.
fix: Depend on a port/interface owned by an inner layer instead, or move this code.
- uses: pedroknigge/ark-runtime-kernel@main
with:
github-token: ${{ secrets.GITHUB_TOKEN }} # comments violations on the PR
Inputs: root, config, strict-config, baseline, version.
// eslint.config.js
import ark from 'ark-runtime-kernel/eslint';
export default [ark.configs.recommended];
Rules: ark/no-domain-infra-imports, ark/no-raw-event-publish, ark/require-publish-source.
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:
import { createArkKernel } from 'ark-runtime-kernel';
const ark = createArkKernel(); // strict defaults
const OrderPlaced = ark.registry.define<
'Domain.Order.OrderPlaced',
{ orderId: string; amount: number }
>('Domain.Order.OrderPlaced');
ark.registry.define<'Application.PlaceOrder', { orderId: string }>(
'Application.PlaceOrder',
{ produces: ['Domain.Order.OrderPlaced'] }
);
// Payload contracts: Ark's own schema format, or any Standard Schema
// validator (zod, valibot, arktype) via `standardSchema`.
ark.eventContracts.register({
intent: 'Domain.Order.OrderPlaced',
version: '1',
allowAdditionalFields: false,
schema: {
orderId: { type: 'string', required: true },
amount: { type: 'number', required: true },
},
});
ark.projections.register({
name: 'OrderIds',
sourceIntents: ['Domain.Order.OrderPlaced'],
initialState: { ids: [] as string[] },
project: (event, state) => ({ ids: [...state.ids, event.payload.orderId as string] }),
});
const publisher = ark.publisher('Application.PlaceOrder');
await publisher.publish(OrderPlaced, { orderId: 'o1', amount: 129 }, { eventVersion: '1' });
ark.manifest().toJSON(); // the complete machine-readable contract
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).
Honest scope: runtime enforcement covers governed paths only — what you route through Ark. Everything else is covered by the static gates.
import { ArkModule, InjectArk } from 'ark-runtime-kernel/nestjs';
import type { ArkKernel } from 'ark-runtime-kernel';
@Module({ imports: [ArkModule.forRoot()] })
export class AppModule {}
@Injectable()
export class PlaceOrderService {
constructor(@InjectArk() private readonly ark: ArkKernel) {}
}
@nestjs/common is an optional peer dependency — the core stays zero-dependency.
AuditStore, OutboxStore, …)ark.config.jsonexamples/hexagonal-order-api/, a full hexagonal API you can break on purposenpm ci
npm run build # ark-mcp loads dist/
npx vitest run
npm run typecheck
npm run check:architecture # Ark gates itself in CI
Release: npm run release:npm (verifies typecheck + tests + architecture gate, then publishes; -- --dry for a dry run).
MIT © Pedro Knigge
Ark doesn't generate architecture. It protects the architecture you already have — at the exact moments it matters most.
FAQs
Architecture co-pilot for AI TypeScript: write gate, CI gate, plan/loop (package name ark-runtime-kernel is historical)
The npm package ark-runtime-kernel receives a total of 71 weekly downloads. As such, ark-runtime-kernel popularity was classified as not popular.
We found that ark-runtime-kernel demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.

Product
Socket is bringing experimental protection to Firefox, scanning 97,000+ extensions in Mozilla's official directory for malware and risky updates.

Research
/Security News
Three compromised Rust crates pulled in a malicious dependency that downloaded and executed cross-platform malware during Cargo builds.

Research
/Security News
Socket uncovered 77 linked Firefox extensions, including 40 that steal wallet secrets or credentials and 37 deceptive sports-score shells.