Skip to main content

Project productivity metrics

Project reports use one captured set of selected canonical repositories for the current period, previous period, and trend. A repository added recently can contribute retained earlier PRs to all three windows. Membership before the disclosed history baseline is unknown.

For the reporting workflow, see View Project Productivity. For scope and attribution, see Project reports.

Metric definitions​

In these formulas, N is the distinct eligible merged-PR count, Ns is the count with usable native scores, P is their summed native points, and A is the set of canonical people with eligible merged PRs. R counts accepted exclusively attributed original Gateway requests. C is accepted exclusively attributed estimated cost; C(A) restricts that cost to people in A. G is the set of canonical people with compatible attributed AI activity.

MetricCalculationAvailability rule
Productivity pointsPPending or recomputing scores remain disclosed.
Merged PRsNDeduplicate native PR IDs across the selected repositories.
Active contributorsSize of AUnlinked authors withhold the complete-person count.
Points per active contributorP / size of ARequires a complete person denominator.
Average scored PR pointsP / NsPending PRs enter N, but not Ns.
Repository or contributor shareIts points / P, or its PRs / NUses the full selected Project denominator.
Active repositoriesDistinct selected repositories with PR activity by the contributorAI-only associations do not count.
Estimated spendCMissing usage is unknown; accepted free usage can be zero.
Cost per 1,000 points1,000 × C / PRequires compatible filters, usable scores, pricing, attribution, and retained evidence.
Requests per PRR / NUses original requests, including eligible MCP requests without a price event.
Cost per PRC / NRequires qualified spending and a compatible PR population.
Points per estimated dollarP / CRequires complete usable scores and qualified spending; zero cost is unavailable.
Cost per active contributorC(A) / size of AExcludes AI-only people's spend; missing active-person cost withholds the average.
AI activity among active contributorsSize of the intersection of G and A / size of ARequires complete canonical-person and compatible activity coverage.

Zero or unknown denominators produce Not available, never infinity. These operational ratios do not establish PR causality, saved labor, billing totals, or ROI. Values are pooled from the full selected population; repository averages are never averaged together.

Backend spending and filter boundaries​

The Project UI hides cost information. The backend retains the following spending rules and derived metrics.

Accepted Project cost equals the union of accepted exclusive repository allocations. Shared across Project repositories, shared across the Project boundary, and unresolved references remain excluded. Model and provider breakdowns are separate views of the same cost; do not add them together. Overlapping Projects are not additive.

Gateway and Observer are separate sources. Observer Project spending remains unavailable without trusted repository attribution. Historical session lifetime totals cannot supply selected-period spending or trends.

Repository and linked-person selections can narrow output and spending together. PR work type, target branch, and delivery exclusions narrow output and PR evidence; spending remains on all work types. Incompatible ratios and AI activity comparisons are unavailable.

Scope and display limits​

SettingBehavior
Repository selectionUp to 1,000 canonical repositories; search and paging preserve selection.
Quiet repositoriesRemain in the selected set and repository table.
Custom periodAt most 366 civil days in the reporting timezone.
OverviewFour cards, paged contributor/repository productivity lists, four selected-period timelines, and one repository table.
DetailOutput rankings, contributors, work mix, PR scores, reviews, and sessions load on demand. Cost and Investment remain backend-only.
Qualified ranking previewThree highest and three lowest entries; fewer than six appear once in one list.
Search and pagingChange displayed rows without changing full-scope totals or the ranking population.
RefreshCreates a new capture; membership, access, source-policy, or evidence changes can invalidate an older report.

Reporting calendar​

Periods use the administrator's saved reporting timezone and preference revision, resolved by the native Outcomes context. Custom start and end dates are inclusive local dates; source intervals include their start and exclude their end. A current period stops at its captured cutoff. Daylight saving changes can make a local day 23 or 25 hours; seven civil days need not equal 168 hours.

Comparisons retain the same selected repository set. Rolling and custom periods compare the same number of preceding civil days. Calendar month, quarter and year presets retain their calendar boundaries. To-date comparisons use the same local wall-clock progress, clipped to the prior calendar period. A timezone preference change requires a newly authorized context and report; it does not reinterpret an accepted report's buckets.

Administrator API​

All Project routes require a currently active administrator account and return Cache-Control: no-store. Report requests do not modify Project configuration. Start by obtaining a native context with POST /api/v1/outcomes/analytics/context, using scope: {kind: "project", id: "PROJECT_ID"}, the selected period, prFilters and current preferenceRevision. The server resolves timezone, authorization, membership and evidence revisions; client fields cannot establish trusted identities or costs.

EndpointPurpose
GET /api/v1/project-productivity/projects/{id}/repositoriesRead current canonical repository selection metadata.
POST /api/v1/project-productivity/reportsCapture a new overview root.
POST /api/v1/project-productivity/reports/{id}/viewsRequest a derived view of the accepted root.
GET /api/v1/project-productivity/reports/{id}Poll a job, read its first page, or follow its signed cursor.
DELETE /api/v1/project-productivity/reports/{id}Cancel the authenticated owner's retained computation.

Repository selectors​

The selection endpoint accepts search, offset, limit (10, 25 or 50), and an optional expected revision. It returns the full ordered canonical repositoryIds, full matchingIds, the visible items, selectionDigest, repositoryRedirects, membership counts and historyKnownFrom. Searches and visible pages do not define the selected set. A changed expected revision returns context_stale; reload membership before applying another selection.

Report parameters.projectId must match the context. Without a compact selector, filters.repositoryIds: null uses the full Project; an array selects an explicit subset, and [] selects none. Saved predecessor IDs are resolved by the server; repository names and reused names do not establish canonical membership.

For a compact selection, send repositorySelection: {scopeDigest: "SELECTION_DIGEST", bits: "BASE64URL_BITS"} and filters.repositoryIds: []. Bits refer to the complete returned repositoryIds order, with the least significant bit selecting the first ID in each byte. Encode exactly ceil(repositoryIds.length / 8) bytes as unpadded base64url; unused final bits must be zero. The digest must match the current full canonical set. It is a consistency check, not an access token. The server independently authorizes and expands the selection. This supports up to 1,000 repositories within the unchanged 64 KiB JSON request limit.

Requests and retained pages​

A report body contains version: 1, adapter: "project_productivity_v1", contextToken, section, parameters and limit (1–50). POST routes accept no query parameters. Parameters include the Project selector, normalized filters, source, trendMetric, sortMetric, descending and search (at most 256 UTF-8 bytes). selectedPeriodTrend: true requests the selected-period series; monthlyTrend controls the alternative trend. Supported retained sections are overview, points, investment, reviews, sessions, output_rankings and spending_rankings; cost sections remain backend-only in the Project UI.

Selected-period highlight series​

By default, an overview contains one series for the requested trendMetric. Existing requests and clients keep that representation. To request all four selected-period highlights in one new overview root, send the single request header X-AIC-Project-Highlight-Series: 1 and keep the existing JSON body, with parameters.selectedPeriodTrend: true. The requested trendMetric must be one of productivity_points, gateway_requests, five_minute_peak_sessions, or merged_prs.

A supporting server acknowledges the request with X-AIC-Project-Highlight-Series: 1 on the initial successful HTTP 200 or 202 response. Keep that acknowledgement while polling the returned job. Its header.series contains exactly these four metric keys, in the order above, for the same current window, captured population, basis, and interval plan. Validate every series and its metric identity, unit, status, coverage, and intervals before displaying or caching the bundle. Missing, duplicate, out-of-order, or partial bundles are invalid; unavailable values retain their status and reason rather than becoming zero.

Bundled highlights use native application/json, not the existing single-series compact report-page representation. Omit Accept, send application/json, or include an acceptable JSON or wildcard range. A compact-only bundle submission returns HTTP 406 before creating a job. Request JSON on every poll and page; changing a completed bundle's read to compact-only also returns 406, without changing or deleting the retained result. A JSON read of that same job still works. Legacy single-series reports retain compact transport support.

The equivalent native report parameter is highlightSeries: true; it also requires selectedPeriodTrend: true and the same overview metric scope. Absent or false preserves the default one-series response. For compatibility with older servers that strictly decode request bodies, use header negotiation rather than adding this parameter to the browser's JSON body. Repeated or unknown header values, other sections, and derived-view requests are rejected. Ranking, table, and detail requests keep their existing parameters.

If an older server ignores the request header and sends no acknowledgement, expect exactly one series and load the other highlights through the existing sequential derived views of that root. Do not retry the root to negotiate support. This fallback supports a new client talking to an older serving backend; it does not guarantee that a retained job using the new representation can be routed between arbitrary older and newer server versions.

A pending response is HTTP 202 with its job id and expiry. Poll the GET route for that job, honoring Retry-After. A completed page contains header, rows, totalCount and nextCursor. The header retains context, basis, typed metrics, coverage, counts and series. Null metrics remain unavailable with their reasons.

Follow a page with GET /api/v1/project-productivity/reports/{id}?cursor=..., using the job that issued that cursor. A derived view has its own job ID; use that ID for its pages while retaining the original root for subsequent view requests. Send cursors unchanged and URL-encoded. Offsets, repeated cursors, forged cursors and cursors from a different owner or view are rejected. DELETE accepts no query parameters. Protected jobs are account-bound even after an email rename or reuse.

Sorting, searching, paging and supported evidence views preserve the accepted root's population and cutoff. Explicit Refresh creates a new root. Expiry, access revocation, changed membership or destructive evidence changes can invalidate an older report; obtain a fresh context and capture again. A capacity failure is an error, not permission to truncate the population.