Roadmap
Phases are an order, not a date promise. What is marked done exists in the code, with tests; what remains open is what the product still needs to serve someone outside this repository.
Pace reference: 20h per week. Each phase ends with something valuable on its own.
Phase 0 · Foundation — complete, except going live
Section titled “Phase 0 · Foundation — complete, except going live”- Turborepo monorepo, strict TypeScript, ESLint, Vitest, Playwright
-
tokens.cssinpackages/uiand UI primitives - RDKit.js loading in a worker through Comlink, with a test that sanitizes aspirin
- Continuous integration in GitHub Actions — lint, types, core tests, action tests with Postgres, and desktop and mobile browsers
- Live instance with its own domain — see
docs/DEPLOY.md; depends on a VPS and registrar
Phase 1 · Core — complete
Section titled “Phase 1 · Core — complete”The whole product without accounts, a server, or AI. Everything on the client.
- 2D editor: drawing, drag-to-create, bond order, element, move, erase, undo, fit in view — plus rectangle and fragment selection, right-click menu, long press, page-wide shortcuts, periodic table, and shortcuts in a popover
- Arrange the drawing through RDKit, with a report of what happened to each wedge (D-24)
- RDKit bridge: sanitization, SMILES, InChIKey, descriptors, charge in the formula
- Functional groups recognized through SMARTS in RDKit, with Portuguese names
- Geometry and animated folding — OpenChemLib conformation and MMFF94 (D-10); elements outside MMFF94 show their shape without vibration and explain why
- Molecular dynamics vibration — velocity-Verlet over the numerical MMFF94 gradient at 300 K, trajectory precalculated in the worker and cached by InChIKey (D-14)
- Normal modes — Hessian, mass weighting, rigid-body projection, and diagonalization: 3N − 6 (3N − 5 if linear), each with its own wavenumber and motion (D-20)
- Double and triple bonds as parallel rods in the scene; CIP letters in the drawing and scene
- 2D↔3D synchronization — the highlighted atom is the same (D-18); light and dark themes; responsive down to 390px
- Portuguese error messages that explain chemistry, not code
Phase 2 · Storyline — complete
Section titled “Phase 2 · Storyline — complete”- Mission engine with declarative
spec— the same function evaluates on client and server - 15 missions covering Estrutura, Geometria, and Propriedade (Structure, Geometry, and Property), with handwritten hints
- Paste SMILES and name search through PubChem, with a third state when PubChem does not respond
- Open-ended tool mode, without missions, scores, or achievements (D-09)
- Tutor with a closed schema and no numeric fields, source indicator, cache by
molecule/mission/type, and a daily cap — optional: without
GEMINI_API_KEYit turns off; the default model uses an alias with a fixed fallback, because models leave circulation (GEMINI_MODELchanges it without touching code) - Accounts, saved progress, server-side
specreevaluation — Postgres (D-11) - Password recovery through teacher-issued codes, no email in the path (D-19)
- Minhas moléculas (“My molecules”): save, start another, export SVG and PNG; giving a nickname also saves (D-15)
- Public molecule page with SSR and Open Graph —
/m/<smiles>, no database - Stereochemistry: wedges and dashes in the editor,
wedgein the graph, V2000 molblock,R/S/E/Zassigned by RDKit, enantiomers as mirrored shapes in the scene, and the mission that only succeeds with the correct wedge (D-21)
Phase 3 · Teacher — complete in code, open in the field
Section titled “Phase 3 · Teacher — complete in code, open in the field”- Teacher dashboard: classes with codes, a board showing where each student got stuck — progress, never molecules (D-22)
- Class assignment lists: teachers assemble sequences from catalog missions or create their own
by drawing the answer — the product extracts goals from the molecule, never from typed
text; a mission whose own answer does not satisfy it is rejected; the answer key never reaches
students (D-25,
docs/ROTEIROS.md) - Searchable catalog, for account holders, with missions published by teachers — opt-in per mission, visible authorship, reporting with an audit trail (D-26, D-27)
- A school manages itself: its first administrator comes from the terminal and promotes teachers from the same school through the interface, checking the name before writing — only up to teacher, and every role change leaves a trail (D-29)
- Telemetry implemented and disabled — self-hosted Umami, no cookies, a closed list of
events in
apps/web/lib/track.ts; without both variables, the script does not even load - Backup and restore rehearsal as scripts (
scripts/backup-db.sh,restore-db.sh) - Low-end phone performance measured with throttling: loading the 3D scene on demand reduced first
paint from 11,7 s to 6,9 s;
immutableon the engine; precompressed.wasm
What is missing here is not code:
- Observation sessions with 3 teachers and 8–10 students — watching, explaining nothing. The nomenclature questions, and the rule not to raise the subject, are below
- Nomenclature and language review by a chemist
- Live telemetry and scheduled cron backups with the first restore rehearsal completed (D-11)
- Usability fixes that only the sessions will reveal
What to ask teachers about nomenclature — and in what order
Section titled “What to ask teachers about nomenclature — and in what order”The product does not name compounds, by choice (D-15). The session means watching without explaining anything. Nomenclature is not introduced: wait.
- Do not raise the subject. Record whether the teacher or student asks for a name unprompted: at what minute, and with what structure on screen. Someone who does not ask provides data just as useful as someone who does.
- If they ask, the only question is “what would you do with that name in your lesson?” — then be silent. Record their answer in their words.
- If nobody asks before the end, when closing, in this exact order:
- “In your class, when nomenclature comes up, what do students do more: receive a structure and write its name, or receive a name and draw the structure?”
- “If Rotamer could do only one of those, which would serve you better?”
- “And if the name came out in English — ‘ethyl acetate’ instead of ‘acetato de etila’ — would that help, get in the way, or be worse than no name at all?”
The third question determines the cost of any path: it separates a term mapping
from a nomenclature dictionary maintained forever. The paths, with the cost of each, are
in FORA-DE-ESCOPO.md; the research behind them is in docs/pesquisa/nomenclatura.md.
Phase 4 · Open — in progress
Section titled “Phase 4 · Open — in progress”Rotamer is open-source, MIT, and noncommercial (D-28). What that decision requires:
- MIT license,
CLAUDE.md, and agents describing an open project - Self-hosting in three commands — a three-stage
Dockerfilewithstandaloneoutput,docker-compose.ymlwith the app and Postgres, migration at startup throughdocker/entrypoint.sh, image built in CI on every push and published to GHCR on everyv*tag - Documentation for three audiences, in
docs/: users (GUIA.md), installers (INSTALACAO.md), contributors (ARQUITETURA.md,CONTRIBUTING.md); documents that described intentions now describe what exists, and obsolete material was removed - Opt-in telemetry, stated clearly — off by default, and
INSTALACAO.mdsays what it measures and what never leaves - First
v0.1.0tag, so the published image exists anddocker compose pullworks without building — and make the package public in GHCR, because it starts private - Landing page in a separate repository, static, pulling
docs/at build time —rotamer-site(Astro + Starlight): a landing page with real product screenshots and the complete documentation at/docs/, with edit links pointing to the source file - Publish
rotamer-site— create the GitHub repository and enable Pages; while Rotamer is private, the workflow needs a read token inROTAMER_TOKEN
Open question, recorded in FORA-DE-ESCOPO.md: the entire roadmap serves teaching. Without the
commercial tension that held it back, the research track becomes a legitimate question again — and still
awaits Phase 3 sessions for a written answer.
| Risk | Sign it happened | What to do |
|---|---|---|
| Scope creep — the most likely | A new idea enters the code without going through FORA-DE-ESCOPO.md |
New ideas go to FORA-DE-ESCOPO.md. The pm decides whether they enter. |
| A chemist finds an error | Someone points out incorrect tautomerism or stereochemistry | Never bypass RDKit. Admitting it quickly builds more trust than no errors at all. |
| Tutor cost runs away | The bill rises without proportional usage | Cache by InChIKey, daily caps, fallback to written hints; and the tutor is optional. |
| Nobody uses it | Phase 3 with no interested teachers | Talk to teachers now, with the product as it is. |
| Heavy WASM on phones | More than 5 s to the first drawing on 3G | RDKit loads after first paint; the 3D scene loads on demand. |
| The live instance costs more than the author can sustain | Server or key costs strain the budget | Shrink the instance. The code does not close (D-28). |
How to know whether it is working
Section titled “How to know whether it is working”Real signals
- A teacher shares the link in the class group without being asked
- Someone returns on another day, without a reminder
- A molecule built in Rotamer appears on a lesson slide
- A school runs its own instance
- A chemist opens an issue pointing out a subtle error — it means they took it seriously
Misleading signals
- Likes
- Launch-day traffic spikes
- Praise for the visuals without anyone building a molecule