My free software toolkit for school, redux

Previously: 2018

I've tried my best to use only free software as part of going back to school, and for the most part I've been pretty successful.

I picked up a new Framework 13 right before school started. I appreciate having USB-C charging options on both sides and being able to move the HDMI port to either side depending on the configuration of the room.

Really I just like the orange color scheme I picked out for myself.

I installed Fedora Silverblue on it; I'm a really big fan of the whole atomic OS concept, it works quite well. I've been able to use Flatpaks for nearly everything.

Firefox: not much to say here, it just works.

LibreOffice: I take all my notes in LibreOffice, which is good enough as it's mostly just bullet points and a few tables here and there. All of our writing assignments are required to be submitted in .docx format, so my final step on every assignment is to convert my .odt to Word format. I think, but am not actually sure, Word may have better support for formatting and managing citations than LibreOffice. Its on my todo list to see what it would extra functionality writing an extension would give me.

Signal: our cohort's main group chat is in Signal, and so is my study group's. It wasn't even a thing I had to push for, it was the default that others chose! The only downside is that a number of people have set their profile name to a single letter or gibberish, so I've slowly had to set nicknames for everyone.

draw.io: I really like using draw.io to make a diagram version of my study guide, and my friends were pretty impressed with how nice they looked. During my first semester I used the website, but I've now switched to the offline Electron version.

Nextcloud: I store all of my school work in a self-hosted Nextcloud instance. I tried using the flatpak version of the desktop client but it had some issues that I went back to the RPM version, which integrates with Nautilus much better.

Kiwix: one of my professors had a rule that if we were going to use our laptops, we had to be offline. I found myself wanting access to a dictionary to look up latin and archaic terms, so I downloaded the latest ZIM of English Wiktionary and used Kiwix to access it in class while staying offline.

KeePassXC: for reasons that make zero sense, our login sessions on Brightspace (LMS) and other CUNY websites expire after an hour, which is far too short, so you have to keep logging in, over and over again. It would be pretty hard to design a system to get people to hate 2FA more than this one. KeePassXC (and other password managers to be clear) lets me store a TOTP seed in the database and generate codes. So logging in becomes a dance of: Ctrl+B (copy username), Alt+Tab, Ctrl+V, Tab, Ctrl+C (copy password), Alt+Tab, Ctrl+V, Enter, Ctrl+Tab, Ctrl+T (copy TOTP), Alt+Tab, Ctrl+V, Enter.

Thunderbird is unfortunately not on this list because my school uses Outlook and they restrict OAuth access so I can't get it to work. Using webmail is actually awful, I can't believe that people have to deal with this for all their other email.


Review: The Odyssey (2026)

At some point in high school we read the Odyssey, and I really enjoyed it. I did not like Christopher Nolan's version.

Rating: 4/10

It really felt like he had read all of the different scenes in the story, figured out how to film them and then just shipped it as a movie. Anytime you base a movie off an established book (or poem!), there's a higher bar to clear to make it an engaging story, which wasn't met here.

Emily Wilson's critique resonated with me a lot. I can think of no good reason why you wouldn't include the whole "no man" gambit with the cyclops (and the cyclops didn't even look like what I imagined cyclopses look like).

It's funny that my main critique of a three-hour film is that it felt abridged and didn't go into suffient detail. Should've been a trilogy.


Review: Avatar Aang: The Last Airbender

Sixteen years of agony have finally come to an end, as the Avatar universe has finally received a movie worthy of its excellence. Avatar Aang: The Last Airbender is a nostalgic adventure that brings back most of the fun from the original television series.

The film was originally slated to be released in theaters, then it was leaked online, then Paramount cancelled the theatrical release, and then they backtracked just a little bit and did a one-week theatrical run in New York City and Los Angeles at a single theater each. I caught the very last show in NYC at 1:15am, and it was worth it.

I thought the movie did an excellent job coming up with a story that fit between the TV series and Legend of Korra without raising questions of why the latter never addressed it. It did require a bit of disbelief that some of the most important leaders of the world could all of a sudden abandon their posts when the Avatar asked, but hey, the gaang had to reunite for the nostalgia.

Unfortunately I don't think the movie would've done well as a general theatrical release. Most of the movie had no explainers for Avatar universe concepts, like bending, the spirit world, Republic City, and so on.

So I think it only works as movie for existing fans, but regardless, I am incredibly thrilled with that outcome. Rating: 8/10.

Spoilers ahead#

The coolest part was definitely the joint airbending that turned into tornado(!!) bending. I was not at all expecting a new bending mechanism.

It seemed a bit obvious that Tagah was a bad guy — otherwise why would he have been stuck in an air bubble prison for thousands of years. Using non-benders as the villain again felt unoriginal.

I appreciated that the entire plot revolved around a paradox: if Aang had never released Tagah or retrieved the staff, then nothing would have happened! But when Aang sees someone else trapped in an air bubble, just like how he was, he doesn't even stop to think before releasing them.

The ending was a bit cheesy with them discovering the herd of sky bison, but hey, it was cute. Nostalgia fulfilled.


First year of law school is in the books

CUNY Law during the infamous blizzard.

Previously: Fall 2025, Spring 2026

It's official, I've now finished my first year of law school. As a part-time student, we were required to take torts and another lawyering seminar over the summer to wrap up the 1L curriculum.

Tort law allows people to pursue claims against others for causing harm in a civil manner. We only covered a few select torts: battery, assault, false imprisonment, and then neglience.

My professor's specialty/focus is claims where kids are harmed, so she primarily focused on examples involving kids. In our very first torts class, she showed us body cam footage of cops brutally arresting elementary school students (false imprisonment!); it was incredibly effective at sharing an understanding of how real people are harmed in the real world as opposed to an abstract, educational topic.

I'm not sharing a graphical study guide like I've done previously because I didn't end up creating one this semester. Both of our exams were open book, so I just used my notes and the resources our professor gave us.

Lawyering seminar was a continuation of last semester's simulation of child neglect, except this time the mother was being accused of also neglecting the younger sibling. We learned about educational neglect, failure to protect, and Family Court Act § 1028, which is the procedure to demand return of a child after Children's Services removes them.

In New York, every child gets their own attorney during family court procedings (siblings might share an attorney if appropriate). Close to two decades ago, the court system moved from a "law guardian" role, in which you're an agent of the court, to "attorney for child", in which you are really the child's lawyer, representing them as a client.

But we ended up serving as an attorney for a child who didn't want to go home (yet)! Between that and torts, it was a pretty intense semester; my friend dubbed it "the summer of child abuse".

We got Wednesdays off, which was nice! Unfortunately between the Knicks, the World Cup, and some bad weather, we had a number of remote classes, which I can't stand.

Next semester will be Civil Procedure, Evidence (Fourth Amendment), and drumroll Critical Race Theory. Also I'll be a Staff Editor on the CUNY Law Review.

Reflection#

I thought I'd take the opportunity to reflect on finishing one year by...interviewing myself. But really, these tend to be the questions everyone asks me (I don't mind!), so you can think of it as a FAQ.

What do you want to do with your law degree?

No idea. Definitely not anything family court related (see above regarding the summer of child abuse).

Really?

Really. I think I'd be interested in doing a number of things, like First Amendment free speech/expression/press, or Fourth Amendment anti-surveillance and privacy, or something tech-adjacent.

Lately something around drafting or reviewing legislation seems interesting. But I don't think I've found just exactly what I want to do yet.

Also, as you might have heard, the rule of law in the U.S. is uhhh, going through some struggle lately. So we'll see what the law is even like by the time I graduate.

Is law school hard?

It's certainly harder than any other class I've taken before, but I suppose that's to be expected for a graduate program. I find the hardest part to be balancing my time.

Normally I sign off work at 5pm sharp, eat a quick meal, start class at 6:15, and then we go until 9 or 10. Then after I get home, a bit more food and prep for the next day. Weekends are for reading for the upcoming week and whatever other homework we have.

Hanging out with friends is limited to whenever there's a holiday or by some miracle, a light reading week.

It definitely requires having a good support system; I couldn't have done it without my family and girlfriend helping me out. Whether they wanted to or not, they too learned some law school stuff when I regurgitated it to them as part of my exam prep.

Do you enjoy it?

Except for when it's exam time, absolutely. I've been interested in the law for a while, so actually learning the subtle details feels very enriching because you realize how little you knew beforehand!

Plus I just like learning. To that end, this is probably the most I've ever read in my life.

Best part is definitely the friends I've made. I think our study group is the best one (I'm being 100% objective here), and it was because we mostly happened to sit in the same row during the first week.

What's the most interesting thing you've learned so far?

I think criminal law has been the most fascinating to me, just because we all have some basic understanding of what crimes are and what's illegal, but getting to know the legal framework that underpins it all really taught me that I actually had a very poor understanding of what a crime was! To some extent this is largely academic, at the end of the day what really matters is whether the jury votes to convict.

We also learned a number of defenses to crimes, which is probably a good thing to know! My favorite is the Cheek defense, which can be used if you intentionally screw up your taxes, as long as you had a "good-faith belief" that you were doing the right thing.

However, now that you've learned about the Cheek defense, you can't plan to use it since it would no longer be a good-faith belief. You're welcome.

Where do you get boba from?

I will do a proper review eventually, but Teazzi is right across the street from the CUNY Law campus, it's quite good. The only downside is that the boba often clumps together, which means that you need to suck real hard to get the boba out, which isn't something you can quietly do in class!

During our first-ever study group session, I took the group to Teazzi and we all got boba and they said they enjoyed it. The next day before class I walk in to see my now-best friend is, entirely of her own volition, sitting there drinking boba. One of my proudest moments.


Quoted in The Athletic

During the most recent "Free Culture Friday" slash World Cup watch party, I spoke to a journalist from the The Athletic and ended up being quoted (and photographed!) in the resulting story, "Welcome to the high-stakes universe of World Cup Wikipedia editing" (gift link):

Those editors include sports fans like Kunal Mehta, 31, who began editing Wikipedia in 2006, when he was in middle school.

“It was addicting,” he said during the combination World Cup/Wikipedia editing watch party.

Mehta got his start by updating scores and creating athlete pages for the NHL’s San Jose Sharks, his home team. Now he works as a software engineer for the Freedom of the Press Foundation and edits in his spare time, often about sports. He sees Wikipedia as the “second draft” of history.

“Through all of human history, people have always tried to collect all knowledge together, that has just always been a task, like the Library of Alexandria,” Mehta said. “Wikipedia has shown that you can just do it. You just provide a blank slate for people to do it, and people will come together and work at it.”


Do-the-work instead of proof-of-work, for Git hosting

The insane rise in scrapers across the web has affected a number of websites, including Git repository hosters. The main response has been to set up software like Anubis, which uses a proof-of-work system to limit who can access the website.

While I don't fault overburdened sysadmins for enabling Anubis to protect their servers from overload, I think it's a pretty bad solution. It introduces a delay, wastes energy, and just makes the user experience worse.

We've spent so, so, so much effort and energy squeezing out milliseconds of performance and optimizing connection times that deliberately making performance worse feels like a giant step backwards.

And the work the client does is just thrown away! It's not actually anything useful; people rightfully critized Bitcoin and (formerly) Ethereum for being wasteful for the same reasons.

So I'd like to propose a different solution, which I call "do-the-work".

In a traditional setup, it is cheap for a client to send a request to a server, the server performs some potentially expensive computations/processing and sends back a response. With scraperbots, it becomes easy for those clients to very cheaply send thousands and millions of requests that overload a server.

With proof-of-work protection (i.e. Anubis), the client it must perform its own computations, and only once it's done sufficient work, then it gets permission to send a request to the server. The server does more or less the same amount of work, it's just that the client now also has to do some work.

Do-the-work aims to invert the client-server imbalance by making the server's job cheap and forcing the client to do the more expensive computations. In other words, if you want to see some information, you need to pay the costs of calculating it by... doing the work.

Because of the way Git is designed, I think it's a great fit for this approach.

A client-side Git viewer#

As previously teased, on git.legoktm.com I am now serving an entirely client-side Git repository viewer (source code, README), which imitates the look of cgit (used by e.g. git.kernel.org). On the server-side, it is purely static hosting of bare repositories, requiring just Apache HTTPd and a few rewrite rules.

The only thing I really need to worry about is bandwidth, but since it's now static content, it would theoretically be straightforward to put it behind a CDN.

Since most of my personal projects are quite small, I've mirrored a few larger projects so you can better see how it works: SecureDrop and MediaWiki. All of these repositories are maintained in my private Forgejo instance and I rsync them over to git.legoktm.com.

Under the hood, Git stores everything in "objects", so as long as you have some way to fetch those, then you have all the information you need to calculate everything a Git viewer needs, like file contents, diffs, a log of changes, etc. In reality it's a bit more complicated with pack files, but at the end of the day everything is an object.

Most git clients expect this to be filesystem backed, but cyberia-ng's git-async library abstracts the backend out. So I created a new backend that fetches over HTTP and stores the data in IndexedDB in your browser.

Essentially you're performing a partial git clone and then automatically backfilling missing objects as needed.

There's probably a lot more room for performance improvements, but I think it's already usable enough for small-to-medium-sized repositories. This doesn't cover everything a forge does, but if you're just hosting cgit, this should be a drop-in replacement (aside from all the missing functionality).

I think this approach can be better for privacy too. After the initial load, a subsequent load when nothing has changed on the server doesn't require fetching any more data; it wouldn't take that much more work to behave fully offline.

For now this is mostly a proof-of-concept, but I think it's probably not too far off from turning into a real thing that's usable if there's interest in that.