Appearance
The Declarative Contract
Everything Nanokit does starts from a single file: nanokit.yml. It is not a template or a script generator — it is the complete description of desired state, and the only thing an agent (or a human) needs to write to change infrastructure.
yaml
name: nanokit
activeEnv: local
env:
SMTP_HOST: '${SMTP_HOST:-service://mail}'
databases:
nk_db_postgres:
engine: postgres
mode: local
rootPassword: '${DB_PASSWORD_POSTGRES}'
branching:
enabled: true
services:
api-gateway:
runtime: node
path: ./apps/api-gateway
start: npm run start
expose: 4000
updateStrategy: recreate
docs:
runtime: static
path: ./dist/apps/docs
expose: 80Three things in that example matter to an agent:
- References, not values.
${DB_PASSWORD_POSTGRES}andservice://mailresolve at apply time — from the environment or the secrets vault. Secrets never enter the file, so an agent can write config without ever handling credentials. - Declarations, not steps. There is no "restart after env change" instruction. The reconciler derives what must happen from the difference between this file and reality.
- One file, many targets.
environmentsoverride slices of this document per context;deploy targetsdecide where a context lands. Same contract, laptop or cloud.
From file to outcome
When the config changes (or nkapp up / nkapp plan runs), Nanokit executes a deterministic loop:
- Observe — query the active provider for current state.
- Diff — compare desired vs. current, gated by drift hashes so unchanged resources are provably skipped.
- Plan — produce a typed plan of
CREATE/UPDATE/DELETE/NO_OPactions, ordered by the dependency graph. - Execute proportionally — touch only what the diff justifies; health checks gate each step.
- Report — expose resulting state (see Machine-Readable State).
The properties an agent can rely on:
| Property | Guarantee |
|---|---|
| Determinism | Same config + same current state ⇒ same plan, every time |
| Idempotence | Re-applying is a no-op when drift hashes match |
| Proportionality | A one-service change produces a one-service deploy |
| Reversibility | nkapp deploy --rollback restores the previous reconciler state |
| Constrained scope | Only what the schema expresses is executable |
What this means in practice
An agent that needs "a staging environment with Redis" does not run twelve commands. It edits the contract — add the database block, maybe an environment override — and lets reconcile do the rest. If the edit was wrong, the plan shows it before execution; if the apply fails midway, rollback returns to the last good state rather than leaving a half-built stack.
The full schema (services, databases, runtimes, networks, cron, volumes, infra providers) is documented under Configuration.
Direction
Explicit agent-facing primitives on top of this contract — such as create_environment operations exposed through an MCP server or tool API — are planned but not shipped. Today, editing nanokit.yml and invoking the CLI is the integration surface.