What-If Tab — Feature Guide


What it's for
The What-If tab is the project's sandbox: a place to test how velocity changes, estimate inflation, scope growth, and capacity changes affect the delivery forecast — without touching real data and without writing anything back. It pairs deterministic what-if sliders with a probabilistic Simulation mode (Monte Carlo) and an AI chat that proposes coherent slider values from a free-form question.
The audience is delivery managers, programme leads, and product owners who need to answer questions like what if we lose Alice for the next sprint?, what if scope grows 20%?, or what if we add a developer? The tab makes the answer visible as a cascade chart, an S-curve, or a dollars-and-deadlines KPI line — and as soon as the user navigates away, the project is exactly as it was before.
View toggle (Sprint vs Project)
Two view buttons at the top of the panel — Sprint and Project — switch between the sprint-level (RiskSensitivityPanel) and the weekly time-axis (PlanRiskPanel) views.
- Sprint view is shown when the project has sprints configured and sprint mode is on.
- Project view is shown when at least one issue has a due date.
- When only one view is possible the toggle is hidden and that view loads automatically.
- In Program-All mode (every project at once) only the Project view is available — sprint cadences differ across projects, but ISO weeks are absolute and aggregate cleanly.
The two views keep independent state, so flipping between them does not lose unsaved slider positions.
Sprint view (RiskSensitivityPanel)
Sliders
Four horizontal sliders, range −50% to +50%:
- Velocity — scales sprint capacity. Negative = team running slower than recent history; positive = faster.
- Estimation — scales sprint demand. Negative = work smaller than estimated; positive = larger.
- Scope — scales sprint demand. Negative = backlog tightening; positive = scope growth.
- Capacity — scales sprint capacity directly. Negative = absences / context-switching; positive = headcount or efficiency.
Velocity and Capacity multiply together when both are non-zero (capacity *= (1 + velocity/100) × (1 + capacity/100)). Estimation and Scope multiply together on the demand side identically.
Dragging any slider re-runs the cascade simulation in real time. Releasing the slider commits the value to local component state — there is no save button.
Preset buttons (What-If mode)
Three single-click buttons that snap the four sliders to canonical values:
- Conservative — velocity −15, estimation +15, scope +20, capacity −15.
- Realistic — 0, 0, 0, 0 (the baseline).
- Optimistic — velocity +10, estimation −10, scope −10, capacity +10.
Selecting a preset highlights its button. Dragging any slider afterwards clears the highlight and switches back to freeform.
Per-user override mode
A toggle reveals a per-user override panel where the four sliders can be set independently per team member (e.g., Alice at −20% velocity for this month). The cascade chart then evaluates each member's contribution with their own multipliers before stacking. A reset link clears all per-user values back to the global slider state.
Cascade chart
The right-hand panel is a stacked cascade bar chart. One bar per sprint along the X-axis; demand on the Y-axis in points or hours.
- Stacked segments — bars are stacked by assignee, each segment in the deterministic name-hash colour. An Unassigned segment sits on top in grey.
- Capacity line — a thin horizontal mark inside each bar at the sprint's total capacity.
- Cross-hatched overflow — when demand exceeds capacity, the excess renders as a 45° red cross-hatch pattern stacked above the green segment, visually carrying spillover to the next sprint.
- Ghost baseline bars — when sliders are non-zero, faded ghost bars sit behind the active bars showing the zero-adjustment baseline. The delta is the visible difference.
- Virtual sprints — when overflow extends past the last planned sprint, the chart appends faded virtual columns labelled +1, +2, etc., sized at the team's average sprint capacity.
- Markers — a vertical purple line marks the Target sprint; a vertical line marks the Projected completion sprint, green when P ≤ T and red otherwise.
A legend below the chart explains the assignee colours, the unassigned grey, the overload cross-hatch, the capacity line, and the ghost baseline.
KPI row
Above the cascade chart, four stat cards: Remaining work, Capacity to target, Forecast date, Feasibility score. They use the same shared utilities as the Dashboard cards, so the values update live with each slider drag.
Per-slider risk statement
Each slider has a one-line plain-English statement that updates as the user drags. The statement names the affected sprint (e.g., Overflow begins in Sprint 6, completion pushed to Sprint 9) so the consequence of the slider change is always one glance away.
Simulation (Monte Carlo) mode
Switching to Simulation mode replaces single-point sliders with low/high range pickers and replaces the cascade chart with an S-curve.
Range presets
The same three preset buttons in simulation mode set range bounds instead of single values:
- Conservative — broader negative tails: velocity
−25 to +5, estimation−5 to +30, scope−5 to +30, capacity−20 to +5. - Realistic — moderate spread: velocity
−15 to +10, estimation−10 to +15, scope−5 to +15, capacity−15 to +10. - Optimistic — narrows pessimistic tails, widens optimistic ones: velocity
−5 to +20, estimation−15 to +5, scope−10 to +5, capacity−5 to +15.
S-curve chart
X-axis is sprint index (fractional 0.5 steps allowed). Y-axis is cumulative probability of completing by that sprint.
- The chart is built by running the cascade simulation many times (default 5,000 in the forecast engine; 10,000 in the dedicated Risk panel) with each run drawing values randomly inside the ranges.
- Each run applies a 50/50 split between a single global trend factor (everyone has a similar good or bad sprint) and per-user noise (individuals still vary independently).
- The chart fits a Catmull-Rom spline through the cumulative-probability histogram so the curve reads smoothly.
- A green dot marks the P85 crossing (planning-safe sprint); a purple dot marks the target sprint with its on-time probability label.
- Optional ghost curve in faded grey shows a baseline scenario for before/after comparisons.
Simulation KPI row
Above the S-curve:
- Target Sprint — dropdown to override the goal; shows a
*badge when manually set. Defaults to the last sprint with demand or the project's target date sprint. - On-target probability — % of runs that finished on or before the target. Green ≥ 70, amber 50–69, red < 50.
- Finish on Time? — verdict pulled from the probability: Yes / Maybe / No.
- Expected slip — average sprints late among runs that missed; green when 0, amber ≤ 1, red > 1.
AI Chat (Sprint view)
A chat card sits below the cascade chart with placeholder text Ask a question about the project… and an Analyse button.
The user's free-form question is sent along with a structured payload: per-sprint capacity / demand / overflow, per-issue details, team context, per-assignee workload, time off, holidays, velocity history, backlog summary, and a one-line current-status string (On track, 2 sprints late at baseline, etc.).
The model is asked to return a single JSON object with this shape:
- summary — 2–4 sentence narrative answer.
- impactAssessment — four cards: capacityImpact, scheduleImpact, riskImpact, teamImpact, each with severity (positive / negative / neutral), a short label, and a one-sentence detail.
- recommendations — 2–4 bulleted actions with priority high / medium / low.
- simulatorAdjustments — proposed slider deltas in percentage points (
{velocity: 0, issueEst: 0, scope: 0, capacity: 0}). - sprintAdjustments — per-sprint absolute deltas:
[{sprintName, capacityDelta, demandDelta, reason}].
The first {…} block in the response is parsed (the rules tell the model not to leak preamble, but the parser tolerates it). The four sliders are written back from simulatorAdjustments, clamped to ±50. Per-sprint deltas are validated against the actual sprint name list and applied as absolute values to the sprint's capacity and demand. The cascade chart re-runs immediately with the new inputs; the user sees the slider positions move and the bars shift.
The AI never computes the forecast itself — it only proposes adjustments, and the deterministic engine applies them.
No-key state
When neither aiApiKey nor anthropicApiKey is configured, the chat box reads Add your Anthropic API key in Settings → AI Features to enable AI analysis and the textarea / button are hidden.
Loading / error
While the AI call is in flight the Analyse button reads ⏳ Analysing… and is disabled. Auth errors are caught and shown as Invalid API key. Check your key in Settings → AI Features. Other errors render the model's error text.
Project view (PlanRiskPanel)


Same chart and chat shape as Sprint view, but the X-axis is ISO calendar weeks (Mon–Sun) and the demand is bucketed by the issue's due date. When an issue has both start and due dates the demand is spread evenly over the spanned weeks, prorated by the weekday-overlap fraction (a week the range only touches Mon–Wed counts as 3/5 of the issue's weekly share).
Weekly grid
Above (or below, depending on layout) the cascade chart, a table shows each visible week with three columns: Capacity, Demand, Balance. Cells turn red when balance is negative and green when positive. The grid is the source of truth for the chart's per-bar values.
Undated issues alert
Issues without due dates are surfaced as a small alert beneath the chart so the user knows they were excluded from the weekly grid (rather than silently ignored).
Project-view KPI row
Same four cards as Sprint view, but capacities are aggregated over the visible week range instead of sprint range. The Deliverability verdict card lists the over-capacity week count, total overflow points, and forecast slip in weeks.
AI Chat (Project view)
Same JSON schema as Sprint view, but the payload is week-bucketed and the response's sprintAdjustments apply to weeks keyed by names like Week of Jan 20. Rules block, response schema, and apply-back contract are otherwise identical.
Cross-cutting modes and empty states
- Demo / Regression mode — synthetic sprints, issues, and team data; AI Analyse button is disabled in regression so e2e tests don't burn API quota.
- No data — Sprint view — No Sprint Data — Configure sprints or enable Test Mode.
- No data — Project view — No Plan Data — Configure JQL or enable Test Mode.
- No due dates — Project view — Issues Need Due Dates — Plan Risk uses due dates to build a weekly timeline.
- Estimation mode — bar labels switch between pts, hrs, days depending on the project's mode and time unit.
- Program-All mode — Sprint view button is hidden, only Project view available.
How the numbers are computed
- Cascade simulation — see ALGORITHMS section 1 (Delivery Forecast) and the slider semantics in the Appendix.
- Monte Carlo — section 2 (Monte Carlo Delivery Confidence). Default run counts: 5,000 in the forecast-engine version, 10,000 in the Risk-panel S-curve version.
- Weekly bucketing — section 5 plus the Plan-Risk weekly bucketing variant; the weekday-overlap proration uses the ISO-week utilities documented in the Foundation Utilities section.
- Feasibility score — section 8.
- AI prompt + response schema — sections 18 (What-If Sprint AI) and 19 (What-If Project AI).
Effects on other parts of the app
- Slider state is ephemeral — closing the tab or reloading the page resets every slider and per-user override. Nothing writes back to the project config or to Jira.
- Dashboard AI Insights link — when the Dashboard's AI suggests simulatorAdjustments, the Open the What-If tab to explore this scenario interactively link opens this tab with those values pre-applied.
- No effect on the deterministic forecast outside this tab — the Sprints, Scope, and Dashboard forecasts all read the project config (not the What-If sliders), so they stay on baseline until the user changes the underlying configuration explicitly.
- AI fallback alignment — Auto-Level AI Review and Risks Accept dialog use the same provider/key configured in Settings; if the key works in this tab it works everywhere.