Skip to content
KB-M1
Sign inCalibration record · Rev A

calibration

Synthetic keystroke streams with known ground truth, replayed through the engine. Every figure below is asserted against a value derived by hand, not observed and blessed. Three of these guard correctness traps that produce plausible but wrong numbers: a repeated key cannot overlap itself, modifiers are never keystrokes, and a keyup lost to a focus change must not poison every measurement after it.

All pass — 187 of 187

CheckDetailExpectedActual
IKI → WPM identity — passwpmFromIki(120)100.0000100.0000
IKI → WPM identity — passwpmFromIki(200)60.000060.0000
Rollover: discrete — passno overlap anywhere0.00000.0000
Mean IKI — passkeys 200 ms apart200.0000200.0000
Hold time — passeach key held 80 ms80.000080.0000
Rollover: full — pass3 of 4 keystrokes roll0.75000.7500
Mean overlap — passheld 120 ms, 100 ms apart20.000020.0000
Rollover: repeated key — pass'll' cannot overlap0.00000.0000
Rollover: modifiers — passShift excluded0.00000.0000
Keystroke count — passShift is not a keystroke1.00001.0000
Rollover: stuck key — passblur clears held keys0.00000.0000
KSPC — pass6 keystrokes, 4 final chars1.50001.5000
Corrections — passone backspace1.00001.0000
Accuracy — pass4 of 5 non-correction strokes0.80000.8000
Alternation benefit — passalternating 60 ms faster60.000060.0000
Idle: wall clock — passstart to finish10200.000010200.0000
Idle: active time — passgap capped at 3 s3200.00003200.0000
Idle: paused time — passthe excluded 7 s7000.00007000.0000
Idle: speed uses active — passwpm from active, not wall clocktruetrue
Blur: no time charged — pass60 s hidden costs nothing100.0000100.0000
Final char: run closes — passcursor reached the endtruetrue
Final char: reopens — passbackspace revives ittruetrue
Final char: reports reopened — passso the caller can cancel the savetruetrue
Final char: refinishes — passcorrected and completetruetrue
Final char: accuracy — pass2 of 3 printable correct0.66670.6667
Soft kb: keydown rejected — pass229 carries no timingtruetrue
Soft kb: detected — passfallback path armedtruetrue
Soft kb: text recorded — passtwo characters2.00002.0000
Soft kb: timing survives — pass150 ms apart150.0000150.0000
Soft kb: flagged — passrollover is not measurabletruetrue
Caps Lock: detected — passread off any keystroketruetrue
Integrity: paste flagged — passnever silently droppedtruetrue
Integrity: impossible gaps — pass5 ms is below the motor floor1.00001.0000
Timed: remaining — pass15 s budget, 1 s typed14000.000014000.0000
Timed: text end does not finish it — passbudget decidestruetrue
Gate: fast but sloppy fails — pass12 wpm at 0.96falsefalse
Gate: accurate but slow fails — passspeed still requiredfalsefalse
Gate: both cleared passes — passtruetrue
Unlock: first lesson open — passtruetrue
Unlock: third lesson shut — passone ahead onlyfalsefalse
Unlock: pass opens the next — passtruetrue
Unlock: earlier stays open — passrevision is never blockedtruetrue
Next lesson: skips the passed one — passtruetrue
Placement: never regresses — passa bad day cannot close materialtruetrue
Drill: stays in pool — passpool "fj"0.00000.0000
Drill: non-empty — passtruetrue
Drill: reproducible — passsame lesson and attempt, same texttruetrue
Drill: retry differs — passso it cannot be memorisedtruetrue
Revive: rejects junk — passfalls back to no placementtruetrue
Revive: rejects null — passtruetrue
Revive: keeps valid rows — passone of two survives1.00001.0000
Revive: clamps placement — pass999 is not a stagetruetrue
Habit: streak crosses months — pass30 Jan → 1 Feb3.00003.0000
Habit: days practised — passthree distinct days3.00003.0000
Habit: grace for today — passyesterday still counts1.00001.0000
Habit: gap breaks streak — passonly today counts1.00001.0000
Habit: longest remembered — passthe earlier pair2.00002.0000
Habit: same day merges — passone day, two runs1.00001.0000
Habit: daily total sums — passtwo minutes120000.0000120000.0000
Habit: empty history — passno streak, no crash0.00000.0000
Guide: f is left index — passtruetrue
Guide: j is right index — passtruetrue
Guide: capital needs shift — passA is Shift+KeyAtruetrue
Guide: space is a key — passtruetrue
Guide: covers the alphabet — pass26 lowercase letters resolvetruetrue
Columns: ten of them — passone per finger10.000010.0000
Columns: thirty keys — passno key in two columns30.000030.0000
Columns: cover the alphabet — passevery letter has a fingertruetrue
Columns: eight home keys — passthe anchors, stretches excluded8.00008.0000
Columns: two stretch columns — passthe inner reaches2.00002.0000
Columns: QAZ on US QWERTY — passnames are built from the layouttruetrue
Columns: every key resolves back — passcolumnOf is total over the pooltruetrue
Columns: sweep is a round trip — passd e d c d — three returns in fivetruetrue
Reverse: every prompt distinct — passthirty keys, thirty descriptions30.000030.0000
Reverse: gives nothing away — passno character appears in the prompttruetrue
Reach: names the anchor — passE is one up from Dtruetrue
Recall: correct promotes — passbox 0 → 11.00001.0000
Recall: slow does not promote — passworked out, not retrieved0.00000.0000
Recall: miss drops two — passa slip is not amnesia2.00002.0000
Recall: miss floors at zero — pass0.00000.0000
Recall: cap limits promotion — passcued reps stop at 33.00003.0000
Recall: cap never demotes — passbox 5 stays 5 under a cap of 35.00005.0000
Recall: miss leaves latency alone — passa wrong key times nothing420.0000420.0000
Recall: automatic needs speed — passtop box at 1200 ms is known, not automatictruetrue
Recall: automatic at the top — passtruetrue
Recall: unseen is not shaky — passnever asked ≠ got it wrongtruetrue
Decay: mastered key floors at one — passforgotten becomes slow, not unknown1.00001.0000
Decay: unmastered key falls to zero — pass0.00000.0000
Decay: recent key untouched — passone day is not a lapse5.00005.0000
Key revive: rejects junk — passtruetrue
Key revive: keeps valid rows — passone of two1.00001.0000
Key revive: clamps the box — pass99 is not a box5.00005.0000
Key revive: drops bad clear stamps — pass1.00001.0000
Schedule: terminates — pass0.00000.0000
Schedule: secures every key — pass12 in the pool12.000012.0000
Schedule: no immediate repeats — passanswers cannot come from inertia0.00000.0000
Schedule: two clean reps per key — pass24 prompts for 12 keystruetrue
Schedule: misses buy more reps — passthe missed key outnumbers a clean onetruetrue
Schedule: capped for a stuck typist — passends rather than holding them theretruetrue
Schedule: nothing secured on all-wrong — pass0.00000.0000
Sweep: two columns, two passes — pass5 strokes each20.000020.0000
Sweep: starts at home — passtruetrue
Sweep: names the column once — passtruetrue
Sweep: a miss does not advance — passthe same reach is asked againtruetrue
Sweep: advances on success — passtruetrue
Homing: impossibly fast rep discarded — passhands never lifted2.00002.0000
Homing: median ignores it — pass650.0000650.0000
Homing: best ignores it — pass600.0000600.0000
Homing: slow rep counted but not clean — passfound, not arrived attruetrue
Homing: six clean arrivals pass — passtruetrue
Homing: an abandoned rep is not a homing time — pass48 s is an interruption, not a measurement450.0000450.0000
Homing: and is counted separately — pass1.00001.0000
Homing: best is unaffected — pass400.0000400.0000
Align: omission is one omission — pass'helo'1.00001.0000
Align: and not a run of substitutions — pass0.00000.0000
Align: doubled letter is an insertion — pass'helllo'1.00001.0000
Align: a wrong key is a substitution — passc → b1.00001.0000
Align: nothing else moves — passinsert+omit would cost the same0.00000.0000
Align: identical text is all matches — passtruetrue
Align: empty is empty — pass0.00000.0000
Align: abandoned run is not 500 omissions — passtarget clipped to what was attemptedtruetrue
Realign: positional model miscounts — pass'helo' scores 3 of 4 right3.00003.0000
Realign: every stroke was correct — passthe typist hit no wrong key4.00004.0000
Realign: one omission — pass1.00001.0000
Realign: no substitutions — pass0.00000.0000
Realign: the 'o' is re-attributed — passwas charged to l, belongs to o1.00001.0000
Realign: reports the damage — passone stroke mis-attributed1.00001.0000
Realign: aligned accuracy — pass4 matched of 5 operations0.80000.8000
Realign: the omitted char is named — pass1.00001.0000
Realign: corrections are not insertions — passtyped, deleted, retyped0.00000.0000
Realign: the survivors are clean — pass2.00002.0000
Pearson: perfect positive — pass1.00001.0000
Pearson: perfect negative — pass-1.0000-1.0000
Pearson: a flat series has no correlation — passzero variance is not r = 0truetrue
Pearson: refuses two points — passtruetrue
Detrend: shared trend inflates raw r — passboth rise, r = 11.00001.0000
Detrend: and vanishes once removed — passno relationship beyond timetruetrue
Detrend: residuals sum to zero — pass0.0000-0.0000
Slope: recovers a known gradient — passseries rises 10 per step10.000010.0000
Slope: unit gradient — pass1.00001.0000
Slope: flat series — pass0.00000.0000
Loop: silent below the threshold — pass11 runs is not a findingtruetrue
Loop: confirms a real relationship — passtruetrue
Loop: reports a negative — passfaster runs had less rollovertruetrue
Loop: says so in words — passthe verdict names the contradictiontruetrue
Loop: excludes runs too short to measure — passtruetrue
Loop: the weakness is noticed — passtop pairs were th, ertruetrue
Loop: ranked by time lost, not slowness — passthe costliest pair leadstruetrue
Loop: the plan targets it — passtargets th ertruetrue
Loop: the drill text contains it — passdiagnosis reaches the keyboardtruetrue
Loop: the transfer test is the measured one — passdrill pace is not a typing speedtruetrue
Loop: invents nothing for an even typist — passno pair is slower than the rest0.00000.0000
Loop: and falls back honestly — passordinary text, not a fabricated drilltruetrue
Loop: headroom is real, not aspirational — passyour own 20th percentile, not a targettruetrue
Loop: one dropped letter used to poison the matrix — passpositional model logged 496 confusionstruetrue
Loop: and now logs none — passan omission is not a substitution0.00000.0000
Roll call: order — passthe eight home keys, left to righttruetrue
Roll call: a wrong key holds its place — passQ at position one — a miss, not a resettruetrue
Roll call: eight correct presses end it — passdone on the final home keytruetrue
Roll call: the miss survives the run — passone wrong key is still on record1.00001.0000
Roll call: inert when done — passa ninth press changes nothingtruetrue
Walk: only the thirty count — passEnter is not part of the map0.00000.0000
Walk: two of three is not a column — passQ and A without Z0.00000.0000
Walk: home, up and down make one — passZ completes QAZ1.00001.0000
Walk: the whole board — passthirty keys, ten columns10.000010.0000
Coach: no runs, no evidence — passan empty history sends nothingtruetrue
Coach: recent speed is the median — passruns at 40, 60, 50 wpm50.000050.0000
Coach: costliest pair leads the pack — passer loses the most total timetruetrue
Coach: targets are letters only, ranked — passer in re antruetrue
Coach: passage separated from the read — passtagged block comes out wholetruetrue
Coach: no tag, no passage — passthe read survives untouchedtruetrue
Coach: untypeable passage rejected — passan em dash is not on the boardtruetrue
Coach: whitespace flattened — passa passage is one line on the instrumenttruetrue
Features: mechanics reads the costliest pair — passthe er data travels in the prompttruetrue
Features: mechanics stays silent without misses — passno pairs, no theorytruetrue
Features: the week is exactly seven days — passthe contract says seven linestruetrue
Features: debrief carries today's number — pass42 wpm against a median of 38truetrue
Features: debrief admits a missing baseline — passday one is not judged against nothingtruetrue
Features: mnemonics pick the lost, not the never-asked — passc struggles, f is fine, q was never promptedtruetrue
Features: mnemonics name finger and anchor — passc is the middle finger's drop from dtruetrue
Features: mnemonics cap at eight keys — passtwelve lost keys, eight cues8.00008.0000
Features: mnemonics rank the most lost first — passan unknown key outranks a slow onetruetrue
Features: no cues for nothing — passan empty list is null, not an empty prompttruetrue
Features: topic is flattened and capped — passwhitespace collapses, 200 chars become 80truetrue
Features: topic passage is passage-only — passthe contract forbids text outside the tagstruetrue
Features: question is capped, emptiness rejected — pass400 chars at most, silence is not a questiontruetrue
Features: the answer must come from the pack — passquestion and evidence travel togethertruetrue
KB-M1 · Form 08/08 · Rev AThe same fixtures run headless — npm test