Runbook
Kronika failed — what does the sentence mean, and what do you check? Every
failure is one line on stderr, kronika: <message>, exit status 1; sync
additionally reports per-document failed outcomes and exits 1 when any
document failed. Every sentence below exists verbatim in src/ and the
marked ones were captured by running the CLI.
Flags and commands
| Sentence | Meaning / fix |
|---|---|
Unknown command: <word> † |
first argument is not init, gui, check, write, sources, sync, onboarding, or help |
Unknown option: <flag> † |
flag not in cli; one parser serves all commands |
<flag> requires a value † |
value-taking flag at end of argv or followed by nothing |
<flag> must be a positive integer † |
numeric flags (--max-*, --port) reject zero, negatives, and non-integers |
--port must be between 1 and 65535 |
the graphical importer port exceeds TCP's maximum; omit --port for an available operating-system-assigned port |
check requires --base <ref> † |
check has no default base; pass the ref to audit from |
Environment
| Sentence | Meaning / fix |
|---|---|
BRAMA_URL is required: the address of the Brama gateway † |
check/write/sync need an endpoint; init, gui, sources, onboarding, and help do not |
BRAMA_API_KEY_ROLE is required: ROLE#FIELD naming the role the item holding the Brama bearer plays, and its field |
Declare the credential role reference; the bearer is resolved from the configured credential source, not supplied as an environment secret. |
Brama agent ID and HMAC secret must be supplied together † |
Supply WISENT_APP_AGENT_ID and WISENT_APP_AGENT_AUTH_SECRET_ROLE together, or omit both for unsigned requests. |
Brama URL is required, Brama API key is required |
library-only: BramaClient constructed with empty options (the CLI checks the environment first) |
See configuration for what each variable does.
Graphical importer
Session and request refusals are returned in the workspace; startup failures
use the CLI's kronika: <message> stderr boundary.
| Sentence | Meaning / fix |
|---|---|
request host does not match this Kronika GUI session | the request used an alias, rebound host, or stale URL; open the exact loopback URL, with its port, printed by this process |
Kronika GUI session token is missing or invalid | the URL fragment is absent or belongs to another process; reopen the exact current session URL |
request origin does not match this Kronika GUI session | a mutation did not originate from the exact local workspace; it is refused as cross-origin |
request exceeds 65536 bytes | the JSON selection is over the pre-parse request cap; narrow the document/source lists or instruction |
request content type must be application/json / request body is not valid JSON | a non-workspace or damaged request reached the API; reload the current printed URL |
documents must be an array of paths / sources must be an array of paths, … entries must be strings, … entries must not be empty | the selection is not a list of non-empty path strings; reload the current printed URL and select again |
manifestPath must be a string / manifestPath must not be empty | the destination is missing or blank; use a repository-relative manifest path such as kronika.sync.json |
Project adoption refusals
These reasons come from the shared initializeDocumentationWorkspace
boundary and therefore mean the same thing in CLI and GUI results:
| Reason | Meaning / fix |
|---|---|
repository does not exist or is not a directory | --repo is missing or not a directory; start again with the existing project root |
manifest is outside the repository | the manifest destination escapes the fixed repository; choose an in-repository path |
manifest parent must be a real directory inside the repository: <path> | a destination parent is a symlink or non-directory; choose a real directory under the project |
manifest must be a regular file, not a symbolic link or directory: <path> | the retained destination is not a writable regular-file identity; replace the filesystem entry deliberately before importing |
no existing README.md or docs directory was found; pass --docs <path> | default discovery found no adoption candidate; select existing Markdown explicitly in CLI or the GUI documents field |
Documentation source is outside the repository: <path> / Evidence source is outside the repository: <path> | a selection escapes the project; use a path inside the fixed repository |
Documentation source does not exist: <path> / Evidence source does not exist: <path> | a selected identity is missing; correct the repository-relative path |
Documentation source cannot be a symbolic link: <path> / Evidence source cannot be a symbolic link: <path> | the selected top-level path is a symlink; select its real in-repository target |
Documentation source cannot contain a symbolic link: <path> | a selected directory contains a symlink; choose a narrower real directory or remove the link |
Documentation source is not Markdown: <path> | an explicitly selected file does not end in .md; select existing Markdown or a directory containing it |
documentation selection contains no Markdown documents | the selected directories contain no .md files; choose a real documentation location |
an existing sync manifest declares different documents or evidence; preserve it or pass --replace | the retained manifest is a meaningful conflict and remains unchanged; review its GUI readback or file, then explicitly enable replacement if it should be superseded |
Selection refusals
From src/docs/sources.ts and src/docs/writer.ts; all before any network call:
| Sentence | Meaning / fix |
|---|---|
Source is outside the repository: <path> † |
explicit --source escapes --repo; selection is confined |
Source does not exist: <path> † |
explicit source missing |
Symbolic-link sources are not allowed: <path> † |
symlinks are never followed, even named explicitly |
Repository is not a directory: <path> † |
--repo points at a file |
Output is outside the repository: <path> † |
--output resolves outside --repo; refused by selector and writer both |
No safe UTF-8 source files were selected † |
write with an empty collection — everything was excluded, skipped, or empty; run kronika sources to see why |
Source byte limits must be positive |
library-only: collectSources called with non-positive budgets |
Skip reasons (in skipped, not errors): generated, dependency, recording,
or private deployment directory · credential or generated lock file ·
private key or certificate material · larger than <n> bytes ·
total source limit <n> bytes reached · binary content ·
not valid UTF-8 text. See sources.
Git refusals
| Sentence | Meaning / fix |
|---|---|
Git commit cannot be resolved: <ref> † |
--base/--head is not a commit in this repository; check the ref and --repo |
Git diff cannot be read for <base>...<head> |
diff itself failed (shallow clone missing the merge base, corrupt repo) |
Git diff is <n> bytes, above --max-diff-bytes <m>; narrow or split the change rather than auditing a truncated diff † |
deliberate refusal — a truncated diff would audit a change that did not happen. Audit smaller ranges, restrict sync sources, or raise the budget knowingly |
Diff byte limit must be a positive integer |
library-only: checkDocumentation called with a non-positive maxDiffBytes (the CLI validates --max-diff-bytes first) |
Transport and Brama answers
From src/docs/model/brama.ts:
| Sentence | Meaning / fix |
|---|---|
fetch failed † |
Node's own sentence for a network-level failure (refused connection, DNS); Brama never answered. Check BRAMA_URL and reachability |
Brama returned HTTP <status>: <detail> † |
Brama answered an error; <detail> is the server's own error/error.message or the first 1000 bytes of the body — empty response when there was none. 401/403 are credential scope; 5xx is Brama-side |
Brama returned no documentation content † |
2xx with an empty or unrecognizable completion body |
Model output refusals
The model's answer is validated, never trusted. From src/docs/writer.ts
(write/rewrite):
Brama returned empty documentation— nothing remained after removing one surrounding Markdown code fence and surrounding whitespaceBrama returned invalid NUL content
From src/docs/checker.ts (audit verdicts):
Kronika returned invalid documentation-check JSON† — the answer was not parseable JSON (one surrounding code fence is tolerated)Kronika documentation check is not an objectKronika documentation check has no boolean passed fieldKronika documentation check has no summaryKronika documentation check has no findings arrayKronika documentation check contradicts its blocker findings† —passeddisagreed with the presence of blockersKronika finding <i> is not an object/has invalid severity/has invalid code/has invalid document/has invalid sourcePaths/has no message/has invalid requiredChange
A retry is reasonable — these are usually one bad completion. Persistent
verdict failures on the same change mean the model selector is too weak or
the diff too large to reason over; try a stronger --model.
Sync: fatal sentences
Manifest and state validation, fatal before any document is visited (all †, captured):
Sync manifest is missing: <path>. Declare the maintained documents first.Sync manifest is not valid JSON: <path>Unsupported sync manifest schemaVersion in <path>Sync manifest declares no documents: <path>Sync manifest entry without an output path in <path>Sync manifest entry <output> declares no sourcesSync state is not valid JSON: <path>. Fix or delete it to re-baseline.Unsupported sync state schemaVersion in <path>
Sync: per-document failed outcomes
Not thrown — reported per document, exit 1, baseline
deliberately not advanced, next tick retries the same range:
| Detail | Meaning / fix |
|---|---|
the recorded baseline <sha12> cannot be diffed against HEAD: <git error>. Delete this entry from the state file to re-baseline. † |
history rewrite or corrupt entry; the remedy is in the sentence |
audit did not complete: <message> † |
the check failed — <message> is any transport/Git/verdict sentence above (captured offline: audit did not complete: fetch failed) |
audit found blockers but the rewrite did not complete: <message> |
the check worked, the write failed; findings are in the outcome, nothing was written |
kronika-site (site pipeline)
The separate pipeline reports one JSON object (or, with --text, one
path: value line per field) and exits: 2 usage
(kronika-site <productRepo> --sources <file> (--standard <writing-standard.md> | --plan <file>) [--out <dir>] [--model <selector>] [--text], and authoring a plan needs --standard, the writing standard its pages follow, or --plan to load one already written),
69 model infrastructure down (brama endpoint unreachable: <url>
(<detail>) — a network failure, a response that could not be read, or a
gateway-unavailable status, 502, 503 or 504, with its body),
1 any failing stage, 0 all green. An answering endpoint with another bad
status is brama at <url> answered HTTP <status>: <body>; an answer
without the one required call is brama at <url> answered HTTP <status> without
calling <answer>; body: <body> or brama at <url> did not answer by exactly
one call of <answer>; body: <body>. See
site-pipeline.
† captured by running the built CLI against a toy repository; the remainder
quoted from src/.