In progress

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
The problem

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.

The Mini App
Semester OS Mini App (Today)
Real screens from the app, with an invented semester. Tap the tabs.
The model

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.

Tested on 3 real sheets

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.

AI, with a human in the loop

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.

Engineering

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.

Decisions

Written down before they were built

0002One Cloudflare Worker on the free tier, with a measured CPU budget per request
0004Grade-sheet sync: public CSV export, own row only, header-checked mappings
0005Claude connector v1: read-only MCP with a personal key, stored only as a hash
0006Claude proposes, the student confirms in Telegram
0007Timetable import from ICS with its own parser
0009Read-only Telegram Mini App, authenticated by Telegram's signed initData
Next

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.