0.1.30Latest
Added
- Work Receipt v1 format and signing. New
agentworth_schema::work_receipttypes for an in-toto Statement v1 with predicatehttps://agentworth.dev/work-receipt/v1, canonical JSON,receipt_id, the 64 KiB cap, and session refs. Newcrates/attestcrate 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 atagentworth.dev/schemas/work-receipt/v1.json. Evidence slice 1, PR 1 of 4. archie repo receiptcreate, show, key, and init.createbuilds a Work Receipt for the commits in a range (default: upstream merge-base toHEAD), 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 withAGENTWORTH_RECEIPT_KEY), and writes it as a git note onrefs/notes/agentworth(or--transport filefor.agentworth/receipts/<id>.dsse.json). Nothing is signed or written until the repo is consented withrepo receipt init --write, which creates the key, records consent in~/.agentworth/config.toml, and adds the CI workflow; without consentcreateprints a preview only.showmaps the session refs in a commit's receipts back to local sessions.key --githubprints thegh ssh-key add --type signingline that registers the key. Spend is omitted unless--include-spendis passed. Evidence slice 1, PR 2 of 4.- pre-push hook publishes receipts. The hook printed by
archie repo suspect --hook(and written byrepo receipt init --write) now runsarchie 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 withcat_sort_uniqand retried once. repo_receiptMCP tool. Read-only preview of the receiptcreatewould 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_verifyverifies every receipt for a PR range offline (git notes underrefs/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 aci.jsonfile (5). Rung 3 is only ever "attested locally"; rung 1 is never evidence. Conclusion is neutral by default,successonly when every commit carries a receipt signed by a linked key and head CI is green, andfailureonly through opt-infail-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.ymlat the repository root (uses: unfoundbox-crew/agentworth@v0once tagged). It installs archie from the release tarball and verifies its.sha256, fetchesrefs/notes/agentworthfrom the head repository, waits up towait-for-cifor the other checks on the head commit (ignoring its own), collects the authors' GitHub signing keys, runsrepo receipt verify, and posts theAgentWorth / Evidencecheck run. Fork pull requests with a read-only token get the table in the job summary and a notice; aworkflow_runmode puts the check on forks. Neverpull_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.ymlruns the Action from this checkout (uses: ./, archie built from the same commit) on every AgentWorth pull request, withGITHUB_TOKENonly. - Release moves the
v0Action tag to each stable release once a person has created it; the firstv0is 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 indocs/specs/extensions.md, and the demo tapedocs/dogfood/evidence-demo.tape(not yet recorded).
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-tailfor session updates (#213, #222). - Codex human turns.
archie scaningests~/.codex/history.jsonlinto 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_version2 → 3)./api/insightsvolume / by_adapter / calls_per_turn_by_adapter / top_sessions fields that summedsessions.user_messages_countwere named like thehuman_turnstable (human_turns_index_proxy,human_turns). They are nowsession_user_messages/user_messages. Deprecated aliases with the old names are still emitted for one tip cycle. Real human-turn counts live inday_hour/friction/vocabulary(from thehuman_turnstable). - 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 forsessions_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 PATHpreviously 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. Runscanwithout paths to refresh the global insights turn lane. - Wake after the repository rename.
unfoundbox-crew/agentworthnow 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).
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.27did not ship. - The insights payload's human-turn blocks are real data.
archie scaningests the human-at-the-keyboard turn histories no session adapter owns — Claude Code's~/.claude/history.jsonland per-project transcript user-turns, Antigravity'shistory.jsonl+ braintranscript.jsonlUSER_INPUTrecords — 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'sday_hourheatmap,frictionby-trigger counts andvocabularystreams fill from these tables with the same semantics as thetools/behavioral_insights.pyprototype, windowed by?since=&until=, withdeltas.friction_ratecomputed 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 indeferredwith the run-agentworth scanreason; after a real ingest they leave the list and a zero means a quiet window. archie scan's summary reportshuman turns indexed(inserted + deduplicated), andarchie insightsprints the three turn blocks' headline numbers.- Home / app-merge deck. Path deep links for
/insightsand/s/<id>, 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/agentworthaliases tounfoundbox/agentworthso wake finds the right sessions across rename paths. - Agy token accounting. Antigravity
gen_metadatausage varints land in the token counters where the store actually carries them.
Fixed
Turn rows survive a merge.
human_turnsis registered inSESSION_CHILD_TABLESwith itsvocab_jsoninside the row, soarchie mergecarries 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
agyconversation store records the model that generated each step in field 19 of itsgen_metadatablobs; the adapter read everything else out of that store and never that field, so everyantigravityrow indexed withmodels_used: []whileclaude_codeandcodexrows carried theirs. The adapter now reads it (parser version 3). Later tip work also readsgen_metadatausage varints into token counters where the store actually carries them (see Added above).archie session wake --inject antigravityturns anagyPreInvocationhook payload into theinjectStepswake envelope, andarchie hook print antigravityprints the~/.gemini/config/hooks.jsonentry that points at it. Becauseagyexposes noSessionStarthook, an on-disk marker makes the per-invocationPreInvocationfire the wake document exactly once per conversation; seeapps/cli/src/antigravity_hook.rs.Wake resumes the worktree you are standing in, not the newest session for the repo.
extract_repository_or_workspaceprunes 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 recordedworkspace.cwdequals 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.
Added
- Pi adapter reads the documented v3 session format. The parser matched a session shape pi never wrote (
task_input/step/observationwithprompt_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/--<path>--/*.jsonlas specified: thesessionheader (authoritative id, start, cwd) selects the identity,messageentries become prompt / response (with thinking blocks) / tool-call (name plus arguments) / tool-result / shell-command (with exit codes) events,model_changeentries drive model switches so attribution follows the session instead of the settings default,thinking_level_changesets effort, andcompactionentries 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_existschecked 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". Thegeminiadapter now resolves agy locators to their real database file before answering, mirroring opencode.rs.
Added
- Antigravity CLI (
agy) conversation store is indexed. Newer Antigravity builds keep sessions in SQLite (~/.gemini/antigravity-cli/conversations/<uuid>.db, one DB per conversation) instead of the legacybrain/JSONL transcripts, and thegeminiadapter explicitly skipped those files -- so everyagysession was discovered-but-never-indexed. The adapter now enumerates each conversation database under theantigravityidentity, joins theconversation_summaries.dbindex (workspace, liveness, wall-clock end) and the rollinghistory.jsonl(prompt text with real timestamps), and walks the protobufstepsblobs 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 nowtotal_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/autopsyinclude_stubspaths, and fleet-snapshot handling are unchanged.
Fixed
session show(and every reparse path) works for synthetic source identities.source_existschecked 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". Thegeminiadapter now resolves agy locators to their real database file before answering, mirroring opencode.rs.
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,
tarcould 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.partfile, verifies it against the release's published.sha256before 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)
Added
- AgentWorth is a Claude Code plugin. The repo carries
.claude-plugin/plugin.jsonand is its own marketplace (.claude-plugin/marketplace.json), so/plugin marketplace add unfoundbox-crew/agentworththen/plugin install agentworth@agentworthgives Claude Code the 13 read-only MCP tools (overnpx -y agentworth@<version> mcp) and theagentworthskill in one step, with noclaude mcp addand nonpx skills add. The skill moved toskills/agentworth/SKILL.md, which is where the plugin loader looks; the rootSKILL.mdis a symlink to it sonpx skills addkeeps working.claude plugin validate . --strictpasses. The release version gate now checks the plugin manifest'sversionand its pinnednpxpackage version too. (#133) - AgentWorth is a DeepSeek Harness plugin.
packages/dsh-plugin-agentworthis a dsh bundle (npmdsh-plugin-agentworth): onecordis.patch.ymlrow mounts the MCP server through@deepseek-ai/dsh-mcp-clientasmcp__agentworth__<tool>, and the package's own plugin registers theagentworthskill from a bundled copy ofSKILL.mdthroughctx.skills.register(), so nothing has to exist on disk beyond the package.dsh plugin --profile <name> add dsh-plugin-agentworthinstalls it. The bundledSKILL.mdis test-checked byte for byte againstskills/agentworth/SKILL.md, the release version gate checks the package version and its npx pin, and the release workflow publishes it besideagentworth. (#134) - Cursor and VS Code AI SQLite
state.vscdbextraction. Cursor, Trae, and other VS Code AI derivatives store their actual conversation turns and composer sessions inside SQLite databases (state.vscdb) underworkspaceStorageandglobalStorage. The Cursor adapter now automatically parsescomposer.composerData,workbench.panel.aichat.chatdata, andaiService.promptsfromItemTable, 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_VERSIONbumped 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.mdlisted 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_previewno longer zero across the board, and a newcompaction_countcolumn. 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
agentworthwith its own version, not asrmcp 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 inserverInfo. - The embedding-model download now announces itself instead of failing silently.
LocalEmbedder::new()called fastembed withwith_show_download_progress(false)and no announcement, so a binary built with thefastembedfeature (off in shipped binaries today) fetched a model with no explanation -- an air-gapped user just saw a failure.embedder.rsnow prints awarn!-level line before the model load naming the model, source, rough size, that it is a one-time dependency fetch (likenpm install), and that no local data is sent. README.md,docs/TRENDSHIFT.md,docs/ARCHITECTURE.md, and the web app'sArchiePage.tsxno longer overstate "100% offline" / "zero network calls" -- they name the two real exceptions instead. (#169)
Added
cost_weighted_tokensbesidetotal_tokens.total_tokensaddscache_read_tokensat 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_tokenskeeps that meaning for compatibility; the four counters are now exposed separately everywhere, alongsideinput + 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 insession_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) andstats_ladder.docs/specs/token-accounting.md-- the measurement table, the ledger's contract, why Codex is excluded, and whatcost_weighted_tokensdeliberately 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, becauserepo_blameandsession_showexist 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.
UsagePeriodSummaryandModelUsagePeriodSummarygainedcost_weighted_tokensserver-side so no client re-derives the multipliers.archie policy init [--repo] [--force]. Writes a starterpolicy.tomlwith 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 newStorage::session_token_percentiles.archie policy checkwarns 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:conversationorfleet_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 defaultsession list,statsand the session aggregate, and shown whole bysession list --kind fleet_snapshotor--adapter <snapshot adapter>. Adapters declare it throughAgentAdapter::trace_kind.--all-stubsand 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 behindarchie scan's Total Indexed line andarchie doctormoved toStorage::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 carryidentities(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_VERSIONbumps: 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 untilarchie scanruns.The
[spend]example incrates/loop/src/policy.rs's doc comment dropped its token number —[spend]now ships commented out, pointing atarchie 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,
apiBlockIndex0..n -- and every one repeats the samemessage.usageblock 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/projectsthe machine-wide ratio was 2.194x. Gemini CLI has the same shape keyed onid(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: itstoken_countevents are cumulative running totals andcodex.rsalready 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_usageknewpromptTokenCount-style and OpenAI-style names but not the ones Gemini actually writes --input/output/cached/thoughts/toolinside atokensblock -- so every Gemini CLI session read as zero despite real usage.thoughtsandtoolfold into output, matching Gemini's owntotal.archie session list --jsoncarries the token breakdown. It builds its own JSON and never touchedSessionSummary, so the four counters andcost_weighted_tokensnever 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_varwas a function name and "The MissinglocalWeapon (The Katana Incident)" printed to anyone who tripped that rule. Nowis_leaked_loop_varand "The MissinglocalWeapon", 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 newagentworth_schema::fixturesrather than literals, so the convenient option is also the safe one.archie blundershows 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. Oneredacted_payload()now feeds both, so they cannot drift, and--dry-runprints exactly what would be sent and sends nothing. Submission also switched to the newRedactor::for_publication()--blunder --submitredacts loose strings, so unlikeredact_traceit never picked up the per-tracerepository_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_idanddelegation_id, fields no Herdr file has ever carried, so the real~/.config/herdr/session.jsonparsed to nothing while five fixture tests stayed green. It now decodes the v3 shape (workspaces[].tabs[].panes{}) as afleet_snapshot: oneherdr.paneevent per pane withpane_key(Herdr's internal number),pane_number(what the user sees, frompublic_pane_numbers), cwd, label, agent name andagent_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 toidentity_sightingswith the time seen. Scalars decode leniently (a"version": "3"string, a non-numericactive),active_tabandactivegatefocusedso one pane per file is focused, one bad workspace, tab, pane oragent_sessioncosts only itself, unknown fields are ignored and a newerversionis a warning.PARSER_VERSION2. Capabilities report none of the seven. Fixture: a redacted real herdr 0.8.2 file.install.shruns the binary once and explains a Gatekeeper kill. The macOS binaries are ad-hoc signed and not notarized. A freshcurl | shinstall runs (measured on macOS 27: valid signature, no quarantine flag); a copy that carries the flag is killed on exec with nothing butzsh: killed, exit 137 (measured by adding the flag; removing it clears it). The script now removes any existing file before copying (acpthrough the npm wrapper'sagentworthsymlink would have overwritten the wrapper's JavaScript), drops the flag from what it wrote withxattr -dh(act on the file, not a symlink target), runsarchie --version, and on exit 137 exactly prints thexattr -dline for the installed files. Other failures are reported as what they are. README carries the note.archie doctorandagent showname Herdr's real directory,~/.config/herdr/, not~/.herdr/.
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 editedNtimes with no passing verification between edits) and a session spend cap (tokens or dollars at the table price). No file, nothing governed.archie hook --gateis the same hook binary in synchronous mode, one socket round trip, a 50ms budget, and it fails open —archie servedown, 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 asadditionalContexton the next prompt, so the model resumes knowing why it was stopped. - Session spend cap. Once a session crosses its
policy.tomlcap, the batch halts and every prompt after it is blocked with the reason untilarchie policy lift <session>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 <session>|replay,governor_eventsandsession_suspensionstables, andturn_usageper turn.session_burnover MCP. Tool count moves from 16 to 17 (27 intools/list, aliases included).
Added
archie hook. A harness (Claude Code today) posts itsPreToolUse,PostToolUse,Stopand other lifecycle events as stdin JSON to this command, which forwards one line toarchie serve's loopback socket (~/.agentworth/archie.sock) with a 50ms budget. No socket, or serve down: it appends to~/.agentworth/spool/<session_id>.jsonlinstead. Always exits 0. Never slows the agent, never blocks it, never fails visibly.archie hook print claudeprints the settings.json snippet to paste in — it never writes the file for you.archie servelistens on the loop socket. Beside the dashboard and API,archie servenow owns~/.agentworth/archie.sockand ingests anything sitting in the spool at startup.--no-socketturns the listener off.archie scanalso 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]andarchie session anchors [id].driftre-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").anchorslists 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_statusandsession_driftover MCP. Same two answers, callable mid-session.session_wakegains 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 forSystem.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, plushost_fingerprintonsessions.machines.system_idstays empty until SpacePilot writes it; nothing here invents a configuration id.
Fixed
- A
grep-for-"test" no longer counts as a passing test.is_verification_commandsubstring-matched the whole command line, socd repo && /usr/bin/grep -n "test"registered as wake's "last passed" proof. It now splits the command into segments, stripscd, 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 sameUserMessagerole as a real prompt;last_askednow 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.
Added
session_wakeandarchie 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, agitread, or a stat call, and a missing fact is named ingapsrather than padded. Redacted by default;include_raw/--redactopts 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_forwardand the no-id default ofsession_handoffandsession_forgotten. All three now resolve to primary sessions only.session_carry_forwardgainsinclude_subagents(default false) for the old behaviour, and--laston the CLI resolves the same way. - The Claude adapter keeps
cwdandgitBranch. 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'sworkspace.cwd/workspace.git_branchmetadata, whichsession_wake's "Ran in" line reads. cargo install agentworth-cliandbrew install .../tap/agentworthare 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/clifrom a checkout.README.md's "100% offline" claim wasn't true, and neither was the same line repeated indocs/SHOW_HN.md: the optionalarchie session searchfeature 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_ladderwas 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_INand the MCP alias descriptions now say v0.1.20; the generated reference (docs/REFERENCE.md,docs/reference.json) anddocs/specs/cli-grammar.mdmatch.
Changed
update --json'sadvicevalues 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.shasked 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 serveprints 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 aNextline saying how to stop it. Same glyph set, same width clamp, same--plain/--no-colorcolumns. 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 updatenames the channel you actually installed from. It could only recognise the npm launcher, and called everything else "unknown" — including a binary fromcurl -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 taggedthis install; the rest follow underother ways, where before an npm-launched binary was shown npm and nothing else.--jsongains achannelfield (#129).- Every doc says
npx -y agentworth@latest. A barenpx agentworthreuses whatever npx already cached, which is how a months-old binary answers for what reads like a fresh install. The npm channel on theupdatescreen prints bothnpm install -g agentworth@latestandnpx -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_BINand 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@latestchange above is for (#129).
Added
- The cockpit. A bare
archieon a terminal opens a full-screen reader over the same data: overview, sessions, one session, agents, repos and windows, withj/k,Enter,/,1-6,h/a/f/r,?andq.archie tuiis the explicit spelling. Off a terminal, under--plain, underTERM=dumb, or with JSON output, both print the overview — whatarchie statsprints 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: barearchieused to exit 2 with a usage message; it now exits 0 (#121). - Onboarding, one line everywhere.
install.shdraws 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 firstarchie scanon 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 questiondocs/specs/archie-bench.mdset 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, andstats_ladderover 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;
OutcomeKindhas 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), wherestats,session showandrepo suspectused 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 bystats outcomes, thestats_outcomestool 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 recallno longer reparses a transcript per match; the per-model spend it needs already lives insession_model_usage, written by the same scan that parsed the session.updateprints its install link on one full line. The suite now passes on a machine with real session history, not just a fresh one (#122).
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,completionsandmergestay top-level. Every pre-0.1.16 spelling still runs, hidden from--help, until v0.1.18 (#118). - New verbs:
archie agent show <adapter>,archie repo list,archie window list, andarchie stats outcomes— the verified-outcome rate, on the CLI at last (#118). archie, the short name, shipped everywhereagwtshipped: a third binary, the npm bin map,install.sh, and the release tarball.agwtkeeps working and is out of the docs (#118).- Shell completions.
archie completions <shell>for bash, zsh, fish, powershell and elvish, plus live completion of session ids, repositories and models throughCOMPLETE=<shell> 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
(*) archieunder 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 throughGET/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-spotsis nowarchie 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 cacheandsession bisectgained 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 cumulativetotal_token_usage(including a restarted counter), and the real workspace fromsession_meta.cwdinstead of the home directory.PARSER_VERSION1 → 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/tracesand 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/configno longer returnsconfig_path, which named the user's home directory for no reason a browser needed it (#114).
Fixed
- Fixed:
scanpanicked 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.
Added
- The handoff, written by the machine.
agentworth handoff,agentworth loose-ends, and the MCP toolssession_handoffandcarry_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, plusagentworth forgotten. Measured on one 8-round session: 405 decision sentences in, 28 out (#83).suspect_commitsandagentworth 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).inspectaccepts a session-id prefix;doctorandmatrixrender 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 fromis_errorand "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).
statsandusagecount 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).
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 withclaude 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,scanand the receipt: the evidence ladder with its evidence line, right-aligned numbers, 100-column max, no emoji,--plain,--no-color,NO_COLORand non-TTY honoured.--jsonpayloads 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 | shis 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 <path>silently served the embedded dashboard when the path was wrong; it now fails at startup naming the path (#60).GET /api/tracesdroppedprimary_outcomeandcomposite_scorewhen null, so every outcome dot rendered grey; the keys are always present now (#60).- Release tarballs ship
agwtas well asagentworth; the npm launcher resolves whichever name it was invoked as (#61). - CI now runs
cargo test --workspaceand the npm launcher tests; a test that had been red on main is fixed; one mutexunwrapthat could wedgeserverecovers (#54, #61). - Dashboard formatters no longer throw on a field the server stopped sending (#53).
Fixed
npx agentworthworks on macOS again. 0.1.11 passed--force-localtotaron 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).
Fixed
- Windows dropped as a supported platform. 0.1.10 shipped a Windows build for the first time, and it broke
npx agentworthon real Windows machines within minutes: GNU tar parses aC:\Users\...\agentworth.tar.gzarchive path as a remotehost:pathtar 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 —agentworthon 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/binsilently answer for every later version forever — the same version check already applied toPATHnow applies to those sources too.
Fixed
- The outcome ladder now actually renders.
primary_outcomewas 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, andverified_outcomes_countwas 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_timeoutwas set on the SQLite connection —agentworth serveandagentworth scanrunning at the same time could returnSQLITE_BUSYimmediately on a write collision instead of waiting. prompt_previewwas always empty. It's now populated from each session's first real user message, truncated past 200 characters./api/statsand/api/tracesdisagreed 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-digestandagwt 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.
ModelSwitchevents, tracked across all 20 supported harnesses.agentworth config— persisted defaults forjson/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 --redactstill 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 indocs/specs/mcp-server.md.
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.eventswas 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.
OutcomeKindhas 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.
Fixed
npx agentworth@<version>now runs the version you asked for. Every release before this deferred to anyagentworthalready onPATH, 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.
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/webinto a marketing site and a standaloneapps/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.ymland looked forapps/dashboard/distby 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/tracesdefaults tolimit=50and 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/<id>requested/s/assets/..., got the SPA fallback'sindex.htmlback, 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_tokensvs.cache_*_input_tokens;adapter_name,mtime_epoch_secs,content_fingerprintvs.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 toclaude_c. agwt blamenow persists file modifications so lineage lookups actually match; previously edits went unrecorded and blame silently came up empty.
Fixed
npx agentworthno longer spawns itself into anEAGAINcrash loop on macOS. The launcher's PATH-resolution step found npm'snode_modules/.bin/agentworthsymlink — 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/.mjsshim files outright, and anAGENTWORTH_LAUNCHER_ACTIVEflag that skips PATH lookup once already inside a launcher.
Fixed
npm install agentworthactually installs something again. 0.1.3'snpm publishfailed with a 404 that looked like a missing package but was really an npm auth failure, so everynpx agentworthinvocation — 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, andpackage.jsonversions disagree. 0.1.3 was tagged from a tree whereCargo.tomlstill said 0.1.2, so the binary it built reported the wrong version. npm whoaminow 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> --versionandusage --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 agentworthand thecurl | shinstaller, 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.
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 matrixin 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_outcomeandcomposite_scorenow migrate before index creation ininitialize_schema, instead of after.
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).
- Discovers
- 🌙 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.
- Discovers Moonshot Kimi Code sessions in
- ⚡ MiniMax (
minimax):- Discovers
~/.minimax/and~/.minimax-agent/coding plan trajectories. - Normalizes multi-step planning milestones, tool executions, and token expenditures.
- Discovers
- 🐉 Qwen Code / Qwen-Agent (
qwen):- Discovers Alibaba Qwen Code and Qwen-Agent trajectories in
~/.qwen/and~/.qwen-agent/. - Extracts reasoning CoT,
code_interpreterexecutions, and tool calls.
- Discovers Alibaba Qwen Code and Qwen-Agent trajectories in
- 🧠 Zhipu / CodeGeeX (
zhipu):- Discovers
~/.codegeex/and~/.zhipu/IDE extension and GLM-4 session histories.
- Discovers
- 🛠️ Aider (
aider):- Discovers
.aider.chat.history.mdand~/.aider/git-driven trajectory markdown/JSON logs. - Maps git diff edits and commit messages directly into verified outcome evidence (
OutcomeKind::CommitObserved).
- Discovers
- 👁️ Cline & Roo-Code (
cline):- Discovers VSCode global storage task logs (
saoudrizwan.claude-dev/tasks/androoveterinaryinc.roo-cline/tasks/). - Parses task UI messages, API conversation histories, token cache metrics, and tool execution trees.
- Discovers VSCode global storage task logs (
- 🌊 Windsurf / Cascade (
windsurf):- Discovers
~/.codeium/windsurf/and Cascade execution caches. - Normalizes multi-turn code edits, terminal outputs, and test validations.
- Discovers
- 🦾 Manus (
manus):- Discovers
~/.manus/autonomous agent browser actions and coding trajectories.
- Discovers
- 🐋 DeepSeek Code (
Added
agwt usageCommand & Rollups:- Deep usage analytics by timeframe with
--period day|week|monthand--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.
- Deep usage analytics by timeframe with
agwt blame <file_path>(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, andv_monthly_usagewith pre-computed token math and cache metrics.
- Added native SQLite aggregation views:
agwtCLI Alias & Binary Distribution:- Added native
agwtcommand-line alias alongsideagentworth.
- Added native
Fixed
- Date Range Epoch Anomaly:
- Fixed an issue where corrupt session timestamps or epoch zeroes (
1970-01-01) distorted aggregate date bounds by enforcingMIN(CASE WHEN started_at > '2020-01-01' THEN started_at END)in SQLite aggregate queries.
- Fixed an issue where corrupt session timestamps or epoch zeroes (
- SQLite Concurrency & WAL Performance:
- Configured optimized SQLite WAL mode,
busy_timeout = 5000ms,synchronous = NORMAL, andcache_size = -64000(64MB) to prevent database locking during rapid parallel parsing.
- Configured optimized SQLite WAL mode,
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 agentworthornpx agwt
- Standalone script:
Added
- Core Agent History Normalization Pipeline:
- 100% offline, local-first discovery and streaming JSONL ingestion engine.
- Unified
AgentWorthTraceandNormalizedEventcanonical 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)
- Claude Code (
- Outcome Evidence Ladder & Scoring Engine:
- Deterministic outcome verification (
DoneClaimed<ArtifactChanged<TestOrBuildPassed<CommitObserved<CiOrDeploymentVerified). - Explainable 5-factor
TraceScorerating.
- Deterministic outcome verification (
- 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.