Course Survival Agent — Project Story

Inspiration

Every student knows the frustration: it's finals week, you open Canvas to check your grade, and the built-in calculator gives you a number that ignores half your professor's actual grading rules. Drop your lowest quiz? Attendance penalty after 3 misses? Midterm curve? Canvas doesn't know — and neither do you, unless you buried yourself in the syllabus two months ago.

We wanted to build something that actually understood how your grade works — not just the weights, but the implicit policies buried in the fine print. On top of that, managing study time across five courses with overlapping exams, keeping track of which classes you can still skip, and figuring out which professor is worth going to office hours for — these are all problems that students solve manually, repeatedly, every semester. Course Survival Agent started as our answer to that.


What We Built

Course Survival Agent is a two-part system: a browser extension and a full web app.

The browser extension lives alongside Canvas in your browser. It adds an agentic chat panel directly to your Canvas experience, letting you ask questions about your course status in natural language — "Can I skip tomorrow's quiz and still get a B?" — while showing a live overview of all your courses side by side without leaving Canvas.

The web app is the full course planner hero. It features:

  • Dashboard — a unified cross-course view of assignments, deadlines, and grade status
  • Dynamic Grade Calculator — our flagship feature (more below)
  • Study Planner — AI-generated study blocks that respect constraints like "two exams tomorrow, which do I study first?"
  • Instructor Insights — pulls Rate My Professor data and Reddit threads to surface teaching style, grading tendencies, and exam focus areas before you even step into class
  • Google Calendar Sync — study blocks and deadlines pushed directly to your calendar
  • Canvas Auto-Sync — assignments, grades, and due dates fetched live from Canvas so you never have to enter them twice

The Dynamic Grade Calculator

This is what makes Course Survival Agent genuinely different from every other student planner.

When you upload your syllabus, our pipeline extracts not just the grading weights, but the implicit grading policies — the rules that Canvas ignores entirely. We then call the Gemini 2.5 Flash API as an agent to compile those policies into executable JavaScript code, which is stored in the database and run inside a sandboxed Node.js vm context at grade calculation time.

The compiled code slots into a three-stage template:

$$\text{Grade} = \sum_{i} \frac{\text{ProcessedScore}_i}{100} \times w_i$$

where $\text{ProcessedScore}_i$ is the per-category score after implicit policies are applied:

Slot Runs Used for
PREPROCESS Per category, before averaging Drop lowest score, best-of-N
ADJUST Per category, after averaging Per-category curves, extra credit caps
FINAL Once, after all categories Attendance penalties, overall curves

In practice, if your syllabus says "drop the lowest quiz score and curve the midterm by 5 points," our calculator does exactly that — automatically — while Canvas gives you the wrong number entirely.


How We Built It

The stack is Next.js 15 (App Router) on the frontend with a Supabase (PostgreSQL) backend. The AI layer uses a provider-agnostic client supporting Gemini, OpenAI, and Anthropic, defaulting to Gemini 2.5 Flash for grade policy compilation and the agentic chat.

Key technical decisions:

  • Supabase FK chainsyllabus → courses → assignments / course_grades / study_plan. Getting this schema right upfront saved us from a painful migration mid-hackathon.
  • vm sandbox — LLM-generated code runs in a restricted vm.createContext with a 2-second timeout and no I/O access, making it safe to execute arbitrary grade logic without any security risk.
  • Three-slot code template — rather than asking the LLM to produce a full grade calculator, we give it a fixed template with named slots. The LLM only fills in the policy-specific logic, keeping outputs small, deterministic, and auditable.
  • Canvas OAuth integration — real-time assignment and grade sync without the user ever copy-pasting data.

Challenges

Designing a stable schema that could hold syllabus data, parsed grading policies, compiled code, assignments, grades, study blocks, and professor insights — all with correct foreign key relationships — was harder than expected. We spent real time on the one-to-one FK pattern between courses and course_grades / study_plan, and on ensuring syllabus rows exist before course rows to satisfy constraints.

The agentic grade compiler was our biggest engineering challenge. Gemini would sometimes generate JavaScript that referenced variables from the wrong scope (using categoryName inside the FINAL slot where it's not defined), or return JSON with literal newlines inside string values that broke JSON.parse. We built a multi-layer defense:

  1. A JSON repair pass to escape malformed string values before parsing
  2. Post-parse scope validation that drops any slot referencing out-of-scope variables before the code ever reaches the vm runner
  3. maxOutputTokens: 2048 to prevent response truncation mid-JSON

Keeping Canvas sync and manual entry consistent — students might upload a syllabus and manually add assignments — required careful deduplication logic and a clean store architecture so the UI stayed coherent regardless of data source.


What We're Most Proud Of

Two things stand out.

First, the dynamic grade calculator works end-to-end — syllabus PDF upload → Gemini policy extraction → code compilation → database persistence → sandboxed execution → live grade projection with implicit policies applied. Watching it correctly drop a lowest quiz score and apply a midterm curve that Canvas would have completely ignored felt like the moment the project became real.

Second, the browser extension + web app combination. Rather than forcing students to leave their existing workflow, the extension meets them inside Canvas with an agentic assistant that can answer grade questions, surface study priorities, and show a cross-course snapshot — all without a context switch. The web app is there when they want to go deeper. It's the same data, two different interfaces, zero duplication.

Course Survival Agent doesn't just show you your grades — it understands them.

Built With

Share this project:

Updates