site: canonical forms essay, landing section VI, repositioning, mobile scroll fixes - #18
Merged
Merged
Conversation
An interactive explainer for what spiritwriter's fabric.orbit does and
why it exists: rotations, reflections and reorderings make one structure
look like many, and computing a single canonical form settles them
exactly where a similarity threshold cannot.
Standalone full document rendered like landing.html rather than
extending base.html — the news masthead ("Daily Bias Index · N
articles") would be wrong over an essay, and nginx already serves
spiritwriter.ai separately from news.spiritwriter.ai. Takes base_ctx
only for the footer signature row, so the page states the spiritwriter
version it is describing and the commit it was built from.
The interactive parts are computed in the browser except the scorer
output, which is precomputed from spiritwriter's own fuzzy_score for
all 120 arrangements of the ring rather than reimplemented in
JavaScript — a reimplementation could drift from what the harness
measured, and the page's whole argument is that the measurement is
real. The figures come from spiritwriter's structural-accuracy harness:
200 pairs, rule settles 114/114 with no wrong merges, best similarity
cutoff that makes no wrong merges catches none.
Tests cover both what Jinja could break and what a bad build could
strip: the precomputed table surviving autoescape intact, the essay
staying a complete document rather than a base.html fragment, the
signature row wiring to a live version and commit, and degrading
without advertising a stale stand-in version when neither resolves.
Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01RyrQHRdQXXsfTbKvRnxKjA
"Constellations" named the opening image, not the argument, and it worked against the thesis: a constellation is the canonical example of an arbitrary figure — different cultures drew different shapes on the same stars — while the piece closes on there being only one form to arrive at. The new name states the fork the essay actually turns on: compute an identifier or register one. Template, output path, canonical and social URLs all move to computed-not-assigned.html. Nothing linked to the old path yet, so no redirect is needed. The page now also links back to the library, the canonical-forms guide, and the harness the two hundred pairs come from. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RyrQHRdQXXsfTbKvRnxKjA
The landing page argued the fuzzy half of identity and never mentioned the exact one. Section V is titled "We measured it. We tried to break it" and then measures entity resolution only; II, III and IV never mention canonical forms at all. A link tucked into V would have smuggled in a second pillar as a footnote to the first. It also belongs here on the page's own terms. The spine running through it is no service, no custody, no rent — and canonical forms is the purest case of that at the identity layer: two systems that never communicated agree, with no authority in between. Reuses V's bear / bear-prose / bear-aside / num-fact components, so no new CSS. Displaces "What it ends" to VII. Nav gains an Exact entry, and the footer Specs list gains canonical-forms.md, which was orphaned from the site entirely. The two measurements are deliberately kept apart: V's 100% auto-merge precision comes from the resolution suite, VI's 114/114 from the structural one, and the aside says so in as many words. They measure different problems and must not be read as one combined claim. Tests pin the essay link, the section, its nav anchor, contiguous numbering I–VII, and that the two results stay separated — a landing edit that drops the link would otherwise silently orphan a published page. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RyrQHRdQXXsfTbKvRnxKjA
The landing page had horizontal scroll at every width below ~768px. Five causes, four of them the same underlying mistake. A `1fr` grid track carries an automatic min-content floor, so the widest unbreakable child sets a width the column can never go below and the page grows to fit it. `.hero`, `.hero-grid` and `.code-spread` all used bare `1fr`; they now use `minmax(0, 1fr)`, and `.hero h1` and `.code-block` — both grid items — get an explicit `min-width: 0`. `.code-block` already had `overflow-x: auto`, which had simply never been able to engage. The other two are unwrapped flex rows: the topbar's imprint cluster, which overflowed between 520 and 768 where neither existing hide-rule had kicked in, and the install button, whose parts are individually nowrap. Both wrap now rather than relying on hand-tuned breakpoints, and the hero headline drops to 9.5vw below 520 where 11vw makes the longest word wider than its column. Desktop sizing is untouched. Verified at 1400 / 1200 / 900 / 768 / 520 / 414 / 390 / 360 / 320: the page no longer scrolls sideways at any of them. What still reports as overflowing is the code sample inside its own scroll container, which is the intended behaviour. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RyrQHRdQXXsfTbKvRnxKjA
"Agent memory you own" sells the storage and buries the reason to trust it, in a category that is crowded and that this library is not actually competing in. What is distinctive is not that it remembers — plenty of things remember — but that everything it holds can be checked, and nothing it holds can be quietly altered. That thread already runs through every primitive and was simply never named: shards are content-addressed, traces are hash-chained and signable, entitlements are signed capability chains, audit produces witness bundles, and canonical forms give identity computed rather than registered. Section VI landing so cleanly beside the resolution numbers was the tell — canonical forms is a poor fit for "memory you own" and an obvious one for "a record you can verify". Headline, lede, title, social metadata, topbar imprint and closing lockup move accordingly. Memory stays in the lede as one of the things it does rather than as the category it belongs to. Copy only — every claim is one the repository already supports, and no section bodies, numbers or proof points changed. The hero headline is longer than the one it replaces, so the mobile sweep was re-run: still no horizontal scroll at 1400 through 320. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RyrQHRdQXXsfTbKvRnxKjA
The hero now promises a record you can verify, and the argument underneath it still opened with storage. Both sections were written before the reposition and the seam showed. Section I already asked the right question — "can you prove what actually happened?" — but asked it third, after memory and delegation, as the weakest-sounding of three. It now leads, and the section closes on the real indictment: the hardest question gets answered by logs the system wrote about itself, and that layer is taken on faith. The lede ties the two ideas together, since the part everyone skips when re-gluing this layer is precisely the part that would let them prove anything. Section II listed the primitives without ever saying what they have in common, which is the whole argument: each produces something that can be checked independently, without taking the system's word for it. It also had no entry for canonical forms at all — a gap that predates this branch's section VI and would have read as an omission the moment VI shipped. Identity is now a fifth primitive in the list and in the stack figure. Copy only. No numbers, no proof points, no structural changes, and the mobile sweep still shows no horizontal scroll from 1400 down to 320. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01RyrQHRdQXXsfTbKvRnxKjA
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Publishes an interactive explainer for spiritwriter's
fabric.orbiton spiritwriter.ai, gives it a home on the landing page, repositions that page out of the crowded "agent memory" category, and fixes the horizontal scrolling it had on phones.Companion to spiritwriter-core#89, which adds the library, the harness, and the reference docs.
The page —
/computed-not-assigned.htmlRotations, reflections and reorderings make one structure look like many. Computing a single canonical form settles them exactly, where a similarity threshold cannot. The page argues that and then demonstrates it: a drifting star field, a solid rebuilt one symmetry at a time from a single seed face, a ring you can rotate and flip while its key stays fixed, and a comparator where the rule and the score visibly disagree in both directions.
Rendered like
landing.html— a standalone full document rather than extendingbase.html, since the news masthead would be wrong over an essay, and nginx already serves spiritwriter.ai separately from news.spiritwriter.ai. It takesbase_ctxonly for a footer signature row, so the page names the spiritwriter version it describes and links the commit it was built from.The interactive parts are computed in the browser, with one deliberate exception. The similarity scores come from spiritwriter's own
fuzzy_score, precomputed for all 120 arrangements of the ring rather than reimplemented in JavaScript. A reimplementation could drift from what the harness actually measured, and the page's entire argument is that the measurement is real.Repositioning
"Agent memory you own" sold the storage and buried the reason to trust it — in a category that is crowded and that this library is not actually competing in. What's distinctive isn't that it remembers; plenty of things remember. It's that everything it holds can be checked, and nothing it holds can be quietly altered.
That thread already ran through every primitive and was simply never named:
Section VI slotting in so cleanly beside the resolution numbers was the tell: canonical forms is a poor fit for "memory you own" and an obvious one for "a record you can verify."
Hero,
<title>, social metadata, topbar imprint and closing lockup move accordingly — "A record your agents can't rewrite." Memory stays in the lede as one of the things it does, rather than as the category it belongs to.Sections I and II follow, because the hero promised verification while the argument underneath still opened with storage:
Copy only, throughout. Every claim is one the repository already supports; no numbers, proof points, or structural changes.
#proofstill rests on frio and news, untouched.Landing — new section VI
The landing page argued the fuzzy half of identity and never mentioned the exact one. Section V is titled "We measured it. We tried to break it" and then measures entity resolution only.
Reuses V's
bear/bear-prose/bear-aside/num-factcomponents, so no new CSS. "What it ends" moves to VII. Nav gains Exact; the footer Specs list gainscanonical-forms.md, which was orphaned from the site entirely.The two measurements are deliberately kept apart. V's 100% auto-merge precision is the resolution suite; VI's 114/114 is the structural one. They measure different problems, and the aside says so in as many words. A test pins that sentence so a later copy edit can't weld them into one inflated claim.
Mobile scroll fixes
The landing page scrolled sideways at every width below ~768px. Five causes, four of them the same underlying mistake.
A
1frgrid track carries an automatic min-content floor, so the widest unbreakable child sets a width the column can never go below, and the page grows to fit it..hero,.hero-gridand.code-spreadall used bare1frand now useminmax(0, 1fr);.hero h1and.code-block— both grid items — get an explicitmin-width: 0..code-blockalready hadoverflow-x: auto; it had simply never been able to engage.The other two are unwrapped flex rows: the topbar's imprint cluster, which overflowed between 520 and 768 where neither existing hide-rule had kicked in, and the install button, whose parts are individually nowrap. Both wrap now rather than depending on hand-tuned breakpoints. The hero headline drops to
9.5vwbelow 520, where11vwmakes its longest word wider than the column. Desktop sizing is untouched.Verified at 1400 / 1200 / 900 / 768 / 520 / 414 / 390 / 360 / 320 — no horizontal scroll at any of them, on either page, and re-verified after the new headline, which is longer than the one it replaced. What still reports as overflowing is the code sample inside its own scroll container, which is the intended behaviour.
Tests
Five added, aimed at what can actually break here rather than at coverage:
"01234":[1.0,1]— mangle that and the widget is wrong, not merely ugly),base.htmlfragment,Full suite: 71 passed.
Note on ordering
spiritwriter-core#89's README cites
spiritwriter.ai/computed-not-assigned.html, which 404s until this deploys. Landing this first avoids a dead link in the library README.