End of the year reading catch-up
I have finally been able to get back into reading some books for pleasure, and so I need to catch up with some mini-reviews.
Dissolution by C. J. Sansom is the first in a series of books set in Tudor England featuring Matthew Shardlake, a hunchbacked lawyer working for Thomas Cromwell, in this one investigating a murder at a monastery as those institutions are being dismantled. In the time between when I first put a hold on this book and finally started reading it, the cover changed to highlight that there is now a television series on Hulu called Shardlake that is based on the books. It is a good mystery that seems to be absolutely loaded with historical details and atmosphere, and eventually I will probably get around to reading more of the series and perhaps checking out the show.
The Ministry of Time by Kaliane Bradley is a wonderful time-travel story. A mysterious door has allowed the government (British) to pluck several individuals out of time and bring them to the present day, and the protagonist works as a “bridge” to one of the “expats,” a naval officer from 1847 who would have otherwise died as part of the Franklin expedition to the Arctic. Like any good time travel story, it gets weird. It’s being adapted as a series by the BBC and A24, so that is promising.
Those Beyond the Wall by Micaiah Johnson is a sequel to Space Between Worlds which I read back in 2022 when I wasn’t writing here. The first book was very much a “multiverse” sort of story, and while the second shares the setting and some characters, the story stays in one world. The characters and world are really well-developed. It has more than a little of a Mad Max vibe but commenting more directly on American racial and queer politics. My memory is a little fuzzy on the first book, but it had made enough of an impression that I picked up the sequel without hesitation.
Just make it better
This access hatch on a sidewalk on Main St. in downtown Los Angeles used to have chipped concrete around the edges and the doors had a lot of flex to them when you walked over them. A few weeks ago, it was finally fixed up and now it looks clean, the doors don’t have any flex to them, and my near-daily experience of walking on that stretch of sidewalk feels a little bit better and safer.
Today, the website for the PHP Documentation Team was finally moved to a new host. Everything (or nearly so) related to the installation is on the appropriate repositories, it’s being served up over TLS, some of the code has been cleaned up, and the contribution guide has gotten more focused attention than it has had in several years.
None of this is perfect. None of it is done. But making things incrementally better is the kind of good trouble that I want to continue.
Another side of the fence
I keep running into things about the Zig community that intrigue me. The latest was this post by Loris Cro about “Critical Social Infrastructure for Zig Communities,” where these paragraphs really grabbed me:
We definitely also need bolder moves, but for now let's try to take it one step at a time, starting from structuring our communities around the idea that other interesting Zig communities exist out there, and that we should try harder to at least stay informed of what we all are collectively working on.
Conversely, we should also strive to make it easier for others to keep track of what we are doing. The time for bolder moves will come, but this a strong prerequisite before can we get to those.
Maybe it is because it is a new and small community compared to PHP’s, but the Zig community seems pretty great. Mitchell Hashimoto’s investment in the community is a good sign.
A lot of what Loris wrote about also brought to mind the IndieWeb principles and my own interest in promoting the ideal of doing open source development in the open using open tools. I chafe every time a community is centered on Discord or Slack, or finding that the real discussions and decision-making is happening in inaccessible places. One person’s tight-knit community can be another’s exclusive club.
What we have now
I ran across this RFC “analysis” by Zeev Suraski that was a response to a proposal about PHP adopting a Code of Conduct. Particularly the section headlined “The RFC process is [all that] what we have.”
In it, he says:
A person that joined internals@ only after the RFC process was enacted in 2011 may be excused to believe that the RFC process is all we have, and that it governs every possible aspect of the PHP language. However, that isn't true - and there's ample evidence for that available.
First, there are fundamental principals which date all the way back to the late 1990's, that are apparent to anybody who reads the archives. One of these core tenets was covered above - open unrestricted discussion.
Another, which is just as real, is decision by consensus for critical decisions.
As a principal author of the Voting RFC and as the person who came up with the 2/3 bar - I can say with absolute confidence that it was meant to regulate feature proposals - and not transforming policy changes - which this proposal certainly falls under. You don't only have to take my word for it - there - 'clues' are available all over the various RFC documents, beginning with the Voting RFC itself:
[ ... ]
It's true that since the Voting RFC process was enacted, it was used for limited-scope / tactical policy decisions. However - neither of these imply that it suddenly became as our sole form of governance that can be applied to everything - especially as it attempts to make the giant leap to cover topics like project participation policies, mailing list censorship and full-fledged banning of members. It's also worth pointing out that even in the handful of cases where it was used for minor policy changes - all of these policy changes effectively cleared the bar of decision by consensus, and not just barely clearing a 2/3 bar - which would have implied an extremely controversial decision.
That was five years ago, and it looks like the PHP project has only veered further away from Zeev’s ideal of a consensus-based approach for anything but feature proposals.
As jacked as it sounds
Dries Buytaert, founder of the Drupal project, wrote a great article on “Solving the Maker-Taker problem,” about how Drupal built a system to recognize the contributions of community members and their sponsors. I am not wild about the “Maker-Taker” terminology because it gives me Election 2012 flashbacks, but I don’t have anything better to propose. (It was this post by Ben Werdmuller that brought the article to my attention.)
By transparently rewarding contributions and fostering collaboration, we can build healthier open source ecosystems. A credit system can help make open source more sustainable and fair, driving growth, competitiveness, and potentially creating thousands of new open source businesses.
It looks like there is a lot to like about the Drupal contribution credit system and their approach to community contribution in general.
This idea of how money and other benefits should flow within the free software (and open source) ecosystem has been on my mind for over 32 years and it is frustrating to me that I still don’t feel like I know how I feel about it.
It has been easy, at times, to feel like I have ended up on the wrong side of the deal. It felt pretty good when I made money (a little) from MySQL’s sale to Sun Microsystems. I also feel pretty dumb when I’m working alongside people on open source projects where they’re getting paid and I’m not, or someone else entirely is landing investments and spinning up large companies based on the work of communities to which I’ve contributed.
But this isn’t just a feeling I have encountered in my open source work, it was also something I felt when we ran our art supply store. It was a frustrating feeling to hustle to cut a good deal for a non-profit organization where you know the staff there is being paid a better salary than you could afford to pay yourself, and more often than not they would just rely on the big online suppliers rather than even bring the business to us, the small local business.
Maybe my feelings are complicated because I never managed to become post-economic. My version of becoming post-economic was supposed to be running an art supply store, and instead it turned me sub-economic.
Feel like a cheap bouquet of flowers
I took this photo back in 2005 of a building at 3rd and Broadway in downtown Los Angeles as it was just starting to be converted into residential lofts. Gutted, full of promise, and destined for better things. I can relate.
Configuring third-party Apt repositories with Ubuntu
I just upgraded my primary development machine to the latest Ubuntu LTS (24.04.1) and it disabled the third-party sources I had set up for things like WezTerm, Tailscale, Syncthing, and the GitHub CLI. (It warned it would be doing this.)
When I re-enabled them, I finally made sure they were set up in the modern-ish way and no longer complained about keys that were installed using deprecated methods.
Now, the keychain for each repository is in the /usr/share/keyrings
directory in a file named something like tailscale-archive-keyring.gpg
. Some of the keys were mashed together in /etc/apt/trusted.gpg
before, but apt-key list
showed those were keys that I had individually under /usr/share/keyrings
so I just went ahead and deleted /etc/apt/trusted.gpg
entirely.
For each repository, there is either a repository
.list
or repository
.sources
file in /etc/apt/sources.list.d
. The .list
files are in “one line format”, and the .sources
files in a friendlier key-value format called “deb822”. The formats are explained the sources.list
(5) man page.
For example, here’s the /etc/apt/sources.list.d/tailscale.sources
:
Enabled: yes
Types: deb
URIs: https://pkgs.tailscale.com/stable/ubuntu
Suites: noble
Components: main
Signed-By: /usr/share/keyrings/tailscale-archive-keyring.gpg
And /etc/apt/sources.list.d/wezterm.list
:
deb [signed-by=/usr/share/keyrings/wezterm-fury.gpg] https://apt.fury.io/wez/ * *
The files in my /etc/apt/sources.list.d
were a bit of a jumble, where some had been renamed with an extra .distUpgrade
extension and the deb822-formated files had Enabled: no
. I moved everything back into the proper filenames and changed those yeses to nos, and now when I run apt update
it pulls all from all of the appropriate sources and doesn’t complain about any deprecated keys.
Instead of referencing a key file in the Signed-By
line of a source, you can also directly embed the ASCII representation of the key. With that, the tailscale.sources
looks like:
Enabled: yes
Types: deb
URIs: https://pkgs.tailscale.com/stable/ubuntu
Suites: noble
Components: main
Signed-By:
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQINBF5UmbgBEADAA5mxC8EoWEf53RVdlhQJbNnQW7fctUA5yNcGUbGGGTk6XFqO
nlek0Us0FAl5KVBgcS0Bj+VSwKVI/wx91tnAWI36CHeMyPTawdT4FTcS2jZMHbcN
UMqM1mcGs3wEQmKz795lfy2cQdVktc886aAF8hy1GmZDSs2zcGMvq5KCNPuX3DD5
INPumZqRTjwSwlGptUZrJpKWH4KvuGr5PSy/NzC8uSCuhLbFJc1Q6dQGKlQxwh+q
AF4uQ1+bdy92GHiFsCMi7q43hiBg5J9r55M/skboXkNBlS6kFviP+PADHNZe5Vw0
0ERtD/HzYb3cH5YneZuYXvnJq2/XjaN6OwkQXuqQpusB5fhIyLXE5ZqNlwBzX71S
779tIyjShpPXf1HEVxNO8TdVncx/7Zx/FSdwUJm4PMYQmnwBIyKlYWlV2AGgfxFk
mt2VexyS5s4YA1POuyiwW0iH1Ppp9X14KtOfNimBa0yEzgW3CHTEg55MNZup6k2Q
mRGtRjeqM5cjrq/Ix15hISmgbZogPRkhz/tcalK38WWAR4h3N8eIoPasLr9i9OVe
8aqsyXefCrziaiJczA0kCqhoryUUtceMgvaHl+lIPwyW0XWwj+0q45qzjLvKet+V
Q8oKLT1nMr/whgeSJi99f/jE4sWIbHZ0wwR02ZCikKnS05arl3v+hiBKPQARAQAB
tERUYWlsc2NhbGUgSW5jLiAoUGFja2FnZSByZXBvc2l0b3J5IHNpZ25pbmcga2V5
KSA8aW5mb0B0YWlsc2NhbGUuY29tPokCTgQTAQgAOBYhBCWWqZ6qszghiTwKeUWM
qDKVf1hoBQJeVJm4AhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4BAheAAAoJEEWMqDKV
f1hoWHEP/1DYd9WZrodyV5zy1izvj0FXtUReJi374gDn3cHrG6uYtXcE9HWZhxQD
6nDgYuey5sBhLvPQiE/sl5GYXNw/O95XVk8HS54BHCCYq1GeYkZaiCGLGFBA08JK
7PZItGsfdJHwHfhSMtGPS7Cpmylje9gh8ic56NAhC7c5tGTlD69Y8zGHjnRQC6Hg
wF34jdp8JTQpSctpmiOxOXN+eH8N59zb0k30CUym1Am438AR0PI6RBTnubBH+Xsc
eQhLJnmJ1bM6GP4agXw5T1G/qp95gjIddHXzOkEvrpVfJFCtp91VIlBwycspKYVp
1IKAdPM6CVf/YoDkawwm4y4OcmvNarA5dhWBG0Xqse4v1dlYbiHIFcDzXuMyrHYs
D2Wg8Hx8TD64uBHY0fp24nweCLnaZCckVUsnYjb0A494lgwveswbZeZ6JC5SbDKH
Tc2SE4jq+fsEEJsqsdHIC04d+pMXI95HinJHU1SLBTeKLvEF8Zuk7RTJyaUTjs7h
Ne+xWDmRjjR/D/GXBxNrM9mEq6Jvp/ilYTdWwAyrSmTdotHb+NWjAGpJWj5AZCH9
HeBr2mtVhvTu3KtCQmGpRiR18zMbmemRXUh+IX5hpWGzynhtnSt7vXOvhJdqqc1D
VennRMQZMb09wJjPcvLIApUMl69r29XmyB59NM3UggK/UCJrpYfmuQINBF5UmbgB
EADTSKKyeF3XWDxm3x67MOv1Zm3ocoe5xGDRApPkgqEMA+7/mjVlahNXqA8btmwM
z1BH5+trjOUoohFqhr9FPPLuKaS/pE7BBP38KzeA4KcTiEq5FQ4JzZAIRGyhsAr+
6bxcKV/tZirqOBQFC7bH2UAHH7uIKHDUbBIDFHjnmdIzJ5MBPMgqvSPZvcKWm40g
W+LWMGoSMH1Uxd+BvW74509eezL8p3ts42txVNvWMSKDkpiCRMBhfcf5c+YFXWbu
r5qus2mnVw0hIyYTUdRZIkOcYBalBjewVmGuSIISnUv76vHz133i0zh4JcXHUDqc
yLBUgVWckqci32ahy3jc4MdilPeAnjJQcpJVBtMUNTZ4KM7UxLmOa5hYwvooliFJ
wUFPB+1ZwN8d+Ly12gRKf8qA/iL8M5H4nQrML2dRJ8NKzP2U73Fw+n6S1ngrDX8k
TPhQBq4EDjDyX7SW3Liemj5BCuWJAo53/2cL9P9I5Nu3i2pLJOHzjBSXxWaMMmti
kopArlSMWMdsGgb0xYX+aSV7xW+tefYZJY1AFJ1x2ZgfIc+4zyuXnHYA2jVYLAfF
pApqwwn8JaTJWNhny/OtAss7XV/WuTEOMWXaTO9nyNmHla9KjxlBkDJG9sCcgYMg
aCAnoLRUABCWatxPly9ZlVbIPPzBAr8VN/TEUbceAH0nIwARAQABiQI2BBgBCAAg
FiEEJZapnqqzOCGJPAp5RYyoMpV/WGgFAl5UmbgCGwwACgkQRYyoMpV/WGji9w/8
Di9yLnnudvRnGLXGDDF2DbQUiwlNeJtHPHH4B9kKRKJDH1Rt5426Lw8vAumDpBlR
EeuT6/YQU+LSapWoDzNcmDLzoFP7RSQaB9aL/nJXv+VjlsVH/crpSTTgGDs8qGsL
O3Y2U1Gjo5uMBoOfXwS8o1VWO/5eUwS0KH7hpbOuZcf9U9l1VD2YpGfnMwX1rnre
INJqseQAUL3oyNl76gRzyuyQ4AIA06r40hZDgybH0ADN1JtfVk8z4ofo/GcfoXqm
hifWJa2SwwHeijhdN1T/kG0FZFHs1DBuBYJG3iJ3/bMeL15j1OjncIYIYccdoEUd
uHnp4+ZYj5kND0DFziTvOC4WyPpv3BlBVariPzEnEqnhjx5RYwMabtTXoYJwUkxX
2gAjKqh2tXissChdwDGRNASSDrChHLkQewx+SxT5kDaOhB84ZDnp+urn9A+clLkN
lZMsMQUObaRW68uybSbZSmIWFVM1GovRMgrPG3T6PAykQhFyE/kMFrv5KpPh7jDj
5JwzQkxLkFMcZDdS43VymKEggxqtM6scIRU55i059fLPAVXJG5in1WhMNsmt49lb
KqB6je3plIWOLSPuCJ/kR9xdFp7Qk88GCXEd0+4z/vFn4hoOr85NXFtxhS8k9GfJ
mM/ZfUq7YmHR+Rswe0zrrCwTDdePjGMo9cHpd39jCvc=
=AIVM
-----END PGP PUBLIC KEY BLOCK-----
I converted the binary format of the key (the .gpg
file) into that text representation with:
$ gpg --keyring tailscale-archive-keyring.gpg --no-default-keyring --export -a
Put a pin in it
I did a first cut of moving my bookmarks on to this site instead of using Pinboard.
I still need to wire up a way to create new bookmarks, but that should be pretty straightforward.
Each bookmark can carry with it an excerpt and a comment. That way I can clip a little text for the bookmark while I’m creating it. None of the existing bookmarks use that yet because Pinboard did no such thing.
Things to be done aside from adding a way to add bookmarks include adding an Atom feed, really wiring them up to search, figure out how to be marking these up in a more IndieWeb-friendly way, and thinking about whether I want to take snapshots of the bookmarks. (Those would probably only be accessible to me to avoid copyright headaches.)
The oldest sins the newest kind of ways
When I wanted to get away from using Discord to participate in the online PHP and IndieWeb communities, I did still want a web-based interface that provided access to the backlog of conversations from when I was offline, which IRC servers don’t generally do on their own.
I landed on using The Lounge, which has worked out very well.
I run it on my home server in Docker and it is exposed to my Tailscale tailnet so if I ever was on the road, I could still access it. The configuration is pretty straightforward. There’s a docker-compose.yml
file:
version: '3.9'
services:
tailscale:
image: tailscale/tailscale:latest
hostname: thelounge
env_file: ./.env
environment:
- TS_SERVE_CONFIG=/config/thelounge.json
- TS_STATE_DIR=/var/lib/tailscale
volumes:
- ts_state:/var/lib/tailscale
- ./config/tailscale:/config
- /dev/net/tun:/dev/net/tun
cap_add:
- net_admin
- sys_module
restart: always
backend:
image: ghcr.io/thelounge/thelounge:latest
env_file: ./.env
volumes:
- lounge_state:/var/opt/thelounge
expose:
- "9000/tcp"
restart: always
volumes:
ts_state:
lounge_state:
And config/tailscale/thelounge.json
:
{
"TCP": {
"443": {
"HTTPS": true
}
},
"Web": {
"${TS_CERT_DOMAIN}:443": {
"Handlers": {
"/": {
"Proxy": "http://backend:9000"
}
}
}
},
"AllowFunnel": {
"${TS_CERT_DOMAIN}:443": false
}
}
There is an .env
file that sets TS_AUTHKEY
and TS_EXTRA_ARGS
. It looks kind of like this:
TS_AUTHKEY="tskey-client-{something}?ephemeral=false"
TS_EXTRA_ARGS="--advertise-tags=tag:container --reset"
Never was a cloudy day
Another month in the rear view mirror, and time for me to reflect on my job search and remind people that I’m still out on these streets looking.
Some days it feels like I am not any closer to having a job than I was when this all started. I have a lot of applications behind me, a handful of screening calls with recruiters, a smaller number of interviews, and as of yet no offers. I have been ghosted on countless applications and once after a screening call. (That position still gets re-listed periodically.)
I am in the interview process with a very large tech company with a drawn-out interview process. I have very mixed feelings about it. Do I really want to work there? Am I going to pass through their interview hoops? A big factor in those mixed feelings is that if an offer does happen, it will require moving to another city and working out of an office several days a week.
Some of the rejections, even when they came early, have been hard. There have been positions at a few different companies that were focused on building internal tools for the company, which is something I believe I would be particularly well-suited to do, so I have been looking harder at listings that push that button.
I am grateful to everyone who has offered support, and leads on positions.
Into the blue again after the money’s gone
A reason that I finally implemented better thread navigation for the PHP mailing list archives is because it was a bit of unfinished business — I had implemented it for the MySQL mailing lists (RIP), but never brought it back over to the PHP mailing lists. There, it accessed the MySQL database used by the Colobus server directly, but this time I exposed what I needed through NNTP.
An advantage to doing it this way is that anyone can still clone the site and run it against the NNTP server during development without needing any access to the database server. There may be future features that require coming up with ways of exposing more via NNTP, but I suspect a lot of ideas will not.
Another reason to implement thread navigation was that a hobby of mine is poking at the history of the PHP project, and I wanted to make it easier to dive into old threads like this thread from 2013 when Anthony Ferrara, a prominent PHP internals developer, left the list. (The tweet mentioned in the post is gone now, but you can find it and more context from this post on his blog.)
Reading this very long thread about the 2016 RFC to adopt a Code of Conduct (which never came to a vote) was another of those bits of history that I knew was out there but hadn’t been able to read quite so easily.
Which just leads me to tap the sign and point out that there is a de facto Code of Conduct and a group administering it.
I think implementing a search engine for the mailing list archives may be an upcoming project because it is still kind of a hassle to dig threads up. I’m thinking of using Manticore Search. Probably by building it into Colobus and exposing it via another NNTP extension.
Surprise, it’s a new release of Colobus!
Because there’s nothing that quite says “hire me” like polishing your Perl bona fides, I have finally made a new release of Colobus, the NNTP server that runs on top of ezmlm and Mlmmj mail archives. (It was actually three new releases, I had to work out some kinks. More to come as I work out more in testing.)
The Mlmmj support and some of the other tweaks are really just pulling in and polishing changes that had been made to the install used for the the PHP.net mailing lists. There are also a few bug fixes I pulled in from Ask’s fork of colobus that the perl.org project uses.
I did add a significant new feature, which is a non-standard XTHREAD id_or_msgid
command that returns an XOVER
-style result for all of the messages in the same “thread”. The code to take advantage of this new feature for the PHP mailing list archives is on the way.