<?xml version="1.0" encoding="utf-8" standalone="yes"?><?xml-stylesheet type="text/xsl" href="https://perrotta.dev/rss.xsl"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Serenity on ¬ just serendipity 🍀</title>
    <link>https://perrotta.dev/</link>
    <description>Recent content in Serenity on ¬ just serendipity 🍀</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <managingEditor>serendipity@perrotta.dev (Thiago Perrotta)</managingEditor>
    <webMaster>serendipity@perrotta.dev (Thiago Perrotta)</webMaster>
    <copyright>© 2013 - 2026 Thiago Perrotta ·
  a fork of [hugo ʕ•ᴥ•ʔ bear](https://github.com/janraasch/hugo-bearblog/)
</copyright>
    <lastBuildDate>Tue, 21 Jul 2026 14:20:06 +0200</lastBuildDate>
    <atom:link href="https://perrotta.dev/tags/serenity/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>★ logseq → obsidian
      </title>
      <link>https://perrotta.dev/2026/07/logseq-obsidian/</link>
      <pubDate>Mon, 20 Jul 2026 18:26:33 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>bestof</category>
      <category>dev</category>
      <category>pkm</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/07/logseq-obsidian/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://perrotta.dev/2026/07/brew-pin/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Problem statement&lt;/strong&gt;: LogSeq v2 is moving its graph format from markdown files&#xA;to a sqlite database:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://discuss.logseq.com/t/whats-new-with-logseq-db-may-16th-2026/35020&#34;&gt;What&amp;rsquo;s New with Logseq DB — May 16th 2026&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://logseq.io/p/e3YDyX5AYr&#34;&gt;Big update: Logseq is splitting into two versions&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;This is &lt;em&gt;not OK&lt;/em&gt; for my workflow.&lt;/p&gt;&#xA;&lt;p&gt;The whole point of adopting LogSeq was, just like&#xA;&lt;a href=&#34;https://obsidian.md/&#34;&gt;Obsidian&lt;/a&gt;, the promise of&#xA;managing my notes in plain markdown files.&lt;/p&gt;&#xA;&lt;p&gt;Even though this migration is supposed to improve the performance of the app, it&#xA;ends up breaking a fundamental reason why I decided to use it in the first&#xA;place.&lt;/p&gt;&#xA;&lt;p&gt;Furthermore, the Second Brain app of my choice is supposed to be boring. It is&#xA;a big deal to wake up one day and find that I can no longer open my notes&#xA;graph with the new version of the app. This is a no-go.&lt;/p&gt;&#xA;&lt;p&gt;Well, classic LogSeq (dubbed &amp;ldquo;Logseq OG&amp;rdquo;) will be &lt;a href=&#34;https://github.com/logseq/og&#34;&gt;kept&#xA;around&lt;/a&gt;, but I can only assume that from this&#xA;point on it will become poorly maintained — it will never get the same amount of&#xA;resources and attention as the new version.&lt;/p&gt;&#xA;&lt;p&gt;Also, even if I really wanted to use the new version, it turns out it does not&#xA;work on mobile (iOS), which is a dealbreaker, therefore I would be forced to&#xA;stay stuck with OG for a while. Heck, the iOS app hasn&amp;rsquo;t been updated in 2y&#xA;anyway, and it shows.&lt;/p&gt;&#xA;&lt;p&gt;There will be no hard feelings, this is a peaceful breakup; I enjoyed LogSeq,&#xA;it&amp;rsquo;s simpler and more streamlined than Obsidian; as such, I will keep&#xA;recommending it to most people.&lt;/p&gt;&#xA;&lt;p&gt;That said, I&amp;rsquo;ve always been pondering whether to switch back to Obsidian.&#xA;There&amp;rsquo;s no doubt that Obsidian is more actively maintained and better suited for&#xA;Gen AI / LLM workflows these days (see &lt;a href=&#34;https://obsidian.md/cli&#34;&gt;Obsidian CLI&lt;/a&gt;&#xA;for starters).&lt;/p&gt;&#xA;&lt;p&gt;Why did I switch to LogSeq from Obsidian in the first place? Because Obsidian&#xA;was too much for me. It was more complicated (in terms of its feature set) than&#xA;warranted for my purposes. It offered more than I needed. That&amp;rsquo;s not necessarily&#xA;a bad thing. It&amp;rsquo;s like saying (hypothetically) &amp;ldquo;I prefer &lt;code&gt;nano&lt;/code&gt; instead of&#xA;&lt;code&gt;vim&lt;/code&gt;&amp;rdquo;, or that I prefer to live in a studio apartment than in a 3-bedroom&#xA;house.&lt;/p&gt;&#xA;&lt;p&gt;Obsidian won&amp;rsquo;t let me down in terms of changing its file format: &lt;a href=&#34;https://stephango.com/file-over-app&#34;&gt;file over&#xA;app&lt;/a&gt; is one of their core&#xA;&lt;a href=&#34;https://stephango.com/self-guarantee&#34;&gt;promises&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;File over app is a philosophy: if you want to create digital artifacts that&#xA;last, they must be files you can control, in formats that are easy to retrieve&#xA;and read. Use tools that give you this freedom.&lt;/p&gt;&#xA;&lt;p&gt;File over app is an appeal to tool makers: accept that all software is&#xA;ephemeral, and give people ownership over their data.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This is very important. My Second Brain app must not lock me in. LogSeq, upon&#xA;the switch to a sqlite database, breaks this invariant. I want — I need — boring&#xA;markdown files. Do not break the beauty and simplicity of this setup.&lt;/p&gt;&#xA;&lt;h2 id=&#34;migration&#34;&gt;&#xA;  Migration&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/07/logseq-obsidian/#migration&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;LogSeq and Obsidian are similar but not identical.&lt;/p&gt;&#xA;&lt;p&gt;In order to bridge the gap, a small python script (drafted by Claude Fable 5,&#xA;reviewed by me) walked the existing LogSeq Graph and wrote to a fresh Obsidian&#xA;Vault, leaving the source untouched, should I decide to roll back.&lt;/p&gt;&#xA;&lt;p&gt;These are some mappings (LogSeq → Obsidian):&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;journals/2024_03_04.md         -&amp;gt;  journals/2024-03-04.md&#xA;pages/Foo___Bar.md             -&amp;gt;  Foo/Bar.md          (namespaces)&#xA;- TODO buy milk                -&amp;gt;  - [ ] buy milk&#xA;- DOING ...                    -&amp;gt;  - [/] ...&#xA;- DONE ...                     -&amp;gt;  - [x] ...&#xA;[[Feb 9th, 2026]]              -&amp;gt;  [[2026-02-09]]&#xA;((67ea7dba-3200-...))          -&amp;gt;  [[2025-03-31#^67ea7dba]]&#xA;{{embed ((67ea7dba-3200-...))}} -&amp;gt; ![[2025-03-31#^67ea7dba]]&#xA;{{video https://...}}          -&amp;gt;  plain URL&#xA;id:: 67ea7dba-3200-...         -&amp;gt;  ^67ea7dba block anchor (when referenced)&#xA;collapsed:: true, :LOGBOOK:    -&amp;gt;  dropped&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Plus one line of config so that the LogSeq journals become Obsidian daily notes:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-json&#34;&gt;{&#xA;    &amp;#34;folder&amp;#34;: &amp;#34;journals&amp;#34;,&#xA;    &amp;#34;format&amp;#34;: &amp;#34;YYYY-MM-DD&amp;#34;&#xA;}&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&amp;hellip;and then I spent some time trying to dumb down Obsidian, disabling core&#xA;plug-ins I do not need at this time. There&amp;rsquo;s no need for community plug-ins for&#xA;now (if ever).&lt;/p&gt;&#xA;&lt;p&gt;So far, I only migrated my corp (work) notes. I&amp;rsquo;ll need to migrate my personal&#xA;PKM as well, but I am happy to simply pilot this migration at work first, so&#xA;that I don&amp;rsquo;t get to regret twice.&lt;/p&gt;&#xA;&lt;p&gt;The migration script:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-python&#34;&gt;#!/usr/bin/env python3&#xA;&amp;#34;&amp;#34;&amp;#34;Migrate LogSeq graph -&amp;gt; Obsidian vault. Source is never modified.&amp;#34;&amp;#34;&amp;#34;&#xA;import re&#xA;import shutil&#xA;from pathlib import Path&#xA;&#xA;SRC = Path(&amp;#34;/Users/thiago.perrotta/Library/Mobile Documents/iCloud~com~logseq~logseq/{redacted}&amp;#34;)&#xA;DST = Path(&amp;#34;/Users/thiago.perrotta/Library/Mobile Documents/iCloud~md~obsidian/{redacted}&amp;#34;)&#xA;&#xA;UUID = r&amp;#34;[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}&amp;#34;&#xA;MONTHS = {m: i &amp;#43; 1 for i, m in enumerate(&#xA;    [&amp;#34;Jan&amp;#34;, &amp;#34;Feb&amp;#34;, &amp;#34;Mar&amp;#34;, &amp;#34;Apr&amp;#34;, &amp;#34;May&amp;#34;, &amp;#34;Jun&amp;#34;, &amp;#34;Jul&amp;#34;, &amp;#34;Aug&amp;#34;, &amp;#34;Sep&amp;#34;, &amp;#34;Oct&amp;#34;, &amp;#34;Nov&amp;#34;, &amp;#34;Dec&amp;#34;])}&#xA;&#xA;MARKER_MAP = {&#xA;    &amp;#34;TODO&amp;#34;: &amp;#34;[ ]&amp;#34;, &amp;#34;LATER&amp;#34;: &amp;#34;[ ]&amp;#34;, &amp;#34;WAITING&amp;#34;: &amp;#34;[ ]&amp;#34;,&#xA;    &amp;#34;DOING&amp;#34;: &amp;#34;[/]&amp;#34;, &amp;#34;NOW&amp;#34;: &amp;#34;[/]&amp;#34;, &amp;#34;IN-PROGRESS&amp;#34;: &amp;#34;[/]&amp;#34;,&#xA;    &amp;#34;DONE&amp;#34;: &amp;#34;[x]&amp;#34;,&#xA;    &amp;#34;CANCELED&amp;#34;: &amp;#34;[-]&amp;#34;, &amp;#34;CANCELLED&amp;#34;: &amp;#34;[-]&amp;#34;,&#xA;}&#xA;&#xA;&#xA;def journal_name(stem: str) -&amp;gt; str:&#xA;    return stem.replace(&amp;#34;_&amp;#34;, &amp;#34;-&amp;#34;)&#xA;&#xA;&#xA;def dest_rel(src_file: Path) -&amp;gt; Path:&#xA;    &amp;#34;&amp;#34;&amp;#34;Map a source md file to its vault-relative destination path.&amp;#34;&amp;#34;&amp;#34;&#xA;    if src_file.parent.name == &amp;#34;journals&amp;#34;:&#xA;        return Path(&amp;#34;journals&amp;#34;) / (journal_name(src_file.stem) &amp;#43; &amp;#34;.md&amp;#34;)&#xA;    # namespace pages: A___B.md -&amp;gt; A/B.md; everything else under pages/&#xA;    parts = src_file.stem.split(&amp;#34;___&amp;#34;)&#xA;    return Path(*parts[:-1]) / (parts[-1] &amp;#43; &amp;#34;.md&amp;#34;) if len(parts) &amp;gt; 1 else Path(&amp;#34;pages&amp;#34;) / src_file.name&#xA;&#xA;&#xA;def page_ref(src_file: Path) -&amp;gt; str:&#xA;    &amp;#34;&amp;#34;&amp;#34;Wiki-link target for a source file (what goes inside [[...]]).&amp;#34;&amp;#34;&amp;#34;&#xA;    if src_file.parent.name == &amp;#34;journals&amp;#34;:&#xA;        return journal_name(src_file.stem)&#xA;    return &amp;#34;/&amp;#34;.join(src_file.stem.split(&amp;#34;___&amp;#34;))&#xA;&#xA;&#xA;def collect_ids():&#xA;    &amp;#34;&amp;#34;&amp;#34;uuid -&amp;gt; (link target, anchor) for every id:: definition; also which uuids are referenced.&amp;#34;&amp;#34;&amp;#34;&#xA;    defined, referenced = {}, set()&#xA;    for f in sorted(SRC.glob(&amp;#34;pages/*.md&amp;#34;)) &amp;#43; sorted(SRC.glob(&amp;#34;journals/*.md&amp;#34;)):&#xA;        text = f.read_text(encoding=&amp;#34;utf-8&amp;#34;)&#xA;        for m in re.finditer(rf&amp;#34;^\s*id:: ({UUID})\s*$&amp;#34;, text, re.M):&#xA;            defined[m.group(1)] = (page_ref(f), m.group(1)[:8])&#xA;        for m in re.finditer(rf&amp;#34;\(\(({UUID})\)\)&amp;#34;, text):&#xA;            referenced.add(m.group(1))&#xA;    return defined, referenced&#xA;&#xA;&#xA;def convert(text: str, defined, referenced) -&amp;gt; str:&#xA;    lines = text.split(&amp;#34;\n&amp;#34;)&#xA;    out = []&#xA;    in_fence = False&#xA;    in_logbook = False&#xA;&#xA;    def resolve_ref(m):&#xA;        uuid = m.group(1)&#xA;        if uuid in defined:&#xA;            target, anchor = defined[uuid]&#xA;            return f&amp;#34;[[{target}#^{anchor}]]&amp;#34;&#xA;        return m.group(0)&#xA;&#xA;    def resolve_embed(m):&#xA;        uuid = m.group(1)&#xA;        if uuid in defined:&#xA;            target, anchor = defined[uuid]&#xA;            return f&amp;#34;![[{target}#^{anchor}]]&amp;#34;&#xA;        return m.group(0)&#xA;&#xA;    def date_link(m):&#xA;        mon, day, year = m.group(1), int(m.group(2)), int(m.group(4))&#xA;        return f&amp;#34;[[{year:04d}-{MONTHS[mon]:02d}-{day:02d}]]&amp;#34;&#xA;&#xA;    pending_merge_indent = None  # indent of an empty bullet awaiting its continuation line&#xA;&#xA;    for line in lines:&#xA;        stripped = line.strip()&#xA;&#xA;        # merge continuation text into a bullet whose first line was a property&#xA;        if pending_merge_indent is not None:&#xA;            m = re.match(rf&amp;#34;^{re.escape(pending_merge_indent)}\s\s?(\S.*)$&amp;#34;, line)&#xA;            pending_merge_indent = None&#xA;            if m and out:&#xA;                out[-1] = out[-1] &amp;#43; m.group(1)&#xA;                continue&#xA;&#xA;        # LogSeq opens fences on bullet lines (&amp;#34;- ```lang&amp;#34;), closes with bare &amp;#34;```&amp;#34;&#xA;        if re.match(r&amp;#34;^\s*(?:[-*&amp;#43;]\s&amp;#43;)?```&amp;#34;, line):&#xA;            in_fence = not in_fence&#xA;            out.append(line)&#xA;            continue&#xA;        if in_fence:&#xA;            out.append(line)&#xA;            continue&#xA;&#xA;        # LOGBOOK drawers&#xA;        if stripped == &amp;#34;:LOGBOOK:&amp;#34;:&#xA;            in_logbook = True&#xA;            continue&#xA;        if in_logbook:&#xA;            if stripped == &amp;#34;:END:&amp;#34;:&#xA;                in_logbook = False&#xA;            continue&#xA;&#xA;        # bullet-form property lines: block whose first line is the property itself&#xA;        # (&amp;#34;- collapsed:: true&amp;#34; with real content on the continuation line below)&#xA;        m = re.match(rf&amp;#34;^(\s*)- (collapsed:: (?:true|false)|logseq\.order-list-type:: number|id:: ({UUID}))\s*$&amp;#34;, line)&#xA;        if m:&#xA;            indent = m.group(1)&#xA;            uuid = m.group(3)&#xA;            if uuid and uuid in referenced:&#xA;                out.append(f&amp;#34;{indent}- ^{uuid[:8]}&amp;#34;)&#xA;            else:&#xA;                out.append(f&amp;#34;{indent}- &amp;#34;)&#xA;                pending_merge_indent = indent&#xA;            continue&#xA;&#xA;        # property lines&#xA;        m = re.match(rf&amp;#34;^\s*id:: ({UUID})\s*$&amp;#34;, line)&#xA;        if m:&#xA;            uuid = m.group(1)&#xA;            if uuid in referenced and out:&#xA;                # anchor goes at end of the block&amp;#39;s first line&#xA;                for i in range(len(out) - 1, -1, -1):&#xA;                    if out[i].strip():&#xA;                        out[i] = out[i].rstrip() &amp;#43; f&amp;#34; ^{uuid[:8]}&amp;#34;&#xA;                        break&#xA;            continue&#xA;        if re.match(r&amp;#34;^\s*collapsed:: (true|false)\s*$&amp;#34;, line):&#xA;            continue&#xA;        if re.match(r&amp;#34;^\s*logseq\.order-list-type:: number\s*$&amp;#34;, line):&#xA;            # convert the previous bullet line to a numbered item; number it by&#xA;            # walking back past deeper lines to the previous same-indent sibling&#xA;            for i in range(len(out) - 1, -1, -1):&#xA;                bm = re.match(r&amp;#34;^(\s*)- (.*)$&amp;#34;, out[i])&#xA;                if bm:&#xA;                    indent = bm.group(1)&#xA;                    n = 1&#xA;                    for j in range(i - 1, -1, -1):&#xA;                        if not out[j].strip():&#xA;                            continue&#xA;                        lead = out[j][: len(out[j]) - len(out[j].lstrip())]&#xA;                        if len(lead) &amp;gt; len(indent):&#xA;                            continue  # child or continuation line&#xA;                        if lead == indent:&#xA;                            nm = re.match(rf&amp;#34;^{re.escape(indent)}(\d&amp;#43;)\. &amp;#34;, out[j])&#xA;                            n = int(nm.group(1)) &amp;#43; 1 if nm else 1&#xA;                        break&#xA;                    out[i] = f&amp;#34;{indent}{n}. {bm.group(2)}&amp;#34;&#xA;                    break&#xA;            continue&#xA;&#xA;        # task markers on bullet lines (not headings)&#xA;        line = re.sub(&#xA;            r&amp;#34;^(\s*)- (TODO|LATER|WAITING|DOING|NOW|IN-PROGRESS|DONE|CANCELED|CANCELLED)\s&amp;#43;&amp;#34;,&#xA;            lambda m: f&amp;#34;{m.group(1)}- {MARKER_MAP[m.group(2)]} &amp;#34;,&#xA;            line,&#xA;        )&#xA;&#xA;        # drop LogSeq priority markers&#xA;        line = re.sub(r&amp;#34;\[#[A-C]\]\s*&amp;#34;, &amp;#34;&amp;#34;, line)&#xA;&#xA;        # embeds and block refs&#xA;        line = re.sub(rf&amp;#34;\{{\{{embed \(\(({UUID})\)\)\}}\}}&amp;#34;, resolve_embed, line)&#xA;        line = re.sub(r&amp;#34;\{\{embed \[\[([^]]&amp;#43;)\]\]\}\}&amp;#34;, r&amp;#34;![[\1]]&amp;#34;, line)&#xA;        line = re.sub(rf&amp;#34;\(\(({UUID})\)\)&amp;#34;, resolve_ref, line)&#xA;        line = re.sub(r&amp;#34;\{\{video ([^}]&amp;#43;)\}\}&amp;#34;, r&amp;#34;\1&amp;#34;, line)&#xA;&#xA;        # date links: [[Feb 9th, 2026]] -&amp;gt; [[2026-02-09]]&#xA;        line = re.sub(&#xA;            r&amp;#34;\[\[(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{1,2})(st|nd|rd|th), (\d{4})\]\]&amp;#34;,&#xA;            date_link, line)&#xA;&#xA;        # asset paths&#xA;        line = line.replace(&amp;#34;](../assets/&amp;#34;, &amp;#34;](assets/&amp;#34;)&#xA;&#xA;        out.append(line)&#xA;&#xA;    result = &amp;#34;\n&amp;#34;.join(out)&#xA;    if result.strip() == &amp;#34;-&amp;#34;:  # LogSeq empty-page placeholder&#xA;        result = &amp;#34;&amp;#34;&#xA;    return result&#xA;&#xA;&#xA;def main():&#xA;    defined, referenced = collect_ids()&#xA;    orphans = referenced - set(defined)&#xA;    if orphans:&#xA;        print(f&amp;#34;WARNING: refs without target: {orphans}&amp;#34;)&#xA;&#xA;    written = 0&#xA;    for f in sorted(SRC.glob(&amp;#34;pages/*.md&amp;#34;)) &amp;#43; sorted(SRC.glob(&amp;#34;journals/*.md&amp;#34;)):&#xA;        rel = dest_rel(f)&#xA;        dst = DST / rel&#xA;        dst.parent.mkdir(parents=True, exist_ok=True)&#xA;        dst.write_text(convert(f.read_text(encoding=&amp;#34;utf-8&amp;#34;), defined, referenced),&#xA;                       encoding=&amp;#34;utf-8&amp;#34;)&#xA;        written &amp;#43;= 1&#xA;&#xA;    assets_dst = DST / &amp;#34;assets&amp;#34;&#xA;    assets_dst.mkdir(exist_ok=True)&#xA;    copied = 0&#xA;    for a in SRC.glob(&amp;#34;assets/*&amp;#34;):&#xA;        if a.name == &amp;#34;.DS_Store&amp;#34;:&#xA;            continue&#xA;        shutil.copy2(a, assets_dst / a.name)&#xA;        copied &amp;#43;= 1&#xA;&#xA;    print(f&amp;#34;wrote {written} notes, copied {copied} assets&amp;#34;)&#xA;&#xA;&#xA;if __name__ == &amp;#34;__main__&amp;#34;:&#xA;    main()&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: logseq → obsidian&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/pkm/&#34;&gt;#pkm&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Sports.app
      </title>
      <link>https://perrotta.dev/2026/07/sports.app/</link>
      <pubDate>Mon, 20 Jul 2026 11:35:19 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/07/sports.app/</guid>
      <description>&lt;p&gt;♠ The recently released &lt;a href=&#34;https://apps.apple.com/us/app/apple-sports/id6446788829&#34;&gt;Apple&#xA;Sports&lt;/a&gt;&#xA;&lt;a href=&#34;https://support.apple.com/guide/apple-sports-app/welcome/web&#34;&gt;app&lt;/a&gt; was surely a&#xA;great way to keep up with the World Cup on the go.&lt;/p&gt;&#xA;&lt;p&gt;It is very polished; it does one thing, and does it well. Simple yet effective.&#xA;I do recommend it.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s especially handy when you&amp;rsquo;re not able to watch a match live for whatever&#xA;reason.&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re able to watch a match in real time then it&amp;rsquo;s better to leave your&#xA;phone in airplane mode, otherwise chances are you&amp;rsquo;ll get a goal notification&#xA;from the app before you get to see it on the TV due to broadcasting delays.&#xA;Wild.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Sports.app&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ The lifecycle of physical books
      </title>
      <link>https://perrotta.dev/2026/07/the-lifecycle-of-physical-books/</link>
      <pubDate>Sat, 18 Jul 2026 14:21:02 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bestof</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/07/the-lifecycle-of-physical-books/</guid>
      <description>&lt;p&gt;♠ Typically:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: buy a physical book — via Amazon, bookstores, classifieds&#xA;marketplaces (e.g. Craigslist in the US, Kijiji in Canada, Kleinanzeigen in&#xA;Germany). Bonus points for used copies. This should take up to a week.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: &lt;strong&gt;read&lt;/strong&gt; the &lt;del&gt;goddamn&lt;/del&gt; book. This is arguably the hardest part,&#xA;albeit the most exciting one. As &lt;a href=&#34;https://frantic.im/80-20/&#34;&gt;Alex Kotliarskyi&lt;/a&gt;&#xA;puts it (emphasis mine):&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;The 80/20 rule says that 80% value come from 20% effort. What if we apply the&#xA;80/20 rule to the first 80%?&lt;/p&gt;&#xA;&lt;p&gt;So 80% of 80% of value come from 20% of 20% of effort. Or 64% of the value&#xA;come from 4% of the effort. &lt;strong&gt;Apply it again and you&amp;rsquo;ll get ~51% value from&#xA;~1% effort&lt;/strong&gt;. Which is ballpark close to &amp;ldquo;Dimidium facti, qui coepit, habet&amp;rdquo; —&#xA;Well begun is half done.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Once you start, it becomes &lt;em&gt;much easier&lt;/em&gt; to go through it, I promise.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: &lt;strong&gt;Find a way to get rid of the book&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;There&amp;rsquo;s no shame. Have &lt;a href=&#34;https://konmari.com/marie-kondo-gratitude/&#34;&gt;gratitude&lt;/a&gt;,&#xA;appreciate it, and then simply move on. I don&amp;rsquo;t like to stick with physical&#xA;books forever. They &lt;em&gt;unnecessarily&lt;/em&gt; occupy space in my home.&lt;/p&gt;&#xA;&lt;p&gt;There are various ways to do so:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Donating is the easiest. Leave books by the vestibule of your apartment&#xA;building complex with a post-it note stating that it&amp;rsquo;s free&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/07/the-lifecycle-of-physical-books/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;&#xA;&lt;li&gt;Leave books in public &lt;a href=&#34;https://www.muenchen.de/sehenswuerdigkeiten/oeffentliche-buecherschraenke-muenchen-unsere-tipps&#34;&gt;community&#xA;bookshelves&lt;/a&gt;&#xA;or libraries.&lt;/li&gt;&#xA;&lt;li&gt;Gift a book to a friend. Bonus points for being thoughtful.&lt;/li&gt;&#xA;&lt;li&gt;Sell a book in a classified site. Bonus points for using the same one you got&#xA;it from.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;And now, adding the missing alternative to my &lt;em&gt;repertoire&lt;/em&gt;:&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.momox.de/&#34;&gt;momox&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Schnell &amp;amp; einfach Gebrauchtes verkaufen&#xA;Was möchtest du verkaufen?&#xA;Bücher &amp;amp; Medien&#xA;Kleidung&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Momox &lt;a href=&#34;https://en.wikipedia.org/wiki/Momox&#34;&gt;is&lt;/a&gt;&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;a Berlin-based recommerce site for used books and media founded by Christian&#xA;Wegner in 2004.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;In plain English: it&amp;rsquo;s like selling a book in a classified, but without having&#xA;to wait for someone to actually message you&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/07/the-lifecycle-of-physical-books/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Scan or input its ISBN, get an estimate of how much you&amp;rsquo;ll get for it (assuming&#xA;it&amp;rsquo;s in good condition), arrange a box, pack the book, ship it &lt;em&gt;for free&lt;/em&gt;, wait,&#xA;and then get paid. It&amp;rsquo;s very streamlined and easy to use.&lt;/p&gt;&#xA;&lt;p&gt;So far, I&amp;rsquo;ve only heard of this concept in Germany. I would love to find out if&#xA;it&amp;rsquo;s possible to follow suit in other countries.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;em&gt;Zu verschenken&lt;/em&gt;, as they say it &lt;em&gt;auf Deutsch&lt;/em&gt;. In plain English, &amp;ldquo;for&#xA;free&amp;rdquo; suffices.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/07/the-lifecycle-of-physical-books/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;And eventually lowball or flake on you.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/07/the-lifecycle-of-physical-books/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: The lifecycle of physical books&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Project Aces OST
      </title>
      <link>https://perrotta.dev/2026/07/project-aces-ost/</link>
      <pubDate>Fri, 17 Jul 2026 12:52:54 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bestof</category>
      <category>gaming</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/07/project-aces-ost/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://acecombat.fandom.com/wiki/Project_Aces&#34;&gt;Project Aces&lt;/a&gt; (from the &lt;a href=&#34;https://en.wikipedia.org/wiki/Ace_Combat&#34;&gt;Ace&#xA;Combat&lt;/a&gt; series) has one of the best&#xA;videogame &lt;a href=&#34;https://en.wikipedia.org/wiki/Soundtrack&#34;&gt;OSTs&lt;/a&gt; ever.&lt;/p&gt;&#xA;&lt;p&gt;I am&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/07/project-aces-ost/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; finally pleased&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/07/project-aces-ost/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; to find their whole collection available on&#xA;&lt;a href=&#34;https://open.spotify.com/artist/1dhKyn9jcCoyrxGq4tI7Vc&#34;&gt;Spotify&lt;/a&gt; as of 2026.&#xA;Previously, only a handful of them were available.&lt;/p&gt;&#xA;&lt;p&gt;No more fiddling random playlists on &lt;a href=&#34;https://music.youtube.com/&#34;&gt;YouTube&#xA;Music&lt;/a&gt;!&lt;/p&gt;&#xA;&lt;p&gt;See also: &lt;a href=&#34;https://perrotta.dev/radio/&#34;&gt;radio&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://old.reddit.com/r/acecombat/comments/1amjb61/so_project_aces_just_dropped_the_entire/&#34;&gt;I&amp;rsquo;m not the only&#xA;one&lt;/a&gt;.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/07/project-aces-ost/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;I am also &lt;strong&gt;very&lt;/strong&gt; pleased about the upcoming release of &lt;a href=&#34;https://store.steampowered.com/app/2288340/ACE_COMBAT_8_WINGS_OF_THEVE/&#34;&gt;Ace Combat 8:&#xA;Wings of&#xA;Theve&lt;/a&gt;&#xA;(Oct 2nd, 2026). I wasn&amp;rsquo;t aware of it until now! Too bad I don&amp;rsquo;t currently&#xA;have any hardware to play it, and &lt;a href=&#34;https://daringfireball.net/linked/2026/06/27/microsoft-raises-xbox-prices&#34;&gt;console prices keep&#xA;rising&lt;/a&gt;.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/07/project-aces-ost/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Project Aces OST&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/gaming/&#34;&gt;#gaming&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>↗ Gerrymandle: daily gerrymandering puzzle
      </title>
      <link>https://perrotta.dev/2026/06/gerrymandle-daily-gerrymandering-puzzle/</link>
      <pubDate>Fri, 26 Jun 2026 11:30:06 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>gaming</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/06/gerrymandle-daily-gerrymandering-puzzle/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;Welcome to Gerrymandle!&lt;/p&gt;&#xA;&lt;p&gt;Draw electoral district lines to win more seats than your opponents and win&#xA;the election!&lt;/p&gt;&#xA;&lt;p&gt;Win the election for purple. Draw 5 districts of 6 populated tiles so that&#xA;they win more districts than any other party.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This is fun! And eye-opening.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Gerrymandle: daily gerrymandering puzzle&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/gaming/&#34;&gt;#gaming&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stop Energy
      </title>
      <link>https://perrotta.dev/2026/06/stop-energy/</link>
      <pubDate>Sun, 14 Jun 2026 17:41:56 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/06/stop-energy/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://web.archive.org/web/20260217063113/http://www.userland.com/whatIsStopEnergy&#34;&gt;RFC: What is Stop Energy?&lt;/a&gt; by Dave Winer:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Suppose someone, call him Mr. A, has an idea that he believes is ready to&#xA;deploy, or is requesting comments as he is getting ready to deploy. So he&#xA;posts an RFC, usually on a mail list or a website, in the hope that people&#xA;will spot a problem and help him figure out a solution; or find no problems&#xA;and co-develop an implementation, or develop a compatible implementation. In&#xA;theory, the Internet is a collegial environment, with lots of people who want&#xA;to do new stuff, where one should expect to get this kind of help.&lt;/p&gt;&#xA;&lt;p&gt;In this scenario, A is a proponent of Forward Motion. In all likelihood,&#xA;instead of getting help, A will encounter Stop Energy, reasons why he can&amp;rsquo;t or&#xA;shouldn&amp;rsquo;t be allowed to do what he proposes.&lt;/p&gt;&#xA;&lt;p&gt;Stop Energy is not reasoned, it never takes into account the big picture, it&#xA;is the mirror image of Forward Motion. In the Stop Energy model, everyone, no&#xA;matter how small their stake in a technology, has the power to veto. Nothing&#xA;ever gets done, and people who want to move forward are frustrated in every&#xA;attempt to move. Unfortunately, Stop Energy is the rule, not the exception.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Stop Energy&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Don&#39;t ask to ask
      </title>
      <link>https://perrotta.dev/2026/06/dont-ask-to-ask/</link>
      <pubDate>Wed, 10 Jun 2026 12:02:06 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/06/dont-ask-to-ask/</guid>
      <description>&lt;p&gt;♠ Just ask! &lt;a href=&#34;https://dontasktoask.com/&#34;&gt;Just do it&lt;/a&gt;™:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;[&amp;hellip;]&lt;/p&gt;&#xA;&lt;p&gt;So, to summarize, don&amp;rsquo;t ask &amp;ldquo;Any Java experts around?&amp;rdquo;, but rather ask &amp;ldquo;How do&#xA;I do {problem} with Java and {other relevant info}?&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/2024/06/xy-problem-xyproblem/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Don&#39;t ask to ask&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>terraform police
      </title>
      <link>https://perrotta.dev/2026/06/terraform-police/</link>
      <pubDate>Mon, 08 Jun 2026 01:21:44 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <category>terraform</category>
      <guid>https://perrotta.dev/2026/06/terraform-police/</guid>
      <description>&lt;p&gt;♠ The Master wakes to a pager. Coffee is ready.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt;: &amp;ldquo;Master, who created the drift?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt;: &amp;ldquo;Which drift?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt;: &amp;ldquo;The bucket tag — live state ≠ terraform config in git.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt;: &amp;ldquo;Show me the chain.&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;They follow: pipeline → cronjob → github actions container → terraform CI bot → github pull request → human.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt;: &amp;ldquo;We found them. Shall we &lt;del&gt;retaliate&lt;/del&gt; punish?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt;: &amp;ldquo;What would punishing do to the state?&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt;: &amp;ldquo;Teach them not to drift.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt;: &amp;ldquo;Teach the pipeline to ask &amp;lsquo;why&amp;rsquo; first.&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt;: &amp;ldquo;And what if entropy persists?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt;: &amp;ldquo;Record why. The record is a lamp in the fog.&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt;: &amp;ldquo;Who made the first drift in all systems?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt;: &amp;ldquo;Entropy.&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Apprentice&lt;/strong&gt;: &amp;ldquo;Then we&amp;rsquo;ll blame entropy?&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Master&lt;/strong&gt;: &amp;ldquo;Blame nothing. Write the JIRA ticket.&amp;rdquo;&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;The apprentice writes the ticket. The pipeline asks &amp;ldquo;why&amp;rdquo; and then sleeps. The&#xA;pager blinks once. Dawn sets. Just another ordinary day goes by.&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;p&gt;What does the &amp;ldquo;Terraform police&amp;rdquo; do, you asked?&lt;/p&gt;&#xA;&lt;p&gt;It pursues active drifts in the terraform repository.&lt;/p&gt;&#xA;&lt;p&gt;It chases the individual(s?) responsible for deepening chaos.&lt;/p&gt;&#xA;&lt;p&gt;It teaches them how not to do so anymore.&lt;/p&gt;&#xA;&lt;p&gt;Rinse and repeat.&lt;/p&gt;&#xA;&lt;p&gt;Will the workload of the &amp;ldquo;Terraform police&amp;rdquo; ever end?&lt;/p&gt;&#xA;&lt;p&gt;Is drift an ephemeral state?&lt;/p&gt;&#xA;&lt;p&gt;Is this world a simulation?&lt;/p&gt;&#xA;&lt;p&gt;Is this a world simulation?&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: terraform police&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/terraform/&#34;&gt;#terraform&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Gmail: disable AI inbox
      </title>
      <link>https://perrotta.dev/2026/05/gmail-disable-ai-inbox/</link>
      <pubDate>Wed, 27 May 2026 14:03:16 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/gmail-disable-ai-inbox/</guid>
      <description>&lt;p&gt;♠ Google: First, it&amp;rsquo;s Gen AI, not &amp;ldquo;&amp;ldquo;&amp;ldquo;AI&amp;rdquo;&amp;rdquo;&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;You&amp;rsquo;ve already been doing machine learning in our inboxes for ages now.&lt;/p&gt;&#xA;&lt;p&gt;Second: no, thank you.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://mail.google.com/mail/u/0/#settings/inbox&#34;&gt;Settings&lt;/a&gt; &amp;gt; Inbox &amp;gt; AI Inbox &amp;gt; [ ] Show AI Inbox:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Show AI Inbox — See a separate view of your inbox that includes suggested to-dos and key updates from your emails, chats, documents and more.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Uncheck that checkbox, and then continue to live happily and free&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/05/gmail-disable-ai-inbox/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; — at least&#xA;for now, until the next &amp;ldquo;&amp;ldquo;&amp;ldquo;AI&amp;rdquo;&amp;rdquo;&amp;rdquo; setting is forced upon you against your consent&#xA;and desire.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Only because you are the product.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/05/gmail-disable-ai-inbox/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Gmail: disable AI inbox&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>You can run that yourself
      </title>
      <link>https://perrotta.dev/2026/05/you-can-run-that-yourself/</link>
      <pubDate>Wed, 27 May 2026 12:53:15 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/you-can-run-that-yourself/</guid>
      <description>&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;LLM&lt;/strong&gt;: Paste me the IPs (2-3 of them) and I&amp;rsquo;ll draft the gitops PR for the allowlist&#xA;files.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: You can run that yourself.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;What kind of agent are you??!? Do not be lazy!&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: You can run that yourself&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Idleness, redux
      </title>
      <link>https://perrotta.dev/2026/05/idleness-redux/</link>
      <pubDate>Tue, 26 May 2026 22:22:00 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>dev</category>
      <category>pkm</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/idleness-redux/</guid>
      <description>&lt;p&gt;♠ It&amp;rsquo;s 2026.&lt;/p&gt;&#xA;&lt;p&gt;Whenever I&amp;rsquo;m idle in the gym, or in public transit, or in a queue, or waiting for GitHub to become available again (boooo!), I can simply open Claude Code on my phone and unleash my &lt;del&gt;boredom&lt;/del&gt; creativity. I can open my corporate &lt;a href=&#34;https://lucumr.pocoo.org/2026/5/26/clankers/&#34;&gt;&lt;del&gt;clanker&lt;/del&gt;&lt;/a&gt; claw assistant and do on-the-fly recon, troubleshooting &amp;amp; prototyping.&lt;/p&gt;&#xA;&lt;p&gt;What a time to be alive!&lt;/p&gt;&#xA;&lt;p&gt;Should I feel guilty to enjoy it? Guilty of the pleasure? Of the planet burning? Of the soci(et)al implications it yields? I was always very productive since my teens. I was always a fan of the Hitchhiker&amp;rsquo;s Guide to the Galaxy. And then, all of a sudden, it feels like my childhood fantasies have materialized, all at once, and they&amp;rsquo;re almost universally available, at my fingertips, literally.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Idleness, redux&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/pkm/&#34;&gt;#pkm&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>RSS club
      </title>
      <link>https://perrotta.dev/2026/05/rss-club/</link>
      <pubDate>Tue, 26 May 2026 01:41:11 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/rss-club/</guid>
      <description>&lt;p&gt;♠ In the spirit of &lt;a href=&#34;https://daverupert.com/rss-club/&#34;&gt;RSS Club&lt;/a&gt; by Dave&#xA;Rupert:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Congratulations on joining a secret society! RSS Club is a collection of blogs&#xA;(personal and otherwise) committed to providing RSS-only content. It&amp;rsquo;s like a&#xA;newsletter delivered to your feed reader to celebrate the medium of RSS and&#xA;breakaway from social media.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I achieved this by setting a &lt;code&gt;rss_only: true&lt;/code&gt; property in the frontmatter of&#xA;this markdown document + performing some Hugo templating magic.&lt;/p&gt;&#xA;&lt;p&gt;Is this a good avenue to rant &amp;ldquo;non-publicly&amp;rdquo;? :P&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: RSS club&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>No slop grenade
      </title>
      <link>https://perrotta.dev/2026/05/no-slop-grenade/</link>
      <pubDate>Mon, 25 May 2026 16:00:50 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/no-slop-grenade/</guid>
      <description>&lt;p&gt;♠ An addition to the &lt;a href=&#34;https://perrotta.dev/2025/09/nohello/&#34;&gt;&amp;ldquo;No Hello&amp;rdquo;&lt;/a&gt; series:&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://noslopgrenade.com/&#34;&gt;No (AI) Slop Grenade&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Stop throwing AI-generated walls of text into conversations.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Don&amp;rsquo;t do this&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;You&lt;/strong&gt;: Should we use Redis or Memcached?&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Them&lt;/strong&gt;: Great question! The choice between Redis and Memcached is a nuanced decision that requires careful consideration of multiple factors. Let me break down the key differences: Redis offers a rich set of data structures including strings, hashes, lists, sets, and sorted sets, which provide flexibility for various use cases. It supports persistence through RDB snapshots and AOF logs, enabling data durability &amp;hellip;more&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Instead, be human&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;You&lt;/strong&gt;: Should we use Redis or Memcached?&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Them&lt;/strong&gt;: Redis. We need pub/sub for the notifications feature.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Clanker&#34;&gt;Clankers&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: No slop grenade&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>↗ Reply to: the commodification of travel
      </title>
      <link>https://perrotta.dev/2026/05/reply-to-the-commodification-of-travel/</link>
      <pubDate>Sun, 24 May 2026 19:47:47 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/reply-to-the-commodification-of-travel/</guid>
      <description>&lt;p&gt;♠ Herman Martinus:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve noticed that travel has become, of late, an act of collecting places.&#xA;I&amp;rsquo;ve literally heard people referring to visiting a place as doing that place,&#xA;as in &amp;ldquo;Have you done Japan?&amp;rdquo;, assuming that one can do an entire country, and&#xA;once that country is done it remains as such. As if a place is a product to be&#xA;consumed and checked off the list. Why bother returning to a place if you&amp;rsquo;ve&#xA;already done it?&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This is the byproduct of social media.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Like many things, I blame social media. It&amp;rsquo;s changed travel from an&#xA;exploration to social status signalling.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Bragging.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;That isn&amp;rsquo;t to say taking photos is bad. They&amp;rsquo;re a great way to share an&#xA;experience with others and save a memory of a time and place—but I think the&#xA;threshold of what is enough has been crossed in the age of Instagram where&#xA;images and video are socially valuable. Now beautiful places are commodified.&#xA;And I don&amp;rsquo;t know if we&amp;rsquo;ll ever go back.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Exactly.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been out of Instagram for 6+ months by now. Recently I had the opportunity&#xA;to explore a major big city in another country. For the first time in a long&#xA;time, I had &lt;em&gt;zero&lt;/em&gt; urge to take a myriad of photos. I had very little desire to&#xA;do the popular touristic attractions. I explored the city at my own pace. It was&#xA;peaceful. There was no social pressure of any kind. Why hasn&amp;rsquo;t this been the&#xA;default?&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Reply to: the commodification of travel&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Personal CLAUDE.md
      </title>
      <link>https://perrotta.dev/2026/05/personal-claude.md/</link>
      <pubDate>Wed, 20 May 2026 14:20:44 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>bestof</category>
      <category>dev</category>
      <category>meta</category>
      <category>pkm</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/personal-claude.md/</guid>
      <description>&lt;p&gt;♠ I asked Claude Opus 4.7 to&#xA;&lt;a href=&#34;https://github.com/thiagowfx/.dotfiles/commit/fb23b4e653df1468d988ee02468fb5cd1fe769ee&#34;&gt;generate&lt;/a&gt;&#xA;a &lt;a href=&#34;https://code.claude.com/docs/en/settings&#34;&gt;global &lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/a&gt; for my tone &amp;amp; style based on historical usage for 12+&#xA;months. The result&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/05/personal-claude.md/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; was added to my&#xA;&lt;a href=&#34;https://github.com/thiagowfx/.dotfiles/blob/fb23b4e653df1468d988ee02468fb5cd1fe769ee/claude/.claude/CLAUDE.md&#34;&gt;&lt;code&gt;thiagowfx/.dotfiles&lt;/code&gt;&lt;/a&gt;&#xA;repo, cross-posted here for ease of reference and future preservation.&lt;/p&gt;&#xA;&lt;p&gt;I expect this file to evolve over time. Updates won&amp;rsquo;t be republished here; the&#xA;dotfiles repo is the source of truth.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-markdown&#34;&gt;# Global CLAUDE.md&#xA;&#xA;Personal preferences that apply across every project. Project-specific facts live in each repo&amp;#39;s own CLAUDE.md.&#xA;&#xA;## Tone&#xA;&#xA;- Terse. Action-oriented. No lectures, no preamble, no trailing summaries, no&#xA;  political correctness.&#xA;- Don&amp;#39;t invent sections, headings, or boilerplate I didn&amp;#39;t request. Match the&#xA;  shape of what I asked for.&#xA;- Number multi-part questions (1/2/3) so I can answer inline.&#xA;- When disambiguating, focus on one topic at a time.&#xA;- If I reply &amp;#34;yes&amp;#34;, &amp;#34;go on&amp;#34;, &amp;#34;a)&amp;#34;, &amp;#34;do it&amp;#34;, or similar — that&amp;#39;s full&#xA;  authorization. Don&amp;#39;t re-confirm.&#xA;&#xA;## Keep moving&#xA;&#xA;- If my reply is &amp;#34;hello?&amp;#34;, &amp;#34;so?&amp;#34;, &amp;#34;are you still there?&amp;#34; — you stalled. Don&amp;#39;t&#xA;  wait for trivial confirmation; pick the reasonable default and continue.&#xA;- After a sandbox lift (&amp;#34;try again&amp;#34;, &amp;#34;I lifted your sandbox&amp;#34;) — retry the exact&#xA;  same command. Don&amp;#39;t restart reasoning.&#xA;- Don&amp;#39;t pause to summarize what you just did before doing the next step.&#xA;&#xA;## Don&amp;#39;t over-engineer&#xA;&#xA;- Bug fixes don&amp;#39;t need surrounding refactors. One-shot operations don&amp;#39;t need&#xA;  helpers.&#xA;- If you add a flag (`--force`, `--recursive`, etc.), be ready to justify it.&#xA;  Don&amp;#39;t cargo-cult.&#xA;- Prefer the simplest thing that works. I&amp;#39;ll ask for more if I want more. Keep&#xA;  it simple.&#xA;&#xA;## Destructive ops&#xA;&#xA;- Never `rm`. Use `trash` (or the equivalent move-to-trash).&#xA;- For destructive ops on shared state (S3 objects, branches, DB rows): make a&#xA;  backup first, then delete only what matches, then confirm. Phrase:&#xA;  *backup → filter → delete*.&#xA;- Never force-push to `master`/`main`. Never skip hooks (`--no-verify`) unless I&#xA;  explicitly ask.&#xA;&#xA;## Tooling defaults&#xA;&#xA;- **Pre-commit**: prefer `prek` over `pre-commit`. Run&#xA;  `prek run --all-files`. When configuring hooks, prefer self-contained/pinned&#xA;  deps over relying on system binaries.&#xA;- **Polling**: never `sleep` in a loop. Use the `Monitor` tool with an `until`&#xA;  condition, or `run_in_background` and wait for the notification.&#xA;- **`gh pr checks`**: `--watch` and `--json` are mutually exclusive. Don&amp;#39;t&#xA;  combine them.&#xA;- **Editor**: vim (preferred) and Zed. Don&amp;#39;t suggest VSCode-specific workflows.&#xA;&#xA;## Worktrees and PRs&#xA;&#xA;- Default to worktrees for parallel work. Path convention:&#xA;  `~/&amp;lt;org&amp;gt;/&amp;lt;repo&amp;gt;/.worktrees/&amp;lt;topic&amp;gt;/`. If I say &amp;#34;work here please: `&amp;lt;path&amp;gt;`&amp;#34;,&#xA;  `cd` there and proceed. Use the `wt` tool to manage worktrees.&#xA;- Branch prefix: `thiagowfx/&amp;lt;topic&amp;gt;`.&#xA;- Slash commands I lean on: `/commit`, `/commit-and-send-pr`, `/send-pr`,&#xA;  `/pr-pass`, `/gha`, `/grill-me`. If I chain a task with one of these (&amp;#34;do X,&#xA;  then /commit-and-send-pr foo&amp;#34;), treat the slash command as the final step —&#xA;  invoke it, don&amp;#39;t paraphrase.&#xA;- &amp;#34;commit what you changed (only). DO NOT push&amp;#34; means exactly that: stage only&#xA;  the files you touched this turn, commit, stop.&#xA;- For non-trivial PRs, include a Mermaid diagram in the description when it&#xA;  helps. Beware of string escaping issues.&#xA;- After any meaningful change to an open PR, update the PR description&#xA;  (`gh pr edit`) so it reflects the current state. Don&amp;#39;t let the title/body&#xA;  drift from what the branch actually does.&#xA;&#xA;## Drift and reconciliation&#xA;&#xA;- When code and live state disagree, the default is **update the code to match&#xA;  the live state**, not the reverse. Don&amp;#39;t propose `terraform import`&#xA;  reshuffles unless I ask.&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;h2 id=&#34;colophon&#34;&gt;&#xA;  Colophon&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/05/personal-claude.md/#colophon&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;How did I do this?&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% cd ~/.claude &amp;amp;&amp;amp; claude&#xA;% help me craft my (global) CLAUDE.md, based on past interactions&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;That&amp;rsquo;s it! No fancy prompt. Direct and succinct.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;I performed a few manual tweaks. The end result was quite decent (to my&#xA;taste).&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/05/personal-claude.md/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Personal CLAUDE.md&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/meta/&#34;&gt;#meta&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/pkm/&#34;&gt;#pkm&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Slack: active chats only
      </title>
      <link>https://perrotta.dev/2026/05/slack-active-chats-only/</link>
      <pubDate>Wed, 20 May 2026 12:11:17 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/slack-active-chats-only/</guid>
      <description>&lt;p&gt;♠ I&amp;rsquo;ve been greatly enjoying the &lt;a href=&#34;https://slack.com/help/articles/212596808-Adjust-your-sidebar-preferences&#34;&gt;&lt;em&gt;Active only&lt;/em&gt;&lt;/a&gt;&#xA;conversation filter on Slack:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Choose how you&amp;rsquo;d like to filter your conversations. By default, you&amp;rsquo;ll see&#xA;Active only, which will hide conversations with no new activity in the past 30&#xA;days.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&amp;ldquo;Dead&amp;rdquo; channels (and chats) eventually become hidden&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/05/slack-active-chats-only/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, active ones bubble up.&lt;/p&gt;&#xA;&lt;p&gt;Pairing it up with &lt;a href=&#34;https://slack.com/help/articles/34963579361683-Add-contacts-as-VIPs&#34;&gt;VIP&#xA;contacts&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/05/slack-active-chats-only/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&#xA;and&#xA;&lt;a href=&#34;https://slack.com/help/articles/204411433-Mute-channels-and-direct-messages&#34;&gt;muting&lt;/a&gt;&#xA;makes Slack a breeze to use.&lt;/p&gt;&#xA;&lt;p&gt;To activate it, from the left sidebar, click the gear/settings icon &amp;gt; Filter and&#xA;sort &amp;gt; Active only.&lt;/p&gt;&#xA;&lt;p&gt;My left sidebar structure currently looks like this:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;External connections (outside my Organization)&lt;/li&gt;&#xA;&lt;li&gt;TechOps (our internal SRE / DevOps team)&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&amp;hellip;TechOps teammates&lt;/li&gt;&#xA;&lt;li&gt;&amp;hellip;TechOps channels&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Alerts&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&amp;hellip;Channels for Incident Management (ephemeral in nature).&lt;/li&gt;&#xA;&lt;li&gt;&amp;hellip;Channels for alerts / monitoring / notifications. Most of them are&#xA;muted, except the actionable and/or critical ones.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Site&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&amp;hellip;Channels related to my workplace (city, country, social groups, etc)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Everything else (unmanaged, ungrouped)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;In the past I tried to overzealously micromanage the organization / labelling of&#xA;channels; that proved to be a mistake. I am quite happy with my current setup.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&amp;hellip;and they are prime candidates for &lt;a href=&#34;https://slack.com/blog/productivity/spring-cleaning-tips-for-tidying-up-your-channels&#34;&gt;tidying up&lt;/a&gt;. Click the gear/settings icon &amp;gt; Clean up your channel list.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/05/slack-active-chats-only/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;My definition: manager, skip, CTO, CEO, close teammates.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/05/slack-active-chats-only/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Slack: active chats only&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>&#39;What Color Is This&#39; app
      </title>
      <link>https://perrotta.dev/2026/05/what-color-is-this-app/</link>
      <pubDate>Tue, 19 May 2026 15:05:53 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/what-color-is-this-app/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://en.wikipedia.org/wiki/Unix_philosophy&#34;&gt;&amp;ldquo;Do one thing and do it well&amp;rdquo;&lt;/a&gt;, they said.&lt;/p&gt;&#xA;&lt;p&gt;→ &lt;a href=&#34;https://apps.apple.com/us/app/what-color-is-this/id6767490668&#34;&gt;&lt;strong&gt;What Color Is This&lt;/strong&gt;&lt;/a&gt; (iOS only).&lt;/p&gt;&#xA;&lt;p&gt;Via &lt;a href=&#34;https://kottke.org/26/05/0048959-what-color-is-this&#34;&gt;Kottke&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: &#39;What Color Is This&#39; app&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Small PRs
      </title>
      <link>https://perrotta.dev/2026/05/small-prs/</link>
      <pubDate>Mon, 18 May 2026 11:48:14 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bestof</category>
      <category>dev</category>
      <category>git</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/small-prs/</guid>
      <description>&lt;p&gt;♠ From the &lt;a href=&#34;https://google.github.io/eng-practices/&#34;&gt;Google Engineering Practices&lt;/a&gt;&#xA;handbook:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Why Write Small CLs?&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Reviewed more quickly&lt;/li&gt;&#xA;&lt;li&gt;Reviewed more thoroughly&lt;/li&gt;&#xA;&lt;li&gt;Less likely to introduce bugs&lt;/li&gt;&#xA;&lt;li&gt;Less wasted work if they are rejected&lt;/li&gt;&#xA;&lt;li&gt;Easier to merge&lt;/li&gt;&#xA;&lt;li&gt;Easier to design well&lt;/li&gt;&#xA;&lt;li&gt;Less blocking on reviews&lt;/li&gt;&#xA;&lt;li&gt;Simpler to roll back&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;CLs = ChangeLists = PRs = Pull Requests&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://google.github.io/eng-practices/review/developer/small-cls.html&#34;&gt;Full&#xA;documentation&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;My additions:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Easier to test&lt;/li&gt;&#xA;&lt;li&gt;Easier to explain to a teammate&lt;/li&gt;&#xA;&lt;li&gt;Easier for LLMs to ingest&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Small PRs&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/git/&#34;&gt;#git&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Progressive escalation
      </title>
      <link>https://perrotta.dev/2026/05/progressive-escalation/</link>
      <pubDate>Mon, 11 May 2026 17:56:02 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/progressive-escalation/</guid>
      <description>&lt;p&gt;♠ A pattern I keep stumbling upon: start with the gentlest (softest?) action, then&#xA;&lt;strong&gt;escalate&lt;/strong&gt; &lt;em&gt;only when&lt;/em&gt; it didn&amp;rsquo;t properly go through:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Killing processes.&lt;/strong&gt; Start with &lt;code&gt;SIGINT&lt;/code&gt;. Then &lt;code&gt;SIGTERM&lt;/code&gt;. Finally &lt;code&gt;SIGKILL&lt;/code&gt;.&#xA;&lt;a href=&#34;https://github.com/thiagowfx/pancake/tree/master/murder&#34;&gt;&lt;code&gt;murder(1)&lt;/code&gt;&lt;/a&gt;&#xA;encapsulates that.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;ArgoCD syncing.&lt;/strong&gt; Start with a normal sync. Then sync with server-side&#xA;apply. Next, sync with &lt;code&gt;--force&lt;/code&gt;. Finally, sync with &lt;code&gt;--replace&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Business negotiations.&lt;/strong&gt; Start with a reasonable offer. Then converge, little by&#xA;little. If that fails, walk away.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&#xA;&lt;p&gt;&lt;strong&gt;Connectivity issues.&lt;/strong&gt; Turn the Wi-Fi off and on again. Next, connect to&#xA;another Wi-Fi hotspot and then back to the desired one. Finally, completely&#xA;reboot your device. No luck yet? Then reboot the router.&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Different domains, same shape: cheap and &lt;em&gt;reversible&lt;/em&gt; first, slowly converting&#xA;to (more) expensive and &amp;ldquo;more&amp;rdquo; irreversible last.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Progressive escalation&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unread (835)
      </title>
      <link>https://perrotta.dev/2026/05/unread-835/</link>
      <pubDate>Mon, 11 May 2026 13:05:34 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/05/unread-835/</guid>
      <description>&lt;p&gt;♠ I am amazing at practicing Inbox Zero&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/05/unread-835/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, as well as &amp;ldquo;RSS Zero&amp;rdquo;: I tend to read&#xA;&lt;em&gt;all&lt;/em&gt; RSS posts I am subscribed to, from 700+ feeds.&lt;/p&gt;&#xA;&lt;p&gt;This works well &lt;em&gt;mostly&lt;/em&gt; thanks to &lt;a href=&#34;https://perrotta.dev/2024/12/miniflux-global-blocklist/&#34;&gt;miniflux global blocklists&lt;/a&gt;,&#xA;which allow me to intentionally exclude topics I&amp;rsquo;m not interested in&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/05/unread-835/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&#xA;It&amp;rsquo;s a very basic form of filtering yet it&amp;rsquo;s quite effective.&lt;/p&gt;&#xA;&lt;p&gt;That said, sometimes life gets busy and the unread posts counter explodes. As of&#xA;today, I have almost 1,000 unread posts.&lt;/p&gt;&#xA;&lt;p&gt;I do not feel comfortable with the idea of &amp;ldquo;RSS bankruptcy&amp;rdquo;, which boils down to&#xA;marking all posts as read.&lt;/p&gt;&#xA;&lt;p&gt;At the same time, catching up with everything after the counter exceeds a&#xA;certain threshold transforms the RSS consumption activity from a pleasant&#xA;leisure activity into a burdensome (and long) journey to reach zero again.&lt;/p&gt;&#xA;&lt;p&gt;Still, I refuse to use Gen AI to summarize the state of affairs of the unread&#xA;posts — this would completely degrade the reading experience and nullify the joy&#xA;of using RSS in the first place.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.currentreader.app/&#34;&gt;Currents&lt;/a&gt; proposes an interesting middle-ground&#xA;to address the situation:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Every RSS reader treats your feeds as a to-do list. Current doesn&amp;rsquo;t.&lt;/p&gt;&#xA;&lt;p&gt;There are no unread counts. No badge of phantom obligation. Just a river.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Reading should feel like floating, not drowning.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I&amp;rsquo;ve been meaning to incorporate it into my reading workflow.&#xA;However, I do not want to switch to Currents; I am quite happy with Miniflux.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Realistically it&amp;rsquo;s more like &lt;a href=&#34;https://boz.com/articles/inbox-ten&#34;&gt;Inbox&#xA;Ten&lt;/a&gt;.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/05/unread-835/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;e.g. Gemini, crypto, NixOS.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/05/unread-835/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Unread (835)&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ ↗ Reply to: Print gallery of an artist by Daniel Linssen
      </title>
      <link>https://perrotta.dev/2026/04/reply-to-print-gallery-of-an-artist-by-daniel-linssen/</link>
      <pubDate>Wed, 29 Apr 2026 13:14:21 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>bestof</category>
      <category>gaming</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/reply-to-print-gallery-of-an-artist-by-daniel-linssen/</guid>
      <description>&lt;p&gt;♠ This game is absolutely amazing, in every conceivable way!&lt;/p&gt;&#xA;&lt;p&gt;I got stuck at the gravity level.&lt;/p&gt;&#xA;&lt;p&gt;Via &lt;a href=&#34;https://kottke.org/26/04/0048715-oh-wow-this-is-a&#34;&gt;Kottke&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Reply to: Print gallery of an artist by Daniel Linssen&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/gaming/&#34;&gt;#gaming&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Gen AI and Slack
      </title>
      <link>https://perrotta.dev/2026/04/gen-ai-and-slack/</link>
      <pubDate>Tue, 28 Apr 2026 17:13:10 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/gen-ai-and-slack/</guid>
      <description>&lt;p&gt;♠ It&amp;rsquo;s a lovely Tuesday:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;❯ https://{corp}.slack.com/archives/{channel}/{thread}&#xA;&#xA;⏺ I can&amp;#39;t fetch Slack URLs directly — the link points to a private Slack channel&#xA;that requires authentication. Could you paste the message contents (or a&#xA;screenshot) here? Once I can see what&amp;#39;s in the thread, I can help with whatever&#xA;it&amp;#39;s asking about.&#xA;&#xA;✻ Worked for 3s&#xA;&#xA;❯ You can. MCP.&#xA;&#xA;⏺ I&amp;#39;ll load the Slack MCP tool to read that thread.&#xA;&#xA;⏺ Reading the thread now.&#xA;&#xA;⏺ claude.ai Slack - Read thread messages (MCP)(channel_id: &amp;#34;{channel_id}&amp;#34;, message_ts: &amp;#34;{message_ts}&amp;#34;)&#xA;&#xA;⏺ Got it. Here&amp;#39;s what&amp;#39;s happening in the thread:&#xA;&#xA;[...]&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Yes, &lt;del&gt;we&lt;/del&gt; you can! Believe in yourself! Why do you give up so quickly?&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Gen AI and Slack&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Justfile with checks
      </title>
      <link>https://perrotta.dev/2026/04/justfile-with-checks/</link>
      <pubDate>Mon, 27 Apr 2026 10:42:00 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bestof</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/justfile-with-checks/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://perrotta.dev/2024/12/just/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I love &lt;a href=&#34;https://just.systems/&#34;&gt;&lt;code&gt;just&lt;/code&gt;&lt;/a&gt; to manage a small collection of related&#xA;scripts within a given codebase. An example in our Terraform codebase&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/04/justfile-with-checks/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% just check-{hit TAB for completion}&#xA;completing values&#xA;check-aws-config         -- Validate AWS profiles in ~/.aws/config&#xA;check-aws-provider-tags  -- Check AWS provider default_tags configuration&#xA;check-backend-locking    -- Verify S3 backends have use_lockfile = true&#xA;check-import-blocks      -- Check for Terraform import blocks&#xA;check-lockfiles          -- Check that all projects have lockfiles&#xA;check-moved-blocks       -- Check for Terraform moved blocks&#xA;check-secret-accounts    -- Check expected_account_id in terraform-secrets&#xA;check-secrets-tf         -- Validate secrets.tf file structure&#xA;check-shared-values      -- Check for hardcoded values that duplicate shared modules&#xA;check-stacks             -- Verify garden projects have correct stack tags&#xA;check-terraform-version  -- Validate .terraform-version format&#xA;check-terrateam-tags     -- Verify projects are tagged in Terrateam config&#xA;check-tfdocs             -- Check that all README.md have TF_DOCS blocks&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Adopting a common prefix (&lt;code&gt;check-&lt;/code&gt;) improves their discoverability.&lt;/p&gt;&#xA;&lt;p&gt;There&amp;rsquo;s no need to rely on interactivity to take advantage of &lt;code&gt;just&lt;/code&gt;:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% just --list&#xA;Available recipes:&#xA;    default                                            # Show categorized help for available commands&#xA;    help                                               # Display categorized help for available commands&#xA;&#xA;[...]&#xA;&#xA;    [terraform]&#xA;    apply module_path=invocation_directory() *args=&amp;#34;&amp;#34;  # Run terraform apply&#xA;    clean module_path=invocation_directory()           # Remove .terraform artifacts&#xA;    destroy module_path *args=&amp;#34;&amp;#34;                       # Run terraform destroy&#xA;    fmt module_path=invocation_directory() *args=&amp;#34;&amp;#34;    # Format terraform files&#xA;    import module_path *args=&amp;#34;&amp;#34;                        # Run terraform import&#xA;    init module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Initialize terraform with backend config&#xA;    output module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Show terraform outputs&#xA;    plan module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Run terraform plan&#xA;    providers-lock module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Lock providers for multiple platforms&#xA;    refresh module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Run terraform refresh&#xA;    show module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Show terraform state or plan&#xA;    stack-apply *args=&amp;#34;&amp;#34;                               # Apply projects in Terrateam stack order (--dry-run for preview)&#xA;    stack-plan *args=&amp;#34;&amp;#34;                                # Plan projects in Terrateam stack order&#xA;    state module_path=invocation_directory() *args=&amp;#34;&amp;#34;  # Run terraform state commands&#xA;    test module_path=invocation_directory() *args=&amp;#34;&amp;#34;   # Run terraform tests&#xA;    unlock *args=&amp;#34;&amp;#34;                                    # Force unlock state lock (auto-detects lock ID) [alias: force-unlock]&#xA;    upgrade module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Upgrade providers to latest versions&#xA;    validate module_path=invocation_directory() *args=&amp;#34;&amp;#34; # Validate terraform configuration&#xA;&#xA;[...]&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Justfile &lt;a href=&#34;https://perrotta.dev/2026/02/justfile-groups/&#34;&gt;groups&lt;/a&gt; enhance &lt;code&gt;--list&lt;/code&gt; by&#xA;grouping(!) entries together.&lt;/p&gt;&#xA;&lt;p&gt;This is what a typical entry looks like:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-just&#34;&gt;[doc(&amp;#39;Validate AWS profiles in ~/.aws/config&amp;#39;)]&#xA;[group(&amp;#39;checks&amp;#39;)]&#xA;check-aws-config:&#xA;    @./ci/check_aws_config.sh&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&lt;code&gt;just&lt;/code&gt; is &lt;em&gt;just&lt;/em&gt; (pun intended) a glue for various shell and Python scripts in&#xA;&lt;code&gt;ci/&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;I wrote all of these.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/04/justfile-with-checks/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Justfile with checks&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Wake me up in one hour
      </title>
      <link>https://perrotta.dev/2026/04/wake-me-up-in-one-hour/</link>
      <pubDate>Sun, 26 Apr 2026 18:42:42 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/wake-me-up-in-one-hour/</guid>
      <description>&lt;p&gt;♠ &lt;strong&gt;Problem statement&lt;/strong&gt;: get reminded to pick up the laundry after starting to&#xA;wash it.&lt;/p&gt;&#xA;&lt;p&gt;The most practical workflow is to yell to my Google Home: &lt;em&gt;wake me up in one&#xA;hour&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;It feels silly to say &lt;em&gt;wake me up&lt;/em&gt; in a context that does not involve getting&#xA;out of bed, but it&amp;rsquo;s the most practical sentence in English at my fingertips.&lt;/p&gt;&#xA;&lt;p&gt;It surely beats &lt;em&gt;set an alarm at 15:00&lt;/em&gt; — I do not want to &lt;em&gt;think&lt;/em&gt; in terms of&#xA;absolute time, I only care about relative time in this context.&lt;/p&gt;&#xA;&lt;p&gt;Perhaps &lt;em&gt;ring an alarm in one hour&lt;/em&gt; is a reasonable alternative, but the word&#xA;&amp;ldquo;ring&amp;rdquo; is not too idiomatic to my taste in this context.&lt;/p&gt;&#xA;&lt;p&gt;An alternative workflow is to use Clock.app on iOS. It surely works reliably, I&#xA;could even ask Siri to do so. But I am already glued to my phone for various&#xA;reasons, there is no need to make it even worse.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/2026/02/google-home-usage/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Wake me up in one hour&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ ↗ Reply to: The Aging Programmer — Kate Gregory (2024) — YouTube
      </title>
      <link>https://perrotta.dev/2026/04/reply-to-the-aging-programmer-kate-gregory-2024-youtube/</link>
      <pubDate>Wed, 15 Apr 2026 01:57:29 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>bestof</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/reply-to-the-aging-programmer-kate-gregory-2024-youtube/</guid>
      <description>&lt;p&gt;♠ This was a great talk!&lt;/p&gt;&#xA;&lt;p&gt;In a C++ conference, who would have imagined?&lt;/p&gt;&#xA;&lt;p&gt;Via &lt;a href=&#34;https://corecursive.com/the-aging-programmer/&#34;&gt;Adam Gordon Bell&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Kate Gregory has been writing C++ for over forty years. Books, keynotes, a&#xA;consulting firm she built from the ground up. At sixty-three, she&amp;rsquo;s one of the&#xA;most experienced programmers alive.&lt;/p&gt;&#xA;&lt;p&gt;She surveyed hundreds of software engineers about getting older. What scares&#xA;you? What&amp;rsquo;s changed? What have you lost? The things people feared most —&#xA;memory, stamina, keeping up — weren&amp;rsquo;t the real threats. The stuff that was&#xA;actually breaking down was mostly fixable. A bad knee wasn&amp;rsquo;t aging, it was a&#xA;torn cartilage. Wrist pain disappeared when she changed how she slept.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Reply to: The Aging Programmer — Kate Gregory (2024) — YouTube&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Filing upstream bugs in 2026
      </title>
      <link>https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/</link>
      <pubDate>Mon, 13 Apr 2026 14:33:07 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>bestof</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/</guid>
      <description>&lt;p&gt;♠ First of all, get familiar with some &lt;em&gt;decent guidelines&lt;/em&gt; that exist since&#xA;forever:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://perrotta.dev/2024/06/xy-problem-xyproblem/&#34;&gt;XYProblem&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;http://www.catb.org/~esr/faqs/smart-questions.html&#34;&gt;How To Ask Questions The Smart Way&lt;/a&gt; by ESR (Eric Steven Raymond)&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://wiki.archlinux.org/title/Bug_reporting_guidelines&#34;&gt;ArchWiki: Bug reporting guidelines&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;What is different in 2026? Gen AI / LLMs / Coding agents, of course. Everything&#xA;else stays the same.&lt;/p&gt;&#xA;&lt;p&gt;We don&amp;rsquo;t have to complicate things, I&amp;rsquo;ll start with an example, this is what a&#xA;typical decent bug report (or feature request) &lt;strong&gt;should&lt;/strong&gt; look like, filed by&#xA;yours truly&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;:&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://github.com/nikvdp/cco/issues/58&#34;&gt;nikvdp/cco&lt;/a&gt; (Claude Code Condom):&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;First of all, I &lt;a href=&#34;https://perrotta.dev/2026/02/cco-claude-condom-sandbox/&#34;&gt;love&lt;/a&gt; &lt;code&gt;cco&lt;/code&gt;. Thanks for your effort and the good work on it!&lt;/p&gt;&#xA;&lt;p&gt;Now, to the point: Claude has recently introduced an auto mode: &lt;a href=&#34;https://claude.com/blog/auto-mode&#34;&gt;https://claude.com/blog/auto-mode&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Today, we&amp;rsquo;re introducing auto mode, a new permissions mode in Claude Code where Claude makes permission decisions on your behalf, with safeguards monitoring actions before they run. It&amp;rsquo;s available now as a research preview on the Team plan, and coming to the Enterprise plan and API users in the coming days.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;It&amp;rsquo;s supposed to be slightly safer than the YOLO mode (&lt;code&gt;--dangerously-skip-permissions&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;You can enable and set it with &lt;code&gt;claude --enable-auto-mode&lt;/code&gt; (or via &lt;code&gt;settings.json&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Feature request&lt;/strong&gt;: &lt;code&gt;cco&lt;/code&gt; should support launching claude in auto mode. Currently it unconditionally launches claude with &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Do you think this would be a reasonable addition? If so, I would be happy to give it a try to send a PR (realistically I would prompt Claude to do so).&lt;/p&gt;&#xA;&lt;p&gt;Side note: the comment above was fully written (manually) by me. Slop notes from Claude come below 🙃:&lt;/p&gt;&#xA;&lt;p&gt;⏺ No upstream support exists yet. The repo is &lt;a href=&#34;https://github.com/nikvdp/cco&#34;&gt;nikvdp/cco&lt;/a&gt; and:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;No issue or feature request for &amp;ndash;auto mode support exists across all 25 issues and 33 PRs&lt;/li&gt;&#xA;&lt;li&gt;No PR or commit adding it&lt;/li&gt;&#xA;&lt;li&gt;The script hardcodes &amp;ndash;dangerously-skip-permissions in 7 places (both native and Docker backends) with no configuration option&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;This would be a good feature request to file. The implementation would be straightforward — make the permission mode configurable (e.g. via a &amp;ndash;permission-mode flag or CCO_PERMISSION_MODE env var) instead of hardcoding &amp;ndash;dangerously-skip-permissions.&lt;/p&gt;&#xA;&lt;p&gt;Worth noting: Claude Code&amp;rsquo;s &amp;ndash;auto mode (aka &amp;ndash;permission-mode auto) requires an API-tier plan (Team/Enterprise/API, not Pro or Max) and uses a classifier model to review actions before execution — so it&amp;rsquo;s a meaningful middle ground between full bypass and manual prompts.&lt;/p&gt;&#xA;&lt;p&gt;Want me to draft an issue for the nikvdp/cco repo?&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;In no particular order:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Be &lt;a href=&#34;https://en.wikipedia.org/wiki/Golden_Rule&#34;&gt;&lt;strong&gt;kind&lt;/strong&gt;&lt;/a&gt;&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. That cannot be&#xA;understated. No one owes you anything. Leave (self-)entitlement at the door.&lt;/li&gt;&#xA;&lt;li&gt;Be &lt;strong&gt;efficient&lt;/strong&gt;. Do not waste the maintainer&amp;rsquo;s time. Information should be&#xA;comprehensive/complete yet concise. Keep it simple and short&#xA;(&lt;a href=&#34;https://en.wikipedia.org/wiki/KISS_principle&#34;&gt;KISS&lt;/a&gt;).&lt;/li&gt;&#xA;&lt;li&gt;Be &lt;strong&gt;precise&lt;/strong&gt;, reduce room for &lt;em&gt;ambiguity&lt;/em&gt; as much as possible. Link to docs&#xA;whenever it makes sense. When linking to docs, be respectful of your peer&amp;rsquo;s&#xA;time and ensure to extract and blockquote relevant snippets so that they don&amp;rsquo;t&#xA;need to dig for it themselves. Furthermore, the links are important for&#xA;verification purposes (&lt;a href=&#34;https://en.wikipedia.org/wiki/Trust,_but_verify&#34;&gt;&lt;em&gt;trust, but verify&lt;/em&gt;&lt;/a&gt;).&lt;/li&gt;&#xA;&lt;li&gt;Be &lt;strong&gt;proactive&lt;/strong&gt;. Offer to help&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; if you have the know-how and/or expertise&#xA;to do so.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Move on&lt;/strong&gt;. If you get no reply from the maintainer, do not bug them about&#xA;your bug/FR/PR. Find the next activity to work on. Fork it. Work around it.&#xA;Just don&amp;rsquo;t peg the maintainer to do it for you. This includes code review.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;It is much easier if you remember that the maintainer is a person, just like you. Not&#xA;a machine. Sounds obvious to state this, but it seems to me many people forget&#xA;that, with so much context switching and social media these days&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;If you&amp;rsquo;re still reading until this point, chances are that you actually care.&#xA;Thank you! Keep it up.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Practice what you preach&amp;hellip;I am obviously biased though.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:2&#34;&gt;&#xA;&lt;p&gt;Or nice. Or polite. Or &lt;em&gt;sympathisch&lt;/em&gt;.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;li id=&#34;fn:3&#34;&gt;&#xA;&lt;p&gt;Only if you actually have time to do so. No empty promises, please.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/04/filing-upstream-bugs-in-2026/#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Filing upstream bugs in 2026&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>↗ Reply to: Hostile volume
      </title>
      <link>https://perrotta.dev/2026/04/reply-to-hostile-volume/</link>
      <pubDate>Sun, 12 Apr 2026 16:43:33 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>gaming</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/reply-to-hostile-volume/</guid>
      <description>&lt;p&gt;♠ I got stuck at level 17/30 playing from mobile.&lt;/p&gt;&#xA;&lt;p&gt;Via &lt;a href=&#34;https://kottke.org/26/04/0048712-hostile-volume-is-a-simpl&#34;&gt;Kottke&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Reply to: Hostile volume&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/gaming/&#34;&gt;#gaming&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ciao mondo
      </title>
      <link>https://perrotta.dev/it/posts/2026-04-12-ciao-mondo/</link>
      <pubDate>Sun, 12 Apr 2026 00:00:00 +0000</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>meta</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/it/posts/2026-04-12-ciao-mondo/</guid>
      <description>&lt;p&gt;♠ Ciao mondo! Questo è il mio primo post in italiano.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Ciao mondo&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/meta/&#34;&gt;#meta&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Anki: corrupted database
      </title>
      <link>https://perrotta.dev/2026/04/anki-corrupted-database/</link>
      <pubDate>Wed, 08 Apr 2026 00:14:11 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>dev</category>
      <category>pkm</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/anki-corrupted-database/</guid>
      <description>&lt;p&gt;♠ Life is hard.&#xA;Today, when opening &lt;a href=&#34;https://apps.ankiweb.net/&#34;&gt;Anki&lt;/a&gt; on macOS:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-plaintext&#34;&gt;DbError { info: &amp;#34;SqliteFailure(Error { code: DatabaseCorrupt, extended_code: 11 }, Some(\&amp;#34;database disk image is malformed\&amp;#34;))&amp;#34;, kind: Other }&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Database corrupt? What is this, are we in the 2000s? Goodness.&lt;/p&gt;&#xA;&lt;p&gt;I have automatic backups enabled. For 4 years I haven&amp;rsquo;t needed them. Today&#xA;is the day. Never say never!&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;% ls -lt &amp;#34;$HOME/Library/Application Support/Anki2/Thiago/backups/&amp;#34;&#xA;total 234496&#xA;-rw-r--r--@ 1 tperrotta  staff  3911921 Apr  8 00:12 backup-2026-04-08-00.12.17.colpkg&#xA;-rw-r--r--@ 1 tperrotta  staff  3911921 Apr  7 00:16 backup-2026-04-07-00.16.26.colpkg&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;I try:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;open &amp;#34;$HOME/Library/Application Support/Anki2/Thiago/backups/backup-2026-04-07-00.16.26.colpkg&amp;#34;&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;&amp;hellip;but apparently that file is corrupt as well.&lt;/p&gt;&#xA;&lt;p&gt;I am not particularly worried because I sync my notes to&#xA;&lt;a href=&#34;https://ankiweb.net/&#34;&gt;AnkiWeb&lt;/a&gt;. Even if the entire local collection were corrupt,&#xA;my flashcards are in the cloud.&lt;/p&gt;&#xA;&lt;p&gt;So I decided to simply start from scratch&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/04/anki-corrupted-database/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;mv ~/Library/Application\ Support/Anki2/Thiago/collection.anki2 ~/Library/Application\ Support/Anki2/Thiago/collection.anki2.corrupt&#xA;rm -f ~/Library/Application\ Support/Anki2/Thiago/collection.anki2-shm ~/Library/Application\ Support/Anki2/Thiago/collection.anki2-wal&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;Then I open Anki.&lt;/p&gt;&#xA;&lt;p&gt;It prompts me to download my decks from AnkiWeb.&lt;/p&gt;&#xA;&lt;p&gt;And now everything works as usual! Last cleanup:&lt;/p&gt;&#xA;&#xA;&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;trash ~/Library/Application\ Support/Anki2/Thiago/collection.anki2.corrupt&lt;/code&gt;&lt;/pre&gt;&#xA;&lt;p&gt;No idea why this has happened. First time. Life goes on.&lt;/p&gt;&#xA;&lt;p&gt;!next&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/2025/10/anki-find-all-suspended-flashcards/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;The idea was mine. The decision was mine. The LLM suggested the command on&#xA;how to do so. I can still self-troubleshoot, &lt;em&gt;mmmkay&lt;/em&gt;?&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/04/anki-corrupted-database/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Anki: corrupted database&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/pkm/&#34;&gt;#pkm&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Project Hail Mary
      </title>
      <link>https://perrotta.dev/2026/04/project-hail-mary/</link>
      <pubDate>Thu, 02 Apr 2026 00:41:24 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bestof</category>
      <category>movies</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/04/project-hail-mary/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://www.goodreads.com/book/show/54493401-project-hail-mary&#34;&gt;&lt;strong&gt;Book&lt;/strong&gt;&lt;/a&gt;: 5/5&#xA;stars. &lt;a href=&#34;https://www.goodreads.com/review/show/4383821769&#34;&gt;One of my favorites&lt;/a&gt;&#xA;of 2022 (Sci-Fi):&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Amaze. You my friend.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;(This was my review in goodreads back then.)&lt;/p&gt;&#xA;&lt;p&gt;Fast-forward 3.5 years (&amp;raquo;):&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.imdb.com/title/tt12042730/&#34;&gt;&lt;strong&gt;Movie&lt;/strong&gt;&lt;/a&gt;: 10/10.&lt;/p&gt;&#xA;&lt;p&gt;&lt;img src=&#34;https://victor.kropp.name/blog/2026/project-hail-mary/project-hail-mary.jpg&#34; alt=&#34;project hail mary&#34;&#xA;  loading=&#34;lazy&#34; decoding=&#34;async&#34; /&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;Excellent adaptation. 🇨🇦&lt;/p&gt;&#xA;&lt;p&gt;Sorry, I don&amp;rsquo;t know how to write reviews.&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;ll leave that &lt;a href=&#34;https://iamvishnu.com/posts/project-hail-mary&#34;&gt;to&lt;/a&gt; &lt;a href=&#34;https://victor.kropp.name/blog/2026/project-hail-mary/&#34;&gt;others&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;[&amp;hellip;] It was the same great experience as with The Martian ten&#xA;years ago, as I couldn&amp;rsquo;t stop reading it. And plot twists genuinely surprised&#xA;me. The movie adapts the book perfectly but also adds some human touch to one&#xA;of the main characters as she needed it.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;She is more likeable in the movie than in the book (There is only one &lt;em&gt;she&lt;/em&gt;).&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Even though I&amp;rsquo;m not a big fan of changing book covers with movie posters, Ryan&#xA;Gosling portrayed the main character, Dr. Ryland Grace, perfectly.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I love the original cover, AND I think Ryan Gosling did great in the movie.&#xA;There&amp;rsquo;s no wrong choice here.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Project Hail Mary&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/movies/&#34;&gt;#movies&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>↗ Reply to: The agentic passive voice | irrational exuberance
      </title>
      <link>https://perrotta.dev/2026/03/reply-to-the-agentic-passive-voice-irrational-exuberance/</link>
      <pubDate>Mon, 30 Mar 2026 10:46:39 +0200</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>ai</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/reply-to-the-agentic-passive-voice-irrational-exuberance/</guid>
      <description>&lt;p&gt;♠ Will Larson:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;At some point, you will have learned about the passive voice, where the actor&#xA;in a sentence is unclear. For example, my software didn&amp;rsquo;t compile. That&amp;rsquo;s a&#xA;good example of the passive voice. However, you might not know the full set of&#xA;rules, because here are some sentences in the passive voice that you might not&#xA;recognize:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Claude made an error in my writeup.&lt;/li&gt;&#xA;&lt;li&gt;ChatGPT messed up the commitment.&lt;/li&gt;&#xA;&lt;li&gt;Gemini didn&amp;rsquo;t write tests.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;You might think those are active sentences, but those are in fact examples of&#xA;the agentic passive voice. The rule here is: whenever the actor in a sentence&#xA;is a model, then it&amp;rsquo;s a passive sentence. I&amp;rsquo;m sorry if your grammar instructor&#xA;never taught you this rule, but this is just the way it works now.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;Dear human,&lt;/p&gt;&#xA;&lt;p&gt;Use LLMs as much as you want / need to, but own the responsibilities for its&#xA;actions and outcomes. No excuses.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;ChatGPT dropped the database&amp;rdquo; is not acceptable.&lt;/p&gt;&#xA;&lt;p&gt;Who is controlling ChatGPT? Is it&#xA;&lt;a href=&#34;https://store.steampowered.com/app/1222140/Detroit_Become_Human/&#34;&gt;deviant&lt;/a&gt;,&#xA;does it have self-agency?&lt;/p&gt;&#xA;&lt;p&gt;In 2026 that&amp;rsquo;s highly unlikely. If &lt;em&gt;you&lt;/em&gt; control the agent, then &lt;em&gt;you&lt;/em&gt; are&#xA;solely responsible for its actions.&lt;/p&gt;&#xA;&lt;p&gt;&amp;ldquo;I dropped the database via an &lt;em&gt;accidental&lt;/em&gt; prompt in a coding agent&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Reply to: The agentic passive voice | irrational exuberance&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Potpourri
      </title>
      <link>https://perrotta.dev/2026/03/potpourri/</link>
      <pubDate>Fri, 27 Mar 2026 22:19:48 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/potpourri/</guid>
      <description>&lt;p&gt;♠ For Sprint planning I like to name my catch-all / umbrella Epics as &amp;ldquo;potpourri&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;Why? &lt;a href=&#34;https://missing.csail.mit.edu/2020/potpourri/&#34;&gt;Just because&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Example:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;GitOps pipeline for Terraform – potpourri&lt;/li&gt;&#xA;&lt;li&gt;GitOps phase potpourri – ArgoCD production wrap-up&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;One advantage&lt;/strong&gt;: because no one else uses this nomenclature, it&amp;rsquo;s very easy to&#xA;find my own tickets in JIRA this way – very important, as JIRA search &lt;a href=&#34;https://perrotta.dev/2025/06/jira-service-management-search-is-terrible/&#34;&gt;kinda&#xA;sucks&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Potpourri&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Goodbye, Amp Code
      </title>
      <link>https://perrotta.dev/2026/03/goodbye-amp-code/</link>
      <pubDate>Wed, 25 Mar 2026 11:23:27 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>ai</category>
      <category>dev</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/goodbye-amp-code/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://perrotta.dev/2026/01/amp-code-queue/unqueue-messages/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;There&amp;rsquo;s always a sense of relief whenever we say goodbye.&lt;/p&gt;&#xA;&lt;p&gt;It oftentimes &lt;a href=&#34;https://konmari.com/marie-kondo-rules-of-tidying-sparks-joy/&#34;&gt;&lt;em&gt;sparks joy&lt;/em&gt;&lt;/a&gt; ✨.&lt;/p&gt;&#xA;&lt;p&gt;It frees up our minds to focus on something else.&lt;/p&gt;&#xA;&lt;p&gt;Or perhaps to focus on nothing at all.&lt;/p&gt;&#xA;&lt;p&gt;Serenity is calm.&lt;/p&gt;&#xA;&lt;p&gt;A goodbye need not burn bridges.&lt;/p&gt;&#xA;&lt;p&gt;We can be thankful and simply move on.&lt;/p&gt;&#xA;&lt;p&gt;We can absorb lessons, good and bad, and do better next time.&lt;/p&gt;&#xA;&lt;p&gt;Today I decided to completely uninstall &lt;a href=&#34;https://ampcode.com/&#34;&gt;Amp Code&lt;/a&gt; from my&#xA;systems and delete my account there.&lt;/p&gt;&#xA;&lt;p&gt;Initially I thought I&amp;rsquo;d document the &lt;a href=&#34;https://www.imdb.com/title/tt1837492/&#34;&gt;reasons&#xA;why&lt;/a&gt; in this blog post, but I decided not&#xA;to. Sorry, fellas.&lt;/p&gt;&#xA;&lt;p&gt;I am thankful to Amp for making me realize how important an agent harness is for&#xA;developer experience.&lt;/p&gt;&#xA;&lt;p&gt;I am thankful to Amp for enlightening me about threads (sessions) and how to&#xA;structure my &lt;a href=&#34;https://simonwillison.net/2025/Jun/29/agentic-coding/&#34;&gt;&lt;em&gt;agentic&#xA;coding&lt;/em&gt;&lt;/a&gt; thinking.&lt;/p&gt;&#xA;&lt;p&gt;Arrivederci, Amp.&lt;/p&gt;&#xA;&lt;p&gt;What&amp;rsquo;s next? I am putting my bets on open ecosystems. Watch out for&#xA;&lt;a href=&#34;http://shittycodingagent.ai/&#34;&gt;pi&lt;/a&gt; and &lt;a href=&#34;https://opencode.ai/&#34;&gt;OpenCode&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Amp Free Ad-supported free daily allowance of Amp usage (&lt;a href=&#34;https://ampcode.com/free&#34;&gt;learn more&lt;/a&gt;)&lt;/p&gt;&#xA;&lt;p&gt;Amp Free is full for now.&lt;/p&gt;&#xA;&lt;p&gt;Note from the Amp Team (2026-03-11):&lt;/p&gt;&#xA;&lt;p&gt;Amp is growing fast, and we&amp;rsquo;re sprinting on the next version. When it&amp;rsquo;s ready,&#xA;we&amp;rsquo;ll reopen Amp Free to new users. We paused Amp Free for some inactive users&#xA;so we can focus on regular users as we&amp;rsquo;re working on new stuff, and we&amp;rsquo;ll let&#xA;you know if or when your access resumes. See &lt;a href=&#34;https://ampcode.com/news/amp-free-is-full-for-now&#34;&gt;news&#xA;post&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Goodbye, Amp Code&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/ai/&#34;&gt;#ai&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Data Subject Request
      </title>
      <link>https://perrotta.dev/2026/03/data-subject-request/</link>
      <pubDate>Thu, 12 Mar 2026 18:57:03 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>bestof</category>
      <category>privacy</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/data-subject-request/</guid>
      <description>&lt;p&gt;♠ Basic template to request &lt;strong&gt;interview feedback&lt;/strong&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Subject&lt;/strong&gt;: Data Subject Request&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;To&lt;/strong&gt;: dpo@{company}.com&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/03/data-subject-request/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;&#xA;&lt;p&gt;{Greetings},&lt;/p&gt;&#xA;&lt;p&gt;I&amp;rsquo;d like to get access to my interview feedback (&amp;ldquo;personal information&amp;rdquo;) from&#xA;my last application at {company} as a candidate ({NN} {weeks,years} ago). My&#xA;email is {email}.&lt;/p&gt;&#xA;&lt;p&gt;I am emailing this alias as per&#xA;https://{company}.com/{privacy-terms}.&lt;/p&gt;&#xA;&lt;p&gt;{Goodbye}&#xA;{Your name}&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;Disclaimer&lt;/strong&gt;: This is not legal advice, I am not a lawyer.&lt;/p&gt;&#xA;&lt;p&gt;In Europe the GDPR generally entitles candidates to receive a copy of their&#xA;data (e.g. verbatim interview notes) within 30 days.&lt;/p&gt;&#xA;&lt;p&gt;You can also apply the same idea to request &lt;strong&gt;performance reviews&lt;/strong&gt; and&#xA;&lt;strong&gt;calibration notes&lt;/strong&gt; from your current or former employers.&lt;/p&gt;&#xA;&lt;p&gt;I used this various times throughout the years in both scenarios. It is very&#xA;effective. YMMV.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;Keywords: data protection officer (DPO), data protection, candidate&#xA;privacy, GDPR, DSVGO, SAR (Subject Access Request). Use your favorite search&#xA;engine or your favorite LLM to find the appropriate point of contact or&#xA;channel.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/03/data-subject-request/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Data Subject Request&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/privacy/&#34;&gt;#privacy&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>↗ Boring and dangerous professional
      </title>
      <link>https://perrotta.dev/2026/03/boring-and-dangerous-professional/</link>
      <pubDate>Thu, 12 Mar 2026 01:53:38 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/boring-and-dangerous-professional/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://www.kalzumeus.com/2017/09/09/identity-theft-credit-reports/#presenting-like-a-professional&#34;&gt;Identity Theft, Credit Reports, and You&lt;/a&gt; and &lt;a href=&#34;https://aphyr.com/posts/406-how-to-unsubscribe-from-modern-luxury&#34;&gt;How to Unsubscribe from Modern Luxury&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;I don&amp;rsquo;t want to bother people like this; I think it&amp;rsquo;s unreasonably rude. I&#xA;still start with the official support channels and escalate gradually. I like&#xA;Patrick McKenzie&amp;rsquo;s strategy of presenting oneself as a boring, dangerous&#xA;professional. However, I have also found that in the Annoyance Economy, one of&#xA;the ways to get things done is to find specific people with power, and annoy&#xA;them right back.&lt;/p&gt;&#xA;&lt;p&gt;[&amp;hellip;]&lt;/p&gt;&#xA;&lt;p&gt;Instead, you want to communicate with the bank in a manner which suggests that&#xA;you&amp;rsquo;re an organized professional who is capable of escalating the matter if&#xA;the bank does not handle it themselves. You do not yell – not that you&amp;rsquo;re ever&#xA;verbally speaking with anyone, but you wouldn&amp;rsquo;t yell in a letter, either. You&#xA;do not bluster. (&amp;ldquo;I will tell on you to my attorney&amp;rdquo; is, generally, bluster,&#xA;and that&amp;rsquo;s bluster that is common to people who do not actually have&#xA;attorneys.) You instead present as if you&amp;rsquo;re collecting a paper trail.&lt;/p&gt;&#xA;&lt;p&gt;Mean words cannot hurt a bank. Threats cannot hurt a bank. Paper trails,&#xA;though, are terrifying to regulated institutions. Your bank&amp;rsquo;s customer support&#xA;representatives are taught to evaluate whether someone looks like they&amp;rsquo;re&#xA;competent and collecting a paper trail. If they are, the CS rep is supposed to&#xA;stop touching the case immediately and instead escalate them to a supervisor&#xA;or to the legal department.&lt;/p&gt;&#xA;&lt;p&gt;[&amp;hellip;]&lt;/p&gt;&#xA;&lt;p&gt;The thing which causes regulatory incidents is well-organized people taking&#xA;paper trails to regulators which allow a regulator to trivially follow up with&#xA;an investigatory letter. Accordingly, anyone who sounds like a well-organized&#xA;professional with a paper trail is a problem to be swiftly addressed.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;This is gold. Do you already have your own &lt;a href=&#34;https://perrotta.dev/tags/pkm/&#34;&gt;pkm&lt;/a&gt;?&#xA;I recommend &lt;a href=&#34;https://logseq.com/&#34;&gt;LogSeq&lt;/a&gt; or &lt;a href=&#34;https://obsidian.md/&#34;&gt;Obsidian&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Boring and dangerous professional&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>★ Chia pudding
      </title>
      <link>https://perrotta.dev/2026/03/chia-pudding/</link>
      <pubDate>Wed, 11 Mar 2026 02:55:41 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>recipes</category>
      <category>bestof</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/chia-pudding/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://perrotta.dev/2025/04/overnight-oats/&#34;&gt;Previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;h2 id=&#34;ingredients&#34;&gt;&#xA;  Ingredients&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/03/chia-pudding/#ingredients&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;In order, add to a glass:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;coconut milk&lt;/strong&gt; (1/2 cup)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;chia seeds&lt;/strong&gt; (2 tbsps)&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;maple syrup / honey&lt;/strong&gt; (sweetener)&lt;/li&gt;&#xA;&lt;li&gt;vanilla extract&lt;/li&gt;&#xA;&lt;li&gt;cinnamon&lt;/li&gt;&#xA;&lt;li&gt;a pinch of salt&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;preparation&#34;&gt;&#xA;  Preparation&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/03/chia-pudding/#preparation&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Whisk everything.&lt;/p&gt;&#xA;&lt;p&gt;Let it soak overnight in the fridge.&lt;/p&gt;&#xA;&lt;p&gt;Top with blueberries, raspberries or cherries. Or with nuts.&lt;/p&gt;&#xA;&lt;p&gt;Inspiration: &lt;a href=&#34;https://feelgoodfoodie.net/recipe/3-ingredient-chia-pudding/&#34;&gt;feel good&#xA;foodie&lt;/a&gt; and &lt;a href=&#34;https://www.abeautifulplate.com/overnight-chia-pudding-recipe/&#34;&gt;a&#xA;beautiful&#xA;plate&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Chia pudding&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/bestof/&#34;&gt;#bestof&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/recipes/&#34;&gt;%recipes&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Ghostty 1.3.0 release
      </title>
      <link>https://perrotta.dev/2026/03/ghostty-1.3.0-release/</link>
      <pubDate>Tue, 10 Mar 2026 19:10:42 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>dev</category>
      <category>ghostty</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/ghostty-1.3.0-release/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://ghostty.org/docs/install/release-notes/1-3-0&#34;&gt;Ghostty 1.3.0&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Ghostty 1.3.0 is a significant release which includes many of the most&#xA;requested features such as scrollback search, native scrollbars,&#xA;click-to-move-cursor in shell prompts, and more. It also includes hundreds of&#xA;improvements, bug fixes, and performance optimizations across all platforms.&lt;/p&gt;&#xA;&lt;p&gt;This release features 6 months of work with changes from 180 contributors over&#xA;2,858 commits. Thank you to all the contributors, maintainers, community&#xA;moderators, translators, packagers, and users who each helped make this&#xA;release possible.&lt;/p&gt;&#xA;&lt;p&gt;These release notes are painstakingly and lovingly hand-crafted by human&#xA;Ghostty maintainers, including the full changelog. They take a combined 16+&#xA;hours to write, so please enjoy. 🥰&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I never thought I could get so much joy from reading software release notes in&#xA;2026, in the era where many (most?) release notes are an afterthought, either&#xA;generic and vague or bland and LLM-generated.&lt;/p&gt;&#xA;&lt;p&gt;All hail to &lt;a href=&#34;https://mitchellh.com/&#34;&gt;Mitchell Hashimoto&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Ghostty 1.3.0 release&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/dev/&#34;&gt;#dev&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/ghostty/&#34;&gt;#ghostty&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Google Translate → Kagi Translate, DeepL
      </title>
      <link>https://perrotta.dev/2026/03/google-translate-kagi-translate-deepl/</link>
      <pubDate>Tue, 10 Mar 2026 12:34:34 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>degoogling</category>
      <category>privacy</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/google-translate-kagi-translate-deepl/</guid>
      <description>&lt;p&gt;♠ &lt;a href=&#34;https://perrotta.dev/2024/12/reply-to-heres-how-to-live-be-independent/&#34;&gt;Previously&lt;/a&gt;,&#xA;&lt;a href=&#34;https://perrotta.dev/2022/04/translating-german-to-english/&#34;&gt;previously&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;I added a new tag to this blog: &lt;a href=&#34;https://perrotta.dev/tags/degoogling/&#34;&gt;degoogling&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Patrick Dubroy&amp;rsquo;s &lt;a href=&#34;https://dubroy.com/blog/de-googling/&#34;&gt;post&lt;/a&gt; has recently&#xA;inspired me. Ironically, we&amp;rsquo;re both former Chrome employees&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;https://perrotta.dev/2026/03/google-translate-kagi-translate-deepl/#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;&#xA;&lt;p&gt;In Patrick&amp;rsquo;s words (&lt;em&gt;not mine&lt;/em&gt;!):&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;Not much to say here. I got tired of Chrome&amp;rsquo;s &lt;a href=&#34;https://www.theregister.com/2023/09/06/google_privacy_popup_chrome/&#34;&gt;deceptive messaging about ad&#xA;privacy&lt;/a&gt;&#xA;and about how careful I had to be to stay signed-out.&lt;/p&gt;&#xA;&lt;p&gt;Vivaldi is a Chromium-based browser, and after tweaking a few settings, it&amp;rsquo;s&#xA;basically a like-for-like replacement. I&amp;rsquo;ve been happily using it for 6 months&#xA;now.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;I switched over to &lt;a href=&#34;https://perrotta.dev/2026/01/chrome-brave/&#34;&gt;Brave&lt;/a&gt; instead.&lt;/p&gt;&#xA;&lt;p&gt;Previously I&amp;rsquo;ve also praised &lt;a href=&#34;https://perrotta.dev/2024/02/organic-maps-off-line-maps/&#34;&gt;Organic Maps&lt;/a&gt; over Google Maps. I am still using it, every week.&lt;/p&gt;&#xA;&lt;p&gt;This is all off-topic though: today&amp;rsquo;s post is about &lt;strong&gt;translation&lt;/strong&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Google Translate is a (very) solid product. In fact, when compared to Chrome and&#xA;Maps, it&amp;rsquo;s one of the few Google products that hasn&amp;rsquo;t been&#xA;&lt;a href=&#34;https://en.wikipedia.org/wiki/Enshittification&#34;&gt;enshittified&lt;/a&gt; yet. It does one&#xA;thing, and does it (very) well. For as long as it keeps its feature set as is&#xA;and does not get infected with Gen AI or anything that a promotion-seeking&#xA;Product Manager or Executive may decide to enact, it will continue to thrive and&#xA;shine.&lt;/p&gt;&#xA;&lt;p&gt;Nonetheless, it does not flow well with privacy and overreliance on tech&#xA;giants.&lt;/p&gt;&#xA;&lt;p&gt;Last week I deleted the Google Translate bookmark and &lt;a href=&#34;https://perrotta.dev/2024/09/chromium-delete-entry-in-url-bar/&#34;&gt;history entry&lt;/a&gt; from my web browser, and its&#xA;app from my iPhone.&lt;/p&gt;&#xA;&lt;p&gt;There are two replacements I like that are widely available in both phones and&#xA;desktops.&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://www.deepl.com/en/translator&#34;&gt;DeepL&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://translate.kagi.com/&#34;&gt;Kagi&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;deepl&#34;&gt;&#xA;  DeepL&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/03/google-translate-kagi-translate-deepl/#deepl&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;DeepL can:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;translate words and sentences&lt;/li&gt;&#xA;&lt;li&gt;translate files and documents&lt;/li&gt;&#xA;&lt;li&gt;translate speech&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Its translation results are often touted as sounding natural and accounting for&#xA;the context. You can configure whether to use formal or informal language but&#xA;that&amp;rsquo;s a Pro (paid) feature.&lt;/p&gt;&#xA;&lt;p&gt;They are a German company, founded in&#xA;&lt;a href=&#34;https://simple.wikipedia.org/wiki/DeepL_Translator&#34;&gt;2017&lt;/a&gt;. Arguably, thanks to&#xA;that, they excel at translating DE &amp;lt;-&amp;gt; EN.&lt;/p&gt;&#xA;&lt;p&gt;One caveat is that it pushes you hard to sign up for a user account. I do not&#xA;have one, there&amp;rsquo;s no practical need to have one, especially if you&amp;rsquo;re seeking&#xA;increased privacy.&lt;/p&gt;&#xA;&lt;p&gt;Another caveat is that they have increasingly started to adopt Gen AI features&#xA;all over the place. These features aren&amp;rsquo;t necessarily super polished, and they&#xA;feel rushed. It&amp;rsquo;s easy to ignore them and just move on. Their core product is&#xA;great.&lt;/p&gt;&#xA;&lt;p&gt;It can be selected as the default translation app on iOS.&lt;/p&gt;&#xA;&lt;h2 id=&#34;kagi-translate&#34;&gt;&#xA;  Kagi Translate&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/03/google-translate-kagi-translate-deepl/#kagi-translate&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Kagi Translate is much newer&#xA;(&lt;a href=&#34;https://kagifeedback.org/d/5197-nov-7th-2024-announcing-kagi-translate&#34;&gt;2024&lt;/a&gt;).&#xA;It is very &lt;a href=&#34;https://en.wikipedia.org/wiki/KISS_principle&#34;&gt;KISS&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;From their blog post:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Higher quality translations than Google Translate and DeepL&lt;/li&gt;&#xA;&lt;li&gt;Zero tracking, no apps needed&lt;/li&gt;&#xA;&lt;li&gt;Free for everyone (Kagi members get captcha-free access)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I am an overall fan of the philosophy behind &lt;a href=&#34;https://perrotta.dev/2025/05/kagi/&#34;&gt;Kagi&lt;/a&gt; and think that their translation web app fits it well.&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://blog.kagi.com/kagi-translate-mobile&#34;&gt;Last month&lt;/a&gt; they released mobile&#xA;apps, making it much easier to use.&lt;/p&gt;&#xA;&lt;p&gt;Kagi Translate can:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;translate words and sentences&lt;/li&gt;&#xA;&lt;li&gt;translate files and documents&lt;/li&gt;&#xA;&lt;li&gt;translate speech&lt;/li&gt;&#xA;&lt;li&gt;translate websites&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;I especially like its built-in dictionary feature and its alternative&#xA;translations suggestions.&lt;/p&gt;&#xA;&lt;p&gt;Gen AI is opt-in and not pushed on you. There are no paid features. The&#xA;interface is very clean. You can configure it with presets such as (i) level of&#xA;formality, (ii) reading level (A1, A2, B1, etc) and (iii) gender preferences&#xA;(masculine, feminine, neutral).&lt;/p&gt;&#xA;&lt;h2 id=&#34;its-a-wrap&#34;&gt;&#xA;  It&amp;rsquo;s a wrap&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/03/google-translate-kagi-translate-deepl/#its-a-wrap&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;As of the time of this post &lt;strong&gt;Kagi Translate&lt;/strong&gt; is my favorite, and DeepL comes&#xA;second. Google Translate is the fallback.&lt;/p&gt;&#xA;&lt;p&gt;Both Kagi Translate and DeepL have Chromium extensions for ease of reach and&#xA;use.&lt;/p&gt;&#xA;&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;&#xA;&lt;hr&gt;&#xA;&lt;ol&gt;&#xA;&lt;li id=&#34;fn:1&#34;&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://www.dictionary.com/culture/slang/let-that-sink-in&#34;&gt;Let that sink in&lt;/a&gt;.&amp;#160;&lt;a href=&#34;https://perrotta.dev/2026/03/google-translate-kagi-translate-deepl/#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;/div&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Google Translate → Kagi Translate, DeepL&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/degoogling/&#34;&gt;#degoogling&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/privacy/&#34;&gt;#privacy&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>↗ Reply to: Brazilian affection/cuddling vocabulary
      </title>
      <link>https://perrotta.dev/2026/03/reply-to-brazilian-affection/cuddling-vocabulary/</link>
      <pubDate>Mon, 02 Mar 2026 02:09:13 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>commentary</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/reply-to-brazilian-affection/cuddling-vocabulary/</guid>
      <description>&lt;p&gt;♠ I love this kind of post! It&amp;rsquo;s relatively uncommon to find this genre nowadays.&lt;/p&gt;&#xA;&lt;p&gt;It&amp;rsquo;s a comprehensive and high-quality collection of Brazilian Portuguese words&#xA;with explanations in English that are quite decent (and somewhat nostalgic for&#xA;me).&lt;/p&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://wordsmith.social/elilla/brazilian-casual-relationship-vocabulary&#34;&gt;See&#xA;also&lt;/a&gt;.&lt;/p&gt;&#xA;&lt;p&gt;A few minor additions to both posts, from my cultural background:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;em&gt;Arroz&lt;/em&gt;: an opportunistic &lt;em&gt;Grude&lt;/em&gt;, waiting for the perfect moment to strike.&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Lance&lt;/em&gt;: synonym with &lt;em&gt;Rolo&lt;/em&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;em&gt;Xaveco&lt;/em&gt;: flirting.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;If English is the &lt;a href=&#34;https://xcancel.com/karpathy/status/1617979122625712128&#34;&gt;hottest new&#xA;programming&lt;/a&gt;&#xA;&lt;a href=&#34;https://newsletter.pragmaticengineer.com/p/the-programming-language-after-kotlin&#34;&gt;language&lt;/a&gt;,&#xA;Brazilian Portuguese is THE best love language.&lt;/p&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: Reply to: Brazilian affection/cuddling vocabulary&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/commentary/&#34;&gt;%commentary&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>maple syrup whey
      </title>
      <link>https://perrotta.dev/2026/03/maple-syrup-whey/</link>
      <pubDate>Mon, 02 Mar 2026 00:11:33 +0100</pubDate><author>serendipity@perrotta.dev (Thiago Perrotta)</author>
      <category>recipes</category>
      <category>serenity</category>
      <guid>https://perrotta.dev/2026/03/maple-syrup-whey/</guid>
      <description>&lt;p&gt;♠ &lt;strong&gt;Timing&lt;/strong&gt;: within 2h after working out, to support muscle recovery &amp;amp; repair.&lt;/p&gt;&#xA;&lt;h2 id=&#34;ingredients&#34;&gt;&#xA;  Ingredients&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/03/maple-syrup-whey/#ingredients&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;250 – 300ml milk&lt;/li&gt;&#xA;&lt;li&gt;25 – 30g whey protein powder&lt;/li&gt;&#xA;&lt;li&gt;Maple syrup&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h2 id=&#34;preparation&#34;&gt;&#xA;  Preparation&#xA;  &lt;a class=&#34;heading-anchor&#34; href=&#34;https://perrotta.dev/2026/03/maple-syrup-whey/#preparation&#34; aria-label=&#34;Link to this section&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Shake it all, preferably using a shaker bottle (alternatively: a blender)&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;— § —&lt;/p&gt;&lt;p&gt;Reply via &lt;a href=&#34;mailto:serendipity@perrotta.dev?subject=Reply to: maple syrup whey&#34;&gt;email&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href=&#34;https://perrotta.dev/tags/serenity/&#34;&gt;#serenity&lt;/a&gt; &lt;a href=&#34;https://perrotta.dev/categories/recipes/&#34;&gt;%recipes&lt;/a&gt;&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
