Define the outcome before the disruption
The exercise starts with funds close in a fictional service. The question is whether the team can complete the required flow when identity becomes unavailable. Define covered operations, timing, data, people, dependencies, and acceptance criteria. Then choose a disruption connected to plausible weaknesses, such as the vault depending on that same identity. The March 2021 BCBS principles frame severe but plausible scenarios and critical-operation dependencies. The workshop uses that framing to formulate an original hypothesis; it does not assume that BNP Paribas has this architecture or this limit.
Interpret the number before comparing it
An ordinal score of eight does not automatically represent twice the euros of a score of four. Identify the scale and rationale. NIST SP 800-30 Revision 1 distinguishes qualitative, quantitative, and semi-quantitative approaches and discusses uncertainty. In our explicit model, a ten-percent chance of losing ten thousand and a ninety-percent chance of zero gives a mean of one thousand. Another model with a one-percent chance of one hundred thousand also gives one thousand. Means match, but consequence conditional on the second event is ten times larger. Tolerance, capacity, and objectives may justify different responses.
Make dependence visible
If two controls consult the same incorrect directory, both may fail for the same reason. Do not multiply marginal rates as if independence were demonstrated. In the invented calculation, P(A)=10% and P(B given A)=40% give P(A and B)=4%. An independent model with two ten-percent probabilities would give 1%, but that is a different set of assumptions. No value was estimated from real incidents. The same question applies to providers: two brands can use the same center, specialists, or infrastructure. Map the chain delivering the outcome and identify an alternative still available when the common cause occurs.
Use the outcome clock
The sequential model allows fifteen minutes to detect, twenty to mobilize, forty to restore, and twenty-five to validate. That is one hundred from disruption to usable outcome. Restoration can meet a sixty-minute component objective while the service misses a ninety-minute target. Report both facts. Do not redefine the starting point after seeing the result. A proposal reduces the sequence to five, ten, forty, and twenty: seventy-five. That calculation fits the target but still needs demonstration. If restoration rises to seventy, the total rises to one hundred five.
Assess mitigation with continuing arrivals
The queue starts with two hundred cases and receives twenty per hour. One reviewer completes fifteen, leaving five more per hour; after four hours two hundred twenty remain. Three independent reviewers completing fifteen each give forty-five gross and twenty-five net, requiring eight hours to drain. Four give sixty gross, forty net, and five hours. A six-hour target needs at least four in this model. Actual operations still require confirmation of skills, availability, breaks, quality, and rework. The number of people on a roster measures neither sustainable capacity nor permission to ignore other services depending on them.
Run sensitivity without inventing certainty
Save the code as run.py and execute python3 run.py --output evidence.json. It performs thirty-two deterministic comparisons with synthetic inputs. The program neither recovers systems nor estimates probabilities. Changing assumptions helps locate weaknesses: probability between one and three percent and impact between fifty and one hundred twenty thousand produce means between five hundred and three thousand six hundred when extremes are combined. This is sensitivity, not a confidence interval. Deliver assumptions beside the result and identify which observation or specialist would be needed to substantiate them before an actual decision.
"""Original scenario arithmetic. No production recovery, probability estimate or risk approval.
Run: python3 run.py --output evidence.json
"""
import argparse
import hashlib
import json
import math
import platform
from fractions import Fraction
from pathlib import Path
def drain_hours(backlog, arrivals, capacity):
if min(backlog,arrivals,capacity)<0:
raise ValueError('negative input')
if backlog==0:
return 0
if capacity<=arrivals:
return None
return float(Fraction(backlog,capacity-arrivals))
def exception_valid(e,now,volume,scope,mitigation):
# Synthetic decision record, never an authorization engine.
return bool(e['approved'] and e['start']<=now<e['expires']
and volume<=e['volume_limit'] and scope in e['scopes'] and mitigation)
def run:
checks=[]
def check(name,actual,expected):
assert actual==expected,(name,actual,expected)
checks.append(dict(name=name,actual=actual,expected=expected,passed=True))
check('model A expected amount',int(Fraction(1,10)*10000),1000)
check('model B same expected amount',int(Fraction(1,100)*100000),1000)
check('model B larger conditional impact',100000//10000,10)
check('conditional joint probability percent',float(Fraction(1,10)*Fraction(2,5)*100),4)
check('independent assumption would give different percent',float(Fraction(1,10)*Fraction(1,10)*100),1)
check('conditional joint is four times independent illustration',4/1,4)
check('lower sensitivity estimate',int(Fraction(1,100)*50000),500)
check('upper sensitivity estimate',int(Fraction(3,100)*120000),3600)
timeline=dict(detect=15,mobilize=20,restore=40,validate=25)
total=sum(timeline.values)
check('full timeline includes detection and validation',total,100)
check('ninety minute service target missed',total<=90,False)
check('service target overrun minutes',total-90,10)
check('component target can pass while service fails',timeline['restore']<=60,True)
improved=dict(detect=5,mobilize=10,restore=40,validate=20)
check('improved conditional timeline',sum(improved.values),75)
check('improved timeline margin',90-sum(improved.values),15)
check('slower restore sensitivity',sum({**improved,'restore':70}.values),105)
check('one reviewer backlog after four hours',200+(20-15)*4,220)
check('one reviewer cannot drain with arrivals',drain_hours(200,20,15),None)
check('two reviewers drain time hours',drain_hours(200,20,30),20)
check('three reviewers drain time hours',drain_hours(200,20,45),8)
check('four reviewers drain time hours',drain_hours(200,20,60),5)
check('minimum reviewers for six hour model',math.ceil((Fraction(200,6)+20)/15),4)
check('zero backlog needs no drain time',drain_hours(0,20,15),0)
check('equal arrival capacity cannot drain',drain_hours(200,20,20),None)
e=dict(approved=True,start=0,expires=10,volume_limit=100,scopes=['service-A'])
check('exception within all fictional conditions',exception_valid(e,5,100,'service-A',True),True)
check('exception before window fails',exception_valid(e,-1,100,'service-A',True),False)
check('exception expired boundary fails',exception_valid(e,10,100,'service-A',True),False)
check('exception excess volume fails',exception_valid(e,5,101,'service-A',True),False)
check('exception different service fails',exception_valid(e,5,100,'service-B',True),False)
check('exception unavailable mitigation fails',exception_valid(e,5,100,'service-A',False),False)
check('exception missing approval fails',exception_valid({**e,'approved':False},5,100,'service-A',True),False)
check('funding and deployment alone cannot close treatment',all([True,True,False,False]),False)
check('funding deployment effectiveness acceptance all present',all([True,True,True,True]),True)
return dict(runtime=platform.python_version,scope='Fictional probabilities, linear capacity, sequential timelines and exception predicates only. Not empirical forecasting, actual recovery, capital calculation, control certification or authorization.',passed=len(checks),checks=checks,runnerSha256=hashlib.sha256(Path(__file__).read_bytes).hexdigest)
if __name__=='__main__':
p=argparse.ArgumentParser;p.add_argument('--output',required=True);args=p.parse_args
Path(args.output).write_text(json.dumps(run,indent=2)+'\n')
Example: forty-minute restoration meets the technical objective, but all four phases total one hundred against a ninety-minute service target.
Common pitfalls
Multiplying rates without independence; confusing mean with certain loss; measuring restoration alone; counting gross capacity while cases keep arriving.
Related topics: Risk assessment and control effectiveness · Change and external dependencies · Resilience, scenarios, and improvement
A useful scenario connects disruption to outcome, exposes dependencies, and distinguishes conditional calculation from demonstrated operational capability.
Reference: Principles for operational resilience · BigSavant operational risk professional assessment2026.10