Implementation notes, limits and fixes by project. You can also search all articles.
Study Kit
A course is more than its PDFs: building the materials exporter
How Study Kit 1.8–1.11.1 turns Moodle pages, Books, assignment briefs, Ed Lessons and linked Google files into a local course package, with offline PDF printing, isolated accounts and an explicit list of what is missing.
One download button, three codebases: zipping a unit's Ed materials
Ed Web could zip a whole unit's Ed materials and Study Kit could not, even though it already downloaded them. Closing that gap meant renaming files without downloading them again, catching attachments, a bug the tests had hidden, and deploying to a server that was not running what I thought it was.
Study Kit gets school mail and attendance, and asks before it changes anything
Study Kit 1.5.0 can optionally read your school mail and attendance. Anything that changes something shows you a full preview first and runs only after you confirm. Attendance reads two weeks in seconds without a browser, and students who never open a terminal can connect it by asking their AI app.
Letting ChatGPT reach Study Kit, for one person only
Study Kit 1.4.0 can now be reached from ChatGPT and Claude on the web. It stays a server for one person: a pairing code from your own terminal, a short list of callback addresses, rotating tokens, and only the tools that read.
Which source wins when an AI reads your assignment
Monash Study Kit lets an AI read your own Moodle and Ed. When you ask it what an assignment wants, it now follows a fixed order of sources: the brief and rubric, then staff answers on Ed, with dates and a source for every rule. How that rule is written, and the test that keeps the agent instructions true.
Homelab
Why I want alerts about changes, not an endless stream of pings
Monitoring Linux nodes isn't just about running checks on a schedule. State, recovery and safe limits make alerts useful.
Two J1900 boxes and an N1: why I don't need more production servers
Two J1900 boxes, a Debian N1 and a VPS. Before finding more services to run, I need to decide what should stay online and what should remain disposable.
SecureView
What SecureView's concurrency tests caught that a demo didn't
Connection-pool exhaustion and deadlocks became real questions only when the encrypted file-sharing app handled concurrent use.
100 users, 3% CPU, and most uploads failing
At 100 concurrent users, up to 78% of uploads failed while the CPU sat at 3%. How the cause was found, a first fix that made things worse, and the fix that brought failures to zero.
Sharing files the server cannot read
In SecureView the browser encrypts every file and the server never holds a key that opens one. How sharing works under that rule, and what happens when someone forgets their passphrase.
Monash Hub
Why I built a degree planner for Monash students
Putting units into semesters is easy. Checking prerequisites, campus and offering periods against the Handbook is the harder part.
From 662 official pages to 3,100, without losing any when a crawl fails
Monash Hub's guides went from 662 official pages to about 3,100 in one weekend. How the list is built from two sitemaps, what gets left out, and why a failed fetch no longer takes a page down.
One question, two campuses
Visas, insurance, intermission and closing units follow different rules at Monash's Australian and Malaysian campuses. How Monash Hub answers both side by side, and the test that fails an answer that forgets which country it is about.
A plan code the server never sees, and searches counted without people
Monash Hub has no accounts for course plans. How a plan moves to another device in a link the server never receives, how the home page shows real searches while storing only a word, a day and a count, and a privacy note that had to be corrected.
An offline app that never shows an old page when a new one is there
Monash Hub can now be added to a phone's home screen and opens pages you have read with no signal. Why the service worker always tries the network first, what it refuses to save, and how an app left open for days picks up a new deploy.
Unit ratings without sign-in, and keeping them honest
Students can rate a unit without an account. How one browser keeps one rating per unit, why the limit is on the network and not the key, and what this still does not stop.
Translating the Monash Handbook without paying for it
Five thousand units and hundreds of official pages, translated into Chinese for free. Why a glossary sits in front of the model, and how a bad translation falls back to English.
How Monash Hub deploys itself and rolls back
One VPS, no one watching the deploys. How the deploy script checks the right commit is live and puts the previous images back when it is not.
Blog
Why I use Jekyll but serve the blog from my own VPS
Writing, building and serving a static blog are different jobs. GitHub Pages remains a mirror; the VPS serves the main domain.
Algorithms
The string algorithms I kept after the course ended
A post-course rebuild of Z matching, BWT search, Ukkonen suffix trees and Rabin–Karp, including the limitations I don't want to hide behind complexity claims.
quotegate
Turning a bot's quote check into a package
The word-for-word check in my WeChat bot is now its own Python package with no dependencies. What it keeps and drops, why it does not use a second model as a judge, and how a release gets from a tag to PyPI.
Attendance Helper
Getting a Chrome extension ready for the Web Store
Before putting my attendance extension on the Chrome Web Store, I removed a permission, deleted URLs from a library I never call, and made the build refuse to package remote code. What the store checks, and how I checked it myself first.
Ed Web
Refreshing an Ed forum in the browser without fetching it all again
Ed Web reads a course's Ed forum in the browser with no backend. The redesign added a refresh that only fetches posts that changed, an honest meaning for "new", Ed's post format rendered safely, and support for Ed's API tokens.
Q&A bot
A Q&A bot where the model is only allowed to quote
A WeChat bot answers students and parents about visas, exams and enrolment. Why the language model in it may only quote sentences, how the code checks every quote, and which true sentences it still refuses to send.