No description
  • Python 51.7%
  • JavaScript 18.1%
  • CSS 15.3%
  • Nix 12.8%
  • HTML 2.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-03 14:24:42 -07:00
apps/pyquest first version 2026-08-03 14:24:42 -07:00
.gitignore first version 2026-08-03 14:24:42 -07:00
flake.nix first version 2026-08-03 14:24:42 -07:00
README.md first version 2026-08-03 14:24:42 -07:00

homefree-pyquest

A HomeFree plugin: PyQuest — a guided, self-paced Python course for a kid who wants rigour rather than a tour.

The course itself is CS50P. This app is the rails around it: it answers "what do I do today", records what has actually been finished, and gives a parent a read-only view of where things stand.

Why a harness and not a curriculum

The failure mode of "here are three great resources, off you go" is that it makes a beginner the project manager of their own education. Every session starts with where was I, which tab, what now? — and that overhead is what stalls people before any of the actual learning starts.

So the design goal is narrow:

Open one page, and there is exactly one obvious thing to do.

Rails constrain what to work on next and when — never how hard the problem is. Sequencing is scaffolded; the problems stay difficult. Days unlock in order, and a day is only done when all its tasks are.

The plan is a sequence, not a calendar. "Day 3" is a position, not a date. If a problem set eats six hours across two afternoons, Day 3 simply takes two days and nothing is "late" — the target is depth over coverage.

What runs where

Laptop (the learner's real dev environment) Box (this app)
Python 3, VS Code, git Plan engine — today's card
Their actual code Progress tracking, per SSO user
check50 --local (real CS50 autograding) Parent view
The terminal Syllabus + resource links
Forgejo — their git remote

No code executes on the box. This process only reads and writes JSON, which is why there is no sandbox anywhere in it and no need for one.

Why local, and why Forgejo

A local setup is what actual developers use, so that's what this track builds. It also sidesteps an account problem: submit50 pushes to github.com/me50/<user>, and GitHub requires users to be 13 or older — so for a younger learner, CS50's submission path and its browser codespace are both closed. check50 --local is not: it runs the real check suites from the public cs50/problems repo with no account at all. The autograding survives; only the submission-and-certificate path is gated (and the free course tier has no certificate anyway).

Forgejo on the same box then gives a real git remote with no third-party ToS, no age gate, and nothing leaving the house — plus a natural artifact for the nightly code review: today's commit diff.

Curriculum is data, not code

Everything lives in apps/pyquest/curriculum/*.json — goal, prose, resource link, exact command, expected output. Adding or rewording a lesson never touches Python. Four strands run through it:

  • spine — CS50P notes and problem sets
  • drill — CodingBat, the fluency layer
  • toolcraft — shell, git, debugging, venvs. Delivered just-in-time, at the point it's needed, rather than front-loaded
  • build / review — projects, and the 15-minute nightly walkthrough

Enable

homefree.services.pyquest = {
  enable = true;
  # public = false;          # LAN-only by default
  # subdomain = "pyquest";
};

SSO-gated via Caddy (oauth2 = true). Every authenticated household member gets their own independent track — a parent can work alongside. Admins additionally see the Parent tab, gated on the X-Homefree-Role header.

Tests

nix-shell -p 'python313.withPackages(ps: with ps; [fastapi uvicorn pydantic httpx])' \
  --run "python3 apps/pyquest/test_smoke.py"

Covers the auth gate, admin-only parent view, day unlock/relock, per-user isolation, identity sanitising, and graceful degradation on a corrupt progress file.