Skip to content

feat(audit): spend rollup across runs (audit summary --by) - #139

Merged
prashar32 merged 2 commits into
mainfrom
feat/audit-summary
Jun 14, 2026
Merged

feat(audit): spend rollup across runs (audit summary --by)#139
prashar32 merged 2 commits into
mainfrom
feat/audit-summary

Conversation

@prashar32

Copy link
Copy Markdown
Owner

Closes the honest gap behind the "spend/usage visibility" pitch: the foundation (every model call is a ledger row tied to a run with a name + metadata) was there, but there was no built-in rollup across runs — per-team/user spend was DIY SQL.

The store-level aggregation (SummarizeLedger by provider/model/day/name/metadata.key) already shipped with the Postgres work; this adds the CLI surface and the OTel attribution on top.

CLI

riskkernel audit summary --by metadata.team
riskkernel audit summary --by provider --since 2026-06-01 --json

Rolls cost-ledger spend up by a dimension — provider | model | day | name | metadata.<key> — with --since/--until windows and --json (table by default). Grouping by metadata.<key> turns the tags you put on runs into a spend-by-team/user/feature report. Deterministic SQL over the ledger you own; no LLM in the path.

TEAM    CALLS  PROMPT  COMPLETION  DOLLARS
beta    1      200     20          0.030000
alpha   1      100     50          0.010000
TOTAL   2      300     70          0.040000

OTel attribution

The model-call span now also carries riskkernel.run.name and one riskkernel.run.meta.<key> per run tag, so the same grouping works in Datadog/Grafana/SigNoz without a separate run→team map. Both are pinned in api/v1/otel-genai.md (public contract). Cardinality is the user's own (their tags).

Still single-tenant — this is attribution via user-supplied tags, not auth/RBAC (that stays deferred per the architecture).

Tests

  • audit summary --by metadata.team --json against a seeded SQLite store → asserts per-team dollars (alpha=0.01, beta=0.03) and the grand total; the --by guard; parseTimeFlag (RFC3339 + date + invalid); summaryHeader.
  • OTel: span carries run.name + run.meta.* when set, and omits them on an unnamed/untagged run.
  • go test -race green on otel + cmd; go vet/gofmt clean; binary smoke confirms the command is wired into help, the usage guard, and table output.

Help text and shell completions updated for the new subcommand.

Closes #37

Per-run 'audit export' had no cross-run companion, so spend-by-team/user/feature
was DIY SQL. Add 'riskkernel audit summary --by <provider|model|day|name|metadata.<key>>'
on top of the existing store aggregation: roll cost-ledger spend up by a dimension,
with --since/--until windows and --json output (table otherwise). Grouping by
metadata.<key> turns the tags you put on runs into a spend report —
'audit summary --by metadata.team'. Deterministic SQL over the ledger you own; no
LLM in the path.

Also attribute spend on the OTel side: the model-call span now carries
riskkernel.run.name and one riskkernel.run.meta.<key> per run tag, so the same
grouping works in Datadog/Grafana/SigNoz without a separate run->team map. Both
new attributes are pinned in api/v1/otel-genai.md.

Tests: audit summary by metadata against a seeded store (grouped totals + grand
total), the --by guard, parseTimeFlag, summaryHeader; and span assertions that
run.name + meta.* are emitted when set and omitted when not.
@prashar32
prashar32 merged commit a2c454f into main Jun 14, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Usage attribution & spend rollup by run metadata (team/user)

1 participant