Appearance
Budget requests
Change requests with team-by-team proposals, approvals, and a full audit trail. This is how budgets actually get amended between snapshots.
A budget request is the formal mechanism for changing the active budget. When the team needs more headcount or budget than the current snapshot allows, you raise a request. Affected team managers get the request in their inbox, write proposals, the proposals get reviewed and approved, and when everything is approved the request finalises into a new snapshot.
The request lifecycle
DRAFT (request being prepared)
-> ACTIVE (sent to team managers, proposals being collected)
-> READY (all proposals approved, awaiting finalise)
-> FINALISED (new snapshot created, supersedes the previous active)
-> CANCELLED (request abandoned)
-> LOCKED (read-only after finalise; preserved for audit)The list page on budget snapshots shows ACTIVE and READY requests in the Upcoming section. CANCELLED and LOCKED requests are filtered out — but they are still queryable via the API.
The request detail page
Lands at /plan/[planId]/cost-forecast/budgets/requests/[requestId]. Three sections:
Header
Title, fiscal year label, due date, and the action buttons available to admins:
| Action | When |
|---|---|
| Finalise | Visible when every proposal is APPROVED or MERGED. Creates a new snapshot, supersedes the active one |
| Lock | Marks the request as read-only without finalising. Use when the request gets superseded by a different decision |
| Cancel | Abandons the request. All proposals are voided |
Progress strip
Compact summary across the top of the workspace:
- Proposal counts by status (submitted, approved, rejected, pending).
- Aggregate metrics: net cost delta and net FTE delta if every pending proposal were approved as-is.
- Renders only when the viewer has
FINANCIALS_VIEW_SUMMARY.
Hierarchy tree
Below the progress strip, the team hierarchy tree. Every team in the affected scope shows up. Each team node shows:
- Whether a proposal exists for that team.
- The proposal status (submitted, approved, rejected, merged).
- The assignee — usually the team manager.
- Submitted, approved, rejected, merged timestamps.
Click into any team node to land on the proposal detail page.
Proposal detail
Lands at /plan/[planId]/cost-forecast/budgets/requests/[requestId]/proposals/[proposalId]. Three columns:
| Column | Purpose |
|---|---|
| Header | Breadcrumb back to the request, team name, status, action buttons (submit, approve, reject) |
| Composite change list | Changes from this proposal plus changes from descendant team proposals — so a department head sees the rolled-up impact, not just their own changes |
| History timeline | Every BudgetProposalHistory entry: who submitted, who reviewed, who commented, who approved |
The composite view comes from budgetCompositeView — it joins this proposal's changes with every descendant team's proposal changes, so the picture you see at a parent team includes the children.
The comment thread sits alongside the history. Comments are first-class — proposals get reviewed in conversation, not just by status changes.
What proposals can change
A proposal can adjust:
- Headcount per team (add vacancies, remove planned hires).
- Contractor budget per team.
- Project allocations.
- AI agent seat counts.
What it cannot do directly: change salaries, geographies, or job role definitions. Those are workforce-engineering changes — make them in Workforce first, then raise a budget request to amend the budget around the new shape.
Permissions
- View a request: any user with access to one of the teams in scope.
- Submit a proposal: the team's manager or one of the configured proposal writers (see cost review workflow for the budget approval config).
- Approve, reject, finalise, lock, cancel: configured per org via the budget approval config — typically a small group of finance leads.
Related
- Variance overview — the full variance loop.
- Budget snapshots — where finalised requests land.
- Cost review workflow — review cadence and budget approval setup.