Shellsharks Blogroll - BlogFlock2026-07-20T09:42:05.355ZBlogFlockAdepts of 0xCC, destructured, fLaMEd, Trail of Bits Blog, Aaron Parecki, Westenberg, gynvael.coldwind//vx.log (pl), James' Coffee Blog, joelchrono, Evan Boehs, Kev Quirk, cool-as-heck, Posts feed, Sophie Koonin, cmdr-nova@internet:~$, <span>Songs</span> on the Security of Networks, Werd I/O, Johnny.Decimal, Robb Knight, Molly White, Hey, it's Jason!, Terence Eden’s Blog📝 2026-07-20 08:10: Yup. Goat-proofing the chicken door really worked a treat. FML. 🤦🏼♂️ - Kev Quirkhttps://kevquirk.com/2026-07-20-08102026-07-20T07:11:00.000Z<p>Yup. Goat-proofing the chicken door really worked a treat. FML. 🤦🏼♂️</p>
<p><img loading="lazy" src="https://kevquirk.com/content/images/2026-07-20-0810/IMG_8265-2.webp" alt="IMG_8265-2" /></p> <div class="email-hidden">
<hr />
<p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p>
<p>You can <a href="mailto:19gy@qrk.one?subject=%F0%9F%93%9D%202026-07-20%2008%3A10">reply to this post by email</a>, or <a href="https://kevquirk.com/2026-07-20-0810#comments">leave a comment</a>.</p>
</div>📝 2026-07-19 19:09: Today was spent goat-proofing the automatic chicken door. We recently moved it to ground level... - Kev Quirkhttps://kevquirk.com/2026-07-19-19092026-07-19T18:09:00.000Z<p>Today was spent goat-proofing the automatic chicken door. We recently moved it to ground level and now the goats use it as a scratch post. 🐐</p> <div class="email-hidden">
<hr />
<p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p>
<p>You can <a href="mailto:19gy@qrk.one?subject=%F0%9F%93%9D%202026-07-19%2019%3A09">reply to this post by email</a>, or <a href="https://kevquirk.com/2026-07-19-1909#comments">leave a comment</a>.</p>
</div>I've Moved Back to GitHub - Kev Quirkhttps://kevquirk.com/ive-moved-back-to-github2026-07-19T12:25:00.000Z<p>Back in May, I <a href="https://kevquirk.com/im-off-github">wrote a post</a> about how I'd migrated all my repos away from GitHub. This ended up being a combination of my self-hosted Git server on my Synology (for my private repos) and <a href="https://codeberg.org" rel="noopener noreferrer">Codeberg</a> for my public ones.</p>
<p>Well, since then Codeberg has just given me problem after problem. I had issues working with repos via SSH for <em>weeks</em>. It just kept timing out, or taking an age to actually do anything. So I switched to HTTPS instead, which seemed a little better, albeit still generally <em>very</em> slow.</p>
<p>This morning I came to do a bit of work on some issues and PRs that have been logged against the <a href="https://purecomments.org" rel="noopener noreferrer">Pure Comments</a> repo and (unsurprisingly at this point), I was greeted with this:</p>
<p><img loading="lazy" src="https://kevquirk.com/content/images/ive-moved-back-to-github/codeberg-504.webp" alt="codeberg-504" /></p>
<p>I've been trying to get to the repo for around 30 minutes now, and it just keeps failing. I can't work like this - I'm a busy guy, so when I do get time to work on these fun side projects, my shit needs to work.</p>
<p>People give GitHub a hard time for outages, scraping, etc. but in all the years I've used it, I've <em>never</em> had an issue. It has always been quick, and it <em>always</em> worked.</p>
<p>In my boredom while waiting for Codeberg to sort themselves out, I decided to peruse my RSS feeds and I came across <a href="https://sals.place/blog/moved-the-blog-from-gitlab-to-github/" rel="noopener noreferrer">this post by Sal</a>. It seems he's been having similar problems with Gitlab.</p>
<h2>Moving back</h2>
<p>This was the final straw. I've had enough of battling with Codeberg, so I've switched back to GitHub. Some may not like this decision as Codeberg is generally considered the more community friends code hub, but I need to make a pragmatic choice here as the constant issues are sapping most the fun out of these projects.</p>
<p>I'll continue to host my private projects on the Synology, as that works great. But as of right now, we're back on <a href="https://github.com/kevquirk" rel="noopener noreferrer">GitHub</a> for all [my <a href="https://kevquirk.com/projects">projects</a>. I think I've caught all references to Codeberg across the various sites and docs (thanks to Gemini), but if you see a problem, please log an issue.</p>
<p>There is 1 final update on Codeberg for both Pure Blog and Pure Comments. This points the updater back to GitHub, from then on, subsequent releases will be on GitHub.</p>
<h2>What about...</h2>
<p>I'm bound to get some comments and suggestions about other options other than moving back to GitHub, so I'll try and hit them before you take the time to comment/email with recommendations:</p>
<ol>
<li>
<p><strong>What about a self-hosted Forgejo instance?</strong><br>
Absolutely not. I don't have time to maintain something like that. I'd rather spend my free time working on fun projects than managing infrastructure.</p>
</li>
<li>
<p><strong>But GitHub are really bad because of <code>[reason(s)]</code> what about <code>[other tool]</code>?</strong><br>
Nope, sorry. I don't want to use other platforms that potentially introduce the same issues I've been having with Codeberg. Look at Sal's post further up - he was on Gitlab and having similar problems to me.</p>
</li>
<li>
<p><strong>This is disappointing, are you sure about your decision?</strong><br>
I'm <em>very</em> sure. It is disappointing, I agree. But I've given it a lot of thought over the last few weeks and I'd rather go with the tool that I know will work, than the one I have to battle with. Plus, this is all public code, so I don't think I'm giving anything away by switching back.</p>
</li>
<li>
<p><strong>I'll NEVER use GitHub. I'm gonna stop using <code>[project]</code> now.</strong><br>
That's a shame, but it's your call.</p>
</li>
</ol> <div class="email-hidden">
<hr />
<p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p>
<p>You can <a href="mailto:19gy@qrk.one?subject=I%27ve%20Moved%20Back%20to%20GitHub">reply to this post by email</a>, or <a href="https://kevquirk.com/ive-moved-back-to-github#comments">leave a comment</a>.</p>
</div>Of Day - James' Coffee Bloghttps://jamesg.blog/2026/07/19/of-day2026-07-19T00:00:00.000Z
<p>I close my eyes and listen to the church bells reverberate through the city — the air, the street, the park; the hearts.</p><p>Usually when I go into a bookshop, I find myself looking at all the books. Often, for nothing in particular, but rather to see what is new. Who knows what I might find; what stories might stand out today. My time spent wandering around the walls of words today, however, was characterised more by writing than by reading. The books were my anchor. The word was in my spirit. My disposition was to capture what I heard and saw and felt; to let my thoughts flow onto a new page.</p><p>I took notes on art galleries, places where we can feel both oriented and lost; where we can discover and ponder discovery; where we can let the present pass while considering the past and the future; where the colours of Monet and the shadows of Rembrandt exist a few rooms away. What does it mean that I can see Rembrandt and walk through a few rooms to see Monet?</p><p>I realised I was lost, not in place but in thought. I recognised the shelves in front of me while I stood at the frontier of my imagination, asking questions with increasing momentum – questions of magnetism and enchantment and on the nature of significance.</p><p>“My dream is to have one of each of these.” “The classics?” “Yeah.” “We should do it as a wee Christmassy thing: each of us should pick four or five that we like…” — a gift exchange? “Oh, that’s the one you keep telling me to read.”, as one of the three friends points to the shelf. The conversation flowed. “So you’re having a book stand in your next [flat?]”. I realised they spoke in the kind of sentences where you don’t need to finish for your friends to know what you mean – therein, the language of friendship.</p><p>I learned today that I can be in a bookshop and an art gallery at the same time, and that I can move between them; that the sounds and physicality of stories can ground me as my mind wanders. A book of poetry caught my eye. Opening the book to a page at random – Serendipity being my guide – I pondered the literal shape of the words in poems. One poem was a rectangle of aligned text. Another poem was written in couplets. One was short. Another, long. How does form influence what we read? I wonder. This is why I love bookshops.</p><p>After having walked around all of the shelves of fiction at a slow pace, I went back outside and let my legs take me where they wanted to go. I wandered, on my journey seeing Georgian architecture, hearing the roar of a lion from a parent entertaining their child, and feeling the fresh air of Scotland rush through my lungs as I looked up to the blue and white sky.</p><p>Eventually, I made my way to the National Gallery of Scotland, not the gallery of I was imagining earlier – that one was four hundred miles away – but one in which I always feel enchanted immediately after walking in. I found myself standing in front of works of Turner and Lievens, Da Vinci and Gainsborough, thinking about the nature of the space I had on my mind since the hour of wandering through the bookshop, and my imagination.</p>
Book Review: A City on Mars - by Dr. Kelly Weinersmith and Zach Weinersmith ★★★★⯪ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=720292026-07-18T11:34:18.000Z<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/05/9780141993348-jacket-large.webp" alt="Book cover featuring a cartoon Martian city." width="326" height="500" class="alignleft size-full wp-image-72030">
<p>I'm pretty sure this book is a psyop designed to demoralise a generation of starry-eyed dreamers. It is obviously written by the same people who told us not to land on Europa. A malignant energy designed to limit the scope of human ambition and thwart our plans to colonise the universe.</p>
<p>The problem is, I can't find fault with any of their logic.</p>
<p>The Weinersmiths make a compelling case that space is <em>much</em> harder than any of the propagandists are willing to admit. Even if it were faster, safer, and cheaper - there's still very little point. Any of the technologies we could point at the skies would be infinitely more useful (and profitable) pointed back at our pale blue dot.</p>
<p>Along the way they take in biology (is it even possible to breed in space?), legality (OK, but what jurisdiction will it be under?), and moral philosophy (will we actually become more enlightened beings?)</p>
<p>And yet, space is <em>cool</em>. I know that "because it is there" isn't a <em>logical</em> argument; but it is a hell of an emotional pull. In amongst all their (justified) snarky cartoons are occasional pearls in the rubble:</p>
<blockquote><p>As with the cathedrals of Earth, those of us who cast the first few bricks may not be around to see the spire placed on top, but we might nevertheless want to start building.</p></blockquote>
<p>They excel at making the dull delightful. There are a lot of big and serious facts to get through, but they have a gift for communicating them simply and eloquently. I just wish they'd've come to a different conclusion.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=72029&HTTP_REFERER=Atom" alt width="1" height="1" loading="eager">WwJD: Spend less time doing boring admin (video) - Johnny.Decimalhttps://johnnydecimal.com/blog/0233-wwjd-less-time-boring-admin/2026-07-18T06:22:15.000Z<div class="youtube-embed" data-astro-cid-aomsn35f=""><iframe src="https://www.youtube-nocookie.com/embed/KiK7RxCzt_k" title="YouTube video" loading="lazy" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" referrerpolicy="strict-origin-when-cross-origin" data-astro-cid-aomsn35f=""></iframe></div>
<blockquote>
<p>A '<a href="https://www.youtube.com/playlist?list=PLtBN5zRaar6qyr3N_5R839uHpkoBAK3m6">Working with Johnny.Decimal</a>' video.</p>
</blockquote>
<p>This video shows how my system helps me calmly complete two simple, infrequent tasks. They're far enough apart that I forget how to do them, and they've previously caused more disruption than necessary. One of the benefits of Johnny.Decimal is that it takes the edge off my computer use, turning it into a neat room where I can work efficiently and spend less time doing boring admin.</p>Finished reading Gideon the Ninth - Molly White's activity feed6a5ade2d91f30f1ebee14ee22026-07-18T02:00:13.000Z<article class="entry h-entry hentry"><header><div class="description">Finished reading: </div></header><div class="content e-content"><div class="book h-entry hentry"><a class="book-cover-link" href="https://www.mollywhite.net/reading/books?search=Gideon%20the%20Ninth"><img class="u-photo book-cover" src="https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1546870952i/42036538.jpg" alt="Cover image of Gideon the Ninth" style="max-width: 300px;"/></a><div class="book-details"><div class="top"><div class="series-info"><i>The Locked Tomb</i> series, book <span class="series-number">1</span>. </div><div class="title-and-byline"><div class="title"><i class="p-name">Gideon the Ninth</i> </div><div class="byline">by <span class="p-author h-card">Tamsyn Muir</span>. </div></div><div class="book-info">Published <time class="dt-published published" datetime="2019">2019</time>. 448 pages. </div></div><div class="bottom"><div class="reading-info"><div class="reading-dates"> Started <time class="dt-accessed accessed" datetime="2026-07-16">July 16, 2026</time>; completed July 17, 2026. </div></div></div></div></div><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <time class="dt-published" datetime="2026-07-18T02:00:13+00:00" title="July 18, 2026 at 2:00 AM UTC">July 18, 2026 at 2:00 AM UTC</time>. </div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=fantasy" title="See all books tagged "fantasy"" rel="category tag">fantasy</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=lgbt" title="See all books tagged "LGBT"" rel="category tag">LGBT</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=science_fiction" title="See all books tagged "science fiction"" rel="category tag">science fiction</a>. </div></div></footer></article>Self hosting a PDS isn't hard (so far) - Posts feedhttps://www.coryd.dev/posts/2026/self-hosting-a-pds-isnt-hard-so-far2026-07-17T21:23:00.000Z<div class="e-content"><p>Due to my compulsive need to self-host whatever I possibly can<sup id="fnref:1" class="footnote-ref">1</sup>, I decided to set up a self-hosted PDS. All that's on it so far is <a href="https://bsky.app/profile/coryd.dev">my Bluesky profile data</a>, but it was a surprisingly painless process.</p>
<p>Why bother? Well, I get to own my identity (DID) and my data. The relay and AppView remain Bluesky's, but the authoritative copy of my account is mine. I already syndicate from my site to Bluesky and controlling the PDS is the last part of this infrastructure I can reasonably control.</p>
<p>I've been bolting features on to my own CLI to manage my infrastructure for a bit<sup id="fnref:2" class="footnote-ref">2</sup>. I use <a href="https://hetzner.cloud/?ref=z8HjC9EGAYLe">Hetzner</a> for hosting and it wraps their <code>hcloud</code> CLI for my own convenience. I spun up a <code>CX23</code> box with backups turned on and then ran another CLI command to bootstrap the server.</p>
<aside>
<p>The bootstrap configures the shell, installs Tailscale and other dependencies and clones a repository that contains a shared set of infrastructure dependencies.</p>
</aside>
<p>The server is running only two things: the canonical <code>ghcr.io/bluesky-social/pds</code> container maintained by Bluesky and Caddy. I use <a href="https://forwardemail.net">forwardemail.net</a> for transactional emails.</p>
<p>With the server provisioned, I updated the <code>_atproto</code> record for my domain and added a <code>pds</code> <code>A</code> record. I use <a href="https://dnscontrol.org">DNSControl</a> to manage DNS records, so this only took a few minutes.</p>
<h2 id="the-migration">The migration</h2>
<p>Migrating my data from Bluesky's PDS to my own was the only part of this process that made me a little nervous. I needed to preserve my <code>DID</code>, followers and just over 1,000 account records. I used <a href="https://github.com/bluesky-social/goat">Bluesky's <code>goat</code> tool</a> to manage this process.</p>
<ol>
<li>I generated a recovery key using <code>goat key generate --type k256</code></li>
<li>Logged in to my old (Bluesky) account: <code>goat account login -u <username> -p <app-password> --auth-factor-token <email-code></code></li>
<li>Created a PDS invite for myself using my CLI (or SSH into the box and run <code>pdsadmin create-invite-code</code>).</li>
<li>Ran the migration — it pauses and emails a PLC confirmation code that you paste into the prompt:</li>
</ol>
<pre class="language-bash"><code class="language-bash">goat account migrate <span class="token string">\
</span> --pds-host <host> <span class="token string">\
</span> --new-handle <username> <span class="token string">\
</span> --new-password <span class="token string">"<password>"</span> <span class="token string">\
</span> --invite-code <span class="token string">"<pds-invite-code>"</span>
</code></pre>
<ol start="5">
<li>Added my recovery key to the identity so it's my highest-priority rotation key (this also emails a confirmation token): <code>goat account plc add-rotation-key <recovery-pubkey> --first</code></li>
</ol>
<p>It ran faster than I expected and worked without any issues (shocking, I know). I syndicated a post, opened my profile in an incognito window and it loaded without issue. I also verified that DID doc <code>#atproto_pds</code> pointed at my new host and threw my private recovery key in my password manager.</p>
<h2 id="cleanup">Cleanup</h2>
<p>The last step was to add support for a custom PDS URL to my site and the PWA I built myself to browse Mastodon and Bluesky simultaneously. This consisted of a migration to update the database schema to save the URL and the corresponding field in the UI. The app passwords I use for both also needed to be recreated on the new PDS which I did from the aforementioned CLI.</p>
<p>I have yet another server running which, at this point, I'm starting to collect like trading cards. My ATProto data sits on its own server, free to be used with any apps that support it (for my purposes that's only Bluesky — for now). It was a surprisingly straightforward process and I'm thankful for that.</p>
<p>I'm still getting my head around ATProto, but I appreciate that you <em>can</em> own your own data, if not all of the application infrastructure. I was used to the Mastodon mental model where, while you can migrate between instances, not all data comes with you. You own the identity but, perhaps, not all of the content. You can't own everything in either case, for now, but it feels like we're heading in the right direction.</p>
<div class="footnotes" role="doc-endnotes"><hr/><ol><li id="fn:1"><p>Except email. ↩︎</p>
</li><li id="fn:2"><p>More on that in a future post, probably. ↩︎</p>
</li></ol></div></div>One of those webinars - Joel's Log Fileshttps://joelchrono.xyz/blog/one-of-those-webinars2026-07-17T14:15:00.000Z<p>Don’t worry, it was fully optional.</p>
<p>I assisted to a webinar about “the potential of AI” in the workplace, and you can already guess what sort of conference I had to go through yesterday. I shared a livestream of my thoughts on my <a href="https://polymaths.social/@joel/statuses/01KXNYMFY3YGP7WFHY5NN9N9QM">Polymaths’ profile</a> in case you want to see my reactons to what was said there, it’s hilarious stuff.</p>
<p>Something I didn’t mention on that thread was a little quizz at the start, where people filled out polls and the like, and one of the pages was actually a word cloud, they asked “what words come to mind when you think about AI?”.</p>
<p>Of course, I typed a few: “Wasteful”, “lazy”, “slop”, “unethical”… there was no limit I found to how many I could add, but I stopped with those. They didn’t even show up in the word cloud.</p>
<p>“Useful”, “automation”, “future”, “tool”, “assistant”.</p>
<p>Each word got bigger as more and more people typed them in real time.</p>
<p>This wasn’t a multiple choice question, they were chosen and submitted by many.</p>
<p>It is unfortunate, and undeniable, how many people today are perfectly okay with all this, even when they are aware of the bad they caused and continue to cause—they simply look the other way.</p>
<p>“It’s a necessary evil now, there’s nothing we can do about it.”</p>
<p>“We need to catch up with the times, it’s the same as the calculator or the personal computer”</p>
<p>One of the common themes during the presentation was how “you should learn how to use it, don’t stay behind”, because “you will not be replaced by it, but by those who know how to use it”.</p>
<p>Honestly though, as grim as it sounds, I couldn’t help but cringe at every example and slide showed through the whole thing. The generated graphics, the generated prompts, pretty much all the information there was not made by the presentator, none of the examples or problems solved were real.</p>
<p>It’s such a big charade, and the fact everything started with how much running these things can cost and how “it’s not that the AI is inneficient, it’s just that you don’t prompt it properly” let me know it’s all just a joke.</p>
<p>At some point the host shared their screen and started to copy-paste example prompts, while the sidebar featuring a chat history was in full display. “Answer this email”, “summarise this email”, and almost out of frame… “I’m doing a webinar about[…]”.</p>
<p>Check the thread if you want, it’s a good laugh. Watching the bubble pop will be fun.</p>
<p>This is day 98 of <a href="https://100daystooffload.com">#100DaysToOffload</a>.</p>
<p>
<a href="mailto:me@joelchrono.xyz?subject=One of those webinars">Reply to this post via email</a> |
<a href="https://fosstodon.org/@joel/116935766443228264">Reply on Fediverse</a>
</p>Notable links: July 17, 2026 - Werd I/O6a5a288e3149a20001fdb2092026-07-17T13:28:46.000Z<hr><img src="https://storage.ghost.io/c/18/7c/187cc681-d3f3-49fc-87de-b01d06b76821/content/images/2026/07/Screenshot-2026-07-17-at-9.12.32---AM.png" alt="Notable links: July 17, 2026"><p><em>Most Fridays, I share a handful of pieces that caught my eye at the intersection of technology, media, and society.</em></p><p><em>Did someone forward this to you? </em><a href="https://werd.io/notable-links-july-10-2026/#/portal" rel="noreferrer"><em>Subscribe for free</em></a><em>.</em></p><hr><h3 id="mamdani-invests-in-tech-capacity-to-%E2%80%9Csolve-real-problems%E2%80%9D"><a href="https://donmoynihan.substack.com/p/mamdani-invests-in-tech-capacity" rel="noreferrer">Mamdani invests in tech capacity to “solve real problems”</a></h3><p>There’s a lot that newsrooms can learn from Zohran Mamdani’s mayoral administration in New York City. His latest announcement is the <a href="https://www.nyc.gov/content/pitcrew/pages/">Public Interest Technology (PIT) Crew</a>, a set of dynamic, cross-disciplinary digital teams that will solve problems across the city using a rapid, human-centered approach.</p><p><a href="https://donmoynihan.substack.com/p/mamdani-invests-in-tech-capacity">As Pamela Herd notes here</a>, this is a shift from contracting out to building internal capacity:</p><blockquote>“Traditionally, the conventional wisdom since the 1990s and before was that governments could buy tech products like an off-the-shelf product. This led to a massive turn to contracting out, which was great for consultants but bad for government capacity. The outsourced approach often cost too much, delivering too little and too late.<br><br>[…] What people who know tech and government have been screaming for years is that building good tech needs in-house capacity, even when you are using contractors. It requires the government owning the design, development and delivery of technology, relying on rapid iteration to fix problems in a way that is impossible when contractors are running things.”</blockquote><p>This dynamic is also highly prevalent in newsrooms, resulting in the same problems. If you rely too heavily on buying existing technology or working with outside contractors, you are building operational, functional, and intellectual dependencies on those organizations. You import their values and ways of working, which in the case of some vendors may be catastrophic in itself, but you also put yourself on their timelines and make yourself subject to their feature priorities and interests. And that’s before you consider security and trust profiles, which may radically differ between newsrooms and the vendors that serve them.</p><p>New York City isn’t alone; other governments are beginning to shift from outsourcing back to internally owned technology. The article links to <a href="https://drive.google.com/file/d/1NG4ZOm1fgioLJc7eJZrBSIi4VJ2YyTPi/view">a report explaining Colorado’s move back to internally-run IT</a>, which states the issue plainly:</p><blockquote>“There is an alignment problem: the issue is not effort, but that we have organized around internal structures rather than outcomes, and that misalignment has made excellent work harder.”</blockquote><p>Mamdani’s PIT Crew sounds a lot like how a product team should work: directed groups of experts rapidly prototyping solutions to concretely defined problems anchored in real people’s needs. By doing it internally, he can make sure these solutions are built exactly the way the city needs, build institutional capacity and knowledge, and, theoretically at least, do it far more cheaply in the long run.</p><p>As these sorts of civic measures succeed, I think (or, perhaps, I <em>hope</em>) we’ll see more newsrooms translate those outcomes to their own businesses and begin to understand that they need to prioritize technical capacity too. All the same reasons apply here.</p><p>Of course, most newsrooms don’t have the budget of the New York City Mayor’s office. I think the solution to that is third entities: non-profit organizations that exist to provide shared technical capacity across newsrooms, based on newsroom needs, <em>that behave as if they were part of newsroom teams</em>. Think of it as a kind of PIT Crew for news, operated independently but in deep collaboration with newsrooms. By using a radically open source approach, newsrooms can pool resources together and solve shared technical problems more easily, on their terms and according to their values.</p><p>While there are always places for startups and tech platforms, the idea that the tech industry can always serve needs better than building institutional capacity is fundamentally broken; it’s also fundamentally right-wing. I’m delighted to see the New York City Mayor’s office move in a more productive direction. I hope it becomes an example for everyone.</p><hr><h3 id="we-are-not-alone"><a href="https://restructurednews.substack.com/p/we-are-not-alone" rel="noreferrer">We are not alone</a></h3><p>I was delighted to be included in this roundup by Adiel Kaplan, the Program Director at the Tow-Knight Center for Journalism Futures at the Craig Newmark Graduate School of Journalism at CUNY.</p><p><a href="https://restructurednews.substack.com/p/we-are-not-alone">As Adiel says</a>:</p><blockquote>“Having a say in what the future of news looks like will likely require not just that collaboration across newsrooms, but also outside them, with other institutions that want to shape a future with informed communities at its center — which is, after all, the mission. Right?<br><br>[…] It will also require a different way of thinking about our role in this ecosystem, beyond creating content and distributing it. It might mean getting more involved in building technology, or joining forces in new ways with government-funded institutions.”</blockquote><p>This is exciting to me: I’ve been saying for a while now that news needs to get more involved in building technology. My flippant line is that <em>news treats technology as something that happens to it, like an asteroid</em> — but it’s actually a creative work, like an article. Although many newsrooms are too small to build a strong capacity in themselves, it’s perfectly possible for news <em>as an industry</em> to build capacity and create the technology that is unique to its use cases on its terms. So I think it’s a very good thing that news institutions are talking about this need.</p><p>The people listed in the article are exceptional. I’m just happy to be on the list in such fine company. Don’t sleep on any of them; I feel most connected to Ivan Sigal’s ambitious and vital work at the <a href="https://www.modalfoundation.org/">Modal Foundation</a> and what Trei Brundrett <a href="https://newpublic.substack.com/p/introducing-roundabout-built-for">is building</a> (in collaboration with Blaine Cook and others) at New_ Public. But these are all worthy endeavors: the <a href="https://www.librarynewsroom.com/">Library Newsroom Project</a> is a genius on-the-ground effort to create local newsrooms based in every public library in the US, and Sannuta Raghu’s <a href="https://reutersinstitute.politics.ox.ac.uk/introducing-news-atom-metadata-blueprint-journalism-age-ai">news atoms</a> embed meaning and provenance in natural language articles. All are promising.</p><p>We need to move forward. There are certainly more people who could have been added to such a list; my hope is that if one were written a year from now, it would be exponentially longer. Let’s innovate.</p><hr><h3 id="white-house-directed-patel-to-oversee-investigation-involving-times-reporting"><a href="https://www.nytimes.com/2026/07/11/us/politics/white-house-patel-investigation-times.html?unlocked_article_code=1.xFA.9q52.ZL9VNq1-BClg&smid=url-share" rel="noreferrer">White House Directed Patel to Oversee Investigation Involving Times Reporting</a></h3><p>The White House personally directed FBI Director Kash Patel to <a href="https://www.nytimes.com/2026/07/11/business/media/new-york-times-trump-subpoenas.html">issue subpoenas to journalists reporting on the President’s new Qatari-gifted Air Force One</a>.</p><blockquote>“The White House’s deep involvement in the case came after officials said that President Trump was enraged about the coverage of the Qatari-donated plane, which The Times reported Thursday lacks the same defensive countermeasures of the previous Air Force One.”</blockquote><p>These subpoenas were delivered by hand to some of the reporters at home, echoing <a href="https://www.theguardian.com/us-news/2026/jan/14/fbi-raid-washington-post-hannah-natanson">the FBI’s raid of a Washington Post engagement reporter’s home</a> earlier this year. In both cases, it’s highly likely that these were attempts to discover who leaked information to their respective newsrooms.</p><p>There’s lots to say about first amendment issues here, and commentators like <a href="https://dankennedy.net/2026/07/11/from-the-trump-regime-to-a-rogue-judge-in-new-jersey-the-first-amendment-is-under-assault/">Dan Kennedy at Media Nation</a> have pertinent thoughts. It’s clear that journalism is under attack by the administration, and <a href="https://www.npr.org/2025/04/25/nx-s1-5377624/pam-bondi-reporters-subpoena-leaks">they rescinded rules that protected journalists in leak investigations last year</a>. The <a href="https://pressfreedomtracker.us/">US Press Freedom Tracker</a> is a sobering read. But it’s also important to take a moment to talk about the technology side of this story.</p><p>When the administration wants to issue a subpoena to a newsroom, it has a few avenues available to it. The first is to issue it directly to the newsroom or to its reporters, as they did here. In some ways, this is the best outcome: then the newsroom knows about the subpoena and can actively fight it in court.</p><p>The other avenue is to subpoena the newsroom’s service providers. If source information is stored unencrypted on a service like Google Workspace, the administration could subpoena Google. If a gag order is added — which might well happen if it’s a criminal subpoena or labeled a matter of national security — then the newsroom would never find out and have the chance to fight it. This is true even if the service provider nominally promises to notify the newsrooms about subpoenas: a gag order is a gag order.</p><p>Larger newsrooms have strong data security practices for this reason: they know to create policies and architectures which force subpoenas to come through them. But not every newsroom has the capacity to build a strong security strategy. Which means for every story we hear about that involves these newsrooms, there may be many more that took place in secret.</p><p><a href="https://freedom.press/digisec/">The Freedom of the Press Foundation maintains digital security resources and runs training for newsrooms</a> and <a href="https://freedom.press/digisec/blog/source-protection/">specific advice about source protection</a>. <a href="https://www.eff.org/issues/security-education">The EFF also has some great resources</a>. More resources are out there. But there is more of a need than ever for every newsroom to make sure they have access to someone who can advise them on digital security both holistically and on a case-by-case basis. Not every newsroom can afford a permanent member of staff, but finding access to some kind of resource is vital.</p><p>Likewise, journalism funders should focus on providing access to experts, understanding that these issues are existential for the organizations they fund. Not only is this an attack on press freedoms, but it’s also an attack on trust. Every newsroom can do its reporting because sources feel safe to reach out to it; if their safety is in question, they may be less likely to leak, and we may be less likely to read the stories that help us make good democratic decisions. That’s what the administration seems to be banking on.</p><hr><h3 id="trump-dismantled-a-federal-climate-website-these-women-rebuilt-it"><a href="https://19thnews.org/2026/07/noaa-climate-data-website/" rel="noreferrer">Trump dismantled a federal climate website. These women rebuilt it.</a></h3><p>This shouldn’t have been necessary, but is still wonderful to see. Climate.gov had been the go-to resource for climate data, but it went offline when the Trump Administration radically cut NOAA’s funding. <a href="https://19thnews.org/2026/07/noaa-climate-data-website/">At that point</a>:</p><blockquote>“[Rebecca] Lindsey joined forces with former NOAA employees Anna Eshelman, and Mary Lindsey, her older sister, to become the core team behind the deactivated site’s successor, <a href="https://climate.us">Climate.us</a>, preserving over 15 years of key climate data and resources. The trove features key maps, educational materials and climate indicator reports, including the now-deleted Fifth National Climate Assessment, the government’s most comprehensive analysis of climate change that was at risk of being lost to the public.”</blockquote><p>This is possible because US government data is public domain by law. Had it not been available under a permissive license, the administration’s act of vandalism would have meant the data was gone for good. But because it was, the datasets can find a new home.</p><p>It’s a joy to use. <a href="https://www.climate.us/climatedashboard">Check out the climate dashboard</a>, which tracks numbers like the <a href="https://www.climate.us/news-features/understanding-climate/climate-change-arctic-sea-ice-summer-minimum">total area of the Arctic Ocean that was at least 15% ice-covered each September</a>. It also hosts a set of <a href="https://www.climate.us/teaching">resources for teaching climate and energy</a>. The <a href="https://www.climate.us/maps-data/dataset-gallery">dataset gallery</a> includes crucial information like <a href="https://www.climate.us/maps-data/dataset/noaa-voices-oral-history-archives">the NOAA’s archive of oral histories from people whose lives were affected by climate change</a>.</p><p>But it’s also precarious. The whole thing relies on donations to keep it afloat, which is really what tax dollars are for. Still, for the moment it’s wonderful to see people pick up the slack when government is no longer doing its job. In the absence of government support, archives like this are works of journalism in themselves: ways to help us make stronger decisions. They deserve stronger support, and ultimately, we all deserve the restoration of such important government infrastructure.</p><hr><h3 id="a-leak-of-san-francisco-police-drone-footage-exposes-the-new-reality-of-urban-surveillance"><a href="https://www.wired.com/story/sfpd-drone-video-leak-surveillance/" rel="noreferrer">A Leak of San Francisco Police Drone Footage Exposes the New Reality of Urban Surveillance</a></h3><p>I’m not sure I agree with this article’s implication that the problem with SFPD’s drone policing was that it accidentally leaked the data.</p><blockquote>““There’s a certain trust given to the police to use these things correctly,” says Curry. “When you're watching a drone feed live, you can look into dozens of different apartments, you can see police zooming in on people, you can see arrests. The fact that all of this was exposed feels like a really big issue from a privacy perspective.””</blockquote><p>I’d humbly submit that the privacy problem exists regardless of whether the footage was leaked or not: this is ubiquitous surveillance of a city’s citizens from above. That footage can be analyzed, both by humans and software, to track people and target them for any reason. There is very little oversight, and because the police department is using a private company to run it, the teams there presumably have access to an enormous amount of private footage.</p><p>The thing is, none of this actually makes us safer. <a href="https://www.aclunorcal.org/app/uploads/drupal/sites/default/files//Seeing_Through_Surveillance__Report_Web.pdf">As the ACLU of Northern California points out in its Seeing Through Surveillance report</a>:</p><blockquote>“The evidence is clear that while surveillance has increased exponentially, public safety has not. On the contrary, surveillance systems often make people less safe, especially for groups that have historically been in the government’s crosshairs. Modern surveillance technology makes it possible for the government to track who we are, where we go, what we do, and who we know. It fuels high-tech profiling and perpetuates systems of biased policing. It facilitates deportations, chills speech, and imperils the rights of activists, religious minorities, and people who need reproductive and gender-affirming care.”</blockquote><p>Most importantly, it doesn’t actually help. As the report points out, the city of San Francisco itself learned that adding cameras to its highest-crime neighborhoods <em>had no impact on crime</em>. Regardless, it added more funding to the program and voted to remove oversight in 2023. The result is more money spent, less privacy, with no impact on public safety. And now we know that the footage is being accidentally leaked, the privacy footprint is obviously even worse.</p><p>In a world that is becoming markedly more authoritarian, it’s unconscionable that supposedly permissive cities would add more surveillance. It doesn’t work, it misuses funds that could be spent helping the vulnerable, and it’s data that could be used for undemocratic purposes. It needs to stop — and to do that, we need to apply pressure to our elected representatives and raise awareness of how backwards it is.</p>To innovate, news needs allies - Werd I/O6a5a2d9a3149a20001fdb22d2026-07-17T13:26:50.000Z<p>Link: <a href="https://restructurednews.substack.com/p/we-are-not-alone"><em>We are not alone, by Adiel Kaplan at the Tow-Knight Center</em></a></p><p>I was delighted to be included in this roundup by Adiel Kaplan, the Program Director at the Tow-Knight Center for Journalism Futures at the Craig Newmark Graduate School of Journalism at CUNY.</p><p><a href="https://restructurednews.substack.com/p/we-are-not-alone">As Adiel says</a>:</p><blockquote>“Having a say in what the future of news looks like will likely require not just that collaboration across newsrooms, but also outside them, with other institutions that want to shape a future with informed communities at its center — which is, after all, the mission. Right?<br><br>[…] It will also require a different way of thinking about our role in this ecosystem, beyond creating content and distributing it. It might mean getting more involved in building technology, or joining forces in new ways with government-funded institutions.”</blockquote><p>This is exciting to me: I’ve been saying for a while now that news needs to get more involved in building technology. My flippant line is that <em>news treats technology as something that happens to it, like an asteroid</em> — but it’s actually a creative work, like an article. Although many newsrooms are too small to build a strong capacity in themselves, it’s perfectly possible for news <em>as an industry</em> to build capacity and create the technology that is unique to its use cases on its terms. So I think it’s a very good thing that news institutions are talking about this need.</p><p>The people listed in the article are exceptional. I’m just happy to be on the list in such fine company. Don’t sleep on any of them; I feel most connected to Ivan Sigal’s ambitious and vital work at the <a href="https://www.modalfoundation.org/">Modal Foundation</a> and what Trei Brundrett <a href="https://newpublic.substack.com/p/introducing-roundabout-built-for">is building</a> (in collaboration with Blaine Cook and others) at New_ Public. But these are all worthy endeavors: the <a href="https://www.librarynewsroom.com/">Library Newsroom Project</a> is a genius on-the-ground effort to create local newsrooms based in every public library in the US, and Sannuta Raghu’s <a href="https://reutersinstitute.politics.ox.ac.uk/introducing-news-atom-metadata-blueprint-journalism-age-ai">news atoms</a> embed meaning and provenance in natural language articles. All are promising.</p><p>We need to move forward. There are certainly more people who could have been added to such a list; my hope is that if one were written a year from now, it would be exponentially longer. Let’s innovate.</p>WwJD: This is what Johnny.Decimal was designed for (video) - Johnny.Decimalhttps://johnnydecimal.com/blog/0232-wwjd-this-is-what-jd-was-designed-for/2026-07-17T04:58:04.000Z<div class="youtube-embed" data-astro-cid-aomsn35f=""><iframe src="https://www.youtube-nocookie.com/embed/8wt1aahLULs" title="YouTube video" loading="lazy" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="" referrerpolicy="strict-origin-when-cross-origin" data-astro-cid-aomsn35f=""></iframe></div>
<blockquote>
<p>A '<a href="https://www.youtube.com/playlist?list=PLtBN5zRaar6qyr3N_5R839uHpkoBAK3m6">Working with Johnny.Decimal</a>' video.</p>
</blockquote>
<p>Managing complex tasks is not just possible, it's easy with Johnny.Decimal. Everything has a home, and you keep a simple index that lets you find it again, and everything looks the same no matter what app you're using.</p>Multi-line links on my home page - James' Coffee Bloghttps://jamesg.blog/2026/07/17/multi-line-links-on-my-home-page2026-07-17T00:00:00.000Z
<style media="(prefers-color-scheme: dark)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #49483e }
.highlight { background: #272822; color: #F8F8F2 }
.highlight .c { color: #959077 } /* Comment */
.highlight .err { color: #ED007E; background-color: #1E0010 } /* Error */
.highlight .esc { color: #F8F8F2 } /* Escape */
.highlight .g { color: #F8F8F2 } /* Generic */
.highlight .k { color: #66D9EF } /* Keyword */
.highlight .l { color: #AE81FF } /* Literal */
.highlight .n { color: #F8F8F2 } /* Name */
.highlight .o { color: #FF4689 } /* Operator */
.highlight .x { color: #F8F8F2 } /* Other */
.highlight .p { color: #F8F8F2 } /* Punctuation */
.highlight .ch { color: #959077 } /* Comment.Hashbang */
.highlight .cm { color: #959077 } /* Comment.Multiline */
.highlight .cp { color: #959077 } /* Comment.Preproc */
.highlight .cpf { color: #959077 } /* Comment.PreprocFile */
.highlight .c1 { color: #959077 } /* Comment.Single */
.highlight .cs { color: #959077 } /* Comment.Special */
.highlight .gd { color: #FF4689 } /* Generic.Deleted */
.highlight .ge { color: #F8F8F2; font-style: italic } /* Generic.Emph */
.highlight .ges { color: #F8F8F2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #F8F8F2 } /* Generic.Error */
.highlight .gh { color: #F8F8F2 } /* Generic.Heading */
.highlight .gi { color: #A6E22E } /* Generic.Inserted */
.highlight .go { color: #66D9EF } /* Generic.Output */
.highlight .gp { color: #FF4689; font-weight: bold } /* Generic.Prompt */
.highlight .gs { color: #F8F8F2; font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #959077 } /* Generic.Subheading */
.highlight .gt { color: #F8F8F2 } /* Generic.Traceback */
.highlight .kc { color: #66D9EF } /* Keyword.Constant */
.highlight .kd { color: #66D9EF } /* Keyword.Declaration */
.highlight .kn { color: #FF4689 } /* Keyword.Namespace */
.highlight .kp { color: #66D9EF } /* Keyword.Pseudo */
.highlight .kr { color: #66D9EF } /* Keyword.Reserved */
.highlight .kt { color: #66D9EF } /* Keyword.Type */
.highlight .ld { color: #E6DB74 } /* Literal.Date */
.highlight .m { color: #AE81FF } /* Literal.Number */
.highlight .s { color: #E6DB74 } /* Literal.String */
.highlight .na { color: #A6E22E } /* Name.Attribute */
.highlight .nb { color: #F8F8F2 } /* Name.Builtin */
.highlight .nc { color: #A6E22E } /* Name.Class */
.highlight .no { color: #66D9EF } /* Name.Constant */
.highlight .nd { color: #A6E22E } /* Name.Decorator */
.highlight .ni { color: #F8F8F2 } /* Name.Entity */
.highlight .ne { color: #A6E22E } /* Name.Exception */
.highlight .nf { color: #A6E22E } /* Name.Function */
.highlight .nl { color: #F8F8F2 } /* Name.Label */
.highlight .nn { color: #F8F8F2 } /* Name.Namespace */
.highlight .nx { color: #A6E22E } /* Name.Other */
.highlight .py { color: #F8F8F2 } /* Name.Property */
.highlight .nt { color: #FF4689 } /* Name.Tag */
.highlight .nv { color: #F8F8F2 } /* Name.Variable */
.highlight .ow { color: #FF4689 } /* Operator.Word */
.highlight .pm { color: #F8F8F2 } /* Punctuation.Marker */
.highlight .w { color: #F8F8F2 } /* Text.Whitespace */
.highlight .mb { color: #AE81FF } /* Literal.Number.Bin */
.highlight .mf { color: #AE81FF } /* Literal.Number.Float */
.highlight .mh { color: #AE81FF } /* Literal.Number.Hex */
.highlight .mi { color: #AE81FF } /* Literal.Number.Integer */
.highlight .mo { color: #AE81FF } /* Literal.Number.Oct */
.highlight .sa { color: #E6DB74 } /* Literal.String.Affix */
.highlight .sb { color: #E6DB74 } /* Literal.String.Backtick */
.highlight .sc { color: #E6DB74 } /* Literal.String.Char */
.highlight .dl { color: #E6DB74 } /* Literal.String.Delimiter */
.highlight .sd { color: #E6DB74 } /* Literal.String.Doc */
.highlight .s2 { color: #E6DB74 } /* Literal.String.Double */
.highlight .se { color: #AE81FF } /* Literal.String.Escape */
.highlight .sh { color: #E6DB74 } /* Literal.String.Heredoc */
.highlight .si { color: #E6DB74 } /* Literal.String.Interpol */
.highlight .sx { color: #E6DB74 } /* Literal.String.Other */
.highlight .sr { color: #E6DB74 } /* Literal.String.Regex */
.highlight .s1 { color: #E6DB74 } /* Literal.String.Single */
.highlight .ss { color: #E6DB74 } /* Literal.String.Symbol */
.highlight .bp { color: #F8F8F2 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #A6E22E } /* Name.Function.Magic */
.highlight .vc { color: #F8F8F2 } /* Name.Variable.Class */
.highlight .vg { color: #F8F8F2 } /* Name.Variable.Global */
.highlight .vi { color: #F8F8F2 } /* Name.Variable.Instance */
.highlight .vm { color: #F8F8F2 } /* Name.Variable.Magic */
.highlight .il { color: #AE81FF } /* Literal.Number.Integer.Long */ .highlight .nn, .highlight .n{color: light-dark(black, var(--dark-foreground-color)) }</style><style media="(prefers-color-scheme: light)">pre { line-height: 125%; }
td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; }
td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
.highlight .hll { background-color: #ffffcc }
.highlight { background: #f8f8f8; }
.highlight .c { color: #3D7B7B; font-style: italic } /* Comment */
.highlight .err { border: 1px solid #F00 } /* Error */
.highlight .k { color: #008000; font-weight: bold } /* Keyword */
.highlight .o { color: #666 } /* Operator */
.highlight .ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
.highlight .cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #9C6500 } /* Comment.Preproc */
.highlight .cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
.highlight .c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
.highlight .cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 } /* Generic.Deleted */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
.highlight .gr { color: #E40000 } /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
.highlight .gi { color: #008400 } /* Generic.Inserted */
.highlight .go { color: #717171 } /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
.highlight .gt { color: #04D } /* Generic.Traceback */
.highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */
.highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
.highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
.highlight .kp { color: #008000 } /* Keyword.Pseudo */
.highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #B00040 } /* Keyword.Type */
.highlight .m { color: #666 } /* Literal.Number */
.highlight .s { color: #BA2121 } /* Literal.String */
.highlight .na { color: #687822 } /* Name.Attribute */
.highlight .nb { color: #008000 } /* Name.Builtin */
.highlight .nc { color: #00F; font-weight: bold } /* Name.Class */
.highlight .no { color: #800 } /* Name.Constant */
.highlight .nd { color: #A2F } /* Name.Decorator */
.highlight .ni { color: #717171; font-weight: bold } /* Name.Entity */
.highlight .ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #00F } /* Name.Function */
.highlight .nl { color: #767600 } /* Name.Label */
.highlight .nn { color: #00F; font-weight: bold } /* Name.Namespace */
.highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */
.highlight .nv { color: #19177C } /* Name.Variable */
.highlight .ow { color: #A2F; font-weight: bold } /* Operator.Word */
.highlight .w { color: #BBB } /* Text.Whitespace */
.highlight .mb { color: #666 } /* Literal.Number.Bin */
.highlight .mf { color: #666 } /* Literal.Number.Float */
.highlight .mh { color: #666 } /* Literal.Number.Hex */
.highlight .mi { color: #666 } /* Literal.Number.Integer */
.highlight .mo { color: #666 } /* Literal.Number.Oct */
.highlight .sa { color: #BA2121 } /* Literal.String.Affix */
.highlight .sb { color: #BA2121 } /* Literal.String.Backtick */
.highlight .sc { color: #BA2121 } /* Literal.String.Char */
.highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */
.highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #BA2121 } /* Literal.String.Double */
.highlight .se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
.highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */
.highlight .si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
.highlight .sx { color: #008000 } /* Literal.String.Other */
.highlight .sr { color: #A45A77 } /* Literal.String.Regex */
.highlight .s1 { color: #BA2121 } /* Literal.String.Single */
.highlight .ss { color: #19177C } /* Literal.String.Symbol */
.highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */
.highlight .fm { color: #00F } /* Name.Function.Magic */
.highlight .vc { color: #19177C } /* Name.Variable.Class */
.highlight .vg { color: #19177C } /* Name.Variable.Global */
.highlight .vi { color: #19177C } /* Name.Variable.Instance */
.highlight .vm { color: #19177C } /* Name.Variable.Magic */
.highlight .il { color: #666 } /* Literal.Number.Integer.Long */</style>
<style>
@font-face {
font-family: 'MonaspaceArgon';
src: url('/assets/fonts/MonaspaceArgon-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
}
pre, code {
font-family: 'MonaspaceArgon', ui-monospace, monospace;
}
</style>
<p>Every so often, I publish a blog post with a longer title. When this happens, sometimes the post title wraps onto a second line in my list of blog posts on my site home page. This was a tiny detail, but one that I would often notice.</p><p>Last night, I brought the design to <a href="https://indieweb.org/events/2026-07-16-front-end-study-hall" rel="noreferrer">Front End Study Hall</a>, and asked what I could do to make the text better aligned. For context, the following screenshot shows the grid of links on my home page, with one post, the post about an IndieWeb event in the Southeast Asia / Pacific time zone, wrapping <sup class="footnote-reference" id="f-1"><a href="https://jamesg.blog/longform-feed#1">1</a></sup>:</p><figure><picture><img alt='A grid with two columns: one with the heading "Explore", the other with the heading "Recent essays". All links except for one, the third link down in the "Recent essays" column, span one line.' loading="lazy" src="https://editor.jamesg.blog/content/images/2026/07/links1.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">A grid with two columns: one with the heading "Explore", the other with the heading "Recent essays". All links except for one, the third link down in the "Recent essays" column, span one line.</div></div></figure><p>When a link overflowed to a new line, the text was subtly grouped together, so there was a visual indication that both lines were part of the same text. But, when this happened, the rest of the list would be misaligned with the first list to the left. This was the problem I wanted to solve in FrESH, but I came out with another idea.</p><p>We spoke about the grid alignment issue, but the bigger reservation I had became clearer: I was unhappy with how titles that spanned multiple lines appeared.</p><p>During the call, <a href="https://gregorlove.com/">gRegor</a> shared an idea related to distinguishing if a link had spanned multiple lines: what if I used <code>text-indent</code> to indent the text on a multi-line link? The results looked great. The rule we came up with was:</p><div class="highlight"><pre><span></span><span class="nt">nav</span><span class="w"> </span><span class="nt">ul</span><span class="w"> </span><span class="nt">li</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">text-indent</span><span class="p">:</span><span class="w"> </span><span class="mi">-1</span><span class="kt">rem</span><span class="p">;</span>
<span class="w"> </span><span class="k">padding-left</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="kt">rem</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>This would add left padding to all of the <code>li</code> elements, and indent the text by <code>-1rem</code>. The text indent rule only applies to the first line by default, so this rule would mean that all text except for the first line in each link would be pushed left.</p><p>After the call, I learned I can accomplish this in a single line:</p><div class="highlight"><pre><span></span><span class="nt">nav</span><span class="w"> </span><span class="nt">ul</span><span class="w"> </span><span class="nt">li</span><span class="w"> </span><span class="p">{</span>
<span class="w"> </span><span class="k">text-indent</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="kt">rem</span><span class="w"> </span><span class="kc">hanging</span>
<span class="p">}</span>
</pre></div>
<p><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/text-indent">Per the MDN documentation on text-hanging:</a></p><blockquote><code>hanging</code> <br/><br/> Inverts which lines are indented. All lines <em>except</em> the first line will be indented.</blockquote><p>Now, my site home page grid looks like this:</p><figure><picture><img alt="My home page grid with two columns. This time, the second line in the link that spans two lines is indented, creating a cleaner, clearer visual indication that there is a relationship between the first and second lines." loading="lazy" src="https://editor.jamesg.blog/content/images/2026/07/links2.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">My home page grid with two columns. This time, the second line in the link that spans two lines is indented, creating a cleaner, clearer visual indication that there is a relationship between the first and second lines.</div></div></figure><p>The second line in the long link is now indented. I really like this design. I didn’t consider the idea of indenting until gRegor mentioned it and we saw it on the page.</p><p>I also used this as an opportunity to clean the markup on my home page, moving several inline styles to the main CSS, removing unused styles, and simplifying the markup (which let me remove a few <code>div</code> tags – yay!). I added some more spacing between each link so that the lists breathe a bit more.</p><p>We had several ideas on how to keep both lists aligned, but this is something I might explore another day. For now, I am happy with the greater visual cue that the second line of a link is part of the first line afforded by indenting the second line (and subsequent lines) above the first line.</p><p><em>Thank you to everyone who attended Front End Study Hall and shared feedback and ideas related to this design problem.</em></p>
<div class="footnote-definition" id="1"><sup class="footnote-definition-label" id="f-2">1</sup>
<p>Note: The screenshot was taken from an archival copy of my site, so may not be exactly what it looked like on the page, but is close enough.</p>
<a href="https://jamesg.blog/longform-feed#f-1">[↩]</a></div>
<a class="tag" href="https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/text-indent">Per the MDN documentation on text-hanging:</a>
<a class="tag" href="https://gregorlove.com/">gRegor</a>
<a class="tag" href="https://indieweb.org/events/2026-07-16-front-end-study-hall">Front End Study Hall</a>
<a class="tag" href="https://jamesg.blog/longform-feed#1">1</a>
<a class="tag" href="https://jamesg.blog/longform-feed#f-1">[↩]</a>
Mango Nectar Mead Recipe - Cool As Heckhttps://cool-as-heck.blog/mango-nectar-mead-recipe2026-07-16T19:25:00.000Z<h2 id="mango-nectar-mead">Mango Nectar Mead</h2><p><strong>Created:</strong> 2026-07-14<br><strong>Batch Size:</strong> 1 gallon<br><strong>Style:</strong> Melomel (mango)<br><strong>Target ABV:</strong> ~12–14%<br><strong>Original Gravity:</strong> ~1.105 (estimate — confirm with hydrometer)<br><strong>Final Gravity:</strong> ~1.010–1.018 (71B will finish semi-sweet at this OG)</p><hr><h2 id="ingredients">Ingredients</h2><h3 id="base-must">Base Must</h3><ul>
<li value="1">
<strong>Langers Organic Mango Nectar:</strong> 1 gallon jug (minus ~2 cups reserved for topping up)<ul>
<li value="1"><em>20% juice (Alphonso mango puree concentrate + mango puree), filtered water, organic cane sugar</em></li>
<li value="2"><em>528g total sugars per gallon (1.16 lbs fermentable sugar equivalent)</em></li>
<li value="3"><em>Contains citric acid and ascorbic acid (Vitamin C) — no preservative issues for fermentation</em></li>
</ul>
</li>
<li value="2">
<strong>Honey:</strong> 2 lbs (orange blossom or wildflower — light varietal that won't compete with mango)</li>
<li value="3">
<strong>Pectic enzyme:</strong> ½ tsp (optional but recommended for clarity)</li>
</ul><h3 id="yeast-nutrients">Yeast & Nutrients</h3><ul>
<li value="1">
<strong>Yeast:</strong> Lalvin 71B-1122<ul>
<li value="1">Tolerance: ~14% ABV</li>
<li value="2">Partially metabolizes malic acid, softening the citric acid in the nectar</li>
<li value="3">Produces fruity esters that amplify tropical mango character</li>
<li value="4">Ferment at 64–68°F for clean fruit expression</li>
</ul>
</li>
<li value="2">
<strong>Fermaid O:</strong> 6 tsp total (TOSNA 2.0 scaled for ~1.105 OG — 1.5 tsp per addition × 4)</li>
<li value="3">
<strong>Go-Ferm:</strong> 6.25g (for yeast rehydration)</li>
</ul><h3 id="optional-secondary-additions">Optional Secondary Additions</h3><ul>
<li value="1">
<strong>Frozen mango chunks:</strong> 2 lbs in a mesh bag for 2 weeks — the 20% juice nectar won't deliver intense mango on its own; this pushes the fruit character<ul><li value="1"><em>Pull at 14 days max to avoid off-flavors</em></li></ul>
</li>
<li value="2">
<strong>Vanilla bean:</strong> 1 split bean in secondary for 7–10 days for a mango-vanilla creamsicle vibe</li>
<li value="3">
<strong>Allspice:</strong> ¼ tsp whole allspice in secondary for 7 days (tropical spice accent, go light)</li>
</ul><hr><h2 id="estimated-og-breakdown">Estimated OG Breakdown</h2><figure class="lexxy-content__table-wrapper"><table><tbody>
<tr>
<th class="lexxy-content__table-cell--header"><p>Ingredient</p></th>
<th class="lexxy-content__table-cell--header"><p>Amount</p></th>
<th class="lexxy-content__table-cell--header"><p>Gravity Contribution</p></th>
</tr>
<tr>
<td><p>Mango nectar sugars</p></td>
<td><p>1.16 lbs equivalent</p></td>
<td><p>~53 pts</p></td>
</tr>
<tr>
<td><p>Honey</p></td>
<td><p>2 lbs</p></td>
<td><p>~70 pts</p></td>
</tr>
<tr>
<td><p><strong>Total (1 gal)</strong></p></td>
<td><p><br></p></td>
<td><p><strong>~1.123</strong></p></td>
</tr>
</tbody></table></figure><p><em>Estimate may run high — the nectar is mostly water with dissolved sugars, so actual OG depends on mixing. Expect 1.100–1.123 range. Confirm with hydrometer on brew day and adjust honey if needed.</em></p><hr><h2 id="process">Process</h2><h3 id="day-0-must-preparation">Day 0 — Must Preparation</h3><ol>
<li value="1">
<strong>Reserve nectar:</strong> Pour ~2 cups of nectar into a sanitized container and set aside.</li>
<li value="2">
<strong>Mix must:</strong> Pour remaining nectar into fermentation vessel. Warm honey slightly (hot water bath, not boiling) to pour easily, add to vessel. Shake/stir vigorously for 2–3 minutes to dissolve and aerate.</li>
<li value="3">
<strong>Top up:</strong> Add reserved nectar to reach 1 gallon total volume. Take OG reading.</li>
<li value="4">
<strong>Rehydrate yeast:</strong> 6.25g Go-Ferm in 125mL water at 104°F. Let cool to ~100°F, pitch yeast. Wait 15–20 minutes, then temper with small amounts of must (5-minute intervals) until within 10°F of must temp before pitching.</li>
<li value="5">
<strong>Pectic enzyme:</strong> Add ½ tsp at pitch (or 12 hours before if you want to be thorough).</li>
<li value="6">
<strong>Pitch yeast</strong> and aerate again briefly.</li>
</ol><h3 id="fermentation-schedule-tosna-day-0-pitch-day">Fermentation Schedule (TOSNA — Day 0 = pitch day)</h3><figure class="lexxy-content__table-wrapper"><table><tbody>
<tr>
<th class="lexxy-content__table-cell--header"><p>Day</p></th>
<th class="lexxy-content__table-cell--header"><p>Action</p></th>
</tr>
<tr>
<td><p>0</p></td>
<td><p>Pitch yeast, aerate vigorously</p></td>
</tr>
<tr>
<td><p>1</p></td>
<td><p>Add 1.5 tsp Fermaid O, stir gently to degas</p></td>
</tr>
<tr>
<td><p>2</p></td>
<td><p>Add 1.5 tsp Fermaid O, stir gently to degas</p></td>
</tr>
<tr>
<td><p>3</p></td>
<td><p>Add 1.5 tsp Fermaid O, stir gently to degas</p></td>
</tr>
<tr>
<td><p>4</p></td>
<td><p>Add 1.5 tsp Fermaid O, stir gently to degas (or at 1/3 sugar break — whichever comes first)</p></td>
</tr>
</tbody></table></figure><h3 id="primary-fermentation-days-0-14">Primary Fermentation (Days 0–14)</h3><ul>
<li value="1">
<strong>Temperature:</strong> 64–68°F — cooler end preserves mango aromatics; above 72°F risks fusels</li>
<li value="2">Airlock should show active bubbling within 24–48 hours</li>
<li value="3">Stir gently during nutrient additions to degas CO₂</li>
<li value="4">71B is a steady, moderate fermenter — expect a controlled fermentation, not explosive</li>
<li value="5">
<strong>If adding frozen mango in primary:</strong> Place in mesh bag, remove by Day 10 or when gravity hits ~1.040</li>
</ul><h3 id="secondary-fermentation-weeks-3-12">Secondary Fermentation (Weeks 3–12)</h3><ul>
<li value="1">Rack off lees when gravity stabilizes (~2–3 weeks)</li>
<li value="2">
<strong>Optional mango:</strong> Add 2 lbs frozen mango chunks in mesh bag for 10–14 days. Taste at Day 10.</li>
<li value="3">
<strong>Optional vanilla:</strong> Add 1 split bean after pulling mango. Taste at 7 days.</li>
<li value="4">Top up with reserved mead or similar wine to minimize headspace</li>
<li value="5">Bulk age 2–3 months minimum — mango flavor fades during primary but returns during aging</li>
</ul><h3 id="packaging-week-12">Packaging (Week 12+)</h3><ul>
<li value="1">
<strong>FG target:</strong> ~1.010–1.018 (semi-sweet — residual sugar supports the mango character)</li>
<li value="2">
<strong>Taste and adjust:</strong> The nectar already has citric acid; taste before adding any acid blend</li>
<li value="3">
<strong>Bottle:</strong> Still is traditional, but a light sparkle (¾ tsp corn sugar per bottle) works with tropical meads</li>
<li value="4">
<strong>Aging:</strong> Drinkable at 3 months, peaks at 6–9 months</li>
</ul><hr><h2 id="yeast-considerations">Yeast Considerations</h2><figure class="lexxy-content__table-wrapper"><table><tbody>
<tr>
<th class="lexxy-content__table-cell--header"><p>Yeast</p></th>
<th class="lexxy-content__table-cell--header"><p>Why / Why Not</p></th>
</tr>
<tr>
<td><p><strong>71B-1122</strong> ✅</p></td>
<td><p>Metabolizes malic acid → softens citric tang from the nectar. Fruity esters amplify mango. 14% tolerance → finishes semi-sweet, which suits mango.</p></td>
</tr>
<tr>
<td><p>QA23</p></td>
<td><p>Tropical ester bomb with passion fruit/mango notes. 16% tolerance → would finish drier. Solid backup if you want a crisper mead.</p></td>
</tr>
<tr>
<td><p>D47</p></td>
<td><p>Temp-sensitive (needs <68°F). Good mouthfeel but no tropical ester production. Fine for traditionals, wrong for mango.</p></td>
</tr>
<tr>
<td><p>EC-1118</p></td>
<td><p>18% tolerance → bone-dry finish, strips mango character. Would need heavy backsweetening.</p></td>
</tr>
<tr>
<td><p>K1-V1116</p></td>
<td><p>Neutral workhorse, 18% tolerance. Won't contribute fruit-forward esters.</p></td>
</tr>
<tr>
<td><p>Voss Kveik</p></td>
<td><p>Citrusy/earthy ale esters clash with mango. Needs 80°F+. Wrong profile.</p></td>
</tr>
</tbody></table></figure><hr><h2 id="notes">Notes</h2><p><strong>Low juice content (20%):</strong> This nectar is mostly sweetened water with mango concentrate. The mango character won't be as intense as fermenting on real fruit. The optional 2 lbs frozen mango in secondary is strongly recommended for authentic mango flavor.</p><p><strong>The "organic flavor" ingredient:</strong> Unknown composition. 99% it's fine for fermentation, but if the must stalls unexpectedly, this would be the first suspect. The ascorbic acid and citric acid are non-issues — they're common mead additives.</p><p><strong>No water added:</strong> This recipe uses the nectar as the complete liquid base (no dilution). The nectar is already mostly water (80%), so it functions as the must liquid. If you want a lighter session mead, dilute 50/50 with water and use 1 lb honey instead — OG ~1.085, ~11% ABV.</p><p><strong>Sugar from nectar:</strong> 528g total sugars (368g added cane sugar + ~160g natural mango sugars). This is roughly equivalent to 1.16 lbs of fermentable sugar already dissolved in 1 gallon of liquid — treat it as built-in gravity points, not as a separate honey addition.</p>Weeknote #2009 - Robb Knight • Posts • Atom Feedhttps://rknight.me/blog/weeknote-2009/2026-07-16T18:41:50.000Z<p>I backed <a href="https://www.kickstarter.com/projects/antou/penn-minimal-by-design-built-for-versatile-writing">this pen Kickstarter</a> despite breaking my rule of no hardware Kickstarters - the company, Antou, seem to know what they're doing but we'll see. They have a lot of nice stuff on their site including <a href="https://antou1010.com/product/w-paperweight-s/">this pen rest</a>. The pen should be arriving in August some time.</p>
<p><a href="https://pica.joshpuckett.me/">Pica</a> is a new font management app that looks great and it's free. I need to get a handle on all the fonts I have.</p>
<p>I'm not a font designer but if I was I might need to make proofs and <a href="https://hellbox.com/">Hellbox</a> is the one.</p>
<p>Two fascinating fonts I came across: <a href="https://franktisellano.github.io/datatype/index.html">Datatype</a> is a "<em>variable font that turns text into charts</em>" and then this person <a href="https://medium.com/@kosalsen/how-i-built-a-chess-rendering-engine-inside-an-opentype-font-27e4a4d520e7">built a chess rendering engine into a font</a> which is wild.</p>
<p><a href="https://mattstein.com/thoughts/handwriting-font/">Matt did a handwriting font</a>, something I've done a couple of times to varying levels of success.</p>
<p>The last font and writing link is this post about <a href="https://mmapped.blog/posts/52-backtrack-free-cursive">backtrack-free cursive</a>. I don't write cursive (or in lowercase for that matter) but this is really interesting.</p>
<p>What intrigued me about <a href="https://github.com/zakirullin/files.md">files.md</a> is that it uses <a href="https://developer.mozilla.org/en-US/docs/Web/API/File_System_API">an API I wasn't aware of</a> to access local folders and files. I'm not dropping Obsidian any time soon but this is an API I want to try out more.</p>
<p>Friend of the blog made <a href="https://equinox.netigen.com/">equinox</a> to test light and dark mode at the same time which is handy.</p>
<p>I'd come across but not heard of <a href="https://xyproblem.info/">the XY problem</a> before: "<em>asking about your attempted solution rather than your actual problem</em>". Nice to have a name for this scenario.</p>
<p><a href="https://p4lette.app/#p=225d51-447a2a-b37c34-dd61a5-c8b0f6">P4LETTE</a> is another colour palette generator. Can't have too many.</p>
<p>Daily games is <em>a thing</em> now and I've been enjoying <a href="https://4x3.fun">4x3</a>. I also found <a href="https://gerrymandle.com/">Gerrymandle</a> which is interesting but doesn't spark joy for me.</p>
<p><a href="https://www.map.signalbox.io/">Signalbox</a>, a live train map, does spark joy though.</p>
<p>Finally this is a fun article about using <a href="https://dhester.me/exploring-public-domain-image-archive-for-art-ideas">public domain image archive for art ideas</a>.</p>Finished reading Wasteland Warlords 6 - Molly White's activity feed6a5915fe91f30f1ebee0fc212026-07-16T17:33:50.000Z<article class="entry h-entry hentry"><header><div class="description">Finished reading: </div></header><div class="content e-content"><div class="book h-entry hentry"><a class="book-cover-link" href="https://www.mollywhite.net/reading/books?search=Wasteland%20Warlords%206"><img class="u-photo book-cover" src="https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1701969628i/203421139.jpg" alt="Cover image of Wasteland Warlords 6" style="max-width: 300px;"/></a><div class="book-details"><div class="top"><div class="series-info"><i>Wasteland Warlords</i> series, book <span class="series-number">6</span>. </div><div class="title-and-byline"><div class="title"><i class="p-name">Wasteland Warlords 6</i> </div><div class="byline">by <span class="p-author h-card">James A. Hunter</span> and <span class="p-author h-card">Eden Hudson</span>. </div></div><div class="book-info">Published <time class="dt-published published" datetime="2024">2024</time>. 158 pages. </div></div><div class="bottom"><div class="reading-info"><div class="reading-dates"> Started <time class="dt-accessed accessed" datetime="2026-07-12">July 12, 2026</time>; completed July 15, 2026. </div></div></div></div></div><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <time class="dt-published" datetime="2026-07-16T17:33:50+00:00" title="July 16, 2026 at 5:33 PM UTC">July 16, 2026 at 5:33 PM UTC</time>. </div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=fantasy" title="See all books tagged "fantasy"" rel="category tag">fantasy</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=humor" title="See all books tagged "humor"" rel="category tag">humor</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=litrpg" title="See all books tagged "litRPG"" rel="category tag">litRPG</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=post_apocalyptic" title="See all books tagged "post-apocalyptic"" rel="category tag">post-apocalyptic</a>. </div></div></footer></article>📝 2026-07-16 17:05: Anyone using Pop!OS with Cosmic? I tried it when it was first released, but I... - Kev Quirkhttps://kevquirk.com/2026-07-16-17052026-07-16T16:05:00.000Z<p>Anyone using <a href="https://system76.com/pop" rel="noopener noreferrer">Pop!_OS</a> with Cosmic? I tried it when it was first released, but I looks like they've done a lot of dev work to it and it's improving all the time.</p>
<p>Considering installing it again...</p> <div class="email-hidden">
<hr />
<p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p>
<p>You can <a href="mailto:19gy@qrk.one?subject=%F0%9F%93%9D%202026-07-16%2017%3A05">reply to this post by email</a>, or <a href="https://kevquirk.com/2026-07-16-1705#comments">leave a comment</a>.</p>
</div>Gadget Review: Thermal Master DV2 - Infrared Birdwatching Scope ★★★★⯪ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=730592026-07-16T11:34:50.000Z<p>The good folks at Thermal Master have sent me their <a href="https://thermalmaster.com/en-gb/products/thermal-master-dv2?utm_source=PR&utm_medium=MEDIA&utm_campaign=Terence+Eden%E2%80%99s+Blog_DV2">DV2 camera</a> to review. As their name suggests, this is a thermal / infrared camera - they've specifically designed this for bird watching and animal spotting. Let's put it through its paces and see how it compares to the competition!</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/DV2.webp" alt="A handheld camera with a pivoted screen." width="900" height="900" class="aligncenter size-full wp-image-73069">
<p>Straight away you can see it is different from normal IR cameras - they tend to have a small fixed screen and a rubber button interface. This has a lush touchscreen which displays the thermal image and is used to control the camera. The screen can go bright enough to be easily visible in full daylight, and you can dim it down to something more appropriate for night-time viewing.</p>
<p>OK, enough waffle, time to get snapping!</p>
<h2 id="photos"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#photos">Photos</a></h2>
<p>Here are some shots from the camera of various bits of wildlife near me. I haven't edited these images, they're exactly what you get from the camera.</p>
<p><a href="https://shkspr.mobi/blog/wp-content/uploads/2026/07/cat.jpg"><img src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/cat.jpg" alt="A cat walking away from the camera." width="512" height="384" class="aligncenter size-full wp-image-73134"></a></p>
<p>The resolution is 512x384. There's no EXIF metadata - so no location information.</p>
<p><a href="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Bird-Tree.jpg"><img src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Bird-Tree.jpg" alt="A bird in the tree." width="512" height="384" class="aligncenter size-full wp-image-73135"></a></p>
<p>There's also no in-picture thermal gradient so you can't see the exact temperature of an object. This is designed for spotting animals, not working out how hot your electronics are. The datetime is burned in to the image but can be turned off.</p>
<p>It has the ability to almost totally remove the background "noise" of the sky - making it excellent for spotting things on the wing.</p>
<p><a href="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Bird-Sky.jpg"><img src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Bird-Sky.jpg" alt="A white object silhouetted against the sky." width="512" height="384" class="aligncenter size-full wp-image-73136"></a></p>
<p>Filesize is about 20KB per photo. So you can fit will over a million images on the ~32GB internal storage. Digital zoom goes up to 8X.</p>
<h2 id="videos"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#videos">Videos</a></h2>
<p>The static images don't really do it justice. It's also possible to shoot video. This gives you a reasonable idea of what you'll see on the touchscreen.</p>
<p><video width="512" height="384" src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/bird-flying.mp4" loop="" autoplay="" muted=""></video></p>
<p>Video resolution is the same as the photos - 512x384 - and runs at 30fps. File size is around 40MB per minute. So about 12 hours of footage can be stored. I've re-encoded these videos to be smaller while keeping the same quality.</p>
<p>Here's a friendly fox I found - I've cycled through the various settings so you can see how they work.</p>
<p></p><div style="width: 512px;" class="wp-video"><video class="wp-video-shortcode" id="video-73059-4" width="512" height="384" preload="metadata" controls="controls"><source type="video/mp4" src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Fox1.mp4?_=4"><a href="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Fox1.mp4">https://shkspr.mobi/blog/wp-content/uploads/2026/07/Fox1.mp4</a></video></div><p></p>
<p>Again, as with the photos, there's no metadata and the datetime is burned in. Here are a couple of cats playing around in the park.</p>
<p></p><div style="width: 512px;" class="wp-video"><video class="wp-video-shortcode" id="video-73059-5" width="512" height="384" preload="metadata" controls="controls"><source type="video/mp4" src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat1.mp4?_=5"><a href="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat1.mp4">https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat1.mp4</a></video></div><p></p>
<p>Twisting the lens allows you to adjust the focus - it is really impressive the amount of detail it can pick up.</p>
<p></p><div style="width: 512px;" class="wp-video"><video class="wp-video-shortcode" id="video-73059-6" width="512" height="384" preload="metadata" controls="controls"><source type="video/mp4" src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat2-Focus.mp4?_=6"><a href="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat2-Focus.mp4">https://shkspr.mobi/blog/wp-content/uploads/2026/07/Cat2-Focus.mp4</a></video></div><p></p>
<p>There's no video stabilisation (use the tripod mount if you need it) and there's no audio.</p>
<h3 id="rtsp"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#rtsp">RTSP</a></h3>
<p>You can also stream the video to a computer, VLC, or anything else which will take an RTSP stream.</p>
<p>The URl will be <code>rtsp://[IP Address]:8554/ch0</code> - that will get you a 20fps stream of exactly what the camera is seeing.</p>
<h2 id="range-and-detection"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#range-and-detection">Range and Detection</a></h2>
<p>It reckons it'll detect a human's heat signature from around 900 metres away.</p>
<p>There are several modes which will let you see more or less detail. That's particularly important if you're just interested in the hottest part of the image, or if you need to photograph something against a relatively warm background.</p>
<h2 id="the-app"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#the-app">The App</a></h2>
<p>This'll pair with your Android phone using the <a href="https://play.google.com/store/apps/details?id=com.thermalmaster.p2telephoto">Thermal Masters app</a>. It's a bit of a beast - around 200MB. That's because it's the same app for all their cameras and contains PDFs for several different models. Despite the relatively high download numbers, it has zero reviews.</p>
<p>Like lots of software from hardware manufacturers, the app is basic but serviceable. It connects to your DV2 via WiFi. You can either be on the same network or connect the camera to your phone's hotspot.</p>
<p>Looking through the app's code, it appears to use OpenCV, ffmpeg, and some other popular Open Source libraries. Sadly, the required attribution is missing.</p>
<p>The app is great for monitoring the camera, you can zoom in on the image and fiddle with some of the settings. But you can't actually trigger a photo or video recording! That's a bit annoying.</p>
<h2 id="linux"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#linux">Linux</a></h2>
<p>For our penguin powered friends, this shows up as <code>1f3a:1000</code> "Allwinner Technology Prestigio PER3464B ebook reader (Mass storage mode)". It's a basic drive which lets you copy the media back to your computer via USB-C. Easy as.</p>
<h2 id="comparison"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#comparison">Comparison</a></h2>
<p>So how does it compare to the <a href="https://shkspr.mobi/blog/2026/02/gadget-review-topdon-ts004-thermal-monocular/">Topdon TS004 Thermal Camera</a>? The Topdon is also marketed at the bird-spotting crowd and, on the surface, has fairly similar features.</p>
<p>The most obvious difference is the user interface. The TS004 is a Monocular - so you need to shove your eye into the end to see anything.</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/topdon.webp" alt="Photo of a dark green tube with various buttons on it. It fits snugly in the hand." width="1024" height="1024" class="aligncenter size-full wp-image-67746">
<p>With the DV2, you've got a big screen to look at - which is generally much more pleasant. That display of the DV2 is a touchscreen which makes it pretty easy to interact with - whereas with the TS004 you have to repeatedly mash buttons to change any settings.</p>
<p>In terms of resolution, both have a standard 256×192 sensor. The upscaling on the DV2 is good - but doesn't fundamentally change how much thermal information there is.</p>
<p>But it is the thoughtful little extras which make the DV2 useful. There's a built-in laser pointer which is useful for working out exactly what you're aiming at. At the bottom is a standard tripod mount, so you can rig it up somewhere to monitor an area.</p>
<p>Slightly bizarrely, it comes with an optional <a href="https://gun-data.com/what-is-a-picatinny-rail/">Picatinny Rail</a> adaptor. That screws into the side of your DV2 and allows you to add firearm accessories! So if you ever wanted to add a sniper scope to your thermal camera…</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/Picatinny.webp" alt="Camera with a range finder attachment." width="1024" height="760" class="aligncenter size-full wp-image-73080">
<p>Alright, a regular range-finder will also attach to it 😆</p>
<p>The battery is a bit of an odd one. You can physically remove the battery and place it in its own USB charger. The battery is a <a href="https://www.aliexpress.com/s/wiki-ssr/article/1inr22-71">1INR22/71</a> which is a chunky beast. The charger comes with two slots (although only one battery is included) so you can quick-swap to a full battery if you need to. There is a USB-C port on the bottom, if you want to charge it the normal way.</p>
<p>With the TS004, the only way to stream video was via the app. The DV2 will connect to any WiFi network and present an RTSP stream.
The built in WiFi is useful for grabbing firmware updates.</p>
<p>The DV2 also suffers a little from the lack of a trigger button for taking photos. When held in the hand, it feels natural to click the button under the thumb finger - instead, that toggles the laser. Taking a photo means tapping away on the screen to get to a sub-menu. Annoyingly, your phone can't be used as a remote control.</p>
<p>One thing in the TS004's advantage - it's lens cap is attached to the body of the unit. The DV2's is a separate rubber cap which comes off completely. Best remember to stick it in the supplied carrying case, eh?</p>
<p>The TS004 also has built-in animal recognition. It can detect heat signatures and tell you if they're a bird or a human. However, it always misidentified English foxes as Wild Boars! So was of limited use.</p>
<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/02/Wild-Boar.jpg" alt="Thermal image. A dog-shaped object glows. It is labelled "Wild Boar"." width="640" height="480" class="aligncenter size-full wp-image-67741">
<p>The DV2 uses AI to upscale the quality of the images rather than trying to detect what it is actually looking at.</p>
<p>In general, the DV2 is easier to use and produces seemingly better quality media. But having to tap the screen multiple times to take a photo or video is slightly annoying.</p>
<h2 id="price"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#price">Price</a></h2>
<p>All the infrared cameras I've reviewed have been expensive. This one is no different. At the moment it is in stock for £459.</p>
<p>You can use the code <code>THERMBIRD10</code> for 10% off at <a href="https://thermalmaster.com/en-gb/products/thermal-master-dv2?utm_source=PR&utm_medium=MEDIA&utm_campaign=Terence+Eden%E2%80%99s+Blog_DV2">the official store</a> or from <a href="https://www.amazon.com/dp/B0GTY1P6BT">Amazon.com</a>.</p>
<p>That's a chunk of change - but you do get a <em>lot</em> of tech for the price. This isn't designed for finding hotspots in your home, it's excels at picking out wildlife - and the screen is big enough for several people to gather round to see what you've spotted.</p>
<h2 id="final-thoughts"><a href="https://shkspr.mobi/blog/2026/07/gadget-review-thermal-master-dv2-infrared-birdwatching-scope/#final-thoughts">Final Thoughts</a></h2>
<p>This is one of the better thermal imaging devices that I've reviewed. The large touchscreen makes it so much easier to control than anything else on the market - all the others have squishy rubber buttons. It is mostly a delight to use, if you can put up with the slightly strange process of taking a photo.</p>
<p>Thermal cameras are still very expensive - the sensors are low resolution and sometimes flaky. The DV2 does a great job of producing a usable images and videos.</p>
<p>The app is no worse than the competition. It really ought to inform users about the use of Open Source code though.</p>
<p>The addition of the laser pointer isn't as gimmicky as I'd thought. I've no use for the Picatinny attachment, but I can see how it could be useful.</p>
<p>If you want to go wildlife spotting, this is probably the device to get. It captures an incredible amount of detail and is excellent at picking up the faintest heat signatures.</p>
<iframe title="📖 New to DV2? We&apos;ve got you covered!" width="620" height="349" src="https://www.youtube.com/embed/uQbjc2hpLZM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen=""></iframe>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=73059&HTTP_REFERER=Atom" alt width="1" height="1" loading="eager">📝 2026-07-16 11:47: A few of us were talking to one of the summer interns at work about... - Kev Quirkhttps://kevquirk.com/2026-07-16-11472026-07-16T10:47:00.000Z<p>A few of us were talking to one of the summer interns at work about age:</p>
<p><strong>Someone:</strong> How old do you think Kev is?</p>
<p><strong>Intern:</strong> [with all the confidence in the world] 50?</p>
<p>I turn 42 in August. FML. 🤣</p> <div class="email-hidden">
<hr />
<p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p>
<p>You can <a href="mailto:19gy@qrk.one?subject=%F0%9F%93%9D%202026-07-16%2011%3A47">reply to this post by email</a>, or <a href="https://kevquirk.com/2026-07-16-1147#comments">leave a comment</a>.</p>
</div>Re: An IndieWeb Event for Southeast Asia / Pacific Time Zones - James' Coffee Bloghttps://jamesg.blog/2026/07/16/indieweb-asia-pacific2026-07-16T00:00:00.000Z
<p><a href="https://burgeonlab.com/rsvps/2026/0715-1415/" rel="noreferrer">Naty is hosting a new Homebrew Website Club</a> event on Wednesday, August 5, 2026, at 5:30pm to 7:00pm Hong Kong Time (UTC+8). If there is interest, the event may turn become regular!</p><p>If the time works for you and you love chatting about websites, I recommend checking out the event. Homebrew Website Clubs are always fun, providing a place to chat about what people are building on their websites, the culture of the web, HTML/CSS, writing on the web, and more.</p><p>This event adds to several other online events, geared toward:</p><ul><li><a href="https://events.indieweb.org/2026/07/homebrew-website-club-europe-london-C7hLAVUWvWxs" rel="noreferrer">European timezones (HWC London/Europe)</a> (which I host!)</li><li><a href="https://events.indieweb.org/tag/eastern" rel="noreferrer">The US East Coast (HWC Eastern)</a></li><li><a href="https://events.indieweb.org/tag/pacific" rel="noreferrer">The US West Coast (HWC Pacific)</a></li></ul><p>Furthermore, there are in-person events that happen in several cities listed on the <a href="https://events.indieweb.org/" rel="noreferrer">IndieWeb Events community page</a>, and the <a href="https://blr.indiewebclub.org/" rel="noreferrer">IndieWebClub Bangalore website</a>, all of which are run to provide a place to chat for people passionate about websites.</p><script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a1c35a2bdf86f09c',t:'MTc4NDIyOTUwMA=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
<a class="tag" href="https://blr.indiewebclub.org/">IndieWebClub Bangalore website</a>
<a class="tag" href="https://burgeonlab.com/rsvps/2026/0715-1415/">Naty is hosting a new Homebrew Website Club</a>
<a class="tag" href="https://events.indieweb.org/">IndieWeb Events community page</a>
<a class="tag" href="https://events.indieweb.org/2026/07/homebrew-website-club-europe-london-C7hLAVUWvWxs">European timezones (HWC London/Europe)</a>
<a class="tag" href="https://events.indieweb.org/tag/eastern">The US East Coast (HWC Eastern)</a>
<a class="tag" href="https://events.indieweb.org/tag/pacific">The US West Coast (HWC Pacific)</a>