Design Spec — Phase 3 · rev B (FP&A)

Headcount planning for FP&A

Plan, forecast, actual — and the bridge that explains the gap. Consolidated from systems that disagree, and still refusing to assert what it cannot prove.

Audience FP&A Context eBay — AI builder / internal tools Live reqroom.thomaspeng.ca Status Awaiting approval

0 · Who this is for changes the design

This is a tool for FP&A, not for HR. That is not a cosmetic difference — it moves the spine of the model.

An HR headcount toolAn FP&A planning tool
Primary objectthe personthe plan version
Spinethe org chartthe cost centre — because it ties to the GL
Headline outputa headcounta variance bridge — plan vs forecast, explained
UnitpeopleFTE and dollars, phased by month
The question“who works here?”“why are we off plan, and what do we do about it?”

ELT and project remain — but as rollup and allocation dimensions on top of the cost centre, not instead of it. A number FP&A cannot reconcile to the general ledger is a number they cannot use.

1 · The variance bridge is the product

What a first draft gets wrong

“We are $2.1M under budget” is not an answer. It is the beginning of a two-week investigation that FP&A runs by hand, in a spreadsheet, every single month.

The answer FP&A actually needs is the walk — the decomposition of the gap into its drivers:

Plan (AOP)                          $24.0M    142.0 FTE
  − hiring slippage (6 reqs, ~1 qtr)  −1.4M    − 6.0     favourable, and temporary
  − attrition above plan (2.1 pts)    −0.9M    − 4.2     favourable now, a hole later
  + hired above planned level/geo      +0.2M      0.0     rate & mix — permanent
  + 2 incremental reqs not in plan     +0.3M    + 2.0     unbudgeted
  − backfill lag (avg 47 days)        −0.3M      0.0     timing only
─────────────────────────────────────────────────────
Current forecast                     $21.9M    133.8 FTE
Variance to plan                     −$2.1M    − 8.2 FTE

The drivers must sum to the variance. Exactly. If they don't, the decomposition is wrong — and the system says so rather than plugging the difference.

That is a hard check in this codebase's existing sense: a check that fails if the answer is wrong. A bridge whose drivers don't reconcile to the total is not a bridge, it is a plug — and “plug” is the word FP&A uses right before they stop trusting a tool.

Every driver is separately meaningful, and they carry different implications:

Timing (slippage, backfill lag)

Favourable this year, and reverses next year. Money you have not saved — only deferred.

Rate & mix

Hired at a higher level or a more expensive geo than planned. Permanent. It compounds into next year's run-rate.

Attrition

Favourable in-year, but it is a hole in capacity. The favourable variance and the missed roadmap are the same event.

Volume (incremental reqs)

Genuinely unbudgeted headcount. The only driver that is a real decision rather than a consequence.

2 · Plan versions — FP&A lives in re-forecast cycles

There is never one plan. There is the AOP (the annual operating plan, locked), then F1, F2, F3… — each re-forecast — and then actuals. FP&A is constantly asked “what did we think in F2, and what changed?”

This is already built

The ledger is bitemporal: it separates when something was true (valid time) from when we learned it (transaction time). Plan versions fall straight out of it. “Show me the F2 forecast as we understood it on 15 May” is ledger.asOf(validAt, knownAt) — a query, not a feature.

Every bridge is therefore version-to-version: AOP → F1, F1 → F2, F3 → actual. Not just plan → today.

3 · The cost centre is the spine; ELT and project hang off it

CostCentre is the anchor — it is what reconciles to the general ledger, and it is what a control total is published against. ELT is a rollup of cost centres (ownership). Project is an allocation dimension that crosses cost centres (a person in one cost centre can work on a project sponsored by another — that is cross-charging, and FP&A cares about it a great deal).

The trap

Nesting project under ELT asserts every project belongs to exactly one ELT. Usually false, and it makes shared platform work unrepresentable. The tree must be pivotable: Cost centre → Project → Role, ELT → Cost centre → Project, Project → Cost centre. The leaf is an assignment, not a person.

4 · Headcount and FTE are not the same number

A person split 50/50 across two projects is one head and 0.5 FTE on each. Roll that up and headcount double-counts while FTE stays correct.

FTE is the number that sums. Headcount is not.

Every rollup, total and dollar figure is computed in FTE. Headcount is a distinct-person count via set-union at each node, and is labelled non-additive across siblings. And because FP&A must tie to Finance, three lines are always distinct: Headcount (FTE employees), Total workforce (incl. contractors and interns), and Spend. Contractors are excluded from headcount and absolutely consume budget — collapsing these is how a workforce number stops reconciling.

5 · Canonical model additions

All bitemporal; all flow through the existing mapper, ledger and three-state reconciliation unchanged — so an allocation two systems disagree about becomes a contested claim for free.

EntityFieldsWhy FP&A needs it
PlanVersionversionId (AOP/F1/F2…), fiscalYear, lockedAtevery number is as of a plan version
ElteltId, name, leaderownership rollup
ProjectprojectId, name, sponsorCostCentreId, capitalizablewho funds it — cross-charging
AssignmentpersonId, projectId, allocation, validFrom/Tothe join. Without it, project spend is fiction
DeparturepersonId, lastDay, reason, noticeGivenAta known leaver — a fact, not a rate
RateCardrole, level, geo, employmentType, fullyLoadedAnnual, currencyfully loaded — never base salary
Assumptionscope, kind (attrition / time-to-fill), value, sourcedeclared, versioned, on the page

Person gains role. Req gains projectId, role, level, geo, expectedStart, backfillFor — a req is a to-be-hired head.

5.1 · backfillFor is not optional detail

The most common headcount lie

A req replacing someone who quit is not net-new headcount — it restores a seat attrition removed. Count backfills as growth and you overstate hiring by exactly your attrition rate, every quarter, invisibly. It also makes the variance bridge un-closeable, because backfill lag and incremental adds move in opposite directions.

6 · Spend

7 · Forecast — monthly, six quarters

forecast_fte(m) =   active_fte(m)            // fact:       people on the books
                  − known_departures(m)     // fact:       last day is a date
                  + tbh_arrivals(m)         // assumption: expected start
                  − modelled_attrition(m)   // assumption: a rate, not a person

Facts and assumptions are never blended into one line.

Actual

History, from the ledger.

Committed — facts only

Actuals, minus known departures, plus TBH with a confirmed start (offer accepted). A solid line.

Modelled — an estimate

Plus TBH at its expected start, minus modelled attrition. Drawn as a band, because that is what it is.

Plan

The selected plan version (AOP, F1, F2…), phased by fiscal month.

TBH is a distribution, not a head

An open req is a probability of a person, arriving after a realistic time-to-fill — a Staff engineer in the Bay Area is not a support hire in Bangalore. expectedStart = openedAt + timeToFill(role, geo). Where an offer is accepted, that date is a fact and the head moves to the committed line. Vacancy savings — budgeted heads not yet hired — is a first-class favourable variance, not an accident of the maths.

8 · The honesty rules carry forward

The sharpest thing in this spec

If the PPM tool and a team’s tracker disagree about who is on Project Atlas, and no rule has authority to pick, then Atlas’s FTE is null — and therefore its spend is null. The page says: “we cannot tell you what Atlas costs, because HRIS and the PPM tool disagree about who works on it.” To an FP&A analyst who has been burned by a confident wrong number in a board deck, that is the most valuable sentence in the product.

9 · Where the data comes from — and disagrees

SourceContributesConflict
ppmprojects, assignmentsThese two disagree about allocations — deliberately. It drives a contested project spend: the sharpest demo in the product.
sheet_da team’s own view of who is on what
hrisrole; departures
atsprojectId, backfillFor, expectedStart
financerate card, plan versions, assumptions

Both new sources are mapped cold by the existing agent — no hand-authored mappings, traces committed, graded against a blind golden key. Same rules as every source before them.

10 · Surface

All zero-runtime-LLM, replayed from committed artifacts.

11 · What a first draft would have missed

MissConsequence for FP&A
A headcount number with no variance bridgeAnswers a question nobody asked. The analyst still rebuilds it by hand.
Drivers that don't sum to the varianceA plug. The moment FP&A finds one, the tool is dead.
One plan, not versions (AOP / F1 / F2)Cannot answer “what changed since last forecast?” — the core monthly ritual.
Timing and rate/mix blended togetherDeferred spend looks like saved spend. Next year's budget is set wrong.
Counting backfills as growthOverstates hiring by the attrition rate, every quarter.
TBH with no start dateAssumes every open req is filled tomorrow. Phasing badly wrong.
Annual spend instead of monthly phasingA November hire billed as a full year.
Base salary instead of fully-loaded costUnderstates by 25–40%. Finance rejects the tool.
Contractors folded into “headcount”Either the headcount or the spend is wrong. Usually both.
Adding headcount across a shared-people treeDouble-counts. The totals will not tie to the GL.
No exit run-rateCannot seed next year's budget — the CFO's second question.
Project nested under ELTShared platform work and cross-charging become unrepresentable.
Also worth knowing

Per-source data freshness matters — a three-week-old Anaplan pull beside today's HRIS is a silent trap, and FP&A closes on a calendar. Multi-geo needs FX. And someone must own the definition of headcount when two systems disagree, which is exactly what the contested state forces into the open instead of leaving it to be settled in a meeting.

12 · Explicitly out of scope

The optimizer (allocate a fixed budget and req ceiling across projects, with shadow prices) and interactive what-if levers. Both are attractive; neither is worth building on numbers FP&A has not yet agreed on. The bridge comes first — it is what makes the numbers arguable in the first place.