Sillok
Sillok is a Rust CLI for meticulous agentic work chronicles. It records daily objectives, completed tasks, corrections, and retractions into a structured archive instead of a fragile append-only text log.
The name comes from Korean sillok, the court chronicles of Joseon. The design
goal is similar: keep precise records of what happened, when, under what
objective, and in what working context.
Status
Sillok is an early local-first CLI. The command interface is intended to be stable enough for agent harnesses. The live store is a private Turso/SQLite database and may gain new datashape versions over time.
Install
Build the binary in dev mode:
Install it onto your PATH:
Then use:
Storage
By default, Sillok stores one user-global Turso/SQLite database at:
$XDG_DATA_HOME/sillok/sillok.db
If XDG_DATA_HOME is unset, it falls back to:
~/.local/share/sillok/sillok.db
Override the store with either:
SILLOK_STORE=/path/to/sillok.db
The v2 store keeps append-only events plus indexed current projections in the database. Normal mutations insert a new event and update affected projection rows instead of loading and rewriting the whole chronicle.
Legacy v1 stores used a compressed private archive at sillok.slk.zst. Use
sillok migrate --store /path/to/sillok.slk.zst --target /path/to/sillok.db --yes
to create a v2 database. Migration always validates the legacy archive and
creates a timestamped backup before activating the target.
Git sync is archive-based, not database-based. The configured remote stores one
bitcode + zstd artifact, while every device keeps its own local SQLite/Turso
projection database. Sync config is stored beside the selected store at
<store>.sync.json.
Output
Quiet output is the default and is intended for agents. Successful write/action commands usually print nothing:
Read commands still return compact JSON data without the response envelope. Use
--json when an agent needs IDs or the full verbose response envelope:
Failures are compact JSON by default:
Use --json for verbose failure envelopes:
JSON records include stable RFC3339 created_at and updated_at fields.
Verbose success responses include ids, data, and warnings. Use --human
for interactive summaries with local-device timestamps rendered as readable
wall-clock time:
Functionality
Sillok supports:
- Local-first event logging into a SQLite/Turso projection store.
- Daily task notes with status, tags, purpose text, and parent links.
- Day objectives that can be created and completed with notes.
- Amendments and retractions that preserve event history.
- Day summaries, record history lookup, filtered queries, and task trees.
- Archive integrity validation.
- JSON export of current visible records.
- Legacy v1 archive migration into the v2 store.
- Explicit destructive truncation with timestamped backup.
- Git-backed sync of the authoritative event stream as one compressed artifact.
- Backfilled timestamps and timezone-controlled day attribution.
- Runtime work-context capture including cwd and Git metadata when available.
Command Reference
Global options:
Global option details:
--store: use a specific store path; defaults toSILLOK_STOREor XDG data storage.--human: print verbose readable summaries instead of quiet default output.--json: print the verbose JSON response envelope.--at: assign the event timestamp. Accepts RFC3339 or naiveYYYY-MM-DDTHH:MM:SS.--tz: timezone for local day attribution and naive--atparsing.SILLOK_ACTOR: optional actor label recorded on new events; defaults toagent.
Initialize the archive if absent:
Record a task or work note. Notes default to completed; use --status for
open, active, blocked, or completed:
note creates a task event. Without --parent, Sillok opens or reuses the day
record for the event timestamp and links the task under that day. With
--parent, the task is linked under an existing active record.
The status vocabulary is open, active, blocked, completed, and
retracted. Prefer sillok retract when hiding a record so the retraction
reason is preserved.
Manage day objectives:
Objectives are day-scoped records. Completing an objective changes its derived
status to completed; an optional completion note is stored on the record.
Amend current derived state:
amend records a new event and updates only the supplied fields in the current
projection. It requires at least one changed field.
Retract a task or objective from current views:
Retraction hides a task or objective from normal current views while preserving the underlying event history. Day records cannot be retracted.
Read records:
Read command behavior:
showreturns one current record plus every event that references it.dayreturns the selected day's tree, objectives, and visible non-day records. Omit--dateto use the current day in the selected timezone.queryreturns visible current records created in an inclusive time range. Filter by--context,--tag, or--status.treerenders the visible record tree rooted at--root, or at the selected day when--dateis supplied.
Validate and export:
doctor validates SQLite integrity and replays persisted events to confirm the
derived projection. export json returns visible current records; with
--from and --to, export is limited to records created in that inclusive
range.
Configure and run Git-backed event archive sync. Sync stores one
bitcode + zstd level 22 archive artifact in the configured Git remote; the
SQLite/Turso database remains local and is rebuilt from events when needed:
Sync command behavior:
sync remote set <URL>writes<store>.sync.json; defaults are branchmainand artifact pathsillok.slk.zst.sync remote showprints the configured URL, branch, artifact path, and sidecar path.sync pullreads the remote artifact, merges matching archives by event id, and rebuilds the local database when local state is missing, behind, or diverged.sync pushfetches the remote artifact, merges matching archives by event id, rebuilds local state if needed, then writes the merged artifact to the configured remote.sync runperforms bidirectional merge, validates the merged archive, rebuilds the local database with a backup if needed, then pushes.
Archives with the same archive_id are merged by event_id. Different
non-empty archive IDs fail with sync_archive_mismatch and do not replace local
or remote data. Git authentication is delegated to the user's existing git
setup.
Migrate a legacy v1 archive:
migrate --dry-run validates the source archive and reports the migration plan.
Writing a v2 target requires --yes. If --target is omitted, Sillok writes
sillok.db beside the legacy archive.
Reset the archive only when an operator explicitly asks for a full reset. This creates a timestamped backup first:
truncate is destructive and requires --yes. It backs up the current v2
database, removes it, then initializes a fresh archive.
Backfill with explicit timestamps and timezone attribution:
RFC3339 timestamps keep their explicit offset. Naive timestamps are interpreted
in the selected --tz, or in the system-local timezone when --tz is omitted.
Agent Integration
Add a short Sillok section to a repository AGENTS.md so coding agents record
objectives and completed work while they operate:
Use Sillok for substantive agentic work. Record objectives, completed tasks,
and corrections during the session instead of relying on chat history. Quiet
output is the default for agents; use `--json` only when IDs or the full
response envelope are needed, and `--human` only for summaries intended for a
person.
Never run `sillok truncate --yes` unless the user explicitly asks to reset the
whole archive.
```bash
sillok objective add "Ship the storage/indexing refactor"
sillok note "Split reducer from view indexing" --parent <objective_id> --tags rust,sillok
sillok amend <record_id> --status completed
sillok note "Fixed relink regression coverage" --parent <objective_id> --tags tests
sillok show <record_id>
sillok query --from 2026-05-13T00:00:00 --to 2026-05-13T23:59:59 --tag rust
sillok objective complete <objective_id> --note "Scoped work is complete"
sillok day --human
```
Use `--at` for backfilled work and `--tz` when day attribution matters:
```bash
sillok --tz America/Denver --at 2026-05-13T16:45:00 note "Backfilled release notes" --tags docs
```
Development
Run checks:
Project constraints:
- No
unwrap()orexpect()in project source or tests. - Keep modules under 300 lines where practical.
- Keep folder
mod.rsfiles to module declarations only. - Prefer explicit error handling and structured tracing.
- Do not treat the live database or legacy archive serialization as a public standard; use CLI export/migration commands for compatibility.
Design Notes
See docs/plan/sillok-cli-chronicle-design.md for the initial implementation plan and data model notes. See docs/architecture/be/turso-store.md, docs/architecture/be/view-indexing.md, and docs/architecture/be/git-sync.md for backend architecture notes.