One semester of law school done

I just finished my first semester of law school Tuesday evening...only eight more to go! People say that the first year of law school is the worst, and I certainly hope that's true.

I don't think I've ever had so much information dumped into my brain in such a short period of time. In my Liberty, Equality and Due Process (LEDP) class about the Fourteenth Amendment, I took 109 pages of notes, and for Criminal Law, 54 pages.

As a very very condensed version of what I learned, here are the study guides I made for both classes:

Probably best viewed in a separate tab.
Also best viewed in a separate tab.

I cannot yet vouch for the accuracy contained on those guides yet as I haven't gotten my grades back yet, but I think they're mostly correct!

Next semester is contracts, which'll probably be immediately practically useful, and legal research, which I'm really looking forward to. I now have access to Westlaw, which is both amazing in how rich the content and interface is...and terrible how it's all locked in a commercial, private database.


Three-ish takeaways from Zohran's win

There have been a lot of Zohran Mamdani thinkpieces since November 4th, and I've read most of them! But I want to add three takeaways that I really haven't seen discussed elsewhere in detail.

No repeats of Buffalo#

In the past few weeks people have talked a lot about how Obama's volunteer army fell apart after he was elected and how Mamdani campaign leaders are trying to prevent that from happening by launching "Our Time", a separate entity that can organize former campaign volunteers and keep them politically activated.

But more immediately, I think it's worth understanding that there was a specific effort to prevent a repeat of Buffalo's 2021 mayoral election in which a socialist (India Walton) upset the incumbent mayor (Byron Brown) in the Democratic primary, so Brown launched an independent campaign for the general, rallied the Democratic establishment to support him and not Walton (the Democratic nominee), winning the general by 20 points.

With that context, it made perfect sense that immediately after the primary we saw Zohran moving to consolidate the establishment behind him, including labor and elected officials. It mostly worked, just about everyone backed him except Chuck Schumer and Kirsten Gillibrand. Oh and Jay Jacobs, the chair of the state Democratic party, who refused to endorse Zohran just like he refused to endorse Walton, except at least this time he didn't compare the socialist upstart to David Duke!

On primary day, Hell Gate interviewed Walton and afterwards City & State NY interviewed her too.

But I have yet to see any reporting on how many volunteers came down from Buffalo to support the Zohran campaign in the final stretch. I met a decent amount of people who were very open about why they had come to the city: to prevent a repeat of what happened in 2021.

Being ineligible for president can be a boon#

Because of the natural-born-citizen clause in the U.S. Constitution, Zohran is ineligible to run for U.S. president. Meanwhile it was incredibly obvious that Andrew Cuomo was running for mayor to relaunch his political career so he could run for president in 2028. That would follow the recent trend of NYC mayors running for president, including Bill de Blasio (2020), Michael Bloomberg (also 2020) and Rudy Giuliani (2008).

And of course, way too many people touted Eric Adams as the "future of the Democratic party" and a future presidential candiate. Oops, should've listened to Andrew Yang.

I think it's underrated that Zohran can't run, and so after the primary win, there was no endless dicussion of whether he'd run in 2028 or some made up hypotheticals of him vs. AOC as to who should be the left's standard bearer, etc. And, it's much easier to convey and convince people that Zohran was genuinely interested in improving the lives of New Yorkers as the mayor and not just using it as a stepping stone to higher office.

Indians can move left#

In 2024, it very much felt that Indians were moving right, with Nikki Haley and Vivek Ramaswamy rising in the Republican ranks and Kamala Harris losing. Polling indicated Asians broadly shifted right (though I didn't find anything about Indians specifically). Not to mention the backdrop of Modi's right-wing government rising in India, which undoubtedly affects the views of the diaspora.

Anecdotally, the WhatsApp forwards were getting worse.

Zohran is easily the most high-profile Indian American politician in the U.S., but more importantly, his campaign was backed by incredibly strong South Asian turnout across the board, with Indian turnout rising from 18% to 45%. To quote: "South Asians and Muslims account for just 7 percent of the city’s registered voters, yet they cast an estimated 15 percent of all ballots in the general election." The aunties are activated.

Not to mention, Ro Khanna is now a legitimate 2028 presidential contender who also campaigned with Zohran in the final stretch while Ramaswamy is possibly starting to collapse.

Regardless of how that turns out, it's clear that it's far from inevitable that Indians will move right, and more importantly, we can move them left.

Final thoughts#

People keep repeating how this mayoral election was like none other, and I geniunely have no idea what they mean. This was my first mayoral election as a New York City resident so it's also my baseline. I expect things to only go up from here, starting with the special election for my assemblymember and then the open primary for my U.S. House district.


Where's Eric? Tracking NY politicians' public schedules

Note: I had mostly finished this project last weekend, before Eric Adams dropped out of the mayoral race. While Adams will still be the mayor until January, this project made more sense while he was an active candidate.

WHERE'S ERIC? provides a compilation and visualization of when Eric Adams and other New York officials have failed to make their public schedule available in advance, as reported by Politico.

As the New York City mayor's race escalates, I've been paying closer attention to the local politics-focused media outlets, including reading Politico's "New York Playbook" regularly. Aside from the actual news, they have a brief section where they ask: "Where's Kathy?" and "Where's Eric?", and summarize what their public schedules for the day are.

That is, if they receive them. Lately Adams' entry has been some variant of "Schedule unavailable as of 10 p.m. [previous night]".

I was curious what this actually meant in the long-term; was I coincidentally just reading Playbook on days he didn't provide his schedule? Or has he always been bad about providing his public schedule? Are other politicans any better?

Of course, the best way to answer this question was to look at literally the entire history of New York Playbook, so I processed the entire archive dating back to 2016 to get a more complete picture. The first Playbook issue that contained then-Governor Andrew Cuomo and then-Mayor Bill de Blasio's schedules was February 21, 2017: de Blasio had events in Manhattan and The Bronx while Cuomo had no public schedule.

Moving forward to 2025, I was mildly surprised to learn that Adams was actually perfect in providing his public schedule for the first three years of his term. Then on Friday, March 21, his first ever "Schedule unavailable as of 10 p.m. Thursday." appeared.

In April, he didn't provide his public schedule more often than he did. Over the past 8 weeks, his schedule has been unavailable 65% of the time.

This is...not great.

Knowing what our public officials are up to is a standard form of transparency that enables the press to document their actions so the public can hold them accountable. Not being up front with what you're doing undermines public trust, and while this might feel like a small thing, I think it's a decent indicator for how public officials respect the public and the press in general.

Given how chaotic the last few months of the Adams administration have been, part of me is curious whether this is due to incompetence or malice. We know quite well that Adams acts maliciously when it comes to the city hall press corps.

Where's Cuomo?#

And yet as bad as Adams is at this, he is still better than Andrew Cuomo, who, out of the four officials reported by Politico, is the worst.

WHERE'S ANDREW? shows how his record was consistently spotty since early 2017, but dramatically worsened in May 2020. Admittedly that was a pretty chaotic time for everyone, but this the same person who wanted us to celebrate his leadership during that time period.

Where's Bill and where's Kathy?#

During that same time periods Adams and Cuomo were failing at providing their public schedules, WHERE'S BILL? and WHERE'S KATHY? show in stark contrast that it was completely feasible to regularly provide their schedules.

Both provided their schedule to Politico 99% of the time, which I think shows that this is not a difficult task, and makes Adams' and Cuomo's failure to do so even more inadequate and unacceptable.

Methodology#

After scraping Politico's archive, the "Where's {name}?" fields were extracted into a database (raw data), with special handling for some edge cases. For example, on January 6, 2022, Politico had an joint item, "Where are Kathy and Eric?".

Also for about two weeks, Politico spelled it as "BlLL" (that's a lowercase L instead of an I). Oops.

A regular expression was used to identify days when the schedule was unavailable, specifically matching the phrases:

  • schedule unavailable
  • not available
  • schedule not available
  • schedule not released
  • unavailable as of
  • not released
  • by press time
  • schedule yet
  • no public schedule released as of
  • no public schedule available as of
  • as of {number}

Notably this does not match when a schedule was provided but there were no public events.

I performed a spot check against most of the unavailable dates and far fewer of the available ones, erring on the side of identifying false positives. If you do find an error, please contact me.

Major credit and thanks to the Politico reporters for collecting and reporting this data for nearly a decade.


Adventures of a YAML engineer

I want to brag about a bit of YAML code I wrote back in March for SecureDrop's completed migration to Ubuntu Noble that I neglected to mention in the blog post explaining the technical details. Yes, YAML, is a programming language.

We offered SecureDrop Administrators the option for a "semiautomated" upgrade: they run one command, ./securedrop-admin noble_migration, and it'll take care of the rest. The main advantage for doing so was that the upgrade would happen at the time you chose, and if something happened to go wrong, you were already on hand to deal with it!

Under the hood the semiautomated upgrade was starting an Ansible playbook that edited our JSON control file to mark the server as ready to be upgraded and then started the systemd service. And then it just waits until the upgrade completes, which ended up being the harder part to implement.

During the upgrade, the server reboots twice (once before installing updates and once after), which means Ansible will lose its SSH connection. I used Ansible's wait_for_connection module to reconnect instead of error out, and naively had it wait for that to happen twice before checking if the upgrade had finished.

But during testing we found a problem when using SSH-over-Tor, in which Ansible would disconnect three times. It disconnected on the first pre-upgrade reboot, then during the upgrade when the Tor package was restarted, and then again during the second post-upgrade reboot.

And, to make it even more fun, this was subject to a race condition. In at least one instance, it took long enough for Tor to come back that the server rebooted before it reconnected, so there were only two disconnections.

Knowing that, a naive solution wasn't going to cut it anymore, so I implemented the same state machine as the Rust code, just in the YAML playbook. It now parsed the JSON state file, looked up where in the overall process it was, and then calculated how many reboots are likely remaining. Once it disconnected and reconnected, it looked at the state file again, so it knew how many more to expect.

Here's the end result, it ended up being just over 200 lines of YAML (including comments).

Alternative clickbait titles for this post include: "Porting some of my Rust code to YAML" and "Writing a state machine in YAML".


A small change in plans

A small change in plans: I'm starting law school in the fall. I'll be attending the CUNY School of Law right here in Queens to become a public interest-focused lawyer.

I plan to continue working full time at the Freedom of the Press Foundation and go to school in the evenings, part time. And yes, law school is something I have always wanted to attend.

Going forwards you'll probably see me switch up the standard disclaimer to something like IANALY (I Am Not A Lawyer Yet).


Thoughts from vibecoding

I've been vibecoding for a while now and wanted to share some thoughts that I haven't seen discussed elsewhere regarding the process. To quote the original vibecoding definition by Andrej Karpathy:

It's not too bad for throwaway weekend projects, but still quite amusing. I'm building a project or webapp, but it's not really coding - I just see stuff, say stuff, run stuff, and copy paste stuff, and it mostly works.

And that's pretty much what I do as well. Some of vibecoded projects are on my website (said listing was also vibecoded — but all the text was written by hand), there are plenty more sitting in my ~/Downloads folder that I haven't bothered to clean up and publish.

Also note that I haven't gotten started with the whole "agentic" thing yet, so I'm just still typing prompts into a web browser and copying code out of it.

My standards have gone up#

Being a software engineer generally means that when something goes wrong with computers, you have a rough idea of what might have caused the error. Usually my response is along the lines of, well, all software is buggy, that's life.

These days I'm interested in seeing if I can do something better, both to make my life better, but also to just prove that we can make better software. As an example, a few months ago, I was filming a video for work and was relying on a random teleprompter website for our script.

I was struggling a bit with getting the emphasis right; the website didn't support any type of bold or italic formatting. Knowing what I know about HTML and JavaScript, I guessed that the website was treating everything as plain text, and that in theory, could support rich text if it used contenteditable.

I spent 10 minutes prompting Claude and then an hour fixing small bugs in the CSS/JS, and boom, an "Improved Teleprompter".

When the MTA released a new mobile app, it was okay, but not exactly the way I wanted my routes laid out. I built my own subway stops tracker that presents upcoming trains just how I want to see them, plus it stores all my data locally.

This doesn't necessarily mean the code is better, but rather the user experience is.

JavaScript is privacy-friendly#

Main article: Thinking of JavaScript as privacy-friendly tech

For the longest time, my stance was that JavaScript was a privacy-violating technology that needed to be avoided. I don't think that stance was originally irrational, given that most online tracking uses it, and tools like NoScript and RequestPolicy/uMatrix were effective at stopping that.

But today I think JavaScript has just as much to offer as privacy-friendly technology through things like client-side cryptography but also just keeping computing local instead of happening on someone else's computer.

You can get pretty far with JavaScript, localStorage, and optionally, some remote APIs. (Though CORS can be super annoying...)

Modifying is harder, but#

Modifying vibecoded projects is definitely harder because I didn't write the original code, and often it's not in the style I would have used. But I've found it's usually easy enough to just start over from scratch, replaying your original prompts, but with whatever modifications I needed.

I expect this is an area that I might have a different experience once I get around to agentic LLMs.

Content-Security-Policy is great#

This is not really news, I think it's well understood that the introduction of Content-Security-Policy has significantly improved web security. And that extends to vibecoded projects, especially if you haven't 100% reviewed everything.

The first version of my JSON diff tool that Claude created had a pretty glaring XSS that I noticed and fixed right away. But even if I hadn't, I deployed it with a policy of script-src 'self', so any inline <script> execution would be blocked.

In general it's nice to be able to clearly see and understand exactly what external websites (if any) these small projects will connect to.

I also really like how easy it is to share single-file HTML/CSS/JS projects (pages?), but having inline styles and scripts requires a weaker CSP. So I wrote resource-rewriter to use a single-file for deployment and then automatically move them to separate files during deployment.