Skip to content

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:

  1. Project belongs to an Initiative and the Initiative has a cost centre → Initiative's cost centre.
  2. 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, intact

This 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_CLAIM mode (a CLIENT_BILLING or INTERNAL_COST Initiative is not capitalisable).
  • The period is { periodStart, periodEnd, claimPeriodKey } plus an optional jurisdictionCode (resolves from the org default when omitted — never silently hardcoded) and an optional R&D frameworkId.
  • 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.

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):

FieldMeaning
forecastCostForecast cost from allocations across the Initiative's projects
actualCostActual cost rolled up from effort
costVarianceforecastCost − actualCost
costVariancePctVariance as a ratio (ungated — a ratio leaks no £)
assignedFte / actualFte / fteVarianceThe 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

Flowstate Documentation