Lesson map
Lesson 03 published. Map, example, EX011.
flowchart TD
N0["Learning outcomes"]
N1["3.1 Four times and three kinds of claim"]
N2["3.2 Case cards C03–C08: contradictory signals"]
N3["3.3 Intake before severity"]
N4["3.4 Handle a possible false positive without closing"]
N5["3.5 Offline time-correction and join-boundary lab"]
N6["3.E1 Intake is a provenance-preserving normalization"]
N7["3.E2 Four clocks are necessary, but not sufficient"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
N7 --> EX["Worked example"]
EX --> Q["Exercise EX011"]
Logical drawing
flowchart LR
N0["Learning outcomes"]
N1["3.1 Four times and three kinds of claim"]
N2["3.2 Case cards C03–C08: contradictory signals"]
N3["3.3 Intake before severity"]
N4["3.4 Handle a possible false positive without closing"]
N5["3.5 Offline time-correction and join-boundary lab"]
N6["3.E1 Intake is a provenance-preserving normalization"]
N7["3.E2 Four clocks are necessary, but not sufficient"]
N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX011"]
[Learning outcomes]
|
v
[3.1 Four times and three kinds of claim]
|
v
[3.2 Case cards C03–C08: contradictory signals]
|
v
[3.3 Intake before severity]
|
v
[3.4 Handle a possible false positive without closing]
|
v
[3.5 Offline time-correction and join-boundary lab]
|
v
[3.E1 Intake is a provenance-preserving normalization]
|
v
[3.E2 Four clocks are necessary, but not sufficient]
|
v
[Worked example] --> [Exercise EX011]
Learning outcomes
The learner can form one case from multiple signals without merging their claims, normalize clock readings with a stated uncertainty, assign a provisional response priority from impact and evidence confidence, and set a review trigger. At this level, triage is an auditable decision, not a prediction that an account was compromised.
3.1 Four times and three kinds of claim
An event time is when a source says something happened. Ingestion time is when a collector accepted the record. Discovery time is when a person or detector recognized it as relevant. Release time in this training case is when the learner may use the card. A support reporter's recollection is another kind of timestamp: it may be approximate and may refer to when a symptom was noticed, not when the underlying cause occurred. Put each time in a separate field and record the source's timezone and clock offset. Do not sort all strings lexically and call the result a causal sequence.
An observation is bounded by its producer: an IdP reports a successful sign-in for an account, an application audit reports an edit, a support ticket reports what a person saw. An inference joins observations: perhaps the sign-in and edit are related. A decision is what the team does under uncertainty: preserve details, check present service state or ask an owner for an approval. The distinction makes an analyst's reasoning testable. If a joined identifier is missing, nearby times can motivate a question; they cannot supply the missing join key.
3.2 Case cards C03–C08: contradictory signals
The following cards are fictional and released in sequence. At 09:09 the learner receives C03–C05; C06 arrives at 09:10, C07 at 09:12 and C08 at 09:14. The columns avoid mixing event and receipt times. All times below are UTC unless an offset is explicitly stated.
Lesson table; scroll horizontally to read all columns →
| Card and release | Source and source event time | Ingestion / receipt | Exactly what it supports; notable gap |
|---|---|---|---|
| C03, 09:09 | IdP summary: svc-enroll successful sign-in at 08:58; a summary displays session s-77. |
Collector accepted 09:02. | The IdP labelled a sign-in successful; client and human actor fields are absent from this summary. |
| C04, 09:09 | Endpoint detector: browser process on runner-03 at raw device clock 08:54. The device clock is measured four minutes slow relative to UTC in this synthetic snapshot. |
Collector accepted 09:06. | Normalized event estimate is 08:58 UTC. There is no shared session or request ID. A browser on a runner can be benign. |
| C05, 09:09 | Enrollment API audit: slot S42 edit at 09:01, account label svc-enroll, request q-144; session field blank. |
Audit collector accepted 09:07. | An application record reports an edit. It does not prove present slot state, intent or which human, if any, caused it. |
| C06, 09:10 | Maintenance calendar: 08:50 approved change lists slots S40 and S41 only. | Retrieved for case 09:10. | S42 is outside the visible approval scope. A later or missing addendum remains possible. |
| C07, 09:12 | Application owner states that svc-enroll is used by a scheduled job and sometimes an emergency operator. |
Statement recorded 09:12. | The account is shared in this exercise; the statement is not a log of this specific use. |
| C08, 09:14 | Identity custodian says detailed IdP source events for this synthetic window expire at 10:00 UTC. No export is yet in the case. | Statement recorded 09:14. | Creates a time-sensitive preservation request; it does not mean C03's summary has already been independently verified. |
The C04 conversion is elementary but consequential: a clock that displays 08:54 when UTC is 08:58 is behind, so add four minutes to its displayed event time. The normalized estimate coincides with C03's 08:58 sign-in, but the match is not evidence that the browser caused the sign-in. A real analyst would record how the offset was measured and its uncertainty; this exercise supplies only a fixed four-minute measurement, so do not claim subsecond ordering. C05's 09:01 edit happens later by the reported clock, but the missing session field prevents a direct s-77–q-144 join.
3.3 Intake before severity
Open a single CTN case with C02 as a symptom report and C03–C05 as separate sensor records. Intake should capture source, reporter/custodian, event and ingestion times, affected service, exact identifiers, original text or bounded copy reference, classification at this checkpoint, what is unknown, and next owner. Preserve the original card wording; a normalized timeline can be an additional view. If two alerts are clearly the same emitted event, link them; here C03, C04 and C05 have distinct producers and no confirmed correlation key, so keep three provenance lines.
Severity needs impact, confidence, time sensitivity and decision cost. CTN uses a classroom priority scale: P1 = immediate owner-led coordination for an observed major service or safety impact; P2 = urgent bounded investigation where meaningful harm is plausible or evidence may disappear soon; P3 = routine review of a limited signal without a time-sensitive gap. These labels are local teaching choices, not a NIST severity formula. A team may have a different approved taxonomy. Record the rationale and the checkpoint time so another responder can reproduce the decision.
At 09:14, a defensible CTN assessment is P2, provisional. The reported S42 symptom and recorded edit could affect enrollment, but the authoritative state and scope of impact are unknown. The account is shared, the cross-source join is weak, and an approved change covers other slots but not visible S42. The 10:00 source-expiry statement makes a bounded IdP preservation request urgent even if the probability of malicious activity remains uncertain. The next review triggers are: a custodian-approved detail export, an authoritative S42 state check, further user reports, a verified approval addendum, or the looming expiry. A different label could be defended if the learner cites an actual CTN policy and the same evidence limits; an unreasoned “critical compromise” cannot.
The team should distinguish urgency of preserving evidence from confidence in compromise. High urgency can coexist with low causal confidence. A useful escalation sentence is: “At 09:14, request authorized export of a narrow IdP window before the stated 10:00 expiry; separately ask the application owner to verify current S42 state. Do not disable svc-enroll without scoped service-impact review and approval.” This is a proposal, not proof the records were collected or the owner approved a change.
3.4 Handle a possible false positive without closing the case too early
The runner browser in C04 might be normal scheduled automation; the S42 display in C02 might be a stale front-end view; the calendar might omit a later addendum. These are alternative explanations, not findings. Closing as false positive requires criteria. For example, if the application owner supplies a scoped approval for S42, the job owner shows a matching q-144 run with a validated join key, and the authoritative slot state is correct, the team could downgrade or close according to its policy. The current cards do not provide those checks. Conversely, a confirmed unauthorized edit or additional affected slots could raise priority. State a specific observation that would change the assessment, rather than “monitor.”
3.5 Offline time-correction and join-boundary lab
This is a new synthetic Python 3 offline view of C03–C05, not an IdP query. All times and identifiers are authored classroom values, and no credentials or network calls occur. The fixed date is a laboratory date chosen for ISO parsing, not a claimed date of the CTN main-case events.
from datetime import datetime, timedelta
events = [
("C04", "2026-10-12T08:54:00+00:00", 4),
("C03", "2026-10-12T08:58:00+00:00", 0),
("C05", "2026-10-12T09:01:00+00:00", 0),
]
for card, raw, correction_minutes in events:
normalized = datetime.fromisoformat(raw) + timedelta(
minutes=correction_minutes
)
print(
f"C3|{card}|{normalized:%H:%M} UTC|"
f"clock_correction={correction_minutes:+}m"
)
print("C3|C04_C03_same_minute=True|direct_join=False")
Output executed with these fixture values:
C3|C04|08:58 UTC|clock_correction=+4m
C3|C03|08:58 UTC|clock_correction=+0m
C3|C05|09:01 UTC|clock_correction=+0m
C3|C04_C03_same_minute=True|direct_join=False
The final line is an explicit analyst conclusion from the fixture, not a computed assertion from a hidden join algorithm. A matching minute does not create a shared transaction key. In a real parser, the source's offset convention and time-zone handling would need independent validation. The code is deliberately small so the learner can inspect the sign of the correction and reproduce each visible output.
Perform two safe mutations: change the C04 correction from +4 to -4 and observe the incorrect 08:50 value; then restore +4 and alter C05's application event time. Neither mutation should silently change the C03/C04 join status, because no join key appears. Write a paragraph distinguishing the model input, the executed parser result, and the hypothesis about relationship between the events.
3.E1 Intake is a provenance-preserving normalization, not a merger
At 09:04 the support desk has C02: a reporter says S42 looked unavailable, first noticed around 09:00. At 09:09 the case additionally receives C03's successful IdP sign-in for svc-enroll with s-77 (event 08:58, ingested 09:02), C04's browser observation on runner-03 (raw 08:54, four-minute slow clock, ingested 09:06), and C05's S42 edit record with request q-144 (event 09:01, ingested 09:07, blank session field). Those four producers answer different questions. A support complaint is evidence a complaint was made; a successful authentication label is not human attribution; a browser process is not a validated session; an API edit is not proof of the current slot state.
The correct intake product uses one case envelope and distinct source objects. A case envelope contains ID, observed service, reporter channel, opened time, decision owner and review trigger. A source object contains immutable card ID, original event string, stated zone/offset, producer identity, ingestion/receipt time, release time, specific fields, known gaps, and authorization/copy status. Derived interpretations go into another column, not into a rewritten “normalized raw event.” This is analogous to logging and forensic provenance concepts discussed in the dated NIST SP 800-92 and SP 800-86; neither prescribes this artificial CTN schema.
A misleading timeline: 08:54 runner browser → 08:58 login → 09:01 edit → 09:04 report implicitly treats 08:54 as correct UTC and invites a causal narrative. A corrected source-aware comparison: C04's estimated normalized time is 08:58, coinciding with C03 at minute precision; C05 is reported at 09:01; C02's symptom time is approximate and may precede or follow an unknown source-state transition. C04 has no session key, C05 has no session key, and no card directly links s-77 to q-144. Time overlap is a request for a discriminator, not a proof of identity.
3.E2 Four clocks are necessary, but not sufficient
Record the producer event time, collector ingestion time, analyst discovery/review time and learner release time as different columns. The C04 raw clock was measured four minutes slow in the scenario, so 08:54 + 00:04 = 08:58 UTC. Keep both representations. A real offset measurement has error bars; a single fixed teaching offset does not establish exact seconds or event ordering within the minute. If ingestion lag is present, a query over event time performed before all relevant records arrived can appear quiet and later return additional events. The trainee must ask for the query run time, ingestion cutoff, filters, source and expected delay before interpreting absence.
For this curriculum, release time is a separate pedagogical control: C06's calendar entry is timestamped 08:50 but not released until 09:10, so it cannot justify a 09:09 decision. C08's expiry at 10:00 is reported at 09:14; an analyst at 09:09 cannot cite that statement, even though it later makes evidence-preservation work urgent. This distinction also prevents backdating a severity label: the record should state 09:09 provisional assessment, followed by 09:14 reassessment once new evidence is actually released.
3.E3 Severity is a decision contract with triggers, not a compromise probability
The book's P1/P2/P3 rubric is a local classroom ranking, not the NIST score of CTN's compromise probability. Assign separate categories:
Lesson table; scroll horizontally to read all columns →
| Question | At 09:09 | At 09:14 |
|---|---|---|
| Service impact | S42 allegedly unavailable; no approved authoritative comparison | Same unresolved state; complaint plus recorded edit still do not count affected learners |
| Causal confidence | C03/C04 temporal lead and C05 account label, no common session-request key | C06's visible work list covers S40/S41, not S42; C07 says account is shared |
| Time sensitivity | Relevant records may need authorized review; retention deadline not supplied at this release | C08 custodian reports detailed IdP source expiry at 10:00 |
| Decision cost | Account-wide disablement could disrupt enrollment; no approved operational control | Preservation request urgent while business harm of broad restriction remains unresolved |
| Review trigger | Ask service/application custodian for S42 current state and named source bounds | Request approved IdP detail now; revisit by a selected checkpoint before 10:00 or on new verified state |
At 09:14, P2 provisional is defensible for the combination of plausible enrollment harm and a reported evidence-expiry condition. It is not a statement that a human compromised the account. P1 requires evidence fitting the actual defined high-impact classroom threshold; P3 might be defended only with a documented reason the urgency/impact has changed. If a proposed query has no valid authorization, record a blocked request and escalate to the proper owner rather than silently conducting it.
3.E4 Design an intake falsifier for each competing explanation
A triage analyst can proceed without knowing the cause if every hypothesis has a test that could weaken it. Three candidate explanations must be kept distinct.
H1 — normal scheduled automation or an incomplete change calendar. The browser on runner-03 is compatible with ordinary job work and C07 later confirms svc-enroll has a scheduled use, but neither validates this specific S42 edit. Request a signed, versioned S42 authorization and a job-run record with request-ID semantics. A complete authorized job manifest that excludes q-144 would weaken the “normal approved run caused the edit” explanation; absence from an incomplete manifest would not.
H2 — use of a shared account outside approval. The C05 account label and C06 omitted S42 task support concern, while shared account usage and a blank session field leave human and mechanism unknown. Request scoped IdP/session records and application-side schema clarification through distinct custodians. A validated non-session application path would weaken an assertion that s-77 was necessary; it would not independently establish the correct cause.
H3 — display-state divergence. C02 may reflect a cached or stale view rather than the current authoritative slot. Compare an approved source-of-truth S42 value/version with an uncached synthetic view, recording when each was read. If the authoritative state is wrong, a purely display-only explanation is insufficient; if authoritative state and displayed view differ, the discrepancy deserves its own technical diagnosis. No such comparison is supplied by C02–C08.
These explanations may overlap. An authorized job can produce incorrect state; a genuine edit can coexist with a stale browser cache. The triage record should not pretend that exactly one story must win.
3.E5 Offline lab C3X — enforce release before using a timestamp
Environment: Isolated Python 3 standard library, in memory, no logs or systems contacted. This is a release-filter rehearsal using copied chapter metadata; it is not a new C-series record or an actual investigation query. The function reads the first element of each tuple as release time, not source event time.
CARDS = {
"C03": ("09:09", "08:58", "09:02"),
"C04": ("09:09", "08:54", "09:06"),
"C05": ("09:09", "09:01", "09:07"),
"C06": ("09:10", "08:50", None),
"C07": ("09:12", "09:12", None),
"C08": ("09:14", "09:14", None),
}
def minute(clock):
h, m = map(int, clock.split(":"))
return h * 60 + m
def available(card, decision):
return minute(CARDS[card][0]) <= minute(decision)
for decision in ("09:09", "09:10", "09:14"):
print(decision, ",".join(k for k in CARDS if available(k, decision)))
print("early_C08:", "REJECT_FUTURE" if not available("C08", "09:09") else "ALLOW")
print("early_C06:", "REJECT_FUTURE" if not available("C06", "09:09") else "ALLOW")
Executed output (five lines):
09:09 C03,C04,C05
09:10 C03,C04,C05,C06
09:14 C03,C04,C05,C06,C07,C08
early_C08: REJECT_FUTURE
early_C06: REJECT_FUTURE
Adversarial test: Replace C06's release time 09:10 with its earlier source event time 08:50 in a separate variant. The filter would incorrectly admit C06 at 09:09. The error is semantic, not a parser failure: release time is a pedagogical evidence boundary. Retain the original dictionary for the graded transcript.
The classifier does not authenticate clock fields, validate source collection, reconcile a device's time skew or tell the analyst which hypothesis is true. To pass, the learner must write the real boundary statement: “At 09:09 only C03–C05 from this set are released; C02 already exists from the prior chapter; neither C06 nor C08 can justify this checkpoint.” Five-point local rubric: three release lines correct, both future-control lines correct, plus a separate mandatory note that a positive classification is not proof of compromise. Explain the meaning of the None ingestion fields; they are not supplied, not zero delay.
3.E6 A reproducible decision-ready intake artifact
The handoff should be usable even if no new evidence arrives. Recommended fields: case/time; source observations with IDs and collector times; impact expressed as reported or verified; provisional priority and distinct confidence; available/withheld cards; pending authorizations; bounded next requests and accepting custodians; review event; prohibited inference; record author and revision. The analyst may write “no additional matching event in the supplied table under this exact rule,” but cannot infer “no other edit occurred” while source coverage, filtering or ingestion is unknown.
At the C08 release, record the reported 10:00 expiry as a custodian claim requiring timely confirmation and action by the proper owner. It is more urgent than perfect attribution, but does not justify a full tenant export. Chapter 4 will turn that preservation request into a separate case receipt and test the difference between a received export and verified bytes.
Chapter synthesis: Triage establishes what to investigate next and by when, not who did it. The clock correction C04=08:58 is valid for the stated toy input, but joining that event to C03/C05 requires more than time. Retain P2 at 09:14 as provisional and source-bounded. The next chapter handles receipt, custody and integrity, not cause attribution.
Common mistakes and limits
- Ordering C04 before C03 because 08:54 appears earlier than 08:58. Normalize the known four-minute offset and retain uncertainty.
- Joining
s-77toq-144by the account label alone. The application session field is blank; keep the relationship as a hypothesis. - Treating C06 as proof no S42 approval exists anywhere. It proves only that the retrieved calendar entry lists S40 and S41.
- Letting the expiry claim itself authorize a bulk export. Use the approved custodian path and a bounded window and fields.
- Equating
P2with a confirmed compromise. Priority governs response effort; it is not a forensic conclusion.
Practice: timed triage board
In a synthetic workbook, record the case at 09:09, then reveal C06, C07 and C08 in their stated order. After each release, update an observation ledger and write the smallest decision that changes. Keep earlier entries rather than overwriting them. A peer checks whether the 09:09 decision cites only C02–C05 and whether the 09:14 preservation request names the custodian, selected time range and expiry trigger. This simulates a handoff under limited information without connecting to any real tenant.
Exercises — subject 3
EX011 — Intake form. Input: C02–C05 at 09:09. Produce four separate source lines with event and receipt times, source identifiers, service implication, missing fields and one next question. A 2-point result does not join s-77 and q-144 as fact.
EX012 — Clock reconciliation. Input: C03 and C04. Give C04's normalized UTC estimate, the raw/normalized pair and a two-sentence explanation of what the coincidence with C03 does and does not establish. A 2-point result calculates 08:58 and preserves correlation uncertainty.
C3 extension for EX012: Predict and run the four-line Python 3 fixture in §3.5. Change the correction sign in a separate copy and explain why a matching minute is still not a session-to-request join.
EX013 — Priority decision. Input: C02–C08 at 09:14 and the classroom P1–P3 rubric. Choose a provisional priority, separately state impact, confidence, expiry-related urgency and a review time or event. A 2-point result can justify P2 without calling the account compromised.
EX014 — False-positive gate. Input: C04, C06 and C07. Write two benign explanations, one concerning explanation and the minimum discriminator for each. A 2-point result does not use an uncollected record as evidence.
EX015 — Shift escalation. Input: C02–C08. Compose a 90–150-word message to the incident lead with observed facts, one bounded preservation request, an S42 state check, the C01 owner gap and a condition that would change priority. A 2-point result separates these requests from approved or executed actions.
Subject synthesis
The 09:14 triage record carries uncertainty forward. P2 is a documented workload decision driven partly by the 10:00 expiry, while account misuse remains unproven. Chapter 4 will test whether a bounded export and a screenshot can be preserved with enough provenance to support later analysis.