Proctored assessments & technical interviews
Watch how the answer was actually written
A risk score tells you to be suspicious and hands you nothing to check. ProctorHire replays the whole sitting — every change to the answer, every paste, every tab switch — so you can see what happened, and what it examined and cleared.
No credit card. Build a paper, send it to one candidate, and watch the replay.
7 self.window = 6089 def _key(self, tenant, route):10 return f"rl:{tenant}:{route}"1112 def _prune(self, key, now):13 cut = now - self.window14 pipe = self.redis.pipeline()15 pipe.zremrangebyscore(key, 0, cut)16 pipe.zcard(key)17 return pipe1819 def handle(self, tenant, event):20 prior = self.store.get(event["id"])
Cleared by the cross-question provenance guard: these two helpers were already in this candidate’s own answer to question 1, matched character for character.
The problem
Right now you are guessing, in both directions
Two things happen in every technical hire that nobody can currently see, and a number between 0 and 100 settles neither of them.
The score does not show its working
An opaque risk figure tells you to be suspicious. It cannot tell you what to look at, you cannot act on it on your own, and you certainly cannot repeat it to the candidate when they ask why.
So honest candidates get rejected
Reformatting a file, undoing and redoing, reusing a helper you wrote twenty minutes ago on the previous question, pasting a column name off the schema the question handed you — to a detector that only counts, all of it looks like the real thing.
And a finished submission hides everything
By the time you read the answer there is nothing left to see. How it was written exists only while it is being written, and only if something was recording.
The proof
The evidence is the keystrokes
While a candidate sits an assessment, ProctorHire records the edit stream: every change, in order, per question. Playback merges it into one timeline and lays the integrity record on top of it.
Replay the whole sitting
Which question was open, when they moved between them, and how much was typed in each. The timeline is indexed by change rather than by clock, so a sitting with thirteen hundred separate changes in it is actually navigable — from half speed up to eight times, with a switch that skips the stretches where nobody typed.
Every event sits on the keystroke it happened at
A tab switch, a paste, a block that arrived all at once: one marker each, on the same axis as the typing. Open one and you get the answer exactly as it stood at that moment, and the clip recorded around it — eight seconds by default, and you set that. When there is no clip — the recording never reached storage, or the test was set up without screen recording at all — it says which of those happened instead of handing you a blank frame to draw your own conclusion from.
A marker is only placed where the data supports one
An event with no keystroke to sit on — a tab switch during a multiple-choice section, where there is no editor at all — is listed separately rather than pinned to the nearest one. Where a position had to be inferred, the marker is drawn hollow and the panel says how far off it might be.
Nothing is scored in secret
The integrity figure starts at 100 and subtracts the weights you set: 25 for a tab switch if you chose 25. The arithmetic is on the screen, so a hiring meeting can say “forty, because of two critical events and a fullscreen exit” out loud, and anybody in the room can check it.
0:16 of 0:48 — each block is one occurrence; click a block, or its marker above, to jump straight to it.
The test tab lost focus for 1:03. Its piece of the reel starts at 0:16 and runs 6.9s — the switch itself, with the seconds either side of it.
Every occurrence keeps the time it happened, so a reviewer who wants the rest of that moment can jump straight back to +11:47 in the full recording.
The difference
The part that clears people
A large block of text arriving in a single change is the strongest signal in the whole product. It is also exactly what happens when somebody reformats a file, cuts a function and pastes it back two lines down, moves their own working code from question 1 into question 3, or copies a table name off the schema the question put on their screen.
So before anything is reported, five guards try to explain the insertion. Each guard can only ever remove a finding, never add one. When one of them accounts for the text, the moment still appears on the timeline — marked Cleared, with the guard named and the reason written out. A reviewer watches the exact keystroke the block appeared at and reads why it is not a finding.
The five questions asked before anything is reported
- It is a rewrite of what was already therereformatting, an undo, a redo
- They had cut that text moments earliera cut and paste back into the same answer
- It is already somewhere else in the same answera duplicated block
- It is their own work, from another questioncode moved from question 1 into question 3
- The exam itself put it on their screena starter template, a prompt, a SQL schema
Cleared is a record, not a deletion
A detector that silently drops what it decided to ignore is unauditable. Every clearance stays on the timeline with the sentence that explains it, so the record shows what was examined, not only what survived. It is the difference between telling a candidate “the system did not flag you” and showing them the keystroke, the block, and the reason.
Answer similarity works the same way
Two submissions are compared as normalised token streams rather than as text, so renaming the variables, reindenting and deleting the comments does not defeat it. But the question’s own template, and the phrasing that every correct answer to that question shares, are struck out before the comparison runs. “They both used SELECT … GROUP BY” is never a match, because it is what a right answer looks like.
A finding you can dismiss is worth something. A dismissal you can show the candidate is worth considerably more.
The answer went from 250 to 654 characters between two consecutive changes. 62% of what was on the screen landed at once, and nothing was replaced.
- Was this a rewrite, a reformat or an undo?Similarity guard — No. Nothing was replaced: 404 characters in, none out.
- Had the candidate cut this same text from this question earlier?Removal-history guard — No. Nothing matching it was ever removed from question 3.
- Was it already on screen, further up the same answer?In-document guard — No. Question 3 held no copy of it.
- Was it already in this candidate's own editor on another question?Cross-question provenance guard — Yes. All 404 characters, verbatim, in question 2 — typed there 13:53 earlier.
- Did the question itself put this text on their screen?Question-material guard — Not reached. Guard 4 already accounted for the text.
8 self.prefix = "rl"910 def _key(self, tenant, route):11 return f"{self.prefix}:{tenant}:{route}"1213 def _claim(self, key, ttl):14 token = uuid4().hex15 ok = self.redis.set(key, token, nx=True, px=ttl)16 return token if ok else None1718 def _release(self, key, token):19 if self.redis.get(key) == token:20 self.redis.delete(key)2122 def _ttl(self, s):23 return int(s * 1000)
10 self.window = 601112 def _key(self, tenant, route):13 return f"{self.prefix}:{tenant}:{route}"1415 def _claim(self, key, ttl):16 token = uuid4().hex17 ok = self.redis.set(key, token, nx=True, px=ttl)18 return token if ok else None1920 def _release(self, key, token):21 if self.redis.get(key) == token:22 self.redis.delete(key)2324 def _ttl(self, s):25 return int(s * 1000)
Both blocks are the same 404 characters — matched character for character, at line 10 of one answer and line 12 of the other.
Cleared by the cross-question provenance guard: the text was already in this candidate’s own editor elsewhere, matched character for character. This is a record of a large insertion that was examined and NOT reported.
The queue
And then a person still decides
Playback is for the sitting you are unsure about. The rest of the time it is a list: submissions arriving against a paper, each carrying a score and an integrity figure, and none of them settled until you settle it.
Two columns, because they are two questions
Whether the answer was any good, and how the answer came to exist, are not the same enquiry and do not combine into one figure. Anything that multiplies them has made your decision and hidden which half of it it was made on.
The figure arrives with its working
Under each integrity number is the count of events behind it — five violations, one, none. So the number is never the whole of what you are told, and “why is this one 20?” is answered on the row before anybody opens anything.
And when something else decides, it says so
Approve and reject here are a person’s: a submission waits until somebody presses one. A hiring workflow with a score rule in it can settle an assessment stage on its own — and the review it writes is stamped “auto-synced from the hiring workflow decision”, so a verdict nobody in the room remembers making still names the thing that made it.
The other leak
Two candidates, two different papers, the same test
The quickest way to break an assessment is for the person who sat it on Monday to send the questions to the person sitting it on Thursday. Each paper is drawn from pools, so there is no one paper to pass on — and the pools are balanced, so two people who were never asked the same question are still scored out of the same number.
Every candidate sits 7 questions worth 38 marks, drawn from a bank of 21 worth 114.Every question a slot can draw is worth the same marks and sits in the same difficulty band, so the total is a property of the test and not of the draw. A test that breaks that cannot be published.
| Candidate 1preview:4 | Candidate 2preview:5 |
|---|---|
| 4 easy · 4 marks each · 16 on every paper | |
| 1Count orders per customer4 marks | 1Top five products by revenue4 marks |
| 2Find duplicate email addresses4 marks | 2Rows created in the last 7 days4 marks |
| 3Parse a CSV into records4 marks | 3Merge two dictionaries safely4 marks |
| 4Group a list of dicts by key4 marks | 4Flatten a nested list4 marks |
| 2 medium · 7 marks each · 14 on every paper | |
| 5Rate-limit an outbound client7 marks | 5Page through a cursor API7 marks |
| 6Choose a partition key7 marks | 6Cache a read-heavy list7 marks |
| 1 hard · 8 marks each · 8 on every paper | |
| 7Exactly-once from a queue8 marks | 7Backfill 400M rows without locking8 marks |
| Paper total38 marks4 easy · 2 medium · 1 hard | Paper total38 marks4 easy · 2 medium · 1 hard |
These papers are comparable: identical length, identical marks, identical difficulty profile — so both scores are out of the same 38, and the candidate who sat it yesterday has nothing useful to pass on.
The rest of it
And the whole hire runs in the same place
Playback is what makes the assessments worth trusting. These are the parts around it, so a candidate does not have to be copied between four tools and a spreadsheet on the way to an offer.
Assessments with proctoring built in
Coding, multiple-choice, SQL, Excel and written papers. While a candidate sits one, the session is monitored against rules you set, and what was recorded is shown to a reviewer alongside the answers rather than turned into a verdict.
Code that actually runs
Answers execute against test cases in 22 languages, with the console output the candidate saw.
Live technical interviews
Video and audio over WebRTC, with screen sharing, a Monaco editor both people can type in, and a whiteboard for the parts that are easier drawn.
One-way video screening
Recorded answers a candidate submits in their own time, so a first pass does not need two diaries to agree.
Structured scoring
Each round is run from a scorecard: the same questions, the same rating scales, a written reason and a clear recommendation - so two interviewers are judging the same thing.
The decisions that follow
Stages a candidate moves through, what happens automatically at each one, the funnel and scores behind it, and the offer letter at the end.
Straight answers
What it does not do
At least two of these will cost us a deal at some point. Publishing them is still cheaper than a buyer discovering them on their own in week six, and a page that admits its limits is the only kind whose other claims are worth reading.
No face detection, and no identity check from the webcam
The webcam records and the recording is shown to a reviewer. Nothing here decides that a face is missing, or that there are two of them. Those checks were taken out rather than shipped as a guess, because a guess about somebody’s face ends a career.
No SOC 2 report and no ISO 27001 certificate
Not pending, not in progress: absent. If your security review requires either one, we are not ready for you yet, and you should know that now rather than in week six.
It cannot see a second screen, or a phone in someone’s lap
No browser can. Where a moment looks like that, you get the two facts — when typing resumed, and how much was typed afterwards — clearly labelled as observations, scored at nothing and flagged as nothing.
No customer logos, and the people in the figures are invented
This is a new product with a small number of customers, and none of them has agreed to appear in anyone’s marketing. So the screens on this page are drawn rather than photographed: they are the real layouts, the real controls and the real wording, filled with data we made up. Nobody named in them exists and the counts — 391 in the pipeline, 41 hired — are invented, not customers and not our own usage either. They are there to show what the screens do, and they claim nothing about how many people use this. Everything above is checkable by using the product, which is the only proof we are entitled to offer yet.
Send one assessment and watch it back
Build a paper, publish it, and send it to a single candidate — yourself, if you like. Nothing has to be configured first, and you can see exactly what they will see before you send it. Then open the playback and decide whether the rest of this page was true.
Name, email, company, password. No credit card, and nothing to install.