Walkthrough: one full sync cycle
What does the loop actually print, write, and commit, tick by tick? This
page runs kronika sync through every action of its state machine against
a toy repository, with output pasted verbatim. The state machine itself is
sync; the nouns are manifest,
state, baseline,
drift.
How this was captured. The built CLI (npm run build, Node 22) ran
against a scratch repository under /tmp. Brama needs real credentials, so
no real model was called: ticks that need no model ran with placeholder
credentials pointing at a closed local port (BRAMA_URL=http://127.0.0.1:4899,
BRAMA_API_KEY=placeholder-not-a-secret) — the product's own offline path —
and the two model-dependent ticks ran against a local stub on
127.0.0.1:4891 answering /v1/chat/completions with scripted verdicts.
Framing, parsing, validation, atomic writes, and Git behavior are Kronika's
real code paths; only the verdict prose is canned, and it is marked below.
The toy repository
toy/
README.md # not declared as evidence
src/greet.js # prints "Hello, <name>!"
docs/usage.md # the maintained document
kronika.sync.json
{
"schemaVersion": 1,
"documents": [
{
"output": "docs/usage.md",
"sources": ["src"],
"instruction": "Document every CLI flag of src/greet.js."
}
]
}
Tick 1 — baseline (no model call)
$ kronika sync --commit
Kronika sync at 39825d883997
baseline docs/usage.md — first sync records 39825d883997 as the baseline; nothing is generated on a first run
committed
Exit 0. Offline credentials sufficed: a first run makes no model call.
kronika.sync-state.json now exists and --commit landed it as
kronika sync: advance documentation baselines:
{
"schemaVersion": 1,
"documents": {
"docs/usage.md": {
"headSha": "39825d883997f79f823e7d9be4a24d3f0ea77321",
"syncedAt": "2026-08-24T22:03:29.990Z",
"lastAction": "baseline"
}
}
}
Tick 2 — the sync commit moves HEAD
$ kronika sync
Kronika sync at 6d6a223d5b73
advanced docs/usage.md — no evidence path changed in the range; baseline advanced without a model call
Not current: the state recorded the HEAD the tick ran at, and tick 1's own
commit then moved HEAD by one. The range contains only the sync commit — no
declared path changed — so the baseline advances for free. current appears
when no commit lands between two ticks (tick 8 below).
Tick 3 — undeclared change (no model call)
Edit README.md, which the manifest does not declare, and commit:
$ kronika sync --commit
Kronika sync at 99202b121a20
advanced docs/usage.md — no evidence path changed in the range; baseline advanced without a model call
committed
Tick 4 — drift while Brama is unreachable
src/greet.js gains a --shout flag (a public-surface change) and is
committed. Now the audit is required, and the offline credentials show the
failure posture:
$ kronika sync
Kronika sync at 9d577cd6dad0
failed docs/usage.md — audit did not complete: fetch failed
Exit 1, and the state file still names the tick-3 baseline: a failed
outcome never advances, so the next tick retries the same range
(runbook).
Tick 5 — dry run of the blocked audit (stub verdict)
With the stub answering the audit — passed: false, one blocker
undocumented-flag naming the missing --shout documentation:
$ kronika sync --dry-run
Kronika sync at 9d577cd6dad0 (dry run)
rewritten docs/usage.md — dry run: audit found blockers and a rewrite would be applied. src/greet.js adds a --shout flag that docs/usage.md does not mention.
Exit 0; no file and no state written. --dry-run --json carries the full
findings array for review.
Tick 6 — rewrite, commit (stub verdict and stub rewrite)
$ kronika sync --commit
Kronika sync at 9d577cd6dad0
rewritten docs/usage.md — audit found blockers; the document was regenerated with the findings as the correction brief. src/greet.js adds a --shout flag that docs/usage.md does not mention.
committed
The rewrite was instructed with the blocker itself
(- [undocumented-flag] … Required change: Document the --shout flag …)
plus the standing manifest instruction — correct exactly the audited
defects, do not re-author unnamed sections. The commit stages exactly the
document and the state:
$ git show --stat --format=%s HEAD
kronika sync: reconcile docs/usage.md
docs/usage.md | 5 +++--
kronika.sync-state.json | 6 +++---
2 files changed, 6 insertions(+), 5 deletions(-)
docs/usage.md now documents --shout (stub prose), and the state entry
reads "lastAction": "rewritten" at the audited HEAD.
Tick 7 — a change the audit waves through
A comment-only edit to src/greet.js is drift (a declared path changed),
so one check runs; the stub verdict passes, and the pass IS the update:
$ kronika sync
Kronika sync at 1d5ccd2b41d0
checked-current docs/usage.md — audit passed: docs/usage.md already documents the changed greeting behavior; no public surface is missing.
No file changed; the baseline moved.
Tick 8 — current
Run again with nothing committed in between:
$ kronika sync
Kronika sync at 1d5ccd2b41d0
current docs/usage.md — already reconciled against HEAD
What the cycle demonstrates
| Tick | Action | Model calls | Exit |
|---|---|---|---|
| 1 | baseline |
0 | 0 |
| 2, 3 | advanced |
0 | 0 |
| 4 | failed (offline) |
attempted 1 | 1 |
| 5 | rewritten (dry run) |
1 check | 0 |
| 6 | rewritten + commit |
check + write | 0 |
| 7 | checked-current |
1 check | 0 |
| 8 | current |
0 | 0 |
Unattended operation is the same loop with --commit --push on a schedule
(examples/sync-forever.sh); the one-shot gate is
walkthrough-check.