<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Ripe Route — Changelog</title><description>Build-in-public log for Ripe Route: free agricultural reference tools built on US federal public datasets.</description><link>https://riperoute.com/</link><language>en-us</language><lastBuildDate>Fri, 21 Aug 2026 00:00:00 GMT</lastBuildDate><atom:link href="https://riperoute.com/feed.xml" rel="self" type="application/rss+xml"/><item><title>A feed, and a way around</title><link>https://riperoute.com/changelog/#2026-08-21-a-feed-and-a-way-around</link><guid isPermaLink="true">https://riperoute.com/changelog/#2026-08-21-a-feed-and-a-way-around</guid><description>The changelog can now be subscribed to, and every page links to the rest of the site.</description><pubDate>Fri, 21 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is an &lt;a href=&quot;https://riperoute.com/feed.xml&quot;&gt;RSS feed&lt;/a&gt; now. Entries arrive in it whole rather than as
a headline and a link, because a feed that makes you click through to read it is
one you unsubscribe from.&lt;/p&gt;
&lt;p&gt;Every page also links to the others at last. Those links went into the footer
rather than the header, which was a decision rather than a default: the header
is being kept for the tools, and there will be six of those. Nine pages about
the site itself is a footer at any size. Better to make that split before anyone
learns where things are than after.&lt;/p&gt;
&lt;h3 id=&quot;the-bug-that-had-no-symptoms&quot;&gt;The bug that had no symptoms&lt;/h3&gt;
&lt;p&gt;Feed entries link to their own heading in the changelog, so the link carries a
fragment — the part after the &lt;code&gt;#&lt;/code&gt;. The library that builds the feed tidies up
paths by making sure they end in a slash, which is right for a page and wrong
for a fragment. It appended the slash to the end of the whole link, inside the
fragment, so every entry pointed at a heading that did not exist and every
subscriber would have landed at the top of this page instead.&lt;/p&gt;
&lt;p&gt;Nothing about it looked wrong. The feed was valid, the links were well-formed,
and the page they pointed at loaded fine. It was caught by reading the library’s
source before trusting it, and there is now a check on every release that fails
if a fragment ever ends in a slash again.&lt;/p&gt;
&lt;p&gt;That is the second time in two releases that something passed every test it had
and was still broken. The first was a set of type definitions that only exist
after a build step, so the checks ran against them locally and against nothing
at all on a clean checkout — green on my machine, twenty-seven errors in the
pipeline. Both were found by trying to prove the thing worked rather than
waiting for it to fail.&lt;/p&gt;
&lt;p&gt;If you want to follow along without checking back, the feed is
&lt;a href=&quot;https://riperoute.com/feed.xml&quot;&gt;here&lt;/a&gt;, and how the site is built is on the
&lt;a href=&quot;https://riperoute.com/colophon/&quot;&gt;colophon&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>A design system, and the first pages</title><link>https://riperoute.com/changelog/#2026-08-20-design-system-and-first-pages</link><guid isPermaLink="true">https://riperoute.com/changelog/#2026-08-20-design-system-and-first-pages</guid><description>Colour, type, and layout are now defined once, and the site has a landing page, a privacy page, an about page, and this changelog.</description><pubDate>Thu, 20 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The site has a look. Warm off-white ground, rust accent, serif headlines, hard
rules instead of boxes — the reference is a field guide rather than a
dashboard.&lt;/p&gt;
&lt;p&gt;Everything visual is defined in one place, as CSS custom properties, so the
maps and charts that arrive with the tools can read the same palette instead of
keeping their own copy of it:&lt;/p&gt;
&lt;pre class=&quot;language-css&quot; data-language=&quot;css&quot;&gt;&lt;code class=&quot;language-css&quot;&gt;&lt;span class=&quot;token property&quot;&gt;--color-ivory&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;oklch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;97.8% 0.008 85&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;--color-ink&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;oklch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;23.5% 0.014 60&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token property&quot;&gt;--color-rust&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;token function&quot;&gt;oklch&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;52% 0.14 42&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every foreground and background pairing was computed against the accessibility
contrast thresholds rather than judged by eye. Dividers that mean something —
the edge of a form field, say — use a darker tone than dividers that are only
decoration, because the threshold for the two is genuinely different.&lt;/p&gt;
&lt;p&gt;One decision worth recording: the palette block deletes the framework’s default
colours outright. Writing &lt;code&gt;bg-blue-500&lt;/code&gt; now produces no style at all rather than
quietly working. It is easier to keep a design system coherent when stepping
outside it is a visible mistake.&lt;/p&gt;
&lt;h3 id=&quot;what-is-on-the-site-now&quot;&gt;What is on the site now&lt;/h3&gt;
&lt;p&gt;A landing page listing the five planned tools, marked honestly — one is being
built and four are not started. A privacy page, which was short to write because
nothing is collected. An about page. A colophon. And this.&lt;/p&gt;
&lt;h3 id=&quot;what-is-next&quot;&gt;What is next&lt;/h3&gt;
&lt;p&gt;The seasonality atlas. It is first because it is the simplest of the five,
which means the time goes into the platform rather than into the tool.&lt;/p&gt;
</content:encoded></item><item><title>The site is live</title><link>https://riperoute.com/changelog/#2026-08-19-the-site-is-live</link><guid isPermaLink="true">https://riperoute.com/changelog/#2026-08-19-the-site-is-live</guid><description>riperoute.com is serving from a deployed platform, with every release checked against the running site.</description><pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is nothing on it yet worth reading, but the part underneath is finished.
Infrastructure is defined as code, deployed by a pipeline that holds no
long-lived credentials, and every release is checked against the live site
before it counts as done.&lt;/p&gt;
&lt;p&gt;That last part is the piece I care about. A deploy that reports success is not
the same as a system that works, so each release now makes a set of assertions
against the running site — that the page loads, that an unknown path serves the
real error page rather than a generic one, that &lt;code&gt;www&lt;/code&gt; redirects to the apex,
that the security headers survived, and that the stylesheet the page references
is actually reachable.&lt;/p&gt;
&lt;p&gt;Every one of those checks was tested against a deliberately broken version
first. A check that has never been seen to fail is not a check.&lt;/p&gt;
</content:encoded></item></channel></rss>