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.
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.
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.
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.
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.
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.
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.
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.
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.
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: 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).
Unfortunately I don't have 8.3 million dollars to spend in support of a political candidate, but I do have my blog.
In the ongoing New York City mayor's race (specifically the Democratic primary), I'm supporting, canvassing and voting for my assembly member, Zohran Mamdani. His entire platform is centered around making NYC more affordable, specifically:
- freezing the rent for rent-stabilized tenants (previously done by de Blasio)
- making buses fast and free (he won a 1-year pilot on this, it was reasonably successful)
- free childcare (I didn't have a parenthetical for this)
This is not to mention his various plans to build more housing, both creating new public housing and speeding up construction of private housing.
And he has a plan to create a "Department of Community Safety", which will task dedicated professionals and mental health experts on helping people with homelessness and other crisis response. And that will let police do actual police things.
I know for sure that he can deliver on the first part of his platform, freezing the rent, since the mayor appoints all the members of the rent control board. The rest requires collaboration from the city council and most likely Albany.
It's not a guarantee that it's possible, but if he wins, there will be a public mandate for it, and suddenly, it'll be realistic.
Ultimately I want a mayor who is willing to try new ideas instead of constantly being stuck doing what is "safe" and continuing old policies that have gotten us here. Zohran is that person and my #1 vote.
The more I learn about Brad Lander, the more I like him. Out of all the candidates (including Zohran), I think he is best suited to hitting the ground running as mayor on day one. He seems to have the best grasp on the NYC bureaucracy and has incredibly detailed and technical plans on how to address, well, everything.
I ranked him #2 (in line with Zohran's cross endorsement), but respect and support anyone who ranks him #1 and Zohran #2. If Zohran ends up winning, I hope he gives Brad Lander a significant role in his administration.
I never actually lived in New York during Andrew Cuomo's tenure, but I've read enough from the time and everything that's come out since. The fact that he was governor for 10 years, and HUD secretary for another 4 means that he had the opportunity to fix it in the past, but didn't. It's time for new leadership.
I think this is a perfect example showing that letting people voluntarily resign under pressure is a bad idea; if he had been impeached and removed from office, there wouldn't have been a comeback.
Zohran has been a great representative for me, and I am looking forward to sharing him with the rest of the city.
I told someone once that I'm supporting Zohran because as my assembly member, he's the first elected official to represent me that I'm not embarrassed by. I don't mean that we agree on everything (we mostly do, but not 100%) — rather I think he has a good set of core guiding principles, and sticks by them in ways that are understandable and justifiable.
After having an incredibly embarrassing mayor for the past 4 years, I'm looking forward to one I respect and appreciate. I hope you'll rank Zohran #1 (and Lander #2).
Voting is open today, June 22 (9am-5pm), and then again for the last time on June 24 (6am-9pm).
By default, newer versions of podman run containers with a dual stack network that supports IPv4 and IPv6 (yay). But if you're doing something specific, you can set up IPv4-only and IPv6-only networks.
(Note: I tested this all with rootless podman 5.5.0, the current version in Fedora 42.)
I'm primarily writing this because it took me a while to figure this out, I got entirely tripped up by the --ipv6 option which turned out to not be what I wanted, despite the name implying it enables IPv6.
The documentation for it is technically accurate, as it says:
Enable IPv6 (Dual Stack) networking. If no subnets are given, it allocates an ipv4 and an ipv6 subnet.
The most important part is in parenthesis — it enables a dual-stack network. Which means that passing --ipv6 when creating a network doesn't just enable IPv6, it also enables IPv4!
What you actually want is:
$ podman network create --subnet fd00::/64 --gateway fd00::1 ipv6-only
You can verify that IPv4 doesn't work by:
$ podman pull quay.io/curl/curl:latest
$ podman run --rm -it --net=ipv6-only curl -v4 https://en.wikipedia.org
* Host en.wikipedia.org:443 was resolved.
* IPv6: (none)
* IPv4: 208.80.154.224
* Trying 208.80.154.224:443...
* Immediate connect fail for 208.80.154.224: Network unreachable
* Failed to connect to en.wikipedia.org port 443 after 13 ms: Could not connect to server
* closing connection #0
curl: (7) Failed to connect to en.wikipedia.org port 443 after 13 ms: Could not connect to server
And that IPv6 works:
$ podman run --rm -it --net=ipv6-only curl -I6 https://en.wikipedia.org
HTTP/2 301
date: Fri, 23 May 2025 00:29:41 GMT
...
And now for IPv4, which is even simpler:
$ podman network create ipv4-only
Yep, no options needed, you just need a network in which IPv6 is not enabled by the subnet and doesn't pass the --ipv6 flag.
The default networking stack for rootless containers is documented (under "pasta") as "IPv4 and IPv6 addresses and routes, as well as the pod interface name, are copied from the host". In my testing this is correct, but this is an entirely separate thing from podman network that appears to exist by default, which is IPv4-only.
I ended up figuring out the whole misleading --ipv6 thing thanks to a GitHub comment, which explicitly spelled out "The --ipv6 flags means dual-stack", and even explained the rationale why: "this is fully compatible with docker ..."
I shouldn't be too surprised that Claude also got tripped up by the --ipv6 flag and gave me bad advice. ¯\_(ツ)_/¯
Final final note: if you try a plain podman run curl ... without first pulling the image, it won't know which image you actually want, and none of the three prompts it gives you (registry.fedoraproject.org, registry.access.redhat.com, docker.io/library) are the official upstream image. I've submitted a PR to the containers/shortnames repo to fix that, so a plain curl image name will automatically be aliased to the upstream image.