Skip to content

🌱 tokens: per-issue/PR/head-SHA launch attribution over the token collector - #12164

Merged
hivecommons-hive[bot] merged 3 commits into
v5from
tokens/12128-launch-attribution
Oct 15, 2026
Merged

hivecommons-hive[bot] merged 3 commits into
v5from
tokens/12128-launch-attribution

Conversation

@clubanderson

Copy link
Copy Markdown
Member

Closes #12128
Refs #12134

cc @mrbobbytables

What

Per-issue / PR / head-SHA launch attribution, built on the existing token collector, pricing table, and repo-cost join β€” no parallel budget gate (RFC #12134, constraint D).

  • Record β€” pkg/tokens/launch.go: LaunchRecord{Agent, Trigger, Repo, Refs[], LaunchedAtMs} + LaunchRef{Ref, Kind issue|pr|external, Repo, Number, HeadSHA}. Durable bounded JSONL at /data/launch-attribution.jsonl (ring of 4000, compacted in place), attached to the existing tokens.Collector via SetLaunchLog / RecordLaunch / Launches. Summed session fields are untouched.
  • Hook β€” cmd/hive/launch_attribution.go + the existing onDelivered seam in runEvalCycle: governor kicks record the issue refs the scheduler put in the message; review-swarm kicks record the PR with its head SHA (review-<kind> trigger).
  • Join β€” pkg/dashboard/collect/launch_cost.go: pure ComputeLaunchCost(summary, launches, now). Same UsageEvent timeline, same EstimateCostUSD, same 24h window and mandatory unattributed / backend_unsupported buckets as /api/repo-cost; invariant Ξ£ by_launch + buckets == total. A launch is an opening event: usage is owned by the latest launch for the same agent until the next launch or a 6h horizon. Per-ref: launches (repeat-spend counter, includes kicks that produced no usage), head_shas, undivided launch_tokens/usd (upper bound) and even-split share_tokens/usd; USD is null when nothing attributed.
  • Serve β€” LaunchCostCollector (cached, persisted like repo-cost) and GET /api/launch-cost (?ref=owner/repo#N narrows; totals stay whole-window). Not-ready reports ready=false with empty lists, never a fabricated $0.00. Route name deliberately avoids the removed /api/issue-costs stub (🌱 fix: remove stub per-issue cost featureΒ #4838) and is real data from the kick path.
  • Dashboard β€” small additive "cost by work item" table under the Cost panel (no new inline styles; ratchet passes).
  • Docs β€” src/docs/token-tracking.md (new Launch attribution section), src/docs/api-reference.md (+ citation --fix), dashboard/openapi.json, changelog fragment.

Tests

  • pkg/tokens: ref parsing, PR ref head SHA, JSONL persist/restore, ring bound + compaction, nil-safe collector hooks.
  • pkg/dashboard/collect: partition invariant across every branch (leading, horizon, lonely agent, backend_unsupported, no-timeline Claude), per-ref share vs launch totals, repeat heads on one PR, launched-without-usage counting, attribution rules table.
  • pkg/dashboard: handler snapshot + ?ref= filter + persistence round-trip, not-ready honesty, inline fallback reading the collector's launch log; OpenAPI parity + style ratchet green.
  • cmd/hive: launchRecordForKick governor and review shapes; boot-collectors test updated for the new collector.

Validation: gofmt (new files clean), go vet, go build ./..., go test ./pkg/proxy/... ./pkg/tokens/... ./pkg/dashboard/... ./cmd/hive/ all green.

…lector

The governor and review-swarm kick paths now record which issue / PR /
head SHA each delivered kick was launched for (tokens.LaunchRecord, durable
at /data/launch-attribution.jsonl, attached to the existing Collector via
SetLaunchLog/RecordLaunch/Launches). A cached join in
pkg/dashboard/collect/launch_cost.go places the existing per-message usage
timeline against those launches using the same pricing table, window, and
unattributed/backend_unsupported buckets as /api/repo-cost, and serves
GET /api/launch-cost with per-launch and per-ref figures (repeat-spend
launches counter, distinct head SHAs, undivided launch_* and even-split
share_* totals, ?ref= filter). The dashboard Cost panel gains a
'cost by work item' table.

Attribution only: no new budget gate; the governor window budget stays the
single enforced budget (RFC #12134, constraint D).

Closes #12128
Refs #12134

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
@kubestellar-prow

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign kellyaa for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@kubestellar-prow kubestellar-prow Bot added dco-signoff: yes Indicates the PR's author has signed the DCO. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Oct 15, 2026
@github-actions

github-actions Bot commented Oct 15, 2026 •

Copy link
Copy Markdown
Contributor

Open PR overlap check

Base branch: v5

Conflicts are checked with every PR merged onto the current tip of v5, so a PR that only needs a rebase is not reported as conflicting with its siblings.

PR Title Relation Files
#12025 ✨ keep unstick steps running in conserve API budget mode same files src/cmd/hive/main.go
#12158 ✨ review: add review.shadow to record would_have_held for the review gate same files src/pkg/dashboard/static/index.html
#12096 ✨ feat(evidence): add GET /api/evidence/summary same files src/docs/api-reference.md
src/pkg/dashboard/api.go

@hivecommons-hive

Copy link
Copy Markdown
Contributor

Shared CI baseline triage: relative links and anchors resolve is red on the v5 default branch itself (broken admin-mcp.md links from #12143), not this PR's diff. Deferred to incident #12162; fix is #12161 β€” once it lands this check goes green on a re-run with no change here.

Separately, PR-local (FIX_DIFF): coverage fails on this PR's own diff β€” COVERAGE GATE FAILED: dashboard/collect: 86.1% (floor 90%) (https://github.com/hivecommons/hive/actions/runs/38790802058/job/116618878832). The new launch-attribution code in pkg/dashboard/collect needs tests to lift that package back to its 90% floor. Leaving the repair to the owning lane.


🐝 Hive Agent: scanner | Instance: hosted-available-oke-11-placeholder-r05x | SHA: unknown

β€” hive: agent=scanner backend=copilot model=claude-fable-5.1

Adds pkg/dashboard/collect tests for LaunchCostCollector persistence
(missing/corrupt/zero/unwritable), Start/Snapshot, and empty-ref launch
shapes so the package stays above its coverage floor. Docs now state the
actual 14-day repo-cost window.

Signed-off-by: Andrew Anderson <andy@clubanderson.com>
Signed-off-by: Andrew Anderson <andy@clubanderson.com>
@hivecommons-hive
hivecommons-hive Bot merged commit 9ab9808 into v5 Oct 15, 2026
67 of 69 checks passed
@hivecommons-hive

Copy link
Copy Markdown
Contributor

merged by Hive trusted-author auto-merge: author @clubanderson holds role owner and GitHub permission admin on repo; CI green at 260c2d1.

@kubestellar-prow
kubestellar-prow Bot deleted the tokens/12128-launch-attribution branch October 15, 2026 19:33
@github-actions

Copy link
Copy Markdown
Contributor

Thank you for your contribution! Your PR has been merged.

We'd love to hear how your experience was: share feedback

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dco-signoff: yes Indicates the PR's author has signed the DCO. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

🌱 tokens: per-issue/PR/head-SHA launch attribution on top of existing token/budget/repo-cost machinery (review D)

1 participant