Skip to main content

crewship journal

Read the Crew Journal — the canonical append-only event stream for every observable action in the platform. Filter by crew, agent, mission, entry type, severity, actor, priority, trace, or time window.
The top-level command is the list view. --follow opens an SSE connection to /api/v1/journal/stream and prints entries as they arrive (Ctrl-C to exit). The CLI auto-reconnects on transient failure with bounded exponential backoff (1 s → 30 s) and threads Last-Event-ID so a brief disconnect resumes without dropping or duplicating entries. For pretty in-browser viewing, the web UI /journal page is also available.

Flags

Global output flags apply: --format text|json|yaml|ndjson (default text). Enum values for --severity, --actor-type, and --priority are validated client-side before the request goes out, so a typo fails fast with a list of allowed values. --type and --exclude-type are not validated against a list — entry types are an open set that grows with the features emitting them, and an allowlist here would reject a valid filter every time the server got ahead of the CLI. The one value they do refuse is a wildcard:
Name the types instead. The catalogue below is the list. The same refusal applies to crewship journal count and to crewship watch — a count prints a bare 0 and a live tail prints nothing at all, and neither says the question could not be asked.
--run-id or --trace-id? A run id reaches the journal by three doors and which one depends on the engine: agent runs stamp trace_id, routine runs stamp actor_id and payload.run_id. --trace-id matches only the first, so on a routine run it returns the one entry that happens to carry a trace and misses the rest of the chain. --run-id matches all three. Measured on a live routine run: 1 entry versus 19.

Examples

For free-text “did we discuss this before?” lookups across the journal, prefer crewship recall <query> — same backing endpoint, snippet-card rendering optimised for question-answering.

crewship journal get

Fetch a single entry by ID. Output respects --format (text, json, yaml, ndjson); the text format prints the same single-line summary the list view uses, then indents the entry’s payload and refs underneath so you can see the full structured detail at a glance.
The endpoint is workspace-scoped — IDs from another workspace come back as 404 with the same shape as “not found” (no cross-tenant existence leak).

crewship journal count

Print the total number of entries that match a filter set. Identical filter flags to the list view (minus --lines / --follow); --cursor and --limit are silently ignored — count is always over the full result set.
Default text output is the bare integer for shell scripting:

crewship journal priority

Annotate one entry with a priority marker (normal, high, pin, permanent). Requires OWNER or ADMIN on the workspace. Marker affects compaction and recall — see the Crew Journal guide for the semantics.
The --mark value is validated client-side before the request goes out. Each invocation also writes a memory.priority_changed audit entry to the journal carrying the previous and new priority plus the supplied reason — so the curation history is itself queryable.

crewship journal verify

Verify the workspace’s audit hash-chain is intact — the tamper-evidence check for the append-only journal. Every entry commits to its own content plus the hash of the preceding entry, so any after-the-fact edit, in-place reorder, or deletion of a middle row breaks the chain and is reported here. Requires OWNER or ADMIN.
Backed by GET /api/v1/admin/journal/verify (workspace-scoped, no arguments). On a healthy journal it prints Journal chain OK — N entries verified, no tampering detected. and exits 0. On a broken chain it prints the first bad seq/entry and the reason, and exits non-zero — so you can gate a cron job or CI check on it:
--format json emits the raw result (ok, count, broken_seq, broken_id, reason, breaks, repairable) for machine consumers. See the Audit Log page for the guarantee and what it does (and does not) cover. Verification also reconciles the one committed field that is meant to change after write — entry priority. Setting a pin or permanent marker is an authorised action, so the chain commits to the immutable emit-time value while the live column is checked against its append-only change ledger. A priority mismatch at seq N reason therefore means the column was flipped without a recorded operator edit, i.e. directly in the database. Pinning an entry through the API or UI never breaks verification.
Before this reconciliation existed, priority was hashed directly — so the first time anyone pinned an entry, journal verify started reporting that workspace as tampered forever. If you have been ignoring a persistent break, re-run after upgrading: a false positive from a legitimate pin is now impossible.

Entries with an unresolved priority

Some rows come back in a separate, non-green block:
These are rows whose content the keyed hash proves authentic, but whose live priority the record cannot account for. The EMITTED column is what the entry was actually written with — recovered by finding the priority that reproduces the stored HMAC, which requires no guessing and cannot be faked without the key. There are two ways to arrive here and the row cannot tell you which:
  • the schema-v166 upgrade backfilled priority_at_emit on an entry that had already been pinned, so a legitimate old pin now looks wrong; or
  • someone with database write access downgraded a permanent entry so compaction would delete it, writing both columns to keep them consistent.
Because the two are byte-identical, journal verify reports rather than resolves, and exits non-zero — the same as for a break. Compare the emitted value with what you expect the entry to have been marked, and treat a permanent → normal downgrade you cannot account for as an incident. Compaction will not delete these rows in the meantime.

crewship keeper history

Print the append-only decision history for one Keeper request — see crewship keeper history. crewship keeper requests shows what was decided; history shows how the request got there (that it was PENDING, who caused each transition, and the exit code of any command an ALLOW ran).

crewship journal lookup

Fetch the workspace reference table the web timeline uses to render journal cards with human-readable crew/agent/mission names. Useful for joining crewship journal --format json output against names in shell pipelines.
Backed by GET /api/v1/journal/lookup. The endpoint is workspace-scoped — no filter arguments. The response groups three reference lists: Text mode renders each section as a short table and caps each at 50 rows so the output stays scannable; pass --format json (or yaml) to get the full unbounded snapshot. To narrow the timeline to a single run rather than a reference table, use crewship journal --trace-id <run-id> on the list command — the two surfaces serve different jobs.

Sample output

Columns: timestamp, severity chip (color-coded — gray=info/default, cyan=notice, yellow=warn, red=error), entry type (bold), actor type, summary.

Entry type catalog

See the Crew Journal guide for the full list. Common filters:

Parsing --since / --until

Accepted formats:
  • Duration suffixes: 30m, 1h, 24h, 7d (the d suffix is handled locally; Go’s time.ParseDuration doesn’t support it).
  • RFC3339: 2026-04-17T00:00:00Z.
--until is supported on journal count (lower bound is --since, upper bound is --until); the list view doesn’t currently expose --until because the default ordering is “newest first” and pagination uses a cursor.

Notes

  • Output is scoped to the caller’s workspace automatically — there is no way to query another workspace from the CLI.
  • Pagination is keyset-based on the server; the list view doesn’t expose the cursor (it fetches --lines rows and stops). For paged programmatic access, prefer the JSON output of the /api/v1/journal endpoint.
  • For structured programmatic access prefer --format json.