Chronis
Event-sourced task CLI powered by AllSource, the embedded event database. Every action is an immutable event — state is derived from projections over the event stream.
Binary: cn | Crate: chronis | Storage: .chronis/ | Author: Decebal Dobrica
Install
Quick Start
Commands
Task Lifecycle
| Command | Alias | Description |
|---|---|---|
cn init |
Initialize a .chronis/ workspace in the current directory |
|
cn task create <title> |
Create a task (see flags below) | |
cn list [--status=open] |
cn ls |
List tasks, optionally filtered by status |
cn ready |
cn r |
Show tasks that are open and unblocked |
cn show <id> |
cn s |
Task details, children, and event timeline |
cn claim <id> |
cn c |
Claim a task (uses CN_AGENT_ID env var, defaults to "human") |
cn done <id> [--reason=...] |
cn d |
Mark a task as done |
cn approve <id> |
Approve a task | |
cn archive <ids...> |
Archive tasks (hide from default listings) | |
cn archive --all-done |
Archive all completed tasks | |
cn archive --done-before=30 |
Archive tasks done 30+ days ago | |
cn unarchive <ids...> |
Restore archived tasks |
Task Creation Flags
--type=epic \ # Type: task (default), epic, bug, feature
--parent=<id> \ # Parent task ID (for hierarchy under epics)
--blocked-by=<id1>,<id2> \ #
Bulk Actions (Cascade)
Cascade operations apply to a task and all its children — useful for closing out an entire epic:
Cascade walks the parent-child tree depth-first, processing children before the parent. Tasks already in the target state are skipped.
Archiving
Archive tasks to declutter your default listings. Archived tasks are hidden from cn list and cn ready but preserved in the event stream — nothing is deleted.
Dependencies
Git Sync
Sync chronis state across machines via git. Events are exported to an append-only JSONL file that git can merge naturally.
How it works:
git pull --rebase— fetch remote changes- Import new events from
.chronis/sync/events.jsonlinto local Core - Append new local events to the JSONL file
git commit+git push
Deduplication is handled via UUID tracking — each event is written once by its creating machine and never duplicated. Two local-only ID sets (.remote_ids, .local_ids) prevent re-import and re-export.
Multi-machine workflow:
# Machine A # Machine B
Visualization
Migration
Workflow
cn ready --> cn claim <id> --> (do work) --> cn done <id> --> cn archive --all-done --> cn sync --git
For agent orchestration, set CN_AGENT_ID to identify which agent claims tasks:
Architecture
Chronis wraps AllSource's embedded library. Every mutation (create, claim, done, approve, dependency change) emits an event into the WAL. A TaskProjection folds these events into queryable task state stored in a DashMap (~12us reads).
cn CLI (clap)
|
v
TaskRepository trait
|
v
EmbeddedCore (allsource-core)
|
+--> WAL (CRC32, fsync) --> Parquet (Snappy)
+--> DashMap (in-memory reads)
+--> TaskProjection (event folding)
Data lives in .chronis/ at the project root:
.chronis/
wal/ # Write-ahead log segments
storage/ # Columnar event storage (Parquet)
sync/ # Git sync exchange (events.jsonl)
config.toml # Workspace config
.gitignore # Excludes binary data, tracks sync files
Event Types
All state is derived from these events:
| Event | Emitted by |
|---|---|
task.created |
cn task create |
task.updated |
(future: cn task update) |
task.dependency.added |
cn dep add or --blocked-by flag |
task.dependency.removed |
cn dep remove |
workflow.claimed |
cn claim (first-write-wins) |
workflow.step.completed |
cn done |
workflow.approval.granted |
cn approve |
task.archived |
cn archive |
task.unarchived |
cn unarchive |
Quality Gates