Kronika documentation

Quick start

How do you go from a repository with existing documentation to a reconciled workspace? This page is the one happy path: build the CLI, adopt the existing Markdown without generating it, inspect the evidence boundary, configure Brama, audit one change, preview one document, and turn on the sync loop. Everything else — the full flag surface, the selection rules, and the loop's exact state machine — lives in cli, sources, and sync.

Build the CLI

Prerequisites: Git, Node.js 22 or newer, npm.

git clone https://github.com/wisent-ai/kronika.git
cd kronika
npm install
npm run build
npm link

npm run build compiles TypeScript into dist/; the kronika binary is dist/src/cli.js. npm link puts kronika on your PATH; without it, run node dist/src/cli.js directly. The package has no runtime dependencies.

Adopt the existing documentation

kronika init --repo /path/to/project

Without explicit --docs, init selects an existing root README.md and Markdown beneath docs/. It validates the whole selection and atomically writes only kronika.sync.json. It does not generate, copy, or rewrite a document, execute repository commands, or call Brama. Repeat --docs and --source to declare exact document and evidence paths. An identical manifest is unchanged; a different retained manifest is reported as a conflict and preserved unless --replace is explicit. See kronika init.

Graphical alternative

kronika gui --repo /path/to/project

Open the exact session URL printed by the foreground command. Select repository-relative Markdown and evidence paths, review the destination and conflict policy, then import. The GUI invokes the same adoption function as init and reads the persisted manifest back; it does not open a browser itself, call Brama, generate documentation, or run repository commands. See the graphical importer.

Inspect the evidence boundary

kronika sources --repo /path/to/project

This makes no model request and changes no file — it needs no Brama configuration at all. It prints JSON: the selected files with byte counts, the total, and every skipped file with its reason. Captured against a toy repository (paths and counts will differ):

{
  "repo": "/private/tmp/kronika-docs.OnmsmX/toy",
  "output": "README.md",
  "totalBytes": 442,
  "sources": [
    { "path": "README.md", "bytes": 87 },
    { "path": "docs/usage.md", "bytes": 80 },
    { "path": "src/greet.js", "bytes": 93 },
    { "path": "kronika.sync.json", "bytes": 182 }
  ],
  "skipped": [
    { "path": "credentials.json", "reason": "credential or generated lock file" }
  ]
}

Add --source <path> (repeatable) to select explicit files or directories instead of automatic discovery. Review this boundary before configuring Brama: it is exactly what the model will see.

Configure Brama

export BRAMA_URL=<your-brama-origin>
export BRAMA_API_KEY_ROLE='<bearer-role>#<field>'
# Optional request signing; set both or neither:
export WISENT_APP_AGENT_ID=<agent-id>
export WISENT_APP_AGENT_AUTH_SECRET_ROLE='<signing-role>#<field>'
export KRONIKA_MODEL=any

BRAMA_URL and BRAMA_API_KEY_ROLE are required for model commands. These role references are resolved through stado credentials get --role; secrets themselves do not belong in the environment. The signing identity and secret reference must be supplied together. Without Stado, explicitly select an owner-only KRONIKA_CREDENTIALS_FILE as described in configuration. KRONIKA_MODEL selects the route; unset, it is any.

Audit one change

kronika check --repo /path/to/project --base origin/main --json

check resolves --base and --head (default HEAD) to commit SHAs, sends the bounded Git diff plus current sources to Brama, and prints a structured verdict. Exit 0 means the documentation already covers the change; exit 1 means at least one blocker finding names a concrete defect — captured blocked and passing runs are in walkthrough-check.

Preview one document

kronika write \
  --repo /path/to/project \
  --output docs/architecture.md \
  --source README.md --source src \
  --instruction 'Document components, request flow, invariants, and failure modes.'

Without --apply, write prints the generated Markdown to stdout and changes nothing. Add --apply only after reviewing the preview: it atomically replaces the output file, which must stay inside the repository.

Turn on the sync loop

The earlier kronika init created kronika.sync.json at the repository root. Review the imported declarations before the first sync; its established shape is:

{
  "schemaVersion": 1,
  "documents": [
    {
      "output": "docs/architecture.md",
      "sources": ["src", "README.md"],
      "instruction": "Keep the existing section order."
    }
  ]
}

Then run:

kronika sync --repo /path/to/project --commit --push

The first run for each document records the current commit as its baseline and generates nothing. The output has this shape, with the repository's commit in place of <commit>:

$ kronika sync --commit
Kronika sync at <commit>
  baseline        docs/usage.md — first sync records <commit> as the baseline; nothing is generated on a first run
  committed

Every later run audits only documents whose declared sources changed, rewrites only documents whose audit found blockers, and records the reconciled commit in kronika.sync-state.json. --dry-run reports without writing anything. Exit 1 means at least one document failed to reconcile. The full state machine is the sync loop; every action, captured tick by tick, is walkthrough-sync-cycle.