Build OpenPTE
KINDAreplaces $17.99/mosaves $215.88/yrback to the verdict
A practice platform for exam-style speaking, writing, reading and listening tasks, where the honest engineering problem is producing genuinely useful feedback on a spoken or written response without pretending to be the official scoring engine.
Before step 1
Everything below is assumed from the first step. Tick each one when you actually have it, not when you plan to.
- installfree
Why Runs the server and task delivery.
Get it nodejs.org, or nvm install 22. open ↗
Verify
node --version prints v22 or higher - installfree locally
Why Attempts, recognitions and observations with per-dimension queries.
Get it Docker or your package manager. open ↗
Verify
psql connects and creates a table - installfree, needs machine time
Why Fluency feedback comes from timings and uncertainty from confidence, and sending learners' voice recordings to a service is a poor default.
Get it whisper.cpp or an equivalent, confirmed to emit per-word timings and confidence rather than segments only. open ↗
Verify
A spoken response produces per-word timings and confidences offline - have readyfree, and it is real work
Why Real exam items are copyrighted, and a platform built on them cannot be shared and does not teach the skill.
Get it Write tasks matching the published format descriptions rather than reproducing items. Aim for a handful per format before building the delivery.
Verify
At least five original tasks exist per format, with none copied from an exam - have readyfree, and requires asking people
Why The fairness requirement of this build is that an accent is never reported as an error, and that can only be tested against varied speakers.
Get it Ask people who would actually use this, with their permission, and keep the recordings only as long as needed for testing.
Verify
Recordings from at least four first languages exist and none is reported as mispronunciation
Data model
Create these before the first phase that stores anything. Changing a table later is the expensive kind of change.
- tasks(id, skill, format, prompt_text, audio_path, time_limit_seconds, source) · source is always original - attempts(id, user_id, task_id, started_at, submitted_at, response_text, response_audio_path) - recognitions(attempt_id, word_ordinal, text, start_ms, end_ms, confidence) · the basis for speech feedback - observations(id, attempt_id, dimension, detail, evidence_json) · dimension is fluency, pronunciation, grammar, content or discourse - progress(user_id, dimension, week, observation_count, trend) · improvement over time, never a predicted score - There is deliberately no column anywhere holding a predicted overall band, because a field like that gets displayed eventually.
Environment variables
These go in a .env file the app reads at startup. The pack's .env.example is this table as a file · copy it, never commit the filled-in version.
| Variable | Needed | Example | Where the value comes from |
|---|---|---|---|
DATABASE_URLsecret | required | postgres://localhost:5432/practice | Attempts and observations, including learners' voice recordings by reference. |
AUDIO_DIR | required | ./attempts/audio | Voice recordings. Personal data, so retention and deletion apply to this directory too. |
ASR_MODEL | required | ./models/ggml-medium.en.bin | The local recogniser. Larger models give better timings and fairer confidence across accents. |
AUDIO_RETENTION_DAYS | required | 90 | How long voice recordings are kept. Shorter than the observations derived from them. |
SHOW_PREDICTED_SCORE | required | never | Present as a constant so the answer is visible in configuration. There is no other value. |
The build, in order
Tasks delivered under exam conditions
A practice task runs with the same timing pressure as the real thing.
The client shows a countdown. It does not own one.
Files
src/timer.tsEven if the browser is gone. The attempt still happened.
Files
src/attempts.tsAn interrupted attempt is data, not something to hide.
Files
src/attempts.ts
done when · tick each as it passeswatch out- A timer running in the browser can be paused by opening the developer tools or simply losing focus, which turns timed practice into untimed practice and removes the only thing that makes it resemble the exam. Keep the clock on the server and treat the client display as a hint.
Hearing what was actually said
A spoken response becomes words with times and confidences.
Both are needed. Fluency comes from timings, uncertainty from confidence.
Files
src/recognise.tsTest with several accents. This is the fairness requirement of the whole build.
Files
tests/accents.mdA bad microphone is not a speaking weakness and must not be reported as one.
Files
src/audio-quality.ts
done when · tick each as it passeswatch out- Treating low recogniser confidence as mispronunciation punishes accents the recogniser was simply not trained on, which is both wrong and demoralising to exactly the people using the tool. Report low confidence as uncertain rather than incorrect, and never present the recogniser's difficulty as the speaker's failure.
Feedback that names something specific
Every observation points at a moment or a phrase in the response.
A timestamp or a span. Validate it and reject the output otherwise.
Files
src/observations.tssrc/validate.test.tsNo aggregate field. A number that exists will eventually be shown.
Files
src/schema.sqlFeedback that only lists failures is demoralising and less useful.
Files
src/observations.ts
done when · tick each as it passeswatch out- Combining dimensions into a single figure recreates exactly the predicted score this build refuses to produce, and users will read it as one. Keep the dimensions apart in the model and in the interface, and make sure no aggregate exists anywhere that could be displayed as an overall result.
Written responses, checked honestly
An essay gets specific feedback on grammar, content and structure separately.
Same essay, same findings, every time. Label them as mechanical.
Files
src/checks.tsAn observation about a paragraph must include the paragraph.
Files
src/essay.tsSo the user knows which finding is reliable and which is an opinion.
Files
src/feedback-view.ts
done when · tick each as it passeswatch out- Presenting a model's opinion about an essay's quality with the same authority as a spelling checker's finding misleads the user about how reliable each is, and a model asked to grade will confidently invent criteria. Label the deterministic checks and the model's observations differently, and require the model to quote the text it is describing.
Progress, without inventing a numberproduct builder
A learner sees improvement over weeks without ever being shown a predicted result.
And never on the exam's scale. The axis is the claim.
Files
src/progress.tsWhere it is read, not in a footer where it is not.
Files
src/feedback-view.tsIncluding voice recordings, which are biometric-adjacent and personal.
Files
src/export.tssrc/deletion.ts
done when · tick each as it passeswatch out- A trend line drawn on a zero to ninety axis will be read as a predicted score no matter what the caption says, because the axis is the claim. Use counts and rates on their own scales, and keep the exam's scale out of the interface entirely.
That is the whole plan for OpenPTE. What it deliberately does not cover is below · check the gaps before you call it a replacement.
- Any predicted or estimated official score.
- Real exam questions.
- The official integrated skill scoring model.
- Accreditation or any claim of affiliation with the exam board.
- Scores calibrated to the real automated marker, so your numbers are vibes, not predictions
- A question bank that is maintained and rotated as the exam changes
- Full mock tests with official section timing, weighting and score report layout
- Model answers, templates and community discussion around each item
- Mobile apps, cross-device sync, and anyone to blame when the grader is wrong
- Spaced repetition over the dimensions a learner is weakest in
- Model responses for each task, which is what learners ask for after feedback
- A study plan built from observation trends rather than from a score
Need the files? The project pack on the verdict page hands your agent the whole brief · more education.