How it works

Three steps to a deterministic score.

TIER takes the AI usage your tools already record, prices it at the providers’ list rates, and divides the work that merged in GitHub by those dollars. No AI model does the scoring. Its inputs, what merges and what CI reports, can still be produced or approved by AI agents. This page describes v0.6.1.

TL;DR

The result is outcome points per $1,000 of reference-price usage. An outcome is normally a merged pull request (PR), a change accepted into a codebase. Its points describe size and recorded quality signals; deployment, customer use and business value need separate measures. Nobody self-reports hours or effort. You run TIER on your own systems and set up collection. TIER grades the work, not the worker. TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual.

Launch scope. Use TIER alone, or with people you fully trust. Alone, you get the local tierd score cost table; a real-data score needs a team meeting the k contributor floor (minimum three counted people, default five). Everyone with a read, upload or administrator credential, or control of the database, must be trusted with all retained developer data and to report usage honestly. Use name-free team/division reports for shared use. Promotion of non-synthetic developer mode awaits controls for who can see named records, a viewing audit log and retention limits (#826). v0.6.1 refuses tierd serve --aggregation developer on real data, including loopback and read-only operation (#1253). Per-developer views and the per-issue report are not available on real data in v0.6.1 (#826). The synthetic demo (tierd demo), which generates its own invented data in a private temporary database and cannot load yours, shows these views read-only with capture and write routes absent. Upload credentials are not yet tied to a contributor's identity: a holder can submit usage as someone else, add fabricated contributors to the team list to meet k (the minimum number of contributors a report needs), or claim another uploader's event key first. That minimum does not authenticate contributors. These trust requirements are not enforced access controls. In v0.6.1, an ingest token permits only event uploads; admin credentials retain broader access. Corrective-work accounting (Event 3) is off by default and requires operator opt-in in v0.6.1. When enabled, only declared Corrects: #N relations count: eligible same-author pairs count provisionally before operator review; cross-author pairs require confirmation. A declared correction can lower the original’s points; undeclared repairs are not detected.

The algorithm

Read the spend. Join the outcomes. Divide.

For the selected reporting period and population, Σ means the sum over recorded outcomes. Multiply each outcome’s size weight by its quality multiplier, then divide by captured reference-price cost in thousands of US dollars.

TIER = Σ(outcome_weight × quality_multiplier) ÷ (captured reference-price USD / $1,000)
= size-weighted points, adjusted by caller-supplied quality or supported recorded signals, per $1,000 of captured reference-price usage
TIER prices recorded usage, sums outcome size weights times quality multipliers, and divides weighted points by captured reference-price cost in thousands of dollars. AI agents can produce or approve upstream inputs; deterministic scoring does not establish independent acceptance.
Step 01 — denominator

Read the spend

Tokens are the units AI providers use to count model input and output. TIER prices the recorded input, output and cache usage. Claude Code already writes local usage logs; TIER needs installation and collection setup to read them.

Step 02 — numerator

Join the outcomes

A GitHub webhook brings in merged PRs and later quality events; backfill brings in past merges with their quality initially undiscounted. A PR needs an issue reference to earn an outcome under its author’s GitHub login. Matching developer, repository and issue identities associates usage with work for attribution checks and work-type views, never as observed per-PR expenditure. Several PRs can share an issue; even a sole-outcome issue total can include other work or omit collaborators’ spend.

Step 03 — the ratio

Divide, deterministically

The pooled score adds all outcome points and all captured cost for the included developers, then divides those sums. Unmatched spend, abandoned work and work still in progress remain in the denominator. Outcomes without matching usage retain their points and trigger evidence checks; headlines with too little evidence are withheld.

Worked example: merge 100 weighted points on $1,000 of reference-price usage and TIER is 100. The same points on $10,000 give 10; on $250 they give 400. These are arithmetic examples.

Connect both sides

A central deployment (Path C) collects usage on each developer’s laptop and ships it to your server. Connect GitHub with an authenticated webhook for live outcomes and quality; backfill supplies merge history. The quickstart covers installation, collection and webhook setup.

Cost uses the local account’s identity, while PRs use the author’s GitHub login. Map differing names through aliases and load dated team membership so events stay with the group held when they occurred. Shared accounts cannot be separated into people; the identity instructions explain overrides for score and ship, and account identity for the live watcher.

Give work a matching reference

Give a branch an issue reference, such as fix/142-cache for GitHub issue #142, and keep developer and repository identities consistent on both sides. A PR closing several issues still earns one outcome; several PRs on one issue each earn an outcome while pooled spend is counted once.

A PR naming several issues still receives one outcome and one primary issue. A branch-derived issue takes precedence; otherwise TIER uses the highest-priority recognised reference in the description: close directives, then structured configured tracker keys (including built-in OP), then explicit relation references, first match within that class. Bare #N mentions and unconfigured tracker-shaped tokens do not attribute an issue. The other issues receive no outcome of their own, so issue-level views show a selected association, not every issue the PR served.

A merged PR contributes points only when TIER derives an issue reference from its branch or description. A merge without one records no outcome. Any AI cost captured for the work still counts. Holding captured spend and all other outcomes fixed, omitting an otherwise eligible PR cannot increase the numeric ratio; it can reduce it.

An otherwise eligible merged PR can earn points regardless of its file paths, including documentation, handover and agent-memory changes. A point does not establish that the change improved deployed software. Bot- and agent-produced changes can earn points even when their AI usage is not captured. The attribution rules explain reference selection, branch fallbacks and repository matching.

Know what collection covers

Local capture supports Claude Code and opt-in collectors for Codex, Opencode and Muse Code, each with exclusions. The optional proxy’s Anthropic path has live verification; its OpenAI and Gemini paths and the provider pollers still need live verification. The collector documentation covers setup, settling, deduplication and capture checks.

TIER sees usage only through configured capture paths; missing logs, unsupported tools and non-token fees leave gaps. Re-shipping deduplicates stored calls without repricing them, but capturing Opencode through both its logs and the proxy doubles that spend. Health checks can reveal ingestion faults; they cannot prove that all usage was captured.

The parser is an allowlist

What is stored, and what passes through.

Session parsers extract usage metadata and leave prompt text, replies and source contents out of storage. Optional worktree attribution inspects tool-call paths to infer an issue and is off by default.

The GitHub webhook retains raw event bodies, including titles, descriptions, commit messages, author details and changed-file names. Pasted code, prompts or secrets in those fields remain in TIER’s copy even if GitHub is edited later. Those bodies expire under fixed retention caps; derived outcomes and quality records remain, and body retention comes with the webhook.

A clerk puts cards marked Time, Model, Token count and Branch into a “Kept” box, and envelopes marked Prompts, Code and Conversation into a “Never read” slot. Caption: “The envelope, never the letter.”
Session content: never kept. The proxy handles request and response bodies in transit.
Session content excluded from storage, and a summary of retained metadata
✗Prompts & replies
✗Source code & file changes
✗Keystrokes & screenshots
✓Token counts & model names
✓Timestamps & message IDs
✓Developer, repository, session & issue identifiers

The database also holds costs, pricing provenance, outcomes, quality events, aliases, dated membership and invoice records. Watcher checkpoints retain session-file paths, working directories and branch names; with worktree attribution enabled, they also retain the absolute path of the carried linked worktree. These are identifying records, retained across reporting modes without a general person-level retention limit; the privacy inventory lists stored fields, retention and network paths.

TIER sends no telemetry to its maintainers. Shipping sends metadata to your server; the proxy forwards calls upstream; backfill contacts GitHub; configured provider pollers fetch usage reports. Protect the database through host access controls.

Weight & quality

How an outcome earns its number.

Two inputs set a PR’s points: size weight and quality multiplier. People choose size labels; GitHub supplies change counts, automated check results and revert messages. TIER applies a fixed measurement policy: even a critical fix and a typo fix can receive the same size weight.

A paper boat marked PR passes a “Merged” lock onto a Size scale beside a Quality gauge, and a dockworker awards Points. A sinking PR sits beside “Reverted — points cut”. Caption: “Points are earned at the dock, and cut if the work doesn’t hold.”
Default size weights and unlabeled fallback
LabelWeightUnlabeled effort
size/xs0.5≤ 15
size/s1.0> 15 to 60
size/m3.0> 60 to 200
size/l5.0> 200 to 1,000
size/xl8.0> 1,000

Points are the project's size conventions, derived from labels or changed lines and files. They are not validated measures of difficulty, maintainability, customer value, engineering time or the contribution made by AI. The fallback is capped: every PR whose additions plus deletions plus ten times changed files exceeds 1,000 receives weight 8. Above that threshold the heuristic distinguishes neither additional size nor difficulty. A recognized size label overrides the bucket based on lines and files changed. Apply it before merge: later label edits leave the stored weight unchanged, and TIER has no automatic check for inflated labels. The size rubric gives labeling examples and fallback rules.

Event-derived quality — lowest applicable multiplier wins
SignalMultiplierWindow
No degrading event (or CI pass)1.0—
CI failure on the merge commit0.748h
Revert classified as strategic0.860d
Other revert, including unclear reason0.160d

A PR starts at multiplier 1.0 unless supplied through the outcomes API. A completed GitHub Actions failure on the default branch can match the exact recorded merge SHA within the 48-hour upper cutoff. v0.6.1 changes quality only for push-triggered runs; scheduled and dispatched runs remain audit-only, and merge-queue runs are dropped because their ref is not the default branch. Legacy CI effects remain labelled “CI trigger unknown” until operator-approved recovery. Workflow scope and pre-merge occurrence timestamps are not filtered, so environmental failures can still impose the CI floor. Other PR-head SHAs are not scored. A repository that gates locally gets no CI evidence from those checks. A strictly later attempt of the same workflow succeeding within 30 minutes can neutralise an already recorded failure; delivery order matters. The lowest applicable multiplier wins.

The floor values (0.7, 0.8, 0.1) are scoring conventions chosen by the project, not measured fractions of correctness, business value or value lost; no calibration study is published.

A recognised revert can reduce a matched original outcome according to its commit-message keywords. Missing or mixed keywords select 0.1; that classification does not establish a defect. TIER does not measure the fraction reversed. A partial reversal that matches its supported revert rule receives the same message-selected floor as a full reversal—0.1 or 0.8. Other partial reversals can remain unobserved. Footer matching identifies recorded merge or squash SHAs, not constituent-commit ancestry. Reverting a revert does not restore the original outcome's credit. A reland is assessed separately; it does not erase the earlier revert signal.

A revert more than 60 days after merge, and a revert TIER does not recognise, do not add a revert penalty to the original. This is a scoring cutoff, not evidence later regressions are harmless. The footer matcher does not identify the enclosing PR from a constituent commit SHA. Such reversals can remain unmatched; a separate supported issue fallback may still resolve. In v0.6.1 that fallback requires exactly one same-repository outcome in the preceding 60 days; ambiguous candidates are marked without a new penalty.

In v0.5.2, a merged revert PR whose branch or body resolves an issue reference could earn a separate size-weighted outcome for the revert PR's author. The parser could treat an eligible number in GitHub's revert-<PR number>-… branch as an issue number. A separately recognised revert push could reduce the matched original outcome within the supported window; that did not necessarily reduce the team's total and could leave it higher. The reverter was not penalised merely for reverting.

v0.6.1. A recognised revert PR earns no positive credit. Reducing the original outcome still depends on a separately recognised revert push that matches that outcome within the supported window. Reverting a revert does not automatically restore credit.

Matched quality evidence does not establish continuous webhook coverage. Coverage remains unknown unless a separately identified reconciliation establishes the supported event inventory for that repository and interval.

Backfill reconstructs merged outcomes, not their historical CI or revert signals. Those outcomes start at multiplier 1.0, which means no degrading signal was recorded. Later qualifying matched evidence can change live values; sealed reports remain unchanged.

TIER does not ingest production incidents, deploy data or service-dependency data, and does not attribute an incident or a downstream failure to an upstream PR. An incident changes points only if it also produces a supported signal such as a qualifying revert. TIER does not observe issue reopening as a quality signal. An issue's open or closed state does not establish that a merged change was defective. Hotfix branch names do not change scoring. Corrective declarations do not change scoring with the default policy. An attributed merged hotfix earns ordinary outcome credit; one without a derivable issue earns no ordinary outcome. Corrective-work accounting (Event 3) is off by default and requires operator opt-in in v0.6.1. When enabled, only declared Corrects: #N relations count: eligible same-author pairs count provisionally before operator review; cross-author pairs require confirmation. A declared correction can lower the original’s points; undeclared repairs are not detected.

The quality specification is a historical design, partially implemented. Its unimplemented proportional reversal, incident, hotfix, downstream, no-CI discount and final-lifecycle rules are not product commitments. The implementation-status banner defines supported behavior.

Optional direct-commit capture uses a separate, lower weight and can still double-count some merge histories. Interpret it separately from PR sizing; the direct-commit rules explain attribution and deduplication.

The outcome API also accepts records from other code hosts. Callers should match the developer identity or its alias for the join; TIER checks only the identifier’s format; matching is the caller’s responsibility. Repository is optional and defaults to “unqualified”; supplied weights and quality are caller assertions, bounded to (0, 8] and [0, 1]. The write/admin authentication gate can be disabled by configuration; range validation does not verify the judgments. The outcome API contract gives the payload and validation bounds.

Limits

Choose the period and check the inputs.

There is no absolute good-or-bad TIER band. Check the reporting period, attribution, capture and quality evidence before interpreting a change. A reproducible ratio can still have incomplete inputs or inconsistent size judgments.

A shopkeeper holds a TIER gauge while a customer reads its tag through a magnifying glass: “Recent weeks read low”, “Check the cost horizon”, “Trend, don’t rank”, “Low coverage, low trust”. Caption: “It comes with the instructions it wishes everyone read.”

Match the reporting period to capture

Synthetic-demo developer reports select usage by request time and outcomes by merge time; these views are unavailable on real data in v0.6.1 (#826). Recent spend may precede its merge, while older merges may follow spend outside the window. Start after collection began and allow quality events time to arrive.

Attribution is not capture completeness

Attribution coverage is the cost share assigned an issue reference, even if that issue has no merged outcome. Capture fidelity is the cost share from per-request sources rather than coarse or estimated imports. Either can look complete while logs, tools or quality events are missing.

Trend a group against itself; don’t rank groups

Before interpreting a change, document differences in repository scope, membership, work mix, capture and measurement rules. If those differences are unknown or substantial, report the two observations without calling their difference an improvement or deterioration. Spend is counted when usage happened and points when the work merged, so work that crosses a period boundary can move the ratio either way. Team scores carry no interval, and month-to-month noise is large: TIER has not established how large a change must be to stand out from ordinary variation. Treat a small difference as no evidence either way, and a large one as a prompt to investigate, not a measured effect. Matching versions still requires people to label comparable work consistently. Cost per point is reference dollars divided by weighted points; zero cost or zero points needs the report’s evidence flags before interpretation.

Work-type views have a different denominator

The synthetic demo’s developer mode can split invented work by type using PR labels or API inputs; real-data work-type views are unavailable in v0.6.1 (#826). Each segment uses only cost linked to its outcomes; one issue spanning types can charge the same cost to several segments. Keep these views separate from the pooled headline and from comparisons between work types.

Reference dollars and actual bills

The dollars are what captured usage costs at the reference table’s list rates; operators can supply a table of their own. Unknown models use guessed rates with warnings, and manual imports keep the caller’s dollar amounts, so agree their pricing basis before mixing sources. Stored calls keep their original cost unless explicitly repriced.

Your invoice may differ because of subscriptions, negotiated rates, discounts or credits. Finance supplies monthly invoice amounts; Spend Leverage = reference usage value / actual paid compares the two over matching whole months. Seat allocation estimates each person’s share of an organization invoice; the pricing and invoice guide explains rates and allocation.

Save the inputs behind a quoted result

The same stored rows give the same score and the same confidence range on every read. Live developer calculations can change as usage, quality events or mappings arrive or are corrected; these views are synthetic-demo-only in v0.6.1 (#826). Save the database, configuration, prices, binary and report manifest behind a quoted result; the reproducibility procedure covers verification and source evidence that can expire.

The interpretation guide explains windows, evidence thresholds and capture checks. Use those checks to support a number you can defend in a leadership meeting.

Reporting and access

k-anonymity and the aggregation modes.

Choose team or division mode when starting a server on real data. Per-developer views and the per-issue report are not available on real data in v0.6.1 (#826). v0.6.1 has four credentials: an admin token with full access, a read-only viewer token, a monitoring-only metrics token, and an upload-only ingest token for laptops. Anyone holding the admin token can read every developer's records in any reporting mode. The ingest token cannot read anything, but it is not tied to a person, so its holder can upload usage under another name. The access guide explains the four credentials.

v0.6.1 has an admin token for reads, writes, exports, erasure and provider proxies, a read-only viewer token, a scrape-only metrics token, and an ingest token accepted only on POST /api/v1/events. Use the ingest token for laptop shippers; it grants no reads, outcomes, exports, erasure or proxy access. It is not bound to a developer identity: its holder can post usage under another name or pad a contributor group. Admin token holders can read every developer’s identifying records in any reporting mode and post or erase records. k-anonymity limits what viewers of team and division reports see; it does not restrict admin token holders. Treat admin and metrics credentials as operator-only. Without a configured admin token, the server is loopback-only and unauthenticated; other tokens alone do not enable authentication.

Theatre rows marked Payments, Platform and Mobile. Smaller groups are silhouettes behind a frosted screen marked “Other”, and an usher standing in the aisle holds up a sign on a pole: “Below the threshold? You’re in ‘Other’”. Caption: “In team mode: team rows only. Small groups sit in ‘Other’.”
Viewer reports show named cohorts and a pooled “other” row only when the privacy floor is met.
Developer mode

Invented developer rows in the synthetic demo

In the synthetic demo, each invented developer row shows reference cost, weighted points, cost per point and a confidence range when there is enough evidence. Per-developer views and the per-issue report are not available on real data in v0.6.1 (#826). Below-floor rows remain listed, while below-floor aggregate headlines are withheld. v0.6.1 withholds intervals below the row’s own 50% attributed-cost share; shown intervals exclude uncertainty from unattributed spend. The bounds are nominal bootstrap percentiles whose repeated-sampling coverage is unvalidated; missing logs, price error and unreliable labels still need checking, and per-person access restrictions await #826.

Coaching guidance: TIER is built for coaching, not for evaluating developers. Per-person figures are not accurate enough to judge an individual.
Team / division mode

Closed monthly reports

Team and division reports serve sealed UTC calendar months and stay fixed when later events arrive. The operator loads history, aliases and roster before arming sealing; the default grace can end before all eligible reverts arrive. The sealing setup covers prerequisites, previewing the first month and unavailable reports.

Viewer reports show teams and divisions
The k-anonymity floor

Small cohorts pool or are withheld

k is the minimum number of counted contributors behind a published cohort and each nonzero measure; small or unassigned cohorts pool into “other”. If that pool falls below the floor, TIER withholds the whole response—named rows, pool and grand total—and declares suppression. Only distinct, rostered, active non-bot people with captured evidence count; spend without a person identity is excluded, while unmatched issue spend for a real developer stays included. Team/division reports omit attribution coverage, cost composition and work-type views. Group reports do not disclose exact cost-attribution or quality-evidence shares. Capture-fidelity and cost-horizon warnings are different signals; they do not establish complete capture or observed quality coverage. 'Not shown' is neither a clean bill of health nor evidence that coverage is low. Ask the operator which diagnostics were run, what they found, and which capture or attribution gaps remain. Someone who already knows who is on a small team can still work some things out; the team-report contract explains contributor counting and suppression.

Default k = 5 · hard minimum 3

See how each team uses these modes →