<p>Drop <a href="/tags/562/" rel="tag">#562</a> (2024-11-26): Typography Tuesday</p><p>The Type Archive; Advent Of Fonts; Free Font: Perfect Moment</p><p><p>Programming note: Today is my “Friday”, and <a href="/tags/2/" rel="tag">#2</a>.1 + <a href="/tags/2/" rel="tag">#2</a>.2 are in town, so Drops may be thin or non-existent the remainder of the week.</p></p><p>History, seasonal celebrations, and a freebie await Drop readers in this weekly typography-centric edition of the newsletter.</p><p><a href="https://dailydrop.hrbrmstr.dev/?post_type=post&p=139504356" rel="nofollow">Subscribe</a></p><p>TL;DR</p><p>(This is an AI-generated summary of today’s Drop using Ollama + llama 3.2 and a custom prompt.)</p><p>The Type Archive was established in 1992 as a repository for England’s typographic heritage, but it closed in 2022 due to financial struggles and has since been digitized by the Science Museum Group. (<a href="http://www.typearchive.org/" rel="nofollow"><span class="invisible">http://</span>www.typearchive.org/</a>)</p><p>Damien Guard’s <a href="https://damieng.com/typography/advent/2023/" rel="nofollow">2023 Advent of Fonts</a> is a creative exploration of typography and fonts, featuring daily typographic creations throughout December 2023.<br>The free font <a href="https://pixelbuddha.net/fonts/582-free-perfect-moment-handwritten-font" rel="nofollow">Perfect Moment</a> is a brush-style SVG font with dynamic brushstroke textures that captures authentic handcrafted aesthetics.</p><p>The Type Archive</p><p>The <a href="http://www.typearchive.org/" rel="nofollow">Type Archive</a> was established in 1992 by Susan Shaw in Stockwell, South London, as a repository safeguarding England’s rich typographic heritage. For three decades, it housed over 6 million artifacts representing the legacy of type founding, including original forms, punches, matrices, and patterns from England’s most successful metal and wood type foundries.</p><p>The facility maintained a unique operational capability through Monotype Hot-Metal Ltd., where four former Monotype Corporation pensioners manufactured matrices for hot-metal typesetting equipment, serving letterpress printing enthusiasts and commercial firms worldwide. The Archive’s location at Hackford Road in Stockwell had an interesting past – the buildings previously served as Price & King’s veterinary medicine and quarantine station, occasionally housing baby elephants, which inspired Shaw to adopt an elephant as the Archive’s symbol.</p><p>In mid-2022, the <a href="https://www.typeroom.eu/30-years-after-its-foundation-type-archive-is-no-more" rel="nofollow">Type Archive announced its closure</a> and the dispersal of its collections. The Science Museum Group (SMG) took responsibility for the Monotype collection, relocating it to their National Collections Centre near Swindon. The Stephenson Blake collection, temporarily owned by the V&A, was also transferred to SMG’s care. The closure came after years of financial struggles and the inability to fund necessary building repairs and accessibility improvements.</p><p>While the physical archive has closed, the SMG has digitized significant portions of the Monotype Collection, creating over 5,800 records with photographs and insights that remain accessible to the public. The SMG also conducted oral history interviews and filmed documentation with Type Archive volunteers to preserve the knowledge of typefounding manufacture for future generations.</p><p>I mention them, both for historical awareness, and to note they launched a crowd-funded project to produce “<a href="https://vol.co/collections/type-archived" rel="nofollow">Type Archived</a>“, a new book by <a href="https://richardardaghstudio.co.uk/" rel="nofollow">Richard Ardagh</a>, a long-serving Type Archive volunteer, that documents the remarkable story of the TA.</p><p>The book organizes the Archive’s typographic treasures by material — iron, steel, copper, brass, bronze, lead, wood, and paper — showcasing everything from engraved punches (master letters) to matrices (dies for casting) and letterpress type. These artifacts represented supreme mechanical engineering and type design achievements spanning six centuries of Western communication.</p><p>The book features contributions from distinguished practitioners associated with the Archive, including Berthold Wolpe, Quentin Blake, Toshi Omagari, and MinaLima (known for their work on the Harry Potter films). It includes specially commissioned photography, detailed summaries of the Archive’s accomplishments, essays on typefounding techniques, and a comprehensive glossary.</p><p>I’m all sorts of 😊 we will have a nigh-permanent record of this significant institution’s contributions to typography and printing history, thanks to this effort.</p><p>Advent Of Fonts</p><p>We’ve featured works by Damien Guard before, but — with the holiday season fast approaching, I thought this week would be a good time to feature their <a href="https://damieng.com/typography/advent/2023/" rel="nofollow">2023 Advent of Fonts</a>. It’s a creative exploration of typography and fonts, featuring daily typographic creations throughout December 2023. Each day reveals a new typographic piece, making it an fun way to pass the time whilst making merry.</p><p>Rather than blather, go take some time to peruse the collection and Damien’s previous font advent celebrations.</p><p>Free Font: Perfect Moment</p><p><a href="https://pixelbuddha.net/fonts/582-free-perfect-moment-handwritten-font" rel="nofollow">Perfect Moment</a> is a fun-yet-fancy brush-style SVG font that captures authentic handcrafted aesthetics through dynamic brushstroke textures (modern digital font technical features are so cool). The font maintains a fine balance between raw artistic expression and functional legibility, which is pretty handy if you’re trying to evoke some emotional resonance with your craftings.</p><p>The brushstroke implementation captures natural variations and imperfections typically found in hand lettering, creating an believable “painted” appearance. This authenticity is maintained across different sizes (not all fancy fonts have this attention to detail), with the font remaining legible while preserving its distinctive artistic character.</p><p>The font package includes WOFF2, WOFF, EOT, TTF, OTF, and SVG formats in a 31MB bundle, ensuring broad compatibility across platforms while preserving the intricate brush textures that give it its distinctive character.</p><p>FIN</p><p>We all will need to get much, much better at sensitive comms, and <a href="https://signal.org/" rel="nofollow">Signal</a> is one of the only ways to do that in modern times. You should absolutely use that if you are doing any kind of community organizing (etc.). Ping me on Mastodon or Bluesky with a “🦇?” request (public or faux-private) and I’ll provide a one-time use link to connect us on Signal.</p><p>Remember, you can follow and interact with the full text of The Daily Drop’s free posts on Mastodon via <span class="h-card"><a href="https://dailydrop.hrbrmstr.dev" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>dailydrop.hrbrmstr.dev</span></a></span> ☮️</p><p><a href="/tags/2/" rel="tag">#2</a></p>
2
<p>Drop <a href="/tags/720/" rel="tag">#720</a> (2025-10-20): Back In The Highlight Again</p><p>logalize; ch; Lexical Differential Highlighting;</p><p>No Bonus Drop this past weekend due to <a href="/tags/nokings/" rel="tag">#NoKings</a>, hayrides with the grandkids, and <a href="/tags/2/" rel="tag">#2</a>.1’s 4th birthday celebration.</p><p>We revisit a sparse, reoccurring theme of “highlighting” in today’s Drop, only one of which is source code-related.</p><p>Type your email…</p><p>Subscribe</p><p>TL;DR</p><p>(This is an LLM/GPT-generated summary of today’s Drop. This week, I’m playing with Ollama’s “cloud” models for fun and for $WORK (free tier, so far), and gave gpt-oss:120b-cloud a go with the Zed task. Even with shunting context to the cloud and back, the response was almost instantaneous. They claim to now keep logs, context, or answers, but I need to dig into that a bit more.)</p><p>Logalize provides a fast, extensible YAML‑configured log colorizer that lets you define formats, patterns, words and themes to highlight logs as they stream (<a href="https://github.com/deponian/logalize" rel="nofollow"><span class="invisible">https://</span>github.com/deponian/logalize</a>)<br>ch is a tiny Go utility that highlights specified words in a live text stream without regex or config, letting you color‑code errors, warnings, etc., on the fly (<a href="https://github.com/dtonon/ch" rel="nofollow"><span class="invisible">https://</span>github.com/dtonon/ch</a>)<br>Lexical Differential Highlighting colors tokens based on a hash of their characters, making visually similar code elements distinct without parsing, as described in the 2019 Words and Buttons post (<a href="https://wordsandbuttons.online/lexical_differential_highlighting_instead_of_syntax_highlighting.html" rel="nofollow" class="ellipsis" title="wordsandbuttons.online/lexical_differential_highlighting_instead_of_syntax_highlighting.html"><span class="invisible">https://</span><span class="ellipsis">wordsandbuttons.online/lexical</span><span class="invisible">_differential_highlighting_instead_of_syntax_highlighting.html</span></a>)</p><p>logalize</p><p>Logs can be brutal to read. Endless lines of monochrome text flying by, each one daring you to spot the anomaly before it scrolls offscreen. <a href="https://github.com/deponian/logalize" rel="nofollow">Logalize</a> exists, ostensibly, to make that pain go away. It’s a fast, extensible log colorizer that seeks to turn chaos into clarity.</p><p>Most log colorizers are more opinionated than even I am. They assume they know what matters to you, hardcoding patterns that can’t be changed. Logalize flips that script with a (ugh) YAML configuration file that defines everything: formats, patterns, word groups, and themes. You don’t just get to tweak a theme; you can rewire the logic of how lines are parsed and painted. Want to colorize only certain HTTP status codes or match your own custom app logs? Write it once in logalize.yaml (hey, no tool is perfect) and it just works.</p><p>When Logalize runs, it reads one line at a time, stripping out any ANSI noise, and checking if the line matches a full format you’ve defined. If it doesn’t, it takes a furthe look for regex patterns or specific words to highlight. So, context matters! Its <a href="https://en.wikipedia.org/wiki/Lemmatization" rel="nofollow">lemmatizer</a> even understands that “completed” is just “complete” in disguise. It can also flip meaning when negations show up, so “not successful” is treated like “failure.”</p><p>You describe what’s important using four concepts. Formats define entire lines, like a full Apache access log entry. Patterns are flexible regex snippets for things like IPs or UUIDs. Words are for smart keyword highlighting, backed by lemmatization and negation logic. Themes define how all of that looks—foregrounds, backgrounds, and styles—with colors expressed in hex or ANSI codes. Together, they form an extensive and coherent color grammar for your logs.</p><p>Installation is refreshingly boring as packages exist for Debian, Fedora, Arch, and macOS (via Homebrew). Go folks can grab it straight from source. Once installed, pipe your logs through it and watch the noise disappear: cat app.log | logalize. You can choose from built-in themes like tokyonight-dark, or disable all defaults to work only with your own definitions.</p><p>If you “live in logs” and have not checked this one out yet, I’d suggest carving out 15 minutes to give it a go.</p><p>ch</p><p><a href="https://github.com/dtonon/ch" rel="nofollow">ch</a> is a tiny Go project that’s simple by design. It doesn’t parse logs, it doesn’t do fancy regexes, and it doesn’t pretend to know what your app is doing. It just sits quietly in a pipeline and paints the words you care about as they go by. That’s it. And that’s also enough to make it a mandatory add to the default-install toolbox.</p><p>You feed it a stream of text, say from tail -f, docker logs -f, or journalctl -f, and then tell it what to watch for. Maybe you want “error,” “warning,” and “success” to pop. You run something like:</p><p>tail -f app.log | ch error warning success</p><p>and your terminal feels instantly more dapper. Those tiny bursts of color are like meatspace highlighters sliding across a textbook. This textbook, however, is on fire and the highlighters beep when things get bad. (There’s actually a flag for that now: -a makes ch emit a little ding whenever it sees a match. The author added that in October!)</p><p>ch never gets in your way. No regex tax unless you want it. No elaborate YAML config. It’s for the moments when grep –color isn’t enough, and <a href="https://github.com/deponian/logalize" rel="nofollow">logalize</a> feels like overkill. It’s just: “show me what I care about, right now, while it’s happening.”</p><p>Installing it is a (hacky) one-liner if you’ve got Go:</p><p>git clone <a href="https://github.com/dtonon/ch" rel="nofollow"><span class="invisible">https://</span>github.com/dtonon/ch</a> && cd ch && go build -o ch && sudo mv ch /usr/local/bin/</p><p>After that, it’s your terminal’s new bff. You can tell it to use background colors with -b, make matches case-sensitive with -s, and give specific colors to specific tokens. Something like:</p><p>ch -b error::red warning::orange info::00FF00</p><p>Colors have names (red, green, orange, blue, pink, purple) or you can use hex codes if you’re fancy. It’s all ANSI under the hood, so it works anywhere you’d normally see colored output. If your pipeline suddenly stops showing output, that’s probably because your command started buffering. On macOS, wrap it with script -q /dev/null or expect’s <a href="https://manpages.debian.org/stretch/expect/unbuffer.1.en.html" rel="nofollow">unbuffer</a>; on Linux, stdbuf -oL usually does the trick.</p><p>ch supports “presets”, and these ones seem to work well for different kinds of streams:</p><p># journalctl: show system weirdnessalias chsys='journalctl -f | ch -b error::red fail::red warn::orange critical::purple info::blue'# nginx: see slow or scary traffic in coloralias chweb='tail -f /var/log/nginx/access.log | ch -b 500::red 404::orange 200::green POST::blue GET::purple'# general-purpose log watcheralias chw='stdbuf -oL "$@" | ch -b error::red warn::orange fail::red success::green info::blue'</p><p>You’ll find yourself creating your own presets in no time.</p><p>We need way more focused, small utilities like this, and far fewer vibe-coded nightmare ones.</p><p>Lexical Differential Highlighting</p><p>Thanks to <a href="https://wordsandbuttons.online/lexical_differential_highlighting_instead_of_syntax_highlighting.html" rel="nofollow">a 2019 post</a> by <a href="https://www.simonandschuster.com/authors/Oleksandr-Kaleniuk/198550917" rel="nofollow">Oleksandr Kaleniuk</a> that recently surfaced back into the zeitgeist, I learned about something called “Lexical Differential Highlighting” (LDH). It’s a highlighting technique that makes no effort to try to understand your code the way traditional syntax highlighting does. It cares not a whit what’s a “keyword” or what’s a “variable”. Instead, it leans into how our eyes and brains actually work when we’re reading code.</p><p>Traditional syntax highlighting paints categories. It tells us what kind of thing each word is supposed to be. But that doesn’t help much when two tokens look almost the same yet do wildly different things. A great example Kaleniuk gives is trying to tell the difference between pmulhw and pmulhuw in assembly. In traditional highlighting idioms, they get the same color, so you end up reading letter by letter, hoping you don’t mistake one for the other.</p><p>LDH flips the logic. It says, “If two tokens look similar, make them look very different”. The whole point is to help our eyes see what our brains need to notice, which is the difference between the tokens. Tokens that already look distinct can share colors. That’s the inverse of traditional highlighting, and it’s pretty effective.</p><p>It turns out implementing LDH is super straightforward. You tokenize by splitting on the usual suspects (i.e., spaces, operators, whatever). Then you give each token a color derived from a hash of its characters. Oleksandr used a neat trick: summing character codes multiplied by position-based weights [1, 7, 11, 13]. The primes ensure that character order matters, so “abc” and “bca” don’t collide. That’s it. The entire highlighter fits in about 30 lines of code, though after some tests on non-assembly code, I think we’d need to build a slightly smarter one for most modern programming languages.</p><p>It lowers cognitive load when working with dense code (e.g., assembly source files), math-heavy functions, and config files. Our eyes can instantly see that movl and movq aren’t the same, or that %eax isn’t %ecx. And it helps us start recognizing patterns instead of decoding them.</p><p>The general concept works for any language, since the technique doesn’t need to parse or understand. It just needs to make things that look similar appear distinct. Later, the author layered on a hybrid mode, graying out comments and strings so they fade politely into the background while the meaningful tokens pop with difference.</p><p><p>I’m starting to see some academic research that suggests our shunting of comments to the background is the inverse of what we should be doing. More on that in a later Drop.</p></p><p>This small, elegant correction to decades of visual convention is a reminder that sometimes the best tools aren’t necessarily “technically” smarter; they’re just designed better for us humans.</p><p>FIN</p><p>Remember, you can follow and interact with the full text of The Daily Drop’s free posts on:</p><p>🐘 Mastodon via <span class="h-card"><a href="https://dailydrop.hrbrmstr.dev" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>dailydrop.hrbrmstr.dev</span></a></span><br>🦋 Bluesky via <a href="https://bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy" rel="nofollow" class="ellipsis" title="bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy"><span class="invisible">https://</span><span class="ellipsis">bsky.app/profile/dailydrop.hrb</span><span class="invisible">rmstr.dev.web.brid.gy</span></a></p><p>☮️</p><p><a href="/tags/2/" rel="tag">#2</a> <a href="/tags/nokings/" rel="tag">#NoKings</a></p>
<p>Last Week in Fediverse – ep 97</p><p>A new non-profit for governance of Bridgy Fed, PeerTube releases their yearly update with a complete redesign, and the organisation behind Mammoth and sub.club winds down due to a lack of funding.</p><p>Editors note: I’ll be on holiday break for the next two weeks. The next edition of Last Week in Fediverse will be out on January 7th. Thank you for reading and supporting me in 2024!</p></p><p>The News</p><p>A New Social</p><p>A New Social is a new non-profit that <a href="https://www.anew.social/hello-social-web/" rel="nofollow">launched today</a>. The goal of A New Social is to build cross-protocol tools and services for the open social web. The organisation consists of <a href="https://anujahooja.com/" rel="nofollow">Anuj Ahooja</a> (CEO) and <a href="https://snarfed.org/about#been+around" rel="nofollow">Ryan Barrett</a> (CTO). The main project that they will be focused on is <a href="https://fed.brid.gy/" rel="nofollow">Bridgy Fed</a>, the service that lets people connect their social accounts across a variety of networks and protocols.</p><p>Barrett <a href="https://snarfed.org/2024-11-01_53932" rel="nofollow">wrote</a> in early November about the possible futures for Bridgy Fed. Up until now, Bridgy Fed was his personal one-man side project. Conversations with other organisations like Flipboard and Meta gave Barrett a sense of urgency that the project was quickly trending towards becoming critical infrastructure for the open social web. Heated conversations earlier this year about how people should interact with the bridge (opt-in versus opt-out) also made it clear that such a tool should have cohesive governance, where Barrett writes: “it is about who makes those decisions, and how they should be made.” </p><p>Ahooja has come in as the new leader, to help build a structural organisations that can deal with the conversations around governance and decision making. Ahooja describes his vision as that of the <a href="https://www.augment.ink/bridges-the-last-network-effect/" rel="nofollow">‘last network effect</a>‘, which is worth reading in its entirety. In his view, the current state of the open social web is that of the exploratory phase, where neither ActivityPub nor ATProto have yet fully proven themselves at mass scale yet. Protocol bridges such as Bridgy Fed can bridge the gap: not only allows it for compatibility between platforms, it also bridges the gap in time. It allows us to commit to a platform now, without knowing for certain it the protocol that platform uses will be an important protocol in the future. This is possible because with bridged platforms and networks, you can take your own social graph with you.</p><p>In a conversation with Ahooja and Barrett, they say that people have rallied around A New Social very quickly, and that people have been very supportive of the organisation. The organisation has the support of Mastodon, Meta, Bluesky, IFTAS, SWF and Flipboard. It shows that there is a broader awareness that the open social web needs more organisations that are concerned with governance. The ATProto project of <a href="https://github.com/lexicon-community" rel="nofollow">lexicon.community</a> (not affiliated with A New Social) is another such example of people starting to work towards governance of internet infrastructure.</p><p>A New Social is looking to recruit a Board of Directors, as well as reaching out to developers to collaborate on tools and services that are needed for cross-protocol platforms. For development work, the main focus is on making the bridge more accessible and easier to understand: Barrett and Ahooja will be working on making the bridge easier to user with a cleaner UX, as well as on awareness and education what Bridgy Fed actually does. Ahooja is also clear on separating a protocol network from the platforms that make up a network. Each platform has its own culture and policies, and A New Social will be working with each individual platform on what approach to bridging fits their specific platform best. </p><p>Personally I think the fediverse has struggled for a while to make a clearer distinction between the fediverse as a single place and the fediverse as a network of different platforms. For me, the value of the fediverse is in the ability to build connecting platforms that each have their own culture, governance, moderation, and sense of place. A New Social is aware and mindful of this, and their approach of treating each platform as its own space can help further the fediverse towards a true super-network of interconnected digital places.</p></p><p>PeerTube v7</p><p><a href="https://framablog.org/2024/12/17/peertube-v7-offer-a-complete-makeover-to-your-video-platform/" rel="nofollow">PeerTube v7 has officially been released</a>, and the update brings a major redesign. Framasoft has been working on two major projects this year for PeerTube: mobile apps for Android and iOS (<a href="https://fediversereport.com/last-week-in-fediverse-ep-96/" rel="nofollow">released last week</a>), and a complete remodeling of the PeerTube interface. Framasoft has worked with designers for a thorough UX research, with tests and user interviews. Based on this the interface of PeerTube has been redesigned from the ground up. Framasoft has prioritised accessibility, they completed a full accessibility audit and used the findings to create the improvements and changes to the interface. Menus and pages have also been remodeled and simplified, to counteract some of the organic growth of all the options that has been build up over the years. The interface also looks a lot cleaner and calmer, with a more modern look. </p><p>As a sidenote: Framasoft says that they now refer to PeerTube servers as platforms, not instances. They give inclusion as a reason, saying that this term is easier to understand for people who are less well-versed in technology and the fediverse. I think this is a great change, and something that other fediverse software should consider as well. Platforms better communicates that each fediverse server is its own social network, that can have its own culture and governance. The value of the fediverse is that each platform can be its own separate digital space, and I find that the term platform communicates this better than instance does.</p></p><p>Shutdown of Mammoth and sub.club</p><p>The BLVD, the organisation behind three fediverse projects, has announced that they are shutting down due to a lack of funding. The BLVD has created the Mastodon iOS app Mammoth, fediverse creator payment platform sub.club, and the moth.social Mastodon server. All three projects will be shut down at the end of January 2025. The BLVD <a href="https://moth.social/@mammoth/113550544058629618" rel="nofollow">depended</a> on Mozilla for their funding, and Mozilla announced in September that they are shutting down their fediverse projects. In November the organisation already <a href="https://moth.social/@mammoth/113550544058629618" rel="nofollow">said</a> that they were now operating without any funding. Any community member that is interested in taking over the maintainance of one of the projects can get in touch. Bart Decrem, the founder of BLVD, <a href="https://www.theverge.com/2024/12/16/24322574/sub-club-mastodon-mammoth-fediverse-shutting-down" rel="nofollow">said</a> to The Verge that sub.club had more than 150 creators on the platform.</p></p><p>Nomadic Identity</p><p>Nomadic Identity is a mechanism that allows people to have their fediverse identity to be separate from the fediverse platform that they are using, which results them in being able to seamlessly switch their fediverse account to a different platform. The mechanism has been available in fediverse software Streams for multiple years, but it uses the fediverse protocol Nomad. The Nomad protocol has undergone some renaming (orginally Zot) over the years. Recently a <a href="https://opennomad.net/page/nomad/home" rel="nofollow">new documentation website</a> was launched for the Nomad protocol, which gives some more background information. The site also published an <a href="https://opennomad.net/page/nomad/concepts" rel="nofollow">article</a> explaining the concepts of Nomadic Identity.</p><p>There has been a <a href="https://codeberg.org/fediverse/fep/src/branch/main/fep/ef61/fep-ef61.md" rel="nofollow">Fediverse Enhancement Proposal for bringing Nomadic Identity to ActivityPub</a>, and that proposal is now seeing it’s first implementation: fediverse software Mitra and Streams recently <a href="https://mitra.social/post/01939dc9-51d3-155f-fe1d-5dfcf243ed7b" rel="nofollow">announced</a> the first form of communications between them using the new nomadic implementation of ActivityPub. Account portability is a feature that is regularly used as an example of the valuable features that an open protocol such as ActivityPub enables, but using the actual implementation currently comes with <a href="https://erinkissane.com/notes-from-a-mastodon-migration" rel="nofollow">frictions</a>. Early adopters like the new product <a href="https://a.weird.one/" rel="nofollow">Weird</a> are already <a href="https://writing.exchange/@erlend/113658801135974395" rel="nofollow">thinking</a> about offering Mitra as their fediverse platform of choice due to the new abilities that Nomadic Identity bring.</p></p><p>IFTAS needs assesment</p><p>IFTAS just <a href="https://about.iftas.org/2024/12/17/the-2024-iftas-needs-assessment-report-is-here/" rel="nofollow">published</a> their Needs Assesments report, that gives a detailed overview of the state of moderation on the fediverse. They published this report just before I send out this article, but I want to include it because I think it’s important. So here are the key findings, in IFTAS’ own words:</p><p>Resource gaps – only 16% of communities have 24-hour moderator coverage, and nearly half of moderator teams lack formal guidance. That said, we see roughly one moderator for every 1,200 active accounts.<br>Top ranked priorities – moderators need tools for CSAM detection, spam prevention, and legal guidance for compliance with regulations like GDPR.<br>Burnout is a persistent issue – one in five moderators report experiencing trauma or burnout this year, underlining the need for wellness and resilience resources.<br>Financial struggles – most communities operate on donations, and overall our survey participants are not generating enough money to cover costs. Very few moderators are receiving any compensation for their labour.</p><p>The Links</p><p><a href="https://blog.joinmastodon.org/2024/12/trunk-tidbits-november-2024/" rel="nofollow">Trunk & Tidbits for November 2024</a>, Mastodon’s monthly engineering update.<br><a href="https://blog.elenarossini.com/sharkey-a-fediverse-project-that-is-beautiful-inside-out/" rel="nofollow">Sharkey: a Fediverse project that is beautiful inside & out</a> – Elena Rossini<br><a href="https://wedistribute.org/2024/12/make-loops-video/" rel="nofollow">How to Make Your First Loops Video</a> – WeDistribute.<br><a href="https://www.wrecka.ge/what-people-in-the-global-majority-need-from-networks/" rel="nofollow">what people in the global majority need from networks</a> – wreckage/salvage<br>A proposal for a working group for <a href="https://forum.solidproject.org/t/integrating-activitypub-within-solid-specs/8355" rel="nofollow">Integrating ActivityPub within Solid specs</a>.<br><a href="https://event-federation.eu/2024/12/17/event-bridge-for-activitypub-upcoming-1-0-release/" rel="nofollow">Event Bridge for ActivityPub: Upcoming 1.0 Release</a>.<br>IFTAS December <a href="https://preview.mailerlite.io/emails/webview/454975/139703583531598974" rel="nofollow">update</a>.<br><a href="https://thelettertwo.com/2024/12/15/behind-flipboard-fediverse-embrace-mike-mccue-interview/" rel="nofollow">Why Flipboard Looks to the Fediverse for Its Next Big Evolution</a> – thelettertwo<br>Mastodon now gives server admins the <a href="https://mastodon.social/@Edent/113630403024860565" rel="nofollow">possibility to opt-in</a> to adding referrers to links. This allows other websites to see the traffic that a Mastodon server is sending.<br><a href="https://mitra.social/@weekinfediverse" rel="nofollow">Weekly fediverse software updates.</a><br><a href="https://stefanbohacek.com/blog/alt-text-health-check-image-accessibility-report-2/" rel="nofollow">Alt Text Health Check image accessibility report #2.</a><br><a href="https://shkspr.mobi/blog/2024/12/creating-a-generic-log-in-with-mastodon-service/" rel="nofollow">Creating a generic “Log-in with Mastodon” service</a>.<br><a href="https://akkofe.w.on-t.work/notice/a1rumsky1sd2m9mj" rel="nofollow">ActivityPub in Minecraft.</a><br><a href="https://mastodon.social/@dansup/113665304695257743" rel="nofollow">Loops ‘Unwrapped’</a> with some statistics about how Loops has been growing since launch.<br><a href="https://activitypub.ghost.org/the-reader-experience/" rel="nofollow">Ghost’s weekly development update</a> shares more about the reader client as well as their database design.</p><p>That’s all for this week, thanks for reading!</p><p><a href="/tags/2/" rel="tag">#2</a> <a href="/tags/fediverse/" rel="tag">#fediverse</a></p><p><a href="https://fediversereport.com/last-week-in-fediverse-ep-97/" rel="nofollow" class="ellipsis" title="fediversereport.com/last-week-in-fediverse-ep-97/"><span class="invisible">https://</span><span class="ellipsis">fediversereport.com/last-week-</span><span class="invisible">in-fediverse-ep-97/</span></a></p>
Edited 1y ago
<p>Drop <a href="/tags/580/" rel="tag">#580</a> (2024-12-20): Safety First</p><p>Your 2025 Digital Security Checklist; System and Service Credentials (systemd); Apple Platform Security Guide</p><p>Programming note: we’re off to see <a href="/tags/2/" rel="tag">#2</a>.1 & <a href="/tags/2/" rel="tag">#2</a>.2 next week for the holidays, so the Drops will likely be intermittent or non-existent until ~next Friday. I hope everyone celebrating this holiday season has a safe and restful time!</p><p><a href="https://dailydrop.hrbrmstr.dev/?post_type=post&p=139504510" rel="nofollow">Subscribe</a></p><p>TL;DR</p><p>(This is an AI-generated summary of today’s Drop using Ollama + llama 3.2 and a custom prompt + VSCodium extension.)</p><p>Digital security checklist for 2025 emphasizes strong passwords, encryption, secure messaging via Signal, and multi-factor authentication (<a href="https://freedom.press/digisec/blog/journalists-digital-security-checklist/" rel="nofollow" class="ellipsis" title="freedom.press/digisec/blog/journalists-digital-security-checklist/"><span class="invisible">https://</span><span class="ellipsis">freedom.press/digisec/blog/jou</span><span class="invisible">rnalists-digital-security-checklist/</span></a>)<br>Systemd’s Credentials system provides secure handling of sensitive data like API tokens and passwords using AES256-GCM encryption (<a href="https://systemd.io/CREDENTIALS/" rel="nofollow"><span class="invisible">https://</span>systemd.io/CREDENTIALS/</a>)<br>Apple Platform Security Guide details device security architecture and recommends strong passcodes, security policy configuration, and regular updates (<a href="https://help.apple.com/pdf/security/en_US/apple-platform-security-guide.pdf" rel="nofollow" class="ellipsis" title="help.apple.com/pdf/security/en_US/apple-platform-security-guide.pdf"><span class="invisible">https://</span><span class="ellipsis">help.apple.com/pdf/security/en</span><span class="invisible">_US/apple-platform-security-guide.pdf</span></a>)</p><p>Your 2025 Digital Security Checklist</p>Photo by MART PRODUCTION on <a href="https://www.pexels.com/photo/person-holding-a-paper-pad-7718635/" rel="nofollow">Pexels.com</a><p>Truth be told, this is actually the “<a href="https://freedom.press/digisec/blog/journalists-digital-security-checklist/" rel="nofollow">2025 Journalist’s Digital Security Checklist</a>“, but I think it most definitely has applications for us all. It provides a comprehensive framework for protecting digital assets and communications. We’ll break this down into key areas of focus, but you’ll need to read the full resource to get all the details.</p><p>A proper security posture starts with identifying what needs protection, who might want access to it, and their capabilities. So, the core questions to address are: what assets need protection, who are the adversaries, what resources do they have, how likely are they to act, and what defensive resources are available.</p><p>Modern mobile devices and endpoints require multiple layers of protection. For mobile devices, this means using alphanumeric passcodes, enabling full disk encryption, and carefully managing app permissions and notifications. Computer security demands similar attention through disk encryption (FileVault for macOS, BitLocker for Windows), strong passphrases, and regular security updates.</p><p>End-to-end encrypted messaging is essential for protecting sensitive communications. Signal stands out as the primary tool for secure messaging, while ProtonMail serves well for encrypted email when both parties use it. WhatsApp can be made more secure by disabling cloud backups and enabling disappearing messages.</p><p>Cloud storage presents significant risks for sensitive documents. A clear separation between offline and cloud-stored content is crucial. When using services like Google Drive, Dropbox, or iCloud, sensitive documents should be downloaded and securely deleted from cloud storage. For enhanced security, tools like <a href="https://github.com/veracrypt/VeraCrypt" rel="nofollow">VeraCrypt</a> can encrypt files before cloud upload.</p><p>Browser security requires a multi-layered approach using tools like uBlock Origin to block malicious ads and <a href="https://github.com/EFForg/privacybadger" rel="nofollow">Privacy Badger</a> to prevent tracking. For anonymous browsing, Tor Browser provides the strongest protection by routing traffic through multiple nodes.</p><p>Password managers are non-negotiable for generating and storing unique credentials. Multi-factor authentication should be enabled on all accounts, preferably using security keys like YubiKeys for their strong phishing resistance. For backup authentication, apps like Google Authenticator or Authy provide good secondary options.</p><p>I’m sure you’ll find some of the suggestions in the full post do mostly pertain to journalists, but there are absolutely some good tips for everyone.</p><p>System and Service Credentials (systemd)</p>Photo by Miguel u00c1. Padriu00f1u00e1n on <a href="https://www.pexels.com/photo/close-up-shot-of-keyboard-buttons-2882630/" rel="nofollow">Pexels.com</a><p>Speaking of security and privacy…</p><p>So, you’ve finally bit the bullet, migrated all your janky cron jobs to systemd timers and services and are all proud of yourselves. Except… you still keep API keys in environment variables that are readable by anyone who manages to get access to your server. And (worse), you still stick them in-script and forgot about that, then pushed the whole thing to GitHub (et al.).</p><p>In 2025 (or, y’know, now, if that previous paragraph described you), perhaps make a resolution to migrate to using the spiffy <a href="https://systemd.io/CREDENTIALS/" rel="nofollow">Credentials</a> system of systemd. It provides a secure mechanism for handling sensitive data like cryptographic keys, API tokens, certificates, and passwords in modern Linux systems.</p><p>It operates by acquiring credentials during service activation and releasing them upon deactivation. Services access these credentials through the $CREDENTIALS_DIRECTORY environment variable, with access strictly limited to the service’s user context.</p><p>Credentials are stored in non-swappable memory and can be encrypted using <a href="https://en.wikipedia.org/wiki/TPM2" rel="nofollow">TPM2</a> or keys stored in /var/. The encryption is automatic and requires minimal setup beyond the initial credential encryption. The system enforces kernel-level access checks rather than relying on process inheritance, making it more secure than environment variables. It is highly recommended that you store these on an ecnrypted partition.</p><p>Service credentials can be configured through several unit file directives:</p><p>Basic Configuration</p><p>LoadCredential handles loading from disk or Unix sockets<br>SetCredential manages literal strings in unit files<br>ImportCredential loads from credential stores</p><p>Secure Storage</p><p>LoadCredentialEncrypted and SetCredentialEncrypted handle encrypted credentials, making them safe for sensitive data even in world-readable unit files</p><p>The system uses <a href="https://en.wikipedia.org/wiki/Galois/Counter_Mode" rel="nofollow">AES256-GCM</a> for encryption and authentication. Credentials can be encrypted using TPM2-derived keys, system-stored keys in /var/lib/systemd/credential.secret, or both. This ensures credentials can only be decrypted on the specific hardware and OS installation they were created for.</p><p>Credentials can be passed to systems through container managers, hypervisors, kernel command line, or UEFI boot environment. This enables system-wide credential management that can be propagated to individual services. The implementation supports both plaintext and encrypted credentials throughout the propagation chain, with decryption occurring at service activation.</p><p>The <a href="https://man.archlinux.org/man/systemd-creds.1" rel="nofollow">manual page</a> and <a href="https://wiki.archlinux.org/title/Systemd-creds" rel="nofollow">Arch Linux wiki</a> are good places to start if you aren’t already using this feature.</p><p>Apple Platform Security Guide</p>Photo by Nicholas Githiri on <a href="https://www.pexels.com/photo/close-up-photography-of-wet-padlock-1068349/" rel="nofollow">Pexels.com</a><p>The <a href="https://help.apple.com/pdf/security/en_US/apple-platform-security-guide.pdf" rel="nofollow">Apple Platform Security Guide</a> (direct PDF) may not be as engaging as The Murderbot Diaries, but it is, nonetheless, essential reading for anyone receiving a new Apple device this holiday season (there is no hope for Android users). It documents the security architecture protecting everything on those precious glowing rectangles and screen-less rectangular boxes.</p><p>New device owners should at least flip through the tome to see what steps they can take to make their devices a bit safer to use. First, set up a strong device passcode/complex passphrase. This isn’t just about unlocking your device, but forms the basis of how your iPhone, iPad, Mac, Apple Watch or Apple Vision Pro cryptographically protects your data. While biometric features like Face ID, Touch ID, and Optic ID provide convenient access, they complement rather than replace a robust passcode. Depending on your threat model, you likely will not want to enable biometric authentication.</p><p>Pay special attention to the security settings when first configuring your device. On Macs with Apple Silicon, understand the security policy options. “Full Security” provides iOS-like protection and should be your default choice unless you have specific needs for reduced security. For all devices, enable “Find My” to protect against theft and remote wipe capabilities (again, your threat model may make this feature a non-starter). When setting up Apple Pay, take time to understand how the Secure Enclave protects your payment information and familiarize yourself with the double-click confirmation gestures that help prevent accidental or fraudulent payments.</p><p>The guide also emphasizes the importance of keeping your device updated. Apple’s secure software update system prevents downgrade attacks and ensures you always have the latest security protections. Enable automatic updates to receive these critical security fixes as soon as they’re available. Remember that Apple’s security architecture is designed to be strong by default while remaining transparent to users — but understanding how it works helps you make informed choices about your device’s configuration and use.</p><p>It’s dense, and not-exactly bedtime reading, but it’s a good idea to have it on hand for when you’re setting up a new device or want to understand how Apple’s security architecture works. Apple also updates it periodically, so make sure to check back for updates.</p><p>FIN</p><p>We all will need to get much, much better at sensitive comms, and <a href="https://signal.org/" rel="nofollow">Signal</a> is one of the only ways to do that in modern times. You should absolutely use that if you are doing any kind of community organizing (etc.). Ping me on Mastodon or Bluesky with a “🦇?” request (public or faux-private) and I’ll provide a one-time use link to connect us on Signal.</p><p>Remember, you can follow and interact with the full text of The Daily Drop’s free posts on:</p><p>🐘 Mastodon via <span class="h-card"><a href="https://dailydrop.hrbrmstr.dev" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>dailydrop.hrbrmstr.dev</span></a></span><br>🦋 Bluesky via <a href="https://bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy" rel="nofollow" class="ellipsis" title="bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy"><span class="invisible">https://</span><span class="ellipsis">bsky.app/profile/dailydrop.hrb</span><span class="invisible">rmstr.dev.web.brid.gy</span></a></p><p>Also, refer to:</p><p><a href="https://dailydrop.hrbrmstr.dev/2024/12/04/drop-565-2024-12-04-all-strings-attached/" rel="nofollow">this post</a>, and<br><a href="https://dailydrop.hrbrmstr.dev/2024/12/08/bonus-drop-68-2024-12-08-all-strings-attached-cli-version/" rel="nofollow">this post</a></p><p>to see how to access a regularly updated database of all the Drops with extracted links, and full-text search capability. ☮️</p><p><a href="/tags/2/" rel="tag">#2</a></p>
<p>Drop <a href="/tags/655/" rel="tag">#655</a> (2025-05-19): Just Another Manic Monday</p><p>rv; Jetrelay; How↠Why</p><p>The 7.5 hour trip from ME to DE took over 10, hence no Bonus Drop over the weekend, and it’s yet-another-work-offsite-week (FML), so the Drops will be thin this week.</p><p>I’m covering rv as there was some Mastodon buzz about it, and I took some decent copious notes after playing with it for a bit. Since I’m typing during <a href="/tags/2/" rel="tag">#2</a>.1 & <a href="/tags/2/" rel="tag">#2</a>.2’s naptimes, (visiting them before heading to D.C.) I’m leaning a bit heavily into the previously noted “Smart Brevity” format, since it turns out I’ve been taking notes with those concepts in mind for a few decades. The mid-section is the only one that explicitly uses that framework, since I find it kind of tedious to only write or read things in that style.</p><p>Type your email…</p><p>Subscribe</p><p>TL;DR</p><p>(This is an LLM/GPT-generated summary of today’s Drop using Ollama + Qwen 3 and a custom prompt.)</p><p>rv addresses R’s dependency management challenges with faster installation, reproducible lockfiles, and environment isolation (<a href="https://github.com/A2-ai/rv" rel="nofollow"><span class="invisible">https://</span>github.com/A2-ai/rv</a>)<br>Jetrelay is a high-performance relay for Bluesky’s jetstream feed, using Linux kernel tricks to broadcast data efficiently (<a href="https://www.asayers.com/jetrelay/" rel="nofollow"><span class="invisible">https://</span>www.asayers.com/jetrelay/</a>)<br>Solution-focused questioning shifts the mindset from problem analysis to actionable solutions, improving team productivity and creativity (<a href="https://hachyderm.io/@mweagle/114515586531421699" rel="nofollow" class="ellipsis" title="hachyderm.io/@mweagle/114515586531421699"><span class="invisible">https://</span><span class="ellipsis">hachyderm.io/@mweagle/11451558</span><span class="invisible">6531421699</span></a>)</p><p>rv: Solving? R’s Dependency Management Challenges</p><p><a href="https://github.com/A2-ai/rv" rel="nofollow">rv</a> tackles a set of interconnected challenges that R users have struggled with for years:</p><p>The R package ecosystem has lacked a comprehensive, modern dependency management solution that combines speed, reproducibility, and robust version pinning. While Python has tools like pip, Poetry, and Conda, and now uv, R’s built-in install.packages() function and even newer tools have significant limitations.</p><p>Specifically, rv addresses:</p><p>Performance issues – R package installation is traditionally slow, especially when compiling from source. rv accelerates this process through parallelized installation and prioritizing pre-compiled binaries. NOTE that very recent versions of R install groups of packages at lightning speed, so you don’t really need rv if you rely on “the latest” of everything and stick mostly to CRAN.<br>Reproducibility challenges: R projects often suffer from “works on my machine” syndrome due to inconsistent package versions. rv generates lockfiles that precisely pin all dependencies and subdependencies.<br>Environment isolation: rv integrates with the {box} package to create isolated environments, preventing package conflicts between projects.<br>Cross-platform compatibility: Managing consistent environments across Windows, Mac, and Linux has been difficult in R. rv provides tooling that works consistently across platforms.</p><p>How does rv compares to rxisting R solutions?</p><p>The renv package has been the most popular solution for R dependency management. While both tools create lockfiles, rv differentiates itself in several ways:</p><p>rv is significantly faster, using Rust for core operations while renv is written entirely in R<br>rv has more intelligent binary package selection and fallback strategies<br>The lockfile format in rv is more comprehensive, tracking more metadata about each dependency</p><p>pak improved upon base R’s installation capabilities with parallelization and better dependency resolution. However:</p><p>pak lacks robust lockfile support for exact environment recreation<br>rv offers better integration with project-specific workflows<br>rv provides clearer separation between development and production environments</p><p>packrat was an earlier attempt at package isolation but has been largely superseded by renv. rv improves upon both with:</p><p>Better performance characteristics<br>More comprehensive dependency tracking<br>Cleaner integration with modern R workflows</p><p>So, I will not pretend to fib, and note that my initial thought about rv was (before digging) that it was just going to be a lame attempt to copycat Python’s uv. While rv and Python’s uv do share some similarities (one being both are written in Rust for performance and focus on modern package management) rv is not simply a copycat. It addresses R-specific challenges:</p><p>The R package ecosystem works fundamentally differently from Python’s (CRAN vs PyPI)<br>R’s compilation requirements and binary compatibility issues are unique<br>The integration with R-specific virtual environments via {box} shows consideration for the R ecosystem<br>An increasing reliance on social Git repos, R Universe, and non-standard package hosting idioms.</p><p>Looking at the <a href="https://github.com/A2-ai/rv/tree/main/example_projects" rel="nofollow">example projects</a>, rv implements workflows tailored to R’s package structure and common use cases like RMarkdown documents and Shiny applications.</p><p>Now, one solution often overlooked is <a href="https://nixos.org/" rel="nofollow">nix</a>. It, too, offers an alternative solution to dependency management across languages:</p><p>Language-agnostic approach: Nix can manage R packages alongside other languages in a unified system<br>System-level reproducibility: Nix goes beyond package versions to reproduce the entire computing environment<br>Steep learning curve: Nix requires learning a specialized language and approach to configuration</p><p>While Nix is powerful, its complexity makes it less accessible for teams primarily working in R. rv provides a more focused, user-friendly solution specifically designed for R workflows.</p><p>The aforementioned examples in rv demonstrate real-world benefits:</p><p>Simplified CI/CD integration for R projects<br>Faster package installation in development and deployment<br>Clearer dependency documentation within projects<br>Easier onboarding for new team members working on R projects</p><p>Having only tried it for a few days, my initial impressions are that rv represents a meaningful advance in R dependency management rather than an unnecessary duplication. By combining performance improvements, comprehensive lockfiles, and integration with R-specific workflows, it addresses long-standing pain points in the R ecosystem.</p><p>Its Rust foundation may be inspired by tools like uv, but its implementation and features are thoughtfully designed for R’s unique package ecosystem and user needs. For R teams struggling with dependency hell, package conflicts, or cross-platform consistency, rv offers a compelling solution that goes beyond what existing tools provide.</p><p>Jetrelay</p><p>I still have some reservations about investing anything substantial into Bluesky/ATproto (until there is more “core identity” dispersion outside of reliance on Bsky infrastructure). However, I do still admire ATproto and the way information on it zips throughout the ether. So, we’ll continue to occasionally cover cool tech like <a href="https://www.asayers.com/jetrelay/" rel="nofollow">Jetrelay</a>.</p><p>Big picture:</p><p>Jetrelay is a tiny, high-performance relay for Bluesky’s “jetstream” feed. It uses clever Linux kernel tricks to broadcast real-time data to thousands of clients with minimal CPU and memory overhead.</p><p>How it works:</p><p>Jetrelay writes incoming events to a file. Each client has a “cursor” marking its position in that file. When a client needs data, Jetrelay copies bytes from the file straight to the client’s socket.</p><p>Why it’s fast:</p><p>Uses sendfile() so data moves directly from the file (in kernel cache) to the network-no userspace copying.<br>Uses io_uring to batch I/O for thousands of clients in a few syscalls.<br>Cleans up old data from the file with fallocate() so disk space stays flat.</p><p>Results:</p><p>20,000 clients, 24 Gbps on local loopback.<br>8,500 clients at 10 Gbps in real-world VM tests.<br>Outperforms the official jetstream server by a wide margin.</p><p>Trade-offs:</p><p>No per-client filtering (yet).<br>Lacks production features (metrics, security, etc.).<br>Meant as a demo, not a drop-in replacement.</p><p>Why it matters:</p><p>Jetrelay shows how smart use of OS features can make real-time, push-based systems scale-without complex code or massive hardware. It’s a blueprint for efficient broadcasting in a push-first internet.</p><p>How↠Why: Solution-Focused Questions</p><p>(This section was <a href="https://hachyderm.io/@mweagle/114515586531421699" rel="nofollow">spawned from a Mastoton thread</a>.)</p><p>Have you ever caught yourself or your team stuck in an endless loop of problem analysis? We’ve all been there. And, frustration builds as we repeatedly ask, “Why is this project so slow?” or “Why are we always missing deadlines?”</p><p>These questions might seem logical, but they often lead us further into problem-focused thinking without creating a path forward.</p><p>There’s a simple yet powerful shift you can make in your questioning approach:</p><p>Instead of asking “Why is it X?” where X = {slow, late, taking so long, unclear}, consider rephrasing as “What would it take to be Y?” where Y = {faster, early, done sooner, more clear}.</p><p>This subtle reframing does something remarkable to our brains. Rather than dwelling on obstacles or assigning blame, it immediately redirects our focus toward potential solutions and actionable steps.</p><p>When we ask, “Why is this project behind schedule?” we tend to generate reasons, excuses, and analysis. But when we ask, “What would it take to get this project back on track?” we naturally begin thinking about resources, approaches, and possibilities.</p><p>This solution-focused questioning technique doesn’t just feel better—it works better. It activates our creative problem-solving abilities and keeps us moving forward rather than spinning our wheels.</p><p>Here’s a few more examples to get you started if your team doesn’t already practice solutions-focused principles:</p><p>Instead of: “Why do we keep hitting the same bugs?”<br>Try: “What would it take to consistently catch these bugs before release?”<br>Instead of: “Why is team communication so poor?”<br>Try: “What would it take to improve transparency and collaboration on this team?”<br>Instead of: “Why are our incident response times so slow?”<br>Try: “What would it take to reduce our incident response times by 50%?”<br>Instead of: “Why do our meetings never stay on track?”<br>Try: “What would it take to make our meetings focused and efficient?”<br>Instead of: “Why do we always struggle with onboarding new hires?”<br>Try: “What would it take to make onboarding seamless and effective for new team members?”</p><p>FIN</p><p>Remember, you can follow and interact with the full text of The Daily Drop’s free posts on:</p><p>🐘 Mastodon via <span class="h-card"><a href="https://dailydrop.hrbrmstr.dev" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>dailydrop.hrbrmstr.dev</span></a></span><br>🦋 Bluesky via <a href="https://bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy" rel="nofollow" class="ellipsis" title="bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy"><span class="invisible">https://</span><span class="ellipsis">bsky.app/profile/dailydrop.hrb</span><span class="invisible">rmstr.dev.web.brid.gy</span></a></p><p>☮️</p><p><a href="/tags/2/" rel="tag">#2</a></p>
Edited 321d ago
<p>opstr; go-icu-regex; Intl.NumberFormat</p><p><p>U.S. Folk: REMEMBER TO VOTE THIS WEEK!</p></p><p><a href="https://icu.unicode.org/" rel="nofollow">ICU</a> (International Components for Unicode) is a comprehensive set of C/C++ and Java libraries that provide essential Unicode and globalization support for software applications. The project recently announced <a href="https://unicode-org.github.io/icu/download/76.html" rel="nofollow">ICU 76</a> release candidate, which brings Unicode 16 support and CLDR 46 locale data updates.</p><p>It began as part of <a href="https://en.wikipedia.org/wiki/Taligent" rel="nofollow">Taligent</a>, a joint Apple-IBM venture in the 1990s, before becoming an IBM project and eventually being open-sourced in 1999.</p><p>ICU excels at character set conversion, offering arguably the most complete charset data available, built upon decades of IBM’s collection efforts. The library provides sophisticated text handling capabilities including collation based on the [Unicode Collation Algorithm], locale-aware formatting for numbers and dates, and extensive timezone calculations.</p><p>The framework offers both C++ (ICU4C) and Java (ICU4J) implementations. ICU4C fills critical gaps in C/C++ environments that lack robust Unicode support, while ICU4J extends Java’s built-in internationalization capabilities with enhanced performance and newer Unicode standard compliance. The C/C++ versions are used as bridges to ICU in <a href="https://icu.unicode.org/related" rel="nofollow">many other programming languages</a>.</p><p>Lots of familiar names rely heavily on ICU, including:</p><p>Apple integrates it across macOS, iOS, watchOS, and tvOS<br>Google employs it in Chrome/ChromeOS, Android, and core web services<br>Microsoft uses it in Visual Studio Code and Windows Bridge for iOS<br>Adobe implements it throughout Creative Cloud and Document Cloud</p><p>The upcoming <a href="https://unicode-org.github.io/icu/download/76.html" rel="nofollow">ICU 76</a> introduces significant improvements, including direct formatting support for java.time types and modernized C++ and Java patterns. The release also achieves near-perfect alignment between <a href="https://cldr.unicode.org/index/cldr-spec/collation-guidelines" rel="nofollow">CLDR</a> and Unicode default sort orders.</p><p>In today’s Bonus Drop, we’re covering a few resources that make use of ICU.</p><p>TL;DR</p><p>(This is an AI-generated summary of today’s Drop using Ollama + llama 3.2 and a custom model.)</p><p>This Drop proved somewhat challenging to my custom TL;DR model on the 16GB M1 Mac Mini’s Ollama server. It did the job, but the number of input tokens — and, very likely, the giant bullet list and big blocks of source code — caused it to operate very slowly. I’ll be glad to get it re-setup on the forthcoming M4 Mini (which comes next week while, sadly, I’m AFK).</p><p><a href="https://github.com/typho/opstr" rel="nofollow">opstr</a> is a command-line utility that provides convenient access to common string operations, including Unicode-aware manipulations.<br>The <a href="https://github.com/dolthub/go-icu-regex/tree/main" rel="nofollow">go-icu-regex</a> project is a Go implementation of ICU regular expressions, providing a drop-in replacement for Go’s standard regexp package.<br>The <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat" rel="nofollow">Intl.NumberFormat</a> in JavaScript provides robust support for formatting numeric output, including various notation styles and currency formats.</p><p>opstr</p><p><a href="https://github.com/typho/opstr" rel="nofollow">opstr</a> is a command-line utility written in Rust that provides convenient access to common string operations. The tool let us perform Unicode-aware string manipulations directly from the shell without resorting to icky Python scripts or bloated web applications.</p><p>It accepts UTF-8 strings as input and offers locale-aware operations when configured with proper Unicode data. It can be installed via Cargo or downloaded as a pre-built binary (for some platforms) from the project’s releases page.</p><p>The tool’s behavior can be customized through environment variables rather than command-line flags. These include settings for output radix, hexadecimal case formatting, color schemes, and locale preferences. For locale-specific operations, you’ll need to generate your own locale data using <a href="https://crates.io/crates/icu4x-datagen" rel="nofollow">icu4x-datagen</a>, as the default installation only supports en-US to help keep the binary size as small as possible. The README provides an example, but note that said tool is also deprecated. I haven’t poked at the equivalent in <a href="https://docs.rs/icu_segmenter/latest/icu_segmenter/" rel="nofollow">its replacement</a>, since I don’t really need to do much outside of what it supports by default.</p><p>Incantations with it take a bitof getting used to, such as how you get stdin to the operations:</p><p>$ opstr --op lorem-ipsum 4 | \ opstr --stdin-as-arg 1 --op base64-encode 1TG9yZW0gaXBzdW0gaXVudSBwdHVsb3IgZXJlb2x1c3RlIHVtZGV0ai4K</p><p>And, whilt --stdin-as-arg works in many of the --op contexts, you sometimes have to do things lke this:</p><p>$ opstr --op join ", " $(opstr --op lorem-ipsum 4)Lorem, ipsum, oremau, yadi, miut, etum.</p><p>We’re covering the tool since it has a bonkers number of ops:</p><p>base64-decode: base64 decoding of provided hexadecimal string <a href="/tags/1/" rel="tag">#1</a><br>base64-encode: base64 encoding of provided string <a href="/tags/1/" rel="tag">#1</a><br>base64-url-safe-decode: base64 decoding of provided string <a href="/tags/1/" rel="tag">#1</a> with URL-appropriate representation (c.f. RFC 3548)<br>base64-url-safe-encode: base64 encoding of provided string <a href="/tags/1/" rel="tag">#1</a> with URL-appropriate representation (c.f. RFC 3548)<br>camelcase: turn <a href="/tags/1/" rel="tag">#1</a> to lowercase and replace the ASCII character after ‘ ‘ or ‘_’ sequences with an uppercase letter<br>center: put string <a href="/tags/1/" rel="tag">#1</a> in the middle of string of width <a href="/tags/2/" rel="tag">#2</a> (default 80) repeating char <a href="/tags/3/" rel="tag">#3</a> (default #) on both sides<br>codepoint-frequencies: return the frequency analysis per codepoint of string <a href="/tags/1/" rel="tag">#1</a><br>codepoint-lookup: given the Unicode name as string <a href="/tags/1/" rel="tag">#1</a> (e.g. “LATIN SMALL LETTER A”), return its UTF-8 representation (or an empty string, if unknown)<br>codepoints: represent string <a href="/tags/1/" rel="tag">#1</a> with Unicode codepoints as integers, e.g. [72, 105, 10069]<br>codepoints-names: look up the Unicode name (or ‘unknown-name’ if unknown) of each codepoint of string <a href="/tags/1/" rel="tag">#1</a>, e.g. [“LATIN SMALL LETTER H”, “LATIN SMALL LETTER DOTLESS ”]<br>codepoints-unotation: represent string <a href="/tags/1/" rel="tag">#1</a> with Unicode codepoints, e.g. [“U+0048”, “U+0069”]<br>concatenate: concatenate all provided strings<br>count-codepoints: return the number of Unicode scalars in the Unicode string <a href="/tags/1/" rel="tag">#1</a><br>count-grapheme-clusters: return number of “Grapheme clusters” in string <a href="/tags/1/" rel="tag">#1</a> according to Unicode Standard Annex 29 “Unicode Text Segmentation”<br>count-substring: how often does string <a href="/tags/2/" rel="tag">#2</a> non-overlappingly occur in string <a href="/tags/1/" rel="tag">#1</a>?<br>count-utf16-bytes: encode string <a href="/tags/1/" rel="tag">#1</a> in UTF-16 and return its number of bytes<br>count-utf8-bytes: encode string <a href="/tags/1/" rel="tag">#1</a> in UTF-8 and return its number of bytes<br>dedent: identify and remove common indentation among all non-empty lines of string <a href="/tags/1/" rel="tag">#1</a><br>dedent-with-substring: remove prefix string <a href="/tags/2/" rel="tag">#2</a> at the beginning of every line of string <a href="/tags/1/" rel="tag">#1</a><br>digest-md5: generate the MD5 hexadecimal digest of the given UTF-8 string <a href="/tags/1/" rel="tag">#1</a><br>digest-sha1: generate the SHA1 hexadecimal digest of the given UTF-8 string <a href="/tags/1/" rel="tag">#1</a><br>digest-sha256: generate the SHA256 hexadecimal digest of the given UTF-8 string <a href="/tags/1/" rel="tag">#1</a><br>digest-sha3-256: generate the SHA3-256 hexadecimal digest of the given UTF-8 string <a href="/tags/1/" rel="tag">#1</a><br>emoji-by-name: given a Emoji Sequence Data (UTS <a href="/tags/51/" rel="tag">#51</a>) description string <a href="/tags/1/" rel="tag">#1</a> return the corresponding emoji (e.g. ‘smiling face with halo’ returns ‘😇’)<br>format: replace {placeholders} in string <a href="/tags/1/" rel="tag">#1</a> with consecutive arguments <a href="/tags/2/" rel="tag">#2</a>, <a href="/tags/3/" rel="tag">#3</a>, …<br>grapheme-clusters: return “Grapheme clusters” of string <a href="/tags/1/" rel="tag">#1</a> according to Unicode Standard Annex 29 “Unicode Text Segmentation”<br>guarantee-prefix: if string <a href="/tags/1/" rel="tag">#1</a> does not start with string <a href="/tags/2/" rel="tag">#2</a>, prepend it<br>guarantee-suffix: if string <a href="/tags/1/" rel="tag">#1</a> does not end with string <a href="/tags/2/" rel="tag">#2</a>, append it<br>human-readable-bytes: represent integer <a href="/tags/1/" rel="tag">#1</a> (as 1024-based count of bytes) in a human-readable manner likely with two decimal points<br>indent-with-substring: concatenate string <a href="/tags/2/" rel="tag">#2</a> with every non-empty line in string <a href="/tags/1/" rel="tag">#1</a>, keep other lines<br>is-ascii: does this string <a href="/tags/1/" rel="tag">#1</a> only contain ASCII characters?<br>is-caseinsensitively-equal: do all Unicode strings have the same byte sequence after ASCII lowercasing?<br>is-contained: does string <a href="/tags/1/" rel="tag">#1</a> contain string <a href="/tags/2/" rel="tag">#2</a>?<br>is-crlf-lineterminated: is (U+000D CARRIAGE RETURN)(U+000A LINE FEED) the only sequence causing line breaks in string <a href="/tags/1/" rel="tag">#1</a>?<br>is-empty: does this string <a href="/tags/1/" rel="tag">#1</a> have length zero?<br>is-equal: do all Unicode strings have the same byte sequence?<br>is-lf-lineterminated: is U+000A LINE FEED the only character causing line breaks in string <a href="/tags/1/" rel="tag">#1</a>?<br>is-prefix: does string <a href="/tags/1/" rel="tag">#1</a> start with string <a href="/tags/2/" rel="tag">#2</a>?<br>is-suffix: does string <a href="/tags/1/" rel="tag">#1</a> end with string <a href="/tags/2/" rel="tag">#2</a>?<br>is-whitespace: does the provided string <a href="/tags/1/" rel="tag">#1</a> only contain codepoints in the Unicode Whitespace category?<br>is-whitespace-agnostically-equal: are all strings equal if we ignore any whitespace characters?<br>join: join all following strings with string <a href="/tags/1/" rel="tag">#1</a><br>length-maximum: return the first string among the longest strings<br>length-minimum: return the first string among the shortest strings<br>levensthein-distance: levensthein distance between strings <a href="/tags/1/" rel="tag">#1</a> and <a href="/tags/2/" rel="tag">#2</a><br>linebreak-before: linebreak long lines in (text <a href="/tags/1/" rel="tag">#1</a>) before they reach (integer <a href="/tags/2/" rel="tag">#2</a>) codepoints<br>lines-shortened: shorten lines in string <a href="/tags/1/" rel="tag">#1</a>, if necessary, not to exceed width <a href="/tags/2/" rel="tag">#2</a><br>lorem-ipsum: generate (int <a href="/tags/1/" rel="tag">#1</a>) words of an Lorem Ipsum text<br>lowercase-for-ascii: get locale-independent/ASCII lowercase version of string <a href="/tags/1/" rel="tag">#1</a><br>normalize-with-nfc: NFC-normalize Unicode string <a href="/tags/1/" rel="tag">#1</a> which applies canonical decomposition followed by canonical composition (c.f. UAX <a href="/tags/15/" rel="tag">#15</a>)<br>normalize-with-nfd: NFD-normalize Unicode string <a href="/tags/1/" rel="tag">#1</a> which applies canonical decomposition (c.f. UAX <a href="/tags/15/" rel="tag">#15</a>)<br>normalize-with-nfkc: NFKC-normalize Unicode string <a href="/tags/1/" rel="tag">#1</a> which applies compatibility decomposition followed by canonical composition (c.f. UAX <a href="/tags/15/" rel="tag">#15</a>)<br>normalize-with-nfkd: NFKD-normalize Unicode string <a href="/tags/1/" rel="tag">#1</a> which applies compatibility decomposition followed by canonical composition (c.f. UAX <a href="/tags/15/" rel="tag">#15</a>)<br>regex-search: does regex pattern <a href="/tags/1/" rel="tag">#1</a> occur anywhere inside <a href="/tags/2/" rel="tag">#2</a>? if so, return matching substring, otherwise empty string<br>remove-ansi-escape-sequences: remove any ANSI X3.64 (also found in ECMA-48/ISO 6429) sequences in string <a href="/tags/1/" rel="tag">#1</a> starting with U+001B ESCAPE<br>repeat: repeat string <a href="/tags/1/" rel="tag">#1</a> several (integer <a href="/tags/2/" rel="tag">#2</a>) times<br>replace: replace string <a href="/tags/2/" rel="tag">#2</a> with string <a href="/tags/3/" rel="tag">#3</a> in string <a href="/tags/1/" rel="tag">#1</a><br>sentence-clusters: return “Sentence clusters” according to Unicode Standard Annex <a href="/tags/29/" rel="tag">#29</a> “Unicode Text Segmentation”<br>similarity: indicate similarity (0 = not, 100 = equal) of two strings with a number between 0 and 100<br>skip-prefix: remove string <a href="/tags/2/" rel="tag">#2</a> from the beginning of string <a href="/tags/1/" rel="tag">#1</a> if it exists<br>skip-suffix: remove string <a href="/tags/2/" rel="tag">#2</a> from the end of string <a href="/tags/1/" rel="tag">#1</a> if it exists<br>sort: sort the strings provided<br>sort-lexicographically: sort the strings provided lexicographically by their Unicode codepoints<br>split: split string <a href="/tags/1/" rel="tag">#1</a> by any of the provided substrings <a href="/tags/2/" rel="tag">#2</a>, or <a href="/tags/3/" rel="tag">#3</a>, or …<br>split-by-whitespaces: split string <a href="/tags/1/" rel="tag">#1</a> by any character of Unicode category Whitespace<br>split-by-whitespaces-limited-at-end: split at most <a href="/tags/2/" rel="tag">#2</a> times from the end of the string <a href="/tags/1/" rel="tag">#1</a> by any character of Unicode category Whitespace<br>split-by-whitespaces-limited-at-start: split at most <a href="/tags/2/" rel="tag">#2</a> times at the start of the string <a href="/tags/1/" rel="tag">#1</a> by any character of Unicode category Whitespace<br>strike-through: add U+0336 COMBINING LONG STROKE OVERLAY before each codepoint resulting in strike-through text<br>strip-codepoints: strip codepoints found in string <a href="/tags/2/" rel="tag">#2</a> from start or end of string <a href="/tags/1/" rel="tag">#1</a><br>strip-codepoints-at-end: strip codepoints found in string <a href="/tags/2/" rel="tag">#2</a> from end of string <a href="/tags/1/" rel="tag">#1</a><br>strip-codepoints-at-start: strip codepoints found in string <a href="/tags/2/" rel="tag">#2</a> from start of string <a href="/tags/1/" rel="tag">#1</a><br>strip-whitespaces: strip whitespaces from start and end of string <a href="/tags/1/" rel="tag">#1</a><br>strip-whitespaces-at-end: strip whitespaces from end of string<br>strip-whitespaces-at-start: strip whitespaces from start of string<br>subscript: return the subscript version of the provided string <a href="/tags/1/" rel="tag">#1</a><br>substring-byte-indices: return the byte indices where string <a href="/tags/2/" rel="tag">#2</a> can be found in string <a href="/tags/1/" rel="tag">#1</a><br>superscript: return the superscript version of the provided string <a href="/tags/1/" rel="tag">#1</a><br>uppercase-for-ascii: get locale-independent/ASCII uppercase version of string <a href="/tags/1/" rel="tag">#1</a><br>utf16-big-endian-bytes: encode string <a href="/tags/1/" rel="tag">#1</a> in UTF-16 and return its bytes in big endian order<br>utf16-little-endian-bytes: encode string <a href="/tags/1/" rel="tag">#1</a> in UTF-16 and return its bytes in little endian order<br>utf8-bytes: encode string <a href="/tags/1/" rel="tag">#1</a> in UTF-8 and return its bytes<br>word-clusters: return “Word clusters” of string <a href="/tags/1/" rel="tag">#1</a> according to Unicode Standard Annex 29 “Unicode Text Segmentation”<br>xml-decode: replace the 5 pre-defined XML entities with their unescaped characters &<>”‘ in string <a href="/tags/1/" rel="tag">#1</a><br>xml-encode: replace the 5 characters &<>”‘ with their pre-defined XML entities in string <a href="/tags/1/" rel="tag">#1</a></p><p>It also has some guidelines for folks who want to add more ICU ops.</p><p>This is the CLI equivalent to R’s spiffy {stringi} library, which I use pretty much every day at work.</p><p>go-icu-regex</p><p>The <a href="https://github.com/dolthub/go-icu-regex/tree/main" rel="nofollow">go-icu-regex</a> project is a Go implementation of ICU regular expressions that provides a drop-in replacement for Go’s standard regexp package. This library is hand for when we need Unicode-aware regular expressions that behave consistently across different platforms and programming languages. In other news, it’s 2024 and I still have to re-remember what types of regex are supported in each of the languages I use in a given week (if I want to avoid extra dependencies). This is why we can’t have nice things.</p><p>The package maintains API compatibility with Go’s regexp while implementing the ICU regular expression specification. This means we can use it as a direct replacement in existing Go code that uses the standard library’s regex implementation.</p><p>The implementation wraps the ICU4C library’s regular expression engine. It includes support for Unicode Technical Standard <a href="/tags/18/" rel="tag">#18</a> (Unicode Regular Expressions) and maintains compatibility with other ICU implementations across different programming languages.</p><p>This library is especially useful when:</p><p>We need consistent regex behavior across multiple programming languages<br>Our apps requires advanced Unicode support beyond Go’s native capabilities<br>We’re porting applications that rely on ICU regex behavior to Go</p><p>Since this is a wrapper around ICU4C, there may be some performance overhead compared to Go’s native implementation. However, this tradeoff is often worth it when Unicode compliance and cross-platform consistency are primary requirements. It also means it’s not a “pure Go” library. So much for CISA’s “Use memory-safe languages, like Go” annoying mantra (both Rust and Go can be as unsafe as C/C++).</p><p>Intl.NumberFormat</p>Photo by Black ice on <a href="https://www.pexels.com/photo/lots-of-numbers-1314543/" rel="nofollow">Pexels.com</a><p>I cannot count the number of times I’ve made functions, across many modern languages, to format numeric output. The ICU-powered <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat" rel="nofollow">Intl.NumberFormat</a> in JavaScript (and, in different forms in some other languages) provides robust support for such operations.</p><p>I’ve included a bunch in the remainder of this section which was generated from <a href="https://rud.is/dl/numfmt.ibynb" rel="nofollow">this notebook</a>. To get the same output locally — assuming you have Jupyter instaleld — you can do the following:</p><p>$ # get Deno from <a href="https://deno.land/$" rel="nofollow"><span class="invisible">https://</span>deno.land/$</a> # install the kernel$ deno jupyter --unstable --install$ cd to-somewhere-safe-to-download-things$ curl --silent --output numfmt.ibynb <a href="https://rud.is/dl/numfmt.ibynb$" rel="nofollow"><span class="invisible">https://</span>rud.is/dl/numfmt.ibynb$</a> # prbly shld make sure I'm not pwning you by viewing the notebook$ # never run untrusted code without looking at the source, first$ jupyter \ nbconvert \ --to markdown \ --execute \ --ExecutePreprocessor.kernel_name=deno \ numfmt.ipynb \ --stdout</p><p>macOS folk may need to do:</p><p>$ ln -s /opt/homebrew/share/jupyter/nbconvert ~/Library/Jupyter</p><p>if you encounter errors.</p><p>Basic number formatting:</p><p>const nf = new Intl.NumberFormat('en');console.log(nf.format(123456.789));console.log(nf.formatToParts(123456.789));</p><p>123,456.789[ { type: "integer", value: "123" }, { type: "group", value: "," }, { type: "integer", value: "456" }, { type: "decimal", value: "." }, { type: "fraction", value: "789" }]</p><p>Notation styles:</p><p>const std = new Intl.NumberFormat('en', { notation: 'standard'});console.log(std.format(9876543.21));</p><p>9,876,543.21</p><p>Sign display:</p><p>const signs = new Intl.NumberFormat('en', { style: 'unit', unit: 'celsius', signDisplay: 'always'});console.log(signs.format(23.5));console.log(signs.format(-5));console.log(signs.format(0));</p><p>+23.5°C-5°C+0°C</p><p>BigInt formatting:</p><p>const bigFormatter = new Intl.NumberFormat('fr');console.log(bigFormatter.format(987654321098765432n));</p><p>987 654 321 098 765 432</p><p>Currency with accounting:</p><p>const money = new Intl.NumberFormat('en', { style: 'currency', currency: 'EUR', signDisplay: 'exceptZero', currencySign: 'accounting'});console.log(money.format(42.42));console.log(money.format(-42.42));console.log(money.format(0));</p><p>+€42.42(€42.42)€0.00</p><p>Units:</p><p>const bytes = new Intl.NumberFormat('en', { style: 'unit', unit: 'megabyte'});console.log(bytes.format(42.5));</p><p>42.5 MB</p><p>const speed = new Intl.NumberFormat('en', { style: 'unit', unit: 'kilometer-per-hour'});console.log(speed.format(88));</p><p>88 km/h</p><p>const compact = new Intl.NumberFormat('en', { notation: 'compact'});console.log(compact.format(9876543.21));</p><p>9.9M</p><p>const scientific = new Intl.NumberFormat('en', { notation: 'scientific'});console.log(scientific.format(9876543.21));</p><p>9.877E6</p><p>const engineering = new Intl.NumberFormat('en', { notation: 'engineering'});console.log(engineering.format(9876543.21));</p><p>9.877E6</p><p>FIN</p><p>Remember, you can follow and interact with the full text of The Daily Drop’s free posts on Mastodon via <span class="h-card"><a href="https://dailydrop.hrbrmstr.dev" class="u-url mention" rel="nofollow noopener noreferrer" target="_blank">@<span>dailydrop.hrbrmstr.dev</span></a></span> ☮️</p><p><a href="https://dailydrop.hrbrmstr.dev/2024/11/03/bonus-drop-66-2024-11-03-eye-sea-ewe/" rel="nofollow" class="ellipsis" title="dailydrop.hrbrmstr.dev/2024/11/03/bonus-drop-66-2024-11-03-eye-sea-ewe/"><span class="invisible">https://</span><span class="ellipsis">dailydrop.hrbrmstr.dev/2024/11</span><span class="invisible">/03/bonus-drop-66-2024-11-03-eye-sea-ewe/</span></a></p><p><a href="/tags/1/" rel="tag">#1</a> <a href="/tags/15/" rel="tag">#15</a> <a href="/tags/18/" rel="tag">#18</a> <a href="/tags/2/" rel="tag">#2</a> <a href="/tags/29/" rel="tag">#29</a> <a href="/tags/3/" rel="tag">#3</a> <a href="/tags/51/" rel="tag">#51</a></p>
I submitted a Pull Request to update MacPorts' OpenSSH to 9.9p2 here:<br><br><a href="https://github.com/macports/macports-ports/pull/27712" rel="nofollow" class="ellipsis" title="github.com/macports/macports-ports/pull/27712"><span class="invisible">https://</span><span class="ellipsis">github.com/macports/macports-p</span><span class="invisible">orts/pull/27712</span></a><br><br>GitHub Continuous Integration checks are running. Hopefully they will be OK (Update 2 out of 3 have completed successfully, which is a good sign).<br><br>I tested locally without issues, but I also build against LibreSSL locally, whereas GitHub CI and MacPorts' Build Bots I think default to OpenSSL.<br><br>This release is to address some vulnerabilities identified by Qualys and other less critical bugs.<br><br>More details from upstream here:<br><br><a href="https://www.openssh.com/releasenotes.html#9.9p2" rel="nofollow" class="ellipsis" title="www.openssh.com/releasenotes.html#9.9p2"><span class="invisible">https://</span><span class="ellipsis">www.openssh.com/releasenotes.h</span><span class="invisible">tml#9.9p2</span></a><br><br>Of particular note:<br><br>" Fix CVE-2025-26465 - ssh(1) in OpenSSH versions 6.8p1 to 9.9p1<br>(inclusive) contained a logic error that allowed an on-path<br>attacker (a.k.a MITM) to impersonate any server when the<br>VerifyHostKeyDNS option is enabled. This option is off by default.<br><br>* Fix CVE-2025-26466 - sshd(8) in OpenSSH versions 9.5p1 to 9.9p1<br>(inclusive) is vulnerable to a memory/CPU denial-of-service related<br>to the handling of SSH2MSGPING packets. This condition may be<br>mitigated using the existing PerSourcePenalties feature.<br><br>Both vulnerabilities were discovered and demonstrated to be exploitable<br>by the Qualys Security Advisory team. We thank them for their detailed<br>review of OpenSSH."<br><br>If I read everything correctly, these vulnerabilities primarily only impact the Portable OpenSSH releases (which is what MacPorts uses). However, OpenBSD has also issued the following errata to mitigate one of the issues as it also appears to impact OpenBSD users:<br><br>"008: SECURITY FIX: February 18, 2025 All architectures<br>sshd(8) denial of service relating to SSH2MSGPING handling. ssh(1) server impersonation when VerifyHostKeyDNS enabled.<br>A source code patch exists which remedies this problem."<br><br>Source code patch for OpenBSD here:<br><br><a href="https://ftp.openbsd.org/pub/OpenBSD/patches/7.6/common/008_ssh.patch.sig" rel="nofollow" class="ellipsis" title="ftp.openbsd.org/pub/OpenBSD/patches/7.6/common/008_ssh.patch.sig"><span class="invisible">https://</span><span class="ellipsis">ftp.openbsd.org/pub/OpenBSD/pa</span><span class="invisible">tches/7.6/common/008_ssh.patch.sig</span></a><br><br>Having written as much, it appears as if the main OpenSSH version for OpenBSD is still 9.9, so I am not going to make a submission for undeadly.org Other editors reading this are welcome to though, I just kind of have a lot of other stuff on my plate at present.<br><br>As usual, I also have too much going on in my life to want more responsibilities such as commit access within MacPorts, so it's up to someone else to merge it.<br><br>Update <a href="/tags/2/" rel="tag">#2</a>: I also decided to be a good Samaritan and reported the issue to Apple. Not that they have ever acknowledged my efforts for such things nor paid me from their bug bounty program in years of doing similar things. Because, OFC, Apple can't spare a penny to anyone like me. Maybe Qualys already reported it to them anyway (though they would have no obligation to do so, they did find the vulns and reported them upstream as would be expected).<br><br><a href="/tags/openssh/" rel="tag">#OpenSSH</a> <a href="/tags/macports/" rel="tag">#MacPorts</a> <a href="/tags/secureshell/" rel="tag">#SecureShell</a> <a href="/tags/infosec/" rel="tag">#InfoSec</a> <a href="/tags/cryptography/" rel="tag">#Cryptography</a> <a href="/tags/security/" rel="tag">#Security</a> <a href="/tags/cve/" rel="tag">#CVE</a> <a href="/tags/patchtuesday/" rel="tag">#PatchTuesday</a> <a href="/tags/opensource/" rel="tag">#OpenSource</a> <a href="/tags/openbsd/" rel="tag">#OpenBSD</a> <a href="/tags/macos/" rel="tag">#macOS</a><br>
Edited 1y ago
<a href="/tags/snac/" rel="tag">#snac</a> / activitypub noob <a href="/tags/question/" rel="tag">#question</a>:<br><br><p>job fifo size (cur): 655<br>job fifo size (peak): 1291<br>thread <a href="/tags/0/" rel="tag">#0</a> state: waiting<br>thread <a href="/tags/1/" rel="tag">#1</a> state: output<br>thread <a href="/tags/2/" rel="tag">#2</a> state: output<br>thread <a href="/tags/3/" rel="tag">#3</a> state: output<br></p>This number is decreasing over some minutes after I made a post,<br>I assume it is my instance delivering this to all subscribers, is that correct?<br>And the last thread will stay idle to maybe wait for incoming requests, so that they can be answered too?<br>I've never seen another status then waiting or output so far.<br><br>I guess if I post a picture that might then happen and all workers will be busy? Maybe even too busy to keep up?<br><br>Is that assumption about how the waiting worker and what it is for correct?<br><br>If yes I guess I'll increase the threads, if they are intentional low for low ram systems, that's not my issue with snac. (I've not much ram, but I assume snac is by default tuned to be very very very conservative?)<br><br>(adding Pic to simultaneously test my theory)<br><br><a href="/tags/snac2/" rel="tag">#snac2</a><br><br>
just linux things<br><br><p>$ diff -u a/file b/file > file.diff<br>$ cd a<br>$ patch -p1 < ../file.diff<br>Hunk <a href="/tags/2/" rel="tag">#2</a> FAILED at 73.<br>Hunk <a href="/tags/3/" rel="tag">#3</a> FAILED at 99.<br>$<br></p>definitely a real operating system that adult professionals should be using for importat work<br>
Edited 290d ago
