How Variance Management Controls earn their keep in Idraa's Monte Carlo — a walk from FAIR-CAM's control taxonomy, through one Greek letter, to a million simulated years. With receipts.
seed 42 · N = 1,000,000 · κ = 0.5 · FAIR-CAM §2.2, §4 · 2026-07-23
FAIR-CAM splits the control universe by how a control touches risk. Only one kind ever touches the FAIR graph directly.
The shield. EDR, MFA, firewalls, backups. Directly affect the frequency or magnitude of loss events — they map onto FAIR nodes (TEF, Vulnerability, Loss Magnitude).
The maintenance crew. Config monitoring, patching cadence, pen tests. They keep the shield functioning. FAIR-CAM puts them in the "indirectly affect risk" box — no FAIR node of their own.
The advisors. Threat intel, asset management, threat modeling. They improve the decisions that shape controls. Same box: indirect, no node. Idraa routes them like VMCs — a documented proxy.
FAIR-CAM §2.2 p.5 draws the direct/indirect boundary; §4 p.21 says variance management acts on the operational performance of other controls. That sentence is the whole design.
Every symbol in this deck is one of these. Thirty seconds here makes every later slide read like a sentence.
VaR 95 reads as "the 1-in-20-year loss". The 20 is a long-run frequency: each year crosses the level independently, with probability 5%. Run many 20-year windows and they come in three flavors:
Independence across years holds by construction in the Monte Carlo — one trial is one year (Part III). Real-world threat trends or clustering would loosen the return-period reading; that is a model-scope caveat, not a math one. One boundary case: a portfolio quiet enough that 95%+ of simulated years lose $0 puts VaR 95 itself at $0 — the yearly crossing probability drops below 5% and every figure above becomes an upper bound.
A good maintenance crew doesn't make the shield stronger. It shrinks the windows when the shield is quietly broken.
The naive form 1 − downtime/MTBF goes negative once downtime exceeds the failure cycle. The cycle-based form above is safe on the whole domain. Small print matters.
Before any coupling, every VMC and DSC assignment composes into one meta-effectiveness in [0, 1] — using FAIR-CAM's own gate logic.
Wait — how do you OR probabilities? By computing the probability of the Boolean sentence. For one arriving threat event, "piece i does its job" is a true/false event with success probability xi. Under independence, P(A ∧ B) = a·b and P(A ∨ B) = 1 − (1−a)(1−b) — the "noisy-OR" of Bayesian networks. Example: a = 0.7, b = 0.8 → ∨ = 0.94, ∧ = 0.56. Feed in only 0s and 1s and both collapse to the classical truth tables — the lift generalizes Boolean logic, it doesn't replace it. Both are monotone: improving any control never worsens the composite.
Two honest caveats — (1) independence is an assumption: common-cause failures (same agent, same admin) make noisy-OR optimistic. (2) Weak-∧ is NOT a probability lift — Σwixi is a weighted average, chosen because §3.3 says deficiencies "diminish but don't necessarily inhibit": missing one Response sub-function shouldn't zero the others. Partial credit by design, and labeled as such.
fair_cam/composition.py:99,129,182 · risk_engine/group_composition.py:325–392
The entire mechanism: every Loss Event Control carries an authored reliability r0 — its uptime absent the crew. The crew buys back part of what's missing:
In words — r₀ is the authored reliability: the share of time the shield runs on its own ops, before any crew helps. 1 − r₀ is the headroom: the missing uptime, all a crew could ever add. E_meta is the crew's composed strength from the previous slide (0 = no crew, 1 = perfect crew). κ (kappa) is the coupling gain: what fraction of the headroom a perfect crew actually recovers — pinned at one-half. So: effective reliability = own ops, plus κ·Emeta of whatever was missing.
| E_meta | r_eff (r₀=0.60) | r_eff (r₀=0.90) |
|---|
Linear, monotone, bounded by 1 — and the weaker the shield's own ops, the more the crew is worth. κ is implementation calibration, non-identifiable at single-org scale — reported as ranges, not truth (last slide). fair_cam/models/composition_topology.py:301,331 · risk_engine/group_composition.py:411
Graphite = what the shield's own ops deliver. Blue = headroom the crew buys back (κ·Emeta of it). Hollow = reliability nobody recovered. The crew's dollar value in a run is exactly the risk priced through that blue band — nothing else.
FAIR-CAM fixes the direction (crews improve other controls' uptime), the floor (no crew → nothing changes) and the ceiling (uptime can't exceed 100%). It is silent on how much of the gap a perfect crew closes. Some number must be chosen — better to choose it in the open.
With no evidence favoring any value, the midpoint is the least-opinionated choice: a perfect crew halves the reliability gap. It's locked by a test — changing it is a visible, reviewed decision, not a tuning knob.
Successful attacks are rare, and κ's fingerprint on your numbers looks exactly like slightly different authored reliabilities. One organization's history cannot tell κ = 0.3 from κ = 0.7. A fitted value would be fake precision.
Every run re-computes every control's value 256 times with κ (and the routing weights) wiggled around their pinned values — more wiggle near the middle, never past the 0-and-1 walls. That's why every dollar figure ships as a range (the p5 / p50 / p95 rows in the verification workbook), not a single number. The uncertainty about κ is inside the range, not hidden behind it. Dots above: 48 of those draws, illustrative spread.
Mechanics, for the record: logit-normal perturbation (param "meta.kappa"), same spread setting as the node-routing weights — the weight-robustness ensemble (#419).
reff never touches a FAIR node by itself. It rides through the same five-stage pipeline as every other control effect:
In words — stage 3's (1 − E·w): E is the group's composed effectiveness (0–1), w is how strongly that group is allowed to move that FAIR node. A group with E = 0.6 and w = 0.9 multiplies vulnerability by 1 − 0.54 = 0.46 — it removes 54% of it. Multipliers from different groups stack by multiplication, and stage 4 applies the product to every one of the million sampled years.
Part II left us holding one number: the shield is up A = 81% of the time. What should the simulation do with it? Here is the fork, from scratch.
What one trial does — each Monte Carlo iteration builds one hypothetical year: how many attacks arrive (TEF), whether each succeeds (Vulnerability), what each costs (Loss Magnitude) — then totals the bill. A million iterations = a million plausible years; every number Idraa reports is read off that pile. The fork: where does the shield's downtime enter the recipe?
When an attack arrives, flip a weighted coin: with probability A the shield is up and the attack faces the protected success rate vup; otherwise it catches the shield down and faces the bare vbase. More dice — it feels like what a simulator is for.
Skip the coin. Give every attack the blended success chance A·vup + (1−A)·vbase — the probability-weighted average of the two worlds, computed with algebra instead of dice. This is what Idraa ships (the docs call it the deterministic multiplier).
Anyone who has built a simulator should squint at the right-hand card: averaging before you simulate sounds like a shortcut that erases the very variance you came for. The next four slides take that suspicion seriously:
The coin-toss picture usually smuggles in a second assumption: that each trial is a single attack moment, so you flip the coin once per trial. Idraa's trials don't work that way, and the difference is not pedantry.
TEF is drawn in events per year. One iteration = one candidate year, with (say) 6.7 threat events, ~12 shield failures, and ~12 repairs inside it.
With failure cycles of days-to-weeks, each threat event inside the year independently finds the shield up with probability A. The year averages over the crew's whole schedule.
Sampling shield-state once per trial asserts the shield stays broken for an entire year. That's not a maintenance model — that's abandonment.
The blend, with numbers — A = 0.8, vup = 0.1, vbase = 0.5 → every event succeeds with 0.8·0.1 + 0.2·0.5 = 0.18. The next slide proves this blend and the per-event coin are indistinguishable — law of total probability, not a shortcut.
Per-event coin flips and Idraa's deterministic multiplier are not merely close. For within-year failure cycles they are the same distribution.
In words — "marginalize" means: average over the coin before looking at it. A coin flip (shield up, probability A) feeding a second coin flip (attack succeeds, vup or vbase) is still one coin flip — at the blended rate. That collapse is Bernoulli thinning, and it's exact, not an approximation.
So the "weighted coin flip per attack" story and the reff multiplier agree exactly — in expectation always, and event-by-event in distribution whenever the crew's repair clock runs faster than the calendar. The coin was already flipped, analytically.
The one assumption doing work: events see the shield independently. Short outages, many cycles per year → true enough. Year-long outages → "Where doubt lives", two slides ahead.
Same scenario (PERT-ish TEF, triangular vulnerability, lognormal severity, A = 0.811, Efull = 0.807): Idraa's deterministic multiplier vs the two coin-flip variants.
| metric | pencil & paper | Idraa (blended probability) | coin flip per event | coin flip per year |
|---|---|---|---|---|
| mean LEF | 1.2271 | 1.2268 | 1.2270 | 1.2248 |
| mean ALE | $181,614 | $181,682 | $181,817 | $181,270 |
| VaR 95 | — | $561,417 | $706,962 | $667,848 |
| VaR 99 | — | $1,080,224 | $1,524,294 | $1,606,370 |
| ES 95 | — | $906,436 | $1,254,711 | $1,297,632 |
The pencil-&-paper column — four averages multiplied, no simulation: average attacks/year (6.667) × average baseline vulnerability (0.5333) × the shield factor (0.34512) × average loss per event ($148,003) ≈ $181.6k. In symbols: E[TEF]·E[v]·(1−A·Efull)·E[LM], where E[X] = "the average of X". All three simulated means land on it to a third decimal.
The tail columns — VaR 99 = the annual loss only 1-in-100 simulated years exceeds; ES 95 = the average loss across the worst 5% of years. The per-event column's fatter tail is mostly the randomness of how many attacks land in a given year — a noise source FAIR's LEF = TEF × Vuln convention deliberately averages out everywhere, for every control effect, not just for VMCs.
The averages agree. The tails don't — and that difference is the honest part of this story →
Now make the coin flip once per year: the shield is either up all year or broken all year. The average loss doesn't move — but the bad years get much worse.
How to read this chart — each curve answers "what fraction of years lose more than $x?" Where the orange curve sits above the blue one, year-long outages make big-loss years more likely. Both axes are logarithmic — each gridline is 10×.
| loss x | P>x, deterministic | P>x, per-year flip |
|---|
When is the year-long-outage model the right one? When breakage persists — configuration drift nobody audits, agents dead for quarters: exactly the weak-crew world. FAIR-CAM prices reliability as a fraction of time (what Idraa implements); year-long persistence is a tracked extension (issue #434), not a correctness bug. Averages, ALE, ROI and NPV are identical either way.
All VMC/DSC value flows through reff = r₀ + (1−r₀)·κ·Emeta into co-present shields' opeff. No direct FAIR-node targets; no double counting. A crew with no shield to maintain — or a one-legged ∧-pair — prices at $0, by design.
The expected-value multiplier is the per-event coin flip, integrated exactly (Bernoulli thinning). Means, ALE, ROI, NPV: identical. No fidelity was lost where the money is computed.
Year-persistent outages would fatten VaR/ES beyond what time-fraction reliability shows (+49% VaR99 in our stress case). Known, bounded, tracked — and reported honestly rather than modeled implicitly.
Epistemic status: κ = 0.5 is implementation calibration —
non-identifiable from single-org data, so the weight-robustness ensemble perturbs it (logit-normal,
param "meta.kappa") and every control value ships as a range across 256 draws, not a point.
The authored r₀ convention: expected reliability absent co-present crew uplift.
fair_cam @ yasirhamza/idraa · composition.py · models/composition_topology.py ·
risk_engine/{group_composition,control_aware,fair_core}.py · simulation: seed 42, N=10⁶, A=0.811