Skip to content

squad cost finds the current session from Scribe's session logs, which the shell never writes #2347

Closed

Description

@joslat

squad cost reads usage from the structured ledger (.squad/log/usage.jsonl), and only the interactive shell writes that ledger. To scope plain squad cost to the current session, though, it takes the newest .squad/log/*.md file as the session start (getCurrentSessionCutoff, packages/squad-cli/src/cli/commands/cost.ts:249-262). Those files are Scribe session logs, and the shell never writes one: its coordinator prompt is a router built from team.md and routing.md (packages/squad-cli/src/cli/shell/coordinator.ts:232-300). The only prompts that still ask for session logs are after-agent-reference.md:53 and the host digest (packages/squad-sdk/src/client/adapters/coordinator.ts:131). #2030's charter already retired them, and #2322 removes them.

So the numbers come from one writer and the session boundary from another.

What happens

I ran runCost against a ledger shaped like the shell's writes: one run yesterday (coordinator plus Flight) and one today (coordinator plus Control, then EECOM). Today's run is 13,000 input tokens, $0.13, 3 turns.

Case Plain squad cost
No session log (the shell today, and every host once #2322 lands) 23,000 tokens, $0.23, "5 turns in 5 sessions", yesterday included
An old session log from an earlier Copilot session the same
A Copilot session in the same repo writes a session log at 10:15, during today's run 7,000 tokens, $0.07, EECOM only

The "N sessions" count is off as well. It counts sessionId, which is the SDK session, and the shell uses one for the coordinator plus one per agent (packages/squad-cli/src/cli/shell/index.ts:519-528, :716-725). One shell run with three agents shows up as four sessions.

How it got here

#454 added the session-log cutoff when both the cost rows and the session logs came from Scribe in the same host. #2063 (for #1716) moved the numbers to the shell's ledger but kept the cutoff.

Proposal

The shell already has a session id: persistedSession.id (packages/squad-cli/src/cli/shell/session-store.ts:48-55), the one /resume restores. Stamp every ledger record with it as an optional squadSessionId, and have plain squad cost show the records that share the newest one. --all stays the same. A ledger with no stamped records falls back to today's cutoff, so existing data reads the same. The validators ignore extra fields, so older CLIs still read the new records. The summary should count Squad sessions instead of SDK sessions.

Tamir raised this on #2322, and it should land before that PR. I have a PR for it.

Activity

  1. added a commit that references this issue on Oct 28, 2026
    017e585
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions