Valerii Kozhevets about work study certificatescerts projects tools

Terramentor

A study app I built alone and released as 1.0.0 on 2 October 2026: it plans a course against a deadline, verifies the questions the model writes, and schedules review with FSRS-6.

2026 softwareAI source on GitHub ↗1.0.0 release ↗

Terramentor
Front end React 18, TypeScript, Vite, Tailwind, Zustand
Back end Node, Express, SQLite with sqlite-vec, server-sent events
Model Ollama or any OpenAI-compatible endpoint, optional
Learning model Bayesian knowledge tracing, FSRS-6 with a per-learner parameter fit
Ships as desktop builds for Windows, macOS (Apple silicon) and Linux, Docker image
Interface 12 languages
Licence AGPL-3.0-or-later

Terramentor is a study app for someone learning alone against a deadline. It spreads a course over the days until the exam, writes lessons and questions with a language model and checks them before they are served, asks for proof before a topic closes, and schedules flashcard review with FSRS-6. I have built it on my own since 17 March 2026. The repository went public on GitHub on 17 September under AGPL-3.0-or-later, and the 1.0.0 release of 2 October ships desktop builds for Windows, macOS and Linux and a Docker image.

A lesson on total internal reflection in my physics course, generated on 11 August 2026. The text, the formulas and the animation are the model's; the Fix this button on every visual sends a note on what is wrong back to the model, which rebuilds it.

March to June 2026: from a topic tree to a planner

The first version, on 17 March, was a recursive topic tree with drag and drop. A week later it could talk to a local model through Ollama and answer from my own material, and from 4 April the model could draft a whole phased tree from a description of the subject, streamed and cancellable.

Scheduling arrived on 14 May. A course has a start date, a deadline and the days of the week I study; the time between is spread over the topics by weight, pace compares the topics finished with the ones the plan puts before today, and recalibrating re-plans only what is still open.

a course timeline with twelve phases from July to December 2026, each a bar on a month axis with a vertical line marking today; the first two phases are green, the three up to today are red, and the later ones are pale blue or green
My physics course as planned on 23 September 2026: twelve phases towards a 1 December deadline.

In June each topic got a Bayesian knowledge tracing estimate. A topic counts as proven when that estimate clears a threshold or when a mastery check of at least four questions is passed. By default this rule is advisory: it asks for proof and still lets the topic be marked done, and a stricter mode refuses. Skipping is always allowed and stays recorded as skipped, never as proven. By the end of June there was spaced repetition (SM-2 at first), a per-course vault for PDFs and Office files, questions that bring fading topics back into later quizzes, and an installable web app served over local HTTPS that I could open on my phone.

July 2026: one stream, and checking what the model writes

In early July the model started writing its own diagrams, charts and animations as code: Mermaid, Vega-Lite, SMILES molecules, animated SVG and sandboxed p5 sketches. Every renderer throws a descriptive error, and that error becomes the prompt for a repair. On 6 July the app learned to use any OpenAI-compatible endpoint besides Ollama, and on 13 July the home page stopped being a dashboard and became a single stream of lessons, questions, flashcards and recall prompts in the order the engine picks.

On 29 July I audited every generated question in my library and found that the question writer had only ever been given one segment of one lesson, so it could only ask about that paragraph: the app was testing reading comprehension of its own text. The writer now gets the whole topic and its outline, and everything it writes goes through the checks that apply to it:

A question that fails is never served. A lesson that still fails after its rewrites is served with the fault recorded on it. The same rebuild made the knowledge-tracing guess probability depend on the question format (0.5 for true/false, 0.25 for multiple choice, 0.05 for a short answer) instead of one global 0.2.

On the topics I regenerated after that rebuild, true/false questions fell from 30% to 8%. The cold answer has a limit, which my own physics course showed: a standing-wave question called the fifth harmonic the third, and the verifier, being the same model, agreed with it.

Two questions from a topic's saved bank, marked as they are answered, then the topic's flashcards. Recorded with the model switched off.

August 2026: paper, placement and FSRS-6

Paper practice, built on 29 July, is the part closest to an exam. The exercise is worked by hand and photographed, the four corners of the page are dragged into place, the browser warps it flat, and a vision model marks it against a rubric of at least four points. An unreadable photo records nothing. I used it four times on my physics course between 1 and 11 August. The first version transcribed the photo to text and graded the text in a second call. On the standing-wave attempt of 5 August the transcription reduced a labelled diagram to one line and two marks of evidence were lost, so grading became a single pass over the image, and the grader may not use one line of working both as evidence for one rubric point and as an error against another.

a paper exercise card: an ambulance at 30 m/s passes a stationary observer with a 1100 Hz siren, three parts asking for the observed frequency approaching, receding and the change, a note to show the Doppler formula and sign convention, and a folded rubric of six points worth eight marks
A paper exercise the model wrote for my physics course. The worked solution is not part of the card: it is fetched only after the work is submitted or self-marked.

On 11 August every topic got an embedding vector. The vectors place the whole library on the atlas, a map of topics by meaning, and let a topic proven in one course give the matching topic in another course a head start, capped so it can never prove a topic on its own.

On 18 August a short placement test before a course started seeding the knowledge estimates, each answer vouching for the topics before or after it in course order. The first version spread that across a whole project. On my mixed projects 31% to 63% of the seeded topics were vouched for by an answer from an unrelated section, so from 19 August an answer only counts inside its own section.

On 19 August flashcards moved from SM-2 to FSRS-6 through the ts-fsrs library. Existing cards kept their progress: each card’s stability was seeded from the interval it had already earned instead of being reset. The same day Anki decks started coming in as .apkg files, from both the old and the current Anki format, with media, card templates and each card’s scheduling state, and every note that fails to import is counted with its reason.

September 2026: the optimiser, a desktop app, the public repository

On 1 September courses could go back out to Anki as .apkg. On 2 September every review started going into a log, Anki’s own review history included, and an optimiser fits the 21 FSRS-6 parameters to that log in a worker thread. It needs 100 reviews of cards already seen on an earlier day, holds out the latest 20% of them, and the fit is kept only if it predicts those better than the default parameters. The same day the knowledge-tracing rates became fittable to my own evidence, under the same hold-out rule.

On 6 September the interface went to twelve languages, extracted by a codemod that rewrote 1,949 call sites in one pass, and the desktop build shipped: its own Node runtime, opened in an app window of the Chromium browser the machine already has, no Electron, packaged per operating system. On 15 September the atlas became a globe, on which a course replays as a route in the order its topics were finished.

The atlas replaying my physics course: each finished topic in the order I finished it, placed by its embedding among every other topic in the library. Each disc is a cluster of related topics.

On 17 September the repository went public, with a contributor licence agreement enforced by a bot and CI that runs every suite on Linux and Windows. The next week added studying a whole course as one stream, one-file course bundles, and an assistant that looks things up mid-answer and prepares a mastery check, a flashcard or a note, none of which takes effect until I press it.

How it runs

The whole app is one Node process, one SQLite file and an optional model endpoint: Ollama, or any OpenAI-compatible server or hosted provider. With no model reachable it still schedules, tracks, serves the notes and saved questions, and runs spaced repetition. There is no account and no telemetry, and SECURITY.md lists every outbound connection, then tells the reader to trust a packet capture rather than the file and gives the steps to run one. Every test suite runs against a scratch database with no model and no network, and it is the same command CI runs on every push and pull request.

I use it for my own studies. I prepared for my IELTS Academic exam with a course in it set to the test date, and on 20 June 2026 I scored 8.0 overall. On 28 September 2026 my library held 20 courses and 5 imported Anki decks, with about 17,000 flashcards between them.