Shipped
Joins each session to the commits it produced at a labelled confidence, then reports the measured cost of the sessions that left no joined commit and the ones whose commits were all reverted.
Every other analyzer asks what a session cost. Shipped asks what it left behind. It joins each session to the commits it produced, records the confidence of each join, and reports how many of the window’s sessions put a commit on the default branch that stayed there. Alongside that sits the measured cost of two groups the rollup sums together: the sessions that left no joined commit at all, and the ones whose commits were all backed out. Sessions whose commits exist but have not reached the default branch are counted separately.
tj optimize shipped
The analyzer itself runs no git. It reads tables the matcher keeps current, so the figures can be served from a stored report. The matcher runs earlier in the same daemon pass, and ahead of a direct-database tj optimize when no daemon is running, which means the finding is at most one pass behind your repo.
How a session is joined to a commit
Read-only git, bounded to the session’s own window (60 seconds before it started to 15 minutes after it ended), with a two-second timeout, and never on a request path. A repo whose checkout no longer exists is skipped. Each (session, commit) pair is written once at the best confidence the evidence supports, and a later pass can raise a row but never lowers one.
| Confidence | Source | Evidence |
|---|---|---|
deterministic | tool_span_git_log | a git commit Bash tool call inside the session, within 30 seconds of the commit’s own timestamp |
deterministic | trailer_session | the commit body carries TokenJam-Session: <id> or Claude-Session: <url> naming a session tj has ingested |
deterministic | git_note | a note on the commit under refs/notes/ai, refs/notes/tokenjam, or one other third-party attestation ref, names a session tj has ingested |
inferred | trailer_window | an AI co-author trailer, on the session’s own branch, inside the session window, with no stronger evidence pointing elsewhere |
The confidence travels with the row. It is stored per (session, commit) pair, and every surface that renders a commit renders the label with it. Nothing in a local database is ever written at estimated; that value belongs to an allocation with no session evidence behind it.
An inherited trailer ranks below the tool call that ran the commit. A subagent inherits its parent’s session id, so a commit the subagent’s own Bash tool produced still carries the parent’s trailer. When a trailer names a different session than a tool span does, the row is stored at inferred. Without that rule a parent session would absorb its subagents’ commits at the top confidence.
refs/notes/tokenjam is written only when you opt in with tj init --notes. The other two refs are read and never written.
The five states
Derived at read time from the join plus an index of the default branch that the same pass keeps current.
| State | Meaning |
|---|---|
shipped | a joined commit is reachable from the default branch and was not reverted |
committed | joined commits exist, none of them on the default branch yet |
reverted | every joined commit was reverted by a Revert "..." commit naming its sha |
unshipped | no joined commit at all |
no_repo | the session had no repo context and was never analysed |
committed and reverted are states in their own right, and neither is counted as shipped. A session whose work landed and was then backed out is a different fact from a session that produced no commit.
Where that distinction survives, and where it does not, matters when you read a number. The per-session state is reported as reverted everywhere a single session is rendered: shipped_state on the API, the Sessions view and the session page in Lens. The window rollup has no reverted counter, so a reverted session is counted in sessions_unshipped and its cost in cost_unshipped_usd. Rows in top_unshipped each carry their own state, which is where you can tell the two apart.
What the finding carries
sessions_total and the three counts that add up to it: sessions_shipped, sessions_committed and sessions_unshipped, each with its measured cost. sessions_no_repo sits outside that total, counted on its own, because those sessions were never analysed and rolling them into any state would claim a result nobody produced.
Then commits_joined and commits_on_default, the largest unshipped sessions, and two figures that need their own basis line:
cost_rework_usd: the cost of sessions where at least half of the lines their commits added were deleted again by other work inside 14 days. Measured from git numstat on the commit’s own files; a commit’s own session is excluded from the deletions counted against it. The finding carries arework_basisstring naming how many sessions had line counts to measure and how many qualified.cost_loop_usd: consecutive Edit or Write calls on one path with identical content, priced at the model turn that issued each repeat. When[capture] tool_inputsis off the content cannot be compared, so repeats are counted on path alone andloop_basissays so.
Both are None rather than zero when there is no evidence yet. Zero would claim the analyzer looked and found nothing.
Coverage qualifies every figure
coverage is the share of the default-branch commits in the window, on the repos this window’s sessions ran in and authored by those sessions’ developers, that carry a deterministic or inferred row. Reverts are excluded from the pool. When there is no such commit to cover, coverage is None.
Read every figure on this finding through that number. At 40% coverage, “12 of 30 sessions shipped” describes the joins tj could make, not the work your team did. The hooks that raise it are tj init --hooks, which writes a TokenJam-Session trailer onto commits made from a plain shell while a session is open, and tj init --notes, which adds the post-commit note.
This is not a saving
Unshipped cost is measured spend on two kinds of session: the ones that left no joined commit, and the ones whose commits were all reverted. The rollup sums them and publishes no split between them. It is a fact about output, not money to claw back. The finding publishes no past_overspend_* field and sits outside the recoverable-waste rollup on purpose: pulling it in would price research, review and operations work as waste.
A session can ship real value with no commit. Reading a codebase before a design decision, reviewing someone else’s branch, working through a failing test: none of those produce a commit, and each one lands in unshipped when it ran inside a repo. The same work done outside a repo lands in sessions_no_repo, outside the total.
The caveat is carried as a dataclass default so no surface can drop it, and it reads:
Unshipped is measured cost of sessions with no joined commit; a session can ship value without a commit (research, review, ops). Review before acting.
Where it shows up
tj optimize shipped, and tj optimize shipped --json for the machine-readable form. The tj status --agent <id> card carries a “Shipped N of M sessions” line. Over HTTP it is GET /api/v1/shipped, plus commits and shipped_state on GET /api/v1/sessions/{id}. Those are routes on the local API tj serve runs, http://127.0.0.1:7391 by default, not this website’s public content API at the same path shape. Its read routes are unauthenticated until you set [api.auth] enabled = true and an api_key; see Local API auth. In Lens it appears as the shipped column and filter in the Sessions view, the commit chips with their confidence glyph on a session page, the “Shipped this week” tile on the Dashboard, and the Shipped card on the Optimize page.
See also
- How the analyzers work — the full registry and how findings are ranked
- Cost visibility — the spend-facing half of the same window
- CLI reference —
tj init --hooksandtj init --notes