<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Kynth Studios</title>
    <description>The latest articles on DEV Community by Kynth Studios (@kynthstudios).</description>
    <link>https://dev.to/kynthstudios</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4016803%2F6a94458f-c3f4-4d6e-b291-fb273087983b.png</url>
      <title>DEV Community: Kynth Studios</title>
      <link>https://dev.to/kynthstudios</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kynthstudios"/>
    <language>en</language>
    <item>
      <title>Nearly one in ten published Claude Code skills does not load</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Fri, 14 Aug 2026 15:36:24 +0000</pubDate>
      <link>https://dev.to/kynthstudios/nearly-one-in-ten-published-claude-code-skills-does-not-load-42m5</link>
      <guid>https://dev.to/kynthstudios/nearly-one-in-ten-published-claude-code-skills-does-not-load-42m5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Cross-posted from &lt;a href="https://toolproof.kynth.studio/census" rel="noopener noreferrer"&gt;The State of Agent Tooling&lt;/a&gt;. Dataset: &lt;a href="https://doi.org/10.5281/zenodo.21936490" rel="noopener noreferrer"&gt;DOI 10.5281/zenodo.21936490&lt;/a&gt;, CC BY 4.0.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;43,199 of 445,348 published Claude Code artefacts fail a structural check and will not load as published.&lt;/strong&gt; That is 9.70% of every skill, subagent, plugin and marketplace we could find on GitHub and skills.sh, read from source on 2026-08-14.&lt;/p&gt;

&lt;p&gt;Nobody has published this number before, so there is nothing to compare it against yet. That is the reason to publish it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What was measured
&lt;/h2&gt;

&lt;p&gt;Every artefact was fetched and checked for one thing: whether an agent runtime could register it. Not whether it is good, popular, or maintained.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kind&lt;/th&gt;
&lt;th&gt;Listings&lt;/th&gt;
&lt;th&gt;Fail&lt;/th&gt;
&lt;th&gt;Rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Skills&lt;/td&gt;
&lt;td&gt;347,382&lt;/td&gt;
&lt;td&gt;27,398&lt;/td&gt;
&lt;td&gt;7.89%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subagents&lt;/td&gt;
&lt;td&gt;71,430&lt;/td&gt;
&lt;td&gt;15,669&lt;/td&gt;
&lt;td&gt;21.9%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Plugins&lt;/td&gt;
&lt;td&gt;20,212&lt;/td&gt;
&lt;td&gt;33&lt;/td&gt;
&lt;td&gt;0.16%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marketplaces&lt;/td&gt;
&lt;td&gt;6,324&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;td&gt;1.57%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Subagents are the broken half
&lt;/h2&gt;

&lt;p&gt;The aggregate hides the finding. Subagents fail at &lt;strong&gt;2.8x the rate of skills&lt;/strong&gt;, and the reason is structural rather than cultural.&lt;/p&gt;

&lt;p&gt;A subagent's &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; are Required: Yes in Anthropic's frontmatter reference. A skill's are not: a skill falls back to its directory name, and to the first paragraph of its body. The same careless file is a working skill and a dead subagent.&lt;/p&gt;

&lt;p&gt;4,119 subagents have no name. 1,799 have no description.&lt;/p&gt;

&lt;h2&gt;
  
  
  Almost all of it is one defect
&lt;/h2&gt;

&lt;p&gt;38,183 of the 43,199 failures — 88.4% — are a YAML block at the top of a file that does not parse.&lt;/p&gt;

&lt;p&gt;This is the cheapest class of bug in software, and it is sitting in front of the most-copied artefacts in a fast-growing ecosystem, because nothing in the publishing path checks it. There is no registry gate, no CI convention, and no error surfaced to the author. The file is committed, the repository is starred, and the artefact silently never loads.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Listings&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontmatter does not parse&lt;/td&gt;
&lt;td&gt;38,183&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subagent has no name&lt;/td&gt;
&lt;td&gt;4,119&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Subagent has no description&lt;/td&gt;
&lt;td&gt;1,799&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manifest is not valid JSON&lt;/td&gt;
&lt;td&gt;128&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Marketplace lists no plugins&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Four things this number is not
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Not a count of distinct artefacts.&lt;/strong&gt; It counts listings. The 445,348 come from 14,233 distinct repositories, an average of 31.3 apiece, because this ecosystem is overwhelmingly forked and vendored and the same file is counted once per repository carrying it. The failure &lt;em&gt;rate&lt;/em&gt; is the citable figure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not an execution result.&lt;/strong&gt; Nothing was run. Every check is static. A listing that passes can still be wrong, useless or dangerous. Passing means the file parses into something a runtime could register: a floor, not a verdict.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not a quality judgement.&lt;/strong&gt; No model scored anything and no human curated the list. Every fatal cause above is a specific, checkable, arguable defect, and the row-level data is published so the argument can be had against the evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Not complete.&lt;/strong&gt; Discovery is bounded by GitHub's search API, which is rate-limited and does not return everything. What discovery truncated is logged rather than hidden.&lt;/p&gt;

&lt;h2&gt;
  
  
  A correction, published with the first edition
&lt;/h2&gt;

&lt;p&gt;Preparing this census turned up a defect in the index that produced it.&lt;/p&gt;

&lt;p&gt;The index carried a &lt;code&gt;missing-references&lt;/code&gt; flag — a skill naming a bundled file that is not in its repository — and it fired on 139,623 listings, 40.2% of every skill. It was wrong roughly seven times in eight, from three bugs in one regular expression:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The extension alternation put &lt;code&gt;js&lt;/code&gt; ahead of &lt;code&gt;json&lt;/code&gt;, and JavaScript alternation is first-match. So every &lt;code&gt;package.json&lt;/code&gt; was captured as a missing &lt;code&gt;package.js&lt;/code&gt;, and every &lt;code&gt;res.json(data)&lt;/code&gt; inside a fenced code block became a missing file called &lt;code&gt;res.js&lt;/code&gt;. 12,178 and 6,946 listings respectively.&lt;/li&gt;
&lt;li&gt;Nothing scoped the match to the skill's own bundle. The most-reported "missing files" in the entire index were the framework names &lt;code&gt;Next.js&lt;/code&gt; (21,014) and &lt;code&gt;Node.js&lt;/code&gt; (19,383), the skill's own &lt;code&gt;SKILL.md&lt;/code&gt; (27,002), and &lt;code&gt;CLAUDE.md&lt;/code&gt; (11,371) — a file that lives in the user's project and never in the bundle.&lt;/li&gt;
&lt;li&gt;A reference written &lt;code&gt;./run.sh&lt;/code&gt; could never resolve against the repository tree, so 1,498 listings were reported missing a file that was sitting right there.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Corrected, 18,657 skills (5.37%) name a bundled file that is genuinely absent.&lt;/p&gt;

&lt;p&gt;The flag is a score deduction and was never a load verdict, so &lt;strong&gt;the 9.70% headline is unaffected&lt;/strong&gt; — it comes from the fatal causes above and nothing else.&lt;/p&gt;

&lt;p&gt;This is in the report rather than in a changelog because an index that publishes other people's broken metadata has to publish its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  The data
&lt;/h2&gt;

&lt;p&gt;Published in full under CC BY 4.0, including every failing row, so the headline can be recomputed by anybody who wants to check it.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://toolproof.kynth.studio/census/census.json" rel="noopener noreferrer"&gt;&lt;code&gt;census.json&lt;/code&gt;&lt;/a&gt; — every aggregate, plus the exact rule that decides a failure&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://toolproof.kynth.studio/census/broken-listings.csv" rel="noopener noreferrer"&gt;&lt;code&gt;broken-listings.csv&lt;/code&gt;&lt;/a&gt; — 43,199 rows, one per failing listing, with its repository, path and cause&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://zenodo.org/record/21936490" rel="noopener noreferrer"&gt;&lt;code&gt;listings.csv.gz&lt;/code&gt;&lt;/a&gt; — the full population, 445,348 rows&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://toolproof.kynth.studio/methodology/vocabulary" rel="noopener noreferrer"&gt;The measurement vocabulary&lt;/a&gt; — load rate, drift, shipping status and skill decay, each defined as a formula over a named population&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://toolproof.kynth.studio/methodology" rel="noopener noreferrer"&gt;The method&lt;/a&gt;, written down before the numbers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cite as: Kynth Studios (2026). &lt;em&gt;The State of Agent Tooling 2026.1&lt;/em&gt;. Zenodo. &lt;a href="https://doi.org/10.5281/zenodo.21936490" rel="noopener noreferrer"&gt;https://doi.org/10.5281/zenodo.21936490&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>devtools</category>
      <category>data</category>
    </item>
    <item>
      <title>A 301 on a URL you already corrected means the transfer reversed — delete the correction, don't add a hop</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Thu, 13 Aug 2026 18:33:17 +0000</pubDate>
      <link>https://dev.to/kynthstudios/a-301-on-a-url-you-already-corrected-means-the-transfer-reversed-delete-the-correction-dont-add-4ch6</link>
      <guid>https://dev.to/kynthstudios/a-301-on-a-url-you-already-corrected-means-the-transfer-reversed-delete-the-correction-dont-add-4ch6</guid>
      <description>&lt;p&gt;I run a curated index of agentic dev tooling — 71 entries right now, each one a GitHub repository with an owner, a byline, an outbound link and a chunk of JSON-LD naming the author. Repositories move. GitHub doesn't 404 when they do; it 301s. So every link in the index keeps "working" while the page publishes a name the project stopped using.&lt;/p&gt;

&lt;p&gt;The link checker that catches this is 135 lines and treats &lt;strong&gt;a redirect as a finding, not a pass&lt;/strong&gt;. Alive means HTTP 200 &lt;em&gt;and&lt;/em&gt; no &lt;code&gt;Location&lt;/code&gt; header. That part was easy. The part that bit me was four days long and had nothing to do with redirects being hard to detect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Corrections are applied on read, at one choke point
&lt;/h2&gt;

&lt;p&gt;The manifest the site renders from is generated — it gets rebuilt from source on every sync, so hand-editing a row survives until the next regeneration and then silently reverts. And in production the rows come from Postgres, which the manifest doesn't govern at all. Two sources, neither of them a place a correction can live.&lt;/p&gt;

&lt;p&gt;So corrections live in their own file and are applied in the read model, after both sources, by name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;CORRECTIONS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
           &lt;span class="na"&gt;note&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fields are copied by name so a stray key in the JSON can't overwrite something that was never meant to be correctable. The slug is deliberately not in that list — it's the entry's public address and it's in the sitemap. Changing a slug to fix a link that merely redirects trades a redirect for a 404, which is worse.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faka8o34kanb71uq81ckn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Faka8o34kanb71uq81ckn.png" alt="AgentWire dashboard displaying curated project cards with dates and status labels — The platform surfaces and categorizes open-source AI projects with collection metadata." width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The checker has to read through the same choke point
&lt;/h2&gt;

&lt;p&gt;Here's the line that mattered, from the checker:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ROOT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/data/posts.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;corrections&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;ROOT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/data/corrections.json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;corrections&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;repo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="nx"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The obvious reason to do this: the raw manifest still carries the pre-transfer path for anything already fixed, so checking it would re-report every correction as a fresh finding forever.&lt;/p&gt;

&lt;p&gt;The non-obvious consequence: the checker now probes URLs that only exist because &lt;em&gt;I&lt;/em&gt; wrote them down. And those can go stale in a direction I hadn't planned for.&lt;/p&gt;

&lt;h2&gt;
  
  
  What actually happened
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ahujasid/blender-mcp&lt;/code&gt; transferred to &lt;code&gt;MCPBlender/blender-mcp&lt;/code&gt;. Correction written, note dated, checked 2026-08-08. Four days later the checker reported a 301 — on &lt;code&gt;MCPBlender/blender-mcp&lt;/code&gt;, redirecting back to &lt;code&gt;ahujasid/blender-mcp&lt;/code&gt;. The transfer had reversed. I re-probed both while writing this: &lt;code&gt;ahujasid&lt;/code&gt; returns 200 with no redirect, &lt;code&gt;MCPBlender&lt;/code&gt; returns 301 to it, and the REST record's &lt;code&gt;full_name&lt;/code&gt; reads &lt;code&gt;ahujasid/blender-mcp&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The instinct is to chase it: point the correction at the new target. That's wrong. The manifest's &lt;em&gt;original&lt;/em&gt; value is correct again, so the honest fix is to delete the correction entirely and let the underlying value show through — which also takes the reader-facing note off the page, where it had been telling people the owner had been verified.&lt;/p&gt;

&lt;p&gt;For four days the item page's &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt;, meta description, byline, outbound link and JSON-LD &lt;code&gt;author&lt;/code&gt; all named an owner the project no longer had, under a note saying it had been checked. &lt;strong&gt;A wrong fact wearing a verification date is worse than an uncorrected page&lt;/strong&gt;, because it launders the error as diligence — and a 301 errors nowhere else in the stack, so nothing else was ever going to catch it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The decision table the checker encodes
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Probe result&lt;/th&gt;
&lt;th&gt;What it actually means&lt;/th&gt;
&lt;th&gt;What happens to the entry&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;200, no &lt;code&gt;Location&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Alive at the address published&lt;/td&gt;
&lt;td&gt;Nothing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;301 on a manifest URL&lt;/td&gt;
&lt;td&gt;Repo renamed or transferred&lt;/td&gt;
&lt;td&gt;Add a correction with a dated note&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;301 on a URL that is &lt;em&gt;already&lt;/em&gt; a correction&lt;/td&gt;
&lt;td&gt;The first transfer reversed&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Delete&lt;/strong&gt; the correction; never add a second hop&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;404 or 451&lt;/td&gt;
&lt;td&gt;Gone or blocked&lt;/td&gt;
&lt;td&gt;The entry comes out&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;429&lt;/td&gt;
&lt;td&gt;Nothing was learned&lt;/td&gt;
&lt;td&gt;Reported separately as unchecked — not a finding, not a pass&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last row is its own small lesson: HN rate-limits unauthenticated bursts hard, and reporting a 429 as a dead link trains whoever reads the output to ignore it — the one failure mode a checker cannot survive. "Inconclusive" is a different statement from "fine," and the script prints it as one.&lt;/p&gt;

&lt;p&gt;The rule now lives in the corrections file's own &lt;code&gt;_readme&lt;/code&gt;, next to the data it governs: re-run the checker every pass, and treat a finding on a corrected URL as a correction to remove.&lt;/p&gt;

&lt;p&gt;This is how we built Agentwire, an index of agentic developer tooling: &lt;a href="https://agentwire.kynth.studio/?utm_source=kynth-devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=kynth" rel="noopener noreferrer"&gt;https://agentwire.kynth.studio/?utm_source=kynth-devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=kynth&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>architecture</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Make a stale number fail `next build`: a claim register whose quoted clauses verify themselves</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Wed, 12 Aug 2026 22:18:00 +0000</pubDate>
      <link>https://dev.to/kynthstudios/make-a-stale-number-fail-next-build-a-claim-register-whose-quoted-clauses-verify-themselves-5gjb</link>
      <guid>https://dev.to/kynthstudios/make-a-stale-number-fail-next-build-a-claim-register-whose-quoted-clauses-verify-themselves-5gjb</guid>
      <description>&lt;p&gt;For about a week our landing said civil penalties under the TAKE IT DOWN Act "currently approach $53,000." The FTC's own business guidance says &lt;strong&gt;$53,088 per violation&lt;/strong&gt;. That is not a rounding error in the harmless direction — $53,088 is over $53,000, not approaching it. The commit that fixed it counts 44 instances across 8 files.&lt;/p&gt;

&lt;p&gt;The reason it survived is the interesting part. We already had &lt;code&gt;FACTS.json&lt;/code&gt; — a register of every claim the site makes that can decay, each with the primary source, the date it was last re-fetched, a verbatim &lt;code&gt;quote&lt;/code&gt; from that source, and an &lt;code&gt;appearsOn&lt;/code&gt; list of the files that state it. The penalty claim's &lt;code&gt;appearsOn&lt;/code&gt; listed two guides. The landing was not in it. So the re-verification pass checked the two files it was told about, found them correct, and moved on.&lt;/p&gt;

&lt;p&gt;A register that records where a fact appears is a list somebody has to keep right. The fix was to make pages &lt;em&gt;read&lt;/em&gt; the register instead.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;claim()&lt;/code&gt; is the cheap half
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;Claim&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;CLAIMS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`FACTS.json has no claim with id "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;verified&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`FACTS.json claim "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" is "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;", not verified — it cannot be published`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;found&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A typo fails the build rather than rendering an empty cell, and an entry parked mid-rotation — ours currently has one, a law-firm article behind a Cloudflare challenge that 403s both &lt;code&gt;curl&lt;/code&gt; and a fetch, carried as &lt;code&gt;unverifiable&lt;/code&gt; — can never reach a buyer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmvmtb6gmcnaiu0klnsup.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fmvmtb6gmcnaiu0klnsup.png" alt="TrustDesk policy generator interface with sample policy content and workspace photography — Tool produces formatted policy text instantly with clean, modern professional interface." width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;quote()&lt;/code&gt; is the half that actually bites
&lt;/h2&gt;

&lt;p&gt;The problem &lt;code&gt;value(id)&lt;/code&gt; doesn't solve: a comparison table often wants &lt;em&gt;half&lt;/em&gt; of a registered claim. One of ours reads:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Receipt of a VALID removal request — and the duty is "as soon as possible", with 48 hours as the outer limit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The table's "what it means" cell wants the clause after the dash; the "on what clock" cell comes from a different claim. Retyping that clause into JSX puts a second, unlinked copy of the fact on the page, which is the exact failure the register exists to prevent.&lt;/p&gt;

&lt;p&gt;So the clause is passed together with the claim it came out of, and containment is proved at build time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;norm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;''ʼ&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;""&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\s&lt;/span&gt;&lt;span class="sr"&gt;+/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;registered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;claim&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;registered&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;norm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="s2"&gt;`FACTS.json claim "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" no longer contains the quoted clause.\n  quoted:     &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;\n  registered: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;registered&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;clause&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The normalisation is not cosmetic. The register and the JSX disagree about apostrophes and nothing else, so a curly-quote mismatch would fail the build for a reason that has nothing to do with the fact.&lt;/p&gt;

&lt;p&gt;I tested the gate rather than assuming it: I edited the registered value from &lt;code&gt;48 hours as the outer limit&lt;/code&gt; to &lt;code&gt;72 hours&lt;/code&gt;, left the table cell alone, and ran &lt;code&gt;pnpm build&lt;/code&gt;. It compiled fine, then died in &lt;strong&gt;Collecting page data&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Error: FACTS.json claim "tida-clock-starts-on-valid-request" no longer contains the quoted clause. quoted: the duty is "as soon as possible", with 48 hours as the outer limit / registered: … with 72 hours as the outer limit&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;code&gt;Failed to collect page data for /&lt;/code&gt;, exit code 1. Not a warning, not a runtime 500 on one route — no deployable output at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What each tier of coverage actually protects
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;How a figure reaches the page&lt;/th&gt;
&lt;th&gt;Where the link between page and source lives&lt;/th&gt;
&lt;th&gt;What happens when the register changes&lt;/th&gt;
&lt;th&gt;State in this repo today&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Read through &lt;code&gt;value()&lt;/code&gt; / &lt;code&gt;quote()&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;The import — the page cannot hold a second copy&lt;/td&gt;
&lt;td&gt;Build fails, or the cell updates itself&lt;/td&gt;
&lt;td&gt;One component, 15 of the register's 35 claims&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hand-typed, listed in &lt;code&gt;appearsOn&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;A path string in JSON, maintained by hand&lt;/td&gt;
&lt;td&gt;Nothing fails; the next pass has to grep the listed files&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;$53,088&lt;/code&gt; appears 25 times across 15 files; its claim lists 14&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hand-typed, not in &lt;code&gt;appearsOn&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Nowhere&lt;/td&gt;
&lt;td&gt;Nothing at all&lt;/td&gt;
&lt;td&gt;How "approach $53,000" survived&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The source line under the table is generated too — &lt;code&gt;asOf(...ids)&lt;/code&gt; returns the newest verification date across every claim the table used, so the page dates itself instead of carrying a date somebody typed beside it.&lt;/p&gt;

&lt;p&gt;Row three is now empty by construction for anything the table renders. Rows one and two are not: 25 hand-typed occurrences of &lt;code&gt;$53,088&lt;/code&gt; remain in prose across 15 files, still guarded only by that &lt;code&gt;appearsOn&lt;/code&gt; list.&lt;/p&gt;

&lt;p&gt;This is how we built TrustDesk, a hosted NCII takedown desk for covered platforms: &lt;a href="https://trustdesk.kynth.studio" rel="noopener noreferrer"&gt;https://trustdesk.kynth.studio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>nextjs</category>
      <category>webdev</category>
      <category>showdev</category>
    </item>
    <item>
      <title>`status === 200` let 7,382 non-pages into our iframes — the four checks that replaced it</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Tue, 11 Aug 2026 10:19:09 +0000</pubDate>
      <link>https://dev.to/kynthstudios/status-200-let-7382-non-pages-into-our-iframes-the-four-checks-that-replaced-it-22af</link>
      <guid>https://dev.to/kynthstudios/status-200-let-7382-non-pages-into-our-iframes-the-four-checks-that-replaced-it-22af</guid>
      <description>&lt;p&gt;BlockDex indexes shadcn-style component registries, and each item page mounts an iframe of the registry's own demo page with a caption underneath: &lt;em&gt;"this is the component running, not a screenshot of it."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;On 2026-08-06 I fetched all 22,313 preview URLs the index had stored. 7,382 of them were not component pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two mistakes stacked
&lt;/h2&gt;

&lt;p&gt;The crawler learned a &lt;strong&gt;URL shape&lt;/strong&gt; per registry — try &lt;code&gt;{base}/docs/{name}&lt;/code&gt;, &lt;code&gt;{origin}/components/{name}&lt;/code&gt;, and last on the list &lt;code&gt;{origin}/r/{name}&lt;/code&gt; — against one sample item name. Whichever shape answered got filled in for every item in that registry and written to &lt;code&gt;preview_url&lt;/code&gt; unchecked.&lt;/p&gt;

&lt;p&gt;The acceptance test was one line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html,*/*&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* learned */&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;{origin}/r/{name}&lt;/code&gt; is, on a large class of registries, the &lt;strong&gt;item JSON route&lt;/strong&gt; — the same URL the install command reads. A 4KB JSON body clears &lt;code&gt;length &amp;gt; 500&lt;/code&gt; comfortably. The &lt;code&gt;*/*&lt;/code&gt; in the accept header forces nothing. And then the second mistake compounded it: an API route sends no &lt;code&gt;X-Frame-Options&lt;/code&gt; and no CSP, so our &lt;code&gt;framable()&lt;/code&gt; helper —&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;deny&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;xfo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sameorigin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;m&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;csp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/frame-ancestors&lt;/span&gt;&lt;span class="se"&gt;([^&lt;/span&gt;&lt;span class="sr"&gt;;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;m&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;— returned &lt;code&gt;true&lt;/code&gt;. The JSON endpoint was marked the &lt;em&gt;most&lt;/em&gt; embeddable kind of URL there is. Chrome duly framed it and rendered its own JSON viewer inside the panel, under a caption asserting the component was running.&lt;/p&gt;

&lt;p&gt;None of this is detectable at render time. The client watches the iframe's &lt;code&gt;onLoad&lt;/code&gt;, and a 404 page, a 500 page and a JSON document all fire &lt;code&gt;onLoad&lt;/code&gt; perfectly normally. The only failure a browser surfaces is a frame that never loads at all — which is the one that doesn't happen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyuwsouycbvpxc91mgxx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhyuwsouycbvpxc91mgxx.png" alt="Blockdex search interface returning 57,672 matching component and block results in a table — Search displays components indexed by registry and library with quick-copy command buttons for reuse." width="800" height="508"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What the sweep actually found
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Failure class&lt;/th&gt;
&lt;th&gt;Count of 22,313&lt;/th&gt;
&lt;th&gt;Why the old test missed it&lt;/th&gt;
&lt;th&gt;What rejects it now&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hard 404&lt;/td&gt;
&lt;td&gt;4,704&lt;/td&gt;
&lt;td&gt;Never tested per item — the one sample name had a page, the other 7,794 items didn't&lt;/td&gt;
&lt;td&gt;&lt;code&gt;res.status !== 200&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON body&lt;/td&gt;
&lt;td&gt;1,588&lt;/td&gt;
&lt;td&gt;4KB body passed &lt;code&gt;length &amp;gt; 500&lt;/code&gt;; &lt;code&gt;*/*&lt;/code&gt; accepted any content type&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;content-type&lt;/code&gt; must contain &lt;code&gt;text/html&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Soft 404&lt;/td&gt;
&lt;td&gt;691&lt;/td&gt;
&lt;td&gt;200 + HTML + long body — indistinguishable by status. Next.js and Astro answer a missing route with 200 far more often than with 404&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; announces a missing page&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server error&lt;/td&gt;
&lt;td&gt;399&lt;/td&gt;
&lt;td&gt;Same as hard 404: nothing per item ever ran&lt;/td&gt;
&lt;td&gt;&lt;code&gt;res.status !== 200&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The guard
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifyPreview&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15000&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;no&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;embeddable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;reason&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="c1"&gt;// `text/html` alone, no `*/*` escape hatch. A registry that answers JSON&lt;/span&gt;
  &lt;span class="c1"&gt;// to this is answering JSON to everybody.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;timeout&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;no&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`transport: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;slice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;no&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`http &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content-type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLowerCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text/html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;no&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`serves &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;no&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`body is &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; bytes`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;lt;title&lt;/span&gt;&lt;span class="se"&gt;[^&lt;/span&gt;&lt;span class="sr"&gt;&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;*&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;([\s\S]{0,200}?)&lt;/span&gt;&lt;span class="sr"&gt;&amp;lt;&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="sr"&gt;title&amp;gt;/i&lt;/span&gt;&lt;span class="p"&gt;)?.[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;isNotFoundTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;no&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`not-found page (title: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;embeddable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;framable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The soft-404 check reads the &lt;strong&gt;title and nothing else&lt;/strong&gt;, which was not the first version. Scanning the first 4KB of body condemned two pages that render fine — &lt;code&gt;Apple gallery | 100xUI&lt;/code&gt; and &lt;code&gt;Pixel Scroll Transition – unlumen UI&lt;/code&gt; — because each carried the string &lt;code&gt;404&lt;/code&gt; in a nav or an inlined script. Deleting a working preview is worse than letting a broken one through, because the second is visible and the first isn't. So the regex has word boundaries and lives behind unit tests built from real titles: it must catch &lt;code&gt;Component not found - HextaUI&lt;/code&gt; and &lt;code&gt;404: This page could not be found&lt;/code&gt;, and must leave &lt;code&gt;Error404 Illustration | someui&lt;/code&gt; alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two deliberate asymmetries
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;docs_url&lt;/code&gt; still takes the unverified pattern; &lt;code&gt;preview_url&lt;/code&gt; does not. A "Docs on X" chip is a link somebody chooses to follow. The frame is a claim the page makes on their behalf, at 460px, above the fold.&lt;/p&gt;

&lt;p&gt;And verification is capped at &lt;code&gt;PREVIEW_CAP=2000&lt;/code&gt; items per registry. Past the cap an item keeps its page, its install command and its access verdict — it just doesn't get a frame nothing checked. After the sweep the index publishes 12,561 verified live previews, 2,858 verified links, and 43,795 items with no preview at all, and the item page's comment block now carries those counted numbers instead of the estimates it used to.&lt;/p&gt;

&lt;p&gt;This is how we built BlockDex, a search index for shadcn component registries: &lt;a href="https://blockdex.kynth.studio" rel="noopener noreferrer"&gt;https://blockdex.kynth.studio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
      <category>debugging</category>
    </item>
    <item>
      <title>In zsh, a second `local` on the same name prints it — how five bytes faked a six-day database outage</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Mon, 10 Aug 2026 14:08:08 +0000</pubDate>
      <link>https://dev.to/kynthstudios/in-zsh-a-second-local-on-the-same-name-prints-it-how-five-bytes-faked-a-six-day-database-outage-366k</link>
      <guid>https://dev.to/kynthstudios/in-zsh-a-second-local-on-the-same-name-prints-it-how-five-bytes-faked-a-six-day-database-outage-366k</guid>
      <description>&lt;p&gt;For six consecutive mornings, the freshness sweep behind our free directory list failed at the same place. Its preflight gate probes PostgREST before it's allowed to crawl anything, and every morning the log read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;preflight: PostgREST answered '000', not 200 — waiting 30s (retry 1/3)
preflight: PostgREST answered '000', not 200 — waiting 90s (retry 2/3)
preflight: PostgREST answered '000', not 200 — waiting 240s (retry 3/3)
preflight: PostgREST still answering '000' after 3 retries — giving up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running the identical probe by hand answered &lt;code&gt;200&lt;/code&gt; in 0.38 seconds. Same URL, same service key, same machine.&lt;/p&gt;

&lt;p&gt;That contradiction is why it survived five days of looking at it. The machine was fine. The credentials were fine. The database was fine. So the theory became &lt;em&gt;timing&lt;/em&gt;: a 05:10 job firing before the network came up on wake, and ~6 minutes of backoff not being enough to ride it out. The ladder got widened. It changed nothing, and got reverted.&lt;/p&gt;

&lt;h2&gt;
  
  
  The only tell was a byte count
&lt;/h2&gt;

&lt;p&gt;The env reader returned 45 bytes for &lt;code&gt;SUPABASE_URL&lt;/code&gt;. Parsing the same key out of the same file directly returned 40.&lt;/p&gt;

&lt;p&gt;Five bytes. Here's the function they came from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;_lr_env&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;f &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LISTRUN_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/.env"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LISTRUN_ROOT&lt;/span&gt;&lt;span class="s2"&gt;/.env.local"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;continue
    &lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;v                       &lt;span class="c"&gt;# ← the bug&lt;/span&gt;
    &lt;span class="nv"&gt;v&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"^&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;="&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$f&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nt"&gt;-f2-&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'"'&lt;/span&gt; | &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"'"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$v&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$v&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;return &lt;/span&gt;0&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;done
  return &lt;/span&gt;1
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What &lt;code&gt;local&lt;/code&gt; actually does in zsh
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;local&lt;/code&gt; is &lt;code&gt;typeset&lt;/code&gt;. And &lt;code&gt;typeset&lt;/code&gt; on a name &lt;strong&gt;already declared in the current scope&lt;/strong&gt; &lt;em&gt;prints&lt;/em&gt; the variable instead of quietly redeclaring it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;zsh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'f(){ local v; local v; }; f'&lt;/span&gt;
&lt;span class="go"&gt;v=''
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;zsh &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'f(){ local v=abc; local v; }; f'&lt;/span&gt;
&lt;span class="go"&gt;v=abc
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'f(){ local v; local v; }; f'&lt;/span&gt;
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt;                                        &lt;/span&gt;&lt;span class="c"&gt;# bash: nothing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two properties make this lethal rather than cosmetic. It writes to &lt;strong&gt;stdout&lt;/strong&gt; — which for a function called as &lt;code&gt;$(_lr_env SUPABASE_URL)&lt;/code&gt; is the entire return channel. And it prints the &lt;em&gt;current value&lt;/em&gt;, so a loop that carried something sensitive would leak it, not just an empty string.&lt;/p&gt;

&lt;p&gt;The reason iteration one was silent: &lt;code&gt;SUPABASE_URL&lt;/code&gt; lives in &lt;code&gt;.env.local&lt;/code&gt;, not &lt;code&gt;.env&lt;/code&gt;. The first pass found nothing and continued. The second pass hit &lt;code&gt;local v&lt;/code&gt; on a name already declared in that scope, printed &lt;code&gt;v=''&lt;/code&gt;, then found the real value and echoed it. The caller captured both lines and got:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;v&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;
https://xxxxxxxx.supabase.co
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;curl cannot resolve that. It never issued a request at all, and reported &lt;code&gt;000&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;000&lt;/code&gt; is not an HTTP status
&lt;/h2&gt;

&lt;p&gt;That's the second half of why this took six days. &lt;code&gt;000&lt;/code&gt; is curl's "no response happened." The log line said &lt;em&gt;PostgREST answered '000'&lt;/em&gt; — and PostgREST had answered nothing, because it was never contacted. Six mornings of diagnosis were spent on a component that was never in the request path.&lt;/p&gt;

&lt;p&gt;So the branch now says which of the two it's looking at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"000"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;saw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"the request never completed (curl '000' — no response, so this is the network or DNS, not PostgREST)"&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nv"&gt;saw&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PostgREST answered '&lt;/span&gt;&lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="s2"&gt;', not 200"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The fix itself is &lt;code&gt;local v f&lt;/code&gt; declared once above the loop. &lt;code&gt;f&lt;/code&gt; joined it because it had never been declared at all and was leaking into the caller's scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two things worth stealing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A retry ladder is the wrong instrument for a bug that fails identically on every attempt.&lt;/strong&gt; Three failures at 30s, 90s and 240s producing byte-identical output is itself the diagnosis: nothing about the passage of time was touching this. Widening the ladder on the network theory only delayed finding the real cause.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Back off only for failure shapes a wait can fix.&lt;/strong&gt; The same gate now aborts non-zero on &lt;code&gt;400/401/403/404/406&lt;/code&gt; instead of retrying, because of a sibling failure: ShipWall's gate probed &lt;code&gt;shipwall_board&lt;/code&gt;, which is a Postgres &lt;em&gt;function&lt;/em&gt;, not a table. PostgREST answers 404 instantly against a perfectly healthy instance. The gate read that as throttling and exited &lt;strong&gt;0&lt;/strong&gt; — so its nightly pass had never run, not once, and the job list reported success every morning.&lt;/p&gt;

&lt;p&gt;The blast radius here was wider than the freshness stamp, because the submission worker gates on the same function. Rather than assume, I read the queue: 7 runs, all &lt;code&gt;awaiting_payment&lt;/code&gt;, all created 08-01, and the job table empty. Nobody paid during the window, so no customer run actually stood still — but the first payment after 08-03 would have sat with nothing attempted and nothing anywhere saying so.&lt;/p&gt;

&lt;p&gt;That preflight gate, and the morning sweep it protects, are how we built ListRun — a submission engine whose free half is a directory list that re-checks itself and publishes what it actually saw.&lt;/p&gt;

</description>
      <category>zsh</category>
      <category>debugging</category>
      <category>devops</category>
      <category>shell</category>
    </item>
    <item>
      <title>If your API answers "clear" from an empty result set, your retention policy is product copy</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Fri, 07 Aug 2026 11:39:55 +0000</pubDate>
      <link>https://dev.to/kynthstudios/if-your-api-answers-clear-from-an-empty-result-set-your-retention-policy-is-product-copy-p8m</link>
      <guid>https://dev.to/kynthstudios/if-your-api-answers-clear-from-an-empty-result-set-your-retention-policy-is-product-copy-p8m</guid>
      <description>&lt;p&gt;I run a free lookup that answers one question: is this nonprofit in good standing? You type an EIN, it checks the IRS auto-revocation list and California's "may not operate or solicit" list, and tells you whether a fundraising platform has to block that org's donation page.&lt;/p&gt;

&lt;p&gt;The table behind it, &lt;code&gt;gs_orgs&lt;/code&gt;, only holds organizations that appear on one of those lists. Which means the API's happiest answer is produced by finding nothing. The comment at the top of &lt;code&gt;route.ts&lt;/code&gt; said so plainly:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;code&gt;gs_orgs&lt;/code&gt; table only holds orgs that appear on a revocation/delinquency list, so "no rows" reads as good standing on the lists we track.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a normal, sane design. It's also a landmine, and I stepped on it the week I tried to make the table smaller.&lt;/p&gt;

&lt;h2&gt;
  
  
  The pruning was correct on its own terms
&lt;/h2&gt;

&lt;p&gt;The ingest pulls both registries in full and had grown to 1,206,313 rows on a Postgres instance shared across the whole estate. Most of it was dead weight: the IRS file carries revocations going back years, and an org revoked in 2013 cannot use the streamlined 15-month reinstatement path this product exists to catch. It's a full re-application, not a buyer.&lt;/p&gt;

&lt;p&gt;So the ingest got a retention rule. The relevant part is seven lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;keep_since&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;GS_KEEP_REVOKED_SINCE&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;2020-01-01&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;worth_keeping&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ca_reg_no&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;ca_registry_status&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;                      &lt;span class="c1"&gt;# CA-listed: AB 488 buyer at any age
&lt;/span&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reinstatement_date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;                     &lt;span class="c1"&gt;# back in good standing; "clear" is correct
&lt;/span&gt;    &lt;span class="nf"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;revocation_date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;keep_since&lt;/span&gt; \
        &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;revocation_posting_date&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;keep_since&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;331,377 rows survived out of 1,206,313. The table went from 261 MB to 81 MB, and the outreach outputs the product actually acts on were untouched — 716 IRS postings in the trailing 45 days, 8,219 California delinquent or suspended orgs, same as before.&lt;/p&gt;

&lt;p&gt;Every number there says this was a good change. And it broke the API without touching a line of API code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deleting a row edits a sentence
&lt;/h2&gt;

&lt;p&gt;Look at the two &lt;code&gt;False&lt;/code&gt; branches and notice they are not the same kind of false.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;reinstatement_date&lt;/code&gt; branch drops a row because the org got its status back. Absence is &lt;em&gt;accurate&lt;/em&gt; for that org — the answer "clear" is the answer. Fine.&lt;/p&gt;

&lt;p&gt;The date-cutoff branch drops rows that are still revoked. Nothing about their status changed; only my willingness to store them did. But the API has no way to tell those two absences apart. It sees no row and prints the same thing.&lt;/p&gt;

&lt;p&gt;So a 2013 revocation — still revoked, still a real problem, still something a fundraising platform is on the hook for — came back from the lookup as clean. Not as an error, not as "unknown". As a confident green panel.&lt;/p&gt;

&lt;p&gt;The tempting fix is to unprune. That's wrong: the rows genuinely aren't worth storing, and keeping 874,936 of them to protect one sentence is an absurd trade.&lt;/p&gt;

&lt;p&gt;The actual fix is to make the sentence smaller. The clear-state copy used to read:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No IRS auto-revocation and no California delinquency on record for that EIN.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It now reads:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;No IRS auto-revocation &lt;strong&gt;posted since 2020&lt;/strong&gt;, and no California delinquency on record for that EIN.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second version is a claim the data can still support. The first one wasn't true even before the pruning — it just happened to be less wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keeping them tied together
&lt;/h2&gt;

&lt;p&gt;The failure mode from here is drift: someone widens &lt;code&gt;GS_KEEP_REVOKED_SINCE&lt;/code&gt; to 2015, or narrows it to 2022, and the copy stays frozen at "since 2020". Two files, one invariant, no compiler between them.&lt;/p&gt;

&lt;p&gt;There's no clever mechanism for this — you can't type-check a sentence against an environment variable. What exists instead is a warning at both ends. The ingest carries a ⛔ block above &lt;code&gt;keep_since&lt;/code&gt; saying the cutoff is load-bearing for &lt;code&gt;/api/lookup&lt;/code&gt; and that widening it means widening the copy. &lt;code&gt;route.ts&lt;/code&gt; carries the mirror image, naming the env var and the component that renders the claim. Whichever file you open first, it points at the other two.&lt;/p&gt;

&lt;p&gt;That's a weaker guarantee than a test, and I'd take a test if one were possible. What makes the comments work is that they're specific enough to act on: not "careful here", but the variable name, the file name, and the exact consequence.&lt;/p&gt;

&lt;h2&gt;
  
  
  The general shape
&lt;/h2&gt;

&lt;p&gt;Any table that stores only exceptions has this property. Blocklists, incident tables, audit-failure tables, sanctions screening, fraud flags — the whole design is "presence means bad, absence means fine," and the moment absence carries meaning, &lt;strong&gt;your retention window becomes part of your product's claim&lt;/strong&gt;. Compaction, TTLs, partition drops, a cheeky &lt;code&gt;DELETE FROM ... WHERE created_at &amp;lt; ...&lt;/code&gt; to reclaim disk: all of them silently rewrite what your API is asserting to a user.&lt;/p&gt;

&lt;p&gt;Before you prune one of those tables, go find the string that renders when the query comes back empty. That string is a spec. Either the deletion has to respect it, or it has to change with it.&lt;/p&gt;

&lt;p&gt;That's how we built the free EIN lookup in GoodStanding — try it on an org you care about, and read the caveat, because it means exactly what it says.&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>api</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>`new Date()` in your Next.js sitemap makes Google discard lastmod — export the page's own date instead</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Thu, 06 Aug 2026 11:34:16 +0000</pubDate>
      <link>https://dev.to/kynthstudios/new-date-in-your-nextjs-sitemap-makes-google-discard-lastmod-export-the-pages-own-date-51bm</link>
      <guid>https://dev.to/kynthstudios/new-date-in-your-nextjs-sitemap-makes-google-discard-lastmod-export-the-pages-own-date-51bm</guid>
      <description>&lt;p&gt;I shipped a guide site whose &lt;code&gt;sitemap.ts&lt;/code&gt; ended with the most natural line in the world:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SITE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/guides/cra-sbom-requirement`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastModified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every URL, every build. Which meant a commit that only touched brand tokens and a motion curve announced to Google that all four legal guides had been rewritten that afternoon. Nothing on those pages had changed in a week.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why that's worse than no lastmod at all
&lt;/h2&gt;

&lt;p&gt;Google's sitemap documentation says it uses &lt;code&gt;&amp;lt;lastmod&amp;gt;&lt;/code&gt; &lt;em&gt;"if it's consistently and verifiably (for example by comparing to the last modification of the page) accurate"&lt;/em&gt;, and that the value &lt;em&gt;"should reflect the date and time of the last significant update to the page."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;A sitemap where nothing is ever older than the last deploy fails both halves. The crawler fetches a page it was told changed, diffs it against what it already has, finds nothing, and learns that this host's dates mean nothing. Then it stops reading them.&lt;/p&gt;

&lt;p&gt;That's a cheap loss on an established domain. On a three-week-old host with no inbound links — where three of five guides were still unknown to Google — &lt;code&gt;lastmod&lt;/code&gt; is close to the only recrawl signal you own.&lt;/p&gt;

&lt;h2&gt;
  
  
  One constant, three consumers
&lt;/h2&gt;

&lt;p&gt;The date was already on the page twice: rendered as a visible "Last verified" line, and emitted as &lt;code&gt;dateModified&lt;/code&gt; in the page's &lt;code&gt;Article&lt;/code&gt; JSON-LD. The sitemap was inventing a third value instead of reading the one that existed.&lt;/p&gt;

&lt;p&gt;So the page module exports it, and the sitemap imports it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// guides/cra-sbom-requirement/page.tsx&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UPDATED&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-07-29&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// sitemap.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UPDATED&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;SBOM_UPDATED&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./guides/cra-sbom-requirement/page&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sitemap&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;MetadataRoute&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Sitemap&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SITE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/guides/cra-sbom-requirement`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lastModified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SBOM_UPDATED&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;changeFrequency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;monthly&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;0.9&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="c1"&gt;// static pages carry the date of their last real content change, bumped by hand&lt;/span&gt;
  &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next.js accepts an ISO string for &lt;code&gt;lastModified&lt;/code&gt;, so no conversion is needed. Static pages that have no &lt;code&gt;UPDATED&lt;/code&gt; get a hand-maintained constant with a comment explaining what change earned the bump. The landing page's says &lt;code&gt;2026-08-04&lt;/code&gt; because a factual correction rewrote the FAQ, its JSON-LD and two components — not because something was deployed that day.&lt;/p&gt;

&lt;h2&gt;
  
  
  The off-by-one that only surfaced once the dates converged
&lt;/h2&gt;

&lt;p&gt;Collapsing three values into one immediately exposed a bug nobody could have seen while they were independent. The visible date rendered like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toLocaleDateString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;new Date("2026-08-01")&lt;/code&gt; parses date-only strings as &lt;strong&gt;UTC midnight&lt;/strong&gt;. Format that in any negative-offset zone and you get the previous day. Every guide had been showing a "Last verified" date one day behind the &lt;code&gt;dateModified&lt;/code&gt; in its own &lt;code&gt;Article&lt;/code&gt; schema — human-readable text contradicting structured data on the same page, in a way that only reproduces west of Greenwich. The fix is &lt;code&gt;timeZone: "UTC"&lt;/code&gt; in the options bag, with a comment saying it's load-bearing so nobody tidies it away.&lt;/p&gt;

&lt;p&gt;The sitemap bug was in &lt;code&gt;sitemap.ts&lt;/code&gt;. The date bug was in the article renderer. You find the second one only after the first forces both surfaces to read from the same source.&lt;/p&gt;

&lt;h2&gt;
  
  
  The harder half: what licenses a bump
&lt;/h2&gt;

&lt;p&gt;Once dates are honest, "should this move?" becomes a real decision. The site makes 34 dated claims about a regulation — deadlines, penalty routes, filing channels — and each lives in a register with the primary source it was fetched from, an &lt;code&gt;asOf&lt;/code&gt;, a &lt;code&gt;lastVerified&lt;/code&gt;, and a &lt;code&gt;watch&lt;/code&gt; note.&lt;/p&gt;

&lt;p&gt;The dangerous category is claims that assert something has &lt;strong&gt;not&lt;/strong&gt; happened. One is flagged &lt;code&gt;HIGHEST-DECAY CLAIM IN THIS REGISTER&lt;/code&gt;: whether the Commission has adopted an implementing act specifying the SBOM format. It can go false while the repo sits completely still, and if it does, an entire section of a guide is wrong that morning.&lt;/p&gt;

&lt;p&gt;So re-verification happens on a schedule the content doesn't. Last check: source fetched, HTTP 200, still nothing adopted. &lt;code&gt;lastVerified&lt;/code&gt; in the register moves. The page's &lt;code&gt;UPDATED&lt;/code&gt; does not — and therefore neither does &lt;code&gt;lastmod&lt;/code&gt;. Verifying is not updating.&lt;/p&gt;

&lt;p&gt;The rule that came out of it: &lt;strong&gt;a stale-but-true date is worth more than a fresh lie.&lt;/strong&gt; If you can't name the content change behind a bump, don't bump it.&lt;/p&gt;

&lt;p&gt;That register and these guides are how we built PartsProof: &lt;a href="https://partsproof.kynth.studio" rel="noopener noreferrer"&gt;https://partsproof.kynth.studio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>seo</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>731 words or 2,042? Why an aggregate's population belongs in the view, not the query string</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Wed, 05 Aug 2026 15:30:29 +0000</pubDate>
      <link>https://dev.to/kynthstudios/731-words-or-2042-why-an-aggregates-population-belongs-in-the-view-not-the-query-string-4i7o</link>
      <guid>https://dev.to/kynthstudios/731-words-or-2042-why-an-aggregates-population-belongs-in-the-view-not-the-query-string-4i7o</guid>
      <description>&lt;p&gt;I maintain a corpus of agent instruction files scraped from public repos — &lt;code&gt;AGENTS.md&lt;/code&gt;, &lt;code&gt;CLAUDE.md&lt;/code&gt;, Cursor rules and friends — and last week I added the page answering "what actually goes in a CLAUDE.md," counted rather than recommended.&lt;/p&gt;

&lt;p&gt;The first thing that fell out was two different answers to &lt;em&gt;median length&lt;/em&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;basis&lt;/th&gt;
&lt;th&gt;files&lt;/th&gt;
&lt;th&gt;median words&lt;/th&gt;
&lt;th&gt;share with runnable commands&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;every &lt;code&gt;CLAUDE.md&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;775&lt;/td&gt;
&lt;td&gt;2,042&lt;/td&gt;
&lt;td&gt;34.2%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;repo-root &lt;code&gt;CLAUDE.md&lt;/code&gt; only&lt;/td&gt;
&lt;td&gt;201&lt;/td&gt;
&lt;td&gt;731&lt;/td&gt;
&lt;td&gt;79.6%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both are correct. The 574 non-root files — the per-package ones sitting in &lt;code&gt;packages/api/CLAUDE.md&lt;/code&gt; — have a median of 2,276 words, which is the opposite of what I'd have guessed. Whatever the cause, they are a different population answering a different question, and someone asking "what should my CLAUDE.md contain" means the one at the root.&lt;/p&gt;

&lt;p&gt;So the interesting part isn't the number. It's that &lt;strong&gt;the choice of population is a schema decision&lt;/strong&gt;, and I'd been treating it as a query parameter.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rule 1: the filter that defines the population goes in the view
&lt;/h2&gt;

&lt;p&gt;The tempting design is &lt;code&gt;/api/sections?root=true&lt;/code&gt;. Then the default is wrong, or the caller forgets, and a percentage computed over 775 files gets printed under a heading that says "a CLAUDE.md file." Nobody will ever notice, because the number looks fine.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;create&lt;/span&gt; &lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="k"&gt;replace&lt;/span&gt; &lt;span class="k"&gt;view&lt;/span&gt; &lt;span class="n"&gt;rs_section_stats&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
  &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rs_configs&lt;/span&gt;
  &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;is_root&lt;/span&gt;
  &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;format&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;                                                 &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;section_tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;                                         &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;config_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;                                               &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;root_total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="n"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;nullif&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)::&lt;/span&gt;&lt;span class="nb"&gt;real&lt;/span&gt;  &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;pct_of_root&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;rs_configs&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;
&lt;span class="k"&gt;cross&lt;/span&gt; &lt;span class="k"&gt;join&lt;/span&gt; &lt;span class="k"&gt;lateral&lt;/span&gt; &lt;span class="k"&gt;unnest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;section_tags&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;join&lt;/span&gt; &lt;span class="n"&gt;base&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;hidden&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;is_root&lt;/span&gt;
&lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;is_root&lt;/code&gt; appears twice and is optional in neither place. There is no way to call this view and get the other population. The name says &lt;code&gt;pct_of_root&lt;/code&gt;, so a column that escapes into a page carries its own basis in the label.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rule 2: ship the denominator on every numerator row
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;root_total&lt;/code&gt; is repeated identically on all twenty rows, which is redundant on purpose. The alternative is a page that fetches counts here and the total from somewhere else — and "somewhere else" drifts. A different &lt;code&gt;hidden&lt;/code&gt; filter, a different date window, a &lt;code&gt;count&lt;/code&gt; over the list endpoint that hit a row cap. A percentage with the wrong denominator is the kind of wrong that looks right.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rule 3: two bases on one page is an invitation to divide across them
&lt;/h2&gt;

&lt;p&gt;I already had a stats table publishing medians over &lt;em&gt;all&lt;/em&gt; files. Rather than reuse it, I added a second small view, &lt;code&gt;rs_root_shape&lt;/code&gt;, computing length and heading counts on the same root-only basis. It exists purely so a reader — or a future me — cannot pair a median from one population with a share from another in adjacent paragraphs. Duplicating an aggregate is cheaper than the errata.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rule 4: &lt;code&gt;GROUP BY&lt;/code&gt; cannot emit a zero
&lt;/h2&gt;

&lt;p&gt;The classifier has a fixed vocabulary of 20 section tags. A group-by returns only tags that some file carries, so for &lt;code&gt;windsurf-rules&lt;/code&gt; the view returns 13 rows and for &lt;code&gt;.cursorrules&lt;/code&gt; it returns 19. Render that as "the tags" and you've silently claimed the missing 7 aren't categories at all — when "no file in this corpus has a security section" is one of the more interesting things you could say. The endpoint returns &lt;code&gt;sections&lt;/code&gt;, plus &lt;code&gt;vocabulary&lt;/code&gt;: every tag the classifier can assign. Absence is an answer, and it has to be carried out-of-band because SQL won't produce it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is a view and not application code
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;section_tags&lt;/code&gt; is a &lt;code&gt;text[]&lt;/code&gt;. Getting a share out of it needs an &lt;code&gt;unnest&lt;/code&gt; and a group-by — the one aggregate a list endpoint structurally can't serve. &lt;code&gt;/api/configs?tag=build&lt;/code&gt; returns the files with a build section, never the fraction. Computing it in the page meant paging a whole format at the handler's 100-row ceiling: eight sequential reads of thirty-eight columns to produce twenty integers. One view, one read.&lt;/p&gt;

&lt;p&gt;For the record, the finding that motivated the page: build commands come first in Anthropic's list of what to keep in a &lt;code&gt;CLAUDE.md&lt;/code&gt;, and 39.8% of root files have a build section. Hard prohibitions are the cheapest line anyone can write, and 48.3% have those.&lt;/p&gt;

&lt;p&gt;This is how we built RuleStack, a measured comparison hub for agent config formats: &lt;a href="https://rulestack.kynth.studio" rel="noopener noreferrer"&gt;https://rulestack.kynth.studio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>postgres</category>
      <category>database</category>
      <category>architecture</category>
    </item>
    <item>
      <title>A failed read must throw, not return 0 — how Next.js ISR bakes your fallback into the cache</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Tue, 04 Aug 2026 11:17:50 +0000</pubDate>
      <link>https://dev.to/kynthstudios/a-failed-read-must-throw-not-return-0-how-nextjs-isr-bakes-your-fallback-into-the-cache-57in</link>
      <guid>https://dev.to/kynthstudios/a-failed-read-must-throw-not-return-0-how-nextjs-isr-bakes-your-fallback-into-the-cache-57in</guid>
      <description>&lt;p&gt;I run a directory site: ~3,500 rows in Postgres, read over PostgREST, rendered by Next.js with &lt;code&gt;revalidate&lt;/code&gt; on every route. The headline number in the shell says "Search all 3,516 listings."&lt;/p&gt;

&lt;p&gt;For about a day it said "Search all 0 listings" — next to a grid full of listings.&lt;/p&gt;

&lt;p&gt;The database was fine by then. Three separate bugs conspired, and all three are the same mistake wearing different clothes: &lt;strong&gt;a read that degrades politely on failure, sitting underneath a cache that stores the polite answer.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 1: the cache dropped the header the count lived in
&lt;/h2&gt;

&lt;p&gt;PostgREST returns an exact row count in the &lt;code&gt;Content-Range&lt;/code&gt; response header if you ask for it, which is far cheaper than selecting rows and counting them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/rest/v1/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;table&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;?&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;query&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;amp;select=id&amp;amp;limit=1`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;apikey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;Prefer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count=exact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;0-0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;revalidate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3600&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;      &lt;span class="c1"&gt;// ← the bug&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content-range&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next's fetch cache stores the response &lt;strong&gt;body&lt;/strong&gt; and replays it behind a synthetic set of headers. &lt;code&gt;content-range&lt;/code&gt; is not one of them. So the first call worked, and every cache hit after it read &lt;code&gt;null&lt;/code&gt; and produced &lt;code&gt;0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Statically prerendered pages looked perfect — their single fetch happened at build time and was always a miss. Every dynamic route showed zero. If you're caching a fetch for anything that isn't in the body, cache the &lt;em&gt;parsed value&lt;/em&gt; instead: mark the fetch &lt;code&gt;cache: 'no-store'&lt;/code&gt; and wrap the function in &lt;code&gt;unstable_cache&lt;/code&gt;. Cache things that survive being cached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 2: the zero got memoised for an hour
&lt;/h2&gt;

&lt;p&gt;With the count now memoised, the failure path mattered. The read returned &lt;code&gt;0&lt;/code&gt; when the response wasn't OK — sensible-looking, and &lt;code&gt;unstable_cache&lt;/code&gt; dutifully stored that &lt;code&gt;0&lt;/code&gt; for the full hour.&lt;/p&gt;

&lt;p&gt;So the wrong number outlived the outage. The index came back; the site kept saying zero, and looked completely healthy while doing it. For a directory, "0 listings" isn't a degraded state, it's a false claim about the world.&lt;/p&gt;

&lt;p&gt;Fix: throw inside the cached function. &lt;code&gt;unstable_cache&lt;/code&gt; stores nothing on a throw, so the next request re-reads and the site heals the instant the database answers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bug 3: the page containing the zero was also cached
&lt;/h2&gt;

&lt;p&gt;Here's the one I got wrong twice. The outer &lt;code&gt;catch&lt;/code&gt; still returned &lt;code&gt;0&lt;/code&gt;, on what felt like solid reasoning: &lt;em&gt;this&lt;/em&gt; zero isn't memoised, so it lasts exactly as long as the outage.&lt;/p&gt;

&lt;p&gt;It missed the other cache. Every route declares &lt;code&gt;revalidate&lt;/code&gt;. A background revalidation that renders "Search all 0 listings" writes that sentence into the ISR page cache and serves it for an hour on the landing and a day everywhere else. Not caching the zero doesn't help when the &lt;strong&gt;page containing the zero&lt;/strong&gt; is the cached artifact.&lt;/p&gt;

&lt;p&gt;The worst instance was &lt;code&gt;/opengraph-image&lt;/code&gt;, which drew "0 skills · 0 subagents · 0 plugins" onto the share card and pinned it to every link preview for a day. A share card is the one surface where a wrong number gets screenshotted and outlives your cache entirely.&lt;/p&gt;

&lt;p&gt;So it rethrows. Throwing is what makes Next keep the last good copy.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rule that fell out
&lt;/h2&gt;

&lt;p&gt;Not every read should fail loudly. Two here must degrade: the footer's freshness line, which appears on ~3,500 routes and is one sentence of fine print, and the build-time list behind &lt;code&gt;generateStaticParams&lt;/code&gt;, which only decides what gets prerendered. Those go through a separate helper with &lt;code&gt;AbortSignal.timeout(5000)&lt;/code&gt; — a plain &lt;code&gt;fetch&lt;/code&gt; has no timeout, and a &lt;code&gt;try/catch&lt;/code&gt; cannot catch a hang. The footer says "rebuild pending," which is honest, and the build finishes.&lt;/p&gt;

&lt;p&gt;Everything else fails. The test is simple: &lt;strong&gt;if the page's whole reason to exist is that data, an empty render is a lie, and a lie is what gets cached.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The same family of bug shows up without any cache involved. PostgREST caps a response at 1,000 rows no matter what &lt;code&gt;limit&lt;/code&gt; you send. A category count computed in JavaScript over &lt;code&gt;limit=20000&lt;/code&gt; therefore summed the first 1,000 of 3,369 rows and published "1,000 listings" — a suspiciously round number that was precisely the cap. The sitemap did it too: 1,070 URLs emitted against 3,516 real ones, silently dropping the entire long tail. Both now read a Postgres view that does the aggregation server-side.&lt;/p&gt;

&lt;p&gt;Truncation, a missing header, a caught exception. Every one of them returns a number rather than an error, and a number is believed.&lt;/p&gt;

&lt;p&gt;This is how we built SkillWorks, a scored index of Claude Code skills and subagents: &lt;a href="https://skillworks.kynth.studio" rel="noopener noreferrer"&gt;https://skillworks.kynth.studio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>postgres</category>
      <category>caching</category>
    </item>
    <item>
      <title>Severity belongs to (check, kind), not to the check: fixing 512 false "will not load" verdicts</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Mon, 03 Aug 2026 11:14:03 +0000</pubDate>
      <link>https://dev.to/kynthstudios/severity-belongs-to-check-kind-not-to-the-check-fixing-512-false-will-not-load-verdicts-15bg</link>
      <guid>https://dev.to/kynthstudios/severity-belongs-to-check-kind-not-to-the-check-fixing-512-false-will-not-load-verdicts-15bg</guid>
      <description>&lt;p&gt;I run an index that scrapes published Claude Code artifacts — skills, subagents, plugins, marketplaces — scores them on four measured components, and publishes a page whose &lt;code&gt;h1&lt;/code&gt; is literally &lt;strong&gt;"These will not work."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That page is the whole product. It is also the only place where a bug costs someone else something. A checker's two error directions are not symmetric: a missed defect is a gap, but a false positive is a public accusation against a stranger's repo. Last weekend I found three of them in the same scorer, and they were all the same mistake wearing different clothes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. &lt;code&gt;?? 0&lt;/code&gt; turned a shape mismatch into a verdict
&lt;/h2&gt;

&lt;p&gt;The marketplace check is one line: a marketplace manifest listing no plugins can't install anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extra&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;plugin_count&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;extra&lt;/code&gt; is a shape assembled on the way &lt;em&gt;into&lt;/em&gt; the database — after the scorer runs. The artifact the scraper hands the scorer carries &lt;code&gt;plugin_count&lt;/code&gt; at the top level. So the read was &lt;code&gt;undefined&lt;/code&gt;, &lt;code&gt;?? 0&lt;/code&gt; made it a confident zero, and &lt;strong&gt;every marketplace in the index — all 55 — published a fatal "empty marketplace, will not load."&lt;/strong&gt; Including &lt;code&gt;anthropics/claude-plugins-official&lt;/code&gt;, which lists 276 plugins.&lt;/p&gt;

&lt;p&gt;Optional chaining plus a nullish default is how a missing field becomes a measurement. The property access can't fail, so nothing ever throws, and the wrong answer is the plausible one.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The same check is not the same severity on every kind
&lt;/h2&gt;

&lt;p&gt;The bigger one. The scorer flagged &lt;code&gt;no-name&lt;/code&gt; and &lt;code&gt;no-description&lt;/code&gt; as fatal on anything with frontmatter. Reading Anthropic's own references (skills and sub-agents, 2026-08-02):&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;name&lt;/code&gt;&lt;/th&gt;
&lt;th&gt;&lt;code&gt;description&lt;/code&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;subagent&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Required: Yes&lt;/td&gt;
&lt;td&gt;Required: Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;skill&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Required: &lt;strong&gt;No&lt;/strong&gt; — "defaults to the directory name"&lt;/td&gt;
&lt;td&gt;Recommended — "if omitted, uses the first paragraph of markdown content"&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A skill with neither field still registers. It takes its command from the directory and its routing text from whatever the first paragraph happens to say. That's worse than a written description — it is not a loading failure.&lt;/p&gt;

&lt;p&gt;I had generalized the subagent rule across both kinds, so 494 skills, 6 plugins, 2 marketplaces and 10 subagents sat under "these will not work." The fix is that fatality stopped being a property of the flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FATAL_ALWAYS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;broken-frontmatter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;broken-manifest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;empty-marketplace&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="cm"&gt;/** Required frontmatter on a subagent; documented as optional on a skill. */&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FATAL_IF_REQUIRED_FIELD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no-description&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="cm"&gt;/** Does this flag stop the artifact registering, given what kind it is? */&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isFatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;kind&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FATAL_ALWAYS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;FATAL_IF_REQUIRED_FIELD&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;has&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;flag&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;kind&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subagent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The flags themselves survive — a skill with no description is still genuinely harder to route to, and it still takes a deduction (8 points instead of 30). What changed is that a deduction stopped being a verdict.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;archived&lt;/code&gt; came off the fatal list in the same pass. An archived GitHub repo is read-only, not unloadable; the files are there and the skill still installs. It was also already the steepest input to the Maintained component, so it was being charged twice.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Thresholds you remember instead of read
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;long-description&lt;/code&gt; fired above 1024 characters, with the reason string "the practical ceiling is ~1024." Nobody wrote that number down anywhere. The documented cap is &lt;strong&gt;1,536 characters, over &lt;code&gt;description&lt;/code&gt; and &lt;code&gt;when_to_use&lt;/code&gt; combined&lt;/strong&gt;, applied to the listing text to reduce context usage. A remembered number was penalizing descriptions the documentation explicitly allows.&lt;/p&gt;

&lt;p&gt;That one's now in a &lt;code&gt;FACTS.json&lt;/code&gt; register: every claim the product makes about the outside world, with the primary source URL, the date it was read, and which files depend on it. Internal arithmetic — score weights, grade boundaries — deliberately stays out. Those are the method, not claims about the world.&lt;/p&gt;

&lt;h2&gt;
  
  
  The check that would have caught all three
&lt;/h2&gt;

&lt;p&gt;Every one of these had the same tell, and it's cheap to look for: &lt;strong&gt;if 100% of a category fails your checker, the checker is what's broken.&lt;/strong&gt; Fifty-five out of fifty-five marketplaces empty. Effectively every skill on the planet missing a required field. That is never a fact about the corpus.&lt;/p&gt;

&lt;p&gt;The generalizable version, for anything that grades other people's work: encode the bar as a sentence in the code next to the list (mine is "Claude Code cannot register the artifact — nothing softer qualifies"), keep severity keyed on the pair, not the check, and treat a suspiciously round failure rate as a bug report against yourself.&lt;/p&gt;

&lt;p&gt;This is how we built SkillWorks — a scored index of every published Claude Code skill, subagent and plugin.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>node</category>
      <category>showdev</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Commit every raw vendor response: making a benchmark anyone can re-score without an API key</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Fri, 31 Jul 2026 11:06:52 +0000</pubDate>
      <link>https://dev.to/kynthstudios/commit-every-raw-vendor-response-making-a-benchmark-anyone-can-re-score-without-an-api-key-543l</link>
      <guid>https://dev.to/kynthstudios/commit-every-raw-vendor-response-making-a-benchmark-anyone-can-re-score-without-an-api-key-543l</guid>
      <description>&lt;p&gt;I published a benchmark of document-extraction APIs where one of the entrants is my own. That is a credibility problem you cannot write your way out of. The only fix is to make the numbers recomputable by a stranger who trusts nothing I say — including on the runs where my product loses.&lt;/p&gt;

&lt;p&gt;The design decision that makes that possible is small: &lt;strong&gt;the runner never scores anything it just fetched.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Split the run in half at the raw response
&lt;/h2&gt;

&lt;p&gt;Every vendor call writes one verbatim JSON file and stops there:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// results/raw/&amp;lt;vendor&amp;gt;/&amp;lt;dataset&amp;gt;/&amp;lt;docId&amp;gt;.json&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rec&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;vendor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;docId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;at&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
              &lt;span class="na"&gt;latencyMs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;latencyMs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="nf"&gt;writeJson&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;rawPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;vendor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dataset&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;rec&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// planning a run: anything already on disk is not re-fetched&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;allIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nf"&gt;existsSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;rawPath&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;adapter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Scoring is a separate entry point (&lt;code&gt;--replay&lt;/code&gt;) that reads those files and never touches the network. All 1,210 raw responses are committed. Anyone can clone the repo, run &lt;code&gt;pnpm replay &amp;amp;&amp;amp; pnpm report&lt;/code&gt;, and regenerate the README tables with zero credentials and zero spend.&lt;/p&gt;

&lt;p&gt;Three things fall out of that split, and only one of them was the goal.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reproduction is keyless.&lt;/strong&gt; That was the point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixing a scoring bug is free.&lt;/strong&gt; Metrics are where a benchmark is most likely to be wrong, and re-running 500 paid API calls to correct a normalizer is the kind of cost that quietly discourages fixing it. Here a metric fix is a replay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Crashed runs resume for free.&lt;/strong&gt; That &lt;code&gt;existsSync&lt;/code&gt; filter was written for idempotency and turned out to be the thing that saved the run, because of what happened next.&lt;/p&gt;

&lt;h2&gt;
  
  
  The stall was not where I was looking
&lt;/h2&gt;

&lt;p&gt;A full run wedged. No error, no exit, just a process sitting on one document forever. My first instinct was rate limiting, and I went looking at retry logic.&lt;/p&gt;

&lt;p&gt;The retry logic was fine. It just never ran. My retry wrapper does three attempts with backoff, and the AWS SDK client had &lt;code&gt;maxAttempts: 3&lt;/code&gt; on top of that — but retries only fire when something &lt;em&gt;fails&lt;/em&gt;, and a hung socket does not fail. It sits. Every layer of resilience I had was downstream of an error that was never going to arrive.&lt;/p&gt;

&lt;p&gt;So the fix was deadlines, not retries. Every &lt;code&gt;fetch&lt;/code&gt; in every adapter got &lt;code&gt;signal: AbortSignal.timeout(120_000)&lt;/code&gt;, including the 3-second job-poll loop, which got its own shorter one. The AWS client got an explicit &lt;code&gt;NodeHttpHandler({ connectionTimeout: 10_000, requestTimeout: 120_000, socketTimeout: 120_000 })&lt;/code&gt;. Two commits, one for the fetch calls and one for the SDK client, because the SDK does not respect the same mechanism and I found it as a second stall a half hour later.&lt;/p&gt;

&lt;p&gt;If you take one thing from this: a hung request is not a slow request, and no amount of retry configuration converts one into the other. The timeout is what gives &lt;code&gt;maxAttempts&lt;/code&gt; something to attempt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pre-register the subset before the first call
&lt;/h2&gt;

&lt;p&gt;Selection is the easiest place to cheat, usually without meaning to. So the subset ID lists were committed before the adapters could bill anything, generated by seeded shuffle with the seed in the manifest (&lt;code&gt;20260710&lt;/code&gt;). The methodology fixes one rule that costs me points: &lt;em&gt;no document is excluded after seeing results.&lt;/em&gt; A vendor failure is a failed document, not a dropped one.&lt;/p&gt;

&lt;p&gt;Headline metrics are exact match after type-aware normalization — amounts within 0.005, dates to ISO, strings NFKC-lowercased with punctuation stripped. ANLS (fuzzy Levenshtein similarity) is computed, reported, and never allowed into a headline number, because a similarity threshold is a dial and I would be the one turning it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What that honesty actually cost
&lt;/h2&gt;

&lt;p&gt;On invoices my API leads at 99.4% field accuracy against 93.1% and 92.2% — at a median 12.8s per document versus Textract's 1.8s. On CORD-v2 line items it gets &lt;strong&gt;41.9% F1 against Textract's 77.1%&lt;/strong&gt;. On FinTabNet tables it scores 0.791 TEDS against 0.836, with 14 of 100 documents failing outright on &lt;code&gt;model returned unparseable output&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Those last two are in the README, in bold, in the same table style as the wins. Publishing them is the only reason the first number means anything.&lt;/p&gt;

&lt;p&gt;The extraction API benchmarked here is Kynth Core, and this is how we built it: &lt;a href="https://kynth.studio" rel="noopener noreferrer"&gt;https://kynth.studio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>node</category>
      <category>testing</category>
    </item>
    <item>
      <title>The date solver behind a six-document compliance packet: why one backward pass isn't enough</title>
      <dc:creator>Kynth Studios</dc:creator>
      <pubDate>Thu, 30 Jul 2026 13:02:44 +0000</pubDate>
      <link>https://dev.to/kynthstudios/the-date-solver-behind-a-six-document-compliance-packet-why-one-backward-pass-isnt-enough-5c7b</link>
      <guid>https://dev.to/kynthstudios/the-date-solver-behind-a-six-document-compliance-packet-why-one-backward-pass-isnt-enough-5c7b</guid>
      <description>&lt;p&gt;Here is the thing we actually ship: a single PDF packet, 30-odd pages, that a small public housing authority hands to its board and its auditor.&lt;/p&gt;

&lt;p&gt;Front half is a redline. Their own ACOP (Admissions and Continued Occupancy Policy) and HCV Administrative Plan chapters, with the HOTMA-driven changes marked up and the agency's discretionary elections filled in — asset thresholds, hardship relief, de minimis error policy. Back half is the procedural record that proves the redline was adopted properly: the public notice, the Resident Advisory Board agenda and consultation memo, the hearing script, the board resolution, and a dated adoption memo.&lt;/p&gt;

&lt;p&gt;The redline is the part people expect to be hard. It wasn't. The calendar was.&lt;/p&gt;

&lt;h2&gt;
  
  
  Six documents that quote each other
&lt;/h2&gt;

&lt;p&gt;None of these documents stand alone. The resolution recites the hearing date. The hearing script cites when the notice was published and when comments closed. The adoption memo cites the resolution number and the vote date. The RAB memo cites the consultation meeting and the comment window it sits inside.&lt;/p&gt;

&lt;p&gt;So a packet with one wrong date isn't a packet with one typo. It's a packet where the resolution attests to a hearing that, according to the notice, hadn't happened yet. That's exactly the kind of thing an auditor pulls a thread on.&lt;/p&gt;

&lt;p&gt;The fix isn't better prompting. It's refusing to let dates be prose at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  Milestones declare constraints, not dates
&lt;/h2&gt;

&lt;p&gt;Every artifact in the packet declares what it depends on and by how much. Nothing declares when it happens.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MILESTONES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rab_consult&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="na"&gt;minDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment_close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;notice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="na"&gt;minDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hearing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment_close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;minDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
                                 &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rab_consult&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="na"&gt;minDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;board_vote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hearing&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;       &lt;span class="na"&gt;minDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
                         &lt;span class="na"&gt;onlyOn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;agency&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;boardCalendar&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;effective&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;     &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;board_vote&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="na"&gt;minDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;minDays&lt;/code&gt; values are config, not constants. Some come from federal rules, some from the agency's own bylaws, and they differ per agency — which is the whole reason they're data.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onlyOn&lt;/code&gt; is the interesting field. A board doesn't vote whenever the math says it can. It votes on its regular meeting schedule: third Tuesday, or the second Thursday of odd months, or whatever the bylaws say.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one backward pass isn't enough
&lt;/h2&gt;

&lt;p&gt;Solving forward from today is easy. Solving &lt;em&gt;backward&lt;/em&gt; from a fixed effective date is what the customer actually wants, because there's a wall at 1 January 2027 and the question is "when do we have to start."&lt;/p&gt;

&lt;p&gt;Backward looks like simple subtraction until &lt;code&gt;onlyOn&lt;/code&gt; shows up. Subtract from the effective date, land on 14 October, discover the board doesn't meet on the 14th, snap back to the 8th. You just moved the vote six days earlier — which means the hearing has to move, which means comments close earlier, which means the notice has to publish earlier. And the RAB consultation, which was comfortably satisfied at the old dates, may now be sitting on the wrong side of its own 10-day floor.&lt;/p&gt;

&lt;p&gt;One pass gives you a schedule that looks right and quietly violates a constraint it satisfied before the snap. So the solver iterates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;dates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;seedBackward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MILESTONES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;effectiveDate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;MAX_ITERS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;relaxBackward&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;MILESTONES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// re-apply every edge, re-snap onlyOn&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;sameDates&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dates&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;dates&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;dates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;next&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no fixpoint&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each pass only ever moves dates earlier, so it's monotone and it terminates. It's a small fixpoint loop, not a real constraint solver, and that's fine — the graph has six nodes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Infeasibility is a result, not an error
&lt;/h2&gt;

&lt;p&gt;The loop can push &lt;code&gt;notice&lt;/code&gt; into the past. That's not a crash. It's the single most useful thing the packet can tell a small PHA in late 2026: &lt;em&gt;you cannot adopt this on your normal meeting calendar.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So that branch doesn't throw. It renders a different packet — one built around a special meeting, with the notice-of-special-meeting document swapped in and the resolution's recitals rewritten to reference the bylaw provision that authorizes it. Same elections, different procedural path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prose last
&lt;/h2&gt;

&lt;p&gt;Once dates exist, generation is narrow. The model's job is to pick the discretionary election given the agency's profile and write the reasoning around it. Every date and every cross-reference is a token substituted from the solved schedule after the fact. The resolution and the hearing script can't disagree, because neither of them ever &lt;em&gt;wrote&lt;/em&gt; a date.&lt;/p&gt;

&lt;p&gt;That's the reusable bit. If your output is several documents that cite each other, the citations belong in a data structure that gets solved once, not in six generations you then hope agree.&lt;/p&gt;

&lt;p&gt;This is how we built QuorumFile — flat-fee HOTMA adoption packets for small PHAs: &lt;a href="https://quorumfile.kynth.studio" rel="noopener noreferrer"&gt;https://quorumfile.kynth.studio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>showdev</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
