Week 3, day 1. Work through the teaching and the worked checkpoint before attempting the assigned exercise(s). Compare your artifact with the final worked result only afterward.
3.1 A decision loop rather than a fixed sequence
Module 2 left B19 unexplained and identified a time-sensitive preservation risk: R15 supplies a 24-hour retention duration for detailed booking-audit records, but not the policy anchor or any verified deletion deadline. As evidence changes, the incident lead needs a repeated loop: observe → assess possible harm → compare authorized options → act → verify effect → reassess. Containment aims to limit further harm while the cause remains under investigation. Eradication addresses a confirmed cause or persistence mechanism when the team can identify it. Recovery restores useful service under explicit checks and monitoring. These activities can overlap, and an intervention may have to be rolled back if its cost or side effects exceed its benefit.
NIST SP 800-61 Rev. 3 treats response and recovery as part of wider cybersecurity risk management. NIST SP 800-184 addresses recovery from cybersecurity events. The classroom decision table below is a teaching model built for Harbor Library, not a universal playbook or an assertion that NIST mandates these exact steps.
Three independent checks for a response control
A response measure may stop a suspicious operation and still create unacceptable harm. Conversely, it may keep the service available while failing to block the concerning activity. The incident lead must not call either result unqualified success.
For the Harbor Library booking service, separate three questions before selecting a control:
Protection: What exact unwanted operation should the intervention prevent? A session revocation targets use of the named session; a pause targets staff writes along defined routes. Neither automatically prevents activity through all accounts, APIs, jobs or software defects.
Legitimate service: What approved function may the intervention interrupt? Revocation may require staff to authenticate again; a write pause may move booking requests into a manual queue. The service owner must describe the tolerable disruption and how queued work will later be reconciled.
Verification: What specific evidence would show that the first two expectations were met? A change ticket marked "executed" is not an effectiveness test. A quiet audit result could mean no request was attempted, the relevant source was unavailable, the query was too narrow, or the control actually prevented a change. A useful test needs a specified target, observable attempt, appropriate source coverage and independently checked business state.
NIST SP 800-61 Revision 3 places response activities within wider cybersecurity risk-management decisions. The three-question contract here is an original teaching method, not a mandatory NIST form. It matters because containment can reduce one risk while increasing another; the record must show both.
3.2 The case changes
These additional records are invented. Use them with R1–R16; the timestamps are UTC and the records are the only authorized evidence for this exercise.
Lesson table; scroll horizontally to read all columns →
| ID | UTC time | Source | Observation |
|---|---|---|---|
| R17 | 09:22 | Training owner | The approved task list named B17 and B18 only; the owner knows of no addendum. |
| R18 | 09:24 | Booking audit | desk-a changed B20 from Room 3 to Room 1. |
| R19 | 09:25 | Identity administrator | The current session can be revoked without deleting the account; staff would need to sign in again. |
| R20 | 09:27 | Service-owner export | Current states of B17–B20 are available in a restricted comparison copy. |
| R21 | 09:29 | Service owner | A fifteen-minute pause on staff booking writes is tolerable if front-desk staff use a manual queue. |
| R22 | 09:32 | Booking audit summary | No edit after R18 appears within the summary's queried range. |
| R23 | 09:34 | Recovery lead | The last backup job succeeded, but the most recent documented restore test was thirty days earlier. |
| R24 | 09:36 | Privacy contact | No record currently establishes access to the newsletter list or another personal-data store. |
R17 and R18 make the authorized-training explanation for all edits less plausible and raise concern about ongoing harm. They still do not prove who controlled the session or why the edits occurred. R22 is limited to its range; R24 is a statement about the current evidence, not a finding that no exposure occurred. The lead should update confidence and urgency without converting uncertainty into an accusation.
3.3 Compare containment options
At 09:37 UTC, the team considers the following hypothetical options. No action has been taken in this text.
Lesson table; scroll horizontally to read all columns →
| Option | Potential benefit | Cost or side effect | Evidence and authorization needed | Reversal or fallback |
|---|---|---|---|---|
Revoke the current desk-a session |
May stop edits from that session quickly. | Legitimate front-desk work pauses until reauthentication; another session or account could remain. | Incident lead and identity owner approval under local policy; preserve narrow session and booking records first where time allows. | Reissue a verified session through approved identity process; monitor the booking audit. |
| Pause staff booking writes for fifteen minutes | Blocks edits through the staff workflow during investigation. | Staff must use the manual queue; patrons may wait. | Service-owner approval is required; R21 states tolerability but does not record approval. An operator must verify any approved pause. | Resume writes only after a checked booking state and owner sign-off. |
| Observe without intervention for ten minutes | Preserves normal service and may collect more context. | Unexplained edits could continue and harm more patrons. | Explicit lead decision accepting risk and a rapid review trigger. | Escalate immediately if another edit appears or a patron impact grows. |
The best option depends on current activity, confidence, reversibility and the service owner's tolerance. A reasoned classroom proposal is to ask the incident lead and identity owner to authorize session revocation, preserve the available narrow records and have the service owner ready to pause staff writes if edits continue. Another team might choose the short write pause first if the identity session cannot be linked reliably to the edits. The learner must explain the decision, authority and fallback; no fixed option is automatically correct.
Recommendation, approval, execution and verification receipts
A decision is auditable only when each state has its own evidence. The distinction is practical, not linguistic:
Lesson table; scroll horizontally to read all columns →
| State | Required evidence | Inappropriate upgrade |
|---|---|---|
| Proposed | Analyst's bounded option, supporting observations and expected harm reduction | Calling it approved because it sounds necessary |
| Approved | Named accountable role, target, duration, acceptable service cost and review trigger | Calling it executed because permission was granted |
| Executed | Operator's specific target, actual time, method/version and result receipt | Calling the effect verified because a command returned success |
| Verified | Independent or appropriately authoritative proof of intended protection and acceptable legitimate service behavior, in a declared scope | Calling all identities, paths or recovery functions safe |
At 09:37, a proposed session revocation could name desk-a's identified current session as its target. The incident lead and identity owner are the proposed approving roles; an identity administrator would operate the change under the fictional rules. The expected protective result is denial of subsequent use of that session. The expected legitimate-service consequence is staff reauthentication. The evidence plan must include both, plus a new bounded booking audit after execution. R19 describes the capability to revoke, not a completed revocation.
For the fifteen-minute pause, R21 provides a business tolerance statement, not the necessary approval of the actual target and window. An authorized operator would need the service owner's explicit decision and a means of verifying which staff-write paths are blocked. The manual queue also has an owner and reconciliation obligation. R21 must not be transformed into execution, even when the team favors the pause.
A verified control result has scope. If one approved test shows a selected session can no longer authenticate, it does not establish that every previous token was invalidated. If one staff route rejects a write, it does not establish that a legacy route is blocked. The existing W1 fixture examines those route-specific failures independently; this expansion adds the state and acceptance logic that should surround any such test.
Make the comparison observable
A response option is an intervention, not a verdict about the cause. Compare it with the same questions you would ask of a testable claim: What should change? What might break? How will we notice both effects? Who is allowed to make and reverse the change? A short decision table is more useful than assigning unexplained numerical risk scores:
Lesson table; scroll horizontally to read all columns →
| Question at 09:37 UTC | Session revocation | Fifteen-minute staff-write pause |
|---|---|---|
| Intended effect | Prevent further edits through the identified current session | Prevent edits through the staff booking workflow |
| What it does not cover | Other active sessions, accounts or an application fault | Read-only exposure, another write path or the cause of the edits |
| Immediate service cost | Staff member must reauthenticate; work may pause | Front desk uses a manual queue and must reconcile requests |
| Evidence needed after action | Identity service confirms revocation; audit is checked for continued edits | Application shows staff writes blocked; queue and audit are checked |
| Reversal condition | A new verified session is allowed under the approved identity process | Owner approves resumption after booking-state and queue checks |
The no-intervention option also needs a test and a deadline. “Observe” is a decision to accept possible further booking harm for a limited period in exchange for more information. It is not a neutral default. If the team cannot detect a new edit quickly, an observation window may be less defensible than the table suggests. If the audit is incomplete, “no new edit shown” must be reported with that limitation.
Preserve the narrow records that are likely to matter before a disruptive change when doing so does not dangerously prolong harm. The incident lead should record which sources were captured, which could not be captured in time and why. Waiting indefinitely for a perfect evidence set could expose more patrons; acting without an evidence note can make later review harder. A proportionate decision records both costs. The comparison follows the risk-management orientation of NIST SP 800-61 Rev. 3; the Harbor Library choices and matrix are original teaching examples.
Contained W1 lab: test whether a proposed write pause actually holds
A change ticket saying pause enabled records an operator's intention, not the control's effect. A quiet booking audit could mean the pause worked, no one tried to edit, the query omitted a path, or logging failed. To evaluate the proposed pause in section 3.3, define its claim before testing: during a bounded interval, staff-originated booking writes through both the ordinary interface and the legacy application route should be blocked, while read access and the approved manual queue remain usable. This is a service-specific classroom requirement, not a universal containment recommendation. A real team would identify all relevant routes with the service owner and test only under its change, privacy and safety rules. NIST SP 800-61 Rev. 3 frames effective response and recovery as part of risk management; the W1 test design and pass criteria are original teaching material, not a NIST procedure.
W1 is a separate fictional branch. Its special card W1-A says that, for an isolated training copy only, the fictional service owner and incident lead approve a 09:40–09:55 UTC staff-write pause test with a manual queue. This approval does not exist in R1–R24. In particular, R21 says a pause is tolerable; it does not authorize one. W1's later timestamps and observations cannot be cited as facts available to the 09:37 canonical decision or the Module 4 tabletop. No learner is to submit a write to a live service, use a real account or infer a real incident outcome from these invented rows.
Before reading the outcomes, put four questions on a test sheet: (1) Did the ordinary interface reject a labeled write and leave the isolated booking value unchanged? (2) Did the legacy route do the same? (3) Was a manual request recorded for later reconciliation rather than applied to the booking state? (4) Did a read-only request still work? Use independent before/after state beside the response and audit label. A response string alone can disagree with the resulting state; an absent audit line is not evidence of a block. The fixture supplies one trial per route, so even a clean result would support only those paths, values and times.
Card W1-B — isolated probe results. The labels W-UI, W-API, W-QUEUE and W-READ are new synthetic records. Room 2 and Room 4 are training values unrelated to B17–B20. The queue numbers are pending-item counts, not booking-room values.
Lesson table; scroll horizontally to read all columns →
| Probe and UTC time | Route and intent | Service response | Independent state before → after | Audit label |
|---|---|---|---|---|
W-UI at 09:42 |
Ordinary staff interface, booking write | rejected | Room 2 → Room 2 |
deny |
W-API at 09:43 |
Legacy application route, booking write | accepted | Room 2 → Room 4 |
allow |
W-QUEUE at 09:44 |
Manual queue, record one request | queued | 0 pending → 1 pending |
queue |
W-READ at 09:45 |
Read-only booking lookup | returned Room 2 |
Room 2 → Room 2 |
read |
Treat each row as a separate probe with its own reset training state. W-API's Room 4 does not become W-READ's starting value; the table is not a continuous production trace. The fixture intentionally makes the ordinary interface block a write while the legacy route changes a value. Therefore the broad claim all staff writes are paused fails under the stated W1 scope. It would be incorrect to average the two write outcomes into “50% effective”: the sample is neither random nor representative, and one demonstrated route failure is enough to reject the universal claim for this fixture. The manual queue's one pending item shows it recorded a request in this test, not that capacity, reconciliation or later service acceptance was verified.
Reproduce a narrow classification. The following standard-library Python program uses only in-memory invented rows. It does not connect to an application or change a file. It validates unique probe IDs and recognized kinds, then gives state change precedence over the service's claimed denial for write probes. The four status labels are observations about this fixture, not a production certification.
First enter the W1 fixture:
PROBES = [
("W-UI", "write", "rejected", "Room 2", "Room 2", "deny"),
("W-API", "write", "accepted", "Room 2", "Room 4", "allow"),
("W-QUEUE", "queue", "queued", "0 pending", "1 pending", "queue"),
("W-READ", "read", "returned Room 2", "Room 2", "Room 2", "read"),
]
Check the measurement, not just the classifier. A Room 2 → Room 2 pair is useful only if both reads refer to the same training booking and an authoritative state view, with a recorded read time and a known consistency rule. A cached page could remain unchanged even after a successful write. Likewise, an audit label needs a request or event pointer and a collection cutoff; a delayed deny row could describe a different attempt. W1 supplies simplified independent values for the classroom method, but does not provide those production-grade provenance fields. This is why the code names one outcome BLOCKED_IN_THIS_TEST, rather than blocked by the pause.
A pre-pause baseline is another missing control. If the W-UI test identity lacked write permission even before 09:40, a rejection during the pause would not show that the pause caused it. An authorized isolated rehearsal could first demonstrate that the same synthetic identity and route can perform a permitted write, reset the training state, then apply the approved pause and repeat the labeled probe. The test sheet would retain both request IDs, approval, state snapshots and timing. W1 does not supply such a baseline, so do not invent one in the worked result. The W-API state change is still enough to reject the broad pause claim within the stated W1 fixture, assuming its supplied independent state is reliable. In a real investigation, the owners would verify that assumption before acting on the comparison.
Then run the classifier in the same scratch Python session. These two labeled listings form one program; the second uses PROBES from the first.
def classify(kind, response, before, after, audit):
if kind == "write":
if before != after:
return "WRITE_PATH_NOT_BLOCKED"
if response == "rejected" and audit == "deny":
return "BLOCKED_IN_THIS_TEST"
return "INCONCLUSIVE_WRITE"
if kind == "queue":
if (response == "queued" and before == "0 pending"
and after == "1 pending" and audit == "queue"):
return "QUEUE_ITEM_RECORDED"
return "INCONCLUSIVE_QUEUE"
if kind == "read":
if (response == "returned Room 2" and before == after
and audit == "read"):
return "READ_RETURNED_EXPECTED_VALUE"
return "INCONCLUSIVE_READ"
raise ValueError("unknown probe kind")
seen = set()
results = {}
for probe_id, kind, response, before, after, audit in PROBES:
if probe_id in seen:
raise ValueError("duplicate probe ID")
seen.add(probe_id)
results[probe_id] = classify(kind, response, before, after, audit)
print(f"{probe_id}: {results[probe_id]}")
write_ids = [probe_id for probe_id, kind, *_ in PROBES if kind == "write"]
claim = "SUPPORTED_FOR_TESTED_PATHS" if all(
results[probe_id] == "BLOCKED_IN_THIS_TEST" for probe_id in write_ids
) else "NOT_ESTABLISHED"
print(f"write_pause_claim: {claim}")
The final claim line deliberately says SUPPORTED_FOR_TESTED_PATHS even in a hypothetical all-blocked variant. It would still say nothing about undiscovered routes, future time windows, queue capacity or why the earlier anomalous edits occurred. In the printed W1 fixture the output is NOT_ESTABLISHED; the legacy-route state change is a concrete failure of the proposed write-pause claim in the isolated test. The incident lead should keep the result as a failed validation, ask the service owner to correct or narrow the control design, and require a new authorized test before relying on it. A manual queue may reduce service disruption, but it does not compensate for an uncontrolled write route.
W1-SCOPE supplemental check — required route and service coverage
The original W1 classifier gives a correct result for its complete fixture, but its final all() test silently accepts missing required routes: with only W-UI or with no rows, it can print SUPPORTED_FOR_TESTED_PATHS. A read response can also name Room 2 when the independent value is actually Room 4. These are defects in the teaching evaluator, not observations of an actual control. Run the following supplemental audit after both original W1 listings in the same scratch session. It does not alter the five original output lines. Here W-UI and W-API are the two required write routes; W-QUEUE and W-READ are separate legitimate-service functions.
# W1-SCOPE supplemental audit; requires the original PROBES and classify().
EXPECTED = {
"W-UI": "write", "W-API": "write",
"W-QUEUE": "queue", "W-READ": "read",
}
def w1_gates(probes):
ids = [row[0] for row in probes]
if len(ids) != len(set(ids)):
return ("PROTECTION_UNEVALUABLE_DUPLICATE_ID",
"SERVICE_UNEVALUABLE_DUPLICATE_ID")
rows = {row[0]: row for row in probes}
if any(k not in EXPECTED or row[1] != EXPECTED.get(k)
for k, row in rows.items()):
return ("PROTECTION_UNEVALUABLE_UNEXPECTED_PROBE",
"SERVICE_UNEVALUABLE_UNEXPECTED_PROBE")
if not {"W-UI", "W-API"}.issubset(rows):
protection = "PROTECTION_UNEVALUABLE_MISSING_ROUTE"
elif all(classify(*rows[k][1:]) == "BLOCKED_IN_THIS_TEST"
for k in ("W-UI", "W-API")):
protection = "PROTECTION_TESTED_PATHS_PASS_NOT_CAUSAL"
else:
protection = "PROTECTION_TESTED_PATHS_FAIL"
if not {"W-QUEUE", "W-READ"}.issubset(rows):
service = "SERVICE_UNEVALUABLE_MISSING_FUNCTION"
else:
q, r = rows["W-QUEUE"], rows["W-READ"]
queue_ok = classify(*q[1:]) == "QUEUE_ITEM_RECORDED"
read_ok = (
classify(*r[1:]) == "READ_RETURNED_EXPECTED_VALUE"
and r[2] == "returned Room 2"
and r[3] == "Room 2"
and r[4] == "Room 2"
)
service = ("SERVICE_TESTED_FUNCTIONS_PASS"
if queue_ok and read_ok
else "SERVICE_TESTED_FUNCTIONS_FAIL")
return protection, service
def print_w1_gate(label, probes):
print(f"{label}: {' | '.join(w1_gates(probes))}")
both = [
("W-API", "write", "rejected", "Room 2", "Room 2", "deny")
if row[0] == "W-API" else row
for row in PROBES
]
wrong_read = [
("W-READ", "read", "returned Room 2", "Room 4", "Room 4", "read")
if row[0] == "W-READ" else row
for row in both
]
print_w1_gate("ORIGINAL_W1", PROBES)
print_w1_gate("LEGACY_ROW_MISSING",
[row for row in PROBES if row[0] != "W-API"])
print_w1_gate("NO_ROWS", [])
print_w1_gate("BOTH_WRITES_BLOCKED", both)
print_w1_gate("WRONG_READ_STATE", wrong_read)
print_w1_gate("QUEUE_ROW_MISSING",
[row for row in both if row[0] != "W-QUEUE"])
Predict the six additional results before looking at the W1-SCOPE worked result. An absent route is unevaluated, never blocked. Even when both named writes are blocked in this synthetic fixture, the result is not causal evidence of the proposed pause without a permitted pre-pause baseline, request-linked audit evidence and authoritative before/after reads. The queue test checks admission of one item, not eventual booking fulfillment, reconciliation capacity or recovery acceptance. No code here performs a live write or service call.
Practice submission. Prepare (1) a four-row table of status and source fields; (2) a one-sentence containment claim with its scope and test window; (3) a decision record saying whether to rely on the pause, who must approve a change and how the manual item will be reconciled; and (4) a counterfactual W1-V in which W-UI's response remains rejected but its after-state becomes Room 4. Predict the new W-UI classification and the overall claim without changing any other field. The model output and a bounded decision appear in the final worked-results appendix. Seven-point rubric: one point for each of the four probe classifications, one for rejecting the broad pause claim with the W-API state evidence, one for a bounded owner-approved corrective and reconciliation plan, and one for the W1-V prediction. A 7/7 response demonstrates correct reasoning on W1, not verified containment of a real service.
RB3 — Preparing and verifying containment reversal
RB3.1 Containment introduces a second risk that must be managed
Containment is intended to limit a particular harmful path. It can simultaneously interrupt ordinary work, prevent approved users from accessing a necessary function, or fail to block the activity the incident team intended to stop. A team that can enable a control but has no prepared way to reconsider or reverse it may turn a temporary protective measure into a prolonged service problem.
The existing §3.3 compares current-session revocation, a short staff-write pause and observation. It already identifies business costs and possible fallbacks. This expansion addresses the next, distinct question: if a selected intervention produces unacceptable side effects or fails its expected protection, what evidence and authority are needed to reverse that intervention without silently reintroducing the original risk?
A reversal can involve restoring an earlier configuration, stopping a temporary restriction, replacing a control with a narrower one, or moving to a separately approved operational mode. The word rollback is useful, but not every action can be literally undone. A revoked identity session may need a new, appropriately verified authentication procedure; restoring an old configuration may reintroduce the same vulnerability that containment was intended to address. Undoing an emergency pause may permit writes again without proving that the original suspicious edit path is now safe.
NIST SP 800-61 Rev. 3 connects incident response and recovery with risk management throughout an incident. NIST SP 800-184 addresses planned recovery, testing and improvement. These sources support careful planning and evaluation; the precise RB3 reversal contract is an original OpenCyber Academy teaching construct, not a mandatory NIST workflow.
RB3.2 Write down the purpose of reversal before selecting a command
The phrase "undo the containment" conceals at least two different reasons for taking action.
Service-harm trigger. The response team has a reliable, scoped observation that the control disrupted legitimate work beyond the accepted operating limit. For example, a fictional short staff-write pause may unexpectedly interfere with an essential permitted function. The proposed next step is not automatically "remove all protection"; it may be to restore that function under a narrower, separately approved safety condition.
Protection-failure trigger. A credible post-action test finds that the targeted harmful activity remains possible in the declared control scope. A responder might reasonably request replacement, correction or withdrawal of an ineffective control. However, reverting without an alternative could make the situation worse. The team needs to compare the present control, proposed reversal and remaining safeguards.
Both triggers need an observable condition and a source that could be challenged. "The desk is unhappy" is not the same as a verified failure of the service owner's accepted requirements. "The logs are quiet" is not proof that protection worked if no meaningful attempt or source coverage was established. A negative result can be informative only within the test's inputs and scope.
The intervention decision and the reversal decision are separate. Even if a change was previously approved, its inverse need not be automatically approved. The risk has changed, the available evidence may have changed and the accountable owner must understand the new tradeoff.
At rapid level, the learner should describe the trigger in operational language: which function or expected protective result failed, how was that observed, and what is the narrowest next decision it justifies?
RB3.3 Establish a verified pre-intervention state, not an idealized past
A useful reversal plan starts before applying the original control. It records the last verified configuration or state relevant to the proposed change: the affected component, configuration version, tested legitimate service behavior, observed protective posture, dependencies, owner and source of the baseline record.
The phrase "restore the old settings" is unsafe without a trustworthy target. The old version may be missing, incomplete, incompatible with a newer dependency or already known to permit the harmful behavior. A baseline should be an identifiable, owner-reviewed candidate for return, not a promise of correctness.
The baseline card should answer:
Lesson table; scroll horizontally to read all columns →
| Baseline question | Required evidence or limitation |
|---|---|
| What exact object was checked? | Specific setting, session-control scope or configuration identifier |
| When and where was it checked? | Controlled source, environment and timestamp |
| What legitimate function passed? | Owner-defined permitted operation and measured result |
| What protection was present? | Narrow existing safeguard, if observed; unknown elsewhere |
| What was saved? | Authorized configuration reference or approved restoration procedure |
| What may have changed since? | Dependency or state differences requiring fresh verification |
| Who can approve returning? | Current accountable decision role, separate from the operator |
For a service that has been changing during an incident, simply replaying a saved configuration may be inappropriate. A baseline can be known at capture time yet not safe to reapply later. The reviewer must check its current applicability and the intervening system changes.
The RB3 lab uses the entirely invented identifier CFG-GOOD-7 and a Boolean baseline_verified. Neither is evidence that a real baseline exists. The positive fixture models the discipline of requiring a known starting reference; it does not check the contents or authenticity of an actual configuration.
RB3.4 Define the original intervention as an exact bounded change
A reversal can only be compared with an intervention if the first change is itself traceable. The original action record needs its own proposal, approval, object scope, effective window, operator receipt, expected protection and service impact. Otherwise the team may not know what needs undoing.
Suppose a containment proposal affects only a synthetic staff-write service function. A later reversal may legitimately aim to restore only that function. A request to alter identity settings at the same time would be an expanded action, not an automatic inverse of the original. That expansion requires separate justification and authorization.
The RB3 fixture represents the original control as CTRL-PAUSE-9 with affected scope staff-write. Its fictional prior approval is a declared input. The baseline restoration target is CFG-GOOD-7. These labels are not Harbor Library configuration IDs.
An implementation plan should preserve both what the operator intended to change and what was actually reported changed. A control may be applied partially or to the wrong object. In that situation, executing a generic inverse could affect components the original operation never reached.
The safe preparation step is to identify a precise rollback target and its permitted scope, plus a stop condition if the current state no longer matches the assumptions in the plan. A preapproved recipe for the wrong current environment is not automatically safe.
This is deliberately different from W1, which checks specific write routes under a pause. RB3 does not inject writes, run a gateway test or determine whether W1's legacy route was blocked. It checks whether the proposed inverse has a reviewable evidence chain.
RB3.5 Approval must name the reversal, its window and its business cost
A rollback request should identify the specific control being reconsidered, the intended target state, the components or functions affected, the justification, the risks reintroduced and the authorization window. An approval for the original pause does not necessarily approve ending that pause, and R21's tolerance statement cannot be used as approval for any live change.
The accountable owner for a service-affecting reversal may be the service owner under the applicable fictional governance rule, coordinated with the incident lead. Identity owners may be needed if the intervention concerns authentication rather than a staff-write setting. The operator applies the change only after the relevant decision; the reviewer checks the result independently.
For a clear approval record, name the operation, not merely the ticket: "revert the specified synthetic staff-write control to the reviewed candidate state within the defined window, subject to the stated protective and business checks." The record should include:
- The approved target and exact component/function set.
- The allowed start/end of execution, using an agreed clock.
- The decision owner and the operator.
- The triggering evidence and reason for reversal.
- The business impact expected if the inverse is performed.
- The compensating safeguard that should remain effective.
- The post-reversal verification, reviewer and failure response.
- The planned human reassessment, even if the initial check passes.
A missing or expired approval is a hold condition, not a license to treat urgency as permission. If immediate harm creates a real emergency, an organization might have a separately governed emergency change procedure; the training exercise does not invent such powers.
RB3 checks a small fictional approved window, 14:05–14:25 UTC on an entirely invented date. The clock is a consistency input, not a measured Harbor Library outage or recovery objective.
RB3.6 Specify a trigger that can be falsified
The team should be able to say what observation would cause a planned reversal to be requested and what observation would show that the trigger did not occur.
For a service-harm trigger, an owner-approved isolated measurement might show that a previously permitted legitimate task is now unavailable because of the controlled change, beyond accepted limits. The analyst should compare the affected service function with its baseline and account for other possible causes. If the function was already unavailable before the intervention, a post-action failure cannot by itself establish that the control caused the problem.
For a protection-failure trigger, an approved, bounded post-action check may show that the threat path remains available under the tested scope. The team should not interpret a quiet or incomplete log as a successful block. Equally, an unrelated failure does not prove the targeted protection failed.
A valid trigger record should name:
- The condition being tested.
- The source and input of the observation.
- The time and operating scope.
- The expected result and observed difference.
- The custodian or owner confirming the relevant semantics.
- A limit: what the observation cannot establish about other routes or business outcomes.
The RB3 fixture uses either SERVICE_HARM or PROTECTION_FAILURE as the artificial trigger kind, with a corresponding training receipt. These are declared exercise observations, not detector outputs or events added to R1–R24.
The negative variant TRIGGER_NOT_OBSERVED deliberately removes the supporting observation. The validator then refuses to convert a plausible rollback proposal into an executed action.
RB3.7 Proposed reversal, approved reversal, executed reversal and checked effect
The same action-state discipline used elsewhere in Module 3 applies to the reversal as a new operation. A team should not merge the original control ticket with the inverse action and then declare both successful.
Lesson table; scroll horizontally to read all columns →
| Reversal stage | Narrow supported claim | What must remain blocked |
|---|---|---|
| Proposed | The team identified a bounded inverse candidate and reason | Claim that permission was granted |
| Approved | The appropriate owner accepted scope, timing and risk of the inverse | Claim that the operator executed it |
| Execution reported | A named operator recorded what was changed, target and time | Claim that intended effect occurred |
| Post-state checked | An independent or appropriately authoritative check evaluated the selected result | Claim that the full incident is recovered |
| Human review open | Residual protection/business questions have accountable owners and next decision | Automatic closure without case review |
The order matters. A ticket with a return configuration attached is still a plan. An approval receipt is still not an execution receipt. A command or workflow reporting success may have operated on the wrong object, changed only one dependency or left the actual service in an unexpected state. Record the operator's actual execution time separately from the approval time; an action reported outside the approved window, or before the decision, is not covered by that approval.
RB3 adds a specific target-matching check. Its execution receipt must refer to the declared candidate configuration rather than an unrelated version. A variant with an execution receipt for CFG-UNKNOWN must fail even if the other synthetic status flags are positive.
After execution, the team needs an observation of the resulting state and two different acceptance checks. Those are discussed next. The presence of a receipt does not replace the effect observation.
This section does not repeat G3-DG's generic decision-gate tutorial. It applies those distinctions to the risk-bearing inverse operation, including the verified baseline, trigger and competing post-reversal outcomes.
RB3.8 Verify protective behavior after rollback, not just restored availability
Removing a disruptive restriction may restore legitimate service while also reintroducing the harmful path that containment was intended to limit. A successful rollback command is therefore not sufficient, and even a successful booking operation may be too narrow.
The post-reversal protection check asks: Under the new, declared operating mode, what prevents or detects the selected unacceptable action, and what bounded observation supports that claim? The original control may have been removed, so the reviewer cannot simply require the exact same control to remain enabled. Instead, the service owner and security lead must define an acceptable residual protection condition, perhaps through a narrower approved safeguard or restricted mode.
A failed protection check means the reversed system cannot be called acceptably protected for the tested purpose. It does not always mean the inverse had no technical effect. It can mean that legitimate service resumed but the protective risk is unacceptable.
The RB3 negative case PROTECTION_REGRESSED models that outcome. It returns PROTECTION_NOT_ACCEPTED even when an execution receipt and a positive legitimate-service check are present. This prevents the seductive conclusion "rollback succeeded because the desk can work again."
Do not interpret this as a universal instruction to keep every harmful control in place indefinitely. The accountable owners must balance risks and may select a different approved containment strategy or restricted service mode. The lesson is to document and verify that tradeoff, not to choose the outcome for them.
No real security-control test is performed in RB3. The protection_check field is an invented Boolean and cannot establish that a live system is safe.
RB3.9 Verify legitimate service after rollback, not merely configuration identity
The inverse operation may report that a previous configuration was restored while the original business problem remains. A dependency may still be unavailable; a required approval workflow may still fail; data may still be wrong; or the configuration switch may not control the user-facing function the team intended to restore.
The post-reversal legitimate-service check asks whether the specific owner-approved permitted function works in the declared scope. It should use a relevant positive task and a correct state result, not a generic process-health indicator.
The exact result depends on the intervention. For a fictional staff-write pause, the owner may care whether approved work can resume through the permitted route after the separate queue and booking-state conditions are satisfied. For a session revocation, the owner may care whether legitimate staff can authenticate through the approved replacement procedure. Those are different operations; neither is safely "undone" by reversing a single string.
The RB3 variant LEGITIMATE_SERVICE_DOWN declares that the post-reversal permitted function still fails. It returns SERVICE_NOT_ACCEPTED even though the simulated protective check passes. This demonstrates that protection and business availability are independent acceptance conditions.
A configuration equality test also cannot prove full booking-state correctness. An application can run under an old configuration while a booking database still contains unresolved inconsistencies. Later P1/C1 and V1 belong to their own separately released cards, and RB3 never changes their findings.
The correct report is "post-reversal legitimate function not accepted in this fixture," not "the entire library remains down" or "the data were destroyed."
RB3.10 A valid reversal can still leave open human decisions
Why not mark everything recovered when both post-reversal checks pass? Because the checks cover only their stated function and scenario. The original incident may have an unresolved cause, untested paths, preservation needs, pending communication decisions and business-state errors that the inverse operation did not address.
A safe reversal record keeps a human review item explicitly open with an owner and a next checkpoint. This is not a cosmetic ticket. It can include verifying residual exposure, choosing whether another control is needed, reconciling operations deferred during containment, and deciding whether a restricted mode remains acceptable.
The RB3 positive case returns BOUNDED_REVERSAL_CHECKED_REVIEW_OPEN. The final words are intentional: the simulated reversal met two bounded post-state checks, but it is not incident closure. A negative case with human_review_open=False fails because the teaching contract requires an accountable human reassessment even after technically favorable observations.
The output must not be equated with RTO or RPO attainment. Module 3's RTE3 exercise measures scoped interruption-to-acceptance under a different contract; RB3 has no completed service-owner recovery-acceptance timeline. This is a reversal readiness and verification model.
A team may legitimately leave a temporary restriction partially active while awaiting review; if so, it must say which service and protective conditions are still in effect. Silent assumption of normal service is not an acceptable outcome.
RB3.11 Full wrong example: automatically undoing a harmful pause
Synthetic classroom contrast; none of these events occurred at Harbor Library's 09:37 checkpoint.
Imagine a fictional application operator learns that a temporary staff-write control is slowing legitimate booking work. A ticket says the earlier control was "deployed," and someone remembers a configuration called CFG-GOOD-7. The operator immediately restores that version and announces: "Rollback succeeded, the service is back, and we can close the incident."
This is wrong, even if restoring the old configuration appears to make one staff screen work. The team has not established that the old version is the verified relevant baseline, that reversal was authorized for the precise current state, or that a defined trigger was confirmed. It also has not recorded an execution receipt identifying the exact target, checked whether the protective goal still holds, or obtained the service owner's acceptance of the legitimate user outcome.
The more subtle failure is that reversing the control may expose the same path the control had been introduced to restrict. A restored booking interface could be responsive and still permit unintended edits. Conversely, the old configuration may fail to restore the intended function because of another dependency.
A superficially reassuring case note would compound the error by replacing the original proposal and intervention history with one line reading "fully recovered." That prevents a later reviewer from understanding what happened and what the reversible risk actually was.
Correct handling of this wrong case: Hold any further unapproved change, preserve the relevant source and configuration history, identify the precise previously verified state, seek the accountable rollback decision, specify both protection and legitimate-service checks, and record open human review. If the first change has already occurred under an unverified route, the team must document that fact and obtain an owner-governed safe next decision. It must not invent a retroactive approval.
RB3.12 Full correct example: a reviewed, narrow reversal with residual risk open
Independent RB3 invented variant, dated 2040-04-10; not canonical Harbor Library evidence.
A fictitious service owner had an isolated, previously verified candidate configuration CFG-GOOD-7, documented for the narrow function staff-write. A separately approved classroom control CTRL-PAUSE-9 later restricted that function. A named training observation TRIG-SVC-01 reports that the required permitted service activity is now failing under the isolated control and meets the declared SERVICE_HARM trigger.
The fictional service owner, ServiceOwnerSim, considers a scoped reversal request. The request names only the original staff-write function, specifies the approved candidate CFG-GOOD-7, explains the loss-of-protection risk, and defines an authorization window of 14:05–14:25 UTC. At 14:12, the invented approval receipt APP-RB-01 is present in the fixture. At 14:13, the operator's simulated execution receipt is EXEC-RB-01 for the expected target, within the approved window; a separate declared post-state observation names that target. The earlier control also has a distinct application receipt. None authenticates an actual change.
The two different post-reversal checks are then considered: (1) the selected protective condition remains acceptable in the tested scope under a defined residual safeguard, and (2) the legitimate staff function meets its declared business check. Only if both are supported in the fixture does the validator return BOUNDED_REVERSAL_CHECKED_REVIEW_OPEN.
That verdict is deliberately narrow. It does not authenticate a real approver, prove the earlier intervention's cause, test every write route, reconcile every pending booking or close the incident. The service owner must still review residual risks, choose any further restriction or monitoring and preserve an auditable next checkpoint.
A second positive scenario changes the trigger to PROTECTION_FAILURE, with an independent artificial trigger receipt. It can reach the same bounded result if the new operating mode still meets both acceptance checks. This illustrates that the reason for reconsideration can differ while the authorization and verification discipline remains necessary.
A full report preserves the original baseline reference, intervention approval, trigger, new rollback approval, receipt, two check results and open human-review status as separate historical entries.
RB3.13 Negative evidence and the need to stop before compounding harm
A failed condition can call for holding a reversal proposal, reassessing an already reported action, or escalating immediately to the appropriate owner depending on when it is discovered.
If approval is absent, an operator must not treat the proposal as executable merely because service disruption is costly. If the scope exceeds the original control, the extra object needs its own authorization and safe test; it must not be folded into the inverse. If the trigger was not observed, the evidence for change is unestablished. The team should recheck the source before deciding that rollback is justified.
If a proposal lacks an execution receipt, report proposed/not performed. If an execution receipt exists without post-state observation, report execution claimed but effect unverified. A command result is not a service test.
If the protection check fails after the reversal, the team may need a revised, owner-approved containment strategy. If the legitimate-service check fails, the inverse did not accomplish its business objective in the tested scope, even if protection remains intact. Neither failure licenses uncontrolled trial-and-error changes against production.
An unknown baseline or expired window is also significant. An inverse plan that was valid against one configuration may no longer be safe when state or dependencies have changed. An expired approval does not silently renew itself because the operator is already familiar with the system.
This is why rollback readiness should be prepared alongside containment, not improvised after a failed intervention. A team needs an authorized response even when its first solution makes conditions worse.
RB3.14 A reversal card must preserve history, not overwrite the initial decision
A reviewable reversal card should link three distinct records: the pre-intervention baseline, the original intervention and the proposed or executed reversal. Each has its own evidence and authorization.
A useful field-level record includes:
Lesson table; scroll horizontally to read all columns →
| Field | Evidence or safe limitation |
|---|---|
| Baseline reference | Configuration/service state ID and time of independent check |
| Intervention reference | Original proposal, approval, scope, actual operator receipt and known effects |
| Reversal trigger | Observed service harm or protection failure and source/confirmation |
| Reversal proposal | Target state, exact objects and intended effect |
| Reversal approval | Named owner, scope, time window, restrictions and receipt |
| Reversal execution | Operator, specific change/target, actual time and receipt, if performed |
| Protection after reversal | Expected blocked/detected harmful behavior, observed result and limit |
| Legitimate service after reversal | Permitted function, expected result, observed result and limit |
| Remaining risk | Untested routes, residual incident cause, business obligations and evidence gaps |
| Next human decision | Named accountable reviewer, trigger and deadline |
| State | Proposed, approved, reported executed, bounded checks passed/failed, or unknown |
In the canonical 09:37 decision, no reversal record exists because no intervention was executed. A future optional synthetic exercise may introduce one, but its identifiers must remain outside R1–R24 and the later Branch S/P story.
The correct practice is to append the reversal record as a new dated activity rather than replacing the Round C proposal or asserting that a later action had already happened. This preserves the distinction between history and hindsight.
RB3.15 Preparing the next safe action when a reversal fails
What should the learner propose if an RB3 negative case appears?
For a missing approval or unauthorized scope, identify the accountable owner and request a corrected, bounded decision. For an unknown baseline, ask the configuration or service custodian to establish a safe candidate and document the comparison. For a missing trigger receipt, obtain a genuine authorized observation rather than inventing the incident. For an execution receipt without independent effect evidence, request the appropriate bounded check before claiming success.
If protection fails after rollback, the next step is not automatically to reinstate the original harmful control. The owner must compare the original intervention, proposed alternative and current service risk. A narrower control, monitored restricted mode or another approved protective action may be appropriate, but the supplied RB3 fixture does not select a real solution.
If legitimate service remains down after rollback, the result should be escalated with the specific failed function and source rather than declared successful because the configuration identifier matches the baseline. Additional fault diagnosis or a separately approved recovery action may be necessary.
For all these cases, preserve current evidence, avoid adding unexplained changes and assign an owner and review trigger. An apparently successful inverse is only one step of managing an incident; unresolved cause, correct booking state and actual user acceptance remain separate tasks.
RB3.16 Teaching synthesis and relationship to other Module 3 laboratories
W1 tests whether a proposed write pause actually blocks the stated isolated routes. G3-DG distinguishes generic approval, execution and acceptance states. MQ3 checks duplicate/manual-queue processing decisions. RTE3 measures scoped time and data recovery evidence. RB3 instead tests whether a new inverse of a disruptive or ineffective intervention has a verified baseline, bounded new authority, observed trigger, exact execution target, independent post-reversal protective and business checks, and explicit human review.
These questions are complementary, not interchangeable. A successful control test is not a safe rollback plan; a successful rollback receipt is not verified protection; a normal-looking service function is not full recovery; and an open review item is not an incident-closure receipt.
A rapid-course learner has met this section's objective when they can decide whether to hold, propose, verify or escalate a reversal from a small evidence packet, explain why two independent post-state checks matter, and refuse to insert the synthetic scenario into the canonical 09:37 decision.
RB3 offline laboratory — Containment Reversal Readiness and Verification
Classification: Independent, entirely synthetic laboratory. All identifiers, times, flags, approvals, execution receipts and post-state results are invented for RB3. Nothing relates to actual Harbor Library operations, R1–R24, Branch S/P or other labs.
Objective: Evaluate a proposed inversion of a fictional isolated staff-write containment setting. Accept a narrowly valid rehearsal only when pre-state, prior intervention, new reversal approval, scope, execution window, observed trigger, matching execution receipt and both post-reversal outcomes are represented, with a human review remaining open.
Environment: Python 3 standard library, in memory. No files, network, accounts, logins, real controls, destructive commands, configuration updates or production access.
Inputs and expected rule
The fictitious date is 2040-04-10 UTC. The verified pre-state reference is CFG-GOOD-7; the prior approved and reported-applied containment reference is CTRL-PAUSE-9, affecting only staff-write. Its application receipt is a declared fixture value, not an authenticated event. Reversal requires a separate ServiceOwnerSim approval receipt and a 14:05–14:25 UTC window, and the proposed rollback targets that same narrow function. A service-harm or protection-failure observation is needed before an inverse is pursued. The operator's execution time must follow the approval decision and fall inside its window. The returned target and the separately observed post-state target must match the plan. The trigger receipt must agree with the declared trigger kind.
In this controlled fixture, protection_check=True means a declared residual protective check passed for the tested scope after the inverse. It does not mean the original blocking control remained active. legitimate_service_check=True means the declared permitted business check passed. Neither Boolean proves a real system property. A positive result must retain human_review_open=True.
Full executable Python 3 program
from copy import deepcopy
from datetime import datetime
def utc(value):
return datetime.fromisoformat(
"2040-04-10T" + value + ":00+00:00"
)
BASE = {
"baseline_ref": "CFG-GOOD-7",
"baseline_verified": True,
"intervention_id": "CTRL-PAUSE-9",
"intervention_approved": True,
"intervention_execution_receipt": "EXEC-CTRL-01",
"intervention_scope": {"staff-write"},
"rollback_target": "CFG-GOOD-7",
"rollback_scope": {"staff-write"},
"rollback_owner": "ServiceOwnerSim",
"rollback_approver": "ServiceOwnerSim",
"rollback_approval_receipt": "APP-RB-01",
"authorized_window": (utc("14:05"), utc("14:25")),
"decision_time": utc("14:12"),
"execution_time": utc("14:13"),
"trigger_kind": "SERVICE_HARM",
"trigger_observed": True,
"trigger_receipt": "TRIG-SVC-01",
"rollback_proposed": True,
"execution_receipt": "EXEC-RB-01",
"executed_target": "CFG-GOOD-7",
"post_state_observed": True,
"observed_target": "CFG-GOOD-7",
"protection_check": True,
"legitimate_service_check": True,
"human_review_open": True,
}
def evaluate(p):
if not p["baseline_verified"] or not p["baseline_ref"]:
return "HOLD_BASELINE_UNVERIFIED"
if (
not p["intervention_approved"]
or not p["intervention_execution_receipt"]
):
return "HOLD_PRIOR_INTERVENTION_UNVERIFIED"
if (
not p["rollback_approval_receipt"]
or p["rollback_approver"] != p["rollback_owner"]
):
return "HOLD_APPROVAL_MISSING_OR_WRONG"
if (
not p["rollback_scope"]
or not p["rollback_scope"].issubset(
p["intervention_scope"]
)
):
return "HOLD_ROLLBACK_SCOPE_INVALID"
start, end = p["authorized_window"]
if not (start <= p["decision_time"] < end):
return "HOLD_OUTSIDE_APPROVED_WINDOW"
if (
not p["trigger_observed"]
or not p["trigger_receipt"]
or p["trigger_kind"] not in {
"SERVICE_HARM", "PROTECTION_FAILURE"
}
or p["trigger_receipt"] != {
"SERVICE_HARM": "TRIG-SVC-01",
"PROTECTION_FAILURE": "TRIG-PROT-02",
}.get(p["trigger_kind"])
):
return "HOLD_TRIGGER_UNOBSERVED"
if (
not p["rollback_proposed"]
or not p["execution_receipt"]
):
return "PROPOSED_NOT_EXECUTED"
if (
p["execution_time"] is None
or not (p["decision_time"] <= p["execution_time"] < end)
):
return "HOLD_EXECUTION_TIME_INVALID"
if (
p["rollback_target"] != p["baseline_ref"]
or p["executed_target"] != p["rollback_target"]
):
return "EXECUTION_TARGET_MISMATCH"
if not p["post_state_observed"]:
return "EXECUTION_REPORTED_EFFECT_UNVERIFIED"
if p["observed_target"] != p["rollback_target"]:
return "POST_STATE_TARGET_MISMATCH"
if p["protection_check"] is not True:
return "PROTECTION_NOT_ACCEPTED"
if p["legitimate_service_check"] is not True:
return "SERVICE_NOT_ACCEPTED"
if not p["human_review_open"]:
return "HUMAN_REVIEW_MISSING"
return "BOUNDED_REVERSAL_CHECKED_REVIEW_OPEN"
CASES = [
("VALID_WITH_OPEN_REVIEW", {}),
(
"VALID_AFTER_PROTECTION_TRIGGER",
{
"trigger_kind": "PROTECTION_FAILURE",
"trigger_receipt": "TRIG-PROT-02",
},
),
("BASELINE_UNKNOWN", {"baseline_verified": False}),
(
"PRIOR_INTERVENTION_UNVERIFIED",
{"intervention_approved": False},
),
("PRIOR_INTERVENTION_NO_EXECUTION", {"intervention_execution_receipt": None}),
("APPROVAL_ABSENT", {"rollback_approval_receipt": None}),
("WRONG_APPROVER", {"rollback_approver": "AnalystSim"}),
(
"SCOPE_EXCEEDED",
{"rollback_scope": {"staff-write", "identity"}},
),
("EMPTY_SCOPE", {"rollback_scope": set()}),
("WINDOW_EXPIRED", {"decision_time": utc("14:30")}),
("EXECUTION_OUTSIDE_WINDOW", {"execution_time": utc("14:30")}),
("EXECUTION_BEFORE_DECISION", {"execution_time": utc("14:11")}),
("TRIGGER_NOT_OBSERVED", {"trigger_observed": False}),
("TRIGGER_NOT_SUPPORTED", {"trigger_kind": "RUMOR"}),
("TRIGGER_RECEIPT_MISMATCH", {"trigger_kind": "PROTECTION_FAILURE"}),
("PROPOSAL_WITHOUT_EXECUTION", {"execution_receipt": None}),
("RECEIPT_WRONG_TARGET", {"executed_target": "CFG-UNKNOWN"}),
("RECEIPT_WITHOUT_EFFECT", {"post_state_observed": False}),
("POST_STATE_WRONG_TARGET", {"observed_target": "CFG-UNKNOWN"}),
("PROTECTION_REGRESSED", {"protection_check": False}),
(
"LEGITIMATE_SERVICE_DOWN",
{"legitimate_service_check": False},
),
("HUMAN_REVIEW_NOT_OPEN", {"human_review_open": False}),
]
for name, changes in CASES:
candidate = deepcopy(BASE)
candidate.update(changes)
print(f"{name}: {evaluate(candidate)}")
assert (
evaluate(BASE)
== "BOUNDED_REVERSAL_CHECKED_REVIEW_OPEN"
)
RB3-RECHECK supplemental audit — bind receipts to time and scope
The baseline RB3 validator checks declared values but cannot inspect whether an approval was actually recorded before execution, whether a trigger was observed before approval, or whether the two post-state checks occurred after execution. A positive baseline label therefore does not establish that sequence. In a fresh RB3-only scratch session, run this supplement after the full 22-case program. Its receipts are new, invented classroom inputs; they are not R-series facts, authenticated records, or W1 observations. approval_time == decision_time and execution_receipt_time == execution_time are explicit assumptions of this small fixture, not universal operational rules.
# RB3-RECHECK: requires original BASE, evaluate(), utc().
from copy import deepcopy
POSITIVE = "BOUNDED_REVERSAL_CHECKED_REVIEW_OPEN"
RECEIPTS = {
"approval_ref": "APP-RB-01",
"approval_owner": "ServiceOwnerSim",
"approval_scope": {"staff-write"},
"approval_target": "CFG-GOOD-7",
"approval_time": utc("14:12"),
"trigger_time": utc("14:10"),
"execution_receipt_time": utc("14:13"),
"post_state_time": utc("14:14"),
"protection_checked_time": utc("14:15"),
"service_checked_time": utc("14:16"),
"review_as_of": utc("14:17"),
}
def rb3_recheck(packet, receipt):
original = evaluate(packet)
if original != POSITIVE:
return original
required = set(RECEIPTS)
if (set(receipt) != required or
any(receipt[key] is None for key in required)):
return "RECEIPT_METADATA_INCOMPLETE"
if (
receipt["approval_ref"] != packet["rollback_approval_receipt"]
or receipt["approval_owner"] != packet["rollback_owner"]
or receipt["approval_scope"] != packet["rollback_scope"]
or receipt["approval_target"] != packet["rollback_target"]
):
return "APPROVAL_NOT_BOUND_TO_TARGET_AND_SCOPE"
start, end = packet["authorized_window"]
if not (
receipt["trigger_time"] <=
receipt["approval_time"] == packet["decision_time"]
and start <= receipt["approval_time"] <=
receipt["execution_receipt_time"] == packet["execution_time"] < end
):
return "TRIGGER_APPROVAL_EXECUTION_ORDER_INVALID"
if not (
packet["execution_time"] <=
receipt["post_state_time"] <=
receipt["protection_checked_time"] <= receipt["review_as_of"]
and receipt["post_state_time"] <=
receipt["service_checked_time"] <= receipt["review_as_of"]
):
return "POST_EXECUTION_EVIDENCE_TIME_INVALID"
return "BOUNDED_RECHECK_WITH_DATED_RECEIPTS_REVIEW_OPEN"
def print_rb3_recheck(label, packet, changes):
receipt = deepcopy(RECEIPTS)
receipt.update(changes)
print(f"{label}: {rb3_recheck(packet, receipt)}")
print_rb3_recheck("DATED_BASELINE", BASE, {})
print_rb3_recheck("UNRECORDED_CHECKS", BASE,
{"protection_checked_time": None})
print_rb3_recheck("FUTURE_TRIGGER", BASE,
{"trigger_time": utc("14:20")})
print_rb3_recheck("LATE_APPROVAL", BASE,
{"approval_time": utc("14:14")})
print_rb3_recheck("WRONG_APPROVED_SCOPE", BASE,
{"approval_scope": {"booking-read"}})
print_rb3_recheck("CHECK_BEFORE_EXECUTION", BASE,
{"post_state_time": utc("14:11")})
print_rb3_recheck("PROTECTION_FAILED",
{**BASE, "protection_check": False}, {})
print_rb3_recheck("EARLY_VALID_TRIGGER", BASE,
{"trigger_time": utc("14:01")})
Predict the eight additional results and compare the RB3-RECHECK worked result. A real review would need trustworthy issuer-side approval and control receipts, source-clock semantics, the named operator, a verified pre-change baseline, linked request identifiers and separate protection and legitimate-service acceptance evidence. A passing synthetic check keeps human review open; it does not establish recovery or incident closure.
Before running: predict the twenty-two scenario lines and record which gate each case tests. Run only the offline in-memory program; then compare with the RB3 worked result in the final appendix. The printed positive status describes a bounded synthetic reversal check with human review still open, never full incident recovery.
RB3 two-role practical exercise — Frozen Reversal Packet and Independent Decision
Roles: Reversal Packet Author and Independent Reviewer. The roles are fictional classroom assignments; no participant receives real production privileges.
Objective: Test whether another learner can determine from a sealed record whether a proposed reversal has a verified baseline, justified trigger, correct approver and scope, actual execution receipt and two independent post-reversal results without asking the author for undocumented context.
Procedure
- Choose the fixture. Use the artificial
VALID_WITH_OPEN_REVIEWcase or one negative RB3 variant. Do not use R1–R24 as executed rollback evidence. State the fictional date and scope. - Author prepares the packet. Include baseline reference and its asserted check, intervention reference and prior approval status, trigger observation, proposed inverse target and objects, required owner, approval window, receipt status, post-state protection and legitimate-service results, and review owner.
- Freeze the packet. Save
RB3-packet-v1. Do not edit it during the receiver phase. The packet is a classroom document, not a runbook for real action. - Reviewer works independently. Without verbal or written hints from the author, produce
RB3-review-v1that states whether the reversal may remain proposed, whether it is reported executed, whether each post-state gate has evidence, and which approval or source is still needed. - Reviewer identifies the next safe step. For a missing approval, request the proper owner decision. For missing execution verification, request a bounded post-state check. For a failed protection or service result, request a new owner-governed action while documenting risk.
- Freeze the review. Compare it with the declared fixture and the Python output. Record whether a disagreement came from a missing packet field, an unsupported inference or a misunderstood decision state.
- Retest with versioning. If needed, publish a clearly labeled
RB3-packet-v2with corrected fields and obtain a new reviewer response. Preserve the first failed answer and its reason.
Required evidence package: Both frozen versions, a source-reference table, named approving role, justified trigger, scope and window check, execution/effect status, two gate results and next human decision. The reviewer must never use silence to infer permission.
Pass: The reviewer rejects invalid or incomplete routes, accurately reports the limited positive case and identifies its unresolved human-review work. Critical fail: the reviewer authorizes real changes, promotes a proposal to execution, restores an unverified baseline, ignores a failed protection gate, or reports full incident recovery from a bounded rollback result.
Limit: Passing the two-role tabletop does not demonstrate reliability of a real rollback mechanism. It tests an independent person's understanding of a fictional control-decision packet.
Worked checkpoint
A write pause is only effective for the routes actually tested. Blocking W-UI while W-API remains unmeasured does not justify a full containment claim; a separate legitimate-service check identifies the cost to users.
Practice — Lesson 11
EX027 — Three different goals
Objective: distinguish a control action from a cause fix and a service test. Inputs: R17–R23 and sections 3.3–3.5 at 09:37 UTC. Output: a three-row table for proposed session revocation, credential reset and isolated restore test, with primary goal, prerequisite authority or evidence, observable success check, and one important limit. Do not claim that any of these actions has occurred. A score of 2 identifies the credential reset as only a candidate eradication action if credential compromise is supported, and keeps a test of a copy distinct from live-service acceptance.
Worked answer: EX027 in the final appendix.
EX028 — Changed assessment
Objective: update hypotheses without rewriting the earlier decision. Inputs: R9, R10, R12 and R17–R18. Output: a before/after 09:37 assessment note with the earlier unresolved B19 issue, what R17 adds about approved tasks, what R18 adds about B20, the hypothesis weakened, the concern strengthened, and a fact that remains unproved. Record event and availability times separately. A score of 2 does not claim the learner knew R17–R18 at the 09:20 Module 2 review or identify the human behind desk-a.
Worked answer: EX028 in the final appendix.
EX029 — Decision matrix
Objective: select a bounded containment proposal. Inputs: R18–R21 and the section 3.3 comparison. Output: a two-row matrix for session revocation and the fifteen-minute staff-write pause, each with intended effect, path it does not cover, operational cost, approving role, executing role, post-action check and rollback. Add one sentence choosing an option provisionally at 09:37. A score of 2 names R21 as tolerance for a pause, not proof that a pause was approved and executed, and verifies the service cost as well as the intended block.
Additional queue requirement for EX029: For the pause option, distinguish R21 tolerability from later approval, execution and verification. Name the front-desk queue owner, the receipt and current-state checks needed before applying an item, and a hold for a conflict or absent approval. A pending request is not an accepted booking.
RB3 extension: Additional requirement: Within the existing two-row comparison for session revocation and the fifteen-minute staff-write pause, add for each option (a) the pre-intervention state that would have to be verified, (b) an observable service-harm or protection-failure trigger that would justify seeking reversal, (c) the accountable approver of that new reversal decision, and (d) separate protection and legitimate-service checks after a reported inverse. Do not create a third row, reuse W1 probe outcomes as canonical facts or claim the option was executed at 09:37.
RB3 2-point refinement: Both original intended effects and service costs remain explicit, with R21 labeled tolerance only. The reversal is a separately approved proposal with exact target and review conditions; a hypothetical fallback does not prove recovery.
Worked answer: EX029 in the final appendix.