Semester OSa Telegram-first academic planner
It knows your courses, your lab-defense sessions, your grades and your free time, and answers one question in Telegram: what should I do now, and why.
- Role
- Sole developer and first user
- Started
- 30 October 2026
- Stack
- TypeScript, Cloudflare Workers, Hono, Postgres, grammY, React
- Source
- Private repository
A calendar can't tell you that you're about to fail
At ITMO most of my courses are passed by defending labs in person, in a limited number of sessions. If four sessions are left and four labs still need defending, missing one session fails the course. No calendar or to-do app shows that. Grades live in teacher-maintained Google Sheets, each with a different layout, and the schedule changes week to week.
Semester OS is built around one promise: open Telegram, ask “what should I do now?”, and get one recommendation you can trust, with the reason and a button to act on it.





Five things it keeps track of
- Requirements
- What you actually have to complete to pass or to reach a target grade.
- Opportunities
- When each requirement can still be done: lab defenses, resits, teacher-approved windows.
- Evidence
- Prepared, submitted, verified and graded are four different states, never merged into one.
- Capacity
- The time you really have, after classes, work, commuting and sleep.
- Recoverability
- Which outcomes are still possible, and the minimum path to them.
The engine is deterministic: a priority score with hard constraints and a written explanation, a course-health state, and a recoverability check. That check uses a branch-and-bound search for the minimum set of items that still passes, allocates labs to the remaining sessions, and runs an earliest-deadline-first time check. It returns one of five honest answers: feasible, high risk but possible, impossible by schedule, impossible by points, or unknown when data is missing.
Reading teachers' grade sheets without reading anyone else's grades
My three courses use three completely different sheet layouts: letter grades with two header rows, comma decimals with formulas that show 0,0 before a test, and one row per team with “+” marks. The sync fetches each sheet's public CSV export, finds only my row by comparing a SHA-256 hash of my identifier, and keeps only the mapped cells of that row. Classmates' rows are never stored or logged.
Every mapped column remembers its header. If a teacher inserts or renames a column, the sync stops and says where the column moved instead of silently reading the wrong one. A blank cell means unknown, never a fail. Only the sync is allowed to write official results; a database trigger rejects anything else.
Claude proposes, I confirm in Telegram
Semester OS runs its own MCP server, so Claude can read the real semester: status, courses, capacity and the current recommendation. When Claude wants to change something, such as adding a task or marking a lab prepared, it can only create a proposal. The bot sends it to me with Confirm and Reject, and the change is applied once, in one transaction, however many times the button is tapped. Teacher-verified results and grades can never be proposed.
Built to be trusted with real deadlines
- Every Telegram update is deduplicated, so a webhook replayed five times has exactly one effect.
- Each request runs in a transaction scoped to one user, and Postgres row-level security blocks cross-user reads.
- Reminders go through a jobs table with leases, backoff and a dead-letter state, driven by a one-minute cron.
- Data freshness is part of every answer: stale, unverified and self-reported are labelled as such.
- The deployed service checks its own database schema and reports a clear error if code ships without its migration.
244 automated tests, 10 architecture decision records, and 18 merged changes in the first four days.
Written down before they were built
| 0002 | One Cloudflare Worker on the free tier, with a measured CPU budget per request |
| 0004 | Grade-sheet sync: public CSV export, own row only, header-checked mappings |
| 0005 | Claude connector v1: read-only MCP with a personal key, stored only as a hash |
| 0006 | Claude proposes, the student confirms in Telegram |
| 0007 | Timetable import from ICS with its own parser |
| 0009 | Read-only Telegram Mini App, authenticated by Telegram's signed initData |
Where it is now
The Telegram bot, the academic engine, grade-sheet and timetable sync, the Claude connector and a read-only Mini App work on staging, and I use them for my own semester. Next come the weekly planner and recovery plans, editing in the Mini App, a standalone web login, and a pilot with a few classmates.
The repository is private. I'm happy to walk through the code.