ArkGate — Write. Check. Ship.
When the agent writes a bad import, the write doesn’t land. The same check fails the pull request.
Not an API Gateway. Not a folder linter. If the check is not required on the PR, the config
is just documentation.
Works with Cursor, Claude, Codex, and Grok.

┌─────────┐ ┌─────────┐ ┌─────────┐
│ WRITE │────▶│ CHECK │────▶│ SHIP │
│ agent │ │ block │ │ merge │
└─────────┘ └────┬────┘ └─────────┘
│
▼
bad import
doesn't land
ArkGate 4.7.5 (tree). npm latest remains 4.7.4 until this patch publishes.
Write. Check. Ship. Adopted = required GitHub status running
arkgate-check --strict-merge, or an explicit advisory-only stance.
Status is compact (arkgate-check --doctor; --all for Details). Optional ArkRun
(@arkgate/runtime, experimental) is an in-memory runtime — not Postgres.
4.7.5 · 4.7.4 · Docs hub · Voice
Choose your path
Full map: docs/README.md
Start in one minute
npm install -D arkgate typescript
npx arkgate start
npx arkgate start --apply
npx arkgate-check --doctor
npx arkgate-check --doctor --all
That is the product. Stuck? Run status (--doctor) and do action #1.
start → doctor → new files in the right folder
↘ leftover mess: map, then one small refactor
Keep the rules file out of product PRs. Local check:
ark-check --changed --base origin/dev. Changing the rules themselves uses --contract-session.
Aliases ark / ark-check / ark-mcp still work. npm / pnpm / yarn. No install lifecycle scripts.

What it is
src/domain/order.ts
│ import { db } from "../infra/postgres"
▼
┌──────────────────────────────────────────┐
│ CHECK │
│ Domain ─✕─▶ Infrastructure │
│ write doesn't land · PR check fails │
└──────────────────────────────────────────┘
When the agent writes a bad import, the write doesn’t land.
The same check fails the pull request. That is ArkGate — import rules, always on
once you adopt. The other two are optional.
| While the agent writes | The write doesn’t land on supported hosts; warning only elsewhere | Always (ArkGate) |
| Before merge | arkgate-check as a required CI status | Always (ArkGate) |
| ArkRules | Optional policies inside a layer | When you ask |
| ArkRun | Optional experimental runtime (@arkgate/runtime) | Off unless you turn it on |
Layers (who may import whom) always run. ArkRules and ArkRun change no inter-layer
verdict when absent. Label leftovers [Layer] vs [ArkRules].
Details: configuration · use.
Not an API Gateway, a folder linter, a web framework, ORM, or job runner.
ArkRun is in-memory — local and tests, not Postgres.
Name note: npm package arkgate — not affiliated with the separate Archgate CLI project.
When not to adopt
ArkGate is overkill for small trees with no AI agents and no multi-layer boundaries, for
single-developer hobby CRUDs under no integration pressure, and for teams that will not maintain
ark.config.json or a required CI status running arkgate-check --strict-merge. Without that
status the rules file is just documentation — stay with a boundary linter alone (see
Why not only ESLint / Nx / cruiser?).
Anyone path: docs/use.md — When not to adopt. Limits of a green
check: 4.3.0 — What ArkGate is / isn't.
Status lights (not settings)
[ Setup ] ──▶ [ In progress ] ──▶ [ Ready ]
│
└── Ready · needs a refactor
| Setup | Thin / new tree | Finish start → status |
| In progress | Not fully protected | Status action #1 |
| Ready | Honest import edges, and no new UI business-rule files vs merge-base | Keep write path + CI |
| Ready · needs a refactor | Edges clean; leftover design work remains | One small change — not “done” |
Details: docs/use.md.
Host enforcement support
| Claude Code | Hard block for listed ops (PreToolUse Write / Edit / MultiEdit) when installed + trusted | Advisory; the agent must call it | Required GitHub status context running arkgate-check --strict-merge (alias ark-check) | Emitted on hook deny; host must re-inject (hard path when installed + trusted) |
| Grok Build | Hard block for listed ops (PreToolUse write / search_replace (plus aliases)) when installed + trusted | Advisory; the agent must call it | Required GitHub status context running arkgate-check --strict-merge (alias ark-check) | Emitted on hook deny; host must re-inject (hard path when installed + trusted) |
| Google Antigravity | Hard block for listed ops (PreToolUse write_to_file / replace_file_content / multi_replace_file_content) when installed + trusted | Advisory; the agent must call it | Required GitHub status context running arkgate-check --strict-merge (alias ark-check) | Emitted on hook deny; host must re-inject (hard path when installed + trusted) |
| Cursor | Hard block for listed ops (preToolUse Write / StrReplace) when installed + trusted | Advisory; the agent must call it | Required GitHub status context running arkgate-check --strict-merge (alias ark-check) | Envelope may emit (--hook-repair); reinjection not guaranteed |
| OpenAI Codex | Hard block for listed ops (PreToolUse apply_patch in Codex CLI and local ChatGPT Desktop/App Server) when installed + trusted | Advisory; the agent must call it | Required GitHub status context running arkgate-check --strict-merge (alias ark-check) | Envelope may emit (--hook-repair); reinjection not guaranteed |
| OpenCode | Advisory / best-effort at write (MCP + optional plugin; not a hard boundary) | Advisory; the agent must call it | Required GitHub status context running arkgate-check --strict-merge (alias ark-check) | No hard-boundary payload |
Read the CI column: for every host, the repository-wide hard guarantee is a required
GitHub status context that runs the CLI — not “CI file present,” and not the CLI binary name alone.
Codex hard write covers only a complete local apply_patch; Cursor covers only listed
preToolUse ops. In both cases the project hook must be installed + trusted, while shell/direct
filesystem writes, hosted or specialized opt-out paths, and human edits still rely on CI.
This table describes the supported profile after its files are installed and the host loads/trusts them. A hard local boundary covers only the listed hook operations; alternate tools, direct filesystem writes, and human edits still rely on CI. MCP validation is advisory because the agent must call it. The CI check blocks a merge only when the repository makes that status required. Repair envelopes may be emitted without reinjection being guaranteed; silent auto-apply never happens. Run arkgate-check --doctor (or ark-check --doctor) for the evidence actually detected in the current repository.
Why required CI is the hard line
The split above is a deliberate trade-off, not a gap. ArkGate validates at the earliest boundary
each host offers and enforces at the earliest boundary a repository can make non-bypassable: the
required merge status. Hard hooks (Claude Code, Grok Build, Google Antigravity, Cursor, and
Codex’s complete local apply_patch) deny their listed write operations at write time; advisory
surfaces (MCP, rules, OpenCode plugins) warn the agent while it works. But any local boundary can
be routed around — another tool, a hosted/specialized path, a direct filesystem write, or a human
edit — so the only guarantee ArkGate claims for every path is the
arkgate-check --strict-merge check, and only when the repository makes that status required.
Local checks optimize feedback speed; required CI owns correctness.
A useful consequence: the rules file doubles as a pressure sensor. Recurring violations or baseline
exceptions concentrated on one layer edge are evidence that the current design stopped fitting the
code — a reason to reshape the rules deliberately (start with /ark-explore), never to weaken
the check.
Setup per host: docs/ai-gates.md · Develop path: docs/develop.md
For authoritative MCP contract evidence, call ark_identity with the exact project root, then
call ark_manifest with that root plus the returned project id. A contained descendant requires
the matching id. The legacy ark://manifest resource remains compatibility-only and always
unverified/non-authoritative because standard resources/read cannot portably carry that
expectation.
Why not only ESLint / Nx / cruiser?
| CI import rules | ✅ | ✅ |
| Hard-block AI writes on supported hosts | ✅ | ❌ |
Project-bound rules agents can read (ark_manifest) | ✅ | ❌ |
| Placement + preflight for multi-file changes | ✅ | ❌ |
| Honest governed % + dual plan (edges vs shape) | ✅ | ❌ |
| Opt-in intra-layer ArkRules (structure + invariants) | ✅ | ❌ |
| Incomplete analysis cannot look green | ✅ | varies |
Common commands
npx arkgate start --apply
npx arkgate status --json
npx arkgate-check --doctor
npx arkgate-check --plan
npx arkgate-check --coverage
npx arkgate-check --strict-merge
npx arkgate-check --install-agent-gates --tools claude,cursor,codex,grok
More: docs/develop.md · skills install: docs/agent-guide.md · enthusiast track: docs/enthusiast/
Optional ArkRun
Gates need no app runtime. Skip this unless you want an optional runtime
for decoupling.
ArkRun (@arkgate/runtime, npm tag experimental) is that runtime. Each
createStrictArkKernel() call is a new instance — no process singleton. Data
lives in memory and dies on restart. Fine for local. Not Postgres, not an
outbox, not Temporal.
The arkgate tarball does not bundle it.
Durability stance
Default stores (InMemoryEventBuffer, InMemoryAuditStore, InMemoryReadModelStore,
InMemoryWorkflowStore) are reference in-memory only. Fine for tests. They
do not survive restarts and are not production durability. Wire real store
interfaces for production. Details: docs/production-hardening.md.
Documentation
Contribute to this library
git clone https://github.com/pedroknigge/arkgate
cd arkgate && npm ci && npm run build
npm test && npm run check:architecture
Full guide: CONTRIBUTING.md · queue: ROADMAP.md
Website: arkgate.online · npm: arkgate
MCP: io.github.pedroknigge/arkgate
Node ≥ 18 · MIT
Ark doesn’t invent your product. It rejects the illegal write — and tells you when it isn’t really enforcing anything yet.