Journals
Every resource writes its output and events to a journal, a SQLite file under the workspace’s cache folder at <namespace>/<kind>/<name>/journal. A process’s stdout and stderr land there line by line, with its starts, exits, signals and health transitions. The workspace’s own journal (journal.sqlite in its cache root) takes what the reconciler reports: reloads and diagnostics.
Retention
Section titled “Retention”A journal keeps its last max_lines lines: for a process spec.journal.max_lines, default 1000, which a changed spec applies without restarting the child. Lines are appended in batches and pruned back to the cap once the journal is a tenth over it (at least 50 lines), so a chatty process is not pruned per line.
spec: journal: max_lines: 200Queries
Section titled “Queries”The console’s filter box and the Journal RPC take the same query language. Every condition in a query must hold; several values of one field are alternatives.
| query | matches |
|---|---|
@stdout, @stderr |
lines of that stream |
level: warn |
lines at that level (trace, debug, info, warn, error) |
field: value |
a field whose value contains value; req.id: 42 descends into nested objects |
error |
a bare word: the message contains it |
@stderr level: error connection |
all three |
The same query applies to the lines already stored and to the ones appended while the stream is open, so a filtered view keeps following.
Streaming
Section titled “Streaming”The Journal RPC streams a window over the matching lines: absolute indexes from 0 in journal order, as records of first and length, with JournalEntries fetching lines by index. Pruning raises first and leaves the indexes above alone, so a client keeps what it rendered; a client that fell behind starts over under a new epoch. The daemon shares one journal instance per file between its writer and its readers, so a reader hears of every line and prune instead of polling.

