# AgentWorth — full text > You're burning tokens you can't see. Archie reads the receipts. Generated 2026-10-24 from https://agentworth.dev. Source: https://github.com/unfoundbox-crew/agentworth (Apache-2.0). ## Install npx -y agentworth@latest scan curl -fsSL https://agentworth.dev/install.sh | sh agentworth serve ## MCP tools - sessions_find: filter the index by adapter, model, repo, time or outcome - session_get: one session with its events, tokens and outcome rung - blame_find: which session, model and prompt produced a line of code - usage_summary: tokens and cost rolled up by day, week or month - pacing_window: throughput over a moving window - coverage_stats: which adapters are detected and what they yield - outcome_rate: verified-outcome rate by model, adapter or repo, with an n floor - session_handoff: what a session promised, decided and did not finish - carry_forward: what the previous session left for this one - forgotten_context: decisions compaction dropped, returned verbatim with receipts - suspect_commits: commits whose session had no exit-0 test or a demoted claim ## AgentWorth Reference _Generated by `archie docs --write` from v0.1.30 on 2026-10-20. Do not edit by hand -- regenerate with `archie docs --write` (see `apps/cli/src/commands/docs.rs`)._ Three sections, each read straight from the running code: every `clap` subcommand and flag, every route the local API server registers, and every MCP tool this binary exposes over stdio. ### CLI #### Global flags Accepted before the subcommand on every command below. | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--verbose, -v` | no | Enable verbose debug logging | false | - | | `--db-path` | no | Custom path for the local SQLite index database | - | - | | `--no-json` | no | Force text output even if persisted config defaults to JSON (see `archie config`) | false | - | | `--no-color` | no | Disable colour. NO_COLOR in the environment does the same thing | false | - | | `--plain` | no | No colour and ASCII-only glyphs, at identical column positions | false | - | #### `archie scan` Scan and index agent histories from the local system | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `PATHS` | no | Optional session paths or directories to scan; omit to also refresh global human-turn history | - | - | | `--force, -f` | no | Force rescanning and re-indexing of unchanged source files | false | - | | `--include-stubs` | no | Keep storing/pruning near-empty stub sessions instead of filtering them out | false | - | | `--json` | no | Output scan results as formatted JSON | false | - | #### `archie stats` Machine-wide summary statistics. `stats usage` rolls spend up by period; `stats outcomes` reports the verified-outcome rate | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Output summary statistics as formatted JSON | false | - | #### `archie stats usage` Deep usage, pacing, and token expenditure rollups | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--period, -p` | no | Rollup period: day, week, month, year, or all -- `all` is one row per group across all time, with no period column. Single-letter aliases d/w/m/y also work. Default day, or persisted `config period` | - | - | | `--pacing` | no | Show the rolling pacing window instead of the rollup. `archie window show` is the spelling that survives; this flag is kept for scripts written against `usage` | false | - | | `--hours` | no | Pacing window duration in hours | 5 | - | | `--alert-above` | no | Alert and highlight if window spend exceeds this threshold in USD | - | - | | `--limit, -l` | no | Maximum number of periods to keep (default 30 for day, 26 for week, 24 for month, unbounded for year) -- or, under `--period all`, the number of top groups by spend to keep (default 20, or persisted `config limit`). Counts periods, not rows: a day with two adapters is one period, not two | - | - | | `--by` | no | Group the rollup by adapter (default; most informative when nearly every session shares one adapter, e.g. Claude Code), model (usually the useful one), or repo | adapter | adapter, model, repo | | `--since` | no | Only include sessions started at or after this time: an absolute date (`2026-08-01` or RFC 3339), or a relative shorthand (`1d`, `7d`, `2w`, `3m`) | - | - | | `--json` | no | Output usage data as JSON | false | - | #### `archie stats outcomes` Verified-outcome rate by model, adapter, or repo: of the sessions that claimed done, what share left evidence a test, build, commit or CI run can be pointed at | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--by` | no | Group the rate by model (default), adapter, or repo | model | model, adapter, repo | | `--min-n` | no | Suppress groups with fewer than this many sessions (default 20) | - | - | | `--since` | no | Only sessions started at or after this time: an absolute date (`2026-08-01` or RFC 3339), or a relative shorthand (`1d`, `7d`, `2w`, `3m`) | - | - | | `--until` | no | Only sessions started before this time, same formats as `--since` | - | - | | `--include-stubs` | no | Include 1-event session stubs in the population | false | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie stats ladder` The evidence ladder, what a verified outcome costs, and the newest sessions that left evidence -- one screen, ending on the share of spend that sits below the evidence line | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--period, -p` | no | How far back the window reaches: day, week, month, year, or all. Single-letter aliases d/w/m/y also work. Default month (30 days), or persisted `config period`. Note this is a lookback, where `stats usage --period` is a rollup granularity | - | - | | `--by` | no | Group the cost-per-verified-outcome table by model (default), repo, adapter, or effort. Only Codex records an effort today, so `--by effort` counts what it can and names what it cannot | model | model, repo, adapter, effort | | `--repo` | no | Filter by repository or workspace substring (e.g. unfoundbox/agentworth) | - | - | | `--adapter, -a` | no | Filter by adapter name (e.g. claude_code, codex, gemini, opencode) | - | - | | `--model, -m` | no | Filter by model substring (e.g. sonnet, gpt-4o, gemini-2.5) | - | - | | `--min-n` | no | Blank a group's rate and cost below this many claimed sessions (default 20, the same floor `stats outcomes` applies) | - | - | | `--include-stubs` | no | Include 1-event session stubs in the population | false | - | | `--json` | no | Output all three blocks as formatted JSON | false | - | #### `archie session` Everything that acts on sessions: list them, read one, hand one over #### `archie session list` List indexed sessions with optional filtering | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--limit, -l` | no | Maximum number of sessions to display (default 20, or persisted `config limit`) | - | - | | `--adapter, -a` | no | Filter by adapter name (e.g. claude_code, codex, gemini, opencode) | - | - | | `--model, -m` | no | Filter by model substring (e.g. sonnet, gpt-4o, gemini-2.5) | - | - | | `--all-stubs` | no | Include 1-event session stubs in the listing | false | - | | `--kind` | no | Which kind of row to list: `conversation` (the default) or `fleet_snapshot` (a multi-agent workspace as of one moment, e.g. Herdr). `--adapter` on a snapshot adapter implies it | - | conversation, fleet_snapshot | | `--unproven` | no | Only sessions whose completion claims were never independently corroborated by tests or CI -- the blind spots | false | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie session show` Read one session in detail, with its timeline | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session to read, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--last` | no | The newest session for this directory's repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--json` | no | Output raw trace structure as formatted JSON | false | - | #### `archie session export` Export one session safely, in JSON or ATIF format | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session to export, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--last` | no | Export the newest session for this directory's repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--redact, -r` | no | Apply redaction to mask secrets, API keys, tokens, emails, and home paths | false | - | | `--format, -f` | no | Export format: json (default), atif, receipt, or svg | json | json, atif, receipt, terminal, ansi, svg | | `--output, -o` | no | Optional file path to write export output to (defaults to stdout) | - | - | #### `archie session receipt` Render one session's Flight Receipt, as ANSI or SVG | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session to render a flight receipt for, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--last` | no | Render the newest session for this directory's repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--format, -f` | no | Output format: terminal (default), ansi, svg, receipt, or json | terminal | terminal, ansi, svg, receipt, json | | `--output, -o` | no | Optional file path to write receipt or SVG output to (defaults to stdout) | - | - | #### `archie session handoff` Hand a session over: what it promised and dropped, decided, changed, ran, and proved | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | Session to hand over, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--last` | no | Hand over the newest session for this repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--redact, -r` | no | Mask secrets, paths, and this session's own repository name before printing | false | - | | `--markdown` | no | Emit the same markdown the `session_handoff` MCP tool returns | false | - | | `--max-lines` | no | Line budget for `--markdown` (default 60, ceiling 120) | - | - | | `--json` | no | Output the structured handoff as JSON | false | - | #### `archie session wake` What you were doing: the checkout, the newest session's task, proof, loose ends, and the next step, in 30 lines | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--workspace` | no | Directory to read the checkout from and to derive the repo from. Defaults to the current directory | - | - | | `--repo` | no | Repository/workspace key, as `session handoff`'s receipt reports it. Defaults to the key derived from `--workspace` | - | - | | `--redact, -r` | no | Mask secrets, paths, and this session's own repository name before printing | false | - | | `--json` | no | Output the wake report as JSON | false | - | | `--inject` | no | Read an Antigravity CLI `PreInvocation` hook payload on stdin and print the `injectSteps` wake envelope on stdout (docs/specs/wake.md, "Automation"). Only `antigravity` today: Claude Code and Codex inject through their own hook commands | - | antigravity | #### `archie session forgotten` What compaction dropped: decisions this session made and its own summaries did not keep | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | Session to diff, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, defaults to the newest session indexed for this directory's repository (same as `--last`) | - | - | | `--last` | no | Diff the newest session for this directory's repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--round` | no | One 1-based compaction round. Defaults to every round | - | - | | `--class` | no | Any of decision, rejected, reason. Repeatable. Defaults to all three | - | - | | `--limit` | no | How many statements to return, newest first (default 20, ceiling 200) | - | - | | `--redact, -r` | no | Mask secrets, paths, and this session's own repository name before printing | false | - | | `--json` | no | Output the structured diff as JSON | false | - | #### `archie session loose-ends` The handoff's loose-ends section alone: what a session said it would do and did not | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | Session to check, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--last` | no | Check the newest session for this repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--redact, -r` | no | Mask secrets, paths, and this session's own repository name before printing | false | - | | `--prompt` | no | Print the copyable prompt to hand to an agent that has the repository open | false | - | | `--json` | no | Output the loose ends as JSON | false | - | #### `archie session asks` The questions you asked and where their answers are -- built so you never have to re-scroll or re-ask because the answer landed several messages later | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | Session to index, by full ID, a unique prefix, or a raw JSONL file path (parsed directly if it isn't an indexed session). With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--session` | no | The same session, named with a flag. Kept because `archie session asks --session ` is the spelling that shipped in #97 | - | - | | `--last` | no | Resolve the newest session for this directory's repository, falling back to the newest session anywhere | false | - | | `--current` | no | Alias of `--last` | false | - | | `--since` | no | Only questions asked at or after this time: RFC 3339, `YYYY-MM-DD`, or a relative duration like `2h`, `30m`, `1d`, `3w` | - | - | | `--unanswered` | no | Only questions that are not `answered` -- still open, or flagged back to you | false | - | | `--json` | no | Output the structured index as JSON | false | - | #### `archie session cache` Diagnose turn-by-turn prompt caching dynamics and identify cache drop root causes | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session to act on, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--last` | no | The newest session for this directory's repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--json` | no | Output findings as formatted JSON | false | - | #### `archie session bisect` Pinpoint the exact turning point where a session's trajectory turned negative | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session to act on, by full ID or a unique prefix. With nothing given on a TTY, a picker lists the newest sessions; elsewhere, pass an ID or `--last` | - | - | | `--last` | no | The newest session for this directory's repository. The default when no ID is given and stdout is not a TTY | false | - | | `--current` | no | Alias of `--last` | false | - | | `--json` | no | Output findings as formatted JSON | false | - | #### `archie session search` Semantic vector search across indexed trajectory turns with ASCII thermal receipts | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `QUERY` | yes | Search query (natural language or code snippet) | - | - | | `--limit, -l` | no | Maximum number of results to return (default 10, or persisted `config limit`) | - | - | | `--min-score` | no | Minimum similarity score threshold (0.0 to 1.0) | 0 | - | | `--kind, -k` | no | Filter by chunk kind (summary, error_recovery, tool_invocation, apology_panic, code_lineage, user_turn) | - | - | | `--json` | no | Output results as JSON | false | - | #### `archie session recall` Semantically recall past solutions joined with outcome validation and cost | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `QUERY` | yes | Search query to match against previous trajectories | - | - | | `--limit, -l` | no | Maximum number of results to return (default 5, or persisted `config limit`) | - | - | | `--min-score` | no | Minimum similarity score threshold (0.0 to 1.0) | 0 | - | | `--json` | no | Output results as JSON | false | - | #### `archie session audit` Safety and threat audit detecting forbidden commands, leaked variables, sweeps, and fake claims, machine-wide over every session | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--safety` | no | Restrict audit to safety and threat vectors only | false | - | | `--json` | no | Output audit results as formatted JSON | false | - | #### `archie session blunder` Discover top agent blunders, render thermal receipts, and export to the Hall of Blunders | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--top, -t` | no | Number of top blunder exhibits to retrieve and display (default: 5) | 5 | - | | `--submit, -s` | no | Submit redacted blunder receipts to the public Hall of Blunders at stfuopus.lol | false | - | | `--dry-run` | no | Print the exact redacted payload a submission would POST, and send nothing. Read this before you ever pass --submit | false | - | | `--json` | no | Output blunder exhibits as formatted JSON | false | - | #### `archie session autopsy` Surface recurring human correction and steering phrases across all sessions | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--min-occurrences, -m` | no | Minimum number of occurrences across sessions to report (default: 2) | 2 | - | | `--json` | no | Output results as JSON | false | - | #### `archie session watch` Watch active session transcripts and detect doom loops or file edit thrashing | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--interval-secs, -i` | no | Polling interval in seconds (default: 3) | 3 | - | | `--poll-once` | no | Run a single poll check and exit immediately | false | - | | `--json` | no | Output findings as formatted JSON | false | - | | `--paths, -p` | no | Custom path directories to monitor | - | - | #### `archie session risk` Rank indexed sessions by real secret/credential exposure risk, by category and severity | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--limit, -l` | no | Maximum number of sessions to show in the report (default 20, or persisted `config limit`) -- every indexed session is still scanned; this only trims the displayed list | - | - | | `--min-severity` | no | Only include sessions whose worst finding is at least this severity | low | low, medium, high, critical | | `--json` | no | Output results as JSON | false | - | #### `archie session drift` What moved under this session since it read it, and which session moved it | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session, by full id or a unique prefix. Defaults to the most recently active one | - | - | | `--last` | no | The most recently active session, which is also the default | false | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie session anchors` The join keys this session's tool results carried -- a SpacePilot run_id, a receipt hash -- and the other sessions that carried them | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session, by full id or a unique prefix. Defaults to the most recently active one | - | - | | `--last` | no | The most recently active session, which is also the default | false | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie session burn` What this session has spent so far, from its own transcript: tokens, dollars at the table price, turns, cache read share, and the rate over the last ten minutes | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION_ID` | no | The session, by full id or a unique prefix. Defaults to the most recently active one | - | - | | `--last` | no | The most recently active session, which is also the default | false | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie agent` The agent adapters: what each one extracts, and how one is doing on this machine #### `archie agent list` Extraction capabilities and coverage across every registered adapter | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Output the coverage matrix as formatted JSON | false | - | #### `archie agent show` One adapter in detail: what it extracts, whether it is present here, and what it has actually put in the index | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `ADAPTER` | yes | Adapter name (e.g. claude_code, codex, gemini, opencode) | - | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie agent status` Where every agent on this machine is right now, one line each, from the loop's own hook events rather than from a scan | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Output as formatted JSON | false | - | #### `archie repo` Repositories: what an agent wrote where, and which commits nothing proved #### `archie repo list` The repositories and workspaces this index holds, by session count | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--limit, -l` | no | Maximum number of repositories to display (default 20, or persisted `config limit`) | - | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie repo blame` Trace file modifications back to the session, model, and prompt that authored them | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `FILE_PATH` | yes | Target file path or pattern to search | - | - | | `--json` | no | Output results as JSON | false | - | #### `archie repo pr-blame` Annotate changed PR files with AI agent authoring provenance and outcome validation | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `FILES` | no | List of files to check (if omitted, infers from git diff) | - | - | | `--json` | no | Output results as JSON | false | - | #### `archie repo suspect` List commits on this branch whose authoring session never proved anything, so you know where to look twice before pushing. Prints a list and a prompt, never a patch | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--repo` | no | Path to a git checkout. Defaults to the current directory | - | - | | `--since` | no | A date (RFC 3339 or YYYY-MM-DD) or a git ref to measure from. Defaults to the branch's upstream, then origin/main | - | - | | `--branch` | no | Branch to walk. Defaults to HEAD | - | - | | `--base` | no | Ref to diff against, if you want to name it separately from --since | - | - | | `--window-hours` | no | How long before a commit a session's file touch still counts as authoring it | - | - | | `--hook` | no | Print a ready-to-install pre-push hook and exit. The hook never blocks a push | false | - | | `--quiet` | no | Print only the copyable prompt, and only when something is suspect. What the hook runs | false | - | | `--json` | no | Output the full report as JSON | false | - | #### `archie repo blunder-blame` Bridge AI Code Blame with the Hall of Blunders: trace a recorded blunder forward to the exact files it blame-attributes to, or a file's blame history backward to any recorded blunders in the sessions blamed for it | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--file` | no | Blame -> blunder direction: file path or pattern. Checks every session AI Code Blame attributes this file to for a recorded blunder | - | - | | `--session` | no | Blunder -> blame direction: one specific session ID, by full ID or a unique prefix. Resolves it to the files AI Code Blame attributes to that session | - | - | | `--last` | no | Blunder -> blame direction for the newest session in this repository, same as `--session` with that session's ID | false | - | | `--current` | no | Alias of `--last` | false | - | | `--top, -t` | no | In default mode (no --file or --session), number of top blunders to bridge | 5 | - | | `--json` | no | Output results as JSON | false | - | #### `archie repo receipt` Work Receipts: a signed, privacy-safe account of what this machine's index saw on the commits you push, for the AgentWorth / Evidence check. Nothing leaves the machine until you say yes once per repository #### `archie repo receipt init` Print the workflow and the pre-push hook. --write writes both (never over an existing file), creates the receipt key, and records consent for this repository | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--repo` | no | Path to a git checkout. Defaults to the current directory | - | - | | `--write` | no | Write the workflow and hook, create the key, and record consent | false | - | | `--json` | no | Output as JSON | false | - | #### `archie repo receipt create` Build, sign and store a receipt for the commits about to be pushed: a git note on the tip (default) or a file under .agentworth/receipts/. Shows the exact JSON first on a terminal, and asks once per repository | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--repo` | no | Path to a git checkout. Defaults to the current directory | - | - | | `--base` | no | Ref to cover commits since. Defaults to the branch's upstream, then origin/main | - | - | | `--push` | no | Push refs/notes/agentworth after writing the note (what the pre-push hook runs) | false | - | | `--remote` | no | Remote to push the notes ref to. Defaults to origin | - | - | | `--transport` | no | Where the receipt goes | notes | notes, file | | `--include-spend` | no | Include API-equivalent spend (micro-USD). Off by default: receipts carry tokens only | false | - | | `--json` | no | Output the result, and the receipt itself, as JSON. Never prompts | false | - | | `--quiet` | no | One line on stderr, never a prompt, never a failure. What the hook runs | false | - | #### `archie repo receipt show` Decode a receipt by id prefix or commit, check its signature offline, and map its session refs back to sessions on this machine | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `RECEIPT_ID_OR_SHA` | yes | A receipt id (or a prefix of one, 4+ hex characters) or a commit | - | - | | `--repo` | no | Path to a git checkout. Defaults to the current directory | - | - | | `--json` | no | Output as JSON | false | - | #### `archie repo receipt key` Print the receipt public key; --github prints the `gh ssh-key add --type signing` line | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--github` | no | Print the `gh ssh-key add --type signing` command that links this key to your GitHub account, so the check can say "Signed by @you" | false | - | | `--json` | no | Output as JSON | false | - | #### `archie repo receipt verify` Verify every receipt for a PR range offline and render the AgentWorth / Evidence check. CI results and signing keys come from files (--ci, --keys); no network | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--base` | yes | Base of the PR range (a commit or ref) | - | - | | `--head` | yes | Head of the PR range (a commit or ref) | - | - | | `--ci` | no | Check runs and statuses on the head SHA, as collected with `gh api` | - | - | | `--keys` | no | GitHub signing keys of the PR and commit authors, as collected with `gh api` | - | - | | `--receipt` | no | An extra receipt file to read, beyond notes and .agentworth/receipts/ (repeatable) | - | - | | `--fail-on` | no | Opt-in failure: invalid-signature, below-rung:N, unattributed (comma-separated) | - | - | | `--format` | no | Output format | md | md, check-json | | `--repo` | no | Path to a git checkout. Defaults to the current directory | - | - | #### `archie window` The rolling burn-rate window: what is being spent right now #### `archie window show` The current rolling window: burn rate, active models, quota headroom | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--hours` | no | Window duration in hours | 5 | - | | `--alert-above` | no | Alert and highlight if window spend exceeds this threshold in USD | - | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie window list` The recent rolling windows, newest first | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--hours` | no | Window duration in hours | 5 | - | | `--limit, -l` | no | How many consecutive windows to show, newest first (default 6) | - | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie serve` Start the local API server and interactive explorer UI | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--port, -p` | no | Port to bind the server to | 3000 | - | | `--open` | no | Automatically open the Web UI in the default browser | false | - | | `--dist` | no | Optional path to custom web frontend dist directory | - | - | | `--no-socket` | no | Do not listen on the loop's Unix socket. Hook events then take the spool, and `archie scan` ingests them (docs/specs/loop.md section 1) | false | - | | `--home` | no | Start the gateway behind `apps/home` (a WebSocket at /ws) alongside the HTTP API. Unix-only: it dials herdr's own Unix socket for live presence. See `apps/cli/src/server/home_gateway.rs` | false | - | #### `archie mcp` Start the read-only MCP server over stdio, for a coding agent to query this machine's session index mid-session (see docs/specs/mcp-server.md). Register it once with `claude mcp add agentworth --scope user -- archie mcp` #### `archie hook` Plumbing: read one harness hook event on stdin and hand it to the loop (docs/specs/loop.md). Never prints to stdout, never fails the agent, exits 0 always. `archie hook print claude` prints the settings.json snippet that registers it | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--gate` | no | Answer the harness synchronously instead of recording and returning: one socket round trip inside 50 ms, and exit 0 with nothing on stdout if it misses | false | - | #### `archie hook print` Print the hook registration snippet for a harness. Never writes a settings file | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `HARNESS` | yes | The harness to print for. Both are verified against that harness's own hooks reference (docs/specs/loop.md, docs/specs/governor.md) | - | claude, codex, antigravity | | `--govern` | no | Also register the sync gates, so the governor can stop a turn. Claude Code only: the Codex snippet is gated by construction, since Codex has no batch hook | false | - | #### `archie policy` The governor's policy file: what it says, whether it parses, and clearing a session it suspended (docs/specs/governor.md). Nothing is governed until a `policy.toml` exists #### `archie policy init` Write a starter policy.toml, with this machine's own token percentiles as comments | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--repo` | no | Write `.agentworth/policy.toml` in the current repo instead of `~/.agentworth/policy.toml` | false | - | | `--force` | no | Overwrite an existing file | false | - | #### `archie policy show` What is governed right now, and which files were read to decide that | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Output as formatted JSON | false | - | #### `archie policy check` Parse both files and say what is wrong with them, naming the file and the line #### `archie policy lift` Clear a spend-cap suspension so the session can submit prompts again | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SESSION` | yes | The session to lift, by full id | - | - | #### `archie policy replay` What the current thresholds would have done to the sessions already indexed | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--since` | no | How far back to replay, in days | 30d | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie insights` Machine agent work in one deterministic report: usable sessions, tool calls, file touches, the evidence ladder, per-model burn, biggest sessions. Read-only; `--json` emits the full payload (same JSON as GET /api/insights) | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Output the full insights payload as formatted JSON | false | - | | `--since` | no | Window start (UTC RFC3339); inclusive | - | - | | `--until` | no | Window end (same format); exclusive. Defaults to the index's newest usable session | - | - | | `--adapter` | no | Single-select equality filter; valid values list under --json (insights.facets) | - | - | | `--model` | no | Filter by a recorded per-session model usage row | - | - | | `--repo` | no | Filter by display repo over session source paths (insights.repo_label) | - | - | #### `archie turns` (Re)ingest the human-turn lane on its own -- the turn-data side of Insights, without a full scan. A taxonomy-version bump wipes and re-parses every turn source; the dedup signature keeps past encounters out. Also the repair turn for the turn↔session link (tier-2/3 need each turn's source file path, which only ingester v2+ writes) | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--force` | no | Re-parse every turn source regardless of fingerprints (dedup keeps stored rows stable) | false | - | | `--json` | no | Output the ingest summary as JSON | false | - | #### `archie doctor` Check local environment, adapter discoveries, and SQLite database health | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Output diagnostic report as formatted JSON | false | - | | `--self-test` | no | Run the real release workflow end to end -- scan, stats, usage, sessions, show, handoff, forgotten, and an MCP round trip -- against the real index on this machine, with no network, and report pass/fail/slow and timing for each step. Exits non-zero if any step fails | false | - | #### `archie docs` Generate CLI, HTTP API, and MCP tool reference documentation from the code itself (see docs/REFERENCE.md). Nothing here is hand-written prose: the CLI section walks the clap command tree, the API section walks the axum route table, and the MCP section walks the rmcp tool router -- so the reference cannot drift from the code | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--format` | no | Output format when printing to stdout (ignored with --write, which always writes both forms) | markdown | markdown, json | | `--write` | no | Write docs/REFERENCE.md and docs/reference.json (relative to the current directory, which must be the repository root) instead of printing to stdout | false | - | #### `archie config` Get, set, or list persisted CLI defaults (~/.agentworth/config.toml) #### `archie config list` List every persisted config key and its current value | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Output as JSON | false | - | #### `archie config get` Print the persisted value for one config key | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `KEY` | yes | Config key: json, limit, period, archie.accessory, or archie.colourway | - | - | | `--json` | no | Output as JSON | false | - | #### `archie config set` Persist a default value for one config key | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `KEY` | yes | Config key: json, limit, period, archie.accessory, or archie.colourway | - | - | | `VALUE` | yes | Value to store (json: true/false, limit: a number, period: day/week/month, archie.accessory: lamp/goggles/none, archie.colourway: C1/C2/C3/C4) | - | - | | `--json` | no | Output as JSON | false | - | #### `archie version` Print version details: binary version, npm install detection, and a live check for a newer release | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--offline` | no | Skip the live GitHub-releases update check (fully local, no network call) | false | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie update` Check for a newer AgentWorth release and show exactly how to get it | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--offline` | no | Skip the live GitHub-releases check and just show install-method guidance | false | - | | `--json` | no | Output as formatted JSON | false | - | #### `archie completions` Write a shell completion script to stdout | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SHELL` | yes | Shell to generate a completion script for | - | bash, elvish, fish, powershell, zsh | #### `archie merge` Merge another local SQLite index database into this index | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `SOURCE_DB` | yes | Path to the source SQLite database file to merge from | - | - | | `--json` | no | Output results as JSON | false | - | #### `archie tui` Open the cockpit: the same grammar, full screen, with a cursor. A bare `archie` does this too; `archie tui` is the explicit spelling. Off a terminal, under `--plain`, under `TERM=dumb`, or with JSON output, both print the overview and exit 0 instead of taking the terminal over | Flag | Required | Help | Default | Values | |---|---|---|---|---| | `--json` | no | Print the overview as JSON and exit, without opening anything | false | - | #### Old spellings The commands and MCP tools below were renamed in 0.1.16. Every old name still runs and reaches the same handler; none of them appears in `--help` any more, and all of them stop working in v0.1.20. | Surface | Old | New | |---|---|---| | cli | `traces` | `session list` | | cli | `inspect` | `session show` | | cli | `export` | `session export` | | cli | `receipt` | `session receipt` | | cli | `handoff` | `session handoff` | | cli | `forgotten` | `session forgotten` | | cli | `loose-ends` | `session loose-ends` | | cli | `asks` | `session asks` | | cli | `cache-doctor` | `session cache` | | cli | `bisect` | `session bisect` | | cli | `search` | `session search` | | cli | `recall` | `session recall` | | cli | `audit` | `session audit` | | cli | `blunder` | `session blunder` | | cli | `autopsy` | `session autopsy` | | cli | `watch` | `session watch` | | cli | `blind-spots` | `session list --unproven` | | cli | `threat-digest` | `session risk` | | cli | `matrix` | `agent list` | | cli | `blame` | `repo blame` | | cli | `pr-blame` | `repo pr-blame` | | cli | `suspect` | `repo suspect` | | cli | `blunder-blame` | `repo blunder-blame` | | cli | `usage` | `stats usage` | | mcp | `sessions_find` | `session_list` | | mcp | `session_get` | `session_show` | | mcp | `blame_find` | `repo_blame` | | mcp | `usage_summary` | `stats_usage` | | mcp | `pacing_window` | `window_show` | | mcp | `coverage_stats` | `agent_list` | | mcp | `outcome_rate` | `stats_outcomes` | | mcp | `carry_forward` | `session_carry_forward` | | mcp | `forgotten_context` | `session_forgotten` | | mcp | `suspect_commits` | `repo_suspect` | ### HTTP API Registered by `archie serve` under `http://localhost:` (default port 3000). Every route below lives in one table, `server::routes::route_entries()`, that also builds the live router -- so this list cannot list a route the server doesn't actually serve. #### `GET /api/stats` Machine-wide experience stats with outcome distributions and verification telemetry #### `GET /api/traces` Filtered, paginated list of indexed sessions | Query Param | Description | |---|---| | `adapter` | Filter by adapter name | | `model` | Filter by model substring | | `search` | Full-text search across session content | | `outcome` | Filter by primary outcome kind | | `min_tokens` | Minimum total token count | | `limit` | Maximum number of sessions to return (default 50) | | `offset` | Number of sessions to skip | | `order_by` | Sort order for the result list | #### `GET /api/traces/:id` Full trace details: metadata, stats, 5-factor score, outcome evidence, timeline | Query Param | Description | |---|---| | `offset` | Number of events to skip (default 0) | | `limit` | Maximum number of events to return (default: all) | #### `GET /api/traces/:id/events` Just the paginated event slice for one trace | Query Param | Description | |---|---| | `offset` | Number of events to skip (default 0) | | `limit` | Maximum number of events to return (default: all) | #### `GET /api/usage` Daily, weekly, and monthly token usage rollups | Query Param | Description | |---|---| | `daily_limit` | Maximum number of daily rollup rows | | `weekly_limit` | Maximum number of weekly rollup rows | | `monthly_limit` | Maximum number of monthly rollup rows | #### `GET /api/pacing` Rolling pacing window: burn velocity and cache hit ratio | Query Param | Description | |---|---| | `hours` | Pacing window duration in hours (default 5) | #### `GET /api/blame` File change lineage matching session histories | Query Param | Description | |---|---| | `file` | Target file path or pattern | | `path` | Alias for `file` | #### `GET /api/matrix` Adapter extraction coverage and capabilities matrix #### `GET /api/insights` The deterministic machine-insights payload: usable sessions, tool calls, evidence ladder, per-model burn, biggest sessions (same JSON as `agentworth insights --json`). Optional since/until window plus single-select adapter/model/repo slice filters (values validated against the payload's facets block) | Query Param | Description | |---|---| | `since` | window start (UTC RFC3339, inclusive) | | `until` | window end (exclusive; requires since) | | `adapter` | single-select equality slice; values validated against the payload's facets | | `model` | single-select model equality over recorded per-session usage | | `repo` | single-select display-repo equality | #### `GET /api/insights/drill` Drill-through: the sessions behind one insights cut (same shape the deck's session feeds render). view=ladder|day_hour|friction + key=, optional since/until and the same adapter/model/repo filters | Query Param | Description | |---|---| | `view` | ladder \| day_hour \| friction | | `key` | rung outcome \| - \| trigger | | `since` | window start (UTC RFC3339, inclusive) | | `until` | window end (exclusive; requires since) | | `adapter` | single-select equality slice | | `model` | single-select model equality | | `repo` | single-select display-repo equality | | `limit` | rows to return (default 50, ceiling 200); count is always the full total | #### `GET /api/archaeology` Archaeology highlights across the whole index #### `GET /api/live-tail` Server-Sent Events stream of live filesystem changes under watched adapter session directories #### `POST /api/scan` Trigger a scanner background sync (body: paths, force) #### `GET /api/config` Persisted CLI defaults from config.toml, every key present and unset ones null #### `POST /api/config` Write a partial set of persisted CLI defaults (body: any of json, limit, period, archie.accessory, archie.colourway; null clears a key) #### `POST /api/export/:id` Export a trace with optional redaction, in JSON or ATIF format (body: redact, format) ### MCP Tools Register once with `claude mcp add agentworth --scope user -- archie mcp` (stdio). Read-only; redaction is on by default for every tool (see `docs/specs/mcp-server.md`). #### `agent_list` Machine-wide aggregate stats: total sessions/events, token usage, sessions by adapter, model/tool usage counts, and verified-outcome count -- the same population /api/stats reports. Pass include_matrix=true to also get the per-adapter detection/capability matrix (/api/matrix's equivalent), answering "what does this machine even have" without opening the dashboard. | Param | Required | Type | Description | |---|---|---|---| | `include_matrix` | no | boolean | Also compute and include the per-adapter detection/capability matrix
(`/api/matrix`'s equivalent). Defaults to false. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "include_matrix": { "default": false, "description": "Also compute and include the per-adapter detection/capability matrix\n(`/api/matrix`'s equivalent). Defaults to false.", "type": "boolean" } }, "type": "object" } ```
#### `agent_status` Where every agent on this machine is right now: one row per session the loop has seen, with its state (registered / working / idle / ended), when it entered that state, the repository it is working in, its terminal pane when herdr exported one, and its event sequence. Fed by the harness's own hooks (`archie hook`), not by a scan, so it is current rather than as-of-last-scan. An empty list means no hook is registered -- `archie hook print claude` prints the snippet.
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "type": "object" } ```
#### `insights_get` The deterministic machine-insights payload over this index -- the exact contract `agentworth insights --json` and /api/insights serve, never a hand-rolled variant: population, volume, by_adapter, ladder, verified, calls_per_turn, turn_buckets, file_modifications, top_repos, top_sessions, session_size_buckets, models, models_totals, series, tool_buckets and tool_buckets_detail, plus the human-turn blocks day_hour, friction and vocabulary, deltas, coverage_flags and the deferred list with its reasons. Optional since/until narrow the window (`until` requires `since`); absent both is all-time. Aggregates only -- no transcript text is ever returned, so there is no include_raw. Zero-data blocks come back empty with the reason in `deferred`, never zero-filled. | Param | Required | Type | Description | |---|---|---|---| | `adapter` | no | string or null | Exact adapter match (e.g. `claude_code`); valid values in the payload's facets. | | `model` | no | string or null | Exact model match over recorded per-session model usage. Optional. | | `repo` | no | string or null | Exact display-repo match over session source paths. Optional. | | `since` | no | string or null | RFC 3339 timestamp; only sessions (and stored human turns) starting at or after
this instant. Optional; omit for all-time. | | `until` | no | string or null | RFC 3339 timestamp; requires `since` -- a window needs a start. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "adapter": { "description": "Exact adapter match (e.g. `claude_code`); valid values in the payload's facets.", "type": [ "string", "null" ] }, "model": { "description": "Exact model match over recorded per-session model usage. Optional.", "type": [ "string", "null" ] }, "repo": { "description": "Exact display-repo match over session source paths. Optional.", "type": [ "string", "null" ] }, "since": { "description": "RFC 3339 timestamp; only sessions (and stored human turns) starting at or after\nthis instant. Optional; omit for all-time.", "type": [ "string", "null" ] }, "until": { "description": "RFC 3339 timestamp; requires `since` -- a window needs a start.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `insights_summary` The compact insights surface: one headline row per KPI -- population, volume, verified share, calls_per_turn strict, friction rate and top trigger, the day_hour peak cell, and the deferred list -- projected from the same payload `insights_get` returns, so the two can never disagree. The series, top lists, vocabulary rows and full turn blocks stay in `insights_get`. Optional since/until as there. Aggregates only -- no transcript text is ever returned, so there is no include_raw. | Param | Required | Type | Description | |---|---|---|---| | `adapter` | no | string or null | Exact adapter match (e.g. `claude_code`); valid values in the payload's facets. | | `model` | no | string or null | Exact model match over recorded per-session model usage. Optional. | | `repo` | no | string or null | Exact display-repo match over session source paths. Optional. | | `since` | no | string or null | RFC 3339 timestamp; only sessions (and stored human turns) starting at or after
this instant. Optional; omit for all-time. | | `until` | no | string or null | RFC 3339 timestamp; requires `since` -- a window needs a start. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "adapter": { "description": "Exact adapter match (e.g. `claude_code`); valid values in the payload's facets.", "type": [ "string", "null" ] }, "model": { "description": "Exact model match over recorded per-session model usage. Optional.", "type": [ "string", "null" ] }, "repo": { "description": "Exact display-repo match over session source paths. Optional.", "type": [ "string", "null" ] }, "since": { "description": "RFC 3339 timestamp; only sessions (and stored human turns) starting at or after\nthis instant. Optional; omit for all-time.", "type": [ "string", "null" ] }, "until": { "description": "RFC 3339 timestamp; requires `since` -- a window needs a start.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `repo_blame` Find sessions whose recorded file modifications match a substring of file_path -- AI Code Blame, the same query /api/blame makes. Returned paths are redacted. | Param | Required | Type | Description | |---|---|---|---| | `file_path` | yes | string | Substring pattern matched against recorded file-modification paths. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "file_path": { "description": "Substring pattern matched against recorded file-modification paths.", "type": "string" } }, "required": [ "file_path" ], "type": "object" } ```
#### `repo_receipt` The Work Receipt the next push would sign, without signing, writing or pushing anything. Same range rules as repo_suspect (upstream, then origin/main, then the last max_commits). Returns the exact receipt Statement (commit SHAs, opaque session refs, adapters, models, token totals, rung kinds with verified_locally, risk counters -- no prompts, no paths outside the commits' own diffs), a `predicted` list per commit (highest rung attested locally, rungs only claimed), a one-line `summary` such as "rung 3 attested, rung 1 claimed only", and `sessions_local` mapping each ref back to a session id for session_show. Use it before pushing: if nothing reaches rung 3 attested, run the tests first. Rungs 2, 4 and 5 are re-derived from CI by the AgentWorth / Evidence check, not here. `key_present: false` means no receipt key exists yet (refs are placeholders); `consent_recorded: false` means the pre-push hook will not export until the user runs `archie repo receipt init --write` or answers yes once. | Param | Required | Type | Description | |---|---|---|---| | `base` | no | string or null | Ref to diff against. Defaults to the branch's own upstream, then `origin/main`, then
`origin/master`, then the most recent `max_commits` commits — the range the pre-push
hook would sign. | | `branch` | no | string or null | Branch to walk. Defaults to `HEAD`. | | `include_spend` | no | boolean or null | Put API-equivalent spend (micro-USD) in the preview, as `create --include-spend` would.
Defaults to false: receipts carry tokens only. | | `max_commits` | no | integer or null | Ceiling on commits walked. Defaults to 200, hard-capped at 1000. | | `repo` | yes | string | Absolute path to a git checkout on this machine. Anything inside it works — the
repository root is resolved with `git rev-parse --show-toplevel`. | | `since` | no | string or null | RFC 3339 timestamp. Only consulted when `base` is absent. | | `window_hours` | no | integer or null | How long before a commit a session's file touch still counts as having authored it.
Defaults to 24. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "base": { "description": "Ref to diff against. Defaults to the branch's own upstream, then `origin/main`, then\n`origin/master`, then the most recent `max_commits` commits — the range the pre-push\nhook would sign.", "type": [ "string", "null" ] }, "branch": { "description": "Branch to walk. Defaults to `HEAD`.", "type": [ "string", "null" ] }, "include_spend": { "default": null, "description": "Put API-equivalent spend (micro-USD) in the preview, as `create --include-spend` would.\nDefaults to false: receipts carry tokens only.", "type": [ "boolean", "null" ] }, "max_commits": { "description": "Ceiling on commits walked. Defaults to 200, hard-capped at 1000.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "repo": { "description": "Absolute path to a git checkout on this machine. Anything inside it works — the\nrepository root is resolved with `git rev-parse --show-toplevel`.", "type": "string" }, "since": { "description": "RFC 3339 timestamp. Only consulted when `base` is absent.", "type": [ "string", "null" ] }, "window_hours": { "description": "How long before a commit a session's file touch still counts as having authored it.\nDefaults to 24.", "format": "int64", "type": [ "integer", "null" ] } }, "required": [ "repo" ], "type": "object" } ```
#### `repo_suspect` Which commits on this branch came out of a session that never proved anything. Walks `git log` over the range, joins each commit's changed paths to indexed sessions that touched them within window_hours before it, and reports each session's risk signals: no_test_run (the session never got past artifact_changed), no_outcome_detected (the adapter extracted no outcome at all -- weaker), demoted_claim (verification contradicted a claim, with the event sequence), and loop (the sentinel caught repetition). Returns a list and a copyable prompt -- never a patch, a diff, or a PR: a trajectory says the session was going badly, not what the code does wrong. Two counts are load-bearing and must be reported to the user, not dropped: `unattributed` commits had no indexed session at all (unknown, not clean), and `unanchored_blame_rows` is evidence that could not be placed in any repository. Paths and session source paths are redacted. | Param | Required | Type | Description | |---|---|---|---| | `base` | no | string or null | Ref to diff against. Defaults to the branch's own upstream, then `origin/main`, then
`origin/master`, then the most recent `max_commits` commits. | | `branch` | no | string or null | Branch to walk. Defaults to `HEAD`. | | `max_commits` | no | integer or null | Ceiling on commits walked. Defaults to 200, hard-capped at 1000. | | `repo` | yes | string | Absolute path to a git checkout on this machine. Anything inside it works — the
repository root is resolved with `git rev-parse --show-toplevel`. | | `since` | no | string or null | RFC 3339 timestamp. Only consulted when `base` is absent. | | `window_hours` | no | integer or null | How long before a commit a session's file touch still counts as having authored it.
Defaults to 24. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "base": { "description": "Ref to diff against. Defaults to the branch's own upstream, then `origin/main`, then\n`origin/master`, then the most recent `max_commits` commits.", "type": [ "string", "null" ] }, "branch": { "description": "Branch to walk. Defaults to `HEAD`.", "type": [ "string", "null" ] }, "max_commits": { "description": "Ceiling on commits walked. Defaults to 200, hard-capped at 1000.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "repo": { "description": "Absolute path to a git checkout on this machine. Anything inside it works — the\nrepository root is resolved with `git rev-parse --show-toplevel`.", "type": "string" }, "since": { "description": "RFC 3339 timestamp. Only consulted when `base` is absent.", "type": [ "string", "null" ] }, "window_hours": { "description": "How long before a commit a session's file touch still counts as having authored it.\nDefaults to 24.", "format": "int64", "type": [ "integer", "null" ] } }, "required": [ "repo" ], "type": "object" } ```
#### `session_asks` The questions-to-answers index for one session: every question asked (a `?` sentence in a user turn, or a flag-prefixed `⚑`/`🚩` line in an assistant turn asking the user something) matched to the first substantive assistant text that follows it, before the next user turn. Exists so an agent can be told where an answer already landed instead of the user re-scrolling or re-asking. Each result carries the question (trimmed to 120 chars), a status (answered, flagged_back_to_user -- either a flag line or a reply that was itself a question, or no_reply_yet), an answer excerpt when one was found (trimmed to 200 chars), and a pointer (event sequence and timestamp) to jump to: the answer's location when there is one, otherwise the question's own. Filter with since (RFC 3339) and unanswered_only; limit defaults to 50, ceiling 500, and the totals describe the whole session regardless of it. No model is involved -- three deterministic patterns, same `regex_v1` method `session_forgotten` uses. Defaults to the newest session for the repo this server runs in. Redacted by default; include_raw=true opts out, per call. | Param | Required | Type | Description | |---|---|---|---| | `include_raw` | no | boolean | Return unredacted questions and answer excerpts. Defaults to false -- everything this
tool returns is transcript text (docs/specs/mcp-server.md, "What it must not expose"). | | `limit` | no | integer or null | How many questions to return, newest first. Defaults to 50, hard ceiling 500. The
totals in the response describe the whole session regardless of this. | | `session_id` | no | string or null | Session to index. Defaults to the most recent indexed session for the repository this
server process is running in, same default `session_handoff` uses. | | `since` | no | string or null | RFC 3339 timestamp; only questions asked at or after this instant. | | `unanswered_only` | no | boolean | Only questions that are not `answered` -- still open, or handed back to the user.
Defaults to false. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "include_raw": { "default": false, "description": "Return unredacted questions and answer excerpts. Defaults to false -- everything this\ntool returns is transcript text (docs/specs/mcp-server.md, \"What it must not expose\").", "type": "boolean" }, "limit": { "description": "How many questions to return, newest first. Defaults to 50, hard ceiling 500. The\ntotals in the response describe the whole session regardless of this.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "session_id": { "description": "Session to index. Defaults to the most recent indexed session for the repository this\nserver process is running in, same default `session_handoff` uses.", "type": [ "string", "null" ] }, "since": { "description": "RFC 3339 timestamp; only questions asked at or after this instant.", "type": [ "string", "null" ] }, "unanswered_only": { "default": false, "description": "Only questions that are not `answered` -- still open, or handed back to the user.\nDefaults to false.", "type": "boolean" } }, "type": "object" } ```
#### `session_burn` What one session has spent so far, metered from its own transcript: tokens, dollars at the pricing table's rates, turns, the cache read share, and the rate over the last ten minutes. This is AgentWorth's own count, not the provider's accounting -- it never reports a 'remaining'. When the harness writes its own rate-limit line (Codex does; Claude Code does not) that line is returned verbatim under `provider_limit`, labelled as the provider's. Numbers are as of the last update `archie serve` wrote, and are zero on a machine with no `policy.toml`, since nothing is metered until something is governed. | Param | Required | Type | Description | |---|---|---|---| | `session_id` | no | string or null | The session, by full id or a unique prefix. Defaults to the most recently active
session in the loop's own index, which is the caller itself in the normal case. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "session_id": { "description": "The session, by full id or a unique prefix. Defaults to the most recently active\nsession in the loop's own index, which is the caller itself in the normal case.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `session_carry_forward` The last N handoffs for one repository, newest first, so a session's first tool call can be "what happened here recently" and the answer is structured rather than a file it has to find and parse. `repo` is the same key session_handoff's receipt reports (e.g. `unfoundbox/agentworth`); a repo's worktrees all answer to one value. n defaults to 3, ceiling 10. Handoffs are listed, never merged -- merging two contradictory facts needs judgment about which is current, and that is not in the index. Subagent transcripts are excluded unless include_subagents is true. Redacted by default. | Param | Required | Type | Description | |---|---|---|---| | `include_raw` | no | boolean | Same per-call raw opt-in `session_handoff` has, applied to every handoff returned. | | `include_subagents` | no | boolean | Include subagent transcripts as their own entries. Defaults to false: a subagent
starts after its parent and would otherwise win "newest" for a session the parent is
still running (docs/specs/wake.md). | | `max_lines` | no | integer or null | Line budget for each rendered handoff. Defaults to 60, hard ceiling 120. | | `n` | no | integer or null | How many handoffs to return, newest first. Defaults to 3, ceiling 10. | | `repo` | yes | string | Repository/workspace key, as `session_list`'s `repo` and the handoff receipt report
it (e.g. `unfoundbox/agentworth`). A repo's worktrees all answer to one value. | | `since` | no | string or null | RFC 3339 timestamp; only sessions started at or after this instant. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "include_raw": { "default": false, "description": "Same per-call raw opt-in `session_handoff` has, applied to every handoff returned.", "type": "boolean" }, "include_subagents": { "default": false, "description": "Include subagent transcripts as their own entries. Defaults to false: a subagent\nstarts after its parent and would otherwise win \"newest\" for a session the parent is\nstill running (docs/specs/wake.md).", "type": "boolean" }, "max_lines": { "description": "Line budget for each rendered handoff. Defaults to 60, hard ceiling 120.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "n": { "description": "How many handoffs to return, newest first. Defaults to 3, ceiling 10.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "repo": { "description": "Repository/workspace key, as `session_list`'s `repo` and the handoff receipt report\nit (e.g. `unfoundbox/agentworth`). A repo's worktrees all answer to one value.", "type": "string" }, "since": { "description": "RFC 3339 timestamp; only sessions started at or after this instant.", "type": [ "string", "null" ] } }, "required": [ "repo" ], "type": "object" } ```
#### `session_drift` What moved under a session since it read it. The support set U is the paths the session actually read, hashed at the time; this re-hashes them and returns the ones that differ, each with the session that predicted a write to that path afterwards, or nothing when no agent on this machine did (someone edited it by hand, or another tool did). The answer to "did my ground move because of me or someone else", which no harness summary can give. Reads files and rows; never scans, never writes. Files over 4 MB were not hashed and are counted as unhashed rather than reported as unchanged. | Param | Required | Type | Description | |---|---|---|---| | `session_id` | no | string or null | The session, by full id or a unique prefix. Defaults to the most recently active
session in the loop's own index, which is the caller itself in the normal case. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "session_id": { "description": "The session, by full id or a unique prefix. Defaults to the most recently active\nsession in the loop's own index, which is the caller itself in the normal case.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `session_forgotten` The decisions this session's compaction rounds threw away, quoted verbatim with a receipt on each. Compaction replaces the conversation with a summary in the model's view while the full transcript stays on disk, so the dropped span and the summary that replaced it both exist and can be diffed. Measured on one real 8-round session (docs/specs/compaction-diff.md): 402 decision-shaped sentences went in and 28 came out -- conclusions survive at 15%, reasons at 1.7%, which is the shape that makes a session re-propose something it already rejected. Filter with round (1-based) and classes (decision, rejected, reason); limit defaults to 20, ceiling 200, and the totals describe the whole session regardless of it. Every statement carries its round, source sequence, and what the session did in the next few events, so a stated decision that was acted on can be told from one that was only claimed. Three answers are kept distinct and none is padded: never compacted, compacted with nothing decision-shaped dropped, and a real list. No model is involved -- three regexes return the sentence verbatim, because a paraphrase would make this a second summariser. Refuses if the raw session file is gone. Redacted by default; include_raw=true opts out, per call. | Param | Required | Type | Description | |---|---|---|---| | `classes` | no | array or null | Any of `decision`, `rejected`, `reason`. Defaults to all three. An unknown name is an
error, not an ignored filter. | | `include_raw` | no | boolean | Return unredacted sentences, paths and evidence labels. Defaults to false -- everything
this tool returns is transcript text (docs/specs/mcp-server.md, "What it must not
expose"). | | `limit` | no | integer or null | How many statements to return, newest first. Defaults to 20, hard ceiling 200. The
totals in the response describe the whole session regardless of this. | | `round` | no | integer or null | One 1-based compaction round. Defaults to every round. | | `session_id` | no | string or null | Session to diff. Defaults to the most recent indexed session for the repository this
server process is running in, which is what an agent asking "what did I forget here"
means; pass one explicitly to reach any other session. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "classes": { "description": "Any of `decision`, `rejected`, `reason`. Defaults to all three. An unknown name is an\nerror, not an ignored filter.", "items": { "type": "string" }, "type": [ "array", "null" ] }, "include_raw": { "default": false, "description": "Return unredacted sentences, paths and evidence labels. Defaults to false -- everything\nthis tool returns is transcript text (docs/specs/mcp-server.md, \"What it must not\nexpose\").", "type": "boolean" }, "limit": { "description": "How many statements to return, newest first. Defaults to 20, hard ceiling 200. The\ntotals in the response describe the whole session regardless of this.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "round": { "description": "One 1-based compaction round. Defaults to every round.", "format": "uint32", "minimum": 0, "type": [ "integer", "null" ] }, "session_id": { "description": "Session to diff. Defaults to the most recent indexed session for the repository this\nserver process is running in, which is what an agent asking \"what did I forget here\"\nmeans; pass one explicitly to reach any other session.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `session_handoff` The handoff for one session, written from rows rather than by a model: what it said it would do and never did, what it said it decided, which files changed, which commands ran and with what exit code, the outcome rung reached, and how often the context was compacted. Returns markdown under a line budget (max_lines, default 60, ceiling 120), the receipt every claim traces back to, and `gaps` -- the machine-readable list of what this session could not answer, which is never padded over. Open decisions, PR/CI state and environment traps are NOT in the index and the output says so. Defaults to the newest session for the repo this server runs in. Redacted by default; include_raw=true opts out, per call. | Param | Required | Type | Description | |---|---|---|---| | `include_loose_ends` | no | boolean or null | Include the "said it would, no evidence it did" section. Defaults to true. | | `include_raw` | no | boolean | Return unredacted paths, commands and quoted sentences. Defaults to false -- redacted
is the default for every tool that can carry event or file content
(docs/specs/mcp-server.md, "What it must not expose"). | | `max_lines` | no | integer or null | Line budget for the rendered markdown. Defaults to 60, hard ceiling 120. | | `session_id` | no | string or null | Session to hand over. Defaults to the most recent indexed session for the repository
this server process is running in, which is what an agent asking "what did I just do
here" means; pass one explicitly to reach any other session or repo. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "include_loose_ends": { "description": "Include the \"said it would, no evidence it did\" section. Defaults to true.", "type": [ "boolean", "null" ] }, "include_raw": { "default": false, "description": "Return unredacted paths, commands and quoted sentences. Defaults to false -- redacted\nis the default for every tool that can carry event or file content\n(docs/specs/mcp-server.md, \"What it must not expose\").", "type": "boolean" }, "max_lines": { "description": "Line budget for the rendered markdown. Defaults to 60, hard ceiling 120.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "session_id": { "description": "Session to hand over. Defaults to the most recent indexed session for the repository\nthis server process is running in, which is what an agent asking \"what did I just do\nhere\" means; pass one explicitly to reach any other session or repo.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `session_list` Find sessions by adapter, model, outcome, search text, date range, token floor, or derived repo/workspace name. `limit` is required with a hard ceiling of 200 -- there is no silent default, so state how many results you want. Returns summaries only (no event content); `source_path` is redacted. | Param | Required | Type | Description | |---|---|---|---| | `adapter` | no | string or null | Exact adapter name match (e.g. `claude_code`, `codex`, `gemini`). | | `end_date` | no | string or null | RFC 3339 timestamp; only sessions started at or before this instant. | | `include_stubs` | no | boolean or null | Include near-empty session stubs (defaults to excluding them). | | `limit` | yes | integer | Maximum rows to return. Required -- there is no silent default -- and capped at
`SESSIONS_FIND_LIMIT_CEILING` (200). | | `min_tokens` | no | integer or null | Only sessions with at least this many total tokens. | | `model` | no | string or null | Substring match against the session's recorded models. | | `offset` | no | integer or null | - | | `order_by` | no | - | Sort order; defaults to `started_at_desc`. | | `outcome` | no | string or null | Exact match against the stored primary outcome, snake_case (e.g. `commit_observed`). | | `repo` | no | string or null | Filter to sessions whose derived repository/workspace name matches exactly. Not a
stored column -- computed per-row from `source_path` and post-filtered client-side,
so combining this with `limit` may require over-fetching (see `truncated` in the
response). | | `search` | no | string or null | Substring match across session ID, source path, models, and adapter. | | `start_date` | no | string or null | RFC 3339 timestamp; only sessions started at or after this instant. |
JSON schema ```json { "$defs": { "SessionsOrderBy": { "description": "Mirrors `agentworth_storage::SessionOrderBy` with the same snake_case wire values. A local\ncopy rather than deriving `schemars::JsonSchema` on the storage crate's own enum, since\n`agentworth-storage` has no reason to take on a `schemars` dependency for one MCP-only need.", "enum": [ "started_at_desc", "started_at_asc", "tokens_desc", "tokens_asc", "events_desc", "events_asc", "duration_desc", "score_desc", "score_asc" ], "type": "string" } }, "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "adapter": { "description": "Exact adapter name match (e.g. `claude_code`, `codex`, `gemini`).", "type": [ "string", "null" ] }, "end_date": { "description": "RFC 3339 timestamp; only sessions started at or before this instant.", "type": [ "string", "null" ] }, "include_stubs": { "default": null, "description": "Include near-empty session stubs (defaults to excluding them).", "type": [ "boolean", "null" ] }, "limit": { "description": "Maximum rows to return. Required -- there is no silent default -- and capped at\n`SESSIONS_FIND_LIMIT_CEILING` (200).", "format": "uint", "minimum": 0, "type": "integer" }, "min_tokens": { "description": "Only sessions with at least this many total tokens.", "format": "uint64", "minimum": 0, "type": [ "integer", "null" ] }, "model": { "description": "Substring match against the session's recorded models.", "type": [ "string", "null" ] }, "offset": { "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "order_by": { "anyOf": [ { "$ref": "#/$defs/SessionsOrderBy" }, { "type": "null" } ], "description": "Sort order; defaults to `started_at_desc`." }, "outcome": { "description": "Exact match against the stored primary outcome, snake_case (e.g. `commit_observed`).", "type": [ "string", "null" ] }, "repo": { "description": "Filter to sessions whose derived repository/workspace name matches exactly. Not a\nstored column -- computed per-row from `source_path` and post-filtered client-side,\nso combining this with `limit` may require over-fetching (see `truncated` in the\nresponse).", "type": [ "string", "null" ] }, "search": { "description": "Substring match across session ID, source path, models, and adapter.", "type": [ "string", "null" ] }, "start_date": { "description": "RFC 3339 timestamp; only sessions started at or after this instant.", "type": [ "string", "null" ] } }, "required": [ "limit" ], "type": "object" } ```
#### `session_show` Get full detail for one session by ID: the trace, its 5-component TraceScore, outcome evidence, and recovery signals -- the same shape /api/traces/:id returns. Redacted by default (trace events, outcome summaries, and recovery summaries all pass through the redaction engine); pass include_raw=true for the unredacted trace. `trace.events` is paginated: events_offset (default 0) and events_limit (default 500, must be > 0) page through it, and the response's events_total says how many events the session actually has, so a large session is never returned in full by accident. | Param | Required | Type | Description | |---|---|---|---| | `events_limit` | no | integer or null | Max number of events to return. Defaults to `SESSION_GET_DEFAULT_EVENTS_LIMIT` (500) so
a call can never receive a session's full event list by accident; pass an explicit,
larger value to see more. Must be greater than 0. | | `events_offset` | no | integer or null | Zero-based offset into the trace's events. Defaults to 0. | | `include_raw` | no | boolean | Return the unredacted trace, outcomes, and recoveries. Defaults to false -- redacted
output is the default for every tool that can carry event or file content (see
docs/specs/mcp-server.md, "What it must not expose"). | | `session_id` | yes | string | - |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "events_limit": { "default": null, "description": "Max number of events to return. Defaults to `SESSION_GET_DEFAULT_EVENTS_LIMIT` (500) so\na call can never receive a session's full event list by accident; pass an explicit,\nlarger value to see more. Must be greater than 0.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "events_offset": { "default": null, "description": "Zero-based offset into the trace's events. Defaults to 0.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "include_raw": { "default": false, "description": "Return the unredacted trace, outcomes, and recoveries. Defaults to false -- redacted\noutput is the default for every tool that can carry event or file content (see\ndocs/specs/mcp-server.md, \"What it must not expose\").", "type": "boolean" }, "session_id": { "type": "string" } }, "required": [ "session_id" ], "type": "object" } ```
#### `session_wake` One call for a cold or just-compacted agent: the checkout it stands in (branch, HEAD, dirty, ahead), the newest primary session for the repo (task, last prompt, outcome rung, last passed and last failed verification command and whether the failure was re-run, files changed, loose ends, what it said it decided, what compaction dropped), the two sessions before it one line each, and a Next block: blocker and next step. At most 30 lines of markdown. Subagent transcripts never answer for their parent. Every line is a row, a git read, or a stat; missing facts are named in gaps, never padded. PR and CI state are not in the index and the output says so. Redacted by default; include_raw opts out per call. Does not scan. | Param | Required | Type | Description | |---|---|---|---| | `include_raw` | no | boolean | Return unredacted paths, commands and quoted sentences. Defaults to false -- redacted
is the default for every tool that can carry event or file content
(docs/specs/mcp-server.md, "What it must not expose"). | | `repo` | no | string or null | Repository/workspace key, as `session_list`'s `repo` and `session_carry_forward` take
it (e.g. `unfoundbox/agentworth`). Defaults to the key derived from `workspace`. | | `workspace` | no | string or null | Directory to read the checkout from and to derive `repo` from when `repo` is absent.
Defaults to the server's working directory. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "include_raw": { "default": false, "description": "Return unredacted paths, commands and quoted sentences. Defaults to false -- redacted\nis the default for every tool that can carry event or file content\n(docs/specs/mcp-server.md, \"What it must not expose\").", "type": "boolean" }, "repo": { "description": "Repository/workspace key, as `session_list`'s `repo` and `session_carry_forward` take\nit (e.g. `unfoundbox/agentworth`). Defaults to the key derived from `workspace`.", "type": [ "string", "null" ] }, "workspace": { "description": "Directory to read the checkout from and to derive `repo` from when `repo` is absent.\nDefaults to the server's working directory.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `stats_ladder` The evidence ladder over a window, in three blocks: how many sessions reached each rung (rung 0 is unflown -- no outcome evidence at all, which is not a failure) with the API-equivalent spend that sits below the evidence line; what a verified outcome costs per model, repo, adapter or effort; and the newest sessions that got past the line. A group under the sample floor returns rate: null and cost_per_verified_usd: null rather than a number nothing supports. Every dollar is API-equivalent at list prices (cost_basis says so), never what the account was billed. Reads the index only -- no transcript is reparsed. See docs/specs/archie-bench.md. | Param | Required | Type | Description | |---|---|---|---| | `adapter` | no | string or null | Exact adapter name (`claude_code`, `codex`, `opencode`, ...). | | `by` | no | object | Axis for the cost-per-verified-outcome table. Defaults to `model`. | | `include_stubs` | no | boolean or null | Include near-empty session stubs in the population. Defaults to false. | | `min_n` | no | integer or null | A group with fewer than this many claimed sessions returns a null rate and a null
cost rather than a number nothing supports. Defaults to 20. | | `model` | no | string or null | Model substring (`sonnet`, `gpt-4o`, ...). | | `period` | no | string or null | Lookback window: `day`, `week`, `month`, `year` or `all`. Defaults to `month`
(30 days). This is how far back the window reaches, not a rollup granularity. | | `repo` | no | string or null | Repository or workspace substring, as `session_list`'s `repo` reports it. |
JSON schema ```json { "$defs": { "LadderGroupByParam": { "description": "Mirrors `agentworth_storage::LadderGroupBy` with the same snake_case wire values -- a\nlocal copy for the same reason `OutcomeRateGroupByParam` is one.", "oneOf": [ { "enum": [ "model", "repo", "adapter" ], "type": "string" }, { "const": "effort", "description": "Only Codex records an effort today; sessions without one are counted and named, not\ngiven a made-up value.", "type": "string" } ] } }, "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "adapter": { "description": "Exact adapter name (`claude_code`, `codex`, `opencode`, ...).", "type": [ "string", "null" ] }, "by": { "$ref": "#/$defs/LadderGroupByParam", "description": "Axis for the cost-per-verified-outcome table. Defaults to `model`." }, "include_stubs": { "default": null, "description": "Include near-empty session stubs in the population. Defaults to false.", "type": [ "boolean", "null" ] }, "min_n": { "description": "A group with fewer than this many claimed sessions returns a null rate and a null\ncost rather than a number nothing supports. Defaults to 20.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "model": { "description": "Model substring (`sonnet`, `gpt-4o`, ...).", "type": [ "string", "null" ] }, "period": { "description": "Lookback window: `day`, `week`, `month`, `year` or `all`. Defaults to `month`\n(30 days). This is how far back the window reaches, not a rollup granularity.", "type": [ "string", "null" ] }, "repo": { "description": "Repository or workspace substring, as `session_list`'s `repo` reports it.", "type": [ "string", "null" ] } }, "type": "object" } ```
#### `stats_outcomes` Verified-outcome rate by model, adapter, or repo: of the sessions that claimed done, what share left evidence (a passed test/build or stronger), with the sample size next to every row. Groups under min_n (default 20) are suppressed and counted in suppressed_groups rather than shown; a group with sessions but zero detected outcomes comes back as rate: null with reason: "no_outcome_detection" instead of being suppressed -- those are different claims. Includes a receipt (db_path, counted_at, index_last_session_at, the non-stub predicate, and the session IDs behind each row) so the answer is checkable. | Param | Required | Type | Description | |---|---|---|---| | `group_by` | yes | object | - | | `include_stubs` | no | boolean or null | Include near-empty session stubs in the population. Defaults to false. | | `min_n` | no | integer or null | Groups with fewer than this many claimed sessions are suppressed (counted in
`suppressed_groups`) rather than returned as a row. Defaults to 20. | | `since` | no | string or null | RFC 3339 timestamp; only sessions started at or after this instant. | | `until` | no | string or null | RFC 3339 timestamp; only sessions started at or before this instant. |
JSON schema ```json { "$defs": { "OutcomeRateGroupByParam": { "description": "Mirrors `agentworth_storage::OutcomeRateGroupBy` with the same snake_case wire values -- a\nlocal copy for the same reason `SessionsOrderBy` is one (see its doc comment above).", "enum": [ "model", "adapter", "repo" ], "type": "string" } }, "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "group_by": { "$ref": "#/$defs/OutcomeRateGroupByParam" }, "include_stubs": { "default": null, "description": "Include near-empty session stubs in the population. Defaults to false.", "type": [ "boolean", "null" ] }, "min_n": { "description": "Groups with fewer than this many claimed sessions are suppressed (counted in\n`suppressed_groups`) rather than returned as a row. Defaults to 20.", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "since": { "description": "RFC 3339 timestamp; only sessions started at or after this instant.", "type": [ "string", "null" ] }, "until": { "description": "RFC 3339 timestamp; only sessions started at or before this instant.", "type": [ "string", "null" ] } }, "required": [ "group_by" ], "type": "object" } ```
#### `stats_usage` Daily, weekly, or monthly usage rollups: session counts, token breakdown, estimated cost, and cache hit ratio, grouped by adapter -- the same rollups /api/usage returns for one period at a time. Every estimated_cost_usd is an API list-price equivalent, not what the account actually paid -- see cost_basis/subscription_tier. | Param | Required | Type | Description | |---|---|---|---| | `limit` | no | integer or null | Row cap; defaults match the HTTP route's own per-period defaults (30 / 20 / 12). | | `period` | yes | object | - |
JSON schema ```json { "$defs": { "UsagePeriodParam": { "description": "Rollup period for the `stats_usage` tool, mirroring `Storage::get_daily_usage` /\n`get_weekly_usage` / `get_monthly_usage`.", "enum": [ "day", "week", "month" ], "type": "string" } }, "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "limit": { "description": "Row cap; defaults match the HTTP route's own per-period defaults (30 / 20 / 12).", "format": "uint", "minimum": 0, "type": [ "integer", "null" ] }, "period": { "$ref": "#/$defs/UsagePeriodParam" } }, "required": [ "period" ], "type": "object" } ```
#### `window_show` Rolling burn-rate window (default 5 hours): tokens/hour, active adapters and models, estimated cost, and cache hit ratio -- the same window /api/pacing computes. Answers "what am I burning right now". | Param | Required | Type | Description | |---|---|---|---| | `hours` | no | integer or null | Rolling window size in hours; defaults to 5. |
JSON schema ```json { "$schema": "https://json-schema.org/draft/2020-12/schema", "properties": { "hours": { "description": "Rolling window size in hours; defaults to 5.", "format": "int64", "type": [ "integer", "null" ] } }, "type": "object" } ```
## Blog posts ### Why nobody hands an agent its receipts https://agentworth.dev/blog/why-nobody-hands-an-agent-its-receipts/ — September 7, 2026 — 2 min read Every coding harness can resume a session. We read their docs to see what an agent actually gets back, and found two answers, both without evidence. That gap is why session_wake exists. Every coding harness can resume a session. We read the official docs on 2026-09-12 to find out what the agent gets back when it does. Two answers came up, and neither carries evidence. Two ways to resume Harness What the agent receives Checkout, tests, promises Claude Code The full transcript by default, or -- past a size and idle threshold -- a choice: reload it as-is, or run /compact and carry forward a summary plus up to five recently read files The git branch loads as its own block in the system prompt. Test results and open promises: not a field Gemini CLI The full conversation, every tool call and output. Checkpointing reverts files to a git snapshot The snapshot restores files; it does not report what passed Codex CLI codex resume reopens a recent chat from the current repo, or searches across local chats The docs do not say Cursor "Load prior context" via --resume [thread id] The docs do not say OpenCode --continue, --session, --fork The docs do not say Sources, all fetched 2026-09-12: Claude Code: sessions, context window Gemini CLI: session management, checkpointing Codex CLI, Cursor CLI, OpenCode CLI Amp and Aider are not in the table: we did not read their own pages, and a search snippet is not a receipt. So you get one of two things: the whole transcript again, at the price of the whole context, or a summary a model wrote. Claude Code's docs say what the summary keeps: intent, files, errors, pending tasks. They also say what it drops: "full tool outputs and intermediate reasoning are gone." The exit code of the last test run is a tool output. The line where the agent promised to re-run it is intermediate reasoning. Those are the two things a waking agent needs, and they are the two things the summary cannot keep. What resume restores, and what it never reads Every harness above restores state: the conversation, the files, the branch. None of them reads its own transcript as evidence. The transcript holds the command, the is_error flag on its result, the edit to each file, and the sentence that said "I'll do that next", each with a position. A resume feature replays those to the model. It does not answer from them. That is the gap. As of their own docs on that date, nobody fills it. Why we built it from the index AgentWorth already indexes every session on the machine, across harnesses, receipts intact. So session_wake does not summarise anything. It reads the newest session for the repo back from its transcript and reports the last test that passed, the last that failed and whether anything re-ran it, the promises with no later evidence, and the checkout as it is right now, each line with the sequence number to go and check. Under 30 lines, no model in the loop, and a fact the index does not hold is named as a gap rather than written around. A summary is what a model believes happened. A receipt is what the transcript says happened. An agent waking up cold should be handed the second. npx -y agentworth@latest scan --- ### The Cross-Domain Map https://agentworth.dev/blog/the-cross-domain-map/ — September 7, 2026 — 4 min read A thesis about three tools that each write down what happened but share no field to join on, and the return path we built for Archie so it can finally ask "this task, on that machine, produced this output." Three tools. Three records. No shared field. That is the whole first plate of the Cross-Domain Map, a thesis written about these three tools, and it names the gap we spent the last stretch of work closing. AgentWorth answers "which model, and how hard?" SpacePilot answers "where does it run, and what's the real cost?" MotionVector answers "what's allowed to change the document?" Each already writes its own record. The thesis's diagnosis: "The missing piece is not the record. It is that the three records share no field. Each was designed on its own and each is good. But you cannot ask 'this task, on that machine, produced this output' — because no two of them name the same thing." (Plate I, page 1) Plate IThree tools, three good records, no field that joins them. The body already solved this Plate II says why the analogy is allowed: "Not metaphor — the same engineering problem, solved by a different substrate, under harder constraints, for longer." It maps the tools onto the brain: AgentWorth is the basal ganglia, selecting among competing actions, trained on the gap between expected and verified; SpacePilot is the part that knows what this body can actually do; the return path is observation, and without it you have a projectile, not a controller. Plate IIThe body already solved this: each tool sits on the part of the nervous system that does its job. Efference copy Plate III is the one that gave us the mechanism, not just the diagnosis: "Send the command and a copy of what you predict it will feel like. Subtract one from the other. That difference does two jobs at once." (Plate III, page 2) In the body, that copy is the efference copy: the motor command goes to the muscles and, at the same time, to a forward model that predicts the sensation it will cause. In a system, the analogue is a typed operation sent for execution and a support_set of what it should leave true. Plate IIIEfference copy, drawn twice: independently derived, same mechanism, same failure mode. The thesis names the failure when that copy is missing as the same failure in both: "delusion of control: the person can no longer tell their own action from an external one, so their own movements feel authored by someone else. That is exactly what a multi-agent system suffers without support_set — an agent cannot tell whether the state it relied on changed because of its own commit or another's." (Plate III, page 2) An agent that can't tell its own edit from another's can't trust anything it reads back — it re-verifies what it already knows, or trusts what already moved. What we built The spec calls this Loop. It reuses the harness's own hooks as the efference copy and reafference the thesis describes, rather than inventing a new channel: Hook What it carries PreToolUse the copy of the command: tool, input, the paths Archie predicts it will touch PostToolUse the reafference: what came back Stop the compare — git status and HEAD against every path this session predicted since its last Stop Read (support_set) the paths this session actually read, hashed drift (session_drift) which of those hashes changed, and which session's Stop moved them A changed path nobody in the session predicted is what the spec calls exafference: the world moved on its own. Archie names the session that predicted it, if one did, or says plainly that no agent on the machine claimed it — the spec's own term, not the thesis's plate. Full detail is in docs/specs/loop.md. The shared field Archie doesn't ask any of the three tools to change first. run_id, SpacePilot's own join key, is minted by the thing that runs and lands in the tool result an agent already sees — Archie just indexes it. Where a record has no id, like MotionVector's Receipt v1, Archie anchors on its sha256 instead, and the machine fingerprint is the same host_fingerprint algorithm SpacePilot already uses. No product had to change first, because the transcript was already carrying the field — nobody had indexed it yet. We've been saying it to ourselves more plainly than that: this is Archie getting a soul and a heartbeat. What stays true Loop changes what Archie sees, not what it does with it. It still never uploads anything, still works fully offline through the spool, still never calls a model, and the hook can never block or fail the agent it's watching — async: true, exit 0, always. Turn it on with archie hook print claude, paste the output into your hooks config, and restart. Archie starts seeing commands as they run instead of reading them off the tape afterward. npx -y agentworth@latest scan --- ### What was I doing? https://agentworth.dev/blog/what-was-i-doing/ — September 6, 2026 — 3 min read A coding agent that starts cold, or comes back from a compaction, burns thousands of tokens re-reading its own past. session_wake answers the four questions it is really asking in under 30 lines, from the local index, with no model in the loop. An agent that wakes up cold has four questions. What was I doing? What state is the checkout in? What passed, and what failed? What is still open? It answers them the slow way: list the directory, grep the transcripts, read whatever handoff markdown the last session left, parse git diff. In our own transcripts that warm-up runs to 15k–30k tokens before the first real edit. Every one of those reads is a fact the index already holds, or a git command that costs nothing. session_wake is one call that answers all four. It ships in v0.1.19 as an MCP tool and as archie session wake on the CLI. What it returns # Wake · unfoundbox/agentworth · 2026-09-05 15:57Z Checkout ~/code/unfoundbox/agentworth · detached HEAD · HEAD 2ca7539 "feat(onboarding): every first-run surface prints the same brand line, a…" · 1 file dirty Index scanned 2026-09-05 15:57Z · source unchanged since scan ## Last session 7f3c9a2e · 2026-09-04 05:32–16:17 · 252.4K tokens · 40 events · 1 compaction **Task** Add a session_wake MCP tool: one call that tells a cold agent what it was doing, under 30 lines, from the index and the… **Last asked** Now rebuild the docs site and push, then open the PR. **Ran in** /Users/x/code/unfoundbox/agentworth/.claude/worktrees/session-wake on claude/session-wake **Outcome** rung 4, commit_observed **Proof** last passed `cargo test -p agentworth-storage` 05:36 · last failed `cd apps/web && npm run build` 15:41, not re-run **Changed** 3 files · Terminal.tsx (1) · lib.rs (1) · provenance.rs (1) **Loose ends** (1) - "I'll fix that next and then push the branch and open the PR." [seq 39] **Said it decided** "I decided to keep the wake renderer in apps/cli beside handoff rather than a new crate." [seq 27] **Forgotten** 1 decision dropped by compaction — `session_forgotten` has them ## Next Blocker `cd apps/web && npm run build` failed at 15:41 and was not run again. Next "I'll fix that next and then push the branch and open the PR." [seq 39] Not here: PR and CI state, open decisions. `gh pr list` for the first. --- session 7f3c9a2e-1b4d-4c8e-9a0f-2d6e8b1c3a5f · claude_code · generated 2026-09-05T15:57Z That is the whole answer: 23 lines, about 500 tokens (1,522 characters, 499 by the cl100k tokenizer). The ceiling is 30 lines, enforced by the renderer. Five blocks, each from a different place: Block Where it comes from Checkout git, run read-only in the directory you name, with a five-second deadline Last session the newest session for the repo in the index, re-parsed from its own transcript Proof the last test or build that passed, the last that failed, and whether the failure was ever re-run Loose ends sentences that promised something, with no later evidence it happened Next the failure nobody re-ran, and the newest promise No model writes any of it. Every line is a row, a git read, or a stat call, with the sequence number to go and check. A fact the index does not hold is named in gaps, never padded. Pull request and CI state are not in the index, and the last line says so. How fast Measured on the fixture index with a release build, the whole CLI process including startup: 240–340 ms across ten runs, and about 200 ms with no git checkout to probe. No inference: the cost is a SQLite read, one transcript parse, and a handful of git calls. Two things the build fixed on the way Subagents used to answer for their parent. A subagent transcript starts after the session that spawned it, so it won "newest session" every time. On our own index, 127 of 131 sessions under one repo key were subagents; the old catch-up call returned three of them and never the parent. Wake, carry-forward, and --last now resolve to primary sessions. The adapter was dropping the checkout. Claude Code writes cwd and gitBranch on nearly every record. The adapter parsed past both. They now land in the trace, which is where the "Ran in" line comes from. What's next The repo key is derived two ways: from the directory you are standing in, and from the project slug the harness wrote. For a repo that sits directly under code/ they disagree, and wake finds nothing unless you pass repo by hand. Aligning the two is the next change. npx -y agentworth@latest scan --- ### The effort dial we can't read https://agentworth.dev/blog/the-effort-dial-we-cant-read/ — September 2, 2026 — 6 min read A developer report calls reasoning effort a behavioral control, not a percentage of the model. We checked the load-bearing claims against Anthropic's and OpenAI's own docs, then asked what AgentWorth can actually see about it in your transcripts today. Every major coding model now takes an effort setting: low, medium, high, and usually more. It changes how much work the model puts into a response. It does not change how much of the model you get. That second sentence is the whole idea, and it is easy to get backwards. Low effort is not "20% of the network." High is not "80% capable." Anthropic says so directly: "Effort is a behavioral signal, not a strict token budget." (Effort) Think of it as a dial on willingness to spend inference-time compute, not a dial on intelligence. ConceptModel, effort, and harness are three independent variables. Changing one doesn't move the others. What we checked A report someone shared with us — produced with GPT — makes that same argument at length, with diagrams and a five-level Anthropic ladder and a comparison of who documents effort better. Per our own rule for anything that can drift, we did not take its claims at face value. We read it in full, then verified the three claims the rest of it leans on against the primary docs. Anthropic's effort parameter has five levels, and high is the default. Confirmed directly on the current docs page: Level What it does low Most efficient; real capability reduction medium Moderate token savings high Default — same as omitting the parameter xhigh Long-horizon agentic work, token budgets in the millions max No constraint on token spending Source: Effort — Claude API docs. Not every model supports xhigh; some only go up to max. VerifiedAnthropic's five effort levels. Leave the parameter out and you get high. Effort changes tool-use behavior, not just hidden thinking. The same docs page states it plainly: lower effort means Claude "combines multiple operations into fewer tool calls," "makes fewer tool calls," and "proceed[s] directly to action without preamble." Higher effort means more calls, a stated plan before acting, and fuller summaries afterward. This is a real finding worth knowing if you've ever wondered why a low-effort agent run looks terser end to end, not just in its answer. OpenAI's current flagship, GPT-5.6, takes the same six-name ladder: none, low, medium, high, xhigh, max, as separate model variants (-sol, -terra, -luna) trade off capability for cost. Source: OpenAI's model guidance docs. OpenAI also keeps reasoning effort and answer verbosity as two separate controls — you can ask for deep reasoning and a short answer. Source: OpenAI's reasoning guide. VerifiedReasoning effort and answer verbosity are separate dials on OpenAI's API — you can turn one up without turning the other up too. What we left out: the report's claim that Anthropic explains effort's meaning more clearly while OpenAI exposes more knobs and telemetry. That's a judgment call about two documentation styles, not a measurement, and we're not going to launder someone else's opinion as a finding. Its "12 mediocre iterations vs. 4 better iterations" cost chart is also labeled illustrative in the report itself — we're repeating that label, not the bar heights. Illustrative, not measuredThe report's structural point — weak first-pass reasoning can add retries that cost more than the extra reasoning would have — shown as shape, not data. Neither we nor the report have numbers behind these bar lengths. What AgentWorth can see about this today Here's the part that matters for us specifically: can we tell, from a transcript on your machine, what effort level a session actually ran at? Not for Claude Code. We parsed 190,573 records across 618 local session files, and Claude Code never writes an effort field to disk — only the harness that set it would know, and Claude Code doesn't log its own request config. What Claude Code does write for a thinking-enabled turn is a thinking content block, and that block is a summary, not the reasoning itself: "No display setting returns the raw chain of thought," and summarization "is processed by a different model" than the one that did the thinking. Source: Thinking — Claude API docs. So even where we can see that a model thought, we can't see how hard. Codex is different. Its turn_context record carries effort on every turn, alongside model, approval_policy, and sandbox_policy — per-turn harness configuration that Claude Code simply does not write. That's a measured fact from parsing real session files, documented in docs/research/traces-and-open-models.md. Harness Effort on disk? Claude Code No — not logged at all Codex CLI Yes — turn_context.effort, every turn MeasuredParsed from 190,573 records across 618 local session files: Codex writes effort on every turn; Claude Code's records never carry it. So if you want to correlate effort level with outcome rate, that analysis is available today for Codex sessions and not for Claude Code ones. We're not going to claim otherwise, and we're not going to infer an effort level from output length or tone — that's a guess wearing a measurement's clothes. What this means day to day We can't tell you the one right effort level, because the data we can actually see doesn't support that sentence. What the verified claims above do support: effort is worth setting on purpose rather than leaving on default, because it changes real behavior — tool-call count, preamble, summary length — not just an invisible thinking budget. If you're on Claude Code, you're flying blind on which level you actually used unless you set it yourself and remember; if you're on Codex, that number is sitting in your session files right now. Everything past that — which level is "right" for which task — is a claim about your own repo and your own evals, not something a report, or we, can hand you. This draws on a report produced with GPT; we verified the claims we repeat here against the primary sources linked above. npx -y agentworth scan ## Changelog ### 0.1.30 — 2026-10-21 Added: Work Receipt v1 format and signing. New agentworth_schema::work_receipt types for an in-toto Statement v1 with predicate https://agentworth.dev/work-receipt/v1, canonical JSON, receipt_id, the 64 KiB cap, and session refs. New crates/attest crate for ed25519 DSSE signing and verification and OpenSSH key encoding; the crypto dependency stays out of the scanner and adapter crates. The JSON Schema is served at agentworth.dev/schemas/work-receipt/v1.json. Evidence slice 1, PR 1 of 4. archie repo receipt create, show, key, and init. create builds a Work Receipt for the commits in a range (default: upstream merge-base to HEAD), attributes sessions through anchored blame, runs the publication redactor over every string leaf and fails closed on a leak, signs with a local ed25519 key (~/.agentworth/keys/receipt_ed25519, override with AGENTWORTH_RECEIPT_KEY), and writes it as a git note on refs/notes/agentworth (or --transport file for .agentworth/receipts/.dsse.json). Nothing is signed or written until the repo is consented with repo receipt init --write, which creates the key, records consent in ~/.agentworth/config.toml, and adds the CI workflow; without consent create prints a preview only. show maps the session refs in a commit's receipts back to local sessions. key --github prints the gh ssh-key add --type signing line that registers the key. Spend is omitted unless --include-spend is passed. Evidence slice 1, PR 2 of 4. pre-push hook publishes receipts. The hook printed by archie repo suspect --hook (and written by repo receipt init --write) now runs archie repo receipt create --push --quiet. It never blocks a push: a missing binary, missing key, or rejected notes push prints one line and exits 0. A notes push that is rejected is merged with cat_sort_uniq and retried once. repo_receipt MCP tool. Read-only preview of the receipt create would produce for a range: sessions, rungs, what a reader would learn, and the predicted attested/claimed result. It never signs, writes, or pushes. Work Receipt verifier and check renderer. New agentworth_cli::commands::receipt_verify verifies every receipt for a PR range offline (git notes under refs/notes/agentworth, committed .agentworth/receipts/*.dsse.json, or explicit files), classifies each signature as signed by a linked GitHub key, key not linked, or invalid, and re-derives the rungs CI can see: commit in PR (4), claimed files against the commit's own diff (2), and head CI from a ci.json file (5). Rung 3 is only ever "attested locally"; rung 1 is never evidence. Conclusion is neutral by default, success only when every commit carries a receipt signed by a linked key and head CI is green, and failure only through opt-in fail-on. Renders the AgentWorth / Evidence check as markdown or as a check-run JSON body. No network code. Evidence slice 1, PR 3 of 4. archie repo receipt verify. The verifier is now on the CLI: --base, --head, --ci ci.json, --keys keys.json, --receipt FILE, --fail-on, --format md|check-json. The conclusion is in the output, never in the exit status. AgentWorth Evidence GitHub Action. action.yml at the repository root (uses: unfoundbox-crew/agentworth@v0 once tagged). It installs archie from the release tarball and verifies its .sha256, fetches refs/notes/agentworth from the head repository, waits up to wait-for-ci for the other checks on the head commit (ignoring its own), collects the authors' GitHub signing keys, runs repo receipt verify, and posts the AgentWorth / Evidence check run. Fork pull requests with a read-only token get the table in the job summary and a notice; a workflow_run mode puts the check on forks. Never pull_request_target, never code from the PR, and the step always exits 0. Inputs: wait-for-ci, fail-on, transport, archie-version, archie-path, github-token. Evidence slice 1, PR 4 of 4. Dogfood. .github/workflows/agentworth-evidence.yml runs the Action from this checkout (uses: ./, archie built from the same commit) on every AgentWorth pull request, with GITHUB_TOKEN only. Release moves the v0 Action tag to each stable release once a person has created it; the first v0 is created by hand with the Marketplace listing. Docs. README "Evidence Check for Pull Requests" section, docs/specs/evidence-check.md, learn page "The evidence check", the L2 amendment in docs/specs/extensions.md, and the demo tape docs/dogfood/evidence-demo.tape (not yet recorded). ### 0.1.29 — 2026-10-08 Added: Home deck P3 parity. Overview, Coverage, Archaeology, Exports, and the command palette now work inside the archive phase (#218, #219). The legacy dashboard remains available; the serve root stays unchanged. Live Tail in both explorers. The dashboard and home archive subscribe to /api/live-tail for session updates (#213, #222). Codex human turns. archie scan ingests ~/.codex/history.jsonl into derived human-turn features for insights heatmaps, friction, and vocabulary (#224). Raw prompts remain in the source file. Codex rollouts continue through the session adapter. Changed: Shared shell components. Both explorers use shared cache-cliff, export, verdict, and fleet components instead of separate copies (#223, #225). Insights field honesty (schema_version 2 → 3). /api/insights volume / by_adapter / calls_per_turn_by_adapter / top_sessions fields that summed sessions.user_messages_count were named like the human_turns table (human_turns_index_proxy, human_turns). They are now session_user_messages / user_messages. Deprecated aliases with the old names are still emitted for one tip cycle. Real human-turn counts live in day_hour / friction / vocabulary (from the human_turns table). Coverage matrix: Detected ≠ Indexed. The matrix UI column formerly labelled "Sessions" showed detected (on-disk presence) as Yes/No, which looked like indexed coverage. It is now Detected plus an Indexed column for sessions_count (API non-stub). cursor / hermes / grok / herdr often show Detected Yes with Indexed 0 — discovery only. Fixed: Explicit scan paths leave global human-turn history untouched. A small scan PATH previously also read Claude, Codex, and Antigravity turn histories from the machine's home directory. Scoped scans now scan sessions at the supplied paths and preserve existing global turn rows and their ingestion version, including with --force. Run scan without paths to refresh the global insights turn lane. Wake after the repository rename. unfoundbox-crew/agentworth now maps to the historical repository key so wake finds existing sessions (#227). Collapsed dashboard rail. The session-list restore control stays visible when the rail is collapsed (#210). ### 0.1.28 — 2026-09-30 Added: Insights as a first-class lane. Core query windows/deltas, MCP tools, deck insights dashboard, slice-and-drill filters, turn-link repair, and human-turn ingest fill the insights payload that 0.1.27 did not ship. The insights payload's human-turn blocks are real data. archie scan ingests the human-at-the-keyboard turn histories no session adapter owns — Claude Code's ~/.claude/history.jsonl and per-project transcript user-turns, Antigravity's history.jsonl + brain transcript.jsonl USER_INPUT records — and stores per turn only derived features (timestamp, local hour/date, word count, the six-trigger friction class, bounded vocabulary mention counts). The insights payload's day_hour heatmap, friction by-trigger counts and vocabulary streams fill from these tables with the same semantics as the tools/behavioral_insights.py prototype, windowed by ?since=&until=, with deltas.friction_rate computed across the requested window. Nothing raw is stored (the dedup key is a hash of timestamp + first 60 chars), unchanged files skip re-parsing by the same (size, mtime, fingerprint) rule sessions use, and a taxonomy version bump wipes and re-ingests every turn so an indexed answer is never staleness-served. Pre-lane payloads keep the three dimensions in deferred with the run-agentworth scan reason; after a real ingest they leave the list and a zero means a quiet window. archie scan's summary reports human turns indexed (inserted + deduplicated), and archie insights prints the three turn blocks' headline numbers. Home / app-merge deck. Path deep links for /insights and /s/, archive phase (SessionList + InspectorPane), and the restored dashboard surface after the #182 revert path. Codex adapter depth + parser v4. Prompts, tool calls, shell outcome ladder; discovery rejects non-session files and prunes stale rows; parser-version guards at 4. Repo-key wake canonicalization. crew/agentworth aliases to unfoundbox/agentworth so wake finds the right sessions across rename paths. Agy token accounting. Antigravity gen_metadata usage varints land in the token counters where the store actually carries them. Fixed: Turn rows survive a merge. human_turns is registered in SESSION_CHILD_TABLES with its vocab_json inside the row, so archie merge carries a merged session's turnaround facts and the insights vocabulary block keeps working without a second table keyed by a volatile rowid. Antigravity CLI sessions carry their models, and the harness can wake them. The agy conversation store records the model that generated each step in field 19 of its gen_metadata blobs; the adapter read everything else out of that store and never that field, so every antigravity row indexed with models_used: [] while claude_code and codex rows carried theirs. The adapter now reads it (parser version 3). Later tip work also reads gen_metadata usage varints into token counters where the store actually carries them (see Added above). archie session wake --inject antigravity turns an agy PreInvocation hook payload into the injectSteps wake envelope, and archie hook print antigravity prints the ~/.gemini/config/hooks.json entry that points at it. Because agy exposes no SessionStart hook, an on-disk marker makes the per-invocation PreInvocation fire the wake document exactly once per conversation; see apps/cli/src/antigravity_hook.rs. Wake resumes the worktree you are standing in, not the newest session for the repo. extract_repository_or_workspace prunes the --claude-worktrees- suffix of a Claude Code project slug on purpose, which is right for carry-forward but meant that with several agents in worktrees under one repository, "newest for repo" woke agent A into whichever worktree ran last. Selection now prefers sessions whose recorded workspace.cwd equals the checkout's git root and falls back to the repo ordering only when none match (Storage::list_sessions_for_repo_preferring_workspace). Claude / Codex discovery scope. Non-session files rejected at discovery; stale rows pruned so the index does not advertise ghosts. ### 0.1.27 — 2026-09-13 Added: Pi adapter reads the documented v3 session format. The parser matched a session shape pi never wrote (task_input/step/observation with prompt_tokens), so every real session file parsed to zero events and zero tokens and the index held no pi rows at all. It now reads ~/.pi/agent/sessions/----/*.jsonl as specified: the session header (authoritative id, start, cwd) selects the identity, message entries become prompt / response (with thinking blocks) / tool-call (name plus arguments) / tool-result / shell-command (with exit codes) events, model_change entries drive model switches so attribution follows the session instead of the settings default, thinking_level_change sets effort, and compaction entries become compaction events. The sessions slug decodes back to the working directory for repo-anchored identities (::pi-repo::, mirroring opencode), falling back to the bare path for container-level checkouts. Measured on one machine: 33 pi sessions in the default list where there were zero, the largest carrying 1,978 events and 91.7M tokens with full cache breakdown. Fixed: session show (and every reparse path) works for synthetic source identities. source_exists checked the identity string as a filesystem path, so any session whose indexed path is a locator (agy ::agy-repo:: rows, same class as opencode's ::opencode-repo:: rows) failed with "Source history ... no longer exists". The gemini adapter now resolves agy locators to their real database file before answering, mirroring opencode.rs. ### 0.1.26 — 2026-09-13 Added: Antigravity CLI (agy) conversation store is indexed. Newer Antigravity builds keep sessions in SQLite (~/.gemini/antigravity-cli/conversations/.db, one DB per conversation) instead of the legacy brain/ JSONL transcripts, and the gemini adapter explicitly skipped those files -- so every agy session was discovered-but-never-indexed. The adapter now enumerates each conversation database under the antigravity identity, joins the conversation_summaries.db index (workspace, liveness, wall-clock end) and the rolling history.jsonl (prompt text with real timestamps), and walks the protobuf steps blobs generically to emit prompt, response, and tool-call events (tool names with their JSON args preserved). The agent persona step is configuration, not history, and is skipped; unmapped step types are warnings, never guesses. Token counters exist nowhere in this store, so agy rows honestly index with zero tokens. Measured on one machine: 461 conversations, 38,322 events, 26,350 tool calls, 391 of them active in the default list. Tokenless sessions with tool calls are no longer stubs. The stub predicate was total_events > 1 AND total_tokens > 0, which hid every agy row (and any future tokenless-but-active session) from the default list, stats, and aggregates despite hundreds of corroborated tool calls. It is now total_events > 1 AND (total_tokens > 0 OR tool_calls_count > 0). Sessions with neither tokens nor tool calls are still stubs; the kind term, the audit/autopsy include_stubs paths, and fleet-snapshot handling are unchanged. Fixed: session show (and every reparse path) works for synthetic source identities. source_exists checked the identity string as a filesystem path, so any session whose indexed path is a locator (agy ::agy-repo:: rows, same class as opencode's ::opencode-repo:: rows) failed with "Source history ... no longer exists". The gemini adapter now resolves agy locators to their real database file before answering, mirroring opencode.rs. ### 0.1.25 — 2026-09-12 Fixed: The npm launcher no longer leaves a broken binary behind after a slow or truncated download, and no longer lets concurrent first runs race into the same version directory. On a slow connection, tar could extract a partial archive before the download finished, leaving an unsigned, non-executable binary that every later invocation ran into exit 137 with no explanation; three invocations starting close together also wrote into the same cache directory at once, since nothing serialized them. The launcher now downloads to a .part file, verifies it against the release's published .sha256 before extraction, extracts into a temp directory and only renames it into place once all three native binaries are present and executable, and takes a lock per version directory so concurrent callers share one download instead of racing. agentworth hook -- which runs on every tool call in some setups -- never starts a download itself; it resolves only from a binary that's already present and fails fast and quietly otherwise, which is what turned a single truncated download into 1,000+ concurrent ones on the reporter's machine. (#173, #174) ### 0.1.24 — 2026-09-12 Added: AgentWorth is a Claude Code plugin. The repo carries .claude-plugin/plugin.json and is its own marketplace (.claude-plugin/marketplace.json), so /plugin marketplace add unfoundbox-crew/agentworth then /plugin install agentworth@agentworth gives Claude Code the 13 read-only MCP tools (over npx -y agentworth@ mcp) and the agentworth skill in one step, with no claude mcp add and no npx skills add. The skill moved to skills/agentworth/SKILL.md, which is where the plugin loader looks; the root SKILL.md is a symlink to it so npx skills add keeps working. claude plugin validate . --strict passes. The release version gate now checks the plugin manifest's version and its pinned npx package version too. (#133) AgentWorth is a DeepSeek Harness plugin. packages/dsh-plugin-agentworth is a dsh bundle (npm dsh-plugin-agentworth): one cordis.patch.yml row mounts the MCP server through @deepseek-ai/dsh-mcp-client as mcp__agentworth__, and the package's own plugin registers the agentworth skill from a bundled copy of SKILL.md through ctx.skills.register(), so nothing has to exist on disk beyond the package. dsh plugin --profile add dsh-plugin-agentworth installs it. The bundled SKILL.md is test-checked byte for byte against skills/agentworth/SKILL.md, the release version gate checks the package version and its npx pin, and the release workflow publishes it beside agentworth. (#134) Cursor and VS Code AI SQLite state.vscdb extraction. Cursor, Trae, and other VS Code AI derivatives store their actual conversation turns and composer sessions inside SQLite databases (state.vscdb) under workspaceStorage and globalStorage. The Cursor adapter now automatically parses composer.composerData, workbench.panel.aichat.chatdata, and aiService.prompts from ItemTable, extracting turns, prompts, model identifiers, token usage, and file diffs with cross-platform path resolution for macOS (Library/Application Support), Linux (.config), and Windows (AppData/Roaming). PARSER_VERSION bumped to 2 for the Cursor adapter, so an incremental scan reparses already-indexed sessions instead of serving stale output. (#167) docs/specs/memory.md. Typed facts with receipts, bi-temporal supersession, and pull hydration -- the spec for what a session remembers across restarts and why markdown alone is not the tax (542 vs 1,552 tokens, measured). (#162) A blog post: why nobody hands an agent its receipts. What five harnesses' own docs say an agent gets back on resume, read against what they actually restore. (#138) Changed: The landing page sells the product; benchmarks moved to docs. The homepage read like a lab manual -- two readers said so. Marketing copy stays on the landing page, the measurement tables move to docs/. (#135) The spec index and capability matrix, re-measured 2026-09-12. The spec index had drifted from each spec's own status header (suspect-commits.md listed proposed when built, four specs had no row at all); rewrote it from each spec's own first-15-lines status. The capability matrix numbers are re-measured against the live SQLite index rather than a 2026-09-02 snapshot: total sessions 10,329 -> 6,054, Codex tokens 1 -> 745 of 972, prompt_preview no longer zero across the board, and a new compaction_count column. Two sections that can't be reproduced from SQL/archie alone stay marked NOT RE-MEASURED. (#168) Roadmap updated after v0.1.23, and AGENTS.md item 8 now says fastembed is off by default in every shipped binary (default = [] in Cargo.toml) -- correcting an earlier claim that overstated it. (#170) Fixed: The MCP server now introduces itself as agentworth with its own version, not as rmcp 3.2.0. Implementation::from_build_env() reads the crate name at rmcp's build, not ours, so every client saw the SDK's name in serverInfo. The embedding-model download now announces itself instead of failing silently. LocalEmbedder::new() called fastembed with with_show_download_progress(false) and no announcement, so a binary built with the fastembed feature (off in shipped binaries today) fetched a model with no explanation -- an air-gapped user just saw a failure. embedder.rs now prints a warn!-level line before the model load naming the model, source, rough size, that it is a one-time dependency fetch (like npm install), and that no local data is sent. README.md, docs/TRENDSHIFT.md, docs/ARCHITECTURE.md, and the web app's ArchiePage.tsx no longer overstate "100% offline" / "zero network calls" -- they name the two real exceptions instead. (#169) ### 0.1.23 — 2026-09-10 Added: cost_weighted_tokens beside total_tokens. total_tokens adds cache_read_tokens at face value, so on a long session it measures how large the context grew rather than what the session spent -- 98.7% of the transcript below was cache reads of a prompt already paid for. total_tokens keeps that meaning for compatibility; the four counters are now exposed separately everywhere, alongside input + output + 1.25 x cache_creation + 0.1 x cache_read (Anthropic's published prompt-caching multipliers, verified 2026-09-10 -- not dollars, and not exact for a 1-hour cache write; a comparable weight for ranking sessions). Surfaced in session_list, session_show, /api/traces, stats_usage (new CACHE WR and WEIGHTED columns, width-gated so the 80-column table is byte-for-byte unchanged) and stats_ladder. docs/specs/token-accounting.md -- the measurement table, the ledger's contract, why Codex is excluded, and what cost_weighted_tokens deliberately is not. Redactor::for_publication() -- the default rules plus path-tail and forge-repo stripping, for the one path where text leaves the machine. Additive and opt-in: Redactor::new() is unchanged, because repo_blame and session_show exist to tell you which repo a session touched. It raises the floor rather than making a payload provably clean -- a project name inside a relative path still survives, and the test suite asserts that limit rather than claiming otherwise. The dashboard shows weighted tokens beside raw ones, flags cache-inflated sessions, and can sort by weighted spend. UsagePeriodSummary and ModelUsagePeriodSummary gained cost_weighted_tokens server-side so no client re-derives the multipliers. archie policy init [--repo] [--force]. Writes a starter policy.toml with the thrash and loop rules on, and a [spend] block left commented out, carrying this machine's own primary-session token percentiles (p50/p90/p99/max) as comments — read from the index with the new Storage::session_token_percentiles. archie policy check warns on a spend cap below your own p99. Names the cap, the machine's (or repo's) p99, and how many already-indexed sessions would have tripped it. Still exits 0 — a warning, not an error. Sessions have a kind: conversation or fleet_snapshot. One column, one migration (every existing row is a conversation). The stub predicates (total_events > 1 AND total_tokens > 0, and the scanner's near-empty rule) apply to conversations only; a snapshot is outside that population, hidden from the default session list, stats and the session aggregate, and shown whole by session list --kind fleet_snapshot or --adapter . Adapters declare it through AgentAdapter::trace_kind. --all-stubs and the include-stubs aggregate relax only the events/tokens bar, never the kind, so neither surfaces a snapshot; the raw "rows in the SQLite index" count behind archie scan's Total Indexed line and archie doctor moved to Storage::total_row_count, which counts every row (snapshots included) and can exceed the conversation aggregate. identity_sightings: names are display, the harness session id is the key. A pane label, a Herdr agent name, a session title can all be renamed. Every trace can carry identities (session id, name, time seen, via), stored append-only keyed on (session, name, via): a rename adds a row, never rewrites one. Storage::identity_sightings(session_id) reads them back. Written by the Herdr adapter today; the field is open to any adapter, and Claude Code session titles do not land there yet. Changed: PARSER_VERSION bumps: Claude Code 2 to 3, Gemini 1 to 2, OpenCode 1 to 2. An incremental scan reparses these sessions even though their bytes never changed. An existing index keeps its inflated token totals until archie scan runs. The [spend] example in crates/loop/src/policy.rs's doc comment dropped its token number — [spend] now ships commented out, pointing at archie policy init. A 20M-token example would have halted this machine's own 728M-token primary sessions dozens of times; the rule stands, the number is now yours to set from your own history. Fixed: A streamed message's tokens are counted once, not once per record. Claude Code writes one assistant message as several JSONL records -- one per content block, apiBlockIndex 0..n -- and every one repeats the same message.usage block verbatim. The parser summed usage per record. On a real 1.08 MB subagent transcript that read 33,777,792 tokens where the true figure is 19,294,496; across a 120-file sample of ~/.claude/projects the machine-wide ratio was 2.194x. Gemini CLI has the same shape keyed on id (1.90x, measured). One shared ledger (crates/adapters/src/usage_ledger.rs) credits each message id at most once, last usage block wins -- only the usage is suppressed, never the record's own content, so a tool call on block 1 is still parsed. Codex is deliberately untouched: its token_count events are cumulative running totals and codex.rs already takes deltas of them. OpenCode's SQLite path gets one row per message from its primary key; its legacy file path now carries the same guard. Gemini CLI sessions no longer index as zero tokens. extract_token_usage knew promptTokenCount-style and OpenAI-style names but not the ones Gemini actually writes -- input / output / cached / thoughts / tool inside a tokens block -- so every Gemini CLI session read as zero despite real usage. thoughts and tool fold into output, matching Gemini's own total. archie session list --json carries the token breakdown. It builds its own JSON and never touched SessionSummary, so the four counters and cost_weighted_tokens never reached it. The maintainer's system username and a third party's project name are out of the public tree. This repo carried one person's real machine layout in 101 places, and -- worse -- a third party's project name in shipped code and user-facing copy: is_leaked_katana_var was a function name and "The Missing local Weapon (The Katana Incident)" printed to anyone who tripped that rule. Now is_leaked_loop_var and "The Missing local Weapon", which describes what the detector actually finds. Product doc comments that addressed the maintainer by name now name the role instead. Fixture paths come from the new agentworth_schema::fixtures rather than literals, so the convenient option is also the safe one. archie blunder shows you the bytes before it posts them. The exhibit printed to your terminal is the local view, with full absolute paths; what a submission POSTs is a redacted payload you never saw. One redacted_payload() now feeds both, so they cannot drift, and --dry-run prints exactly what would be sent and sends nothing. Submission also switched to the new Redactor::for_publication() -- blunder --submit redacts loose strings, so unlike redact_trace it never picked up the per-trace repository_identity_rule, and a captured payload still carried three repositories' names after full default redaction. The Herdr adapter reads the file Herdr actually writes. It used to look for coordination_traces, parent_agent_id and delegation_id, fields no Herdr file has ever carried, so the real ~/.config/herdr/session.json parsed to nothing while five fixture tests stayed green. It now decodes the v3 shape (workspaces[].tabs[].panes{}) as a fleet_snapshot: one herdr.pane event per pane with pane_key (Herdr's internal number), pane_number (what the user sees, from public_pane_numbers), cwd, label, agent name and agent_session.value, the harness session id that is the only key. The live pane id (w9:pA) is a runtime allocation, not in the file, and is never stored. Every label and agent name goes to identity_sightings with the time seen. Scalars decode leniently (a "version": "3" string, a non-numeric active), active_tab and active gate focused so one pane per file is focused, one bad workspace, tab, pane or agent_session costs only itself, unknown fields are ignored and a newer version is a warning. PARSER_VERSION 2. Capabilities report none of the seven. Fixture: a redacted real herdr 0.8.2 file. install.sh runs the binary once and explains a Gatekeeper kill. The macOS binaries are ad-hoc signed and not notarized. A fresh curl | sh install runs (measured on macOS 27: valid signature, no quarantine flag); a copy that carries the flag is killed on exec with nothing but zsh: killed, exit 137 (measured by adding the flag; removing it clears it). The script now removes any existing file before copying (a cp through the npm wrapper's agentworth symlink would have overwritten the wrapper's JavaScript), drops the flag from what it wrote with xattr -dh (act on the file, not a symlink target), runs archie --version, and on exit 137 exactly prints the xattr -d line for the installed files. Other failures are reported as what they are. README carries the note. archie doctor and agent show name Herdr's real directory, ~/.config/herdr/, not ~/.herdr/. ### 0.1.22 — 2026-09-06 Added: The governor. ~/.agentworth/policy.toml (or a repo's own .agentworth/policy.toml) turns on two rules, both blocking, both on by default once the file exists: thrash halt (a file edited N times with no passing verification between edits) and a session spend cap (tokens or dollars at the table price). No file, nothing governed. archie hook --gate is the same hook binary in synchronous mode, one socket round trip, a 50ms budget, and it fails open — archie serve down, or a miss, and the hook exits 0 and writes one spool line rather than blocking the agent. Thrash halt. The batch stops before the next model call (continue: false) with the ground truth attached: the file, the edit count, the last failing command and its last output line, and the sequence numbers. The same text repeats as additionalContext on the next prompt, so the model resumes knowing why it was stopped. Session spend cap. Once a session crosses its policy.toml cap, the batch halts and every prompt after it is blocked with the reason until archie policy lift or a higher cap. archie session burn [id]. Live tokens, dollars, turns, cache-read share, and burn rate per minute for a session, read from the same transcript tail the cap reads. archie policy show|check|lift |replay, governor_events and session_suspensions tables, and turn_usage per turn. session_burn over MCP. Tool count moves from 16 to 17 (27 in tools/list, aliases included). ### 0.1.21 — 2026-09-06 Added: archie hook. A harness (Claude Code today) posts its PreToolUse, PostToolUse, Stop and other lifecycle events as stdin JSON to this command, which forwards one line to archie serve's loopback socket (~/.agentworth/archie.sock) with a 50ms budget. No socket, or serve down: it appends to ~/.agentworth/spool/.jsonl instead. Always exits 0. Never slows the agent, never blocks it, never fails visibly. archie hook print claude prints the settings.json snippet to paste in — it never writes the file for you. archie serve listens on the loop socket. Beside the dashboard and API, archie serve now owns ~/.agentworth/archie.sock and ingests anything sitting in the spool at startup. --no-socket turns the listener off. archie scan also ingests the spool, so the loop works with no server running at all. archie agent status. Live state per session — registered, working, idle, ended — driven by the hook events, not a poll. archie session drift [id] and archie session anchors [id]. drift re-checks the files a session read against what's on disk now and names who changed each one (another session on this machine, or "not an agent on this machine"). anchors lists the join keys a session's tool results carried — run_id, file hashes, pane id — for tying its work to what SpacePilot measured or MotionVector rendered. agent_status and session_drift over MCP. Same two answers, callable mid-session. session_wake gains a "Moved under you" line when the files a session read have changed since it last checked. A machine fingerprint. sessions.host_fingerprint, a salted sha256 truncated to 12 characters — the same algorithm SpacePilot already uses for System.host_fingerprint — so a run on this machine and a run SpacePilot recorded resolve to the same id without either product asking the other. Backs six new tables: machines, agent_state, tool_intents, intent_paths, support_set, trace_anchors, plus host_fingerprint on sessions. machines.system_id stays empty until SpacePilot writes it; nothing here invents a configuration id. ### 0.1.20 — 2026-09-06 Fixed: A grep-for-"test" no longer counts as a passing test. is_verification_command substring-matched the whole command line, so cd repo && /usr/bin/grep -n "test" registered as wake's "last passed" proof. It now splits the command into segments, strips cd, env assignments, sudo, time, nice, flock, and a leading path, and matches the program and its first verb against a small table (cargo test|build|check|..., npm|pnpm|yarn|bun test|run|build|ci, pytest, go build|vet|test, tsc, eslint, vitest, jest, make, mvn, gradle/gradlew, ruff, mypy, docker build, git commit|push, gh pr|run|workflow). session_wake's "Last asked" no longer picks up a harness relay or system notification. A cross-session message or a [SYSTEM NOTIFICATION] line arrives on the same UserMessage role as a real prompt; last_asked now skips those (and compaction continuations) and reports the human's actual last prompt. The checkout line's drift wording read "2 behind of origin/main". Now "N ahead of X", "N behind X" (no stray "of"), or "N ahead, M behind X" when the branch has both. ### 0.1.19 — 2026-09-06 Added: session_wake and archie session wake — one call for a cold or just-compacted agent: the checkout it stands in (branch, HEAD, dirty, ahead), the newest primary session for the repo (task, last prompt, outcome rung, last passed and last failed verification command and whether the failure was re-run, files changed, loose ends, what it said it decided, what compaction dropped), the two sessions before it one line each, and a Next block naming the blocker and the next step. At most 30 lines of markdown, measured at 21 on the fixture; every line is a row, a git read, or a stat call, and a missing fact is named in gaps rather than padded. Redacted by default; include_raw/--redact opts out per call. Never scans (docs/specs/wake.md). Fixed: Subagent transcripts no longer answer for their parent. A subagent starts after the parent it was spawned from, so it used to win "newest session" in session_carry_forward and the no-id default of session_handoff and session_forgotten. All three now resolve to primary sessions only. session_carry_forward gains include_subagents (default false) for the old behaviour, and --last on the CLI resolves the same way. The Claude adapter keeps cwd and gitBranch. Claude Code writes both on nearly every record; the adapter parsed past them. The last non-empty value of each now lands in the trace's workspace.cwd / workspace.git_branch metadata, which session_wake's "Ran in" line reads. cargo install agentworth-cli and brew install .../tap/agentworth are gone from every doc and hint. No such crate was ever published to crates.io (confirmed: the registry returns 404) and no such Homebrew tap exists. Removed from both READMEs, the translated READMEs, the npm package README, SKILL.md, the launcher's missing-binary message, docs/SHOW_HN.md, and the marketing site's getting-started guide. Building from source still works: cargo install --path apps/cli from a checkout. README.md's "100% offline" claim wasn't true, and neither was the same line repeated in docs/SHOW_HN.md: the optional archie session search feature downloads a model on first run. Reworded to local-first / your data never leaves your machine, everywhere it appeared. The MCP setup guide undercounted its own tools by one. It said 12 read-only tools (22 with deprecated aliases); the real count is 13 (23 with aliases) — stats_ladder was missing from the table entirely. Old spellings and MCP aliases now stay until v0.1.20. They were due to go at v0.1.18, but v0.1.16, v0.1.17 and v0.1.18 all shipped inside two days, which gave nobody real time to move off the old names. HIDDEN_ALIASES_REMOVED_IN and the MCP alias descriptions now say v0.1.20; the generated reference (docs/REFERENCE.md, docs/reference.json) and docs/specs/cli-grammar.md match. ### 0.1.18 — 2026-09-03 Changed: update --json's advice values are arrays, not strings. Each channel's advice used to print as one string; it now carries a list of lines, matching how the screen wraps and joins them. A script reading a channel's advice as a single string needs to join the array itself (#129). Fixed: The installer no longer waits on a size probe. install.sh asked GitHub for the asset size with a HEAD request that followed the redirect to the object CDN, with no timeout — on a slow link the download line could sit for tens of seconds, or forever, before it ever appeared. The size now comes from the header dump curl writes while the download streams, so the bar appears at once and fills in the total when the CDN answers. Every request now carries a connect timeout (#128). archie serve prints a screen, not a box. The banner was the last command still drawing its own frame, with a rocket emoji in it and "Explorer Server" for a thing the product calls the dashboard — it was never in the two audit passes. It now renders through the ui module like every other screen: the command and version at column 0, a leaders block for the local URL, the two API routes and the index path with the home directory folded to ~, and a Next line saying how to stop it. Same glyph set, same width clamp, same --plain/--no-color columns. The banner is a function returning a string, so the snapshot sweep holds it to the same four rules without binding a port (#129). archie update names the channel you actually installed from. It could only recognise the npm launcher, and called everything else "unknown" — including a binary from curl -fsSL https://agentworth.dev/install.sh | sh, which is now detected by its install location ($AGENTWORTH_INSTALL_DIR, or ~/.local/bin). The channel this binary came from is listed first and tagged this install; the rest follow under other ways, where before an npm-launched binary was shown npm and nothing else. --json gains a channel field (#129). Every doc says npx -y agentworth@latest. A bare npx agentworth reuses whatever npx already cached, which is how a months-old binary answers for what reads like a fresh install. The npm channel on the update screen prints both npm install -g agentworth@latest and npx -y agentworth@latest, and says why. The release workflow's smoke test still pins an exact version, on purpose (#129). The npm launcher says when it is about to run an older binary than itself. AGENTWORTH_BIN and a vendored binary were the two resolution paths that never checked the version they handed back; they now print one line when the binary is older than the package. It cannot see a stale package from npx's own cache — that is what the @latest change above is for (#129). ### 0.1.17 — 2026-09-03 Added: The cockpit. A bare archie on a terminal opens a full-screen reader over the same data: overview, sessions, one session, agents, repos and windows, with j/k, Enter, /, 1-6, h/a/f/r, ? and q. archie tui is the explicit spelling. Off a terminal, under --plain, under TERM=dumb, or with JSON output, both print the overview — what archie stats prints plus the current window — and exit 0. Read-only, permanently: no writes, no scan, no config changes, no model calls. Every screen is a string a printed command already produces; the cockpit adds a viewport, a cursor and key handling and nothing else. Behaviour change: bare archie used to exit 2 with a usage message; it now exits 0 (#121). Onboarding, one line everywhere. install.sh draws its own download progress — curl's own bars land outside the glyph set, so bytes are read straight from the file it's writing and redrawn in place. The npm launcher and the first archie scan on an empty index now print that same three-line Archie form instead of an emoji or their own text (#123). archie stats ladder — one screen for the question docs/specs/archie-bench.md set out to answer locally: of everything spent in a window, how much of it bought something a test, a commit or a CI run can be pointed at. Three blocks — every rung of the outcome ladder with the spend that sits below the evidence line, what a verified outcome costs by model / repo / adapter / effort, and the newest sessions that got past the line — closing on one sentence with the share of spend that proved nothing. --period, --repo, --adapter, --model, --by, --min-n, --json, and stats_ladder over MCP with the same parameters and the same JSON. Reads the index only; no transcript is reparsed (#124). The bottom row is unflown — no outcome evidence of any kind was found. It is not a failure state and is never danger-coloured; OutcomeKind has no failure value to draw one from. Every screen that draws the ladder now uses that one set of words (unflown, done claimed, artifact changed, test or build passed, commit observed, CI or deployment verified), where stats, session show and repo suspect used to have their own shorter set (#124). The sample floor below which a rate is suppressed now lives in one place, agentworth_storage::OUTCOME_RATE_DEFAULT_MIN_N = 20, read by stats outcomes, the stats_outcomes tool and the new ladder. docs/DESIGN.md's chart rule 3 said 10 and now names that constant, so one product has one floor. Under it, a rate and a cost render blank — never a zero, never a dash pretending to be data (#124). Fixed: The second audit pass. Seven more commands — session autopsy, session recall, session search, session show, config, version, docs — render through the ui module and get a status line on their slow path. session recall no longer reparses a transcript per match; the per-model spend it needs already lives in session_model_usage, written by the same scan that parsed the session. update prints its install link on one full line. The suite now passes on a machine with real session history, not just a fresh one (#122). ### 0.1.16 — 2026-09-02 Added: A grammar instead of a list. Five nouns — session, agent, repo, window, stats — carry everything that acts on indexed data; scan, serve, mcp, doctor, docs, config, version, update, completions and merge stay top-level. Every pre-0.1.16 spelling still runs, hidden from --help, until v0.1.18 (#118). New verbs: archie agent show , archie repo list, archie window list, and archie stats outcomes — the verified-outcome rate, on the CLI at last (#118). archie, the short name, shipped everywhere agwt shipped: a third binary, the npm bin map, install.sh, and the release tarball. agwt keeps working and is out of the docs (#118). Shell completions. archie completions for bash, zsh, fish, powershell and elvish, plus live completion of session ids, repositories and models through COMPLETE= archie. One bounded read on a read-only connection: a missing or locked index offers nothing rather than blocking a Tab (#118). Archie, on four surfaces. A terminal short form on the scan line (three lines, collapsing to (*) archie under 46 columns), a settings picker in the dashboard, a page at agentworth.dev/archie, and a branded 404 — driven by two new config keys (archie.accessory, archie.colourway) read and written through GET/POST /api/config (#114). The M3 redraw. The muzzle folds into one closed head curve instead of a separate shape, and the light moves from a headlamp into a hand-held torch carried in a front paw — sleeping sets it on the ground, error drops it. The terminal form goes to three lines, nine columns (#119). A docs home at /docs/. A card grid over Learn (7 guides), Reference, Specs (24), Research (2) and Changelog, plus a client-side search palette (Cmd/Ctrl-K) over a prebuilt index — no new dependency, no service (#117). Two measured specs: archie-bench, a local leaderboard keyed on model x effort x repo and ranked by verified rate (#112), and convergence, on when a session stops making verified progress — measured over 3,046 real sessions, shipped as a token budget and a coverage warning rather than a stop switch, because the data didn't support one (#113). Changed: blind-spots is now archie session list --unproven — a filter, not a command of its own (#118). Every show-style verb resolves a session identically: unique prefix, --last/--current, the picker on a TTY. An ambiguous prefix exits 2 with the candidates instead of guessing; session cache and session bisect gained all of this (#118). MCP tools renamed to match the CLI (sessions_find → session_list, session_get → session_show, and eight more). Every old name stays registered and reaches the same handler until v0.1.18 (#118). Fixed: The Codex adapter reads the fields Codex rollouts actually carry: model and effort from turn_context, tokens from the cumulative total_token_usage (including a restarted counter), and the real workspace from session_meta.cwd instead of the home directory. PARSER_VERSION 1 → 2, so a normal scan reparses every Codex session once (#116). Model pricing now matches current models. Claude Sonnet 5/Opus 5/Fable 5.x, Sonnet/Opus 4.5-4.8, Haiku 4.5, Gemini 3.x, DeepSeek V4 and GLM 5.x/4.7 were silently priced at the Claude 3.5 Sonnet default rate card; agentworth usage's dollar figures are now right for the models actually in use (#115). The local API's CORS allowed any origin to read a person's whole session history through /api/traces and write their preferences through /api/config. It now passes only a page served from this machine (localhost, 127.0.0.1 or [::1], any port). GET /api/config no longer returns config_path, which named the user's home directory for no reason a browser needed it (#114). ### 0.1.15 — 2026-09-02 Fixed: Fixed: scan panicked on transcripts containing non-ASCII text (a byte-index slice inside recovery detection). Every text truncation now cuts on character boundaries, and a workspace clippy lint denies byte slicing of strings so this class cannot ship again. ### 0.1.14 — 2026-09-02 Added: The handoff, written by the machine. agentworth handoff, agentworth loose-ends, and the MCP tools session_handoff and carry_forward: what a session promised and did not do, what it decided, files touched, commands and how they ended, the outcome rung, compactions. Every line carries a receipt; nothing is summarised (#77). forgotten_context. The decisions compaction dropped, handed back with receipts, plus agentworth forgotten. Measured on one 8-round session: 405 decision sentences in, 28 out (#83). suspect_commits and agentworth suspect --hook: commits whose authoring session had no exit-0 test, a demoted done-claim, or a loop; anchored to the repo so relative blame paths cannot suffix-match every repo on disk (#84). outcome_rate: verified-outcome rate by model, adapter or repo, with an n floor (#75). inspect accepts a session-id prefix; doctor and matrix render in the design system (#76). CI runs tests on ubuntu and macOS, clippy gates, path-aware jobs; the dead GitHub Pages deploy is gone (#79). Fixed: "Tests passed" now means exit 0. The Claude Code adapter never parsed tool results on real transcripts (they nest under message.content), so no exit code ever reached the outcome engine, which granted rung 3 from the command string alone. Exit codes are parsed from is_error and "Exit code N"; a test, build, CI or deploy command with no exit code cannot reach a verified rung. Aider's markdown path no longer hardcodes success (#81, #85). Every real session gets scored; a parser version per adapter triggers a one-time reparse when parsing changes; backfill runs once per version and never loops on sessions with no prompt (#85, #89). stats and usage count the same sessions; usage views apply the non-stub predicate (#78). Live-tail adapter attribution works on macOS (FSEvents reports canonical paths) (#87). The archaeology pane fetches its data (#80). Trace responses gzip and paginate; the inspector streams large sessions (#72, #73). prompt_preview backfills; the matrix derives from the adapter registry (#74). ### 0.1.13 — 2026-09-02 Added: MCP server. agentworth mcp (stdio) exposes the index to any coding agent: sessions_find, session_get, blame_find, usage_summary, pacing_window, coverage_stats. Redaction on by default. Register with claude mcp add agentworth -- agentworth mcp (#56). Per-session compaction tracking in the schema, storage and API, and a compaction pane in the dashboard: rounds, context before and after, what survived, marked on the trajectory (#57, #62). CLI output redesigned. One design system for stats, usage, traces, blame, scan and the receipt: the evidence ladder with its evidence line, right-aligned numbers, 100-column max, no emoji, --plain, --no-color, NO_COLOR and non-TTY honoured. --json payloads unchanged (#67). Real vendor logos in the coverage matrix, and one brand mark across the site, dashboard, favicons and social card (#59, #63, #65, #66). curl -fsSL https://agentworth.dev/install.sh | sh is now a real installer (#55). Fixed: The index stored hundreds of config, telemetry and other non-session files as sessions with zero events. Discovery rules for seven adapters now reject them, the scanner skips zero-event parses, and a full scan prunes existing stubs (#68). agentworth serve --dist silently served the embedded dashboard when the path was wrong; it now fails at startup naming the path (#60). GET /api/traces dropped primary_outcome and composite_score when null, so every outcome dot rendered grey; the keys are always present now (#60). Release tarballs ship agwt as well as agentworth; the npm launcher resolves whichever name it was invoked as (#61). CI now runs cargo test --workspace and the npm launcher tests; a test that had been red on main is fixed; one mutex unwrap that could wedge serve recovers (#54, #61). Dashboard formatters no longer throw on a field the server stopped sending (#53). ### 0.1.12 — 2026-09-02 Fixed: npx agentworth works on macOS again. 0.1.11 passed --force-local to tar on every platform. That flag exists only in GNU tar; macOS ships BSD tar, which rejected it, so every fresh install on a Mac failed with "native binary not found". The flag was a Windows-only workaround and Windows is no longer supported, so it is gone (#51). ### 0.1.11 — 2026-09-02 Fixed: Windows dropped as a supported platform. 0.1.10 shipped a Windows build for the first time, and it broke npx agentworth on real Windows machines within minutes: GNU tar parses a C:\Users\...\agentworth.tar.gz archive path as a remote host:path tar spec (the drive letter before the colon reads as a hostname), so extraction fails instead of just opening the local file. Rather than chase this again, Windows is no longer built or resolved — agentworth on Windows now fails with a clear "unsupported platform" message instead of a 404 or a tar crash. Building from source still works on any platform. The npm launcher no longer lets a stale binary in a cargo target directory or ~/.cargo/bin silently answer for every later version forever — the same version check already applied to PATH now applies to those sources too. ### 0.1.10 — 2026-09-02 Fixed: The outcome ladder now actually renders. primary_outcome was written to the index in hand-rolled PascalCase ("CommitObserved") while the API contract and the whole frontend expect snake_case — every session with a real outcome silently read as unresolved, and verified_outcomes_count was 0 for everyone. A data migration corrects every row already on disk the first time this version opens your index; nothing to run by hand. No busy_timeout was set on the SQLite connection — agentworth serve and agentworth scan running at the same time could return SQLITE_BUSY immediately on a write collision instead of waiting. prompt_preview was always empty. It's now populated from each session's first real user message, truncated past 200 characters. /api/stats and /api/traces disagreed on how many sessions existed (one counted near-empty stub sessions, the other didn't) — several report/dashboard numbers were quietly dividing against the wrong population. Fixed at the source rather than patched per call site. Several commands (audit, threat-digest, stats, archaeology, blind_spots, and more) silently capped how many sessions they looked at while presenting the result as "all sessions" — on an index above the cap, that read as a clean bill of health when it wasn't. All now scan the real total. agwt search's background indexing only ever ran once per process; any session scanned after the first successful run was never indexed for search again. Rebuilt as a real incremental indexer. Every dollar figure in agentworth's reports was priced as Claude 3.5 Sonnet regardless of which model actually ran the session. Added: agentworth version / agentworth update — checks whether a newer release exists and tells you how to get it (never replaces the binary itself). agentworth threat-digest and agwt blunder-blame — rank indexed sessions by real secret exposure, and connect a blunder back to the files it touched (or a file back to the sessions that touched it). A real-time GET /api/live-tail (SSE) endpoint — filesystem-watch-based, no polling. Outcome claims are now cross-checked against real trace state before being trusted — a bare tool-call request with no observed result no longer counts as verified. ModelSwitch events, tracked across all 20 supported harnesses. agentworth config — persisted defaults for json/limit/period, explicit flags always win. A context-rot marker and a human-vs-agent recovery-loop classifier, both intentionally conservative (weak-to-moderate confidence, documented as such) rather than dressed up as more certain than the underlying signal supports. Redaction now covers a session's own repository/project name (previously only a home directory's username was stripped, so export --redact still leaked project identity) and reaches outcome/recovery evidence, not just raw event content — closing a gap flagged ahead of the read-only MCP server spec in docs/specs/mcp-server.md. ### 0.1.9 — 2026-09-01 Added: Trajectory view in the dashboard inspector — a timeline strip (bucketed ticks across three rows), a virtualized event stream, and a detail panel. Before this, the inspector scored a session (80/100) without ever showing what the agent actually did; trace.events was fully populated and rendered nowhere. Categorical colour palette for the dashboard's data views — eight identity hues, full light and dark sets, with a colour/monochrome toggle. A stacked token-economics bar in one hue plus greys wasn't readable; cache read vs. cache creation is the whole point of that chart. SpacePilot icon sprite replaces most hand-drawn icons in the dashboard topbar, rail, and outcome ladder (27 icons ported). Landing state now shows an overview ("how am I doing") instead of "Select a session to inspect it." Fixed: Escape now actually collapses the expanded trajectory view. Its tooltip had promised Collapse (esc) since the explorer shell shipped, but no handler existed — and once one was wired up, a stale-closure bug in the key handler's dependency array kept it doing nothing anyway. Danger red no longer marks sessions that simply lack evidence yet. OutcomeKind has no failure state — every value is a degree of evidence or its absence — so red is now reserved for an actual cost signal (a cache-invalidation spike), and unverified work reads as neutral or hollow instead of a wall of alarms. ### 0.1.8 — 2026-09-01 Fixed: npx agentworth@ now runs the version you asked for. Every release before this deferred to any agentworth already on PATH, so a pinned request silently ran whatever was installed locally instead — four releases stale, in the case that surfaced it. This is the fix 0.1.7 was tagged for; see below — it didn't actually ship until now. The release smoke test no longer races the npm registry. A good release could previously report itself broken because the check ran before the published version had propagated. ### 0.1.7 — 2026-09-01 ### 0.1.6 — 2026-09-01 Added: MotionVector design system applied across the marketing landing page and the new dashboard. Keyboard-first, three-pane explorer shell for the dashboard, splitting apps/web into a marketing site and a standalone apps/dashboard. Inspector detail restored after the shell's first pass thinned it out: a five-component score breakdown with the audit explanations underneath, token economics shown as a proportion (cache read vs. cache creation), a provenance block (source path, fingerprint, on-disk-verified chip), and recovery signals. The session list regained its seven sort modes, cross-field search, and a density toggle. ci.yml — the repo's first Rust CI. Before this, only page-deploy and the tag-triggered release existed, so nothing compiled the workspace on a pull request. Fixed: The installed binary now actually contains the dashboard. Every release back to 0.1.0 built no web app in release.yml and looked for apps/dashboard/dist by a relative path that only resolved inside a repo checkout — so every npm and cargo install served a hardcoded stub page, silently, for months. The session list was showing 50 of 2,903 sessions, because /api/traces defaults to limit=50 and nothing asked for more — every filter, sort, and search ran against just the newest 50 and looked normal doing it. Every deep link was a blank page: Vite's base: './' resolves asset URLs against the current route, so /s/ requested /s/assets/..., got the SPA fallback's index.html back, and died on a MIME check before React ever mounted. Five TypeScript field names never matched the server's actual response shape (cache_read_tokens/cache_creation_tokens vs. cache_*_input_tokens; adapter_name, mtime_epoch_secs, content_fingerprint vs. adapter, modified_timestamp, fingerprint) — cache economics silently read as zero and provenance as em-dashes even though the real data was there. The adapter column was 54px, truncating claude_code — the single most common value in any real index — down to claude_c. agwt blame now persists file modifications so lineage lookups actually match; previously edits went unrecorded and blame silently came up empty. ### 0.1.5 — 2026-08-31 Fixed: npx agentworth no longer spawns itself into an EAGAIN crash loop on macOS. The launcher's PATH-resolution step found npm's node_modules/.bin/agentworth symlink — which points back at the launcher itself — before the GitHub-release binary downloader ever got a chance to run. The old anti-recursion guard compared unresolved paths and didn't follow the symlink, so it missed it. Fixed with three independent guards: realpath-based self-detection, rejecting .js/.cjs/.mjs shim files outright, and an AGENTWORTH_LAUNCHER_ACTIVE flag that skips PATH lookup once already inside a launcher. ### 0.1.4 — 2026-08-31 Fixed: npm install agentworth actually installs something again. 0.1.3's npm publish failed with a 404 that looked like a missing package but was really an npm auth failure, so every npx agentworth invocation — including every landing-page CTA — had been silently stuck on 0.1.1 since. Publishing now goes over trusted publishing (OIDC) instead of a token; classic and even bypass-2FA granular tokens both got a hard 403 when tested against a real publish, which matches npm's own policy of retiring token-based publishing for this case. A version gate now blocks a release where the git tag, Cargo.toml, and package.json versions disagree. 0.1.3 was tagged from a tree where Cargo.toml still said 0.1.2, so the binary it built reported the wrong version. npm whoami now runs before publish, so a broken publish fails in seconds naming the real cause instead of ending in a confusing 404. Added: A clean-room smoke test: npx -y agentworth@ --version and usage --pacing, run on a fresh Ubuntu and macOS runner with no checkout and no cargo cache — the exact conditions 0.1.3 shipped broken under. Removed: brew install agentworth and the curl | sh installer, from the missing-binary message. Neither exists: there's no Homebrew tap, and that install URL just returns the site's HTML with a 200 — so the advertised command would have piped a webpage into a shell. Points at the GitHub releases page instead. ### 0.1.3 — 2026-08-31 Added: Local semantic search (agwt search), backed by a FastEmbed ONNX embedding engine that runs fully offline. Forensic safety auditor (agwt audit --safety). Five-rung outcome ladder indexing in SQLite, plus a cache-cliff visualizer and agwt matrix in the (not-yet-shipped) dashboard UI. agwt blunder — dispatches a redacted incident report to stfuopus.lol, stripping secrets before anything leaves the machine. Adapter discovery now runs across multiple cores in parallel, with adapter stats sorted; native SQLite ingestion for OpenCode sessions. Fixed: primary_outcome and composite_score now migrate before index creation in initialize_schema, instead of after. ### 0.1.2 — 2026-08-31 Added: Expanded Native Adapter Fleet from 11 to 20 Agents: 🐋 DeepSeek Code (deepseek): Discovers ~/.deepseek/, ~/.deepseek-coder/, and .deepseek/ traces. Full reasoning token stream accounting for DeepSeek R1 and V3 (reasoning_content, thought). Tracks prompt cache hits (prompt_cache_hit_tokens) and cache creation (prompt_cache_miss_tokens). Normalizes file editing (str_replace_editor, write, edit) and shell execution (bash). 🌙 Kimi Code (kimi): Discovers Moonshot Kimi Code sessions in ~/.kimi-code/ and ~/.kimi/sessions/wire.jsonl. Parses streaming wire JSONL protocols, subagent delegations (subagent_delegation), and tool calls. ⚡ MiniMax (minimax): Discovers ~/.minimax/ and ~/.minimax-agent/ coding plan trajectories. Normalizes multi-step planning milestones, tool executions, and token expenditures. 🐉 Qwen Code / Qwen-Agent (qwen): Discovers Alibaba Qwen Code and Qwen-Agent trajectories in ~/.qwen/ and ~/.qwen-agent/. Extracts reasoning CoT, code_interpreter executions, and tool calls. 🧠 Zhipu / CodeGeeX (zhipu): Discovers ~/.codegeex/ and ~/.zhipu/ IDE extension and GLM-4 session histories. 🛠️ Aider (aider): Discovers .aider.chat.history.md and ~/.aider/ git-driven trajectory markdown/JSON logs. Maps git diff edits and commit messages directly into verified outcome evidence (OutcomeKind::CommitObserved). 👁️ Cline & Roo-Code (cline): Discovers VSCode global storage task logs (saoudrizwan.claude-dev/tasks/ and rooveterinaryinc.roo-cline/tasks/). Parses task UI messages, API conversation histories, token cache metrics, and tool execution trees. 🌊 Windsurf / Cascade (windsurf): Discovers ~/.codeium/windsurf/ and Cascade execution caches. Normalizes multi-turn code edits, terminal outputs, and test validations. 🦾 Manus (manus): Discovers ~/.manus/ autonomous agent browser actions and coding trajectories. ### 0.1.1 — 2026-08-30 Added: agwt usage Command & Rollups: Deep usage analytics by timeframe with --period day|week|month and --limit. Aggregates sessions, input tokens, output tokens, prompt cache reads, and estimated USD spend. Real-time rolling pacing telemetry with --pacing (default 5-hour window via --hours 5): Token burn velocity (tokens/hour). Prompt cache hit ratio percentage. Active agent adapters and models within the pacing window. Estimated dollar expenditure tracking. Machine-readable JSON output via --json. agwt blame (AI Code Lineage): Trace code alterations and file edits back to the specific AI agent session, model, sequence timestamp, and user prompt that created or modified them. Full support across all 11 supported agent adapter ecosystems. SQL Analytics Views: Added native SQLite aggregation views: v_daily_usage, v_weekly_usage, and v_monthly_usage with pre-computed token math and cache metrics. agwt CLI Alias & Binary Distribution: Added native agwt command-line alias alongside agentworth. Fixed: Date Range Epoch Anomaly: Fixed an issue where corrupt session timestamps or epoch zeroes (1970-01-01) distorted aggregate date bounds by enforcing MIN(CASE WHEN started_at > '2020-01-01' THEN started_at END) in SQLite aggregate queries. SQLite Concurrency & WAL Performance: Configured optimized SQLite WAL mode, busy_timeout = 5000ms, synchronous = NORMAL, and cache_size = -64000 (64MB) to prevent database locking during rapid parallel parsing. Improved: Incremental Rescan Performance: Optimized SHA-256 fingerprint checks to instantly skip unchanged multi-gigabyte session JSONL transcripts. Unified Multi-Platform Installation: Standalone script: curl -fsSL https://agentworth.dev/install.sh | sh Homebrew: brew install unfoundbox/tap/agentworth Cargo: cargo install agentworth-cli NPX: npx agentworth or npx agwt ### 0.1.0 — 2026-08-25 Added: Core Agent History Normalization Pipeline: 100% offline, local-first discovery and streaming JSONL ingestion engine. Unified AgentWorthTrace and NormalizedEvent canonical schema. 11 Native Streaming Agent Adapters: Claude Code (claude_code) Cursor Composer (cursor) Google Antigravity (antigravity) OpenAI Codex (codex) Block Goose (goose) Pi (pi) Herdr (herdr) Nous Hermes (hermes) OpenClaw (openclaw) xAI Grok (grok) OpenCode (opencode) Outcome Evidence Ladder & Scoring Engine: Deterministic outcome verification (DoneClaimed < ArtifactChanged < TestOrBuildPassed < CommitObserved < CiOrDeploymentVerified). Explainable 5-factor TraceScore rating. CLI Commands: agentworth scan — Discovers and indexes local session logs. agentworth stats — Machine-wide token expenditures and top model usage. agentworth traces — Tabular session directory with filters. agentworth inspect — Step-by-step ASCII trajectory timeline. agentworth doctor — System health and adapter discovery diagnostics. agentworth export — ATIF v1.0 and JSON export with 13-rule offline privacy scrubber. agentworth serve — Local embedded Axum API server and monochrome receipt explorer UI.