Skip to content

Team analytics ​

CodeLotse reports how reviews, triage, assignment suggestions and fixes work out for a team, and what the model calls cost. Analytics are team-level: there is no per-person view for anyone except the person themself, no ranking, no leaderboard and no per-person export.

Where to find it ​

ScreenWhoContent
Analytics → Team metricsTenant adminsWhole tenant, a team (group of repositories) or one repository
Analytics → CostsTenant adminsTokens, cost and prompt-cache hits for the tenant
Analytics → TeamsTenant adminsTeams are groups of repositories; people are never assigned to teams
Analytics → SettingsTenant adminsMinimum group size, personal metrics switch, budget alert thresholds
Analytics → My metricsThe person themselfOnly when allowed (see below)
Repository Analytics tabEveryone who can view the repositoryTeam metrics of that repository; costs for repository admins
Settings → Evaluation runsInstance adminsRuns recorded with quavon eval full --record-db

Every chart has a table alternative ("Show as table"). Values can be downloaded as CSV (format=csv).

Privacy ​

  • Minimum group size (k). A point (period, and dimension value when split) is shown only when at least k distinct people contributed to it (default 5, configurable 5 to 50). Otherwise the point is hidden and never exported. Bots never count. The population is the authors of the pull requests or issues the events belong to; it is computed from the source tables at query time and never returned (no head counts are shown).
  • Admin-only wide scopes. Tenant and team scopes need tenant:manage. Members see repositories they can view.
  • Differencing. Comparing overlapping scopes (tenant minus team, team A minus team B) can narrow a group. Each scope applies k on its own, and the wide scopes are admin-only; the residual risk remains and should be covered by the works agreement.
  • Personal metrics (/api/me/tenants/:tenantId/analytics) need the tenant switch Allow people to see their own metrics, the person's own opt-in in their assignment settings (people.individual_metrics_opt_in) and no team-only metrics (works-council mode or the tenant setting). They exclude repositories whose assignment policy sets team-only metrics. Nobody else, including tenant and instance admins, can read them. Users signed in through OIDC have no linked person and get 404.
  • Costs are not about people and are exempt from k; they are only available to tenant or repository admins.

Metric dictionary ​

The period of an event is the UTC day of the timestamp named below. Weeks are ISO weeks starting on Monday; months are calendar months (UTC). Rates are numerator / denominator summed over the period.

MetricDefinitionDay ofPopulationSplit by
acted_on_rateFindings whose feedback outcome is acted / findings with outcome acted or dismissed. The latest event per finding and day counts.feedback_events.occurred_atPR authorscategory, severity (from the event)
dismissed_ratedismissed / (acted + dismissed), same scope as abovefeedback_events.occurred_atPR authorscategory, severity
comments_per_prPosted comments created that day / distinct pull requests with a completed or silent review run that dayposted_comments.created_at, review_runs.finished_atPR authors–
silent_pr_rateReview runs with decision silent / review runs with status completed or silentreview_runs.finished_atPR authors–
findingsFindings with status publishedfindings.created_atPR authorscategory, severity
time_to_first_reviewFirst finished_at of a completed or silent review run minus pull_requests.opened_at (fallback created_at); mean, median and 90th percentilefirst reviewPR authors–
time_to_mergemerged_at minus opened_at (fallback created_at) of merged pull requests; mean, median and 90th percentilepull_requests.merged_atPR authors–
triage_label_acceptancelabel_kept / (label_kept + label_removed); latest event per triage run, label and dayfeedback_events.occurred_atIssue authors–
duplicate_hitsTriage runs with at least one entry in result.duplicatestriage_runs.created_atIssue authors–
assignment_kept_rateAssignments with outcome kept / assignments with an outcome; only suggested or applied rows, never shadowassignments.outcome_atAuthors of the assigned PRs and issues–
fix_pr_merge_ratePublished fix runs whose pull request is merged / published fix runsfix_runs.finished_atIssue authors–
llm_tokensInput plus output tokens; split by token kind gives input, output, cached and cache-write tokensllm_calls.created_at– (cost)feature, model, tier, token kind
llm_cost_eurSum of cost_eurllm_calls.created_at– (cost)feature, model, tier
cache_hit_rateCached tokens / input tokensllm_calls.created_at– (cost)feature, model

Percentiles are interpolated from duration buckets (DURATION_BUCKETS_SECONDS); values above the largest bucket are reported as that bound. A split a metric does not support is reported as dimension_not_supported. Model calls without a repository count towards the tenant scope only.

Rollups and retention ​

The worker task analytics_rollup runs hourly. Per tenant it recomputes the last 3 days (ANALYTICS_ROLLUP_LOOKBACK_DAYS) and, on the first run, the last 90 days (ANALYTICS_BACKFILL_DAYS) into analytics_daily (additive numerators and denominators per repository, day, metric and dimension value; no person columns). Re-runs replace the same days. Rows older than the tenant's data retention are deleted. The screens show when the data was last updated.

Pull requests store opened_at, closed_at and merged_at from GitHub from this release on; older pull requests fall back to created_at and are not backfilled.

Budget alerts ​

The worker task budget_alerts runs every 15 minutes and compares model spend (llm_calls.cost_eur) in the current budget period with the tenant budget and each repository budget (model policy Budget). The period starts at floor(epochDay / periodDays) * periodDays (UTC). Each threshold (50, 80 and 100 % by default, chosen in Analytics → Settings) raises one alert per scope and period. An alert appears as a banner on the analytics and overview pages, is written to the audit log (budget.alert, actor system) and logged as a warning. Acknowledging it is audited. Each new alert is also sent to the notification channels that subscribe to budget alerts (Slack, Microsoft Teams, e-mail or a signed webhook; see notifications.md).

CSV export ​

GET …/analytics?…&format=csv (and /costs) returns metric,dimension,dimension_value,period,value,numerator,denominator. Hidden points are left out. Cells starting with =, +, -, @, tab or carriage return are escaped against formula injection. Responses are sent with cache-control: no-store. Personal metrics cannot be exported.

The open core is released under the Apache License 2.0.