How R&D Capitalization Works
This page explains the methodology behind Antenna’s automated R&D capitalization: how each pull request and issue is classified as capitalizable or non-capitalizable, how effort is estimated, and how monthly capitalized vs. expensed cost is calculated.
For a higher-level overview and step-by-step instructions on generating a report, see the Overview.
Antenna is metadata-only. Classification relies on pull request titles, labels, linked issues, and aggregate code-composition ratios — never on the contents of your source code.
How it works
Capitalization is derived automatically from the engineering activity Antenna already ingests. The end-to-end flow is:
Ingest metadata
Pull requests, linked issues, and code-composition ratios are collected from your Git and project-tracking integrations.
Classify each unit of work
Every merged pull request and every issue is classified as capitalizable or non-capitalizable, along with a confidence level and a human-readable reason.
Estimate effort
Each pull request and issue is assigned a level of effort on a 1–5 scale based on its size and complexity.
Convert effort to weighted hours
For each contributor and month, effort weights are distributed across the contributor’s configured availability to produce capitalizable and non-capitalizable hours.
Calculate cost
Finance adds a fully burdened labor cost per contributor. Antenna converts hours into capitalized and expensed dollars.
Classification inputs
The classification engine evaluates several categories of signal:
| Signal | Description |
|---|---|
| PR title | Natural-language intent (e.g. “Add payments API” vs. “Fix billing typo”) |
| PR labels | Your existing tagging taxonomy (e.g. enhancement, bug, feature) |
| Linked issues | The type and classification of issues linked to the pull request |
| Issue hierarchy | Epic / story / task / subtask / bug relationships and completion order relative to the parent |
| Code composition | The ratio of new, refactor, churn, and other code in the change |
| Story points | Planning estimates, when available, used for effort weighting |
Pull request classification
Each merged pull request is evaluated against an ordered set of rules. The first matching rule determines the classification, so higher-priority signals (manual review, linked-issue evidence) always win over weaker heuristics.
- Manual override — if a reviewer has explicitly set the classification, that value is used.
- Excluded PR — pull requests excluded from metrics (bots, backmerges, noise) are non-capitalizable.
- Linked-issue evidence — when a PR is linked to issues:
- All linked issues non-capitalizable → non-capitalizable
- All linked issues capitalizable → capitalizable
- Linked issues are capitalizable but the PR title and labels signal maintenance → non-capitalizable
- Linked issues conflict or can’t be resolved → non-capitalizable (low confidence)
- Title & label signals — when there are no linked issues, the PR title and labels are matched against Antenna’s classification rules for feature vs. maintenance intent.
- Code composition — when metadata is inconclusive, Antenna automatically flags the pull request based on whether its code changes look like new development or maintenance.
- Default — anything still unclassified defaults to non-capitalizable (conservative).
Issue classification
Issues are classified using both their own metadata and their position in the issue hierarchy. Antenna first computes a direct classification from its rule engine, then refines it with hierarchy and context rules (evaluated in order):
- Epic — uses its own direct rule-based classification.
- Subtask — inherits its parent’s classification.
- Non-capitalizable parent — an issue whose parent is non-capitalizable inherits non-capitalizable.
- Bug completed after its parent shipped — treated as post-delivery maintenance → non-capitalizable.
- Bug completed before/during a capitalizable parent — treated as part of building the feature → capitalizable.
- Bug with no parent — non-capitalizable.
- Story or task under a capitalizable parent, completed before delivery → capitalizable.
- Story or task under a capitalizable parent, completed after delivery → non-capitalizable.
- Likely non-R&D work — an issue with no linked pull requests whose assignee has no linked Git account → non-capitalizable.
- Linked sibling signal — when all linked sibling issues agree, that signal is applied.
- Code composition — when no stronger signal is available, Antenna automatically flags the issue based on whether its code changes look like new development or maintenance.
Effort estimation
Every pull request and issue receives a level of effort from 1 (very low) to 5 (very high). The estimate is based on the size of the change — how many lines were changed and how many files were touched — taking the higher of the two dimensions so that a large change on either measure is reflected.
For issues, effort is derived from the number of linked pull requests and the total lines changed, and story points are used directly as the weight when present. When no effort can be estimated, a default weight of 3 is applied.
From effort to hours
Effort weights are converted into hours per contributor, per month, distributing each contributor’s available hours proportionally to where they spent effort — larger, more complex pull requests absorb a greater share of the month.
| Value | How it’s calculated |
|---|---|
| Availability | Hours the contributor is available that month (default 160; adjustable for vacation, part-time status, or non-development work) |
| Weighted hours (per PR) | Effort weight ÷ total effort weight across all their PRs × availability |
| Capitalizable hours | Sum of weighted hours across capitalizable pull requests |
| Non-capitalizable hours | Availability − capitalizable hours |
When a report is first generated (before review), capitalizable hours are seeded with a simpler estimate — the share of capitalizable pull requests times availability. Once a contributor is reviewed, the effort-weighted calculation above is used.
From hours to cost
Hours become dollars once finance supplies a fully burdened labor cost per contributor — the employee’s gross salary plus stock-based compensation and employer-paid taxes.
| Value | How it’s calculated |
|---|---|
| Hourly rate | Fully burdened labor cost ÷ (availability × 12) |
| Capitalized cost | Capitalizable hours × hourly rate |
| Expensed cost | Non-capitalizable hours × hourly rate |
Review, overrides, and confidence
Every classification carries a confidence level and a reason so reviewers can understand and defend it:
| Confidence | When it applies |
|---|---|
| High | Manual overrides, exclusions, and classifications backed by linked-issue evidence or parent-issue inheritance |
| Medium | Classifications from title/label rules or code composition |
| Low | No strong signal available, or signals that conflict or can’t be resolved |
When signals conflict or are inconclusive, the work is treated as non-capitalizable with low confidence and flagged for review. During review, finance and engineering can override any pull request’s classification and its level of effort. Overrides take top priority in the pipeline, are treated as high-confidence, and trigger an immediate recalculation of the contributor’s hours.
Exporting the report
Once contributors have been reviewed, you can export a spreadsheet to share with your finance or accounting team. The workbook includes:
- Contributors — a central list where each contributor’s fully burdened labor cost is entered. This value automatically flows into every other tab.
- Capitalization by Month — capitalizable, non-capitalizable, and total hours and spend for each month in the report.
- Capitalization by Contributor — the same split for each contributor within each month.
- Capitalization by Contributor by Pull Request — capitalized and expensed hours and spend for each individual pull request, adjusted by its level of effort.
You can export monthly reports covering a single reviewed month, or annual reports that aggregate all fully reviewed and finalized months in the year. Because effort and hours are already calculated, finance only needs to supply salary data to complete the capitalization figures.
Appendix: Capitalization Rules
This appendix summarizes the key accounting standards governing when software development costs may be capitalized under U.S. GAAP and IFRS.
ASC 350-40: Internal-Use and SaaS
ASC 350-40 applies to software built for internal use or cloud-based platforms (i.e. SaaS) where the customer does not take possession of the code. Capitalization begins when the preliminary project stage is completed, management authorizes the project, and it is probable the project will be completed. Capitalized costs include coding, configuration, and testing of new features or major improvements. Planning, training, and maintenance are expensed.
ASC 985-20: External-Use
ASC 985-20 applies to software intended to be sold, leased, or licensed for a customer to host on their own systems. Capitalization begins after technological feasibility is established—meaning all planning, designing, coding, and testing are completed to prove the product works. Research and development costs prior to feasibility are expensed.
IAS 38: Intangible Assets
IAS 38 is the global standard for internally generated software under IFRS. Capitalization starts during the development phase when a company demonstrates technical feasibility, the intent to complete the asset, and the ability to generate future economic benefit. Direct costs for creating and preparing the asset are capitalized. Research expenditure is recognised as an expense.