Appearance
Initiative finance
The Initiative is the finance anchor. This page is the finance-side mechanic: how a project's cost centre resolves through its Initiative, how CapEx/R&D claims anchor and avoid double-counting, and how variance rolls up.
For the conceptual model — the Initiative/Project split, the inert gate, Finance Mode, the OKR tree — start with Initiatives (finance anchor).
Cost-centre inheritance
A project no longer owns its finance outright. Its cost centre resolves through the Initiative-first chain:
- Project belongs to an Initiative and the Initiative has a cost centre → Initiative's cost centre.
- Otherwise → project's own cost centre.
The Finance Mode resolves the same way (the project inherits its parent Initiative's mode), and capitalisable is derived from both.
Dormant-on-adopt
When you adopt a project into an Initiative, the project's own cost centre is not discarded — it is stashed:
adopt: LiveProject.costCentreId ──► LiveProject.dormantCostCentreId
LiveProject.costCentreId := null
LiveProject.initiativeId := <initiative>
→ the Initiative's cost centre now governs
detach: LiveProject.costCentreId := LiveProject.dormantCostCentreId
LiveProject.dormantCostCentreId := null
LiveProject.initiativeId := null
→ the project's own cost centre is restored, intactThis makes adoption reversible and lossless. Detach an Initiative-adopted project and it falls back to exactly the cost centre it had before — no re-keying, no lost binding. The mechanic is enforced server-side in adoptProjectIntoInitiative / detachProjectFromInitiative; the API surface is initiativeAdoptProject / initiativeDetachProject.
One parent only
A project can be adopted by at most one Initiative. Adopting a project that already has a parent throws PROJECT_ALREADY_ADOPTED (with the current parent's id in extensions.currentInitiativeId). Detach it first, or adopt into the Initiative you actually want.
The inert consequence
A synced project with no cost centre and no Initiative is inert — it contributes nothing to CapEx or the forecast. This is deliberate: a PMS sync cannot silently inflate your capitalised spend. Finance only books what a human anchored, either by assigning a cost centre or by adopting into an Initiative.
CapEx / R&D claims
Claims in the Initiative model are pull-based and anchored, replacing the per-project-only flow. A CapexClaim is a header — a reporting period, a jurisdiction, a status — and its CapexClaimProject rows are the evidence set (one per project). Per child project, Flowstate reuses the existing capitalisation machinery (the ProjectCapitalisation scaffold, project evidence, and AI-drafted rationale) — it never re-implements evidence or rationale.
There are two ways to raise a claim:
Initiative-anchored claim
Anchor a claim at an Initiative and Flowstate auto-pulls its child projects as the evidence set.
- Only valid when the Initiative is in
CAPEX_RD_CLAIMmode (aCLIENT_BILLINGorINTERNAL_COSTInitiative is not capitalisable). - The period is
{ periodStart, periodEnd, claimPeriodKey }plus an optionaljurisdictionCode(resolves from the org default when omitted — never silently hardcoded) and an optional R&DframeworkId. - API:
initiativeCapexClaimCreate.
Ad-hoc claim
Raise a claim over a hand-picked set of projects with no Initiative anchor — for the long tail that does not warrant an Initiative.
- API:
adHocCapexClaimCreate. - An ad-hoc claim can be promoted to an Initiative-anchored one later via
capexClaimConvertToInitiative— useful once a one-off body of work grows into a funded Initiative.
The double-count guard
The cardinal rule: one claim per project per period. A project may appear in only one non-rejected claim for a given claimPeriodKey — the normalised period key (e.g. a fiscal-year code) is the double-count axis.
When you try to add a project that is already claimed for that period, the claim creation throws PROJECT_ALREADY_CLAIMED. The error carries the conflicting claim in extensions so the UI can deep-link straight to it:
json
{
"message": "Project already claimed for this period",
"extensions": {
"code": "PROJECT_ALREADY_CLAIMED",
"conflictingClaimId": "clx_claim_id",
"liveProjectId": "clx_proj_id"
}
}A rejected claim releases its projects — they become claimable again for that period. This applies identically to Initiative-anchored and ad-hoc claims, so an Initiative claim and an ad-hoc claim can never quietly capitalise the same project twice.
Permissions
The whole CapEx-claim surface — capexClaims, capexClaim, and all three create/convert mutations — requires FINANCIALS_VIEW_SUMMARY. Initiatives themselves are readable with ROADMAP_INITIATIVES_VIEW; money fields on them are gated by FINANCIALS_VIEW_SUMMARY and zero out without it.
Variance — the headline
Because planned commitment lives on the Initiative and actuals roll up from its projects, forecast-vs-actual variance is the headline finance metric for an Initiative. It is exposed as Initiative.varianceSummary(startDate, endDate):
| Field | Meaning |
|---|---|
forecastCost | Forecast cost from allocations across the Initiative's projects |
actualCost | Actual cost rolled up from effort |
costVariance | forecastCost − actualCost |
costVariancePct | Variance as a ratio (ungated — a ratio leaks no £) |
assignedFte / actualFte / fteVariance | The same comparison in FTE |
Alongside it, four supporting rollups drill into each side: plannedCommitment (committed FTE + AI budget), forecast (assigned FTE + forecast cost), effortActuals (actual FTE + cost), and aiSpend (AI cost from telemetry sessions stamped with the Initiative). All money fields are gated behind FINANCIALS_VIEW_SUMMARY; FTE and counts are always visible. See API → Initiatives → Rollups.
For client-billing Initiatives, the same variance read still applies, but you read it against budgetedCost and marginPct — billed-vs-budgeted rather than forecast-vs-capitalised.
Operating-model settings
The nouns and finance terms are workspace-configurable at Settings → Operating Model:
- Terminology — relabel Initiative / Objective / Project and the capitalisation terms (
entityTerminology). - Preset — pick an archetype (
operatingModelPreset) that seeds defaults — e.g. an internal product company (CapEx/R&D-first) vs an agency (client-billing-first).
This drives the visible labels only; the finance model underneath is the same. The change is applied through organizationOperatingModelUpdate, gated by SETTINGS_ENTITY_CONFIG_UPDATE.
Where to go next
- Initiatives (finance anchor) — the conceptual model.
- API → Initiatives — types, queries, mutations, error codes.
- Cost Capitalisation — the per-project review surface that the claim evidence reuses.
- Variance Tracking — budget snapshots and cost-review workflow the variance feeds.