Shellsharks Blogroll - BlogFlock2026-08-25T23:41:37.398ZBlogFlockAdepts of 0xCC, destructured, fLaMEd, Trail of Bits Blog, Aaron Parecki, Westenberg, James' Coffee Blog, gynvael.coldwind//vx.log (pl), joelchrono, Evan Boehs, Kev Quirk, cool-as-heck, Posts feed, Sophie Koonin, <span>Songs</span> on the Security of Networks, cmdr-nova@internet:~$, Werd I/O, Johnny.Decimal, Robb Knight, Molly White, Hey, it's Jason!, Terence Eden’s BlogImplementing webmentions - Posts feedhttps://www.coryd.dev/posts/2026/implementing-webmentions2026-08-25T20:57:00.000Z<div class="e-content block-subcanvas"><p>I've been working on a number of connection points between my site and the broader web. Part of that effort has been webmentions (which are a fairly small spec). You advertise an endpoint and someone posts a <code>source</code> and <code>target</code> and, from there, you do with the information as you please.</p>
<p>What expanded the scope of my implementation was that I wanted to pull in similarly shaped data from Mastodon and Bluesky. To receive a webmention, you have to advertise the endpoint in the <code>head</code> of your document: <code><link rel="webmention" href="/webmentions"></code>. From there, the flow looks like this:</p>
<ol>
<li>I receive a post to <code>/webmentions</code> and verify that both the <code>source</code> and <code>target</code> are either <code>http</code> or <code>https</code>. The <code>target</code> must be on my site and the <code>source</code> isn't on a blocklist I maintain.<sup id="fnref:1" class="footnote-ref">1</sup></li>
<li>I rewrite the target to my site's canonical host before I store it. This site was once served at the apex and is now served at the <code>www</code> subdomain, so mentions of the legacy, bare hostname are updated to include the subdomain.</li>
<li>New mentions are stored as pending, queue a background job with <a href="https://riverqueue.com">River</a> and return a <code>202 Accepted</code>. I tell the sender that I received the mention and move on.</li>
<li>The background job fetches the source of the mention and looks for the link back to the sent target. If there is no link, the mention is marked invalid.</li>
<li>If the link is there, I pull the rest: the title, author name, a snippet of the text on the page, publish time and the mention type.
<ul>
<li>The mention type is informed by microformats: <code>u-in-reply-to</code> for a reply, <code>u-like-of</code> a like, <code>u-repost-of</code> a repost and <code>u-bookmark-of</code> a bookmark. Anything else is a generic mention.<sup id="fnref:2" class="footnote-ref">2</sup></li>
</ul>
</li>
</ol>
<h3 id="gotcha">Gotcha!</h3>
<p>Fetching an arbitrary URL posted to your public webmentions endpoint is a vector for <a href="https://owasp.org/www-community/attacks/Server_Side_Request_Forgery">server-side request forgery</a>. When I go out to fetch a supplied URL I need to first resolve it to an IP and then open a TCP connection to that IP. If I validate the domain name up front, it's resolved a second time to actually connect. I could get a public address the first time and a private one the second. Instead, I validate the IP when the connection opens.</p>
<h3 id="all-things-in-moderation">All things in moderation</h3>
<p>The first iteration of this made any webmention received live on my site. The lack of friction was nice, but also meant that anything anyone sent could be rendered on my site without any intervention on my part. Don't do that.</p>
<p>I threw together a widget on my dashboard that queues up incoming link mentions so I can approve or block them as they come in.</p>
<h3 id="mention-paths">Mention paths</h3>
<p>In addition to my <code>/webmentions</code> endpoint, I populate mentions from my site's <a href="https://www.w3.org/TR/activitypub/#inbox">ActivityPub inbox</a><sup id="fnref:3" class="footnote-ref">3</sup>. I also have a poller that checks for interactions on posts syndicated to Mastodon and Bluesky. Most of my one-off posts originate as a <a href="https://www.coryd.dev/status">status</a> here that's syndicated out — when I thread status items here, they're threaded at the destination.</p>
<p>Activity from all three sources is written to the same table. Same schema across the board, with a column identifying the source. If someone removes their like or deletes their reply, the next poll notices it's gone and removes my copy.<sup id="fnref:4" class="footnote-ref">4</sup></p>
<p>Posts to my endpoint are verified as discussed above, ActivityPub activity is signed and my poller fetches only my posts. Verified interactions are written to the table.</p>
<h3 id="mentioning-things">Mentioning things</h3>
<p>I link to things (a lot). When I post something here I've built in options to syndicate out to Mastodon and Bluesky. Sitting alongside those platforms are the options to send webmentions, publish to the site's <a href="https://www.w3.org/TR/activitypub/#outbox">ActivityPub outbox</a> and publish to <a href="https://standard.site">standard.site</a>.</p>
<p>When I send webmentions, a job pulls apart the published item to find external links, finds each site's webmention endpoint (if they have one) and sends the same <code>source</code> and <code>target</code> data I accept. Timing can be a factor here (network topology blah blah hostile blah). If something times out during the back and forth here the job will retry it.</p>
<h3 id="rendering-externally-supplied-stuff">Rendering externally supplied stuff</h3>
<p>Rendered replies and bare mentions means rendering input someone else provided. When I render it, the text is escaped and the URL is validated (don't send me <code>javascript:</code> nonsense). Outbound links have <code>rel="nofollow ugc"</code> thrown on them.</p>
<hr/>
<p>So, yes, in theory this is a simple spec and one that takes in little data. <em>But</em> you're dealing with external writes, I elected to add additional sources and then tacked moderation on top. It works and, so far, it works well.</p>
<div class="footnotes" role="doc-endnotes"><hr/><ol><li id="fn:1"><p>This was originally targeted at my contact form, but webmentions now leverages it as well. ↩︎</p>
</li><li id="fn:2"><p>I'm extracting content with regexes like an animal, not with a microformats parser. ↩︎</p>
</li><li id="fn:3"><p>More on this later — yes, this site exists on the <a href="https://en.wikipedia.org/wiki/Fediverse">Fediverse</a>. ↩︎</p>
</li><li id="fn:4"><p>Fediverse removals are sent as an <code>Undo</code> and delete the row without polling. ↩︎</p>
</li></ol></div></div>Theatre Review: Cats at Regent's Park Open Air Theatre ★★★★☆ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=743802026-08-25T11:34:22.000Z<p>Cats is so <em>silly!</em></p>
<p>In the olden days, after a wild animal was slaughtered, the tribe's shaman would wear the skin and re-enact the hunt. As he became one with the beast, the people slowly understood the ways of nature.</p>
<p>Cats is a similarly spiritual experience wherein we watch androgynous sylphs gyrate across the stage and believe (if only for a moment) that the human has become feline, all in service of better understanding the mysteries of our moggies.</p>
<p>Does there need to be so many sequins? So much dry ice? Such a quantity of pyrotechnics?</p>
<p>No, probably not. But it all adds up to a spectacular which will keep you grinning.</p>
<p>The deficiencies in Cats are somewhat inherent. The scrapbook story doesn't make a lick of sense. It is more like a variety show than musical theatre. The lyrics are, at times, utterly asinine. The music soars, until someone starts playing what sounds like a genuine 1980s Casio keyboard - and all you can hear is squelch.</p>
<p>But then Gary Wilmot (!!!) comes on as Gus and all is forgiven on a haze of metatextual glory.</p>
<p>The choreography and dancing are exemplary. The singing occasionally gets muddled but is mostly delightful. The stage is perfect - the wind blowing through the trees and the moon gently rising only helps to accentuate the atmosphere.</p>
<p>The pre-show is good. As well as a variety of food stalls, patrons are encouraged to bring their own food and drink for a picnic. There are plenty of tables and a couple of selfie points.</p>
<p>The programme isn’t horrendous at £6 but still feels like it contains more advertising than content. The queues for the loos were outrageously long and the stalls weren't particularly clean.</p>
<p>There's nothing to do post-show except trudge back through the park. The selfie point is still illuminated if you want to queue for that. Even the t-shirt sales stopped after the interval.</p>
<p>I first saw Cats in the West End some time in the 1980s as a child and loved it. Afterwards my parents asked if I wanted to see a ballet or an opera next. "Eurgh! No! <em>Boring!</em>" I said. They politely informed me that I'd just seen both in one show and my juvenile mind was blown.</p>
<p>A few decades later I saw Cats on Broadway - shortly before it closed, I think. The C90 cassette they used to play the music was warbling like a demented bird and the sets looked equally tired. Despite the half empty auditorium, the cast attacked the songs with vigour. I still loved it.</p>
<p>And, today, I still had goosebumps. Maybe it was the unseasonable chill in the air, maybe it was the moonlight, or maybe it was the magic of Cats!</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=74380&HTTP_REFERER=Atom" alt width="1" height="1" loading="eager">State divergence enables unauthorized access - Trail of Bits Bloghttps://blog.trailofbits.com/2026/08/25/state-divergence-enables-unauthorized-access/2026-08-25T11:00:00.000Z<p>We found and reported a bug in Provenance Blockchain, a public proof-of-stake chain built on <a href="https://docs.cosmos.network/">Cosmos SDK</a>, that lets any user grant themselves admin control over marker accounts without holding a single token. Provenance covers a range of financial services, including on-chain tokenized loans, private equity tokens, bridged assets, and asset registries. Our bug affected 82 markers representing live financial assets on mainnet.</p>
<p>We found the bug, which affects versions before 1.28.0, in March 2026, and reported it to Provenance on April 1. It was fixed in <a href="https://github.com/provenance-io/provenance/pull/2627">PR #2627</a> (commit <a href="https://github.com/provenance-io/provenance/commit/c81fd65f8ad48de42d5a6d68e761a0851c7e72c4">c81fd65</a>), which shipped in v1.28.0 on May 1, 2026.</p>
<h2 id="what-is-a-marker">What is a marker?</h2>
<p>The marker module is Provenance&rsquo;s core primitive for fungible tokens. Chain participants can issue a new asset on Provenance by submitting a <code>MsgAddMarkerRequest</code> transaction; the chain creates a dedicated account for that asset, called a marker. Each marker is a special account type that controls:</p>
<ul>
<li>A <strong>denomination</strong> (e.g., <code>uusd.trading</code>, <code>cusd.deposit</code>, <code>cguaranteedrateomni</code>)</li>
<li>An <strong>access control list</strong> governing who can mint, burn, withdraw, deposit, or administer the token</li>
<li>A <strong>supply field</strong> recording the canonical token count</li>
<li>An <strong>escrow balance</strong> (the marker account can hold any asset, not just its own denomination)</li>
</ul>
<p>Markers are either <code>supply_fixed</code> (the supply field is enforced as a hard cap) or non-fixed (the bank module is the source of truth; the supply field is informational). This distinction is central to the bug.</p>
<h2 id="the-bug-an-access-check-anyone-can-pass">The bug: An access check anyone can pass</h2>
<p><a href="https://github.com/provenance-io/provenance/blob/488b8a73e292043910aaf0ec485fac961b5e2c97/x/marker/keeper/msg_server.go#L139-L159"><code>AddAccess</code></a> is the Cosmos SDK message handler that processes requests to modify a marker&rsquo;s access control list. It checks whether the caller is authorized using three conditions, any one of which is sufficient:</p>
<ol>
<li>The caller is the marker&rsquo;s designated manager and the marker is in <code>Finalized</code> state.</li>
<li>The caller already holds <code>ACCESS_ADMIN</code> on the marker.</li>
<li><strong>The caller controls 100% of the marker&rsquo;s circulating supply.</strong></li>
</ol>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="k">case</span><span class="w"> </span><span class="nx">types</span><span class="p">.</span><span class="nx">StatusFinalized</span><span class="p">,</span><span class="w"> </span><span class="nx">types</span><span class="p">.</span><span class="nx">StatusActive</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">!(</span><span class="nx">caller</span><span class="p">.</span><span class="nf">Equals</span><span class="p">(</span><span class="nx">m</span><span class="p">.</span><span class="nf">GetManager</span><span class="p">())</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nf">GetStatus</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nx">types</span><span class="p">.</span><span class="nx">StatusFinalized</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">!</span><span class="nx">m</span><span class="p">.</span><span class="nf">AddressHasAccess</span><span class="p">(</span><span class="nx">caller</span><span class="p">,</span><span class="w"> </span><span class="nx">types</span><span class="p">.</span><span class="nx">Access_Admin</span><span class="p">)</span><span class="w"> </span><span class="o">&amp;&amp;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">!</span><span class="nx">k</span><span class="p">.</span><span class="nf">accountControlsAllSupply</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="nx">caller</span><span class="p">,</span><span class="w"> </span><span class="nx">m</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;%s is not authorized to make access list changes against finalized/active %s marker&#34;</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nx">caller</span><span class="p">,</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nf">GetDenom</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span></span></span></code></pre>
<figcaption><span>Figure 1: Authorization check in <code>keeper.AddAccess</code> (<a href='https://github.com/provenance-io/provenance/blob/488b8a73e292043910aaf0ec485fac961b5e2c97/x/marker/keeper/marker.go#L94-L100'><code>x/marker/keeper/marker.go#L94–L100</code></a>)</span></figcaption>
</figure>
<p>Condition 3 is implemented by <code>accountControlsAllSupply</code>:</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span><span class="w"> </span><span class="p">(</span><span class="nx">k</span><span class="w"> </span><span class="nx">Keeper</span><span class="p">)</span><span class="w"> </span><span class="nf">accountControlsAllSupply</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nx">ctx</span><span class="w"> </span><span class="nx">sdk</span><span class="p">.</span><span class="nx">Context</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nx">caller</span><span class="w"> </span><span class="nx">sdk</span><span class="p">.</span><span class="nx">AccAddress</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nx">m</span><span class="w"> </span><span class="nx">types</span><span class="p">.</span><span class="nx">MarkerAccountI</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="kt">bool</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nx">balance</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">k</span><span class="p">.</span><span class="nx">bankKeeper</span><span class="p">.</span><span class="nf">GetBalance</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="nx">caller</span><span class="p">,</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nf">GetDenom</span><span class="p">())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nx">supply</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nf">GetSupply</span><span class="p">()</span><span class="w"> </span><span class="c1">// ← bug</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">supply</span><span class="p">.</span><span class="nf">Equal</span><span class="p">(</span><span class="nx">sdk</span><span class="p">.</span><span class="nf">NewCoin</span><span class="p">(</span><span class="nx">m</span><span class="p">.</span><span class="nf">GetDenom</span><span class="p">(),</span><span class="w"> </span><span class="nx">balance</span><span class="p">.</span><span class="nx">Amount</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span></span></span></code></pre>
<figcaption><span>Figure 2: The vulnerable <code>accountControlsAllSupply</code> function (<a href='https://github.com/provenance-io/provenance/blob/488b8a73e292043910aaf0ec485fac961b5e2c97/x/marker/keeper/marker.go#L866-L875'><code>x/marker/keeper/marker.go#L866–L875</code></a>)</span></figcaption>
</figure>
<p>The <code>m.GetSupply</code> function reads the supply field stored directly on the marker struct. For non-fixed supply markers that were activated with zero supply, that field <strong>always stays zero</strong>. The live circulating count lives in the bank module, and non-fixed markers never write back to the marker struct after minting.</p>
<p>So for any non-fixed supply marker, the authorization check reduces to the following:</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="cl">supply = Coin{denom, 0} // stored marker field, always 0
</span></span><span class="line"><span class="cl">balance = Coin{denom, 0} // attacker holds no tokens
</span></span><span class="line"><span class="cl">0 == 0 → true</span></span></code></pre>
<figcaption><span>Figure 3: Authorization check result for a non-fixed supply marker when the caller holds no tokens</span></figcaption>
</figure>
<p>The check intended to restrict access to 100%-of-supply holders becomes unconditionally true for any caller with zero balance.</p>
<h2 id="exploitation-two-transactions-to-mint-or-drain">Exploitation: Two transactions to mint or drain</h2>
<p>An attacker sends a single <code>MsgAddAccessRequest</code> transaction:</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;denom&#34;</span><span class="p">:</span> <span class="s2">&#34;uusd.trading&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;administrator&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;attacker_address&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;access&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;address&#34;</span><span class="p">:</span> <span class="s2">&#34;&lt;attacker_address&gt;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nt">&#34;permissions&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;ACCESS_ADMIN&#34;</span><span class="p">,</span> <span class="s2">&#34;ACCESS_MINT&#34;</span><span class="p">,</span> <span class="s2">&#34;ACCESS_WITHDRAW&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre>
<figcaption><span>Figure 4: <code>MsgAddAccessRequest</code> granting the attacker admin, mint, and withdraw permissions on a target marker</span></figcaption>
</figure>
<p>No existing tokens are needed for exploitation. The authorization check passes immediately via the broken condition 3. From there, the attacker has two paths:</p>
<ul>
<li><code>MsgMintRequest</code>: to mint new tokens of the marker&rsquo;s denom and send them to any address</li>
<li><code>MsgWithdrawRequest</code>: to drain any assets held in the marker&rsquo;s escrow balance</li>
</ul>
<p>The whole attack is two transactions: one to gain permissions, and one more to act on them.</p>
<h2 id="impact-what-was-at-risk">Impact: What was at risk</h2>
<p>At the time of discovery, <strong>82 active markers</strong> on Provenance mainnet had a stored supply of 0 while carrying real circulating supply or escrowed assets, every one of them exploitable. These markers span multiple independent parties on the chain, not a single application.</p>
<p><strong>Escrow withdrawal</strong> was the most direct path. Among the affected markers, those holding nhash (Provenance&rsquo;s base token) in escrow accounted for roughly 30 × 10<sup>15</sup> nhash, or around <strong>$500,000 at HASH prices at the time of discovery</strong>. The three largest markers are shown below:</p>
<table>
<thead>
<tr>
<th style="text-align: left">Marker</th>
<th style="text-align: left">Owner</th>
<th style="text-align: left">Escrowed nhash</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left"><code>grant0051</code></td>
<td style="text-align: left">Provenance Foundation grant program</td>
<td style="text-align: left">19,230,770,000,000,000</td>
</tr>
<tr>
<td style="text-align: left"><code>provenance.validator.incentive.program</code></td>
<td style="text-align: left">Chain validator incentive fund</td>
<td style="text-align: left">8,561,225,000,000,000</td>
</tr>
<tr>
<td style="text-align: left"><code>grant0077</code></td>
<td style="text-align: left">Provenance Foundation grant program</td>
<td style="text-align: left">2,486,556,736,909,250</td>
</tr>
</tbody>
</table>
<p>The three markers shown above are all chain governance programs operated by the Provenance Foundation: one holds validator rewards, and two hold community grant funds.</p>
<p><strong>Supply inflation</strong> was a broader but more constrained vector. The 74 vulnerable markers spanned bridged stablecoins and wrapped assets (<code>uusd.trading</code>, <code>uusdc.figure.se</code>, <code>nbtc.figure.se</code>), consortium deposits (<code>cusd.deposit</code>), tokenized mortgage participations (<code>cguaranteedrateomni</code>, <code>chomebridgeomni</code>), and yield tokens (<code>nuva.ylds</code>, <code>uylds.fcc</code>). An attacker with <code>ACCESS_MINT</code> on any of these could issue arbitrary new tokens of that denom. The practical harm depended on the token type. For restricted tokens with KYC requirements, it was primarily a solvency and integrity threat; for non-restricted coin-type markers, it was a more direct inflation risk.</p>
<p>We confirmed the affected markers and their balances by querying mainnet via the Provenance CLI and the public REST API.</p>
<h2 id="the-fix-read-live-supply-and-guard-against-zero">The fix: Read live supply, and guard against zero</h2>
<p><a href="https://github.com/provenance-io/provenance/pull/2734">PR #2734</a> shipped the fix, which changes one line:</p>
<figure class="highlight">
<pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="c1">// Before: reads stale stored field, always 0 for non-fixed markers</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nx">supply</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nf">GetSupply</span><span class="p">()</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// After: reads live circulating supply from the bank module</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="nx">supply</span><span class="w"> </span><span class="o">:=</span><span class="w"> </span><span class="nx">k</span><span class="p">.</span><span class="nx">bankKeeper</span><span class="p">.</span><span class="nf">GetSupply</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span><span class="w"> </span><span class="nx">m</span><span class="p">.</span><span class="nf">GetDenom</span><span class="p">())</span></span></span></code></pre>
<figcaption><span>Figure 5: The one-line fix (<a href='https://github.com/provenance-io/provenance/pull/2734/changes#diff-bc1ca0afea7f4545a016207811d6f040977cf4ccbd57245b5373f7d4e5adfa40R898'><code>x/marker/keeper/marker.go</code></a> in PR #2734)</span></figcaption>
</figure>
<p>A zero-guard was also added: if the live supply is zero, <code>accountControlsAllSupply</code> returns false. This correctly handles the edge case where a marker exists but no tokens have been minted yet, so no one can self-admin an empty marker via this path.</p>
<h2 id="authorization-must-fail-from-the-default-state">Authorization must fail from the default state</h2>
<p>The root cause of this issue was state desynchronization. The marker struct and the bank module both represent the token supply, but only the bank module is kept current for non-fixed markers. The authorization check read from the wrong one.</p>
<p>The check wasn&rsquo;t just wrong; it was bypassable by default because of the zero-equality shortcut. Because the stale field was always 0, the comparison <code>0 == 0</code> was always true. An access control check that compares against a value that is always the same as the attacker&rsquo;s default state is trivially bypassable.</p>
<p>Switching to the live bank supply alone doesn&rsquo;t fully close the hole. A freshly deployed marker with no tokens minted yet also has live supply of zero, so an attacker could self-grant admin by targeting it before it&rsquo;s funded. The fix handles this with an explicit zero-guard: <code>accountControlsAllSupply</code> returns false whenever live supply is zero, regardless of balance.</p>
<p>The broader pattern: an authorization predicate must never be satisfiable from the attacker&rsquo;s default state. A check of the form <code>balance == supply</code> hands access to everyone when supply can be zero, whether because the state is stale or the marker is simply unfunded.</p>
<p>Two things would have caught this before it went live. First, the access-list authorization model was never specified. Writing the rule down forces both questions that point straight at the bug: which supply, and what happens when it&rsquo;s zero? Second, the property is easy to state: <code>accountControlsAllSupply</code> should only return true when live supply is positive and the caller holds all of it. A property-based test or fuzzer that generates random sequences of marker operations, such as minting, transferring, and creating empty markers, and checks this property after each step would find both failure modes automatically.</p>2026-w34 - Joel's Log Fileshttps://joelchrono.xyz/blog/2026-w342026-08-25T01:47:37.000Z<p>Today I was on vacation and I have been watching YouTube videos all day long for some reason. I could have finished a videogame or a book in all this time. However, I was watching a long playthrough of Outer Wilds. Because I have finished that game and I am absolutely thrilled about it. What a videogame, please play it. Well, will talk more of this on my gaming section. In any case, here’s some other things that happened this week from August 18 to 24, 2026.</p>
<ul>
<li>
<p>Think it’s fair to say I ain’t making 31 posts for Blaugust this year! I can always try some other time.</p>
</li>
<li>
<p>These weeknotes will be super lazy because I was super lazy the whole week. There were visits and I didn’t get a lot of time for myself to sitdown and write, these weeknotes so they’ll also be short.</p>
</li>
<li>
<p>Went out shopping to the mall with my sister, her <em>boyfriend</em> and my parents… I didn’t actually buy much this time other than a frappe.</p>
</li>
<li>
<p>Wanted to get a physical edition of The Odyssey but I couldn’t find a good translation at the mall’s library. I’ll just stick to digital I think, no big deal.</p>
</li>
<li>
<p>Still not going to the gym at all, I haven’t even gone cycling this week. I’ve been lazing around like crazy.</p>
</li>
<li>
<p>Studied more of Land of Eem’s TTRPG system so I can be a better GM for a future playthrough, didn’t manage to play again this weekend.</p>
</li>
<li>
<p>Literally read nothing the whole week. Definitely got absorbed by <em>Outer Wilds</em> and its lore, man…</p>
</li>
</ul>
<h2 id="gaming">Gaming</h2>
<h3 id="completed">Completed</h3>
<ul>
<li><strong>Outer Wilds</strong> - A game I started in January that took me by storm and was abandoned for months, only to return in August and get me through a whole <em>hurricane.</em> This game was an incredible undertaking and I am absolutely floored by every single thing that happened here. The search for knowledge provided the answers, and that finale tore me apart and built me back up. This is a one of a kind experience. You must play it. I need and will play <em>Echoes of The Eye</em> in the future.</li>
</ul>
<h3 id="ongoing">Ongoing</h3>
<ul>
<li>
<p><strong>The Legend of Zelda: Ocarina of Time 3D</strong> - After finally being freed from the hold of Outer Wilds, I’m currently making progress on Jabu Jabu’s Belly! Haven’t finished at all but managed to beat the miniboss, which was a pain until I once again remembered Deku Nuts exist.</p>
</li>
<li>
<p><strong>Hollow Knight: Silksong</strong> - I’m gathering the materials necessary to unlock Act 3 and reach some of the extra stuff this game has to offer! Looking forward to that, but not a lot of progress otherwise.</p>
</li>
<li>
<p><strong>Super Smash Bros</strong> - Played once again and this time we unlocked a couple of characters. Yes, believe it or not I am yet to unlock all the characters in the game, My deepest apologies.</p>
</li>
<li>
<p><strong>Fire Emblem Awakening</strong> - I am still unable to beat Chapter 19, enough said!</p>
</li>
</ul>
<h2 id="around-the-web">Around the Web</h2>
<h3 id="blog-posts">Blog posts</h3>
<ul>
<li><a href="https://manuelmoreale.com/thoughts/on-values-morals-and-doing-business">On values, morals, and doing business</a></li>
<li><a href="https://notes.jeddacp.com/life-lately-001/">Life Lately 001</a></li>
<li><a href="https://syls.blog/my-favorite-game-screenshots/">My Favorite Game Screenshots</a></li>
<li><a href="https://burgeonlab.com/notes/2026/0824-0100/">Mac Mini 2018 i7 Hand-me-down</a></li>
</ul>
<h3 id="youtube">Youtube</h3>
<ul>
<li><a href="https://youtu.be/msABa06aiT0">Outer Wilds Is Hard To Get Into (Feat. Outer Wilds Creative Director Alex Beachum)</a></li>
<li><a href="https://youtu.be/3KeVT0nWsUs">I beat NES Metroid without a guide…. Yeah.</a></li>
<li><a href="https://youtu.be/-1MO8CPqEv8">How a B-List Hero Became Bigger Than The MCU</a></li>
<li><a href="https://youtu.be/eLBFW-4pX34">The Tech Review Nobody Wants to Make</a></li>
<li><a href="https://youtu.be/tYbb-jaWzWE">Mexico City Has a Problem You Can See from Space</a></li>
</ul>
<p>This is day 22 of <a href="https://100daystooffload.com">#100DaysToOffload</a> and day 16 of <a href="https://nerdgirlthoughts.game.blog/2026/07/15/blaugust-2026-is-coming">#Blaugust2026</a></p>
<p>
<a href="mailto:me@joelchrono.xyz?subject=2026-w34">Reply to this post via email</a> |
<a href="https://fosstodon.org/@joel/117154433692560271">Reply on Fediverse</a>
</p>Wonders of Web Weaving, Episode 16 - James' Coffee Bloghttps://jamesg.blog/2026/08/25/www-162026-08-25T00:00:00.000Z
<p><a href="https://web-weaving.jamesg.blog/16" rel="noreferrer">The sixteenth episode of Wonders of Web Weaving is out</a>:</p><blockquote>In Episode 16, I chat with <a href="https://www.nicchan.me">Nic</a>, the author of <a href="https://www.nicchan.me">nicchan.me</a> about, among other things, using the web as a design tool, web accessibility, learning from others' code, and more.</blockquote><p>I hope you enjoy the episode!</p><p><a href="https://web-weaving.jamesg.blog/subscribe/" rel="noreferrer"><em>Wonders of Web Weaving also has an RSS feed</em></a><em> you can use to follow along from wherever you get your podcasts.</em></p>
<a class="tag" href="https://web-weaving.jamesg.blog/16">The sixteenth episode of Wonders of Web Weaving is out</a>
<a class="tag" href="https://web-weaving.jamesg.blog/subscribe/">Wonders of Web Weaving also has an RSS feed</a>
<a class="tag" href="https://www.nicchan.me">Nic</a>
<a class="tag" href="https://www.nicchan.me">nicchan.me</a>
Why do audience members choose specific shows at the Edinburgh Fringe? - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=743302026-08-24T11:34:45.000Z<p>On our <a href="https://shkspr.mobi/blog/2026/08/thoughts-on-the-edinburgh-fringe-as-a-newbie/">recent trip to the Edinburgh Fringe</a>, I was bemused by just how little effort performers put in to finding out <em>why</em> people had selected their show. Taking a show to the Edinburgh Fringe is ridiculously expensive with <a href="https://www.scotsman.com/business/edinburgh-festival-fringe-2025-the-true-cost-of-performing-at-the-worlds-largest-arts-event-laid-bare-5247134">some performers paying tens of thousands of pounds</a>. The way performers recoup the costs of performing is by getting people to pay to see a show.</p>
<p>Acts are spending huge amounts on flyers, posters, and other promotional activities. But is any of it worthwhile?</p>
<p>The performer Danielle Solof has a fascinating blog post "<a href="https://daniellesolof.substack.com/p/my-real-fringe-budgets-line-by-line">My Real Fringe Budgets, Line-by-Line</a>" which details the actual costs of her taking two solo shows to the Fringe. She meticulously details the price of everything from transport and food, to advertising and graphic design. She says:</p>
<blockquote><p>I paid for outdoor ads because absolutely no one in Edinburgh knew who I was. They <em>did</em> help, but you still have to grind to get an audience in.</p></blockquote>
<p>My question to her - and all performers - is how do you know what drives an audience member to see your show?</p>
<p>It can't have escaped your attention that everything we do online is tracked. If you buy so much as a toothpick, the retailer knows which YouTube reviews you watched, which words you searched for, the other products you considered, and the specific adverts you clicked on.</p>
<p>In Edinburgh, no one knows nothing.</p>
<p>At the end of nearly every show the performer begged us to leave a review on the Fringe website and to tell our friends. In absolutely <em>none</em> of the shows did the performer ask why we were there, how we found out about the show, which poster or leaflet attracted us, or whether we followed them on social media.</p>
<p>All that money spent on posters and no one knows if they work. As the old saying goes "<a href="https://quoteinvestigator.com/2022/04/11/advertising/">Half the money I spend on advertising is wasted, and the trouble is I don’t know which half.</a>".</p>
<p>So, in an attempt to bring a <em>little</em> data to proceedings, here are how we chose the 26 shows we saw. I don't claim this is representative of everyone, but I think it might be illustrative. In rough order of importance were:</p>
<h2 id="proximity"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#proximity">Proximity</a></h2>
<p>The EdFringe app has a "nearby now" feature. Click on it and you get a list of shows starting soon which are only staggering distance away.</p>
<p>I cannot stress enough how much of a motivator that was. When you've spent all day traipsing, the last thing you want to do is <em>another</em> 20 minute walk uphill to see a provocative new piece of challenging theatre told through finger puppets.</p>
<p>About 20% of the shows we saw were via that feature.</p>
<p>Roughly another 40% were because the show was close to something else we really wanted to see. We knew that we wanted to see show X, so we looked for shows which weren't too far away from that venue. Yes, Edinburgh is a compact city with decent public transport, but it is much easier to walk round the corner or stay to have a drink in the venue's bar.</p>
<p>You can <em>really</em> want to see a show, but if it is a 20 minute walk between venues and it starts 15 minutes after your last show ends, you'll skip it. I'd say that location was the key driver in most of our choices.</p>
<p>I guess my top tip to any performer would be to be as near as physically possible to a bigger act!</p>
<h2 id="friends"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#friends">Friends</a></h2>
<p>A quarter of the shows we went to were because either a friend-of-a-friend was performing, or a friend booked tickets and asked if we wanted to tag along.</p>
<p>You are morally obliged to go to your friends' shows. Similarly, if a mate says "Oh, my friend has a show on this year", you have to make the effort to go.</p>
<p>Perhaps it is a bit blasé to say that word-of-mouth works, but it's a cliché becausé it is trué.</p>
<h2 id="flyers-and-leaflets"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#flyers-and-leaflets">Flyers and Leaflets</a></h2>
<p>We collected approximately 5,374 different promotional leaflets during our week there. Most of the time we were handed a leaflet by someone paid to hand out leaflets. They were either wordlessly stuffed into our hands, or delivered with a monotone "wanna see improv comdy?" Bleh.</p>
<p>A few actually spoke to us about the show when we asked questions, which was a deciding factor in seeing a couple of performances.</p>
<p>The best flyerers were, undoubtedly, the performers themselves. Kat Ronson in her <a href="https://shkspr.mobi/blog/2026/08/edinburgh-fringe-kat-ronson-millennial-girl/">Millennial Girl</a> guise drawled at us "You look thin and pretty. You're allowed to come to my show." Instant sale!</p>
<p>Similarly, one rather famous comedian walked up to us and said "You look like theatre people!" and proceeded to pitch their show - which was a delightful encounter and would have sold us a ticket if we weren't leaving that day.</p>
<p>Some flyers had a QR code or URl on them so we could watch a trailer of the show. We didn't watch any of them. Perhaps we should have?</p>
<h2 id="posters"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#posters">Posters</a></h2>
<p>Surprisingly effective at drawing the eye! The ones which were just a photo of the comedian looking a bit "whacky" were dull. The ones of performers in their most seductive poses were a little naff. The ones which were just a close up of someone's face only really work if that person is incredibly famous, otherwise you're just left thinking "who?"</p>
<p>But a few posters made us stop and immediately search for the show. Graphic design is a professional skill and one worth investing in.</p>
<p>Some posters were everywhere. I took an instant (and uncharitable) dislike to one poster featuring a smug-looking twat and I swear he followed me around town. Some posters only appeared near the performance venue.</p>
<p>Incidentally, there were a couple of posters which had clearly just been fed into an AI generator. Lazy and off-putting.</p>
<h2 id="reviews"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#reviews">Reviews</a></h2>
<p>The Fringe doesn't allow weighted star reviews - so you can't immediately see if the consensus is that the show is a hit or a miss. Several of the shows we didn't enjoy got excellent reviews (from morons) and some of the shows we loved were panned (presumably by the same morons).</p>
<p>In truth, I don't think the reviews influenced our decision to see anything.</p>
<h2 id="what-stopped-us-going-to-shows"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#what-stopped-us-going-to-shows">What <em>Stopped</em> Us Going To Shows</a></h2>
<p>For every action there is an equal and opposite reaction. I think it is important for performers to know what stopped someone clicking the "buy" button for their show.</p>
<h3 id="ticket-cost-value-for-money"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#ticket-cost-value-for-money">Ticket Cost / Value For Money</a></h3>
<p>Mondays and Tuesdays saw lots of shows doing a 2-for-1 promotion. I didn't mind spending £30 for two of us to take a risk on something. Come Wednesday, I wasn't prepared to pay £60 for a 45 minute show.</p>
<p>I know "surge pricing" gets a bad rap, but <a href="https://shkspr.mobi/blog/2024/09/why-does-no-one-discuss-negative-dynamic-pricing/">dynamic pricing of underselling shows</a> might help. If you've only sold four seats for today, perhaps drop the price? I don't know if the Fringe software supports that - but it seems obvious to me that having 10 people paying a fiver is better than four people paying a tenner.</p>
<h3 id="crap-signal-long-queues"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#crap-signal-long-queues">Crap Signal / Long Queues</a></h3>
<p>We tried to get in to a circus show. My phone didn't have enough signal for the app to work and the nearest box office had a massive queue. So we bailed.</p>
<p>If the venue had WiFi (not a given, weirdly) it would have gotten them an extra sale. If the ticket staff could take contactless (lots of performers did) we'd have happily paid.</p>
<p>You have to make it easy for people to give you money.</p>
<h3 id="not-enough-time"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#not-enough-time">Not Enough Time</a></h3>
<p>This is completely out of the performers' control. We had 6 days and saw about 4 shows per day. We could have seen more, but we needed to eat, explore, and sleep.</p>
<p>Speaking of which, there were several midnight performances which looked excellent - but I also needed to get up the next day to see more shows. Sleep won!</p>
<h3 id="too-famous"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#too-famous">Too Famous</a></h3>
<p>I'd love to see that guy who's on the telly. But I can watch him on the telly. That show looks like a massive success, so I'm sure it'll tour round London soon.</p>
<h3 id="sell-outs"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#sell-outs">Sell Outs</a></h3>
<p>A few shows sold out before we could get tickets. Good for them! If that was your show, you probably don't need this blog post.</p>
<h2 id="better-art-through-commerce"><a href="https://shkspr.mobi/blog/2026/08/why-do-audience-members-choose-specific-shows-at-the-edinburgh-fringe/#better-art-through-commerce">Better Art Through Commerce</a></h2>
<p>Art should be driven by passion.</p>
<p>But every performer I know listens back to their shows to see what works and what didn't. If a joke falls flat, it's cut. If a riff gets a big laugh, it's incorporated. That's the essence of data driven decision making.</p>
<p>I wish every performer at the Fringe had a sell out audience and were able to recoup their costs. But that is never going to happen unless they spend time understanding what gets bums on seats.</p>
<p>So here are a few scattered thoughts on how they could do that.</p>
<ul>
<li>QR code at the end of the show leading to a survey. Literally ask people "what made you choose this performance?"</li>
<li>In the queue before the show, or as people are taking their seats, hand out a paper questionnaire.</li>
<li>Talk to the audience after the show. See if you can gain any insights about what made them attend.</li>
<li>As people are coming in, have a poster asking people to tick a box based on how they heard about the show.</li>
<li>Give each leaflet a unique code (or a code per person handing them out). Ask people to bring the leaflet with them so you can see which area/person/leaflet was most effective.</li>
<li>Each poster can have a unique QR code on it. Track whether the one by the station led to more ticket sales than the one in the underpass. Did the one in the gents toilets get <em>any</em> scans at all?</li>
</ul>
<p>Of course, all of the above rely on talking to people who made the choice to see you. This is classic <a href="https://en.wikipedia.org/wiki/Survivorship_bias">Survivorship Bias</a>. Sure, it'll help you work out what was <em>successful</em>, but you won't know why people looked at your show and chose something else. That said, it is <em>hard</em>. How do you find people who <i lang="la">ipso facto</i> aren't at your show?</p>
<ul>
<li>That could be as simple as asking people what they dislike about the leaflet when you hand it out.</li>
<li>Each poster or leaflet can have a unique QR code on it. Which ones cause people to scan, but then abandon the idea of buying a ticket?</li>
<li>Speak to people who came to the venue for a show other than yours. They obviously like the location, so non-confrontationally ask them why they didn't pick you?</li>
</ul>
<p>Some of these are easier than others. By themselves, they might give you a slightly misleading view of the data. But surely anything is better than looking at a half empty venue and wondering if those huge advertising costs did any good at all.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=74330&HTTP_REFERER=Atom" alt width="1" height="1" loading="eager">2026-08-24 11:01: A friend asked for help setting up a blog, so I went with #Pureblog (obviously).... - Kev Quirkhttps://kevquirk.com/2026-08-24-11012026-08-24T10:01:00.000Z<p>A friend asked for help setting up a blog, so I went with #Pureblog (obviously).</p>
<p>We went from nothing to fully working blog, with <strong>all</strong> the customisations she wanted in about 25 minutes.</p>
<p>I know I'm bias, but I love how flexible and powerful Pure Blog is becoming.</p> <div class="email-hidden">
<hr />
<p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p>
<p>You can <a href="mailto:19gy@qrk.one?subject=2026-08-24%2011%3A01">reply to this post by email</a>, or <a href="https://kevquirk.com/2026-08-24-1101#comments">leave a comment</a>.</p>
</div>First moments - James' Coffee Bloghttps://jamesg.blog/2026/08/24/first-moments2026-08-24T00:00:00.000Z
<p>When I got out of bed this morning, I felt a chill from the autumn air that had been flowing through the room since yesterday evening. The air was cooled by midnight and would soon be warmed by the burgeoning sun rising over the hills. The seasons are changing. I can feel it.</p><p>I opened the window and looked onto the white horizon sky; so intense was the white sky it took me a few moments to notice the faint blues that were already above me and extended across most of the rest of the sky. I love this time of year, when I wake up closer to the sunrise now that it happens a bit later in the morning. The sunlight illuminated the rusty leaves on the tips of a tree outside, a tree still green in its core but, like all trees, starting to change as summer becomes autumn.</p><p>I thought about the first moments of the day. I found great joy in looking out the window for the first time this morning, the same joy as I feel every time I see the sun rise. I revelled in noting the sights and feelings and sounds of the first moments of the day – of seeing the sunrise, feeling the chill in the air, and hearing pouring the boiling water from the kettle into my favourite tea cup, of feeling the warmth of the tea as I cusped my hands around the cosy cup, of enjoying all the light coming through the windows, of appreciating how green the hills are at this time in the morning.</p><p>With every step, illuminated by daylight, thinking about how every day is new, I felt ever more ready for the day ahead.</p><script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a300da18bd94f0b4',t:'MTc4NzU1ODcyNg=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
Dungeon Crawler Carl - Kev Quirkhttps://kevquirk.com/dungeon-crawler-carl2026-08-23T12:03:00.000Z<div class="book card"><h2>Dungeon Crawler Carl</h2><p><b>Author:</b> Matt Dinniman<br><b>Genre:</b> Fantast, Sci-fi<br><b>Released:</b> 2020<br><b>Rating:</b> <span class="star-rating"><span class="star-rating" aria-label="5/5 ★★★★★">★★★★★</span></span></p><p>You know what’s worse than breaking up with your girlfriend? Being stuck with her prize-winning show cat. And you know what’s worse than that? An alien invasion, the destruction of all man-made structures on Earth, and the systematic exploitation of all the survivors for a sadistic intergalactic game show. That’s what.</p>
<p>Join Coast Guard vet Carl and his ex-girlfriend’s cat, Princess Donut, as they try to survive the end of the world—or just get to the next level—in a video game–like, trap-filled fantasy dungeon. A dungeon that’s actually the set of a reality television show with countless viewers across the galaxy. Exploding goblins. Magical potions. Deadly, drug-dealing llamas. This ain’t your ordinary game show.</p>
<p>Welcome, Crawler. Welcome to the Dungeon. Survival is optional. Keeping the viewers entertained is not.</p><p><a class="button" target="_blank" href="https://www.goodreads.com/book/show/211721806-dungeon-crawler-carl">Learn more on Goodreads ➡</a></p></div>
<hr>
<p>Started reading this book after a couple of friends in work recommended it to me. Couldn't put it down and read it in a couple days. I've gone straight onto the next book in the series, and I'm really looking forward to seeing where it goes.</p>
<p>The book has <em>Hitchhiker's Guide To The Galaxy</em> vibes in that it doesn't take itself too seriously, and is a lot of fun to read. Highly recommended.</p> <div class="email-hidden">
<hr />
<p>Thanks for reading this post via RSS. RSS is ace, and so are you. ❤️</p>
<p>You can <a href="mailto:19gy@qrk.one?subject=Dungeon%20Crawler%20Carl">reply to this post by email</a>, or <a href="https://kevquirk.com/dungeon-crawler-carl#comments">leave a comment</a>.</p>
</div>Death to px, long live ch! - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=638472026-08-23T11:34:52.000Z<p>Pixels are a lie. Even if you think you're drawing something with "<a href="https://shkspr.mobi/blog/2018/11/the-myth-of-the-pixel-perfect-grid/">pixel perfect</a>" accuracy, your monitor is lying to you. There is no grid of platonically perfect squares.</p>
<p>In CSS, <a href="https://developer.mozilla.org/en-US/docs/Learn_web_development/Core/Styling_basics/Values_and_units#lengths">pixels are a double lie</a>:</p>
<blockquote><p>Note that <code>1px</code> doesn't necessarily equal one physical device pixel. On HD displays, it may span multiple physical pixels. Similarly, <code>1cm</code> in CSS often doesn't correspond to one hundredth of SI meter. On a large TV screen, it typically is longer than that. The lengths are perceptual: <code>16px</code> looks roughly the same on a phone, laptop, or TV screen at typical viewing distance.</p></blockquote>
<p>This blog is primarily text based. I want the <a href="https://journals.uc.edu/index.php/vl/article/view/5765/4629">width of the text to be readable</a> for the average human. So, rather than setting the main width to be a percentage of the screen, I set it based on character width using the <code>ch</code> unit - which <a href="https://meyerweb.com/eric/thoughts/2018/06/28/what-is-the-css-ch-unit/">isn't exactly a character</a> but good enough for my purposes:</p>
<pre><code class="language-css">--width-content: min(75ch, 100%);
main {
max-width: var(--width-content);
}
</code></pre>
<p>When it comes to padding and margins, the same is true. If I want a gap around an element, I want that gap to be in proportion to the text inside it.</p>
<p>For widths, it makes sense to re-use the <code>ch</code> unit. I want the gap to be in proportion to the text.</p>
<p>But for <em>height</em>, perhaps it doesn't make sense to express vertical distance on character width? In which case <a href="https://www.w3.org/Style/Examples/007/units.en.html">the <code>ex</code> unit can be used</a>. It is the size of a typical lower-case letter.</p>
<p>Just like my idea to <a href="https://shkspr.mobi/blog/2025/09/class-warfare-can-i-eliminate-css-classes-from-my-html/">eliminate CSS classes from my HTML</a>, it's possible to go too far with this. I haven't changed <em>every</em> reference from em to ch, I'm just experimenting to see if it works.</p>
<p>There's nothing wrong, immoral, or evil about using px - or any other measure unit. Using ch and ex fit with my particular proclivities.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=63847&HTTP_REFERER=Atom" alt width="1" height="1" loading="eager">Automated organisation is here - Johnny.Decimalhttps://johnnydecimal.com/blog/0242-automated-organisation-is-here/2026-08-23T04:12:30.000Z<blockquote>
<p>Originally sent to the <a href="https://johnnydecimal.com/support/contact-community/mailing-list-rss-social">mailing list</a>.</p>
</blockquote>
<p>The last of the week's big updates is that you can now connect your AI to Johnny.Decimal. Now Claude or ChatGPT or whatever else you use has access to:</p>
<ul>
<li>The site documentation, blog posts, and 5+ years of my forum posts.
<ul>
<li>So it can give you advice on the system and how it should be used.</li>
</ul>
</li>
<li>The Life Admin and Small Business Systems – all 50,000+ words of explanatory text, exceptions, examples.
<ul>
<li>So it can tell you where to file stuff.</li>
</ul>
</li>
<li>The Workbook process
<ul>
<li>So you can build your own system.</li>
</ul>
</li>
<li>Transcripts of all of our videos.
<ul>
<li>So it can point you to a specific video that answers your question.</li>
</ul>
</li>
</ul>
<p>Your existing Pro account just got an upgrade: all of this just works for you, today. To read the SBS, you need a Business account. Free and Personal accounts can read the documentation including the Workbook. (Get a free account on <a href="https://johnnydecimal.com/">the home page</a>. Upgrade your account at <a href="https://johnnydecimal.com/products">Products</a>.)</p>
<p>I can ask it a question about planning a new range of banana-coloured clothing and it can map it out in the Small Business System.</p>
<figure class="figure jdimage jdimage--auto-dark"> <picture> <img class="figure__inner" alt="Screenshot of Claude's response to my banana clothing question. It shows me which parts of the SBS I need to use, and recommends starting with a Work Package." height="447" loading="lazy" src="https://johnnydecimal.com/blog/0242A_Claude_response_to_banana-1334x894@2x.png" width="667"> </picture> </figure>
<p>Using your tool's 'cowork' feature you can connect it to your local filesystem and JDex. Now you can ask it questions about your own data. Here, it correctly notes that I've deviated from our published advice on filing receipts! I'll update that guidance in the Small Business System…</p>
<figure class="figure jdimage jdimage--auto-dark"> <picture> <img class="figure__inner" alt="Screenshot of Claude's response to my receipt question. It's read my local disk and tells me that I am up-to-date with my receipt filing." height="450" loading="lazy" src="https://johnnydecimal.com/blog/0242B_Claude_response_to_receipt_query-1316x900@2x.png" width="658"> </picture> </figure>
<h2 id="automated-organisation-is-here">Automated organisation is here</h2>
<p>This is the beginning of truly automated organisation. Point Claude at your downloads folder and it'll tell you what needs filing, and where it should go.</p>
<p>I find myself not doing that, if I'm honest. I like knowing where my stuff goes: and Johnny.Decimal makes it easy anyway. I'm still faster than Claude at filing my receipts.</p>
<p>I <em>have</em> found that working with Claude in a very structured environment is a revelation. The other day I had it write a script to monitor my Obsidian vault for conflicts. Now when me and Lucy edit a file at the same time it sends me a Telegram alert. Magic.</p>
<p>This is the future: we'll all write our own custom utilities to help us stay on top of stuff. But that script … where is it? <em>It still has to be somewhere</em>. Having Claude connected to my JDex means I can tell it to "document the script at <strong>23.12</strong>" (my ID for Obsidian, as a tool in my business) and it does that, wiki-linking to <strong>14.11+ Curium</strong> (the server the script runs on).</p>
<p>Having these short, consistent, unambiguous numbers that I can use to refer to anything in my life or business is proving to be a superpower. I can't imagine working without them.</p>
<h2 id="how-to-connect">How to connect</h2>
<p>This is documented at the <a href="https://johnnydecimal.com/jdhq/mcp-server">MCP server</a> page. Updates will be published there, and on the blog.</p>
<p><a href="https://johnnydecimal.com/video/1220522887">Here's a 10-minute video</a> showing you how to connect your agent to the server. This is still young technology, so it's a bit of a fussy setup. If you need a hand, use the <a href="https://forum.johnnydecimal.com/t/mcp-server-support-post/2955">MCP server support post on the forum</a> or in the <a href="https://discord.com/channels/822215537589354566/1490248270813986986">#AI channel on Discord</a>.</p>
<h2 id="also-see-the-skills-and-config">Also see the skills and config</h2>
<p>The server works great with my <a href="https://johnnydecimal.com/jdhq/agent-skills">agent skills</a>, and they in turn work well with the <a href="https://johnnydecimal.com/jdhq/configuration">new configuration file</a>.</p>
<h2 id="lots-more-coming">Lots more coming</h2>
<p>We think we're going to record a 'Learn with Lucy – AI' series. She has no idea how this works, and she'd like to. We'd like to show you how you can use these tools safely and effectively to manage your life and business. No hype, just useful advice. Let us know what you need.</p>
<p>This will all appear on your Pro account as it's released. <a href="https://johnnydecimal.com/products">Buy it once</a>, and we'll keep making it more valuable.</p>
<h2 id="privacy">Privacy</h2>
<p>I say it on that page, and in the video, and I want to reinforce it here. When you connect to an MCP server – any MCP server – <strong>your agent necessarily has to send that server some of your data</strong> so that the server knows what to send back. And of course the server knows who you are, because you're authenticated to it.</p>
<p><strong>I do not and will never log any of this data</strong>. It hits my server, a function responds, and nothing personal is ever saved, logged, or viewed by me. Not your user ID, name, email, IP address, or any of the text that your agent sent.</p>
<p>I log exactly two things: the name of the agent (e.g. <em>claude-code/2.1.240</em>) and the name of my tool that was called (e.g. <em>list_documentation</em>). This helps me troubleshoot connectivity issues.</p>
<p>When you connect to an MCP server the dialog says "ensure that you trust the owner of this server". That is absolutely the case: you need to trust me. If you don't, don't use the server.</p>
<h2 id="">🇯🇵🚅🐄</h2>
<p>Big week! We're going on a trip to Hokkaido, Japan tomorrow. We get to go on the Hayabusa Shinkansen, then I plan on eating my own weight in dairy products. :-)</p>
<p>j.</p>Organising physical artefacts - James' Coffee Bloghttps://jamesg.blog/2026/08/23/organising-physical-artefacts2026-08-23T00:00:00.000Z
<p>I love admiring spaces and thinking about how they work but, when it comes to the physical spaces I use most or every day – my bedroom, my desk, my bookshelves – I haven’t spent as much time thinking about decoration. When an environment functions, I don’t often think about how I can make it beautiful. Indeed, I have never been particularly adept at decorating. </p><p>This evening I had a discussion about organising mementos from trips: museum maps and guidebooks, and all the other little things I have picked up that I don’t already keep in my scrapbook. I have a paper bag from the British Museum in which I keep my museum maps and other paraphernalia, but it isn’t particularly organised; indeed, despite being red, I seldom look through the bag.</p><p>This has me thinking about how I can keep some of my physical collectibles – zines, museum maps, clippings, and everything in between – more organised. I made a few immediate choices: to get a letter rack for my zines, to get a new scrapbook because my current one is full. But I would like to do more.</p><p>As I said to my friends, somewhat inelegantly but spoken from the heart: “I don’t want to keep all these memories in a bag.” One suggestion was to get a pinboard, which I love. I may also look through my museum maps and order them, so that at least I can remember what I have so I can decide what to do next. I would love for the maps not to be sitting in a paper bag, but to be part of something else. Maybe I could have a space on my bookshelf dedicated to museum maps? (I really need another bookshelf too!)</p><p>One thing I love about bookshelves is that all the titles are visible. I can look to my bookshelf and be proud that I have read Moby Dick even though it took a long time, and look at my anime and think about for how many hours and days a particular series has kept me entertained, or to look at my art books and know I can pick one up at any time and look at pictures that will undoubtably make me think. I can recall the memories associated with each book or series. I would like this for physical paraphernalia too. Having shelf space might be just what I need, and a corkboard too.</p><p>I love that I can curate bookshelves: by subject, by theme, by space. The more I write the more I realise this is what I want to do with physical paraphernalia too. I also want to move the zines I have made from where they are stored, on a shelf I don’t often look at, onto my main bookshelf, to elevate them in my space because I am proud of making them.</p><p>How do you organise physical artefacts you have collected? I would love inspiration! If you have any ideas, please feel free to <a href="https://jamesg.blog/email">email me</a>.</p><script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a2fd23346d09321a',t:'MTc4NzUxOTc3Nw=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
<a class="tag" href="https://jamesg.blog/email">email me</a>
Finished reading The Last Devil to Die - Molly White's activity feed6a8b2d9491f30f1ebee9c3ea2026-08-22T04:29:11.000Z<article class="entry h-entry hentry"><header><div class="description">Finished reading: </div></header><div class="content e-content"><div class="book h-entry hentry"><a class="book-cover-link" href="https://www.mollywhite.net/reading/books?search=The%20Last%20Devil%20to%20Die"><img class="u-photo book-cover" src="https://m.media-amazon.com/images/S/compressed.photo.goodreads.com/books/1680740298i/62226126.jpg" alt="Cover image of The Last Devil to Die" style="max-width: 300px;"/></a><div class="book-details"><div class="top"><div class="series-info"><i>Thursday Murder Club</i> series, book <span class="series-number">4</span>. </div><div class="title-and-byline"><div class="title"><i class="p-name">The Last Devil to Die</i> </div><div class="byline">by <span class="p-author h-card">Richard Osman</span>. </div></div><div class="book-info">Published <time class="dt-published published" datetime="2023">2023</time>. 421 pages. </div></div><div class="bottom"><div class="reading-info"><div class="reading-dates"> Started <time class="dt-accessed accessed" datetime="2026-08-19">August 19, 2026</time>; completed August 21, 2026. </div></div></div></div></div><img src="https://www.mollywhite.net/assets/images/placeholder_social.png" alt="Illustration of Molly White sitting and typing on a laptop, on a purple background with 'Molly White' in white serif." style="display: none;"/></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp">Posted: <time class="dt-published" datetime="2026-08-22T04:29:11+00:00" title="August 22, 2026 at 4:29 AM UTC">August 22, 2026 at 4:29 AM UTC</time>. </div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=crime" title="See all books tagged "crime"" rel="category tag">crime</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=humor" title="See all books tagged "humor"" rel="category tag">humor</a>, <a class="tag p-category" href="https://www.mollywhite.net/reading/books?tags=mystery" title="See all books tagged "mystery"" rel="category tag">mystery</a>. </div></div></footer></article>Saturday morning - James' Coffee Bloghttps://jamesg.blog/2026/08/22/saturday-morning2026-08-22T00:00:00.000Z
<p><em>Before I leave this morning, I have to pack some things to read.</em> I picked up a zine and a book on colour and set out to a coffee shop to ease my way into the weekend. I purchased the zine and the book following my reflection on <a href="https://jamesg.blog/2026/08/17/miniatures-reference-works-and-writing">reference works</a> earlier this week, which had me thinking that I wanted to vary the kinds of books on my shelf.</p><p>This year I haven’t read many fiction books. Most of my reading has been devoted to textbooks and what I read online: blogs and the news and articles and everything in between. I would love to read more fiction, but I often find it hard to stay focused on longer works, especially when my mind is busy. I used to read often on Saturday mornings, finding comfort in the tradition of some quiet reading times while the world was waking up, but I haven’t followed that tradition in a while. That is, until this morning, where I found myself sitting in a coffee shop, reading my zine and studying my book on colour.</p><p>The zine I was reading was called “<a href="https://shop.serraglia.com/product/books-as-art-practice" rel="noreferrer">Books as Art Practice</a>”, a reflection on what it means to create printed works. This zine comes at an apt time for me as I reflect more on what we gain and lose from different mediums and, in turn, come to appreciate each medium in more depth. I love the focus that I feel when I am with a book, but I also love the abundance of snippets from the world that I find on the web. When I think of mediums, I think less about their merits and drawbacks so much as their affordances – what does the web allow that other mediums don’t? What does the web make more difficult that are inherent in other mediums?</p><p>When it comes to the web, I have been thinking about time, especially in the context of blogs. Blog posts have published dates. But what if those dates were hidden? Available, but hidden. My thought was that words are already steeped in time, being written in and of a moment. I experimented with a “timeless” mode on my website that hides all the publication dates of works, and I admit I am intrigued. Scrolling through my archives without seeing publication dates, my <a href="https://jamesg.blog/2026/07/11/websites-as-anthologies-of-self" rel="noreferrer">anthology of self</a> speaks not in years but in moments, in seasons. Presented in this way, my writing is still a blog in that entries are printed in reverse chronological order, but each entry is without a specific date.</p><figure><picture><img alt='My archive page for the Nature category, listing blog posts without dates. The top five posts, in reverse chronological order, without dates, are "Change; anchors", "Autumn", "Afterflow", "Sunset", and "Eclipse".' loading="lazy" src="https://editor.jamesg.blog/content/images/2026/08/archive.png" style=" max-width: 130%;"/></picture><div class="alt"><label><input aria-label="Toggle image alt text on screen" type="checkbox"/>ALT</label><div class="content">My archive page for the Nature category, listing blog posts without dates. The top five posts, in reverse chronological order, without dates, are "Change; anchors", "Autumn", "Afterflow", "Sunset", and "Eclipse".</div></div></figure><p style="text-align: center;">⁂ ⁂ ⁂ </p><p>The book on colour that I was reading, published by the <a href="https://shop.nationalgallery.org.uk/colour-art-book-1057166.html" rel="noreferrer">National Gallery in London</a>, featured works of art through the centuries grouped by colour. This book was different from most I have read: it was predominantly visual. While engaged with the book, I was moving between reading and visually analysing, between understanding concepts through words and appreciating details communicated through colour and depth and shadow and tint.</p><p>I started at the end of the book, on the chapter on monochrome. Works with few colours appeal to me. I love seeing how much detail you can add to a work with few colours. One of my favourite works is mostly monochrome, except for a blue flower in the centre of the painting. And yet despite my love of monochrome works, I also love the Impressionists, among whose defining characteristics is their use of colour.</p><p>While I was aware I couldn’t see as many details as I might be able to see if I were studying a painting in a museum, I did enjoy how much I could study each work from its printed version. I appreciated that the book magnified particular aspects of images so I could study features in more depth, like the boats in Peter Balke’s <em>The Tempest</em> that I didn’t discern until seeing them up close.</p><p>Closing the book after being immersed in art for some time, I started to think about technology; this is a relationship that pops up every so often in my mind, even when I am not necessarily studying the intersection of the two.</p><p>We live in time with a rich visual culture, enabled in large part by technology. The book I was reading was enabled by technology: high-resolution photography, the ability to print with such detail. Indeed, art and technology are not separate; today, many aspects of our visual culture are intertwined with the technologies we have.</p><p style="text-align: center;">⁂ ⁂ ⁂ </p><p>After my reading, I ran a few errands and went for a long walk, listening to a podcast about reading and enjoying looking at the leaves and the trees and the fields and the distance. Then, I did as I do: sat down, with a beverage – in this case, a glass of water, having been sufficiently fuelled from the cup of coffee I had consumed earlier – and looked through my notes of the day, with wonder and curiosity and reflection, ready to start writing.</p><script>(function(){function c(){var b=a.contentDocument||(a.contentWindow&&a.contentWindow.document);if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'a2f1383739c56c55',t:'MTc4NzM5NDgwOQ=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script>
<a class="tag" href="https://jamesg.blog/2026/07/11/websites-as-anthologies-of-self">anthology of self</a>
<a class="tag" href="https://jamesg.blog/2026/08/17/miniatures-reference-works-and-writing">reference works</a>
<a class="tag" href="https://shop.nationalgallery.org.uk/colour-art-book-1057166.html">National Gallery in London</a>
<a class="tag" href="https://shop.serraglia.com/product/books-as-art-practice">Books as Art Practice</a>
Streak of procrastination - Joel's Log Fileshttps://joelchrono.xyz/blog/streak-of-procrastination2026-08-21T20:50:00.000Z<p>Sometimes you have such a great idea, a post that you need to write and share with everybody and you just keep meaning to get to it.</p>
<p>Then reality hits and it doesn’t quite let you make that post in a way that feels right for the subject.</p>
<p>In the end, you end up writing nothing at all, or with a draft that is quite big and extensive but still not completed.</p>
<p>And welp, you have many smaller ideas for posts you could do in the meantime, but you don’t want to because you gotta dedicate all of that time to that great post idea.</p>
<p>Except you don’t, work shows up, distraction shows up, life shows up, and you end up procrastinating both the main post and doing anything else.</p>
<p>At this point, I would rather have something out, something complete and ready to be posted on this evil blogpost of mine.</p>
<p>Worst of all is that this is also in the middle of Blaugust (pretty much ending in just ten days now) and now I’ll have to play catch up! If this wasn’t the case I could simply let it happen, I literally post at least twice per week anyway, not that that means something.</p>
<p>The only good thing is that there’s a couple drafts that should be done very soon. I rarely publish thouse but the desperation on my side is on that level already.</p>
<p>In any case, I just want to get some post out there to break the procrastination streak and call it day.</p>
<p>That’s a good title, I’ll use it, hope you enjoy it. The original title was actually <em>“When a blogpost stun-locks you”</em>, but perhaps that is too much of a gaming reference for some.</p>
<p>I really want to write a little less about games too, but also not, because I love to talk about games, confusing stuff!</p>
<p>Perhaps I am just playing way too much <em>Outer Wilds</em> this week and my brain can’t process everything properly right now. Too many mind-bending moments.</p>
<p>The blogpost in question is my retelling of my session of <em>Land of Eem</em> with friends by the way. Though my review of <em>Gris</em> is also pending…</p>
<p>This is day 21 of <a href="https://100DaysToOffload.com">#100DaysToOffload</a> and day 16 of <a href="https://nerdgirlthoughts.game.blog/2026/07/15/blaugust-2026-is-coming">#Blaugust2026</a></p>
<p>
<a href="mailto:me@joelchrono.xyz?subject=Streak of procrastination">Reply to this post via email</a> |
<a href="https://fosstodon.org/@joel/idcomments">Reply on Fediverse</a>
</p>Book Review: An Immense World - How Animal Senses Reveal the Hidden Realms Around Us by Ed Yong ★★★☆☆ - Terence Eden’s Bloghttps://shkspr.mobi/blog/?p=729032026-08-21T11:34:36.000Z<img src="https://shkspr.mobi/blog/wp-content/uploads/2026/07/9781473572737-jacket-large.webp" alt="Book cover featuring various animals." width="200" class="alignleft size-full wp-image-72904">
<p>This is a detailed examination of the various senses possessed by animals. Some will be intimately familiar to you - like sight and sound - whereas some will seem strange and uncanny - like magnetic detection and electro-sensing. Some straddle an almost understandable space like echolocation or tetra-chromatic vision.</p>
<p>This isn't a game of Top Trumps where all the animals are ranked by power. Instead there's a gentle and passionate exploration of what these senses <em>might</em> mean to their owners. It is refreshingly candid about what we don't know, while always trying to convey a sense of wonder about the inherent <a href="https://en.wikipedia.org/wiki/Umwelt"><i lang="de">Umwelt</i></a> experienced by the animal.</p>
<p>But goodness me is it long. It seems that every time the editor told the author to cut out a paragraph, he stuck it in a footnote instead. The text is well referenced, but so are the footnotes, which means occasionally encountering sentences formatted like this:</p>
<blockquote><p>Despite several frustrating false leads, nobody’s ever found them.<sup>fn11,36,37,38,39</sup></p></blockquote>
<p>Speaking of which, the general formatting of the eBook is poor. The CSS contains all sorts of weird stuff which I needed to turn off, and is full of comments which probably should have been stripped before the book was distributed.</p>
<p>Science publishers still haven't grasped that eBooks don't need to relegate glossy images to the back of the book - they can go inline with the text!</p>
<p>This is a funny, heartfelt, and (perhaps overly) thorough book. It will gleefully send you down rabbit holes - even if you're ill-equipped to see in the dark and sense the bugs around you.</p>
<img src="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/info/okgo.php?ID=72903&HTTP_REFERER=Atom" alt width="1" height="1" loading="eager">'Project' section of 'Task & Project Management' course re-recorded - Johnny.Decimalhttps://johnnydecimal.com/blog/0241-taskpm-update/2026-08-21T06:35:47.000Z<p>Our <a href="https://johnnydecimal.com/jdu/taskpm">Task & Project Management course</a> is, perhaps unsurprisingly, split into two sections: tasks, and project management. (Perhaps to our marketing detriment, I have a tendency to name things literally.)</p>
<p>We just re-recorded the entire project management section. If you watched the previous version, you should watch these new videos. Start from <a href="https://johnnydecimal.com/jdu/taskpm/350-feedback-from-the-future">feedback from the future</a>.</p>
<h2 id="updated-based-on-real-world-use">Updated based on real-world use</h2>
<p>Everything we produce is a result of real-world experience. I can't teach you how do to a thing if it's not something I do myself.</p>
<p>The previous projects section was the best that I knew at the time. But since releasing it late last year, I continued to refine the method. The re-recorded episodes reflect 6 months of further work, and are exactly how we run our own business.</p>
<p>It's a great update. I'm really happy with it.</p>
<h2 id="also-see-work-packages">Also see: Work packages</h2>
<p>See the previous blog post, <a href="https://johnnydecimal.com/blog/0240">'50-59 Portfolio of creative outputs' becomes 'W0000-9999 Work packages'</a>.</p>'50-59 Portfolio of creative outputs' becomes 'W0000-9999 Work packages' - Johnny.Decimalhttps://johnnydecimal.com/blog/0240-50-59-becomes-work-packages/2026-08-21T06:35:43.000Z<p>With the release of the <a href="https://johnnydecimal.com/sbs">Small Business System</a> last year we introduced a new pattern. Area <code>50-59 Portfolio of creative outputs</code> was an <a href="https://johnnydecimal.com/documentation/expand-an-area-overview">expanded area</a> with numbers ranging from <code>50000</code> through <code>59999</code>.</p>
<p>The extended numbering is required because you're expected to have more than 100 'creative outputs', so the usual restrictions don't work. This numbering was always a bit weird, not least because <code>50-59</code> as a parent folder name didn't accurately describe its contents.</p>
<h2 id="expanding-the-concept">Expanding the concept</h2>
<p>This concept was originally for 'creative outputs', as its name says. For our type of business that's blog posts and video course lessons. For a restaurant it might be the photo shoot for their latest Instagram campaign.</p>
<p>But the more we used it, the more we realised that it was a useful pattern for <em>all work</em>. If you have a broad Johnny.Decimal ID like <code>21.34 Small Business System</code>, it gets crowded if you try to do work in there.</p>
<figure class="figure jdimage jdimage--auto-dark"> <picture> <img class="figure__inner" alt="A diagram showing ID 21.34 SBS with lots of 'work' floating around it. It's very busy." height="392" loading="lazy" src="https://johnnydecimal.com/blog/0240A-21.34_SBS_busy-862x784@2x.png" width="431"> </picture> </figure>
<p>One solution would be to promote that thing to its own category: <code>61 Small Business System</code>, say. You could do that, but now we've pulled this specific product out of the list of products into its own place. And we still have the limit of 100 things to consider.</p>
<figure class="figure jdimage jdimage--auto-dark"> <picture> <img class="figure__inner" alt="A diagram showing the SBS as a new category '61' containing a bunch of IDs." height="523" loading="lazy" src="https://johnnydecimal.com/blog/0240B-61_SBS_category-1336x1046@2x.png" width="668"> </picture> </figure>
<p>This 'place to do work' turned out to be a really nice alternative. With this pattern, you leave the core thing where it is: <code>21.34 Small Business System</code> never changes. Each piece of work you do gets a new number in this 'work world', and we link it back to <code>21.34</code>.</p>
<figure class="figure jdimage jdimage--auto-dark"> <picture> <img class="figure__inner" alt="The diagram now shows the SBS as 21.34 again, but _connected to it_ – not inside it, crowding it – are a bunch of work packages." height="518" loading="lazy" src="https://johnnydecimal.com/blog/0240C-21.34_SBS_with_WPs-1010x1036@2x.png" width="505"> </picture> </figure>
<h2 id="introducing-work-packages">Introducing 'work packages'</h2>
<p>At this point I realised I'd brought the established concept of <a href="https://en.wikipedia.org/wiki/Work_breakdown_structure#Work_package">work packages</a> into Johnny.Decimal. And that's a good sign: well-established patterns are probably correct. Let's not invent something new for the sake of it.</p>
<p>So that's what the 'creative pattern' has grown into: each of these jobs is now a work package, and they're no longer limited to creative-like things. They're useful for <em>any work</em>.</p>
<p>For example, you might need to conduct a large audit as part of a compliance exercise. That audit could be a work package, linked to the SBS ID <code>11.13 Compliance</code>.</p>
<h2 id="fixing-the-numbers">Fixing the numbers</h2>
<p>A design principle of Johnny.Decimal is that you must always be able to give a stranger – a new starter at your business, say – a number, and they must be able to find it easily. So the parent folder name needs to accurately explain what's in it.</p>
<p>The existing area pattern <code>A0-A9</code> doesn't work here. Work packages are so different, we've given them a completely new scheme. They start at <code>W0000</code> and continue to <code>W9999</code>.<sup><a href="#user-content-fn-w0011" id="user-content-fnref-w0011" data-footnote-ref="true" aria-describedby="footnote-label" class="footnote">1</a></sup> So we call the folder that contains them <code>W0000-9999 Work packages</code>. This sorts them below all of your regularly-numbered Johnny.Decimal areas.</p>
<h2 id="they-must-link-to-an-id">They must link to an ID</h2>
<p>Crucially, work packages may not exist in isolation. <strong>They must belong to an ID</strong>. We indicate this in the title like: <code>W0011~11.13 Compliance audit</code>. Here, we've linked <code>W0011</code> to ID <code>11.13</code>.</p>
<p><strong>This link-to-parent-ID-in-title is required</strong>. You can and should cross-reference these entries using links in your JDex, but trust me: you'll forget to do that. If you always link every work package to its parent using this simple notation, you can never lose anything.</p>
<p>This is how our Small Business example now looks.</p>
<figure class="figure jdimage jdimage--auto-dark"> <picture> <img class="figure__inner" alt="The work packages connected to the SBS are now numbered, e.g. W0011~21.34." height="492" loading="lazy" src="https://johnnydecimal.com/blog/0240D-21.34_SBS_with_numbered_WPs-1314x984@2x.png" width="657"> </picture> </figure>
<h2 id="how-do-i-migrate-from-50-59">How do I migrate from <code>50-59</code>?</h2>
<p>If you've been using area <code>50-59</code>, I recommend switching to this new scheme. Start the numbers where you left off: if your last creative job was <code>50106</code>, your first work package is <code>W0107</code>.</p>
<p>You could renumber your old entries. We didn't: the nature of these things is that, once done, they're rarely referenced again.</p>
<h3 id="weve-also-retitled-40-49">We've also retitled <code>40-49</code></h3>
<p>While we're at it, we've tweaked the title of the Small Business System's area <code>40-49</code>. What was your <strong>Library of creative inputs</strong>, previously mirrored by the now-defunct <strong>Portfolio of creative outputs</strong>, has been renamed to <code>40-49 Creative assets</code>. Same thing, simpler name.</p>
<h2 id="see-more-at-the-updated-task--project-management">See more at the updated Task & Project Management</h2>
<p>We just re-recorded the entire second half of the course. You'll find a full explanation of this concept starting at <a href="https://johnnydecimal.com/jdu/taskpm/490-work-packages-intro">this episode</a>. See <a href="https://johnnydecimal.com/blog/0241">the blog post that follows this one</a> for more information.</p>
<div data-footnotes="true" class="footnotes"><h2 class="sr-only" id="footnote-label">Footnotes</h2>
<ol>
<li id="user-content-fn-w0011">
<p>Just like every other part of the system, you should leave the first 10 for <a href="https://johnnydecimal.com/documentation/the-standard-zeros">standard zero-like</a> IDs. Start your own WPs at <code>W0011</code>. <a href="#user-content-fnref-w0011" data-footnote-backref="" aria-label="Back to reference 1" class="data-footnote-backref footnoteBackLink">↩</a></p>
</li>
</ol>
</div>Small Business System – '50-59 Portfolio of creative outputs' becomes 'W0000-9999 Work packages' - Johnny.Decimalhttps://johnnydecimal.com/support/updates/2026-08-21-50-59-to-wps/2026-08-21T06:23:04.000Z<p>This is the changelog entry for this update. See <a href="https://johnnydecimal.com/blog/0240">blog post 0240</a> for full details.</p>Note published on August 21, 2026 at 12:29 AM UTC - Molly White's activity feed6a879beb52b01ca28c3ff0c12026-08-21T00:29:31.000Z<article><div class="entry h-entry hentry"><header></header><div class="content e-content"><p>delighted to discover that a) Jimothy has a Wikipedia picture and b) it's this</p><div class="media-wrapper"><a href="https://storage.mollywhite.net/micro/6373206f0ebf8cc6fc84_Screenshot-2026-08-20-at-8.27.15---PM.png" data-fslightbox=0f9c8d4fddbddd019e23><img src="https://storage.mollywhite.net/micro/6373206f0ebf8cc6fc84_Screenshot-2026-08-20-at-8.27.15---PM.png" alt="A Wikipedia infobox for Jimothy, featuring an MS Paint-style illustration of Jimothy the raccoon walking through grass with flowers in front of buildings and a sunny sky. Cartoonish illustration of Jimothy made by the USGS Species Common raccoon Sex Unknown Born c. 2025 Known for Abnormal body shape, internet memes" /></a></div></div><footer class="footer"><div class="flex-row post-meta"><div class="timestamp-block"><div class="timestamp">Posted: <a class="u-url" href="https://www.mollywhite.net/micro/entry/202608202027"><time class="dt-published" datetime="2026-08-21T00:29:31+00:00" title="August 21, 2026 at 12:29 AM UTC">August 21, 2026 at 12:29 AM UTC</time>. </a></div></div><div class="social-links"> <span> Also posted to: </span><a class="social-link u-syndication mastodon" href="https://hachyderm.io/@molly0xfff/117130669740897586" title="Mastodon" rel="syndication">Mastodon, </a><a class="social-link u-syndication bluesky" href="https://bsky.app/profile/molly.wiki/post/3mtkixpzopo2h" title="Bluesky" rel="syndication">Bluesky</a></div></div><div class="bottomRow"><div class="tags">Tagged: <a class="tag p-category" href="https://www.mollywhite.net/micro/tag/wikipedia" title="See all micro posts tagged "Wikipedia"" rel="category tag">Wikipedia</a>. </div></div></footer></div></article>