{"blyg":"0.3","id":"5b1m5zwte5yjpa7e410fkpsyq8","kind":"thread","origin":"https://blyg.blygger.org/","page":"t/5b1m5zwte5yjpa7e410fkpsyq8/","author":{"name":"Venkatesh Rao","url":"https://blyg.blygger.org/"},"created":"2026-10-07T20:03:10Z","updated":"2026-10-07T20:03:10Z","version":1,"content_md":"\n# TN-1 — Versioning stays a bare counter: semver, editions, and the pin pattern\n\n**Technical note · non-normative · session 12, 2026-08-10 (Fable + Venkat).\nDecision record for locked decision #19.** Technical notes record design\nreasoning — especially rejected designs — alongside the normative spec; they\nconstrain nothing and are citable rationale, not protocol.\n\n## 1. The question\n\nItem versions are a bare integer counter: `version` increments by exactly 1\nper publish event (spec §5.2). Venkat proposed switching to semantic\nversioning so that version structure could carry an author-asserted\nsignificance signal — the motivating use case being client-side auto-pinning\nheuristics (\"a node might declare a rule that every major version change be\nauto-pinned\"), with the auto-pinning logic itself explicitly outside protocol\nscope.\n\nThe underlying need is real: a machine-readable way for an author to mark a\npublish event as *significant*, which client features can key off. The\nquestion is whether version structure is the right carrier. Two designs were\nconsidered and both rejected; the reasoning is worth keeping because the\nquestion will recur.\n\n## 2. Why not semantic versioning\n\nThree independent arguments, each sufficient:\n\n1. **The counter's rigidity is load-bearing.** \"Increments by exactly 1\"\n   means a version number alone tells an importer exactly how many publish\n   events it missed, and any decrease is unambiguously a history rewrite —\n   the no-silent-regression watermark (decision #18) leans directly on this.\n   Under semver, \"+1 exactly\" becomes \"some component incremented\": is\n   2.3 → 4.0 a gap? Is 2.0 → 1.9.1 a regression or intent? Every comparison\n   becomes structured parsing, and origin violations stop being crisply\n   detectable.\n2. **The counter is wire-permanent surface.** It rides in the GUID scheme\n   (`blyg:{id}:v{n}`), pin URLs (`items/{id}/v{n}.json`), `transclusions`\n   provenance, and the reserved `![[id@vN]]` and `forked_from` shapes\n   (decisions #14/#16). With two live nodes deployed, restructuring it is\n   the protocol's first breaking wire migration — a cost that only grows.\n3. **Semver encodes the wrong semantics.** Its parts are API compatibility\n   claims — patch-vs-minor is a statement about callers not breaking. Prose\n   has no callers. Whatever significance structure writing has, it is not\n   three-valued compatibility.\n\n## 3. The edition counter-proposal (recorded, also rejected)\n\nAn intermediate design was drafted: keep `version` untouched and add an\noptional author-asserted `\"edition\"` integer (default 1, monotonically\nnon-decreasing, bumped as a deliberate publish-time act). Publishing-native\n(\"second edition\"), additive, zero wire breakage; auto-pin heuristics key off\nedition bumps; a semver-looking display (`{edition}.{rev}`) derivable as pure\npresentation.\n\nRejected by Venkat — not on cost grounds (the cost is near zero) but on\ndesign-intent grounds, which is the actual content of this note:\n\n## 4. The pin pattern is the significance primitive\n\nThe protocol already has a construct for \"this state of this work matters\":\nthe **pin** — an irrevocable promise to serve one exact version forever\n(spec §8). The design intent is that publishers think *consciously in pins*,\nand a parallel significance lane would obscure that:\n\n- **An edition bump is cheap talk; a pin is a costly signal.** Marking a\n  version \"major\" costs nothing and promises nothing. A pin costs an\n  irrevocable hosting commitment. The protocol prefers the significance\n  signal an author must back with a promise — that asymmetry is what makes\n  the signal honest, and it would be exactly the asymmetry a free-floating\n  significance field lets authors route around.\n- **Version-structure significance is publishing skeuomorphism.** Editions\n  and major versions are conventions imported from books and software —\n  cosmetic structure over what is, in this medium, a single living stream of\n  states with deliberate frozen citations. The medium's own native gesture\n  is the pin; dressing the stream up in edition numbers teaches publishers\n  the wrong mental model.\n- **The motivating feature doesn't need the field.** \"Auto-pin on major\n  bump\" dissolves into pin-suggestion UX: a studio may prompt, nudge, batch,\n  or apply any local rule it likes for *proposing* pins — studio sugar, zero\n  protocol bytes. This is the standing pattern's next application: AI,\n  identity, and editorial convenience are never in the protocol; neither is\n  significance markup. What reaches the wire is the pin itself.\n\nHuman-readable significance keeps its existing home: the changelog `note`\n(free text, per publish event). Machine-readable significance *is* the pin.\n\n## 5. What stands\n\n- `version` remains a bare positive integer, +1 per publish event — the\n  protocol's ordering primitive, unchanged everywhere it appears.\n- No semver, no edition field, no significance markup on the wire, at any\n  level. This is locked decision #19; relitigating it starts from this note.\n- Clients remain free to build any pinning convenience (prompts, local\n  rules, batch review) on studio-side state — the protocol surface they\n  produce is ordinary deliberate pins.\n\n\n\n*This note's canonical text is at [blygger.org/notes/tn-1/](https://blygger.org/notes/tn-1/), and its source is [`docs/notes/tn-1-versioning-and-pins.md`](https://github.com/blygger/blygger-spec/blob/main/docs/notes/tn-1-versioning-and-pins.md) in blygger-spec. The page there is what the spec cites. To comment, respond to this item from your own blyg.*\n\n","content_html":"<div class=\"blyg-tk-gen\"><h1>TN-1 — Versioning stays a bare counter: semver, editions, and the pin pattern</h1>\n<p><strong>Technical note · non-normative · session 12, 2026-08-10 (Fable + Venkat).\nDecision record for locked decision #19.</strong> Technical notes record design\nreasoning — especially rejected designs — alongside the normative spec; they\nconstrain nothing and are citable rationale, not protocol.</p>\n<h2>1. The question</h2>\n<p>Item versions are a bare integer counter: <code>version</code> increments by exactly 1\nper publish event (spec §5.2). Venkat proposed switching to semantic\nversioning so that version structure could carry an author-asserted\nsignificance signal — the motivating use case being client-side auto-pinning\nheuristics (&quot;a node might declare a rule that every major version change be\nauto-pinned&quot;), with the auto-pinning logic itself explicitly outside protocol\nscope.</p>\n<p>The underlying need is real: a machine-readable way for an author to mark a\npublish event as <em>significant</em>, which client features can key off. The\nquestion is whether version structure is the right carrier. Two designs were\nconsidered and both rejected; the reasoning is worth keeping because the\nquestion will recur.</p>\n<h2>2. Why not semantic versioning</h2>\n<p>Three independent arguments, each sufficient:</p>\n<ol>\n<li><strong>The counter's rigidity is load-bearing.</strong> &quot;Increments by exactly 1&quot;\nmeans a version number alone tells an importer exactly how many publish\nevents it missed, and any decrease is unambiguously a history rewrite —\nthe no-silent-regression watermark (decision #18) leans directly on this.\nUnder semver, &quot;+1 exactly&quot; becomes &quot;some component incremented&quot;: is\n2.3 → 4.0 a gap? Is 2.0 → 1.9.1 a regression or intent? Every comparison\nbecomes structured parsing, and origin violations stop being crisply\ndetectable.</li>\n<li><strong>The counter is wire-permanent surface.</strong> It rides in the GUID scheme\n(<code>blyg:{id}:v{n}</code>), pin URLs (<code>items/{id}/v{n}.json</code>), <code>transclusions</code>\nprovenance, and the reserved <code>![[id@vN]]</code> and <code>forked_from</code> shapes\n(decisions #14/#16). With two live nodes deployed, restructuring it is\nthe protocol's first breaking wire migration — a cost that only grows.</li>\n<li><strong>Semver encodes the wrong semantics.</strong> Its parts are API compatibility\nclaims — patch-vs-minor is a statement about callers not breaking. Prose\nhas no callers. Whatever significance structure writing has, it is not\nthree-valued compatibility.</li>\n</ol>\n<h2>3. The edition counter-proposal (recorded, also rejected)</h2>\n<p>An intermediate design was drafted: keep <code>version</code> untouched and add an\noptional author-asserted <code>&quot;edition&quot;</code> integer (default 1, monotonically\nnon-decreasing, bumped as a deliberate publish-time act). Publishing-native\n(&quot;second edition&quot;), additive, zero wire breakage; auto-pin heuristics key off\nedition bumps; a semver-looking display (<code>{edition}.{rev}</code>) derivable as pure\npresentation.</p>\n<p>Rejected by Venkat — not on cost grounds (the cost is near zero) but on\ndesign-intent grounds, which is the actual content of this note:</p>\n<h2>4. The pin pattern is the significance primitive</h2>\n<p>The protocol already has a construct for &quot;this state of this work matters&quot;:\nthe <strong>pin</strong> — an irrevocable promise to serve one exact version forever\n(spec §8). The design intent is that publishers think <em>consciously in pins</em>,\nand a parallel significance lane would obscure that:</p>\n<ul>\n<li><strong>An edition bump is cheap talk; a pin is a costly signal.</strong> Marking a\nversion &quot;major&quot; costs nothing and promises nothing. A pin costs an\nirrevocable hosting commitment. The protocol prefers the significance\nsignal an author must back with a promise — that asymmetry is what makes\nthe signal honest, and it would be exactly the asymmetry a free-floating\nsignificance field lets authors route around.</li>\n<li><strong>Version-structure significance is publishing skeuomorphism.</strong> Editions\nand major versions are conventions imported from books and software —\ncosmetic structure over what is, in this medium, a single living stream of\nstates with deliberate frozen citations. The medium's own native gesture\nis the pin; dressing the stream up in edition numbers teaches publishers\nthe wrong mental model.</li>\n<li><strong>The motivating feature doesn't need the field.</strong> &quot;Auto-pin on major\nbump&quot; dissolves into pin-suggestion UX: a studio may prompt, nudge, batch,\nor apply any local rule it likes for <em>proposing</em> pins — studio sugar, zero\nprotocol bytes. This is the standing pattern's next application: AI,\nidentity, and editorial convenience are never in the protocol; neither is\nsignificance markup. What reaches the wire is the pin itself.</li>\n</ul>\n<p>Human-readable significance keeps its existing home: the changelog <code>note</code>\n(free text, per publish event). Machine-readable significance <em>is</em> the pin.</p>\n<h2>5. What stands</h2>\n<ul>\n<li><code>version</code> remains a bare positive integer, +1 per publish event — the\nprotocol's ordering primitive, unchanged everywhere it appears.</li>\n<li>No semver, no edition field, no significance markup on the wire, at any\nlevel. This is locked decision #19; relitigating it starts from this note.</li>\n<li>Clients remain free to build any pinning convenience (prompts, local\nrules, batch review) on studio-side state — the protocol surface they\nproduce is ordinary deliberate pins.</li>\n</ul>\n</div>\n<p><span class=\"blyg-tk-gen\">\n<em>This note's canonical text is at <a href=\"https://blygger.org/notes/tn-1/\">blygger.org/notes/tn-1/</a>, and its source is <a href=\"https://github.com/blygger/blygger-spec/blob/main/docs/notes/tn-1-versioning-and-pins.md\"><code>docs/notes/tn-1-versioning-and-pins.md</code></a> in blygger-spec. The page there is what the spec cites. To comment, respond to this item from your own blyg.</em>\n</span></p>\n","content_hash":"sha256:52121138322c120d7a219595bf8984c8987180ce8e3ed6c85f39c7bf69ab025a","media":[],"transclusions":[],"generated":[{"sources":[],"model":"claude-fable-5"},{"sources":[],"model":"claude-opus-5-5"}],"changelog":[{"version":1,"at":"2026-10-07T20:03:10Z","note":"Ported from blygger.org/notes/tn-1/ (decision #66); the canonical text stays there."}]}