Scenario: the exam engine and its anti-cheat pipeline
The server owns each candidate's clock and closes each attempt itself; anti-cheat signals are claims to review, never verdicts.
Predict first
Before you read: predict
ECON-201 runs for 90 minutes from each candidate's own start, with a 30 s grace after that candidate's deadline; the server then finalises the attempt and refuses later saves. In Hall 2, Ana starts at 09:00:00. Ben starts at 09:00:00 with 25% extra time. Chloe starts at 09:04:00, after a late check-in. Dev starts at 09:00:00, and at 09:40:00 a proctor pauses his attempt for 6 minutes while his camera is replaced. Chloe's laptop battery dies at 10:20:00, and she does not come back.
Which finaliser closes all four attempts between 30 s and 60 s after each one's own deadline?
The 30-second version
The server stores each attempt's deadline, set per candidate by start time, extra time and pauses. A finaliser closes each attempt by reading its stored deadline when it runs, after a grace that covers saves already received. Anti-cheat events are a device's claims: score them off the save path, let a person decide, and keep evidence only while needed.
The server owns each candidate's clock and closes each attempt itself; anti-cheat signals are claims to review, never verdicts.
How it works
Step 1 of 14
In the kitchen
- a closing time in the register, read from the office's own clock → the attempt's stored deadline (step 1)
Analogy: A procurement office's sealed-tender box
Each bidder's closing time is written in the office's tender register, and the officer works from the register, never from a bidder's watch.
| At the procurement office | In the exam engine |
|---|---|
| a closing time in the register, read from the office's own clock | the attempt's stored deadline (step 1) |
| a written extension, entered against one bidder's name | one candidate's extra time or pause (step 2) |
| at closing the officer reads the register, extensions written that morning included | the finaliser reads the row when it runs (steps 3–4) |
| an envelope stamped in at the front desk before closing, still in the internal post | a save received within the grace (steps 6–7) |
| two bids with the same typing error, filed for the tender board with the documents | a case for a proctor, with its evidence (step 12) |
| losing bids shredded after the challenge period; the board's minutes kept | deletion when done; decisions kept (steps 13–14) |
Breaks down when: a sealed envelope never changes after it is handed in, while an answer keeps changing until the deadline. And the desk stamp is the office's own, but a candidate's app can fake an event (step 9).
Contrasting case: a signal the server sees itself, such as one attempt saving from two browsers at once. It is harder to fake, yet an honest cause, a reopened tab, produces it too, so it also goes to a person.
In real terms: the server holds every clock and every decision; the browser shows the time and reports what it saw.
Examples, run for real
4.1 ExamHall EXH-2350: extra time that lived only on screen
ECON-201's save handler refused any save after the exam's own end plus 30 s, while the candidate app drew each countdown with that candidate's extra time. Two extra-time candidates kept saving every 30 s until their screens reached zero. MR !2650 stores a deadline on each attempt and checks that instead.
4.1 ECON-201 ends at 10:30:00 for the exam · grace 30 s · two extra-time candidates save every 30 s from 10:31:00 until their own screens reach zero
4.1 before MR !2650, checked against the exam's end: Ivo (25% extra) refused 44 of 44 · Noor (50% extra) refused 89 of 89
4.1 after MR !2650, checked against each attempt's deadline: Ivo refused 0 of 44 · Noor refused 0 of 89
The screens were right and the server was wrong: the accommodation lived where it decided nothing (steps 1–2).
4.2 Media streaming: one account, two cities
A streaming service flags an account when two cities play on it in one evening. A seeded month of flags, with fixture labels for their causes, run through two policies (a model):
4.2 flags 1,000 · travelling 554 · VPN 245 · family member 108 · shared password 93 (fixture labels, seed 2350)
4.2 lock at once: accounts locked by code 1,000, honest among them 907
4.2 ask "was this you?", then a person: accounts locked by code 0 · not confirmed, so sent to a person 158, of them shared passwords 67 of 93
Most flags had an honest cause, so locking by code punished the account holders; asking first and sending the rest to a person locked nobody by code (steps 10, 12).
Try it
Answer first, then check. Nothing is saved.
Question 1 of 6
In this hall, ECON-201 runs for 90 minutes from 09:00:00 and gives each candidate a 30 s grace after their deadline; the server then finalises the attempt and refuses any later save. The app sends a save as soon as a draft is typed and resends it every 10 s until the server acknowledges it. Four candidates type their final Q12 draft at 10:29:59. Ana, Ben and Chloe have a 10:30:00 deadline; Dev has 25% extra time and a 10:52:30 deadline. Ana's save reaches the server at 10:29:59, then her link drops for 90 s, so the acknowledgement never reaches her. Ben's link drops at 10:29:58 and returns 90 s later. Chloe's link drops at 10:29:58 and returns at 10:30:16. Dev's link drops at 10:29:58 and returns 90 s later.
How many of the four 10:29:59 drafts are in the finalised attempts?
Question 2 of 6
ExamHall's candidate app listens for visibilitychange and, each time the exam page becomes hidden, sends a hidden event over the exam's WebSocket, stamped with the device's clock.
What can the anti-cheat service conclude from these events?
Question 3 of 6
ECON-201's save handler checks that the attempt is still open, then awaits antiCheat.score(save.events), and only then stores the save. The scoring service works through calls in arrival order, 2 at a time, 0.6 s each. Attempts are finalised at 10:30:30, and a save not stored by then is lost. At 10:29:58, 600 final saves arrive together.
Which change gets all 600 saves stored before 10:30:30, with every one of their event batches scored by 10:45:00?
Question 4 of 6
After ECON-201's attempts are stored, ExamHall's anti-cheat scorer reads their events from the stream and flags every attempt it scores above 0.9. This sitting, it flags 40 attempts.
Which handling of the flags acts against no honest candidate by code, and gets every flag looked at by a member of staff?
Question 5 of 6
The data section of ExamHall's anti-cheat design lists four rules. A privacy reviewer marks one of them as a real problem.
Which rule?
Question 6 of 6
After ECON-201's attempts are finalised, its anti-cheat scorer works through the 2,400 attempts one at a time, in attempt number order, from 10:31:00, taking 7 s per attempt. When it scores an attempt above 0.8, it opens a case at once that shows the proctors the attempt's events; it will open 48 cases, for attempts #50, #100, #150 and so on up to #2,400. At 12:00:00, when results are released, a privacy job deletes the events of every attempt with no open case, and an attempt with no events scores 0.
Which change gets all 48 cases opened with their events, and keeps no unflagged attempt's events for more than 1 hour after the last process that reads them is done?
Go deeper
Pro tip
- In the first minutes of "design an online exam platform", draw the attempt row before any box:
started_at,time_factor,paused_secs,deadline,finalised_at, and name the one process allowed to change each field. When: the opening of the round, before the high-level diagram (sd-design-round-frameworkstep 2). Status: SELF (this lesson's practice target; not run).
Source
The curriculum row names three sources; every page below belongs to one of them. MDN and the OWASP Top 10 can change: the facts below are as of 2026-10-01. Valid as of 2026-10-01.
- MDN, Page Visibility API: https://developer.mozilla.org/en-US/docs/Web/API/Page_Visibility_API (
mdn-page-visibility.txt; the page was last modified on Dec 30, 2025).hiddencovers a background tab, a minimised window "or because the device's screen is off"; "While onblur and onfocus will tell you if the user switches windows, it doesn't necessarily mean it's hidden." - OWASP Top 10:2025 (the row's owasp.org/Top10/ now answers with a redirect page to the 2025 edition, saved as
raw/owasp-top10-index.html; the edition's index is https://top10.owasp.org/2025/,owasp-2025-index.txt):- A01 Broken Access Control: https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/ (
owasp-2025-a01.txt). "Access control is only effective when implemented in trusted server-side code or serverless APIs, where the attacker cannot modify the access control check or metadata." Supports steps 1 and 5. - A04 Cryptographic Failures: https://top10.owasp.org/2025/A04_2025-Cryptographic_Failures/ (
owasp-2025-a04.txt). "Don't store sensitive data unnecessarily. - A06 Insecure Design: https://top10.owasp.org/2025/A06_2025-Insecure_Design/ (
owasp-2025-a06.txt). Its mapped weaknesses include "CWE-602 Client-Side Enforcement of Server-Side Security". Supports step 5. - A09 Security Logging and Alerting Failures: https://top10.owasp.org/2025/A09_2025-Security_Logging_and_Alerting_Failures/ (
owasp-2025-a09.txt). Logging PII as a weakness, evidence "held for enough time to allow delayed forensic analysis", append-only audit trails, and "If your application or its users behave suspiciously, issue an alert."
- A01 Broken Access Control: https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/ (
Related lessons
Checked against the tools and docs as of 2026-10-01.