AGPL-3.0-or-later · forever.

start · project boundary

Give the SDK a place to stand.

Organize the workflow, binary resolution, generated receipts and application entrypoint before the first production run.

A small boundary pays for itself: workflows stay reviewable, the binary is resolved explicitly, receipts have a predictable home and application code never contains a second workflow language.

Put nika.yaml at the project root.

The root file owns the chosen project profile. The workflows directory owns intent. The SDK receives a workflow path and a cwd so the engine discovers that project root the same way git discovers .git.

project/
├── nika.yaml                  # project profile + optional armed beats
├── workflows/
│   ├── daily-brief.nika.yaml  # intent
│   └── release.nika.yaml
├── src/
│   ├── nika.ts                # LocalNika construction
│   └── release.ts             # product code
├── .nika/
│   ├── traces/                # run journals
│   └── arm/                   # firing ledgers + watermarks
├── package.json
└── .gitignore

Let the engine lay the starter.

The project file is optional, but any project that arms work or governs spend, retention or provenance should make it explicit. The scripted founding door never overwrites an existing file without --force.

nika init --project-file --recipe starter
nika arm

Choose how the binary is found.

The explicit constructor option wins, then NIKA_BIN, then PATH. cwd is equally important: it anchors relative workflow paths, project-file discovery and .nika state.

const nika = new LocalNika({
  bin: process.env.APP_NIKA_BIN,
  cwd: new URL('..', import.meta.url).pathname,
})

Keep generated state out of source control.

Traces can contain run metadata and outputs. Arm ledgers record claims, skips and receipts. Persist them deliberately on a server, but do not commit them as source.

.nika/traces/
.nika/arm/
.env

Fail startup with a useful diagnosis.

Probe the binary once at service startup. A missing executable is an environment error; a dirty workflow remains a typed check report later.

try {
  console.info('engine', await nika.version())
} catch (error) {
  console.error('Nika is unavailable', error)
  process.exit(3)
}