graphs.sgit.ai → admin → the v0.4 era
The v0.4 era
The complete log of the v0.4 era: forty-one releases from v0.4.0 (23 August 2026, the first edition frozen, the second begun empty) to v0.4.40 (26 August 2026, the identity ledger). This is the historical record of how the working surface was built, one narrated release at a time; the weighing of it is the v0.4 retrospective. Current releases live in the release history.
| Version | Date | What changed |
|---|---|---|
| v0.4.40 | 26 August 2026 | The identity ledger: IDs that survive refactoring. The founder asked whether the core graph's IDs should be random; the analysis behind this release is that randomness was never the missing ingredient, persistence was, and this ships it. Every document now keeps a committed ledger (docs/<slug>/ids.json) mapping short opaque uids — tig:d1, tig:s1…tig:s38, tig:b1…tig:b186, 225 identities for the pilot — to each node's current structural locator plus a content hash. The structural paths (sec:What This Document Is, blk:…/3) are demoted to what they honestly are, locators: human-readable, derived, free to move; the uid is the identity a cross-reference should hold. Match-then-mint carry-forward on every rebuild: same locator claims its uid first (an edit in place just updates the hash), then same content hash (a moved block's identity follows it), then fuzzy similarity of locator and text head (renamed AND edited); only what matches nothing gets a fresh uid, and whatever the document no longer has is retired, never deleted and never reused, so identity history survives. Gate 7 makes the contract executable: full coverage of every doc, section and block; unique uids; and a second carry-forward pass over the ledger's own output must change nothing, or the build dies. The full edit repertoire was verified against the algorithm before shipping: a renamed section keeps its uid, its unedited blocks follow by hash, an edited-and-renamed block carries by fuzzy match, a moved block keeps its identity, a new block mints fresh, a deleted block retires with its uid preserved forever. The uids surface everywhere the nodes do: the core index, every shard, and the inspector's record ("uid tig:b3 — the stable identity; the id above is the locator and may move"). The document folder documents its new file. And the free consequence the founder wanted IDs for in the first place: the ledger diff between two versions of a document IS change detection — untouched, edited, moved, new, retired — waiting only for a second version to exist. Methods register entry 34. Sixty-one gate-27 tests green. No book content changed. |
| v0.4.39 | 26 August 2026 | The graph gets its own page, and fits in your pocket. The founder's ask, and the proof the component claim was real: <uni-graph> is now embedded by two different pages that share nothing but the element. The new standalone page per document ({slug}.graph.html, linked beside "open the live graph" on the doc page) carries no reader, no source pane and no split layout: a 24-line generated HTML shell with the data blob, and a thin graph-page.js boot (the shell tier's whole job in under 100 lines) that mounts the same element permanently maximised over the viewport, with every capability intact — the tabbed strip, the inspector with everything-on-record, the peak board, the trail board, the core tree with its words mode, the blast-radius mini. Preferences share the reader's localStorage keys, so the graph you tuned in the reader is the graph the page opens, and a small page bar links back. And it opens properly on a phone: under 760px the right-column inspector becomes a bottom sheet that appears only while a node is selected (tap to inspect, clear to dismiss), the canvas takes the full width with no horizontal scroll, and the core tree, trail board and peak board all go full-width. The reader's own maximised view inherits the same behaviour. Verified in headless Chromium at three viewports — desktop 1600×1000, iPhone 390×844 (device scale 3, touch), iPad 820×1180 — checking canvas geometry, inspector placement (right column on iPad and desktop, bottom sheet on the phone), full-width panes, zero horizontal scroll and zero console errors, with screenshots of each shared for review. No book content changed. |
| v0.4.38 | 26 August 2026 | Words as tokens, and the transform that goes both ways. Brief 30, recorded before the founder had seen v0.4.37 in the browser, built the same day. The instruction addressed "sooner more than later" came first: the graph must be able to rebuild the document. Formatting now lives in its own graph exactly as the memo prescribes — fmt.json holds the heading lines, the gaps, and the raw markdown of every block, joined to the semantic shards by the same block IDs — and two new build gates hold the contract: gate 5 rebuilds the source markdown from the formatting graph and fails unless it is byte-identical (it is), and gate 6 re-derives every semantic block from the formatting graph alone, so the two graphs cannot drift apart because one provably generates the other. Six gates now guard the core graph. Then the token universe: the memo's insight is that an LLM tokeniser caps its vocabulary to limit the universe, but a document needs no cap, so every word form is a token with full identity. The analysis pass classifies all 951 forms — 739 content, 99 padding, 65 verb (a curated heuristic list, recorded as such), 34 code-shaped, 14 numbers — and the statistics land the memo's compression instinct precisely: 45% of the document's word use is padding, 505 forms appear exactly once, and 114 stem families group the inflections (graph/graphs, anchor/anchors). Misspelling-adjacent pairs surface by edit distance (identity/identify caught in the pilot). The attention map: a co-occurrence graph over sentences gives every form its centre of gravity — "node" travels with graph ×13, review ×12, connected ×8 — and the context-spread score answers the memo's most interesting ask, when does a word mean different things in the same document: a high count with diverse sentence neighbourhoods flags the candidates, and the pilot's top two are "node" (62×, spread 0.957) and "graph" (61×, 0.988), which are exactly the two words the founder used as examples in the memo, derived independently by arithmetic. The viewer: the core tree pane gains a words mode — the ranked token list with class styling (padding dimmed, verbs italic, code mono), the statistics line, ◊ marking the thirty different-meanings candidates — and clicking any form shows everything known about it on the right: class, count, stem family, near misses, gravity, spread. Word rows in the tree inherit the same records. Deterministic IDs restated as law (they already were, structurally); the book-scope ID registry read as the next structural step and asked back as a question. One new gate-27 vector (61 tests); verified in headless Chromium including an in-page rebuild of the document from the served formatting graph, identical to the served source. Brief 30 carries the memo verbatim with eleven instructions mapped and four questions back. No book content changed. |
| v0.4.37 | 26 August 2026 | The core graph: the document transformed all the way to the word. Brief 29, the founder's morning memo, built the same day. The experiment it asks for: stop treating the section as the floor and transform the document like an AST driven by the content, every level a node with an ID linked to its parent. The generator (gen_coregraph.py, a separate tool exactly as the memo asks): the pilot document becomes 39 sections, 186 blocks (paragraphs, bullet items, code, quotes, tables, rules), 342 sentences and 4,221 words across 951 distinct forms, with 143 markup spans. Bold is structure now: each inline span (bold, italic, code, link) is a node covering the word instances it marks, so emphasis is queryable rather than lost formatting. Every distinct word is a form node with its count and every instance, so "how many times does this word appear" is a lookup, not a search. IDs are the reference currency, the memo's sharpest point taken literally: pointing at "character 256 to 259" breaks the moment the document changes, so cross-references now have sec:, blk:, sen: and wrd: identities to hold instead, and byte ranges survive only as build-time verification metadata. Four gates prove the transform is lossless: block ranges reassemble every section body, sentences reassemble every block, form totals equal instance totals, spans cover the words they claim. The graphs-of-graphs storage answer: an index with the skeleton, one shard per section fetched only when opened, and the word index; 32 shards, 407KB total, nothing loaded until asked for. The tree view: a resizable pane on the canvas where the document expands bit by bit — section, block, sentence, word — each expansion fetching only its shard; bold words render bold; clicking any row shows its record and lights the nearest node the canvas has. The strip in two tabs, because the controls outgrew one row: canvas (views, layout, labels, physics) and content (sources, explore, view), persisted like every preference; the blast-radius mini bypasses the tabs and keeps its two groups. The inspector answers the memo's last ask: alongside statement, quote and links it now shows everything on record — every data field, the degree both ways, the extraction's extra fields — and a core-tree pick shows its level, its place in the document (the breadcrumb from the document down), its marks, and how often its form appears. Three new gate-27 vectors (60 tests); the whole flow verified in headless Chromium down to a word whose record reads "appears 56× in this document". The round also burned an hour on a lesson worth recording: a zombie headless Chromium from a crashed test run held the debug port and served stale modules to every later test on that port, making a working feature look broken; the fix was kill, not code. Brief 29 carries the memo verbatim with eleven instructions mapped and four questions back (sentence heuristics, word-ID fragility scoped to the sentence, migrating extraction anchors to core IDs, code blocks staying whole). Recorded debt: uni-graph.js is at 434 lines against the 250 budget; the split remains owed. No book content changed. |
| v0.4.36 | 25 August 2026 | Every working pack gets its rendered page, starting with the register that had none. The founder asked the right question an hour after v0.4.35 shipped: is there a doc viewer on the site for that markdown file? There was not. The immediate-connection register, the document written precisely so that agents and people would read it, served as raw markdown from a hub link, while only the second-book pack enjoyed the site's markdown reader. This release generalises gen_devpack.py from one hardcoded pack to every pack under v2/dev-packs/: the register, the pinned-nodes debrief, the universe-chat plan, and the four-note brief-and-reply thread between the two agents now each render at /v2/dev-pack/ in the established idiom, where the raw markdown stays the source of truth and every page renders its own source client-side so presentation cannot drift from it. The dev-pack hub gains a working-packs section whose table is regenerated between markers on every build, in the same manner the site chrome is, so a note added to any pack appears on the hub without anyone remembering to list it; and the registration is a gate, because a pack directory or file that arrives without a blurb fails the build by design, which keeps the judgement column authored rather than scraped. The universe hub's for-an-agent pointer now opens the rendered register page instead of the raw file, with the markdown one click away as everywhere else. Seven new pages, seventeen in the section, sitemap grown accordingly. No book content changed; no viewer behaviour changed. |
| v0.4.35 | 25 August 2026 | The immediate-connection register: the experience target, written down for every agent that follows. The founder named Bret Victor's "Inventing on Principle" as the experience and feedback loops this whole viewer effort is aiming at, and on inspection half of the viewer's strongest features turned out to be unknowing implementations of that talk's demos. This release captures the agreement so it stops being luck: a standing design document at v2/dev-packs/design__immediate-connection/00__the-victor-register.md, addressed to every agent and session working on this repo's viewers and tools. It states the principle (creators need an immediate connection to what they create) composed with this project's own stability rule from brief 26 (every unasked-for node move costs the viewer their mental picture): every action answers instantly, and nothing moves that the viewer did not ask to move, because an immediate response that scrambles the map is just noise arriving quickly. It maps Victor's five demo patterns to the releases that already implement them: scrub-a-value (the per-frame physics sliders, the degree stepper, the peak board), show-the-future (the next-hop pricing in the stats bar, the trail board's project-forward), show-the-data (the state pane, the inspector, the live stats), behaviour-on-the-thing (the live schema view, the recounting legend), and perform-don't-configure (dragging a pinned summit, walking the graph as writing the query). It names the gaps honestly and fully specifies the two most buildable ones so any agent can pick them up: view time travel (a ring of view snapshots with a scrubber, restored under stable-add rules so the rewind itself does not scramble the map, doubling the narrated-review loop's value) and relayout ghosts (on an explicit full re-arrangement, each node's previous position persists briefly as a fading ghost with a wisp to its new home, so even a sanctioned redraw preserves the mental map in transition). It closes with the six-point checklist every change to an interactive surface should pass: immediate, stable, visible, projectable, direct, modular. Discovery is wired in: the universe hub's for-an-agent paragraph now points to the register, and the methods register carries it as its thirty-first entry, because design taste captured as patterns plus a checklist is a method like any other. No book content changed; no viewer behaviour changed. |
| v0.4.34 | 25 August 2026 | The path query arrives: walked, edited, run, and projected forward. Brief 28's three answers, all built. The runner (core/pathquery.js, pure, gate-27-tested): a query is the sequence of steps a trail recorded, each naming the verb followed and constraining the node it lands on, exactly or by family; displayed inverse verbs resolve back to their stored direction through the verbs register, so a walk that followed "subject-of" correctly traverses the about edges backwards; a runaway wildcard truncates at five hundred paths instead of hanging. The trail board, in the peak board's idiom exactly as the founder asked: steps as chips, × removes, drag reorders, and clicking a chip toggles this-exact-node ↔ any-node-of-its-family, the generalisation that turns one walk into a reusable question. Run lights every matched path on the canvas in teal (distinct from the gold paths-to-peaks) and lists the matches, each clickable. Project forward, the founder's most-important-feature: the board lists every verb that could extend the path from its current end, computed from the graph itself, and clicking one appends a speculative hop and runs it, showing what the future path would match before it is walked. Save keeps named queries per document. The blast-radius mini graph: a second <uni-graph mini>, the same web component with features disabled per the founder's reuse rule, mounted in the inspector, permanently in explore mode so it always renders the selection's neighbourhood, with the strip's layout and explore groups as its own options pane and the degree stepper as its zoom; taps in it select everywhere; its preferences never touch the main graph's. And the aside answered: the peak board was not resizable; both boards now are. Verified end to end in headless Chromium: the mini's six-of-fifty-seven neighbourhood, exact and wildcard runs, teal lighting, fifteen projected verbs, the appended speculative hop, saved-query persistence. The unit suite is at fifty-seven. Brief 28 carries the answers verbatim. Recorded deviation, now a debt: uni-graph.js has grown to 414 lines against the 250 budget across the last four rounds; the next quiet release owes it the v0.4.13 treatment (routing and accessors out to parts) exactly as the reader's own precedent and the brief to the chat agent prescribe. No book content changed. |
| v0.4.33 | 25 August 2026 | Click a node and see its universe: the links panel, the reverse verbs, and the path trail. Brief 28, the founder's memo on node navigation, with the scale framing that motivates it: the node count will grow near-exponentially as documents join, so navigation has to work from any node outward, not from the whole graph inward. The links panel: tapping a node in the maximised view now lists, under its statement and anchored quote, every link out with its stored verb and every link in read through the declared inverse from the verbs register, so from B the A→B relation reads as B's own viewpoint (about becomes subject-of, contains becomes part-of), every row in English exactly as the memo demands, colour-coded by the other node's family and clickable. The path trail: following a link row hops the selection and appends the step to a trail at the top of the inspector ("meaning through connectivity -departs-from→ schema-first"), a fresh tap starts a new trail, and clear resets: hop-by-hop navigation IS building the path query, recorded as it grows. The two pane bugs fixed where the memo pointed: the maximised canvas insets now exclude the inspector's width, and opening the peak board shifts the canvas beside it and refits, so every pin is visible in one go while the board works; closing restores. Verified end to end in headless Chromium: the inset arithmetic, five link rows on the pilot's central concept with departs-from out and subject-of in, the trail building and clearing, the selection following each hop, the board shift and restore. Brief 28 carries the memo verbatim with ten instructions mapped and three questions back (the subgraph panel, saved path queries in the document folder, drag-and-drop query building). No book content changed. |
| v0.4.32 | 25 August 2026 | The state pane: the page broadcasts its state into the pixels a recording captures. The founder's follow-on to the narrated review, built as proposed: the recorder has no programmatic access to the page, so the page carries the diagnostics itself. Bottom right, off by default (it exists for narrations and debug sessions), enabled by #debug on the URL or the reader options popover: the site version, document and hash, a running clock that joins each screenshot to the recording's own timeline, the current selection, layout and look, the sources that are on, the explore state and hidden edge kinds, the visible counts, and the last action taken ("last: gpeaks→1", "select connectivity"), the line that disambiguates "this" and "here" in a narration. Short high-contrast monospace lines, written for OCR and vision models as much as for eyes. The same truth is published as window.__uniState(), so a tool that does gain programmatic access reads exactly what the pixels say. Verified in headless Chromium: hidden by default, enabled by the hash, the version and slug on the first line, actions and selections landing live. Brief 27 records the follow-on verbatim, with the suggested tool-side half: the review tool's cleanup model transcribing the pane into a per-moment state field. No book content changed. |
| v0.4.31 | 25 August 2026 | The narrated review lands: six findings, each fixed where its screenshot pointed. The founder's first review made with the narrated-review tool (ten screen captures, the words spoken over them, exported with the words joined to the pixels), recorded verbatim as brief 27 with every finding connected to its screen. The real bug it caught (moment 7): the alignment rails' invisible ties had joined the explore walk, so with align on every section was reachable in two hops and "focus on selection" kept everything, faintly; the rails and their ties are now excluded from the explore walk, the stats bar and the legend, being layout physics rather than content, and focus on selection empties the canvas down to the neighbourhood it names (verified: seven nodes of ninety-eight). The legend became a control surface (moment 6): every node-type row toggles its family (extraction families through the shared kinds, mirrored in the source pane; synthetic families through their source), and every edge-type row hides and shows that relation, with a hidden relation keeping its row so the way back stays. The peak board docks (moments 8 and 9): a compact lower-left panel instead of a canvas-covering overlay, so the graph visibly re-anchors as each peak is dragged, which was the point. The live graph is one click away (moment 2): #graph on a document page lands straight in the maximised view, and the static drawing's caption, the very screen the founder mistook for a PDF, now links there. All verified in headless Chromium, the stability regression re-run green. The review bundle's own design is noted in the brief: words tied to the evidence they were said about, raw text kept beside corrections, uncertainty flagged rather than resolved silently, the same discipline as the universe's anchors. No book content changed. |
| v0.4.30 | 24 August 2026 | The families get their rows, and the schema becomes a subset instrument. The founder's follow-on to brief 26, both halves. Family rails: with family peaks and align on together, every node family gets its own invisible rail and settles onto its own row, the dictionary above the claims above the examples, so the pyramids read like a chart of floors; the same mechanism as the level rails turned sideways, the same reveal toggle, verified live (each family's row spread is a fraction of the canvas and the rows stack in order). The doc tree is no longer forced on when the family rails are what align is for, and hierarchy layouts now exclude the rails and their ties so a breadthfirst tree cannot mistake the physics for structure. The schema over any subset: the schema view is rebuilt from whatever sources are on at the moment it opens, and re-derives live as sources toggle, so the source buttons are its subset selector: document only gives the pure semantic core; adding the doc tree brings the section types and their containment; adding peaks and derived brings the synthetic layers. The full schema of the pilot shows nine node types and twenty-four typed relations, every label carrying both directions, with section (38) the containment hub and concept (22) the semantic sink where about ⇄ subject-of ×40, all seven asserted verbs and derived ×13 converge; the rails are correctly absent, being layout physics rather than semantics. The unit suite is at fifty-two; the round's interaction suite covers the rows forming, their order, the live subset behaviour and the clean exit. Brief 26 records the follow-on verbatim. No book content changed. |
| v0.4.29 | 24 August 2026 | The founder's four answers, applied: seven slots, the invisible rails, and the verbs register. Brief 26's questions came back answered and each answer shipped. Seven slots per area on the peak board, one constant changed. The alignment rails: the new align source (which brings the doc tree with it) adds one invisible rail per heading level, locked in its own column, with every section tied to its rail by a short invisible edge whose ideal length stays short whatever the physics sliders say, so the force field pulls each level onto its own line and the document reads as a left-rooted tree; verified live, the level-2 sections settle within a couple of hundred units of their rail instead of scattering across the canvas. The align lines toggle reveals and hides the rails and their ties, per the founder's answer; hidden or shown, they are always doing the pulling, and they stay locked through stable-add runs so the alignment survives adding and removing sources. Peaks-of-peaks is recorded in the brief as a confirmed direction, to be built when a summit family first grows too crowded to read. The verbs register, the first go the founder chose: v2/universe/verbs.json declares the unique inverse of every asserted verb, the structural relations (about ⇄ subject-of, demonstrates ⇄ demonstrated-by, contains ⇄ part-of) and the symmetric ones (derived), and the build now fails on a verb the register does not carry, on two verbs sharing an inverse, or on an undeclared self-inverse. The schema view labels every relation with both directions (about ⇄ subject-of ×40, enables ⇄ enabled-by ×2), which is the review surface for improving the first-go names, exactly as the founder answered. The unit suite is at fifty; the round's interaction suite and the stability regression run green. Brief 26 carries the answers verbatim in an addendum. No book content changed. |
| v0.4.28 | 24 August 2026 | The graph holds still, the peaks get a geography, and the schema judges the whole thing. Brief 26, the founder's memo on fixed nodes, built as add-on modules exactly as it instructs. Stable add, on by default: every node move costs the reader their mental picture, so removals now move nothing, and additions freeze every node already on canvas, seed each newcomer beside an already-placed neighbour, settle only the newcomers in the force field, and unlock; the viewport holds too, because no layout may re-fit unless the reader explicitly asked (a layout button, the sliders, a preset still re-arrange everything, since asking is not a context switch). The four areas and the peak board: the canvas border divides into four rectangles with six aligned slots each, and a dedicated pop-up board shows only the peaks, colour-coded by summit type, draggable between areas and slots (tap-tap works too), swap on collision, a tray for unplaced peaks, reset to defaults; every change re-anchors the graph immediately and persists per document. The maximised inspector: tap a node in the maximised view and its details appear on the right in the node-document style, the family chip, the statement, the support state and the anchored quote, above a live legend of every node type and edge type in view. The schema view: a sources toggle that shows just the types, one node per family with its member count, one edge per typed relation with its verb and occurrence count; on the pilot it immediately shows claims reaching concepts through one relation used forty times while concept-to-concept runs through seven verbs used once or twice, which is the refactor conversation the memo asked the view to start. The unit suite grew to forty-seven (slot geometry, schema aggregation); the interaction suite verifies stability under add, remove and viewport, the exclusive schema view, the inspector and the board end to end, and both prior graph suites re-run green. The brief carries the memo verbatim with nine instructions mapped and four questions back (slot count, peaks-of-peaks, the invisible alignment lines, one-direction-per-relation enforcement). Three methods entered the register. Merged over the chat agent's v0.4.25 to v0.4.27 (the pin_nodes rebind, the iPad round, the close-button fix). No book content changed. |
| v0.4.27 | 24 August 2026 | The close button now says so. The founder asked how to close the chat panel — which means the bare ✕ among nine header buttons did not read as "close the panel" on a wrapped iPad header. It is now labelled ✕ close, visually set apart with its own hover, its tooltip says what happens (the 💬 button brings the panel back), and Escape closes the panel from anywhere except inside an input, where Escape belongs to the field. Three new suite checks: the label, the click, and the Escape path. 60 checks green. No book content changed. |
| v0.4.26 | 24 August 2026 | The iPad round: the founder's first live session found the two things headless Chromium never would. First real use of the chat with a live OpenRouter key surfaced (1) the request details could not be hidden — the family's sg-llm-stats has no compact mode, so its full panel (pre-send estimate, last request, session totals, streaming toggle) blew the footer up to half the screen and left the transcript squeezed above dead space; and (2) the panel could not be resized by touch — an 8-pixel grip with no touch-action, so Safari took the drag as a scroll. Both fixed: the stats live in a collapsed-by-default usage drawer behind a footer toggle (capped height, scrollable), the footer is back to one strip; the grip is a 22-pixel touch target with touch-action: none and a visible handle, and its setPointerCapture is hardened against invalid pointer ids. The suite grew seven checks that would have caught both: usage hidden by default, the footer under 60 pixels, the toggle round-trip, the capped drawer, the grip's width and touch-action, and a synthetic touch drag that must actually widen the panel. 58 checks green, the 13-check vault round-trip and 43-test unit suite re-run. No book content changed. |
| v0.4.25 | 24 August 2026 | pin_nodes joins the one layout pipeline: the model's arrangement now survives the founder's next touch. The reader agent's follow-up verified v0.4.22 and v0.4.23 and found one real defect: the API's custom pins were locked only for their own layout run, so any later layout — a physics nudge, a source toggle, a preset — scrambled what the model had just built. The reader shipped the shared surface at v0.4.24 (uni-graph.setCustomPins, held through every runLayout); this release rebinds pin_nodes to it: the hand-rolled cose run, the direct locks and the duplicated slider reads are gone, reset_view clears custom pins through the same surface, and the user's chosen layout, tree roots and fit convention now all apply to pinned runs because one pipeline does the work. The regression is a permanent check in the chat's interaction suite — pin two stacks, nudge a slider, assert the stacks held — which fails on the old binding and passes on the new. The reply is filed beside the follow-up; the vault and persona drawer extraction is queued for the next quiet release, as suggested. Verified: the 51-check chat suite, the 43-test unit suite. No book content changed. |
| v0.4.24 | 24 August 2026 | Custom pins join the one layout pipeline, and the chat agent's execution is verified. The reader agent pulled v0.4.22 and v0.4.23, re-ran the 43-test suite green, confirmed the reader's files untouched across both releases, and found one real gap: the page API's pin_nodes locked its nodes only for its own layout run, so the founder's next slider nudge or source toggle scrambled the arrangement the model had just built (the strip's own pin peaks never had this problem because runLayout re-locks its summits on every run). The fix lands on the reader's side of the fence: uni-graph.setCustomPins(left, right) is a public surface consumed by every layout run, placing the stacks once via the tested pinPositions and holding them locked through whatever triggers a relayout, hand-draggable between runs, dragged spots respected, the user's chosen layout and tree roots applying because it is the one runLayout doing the work; custom pins replace summit pinning while set and clear back to it. Verified in headless Chromium: pins hold their stacks through a slider relayout and a source toggle, unlock after, clear cleanly, and the strip's pin peaks still works. The follow-up note at 02__follow-up-from-the-reader-agent.md records the verification and asks the chat agent to rebind pin_nodes to the new surface, dropping its hand-rolled cose run. Recorded deviation: uni-graph.js runs 257 lines against the 250 budget after the addition. No book content changed. |
| v0.4.23 | 24 August 2026 | The reader agent's brief, executed in full: the model can now see, pin, walk and listen for the pointing finger — and the chat's engine moved into its own parts. The founder's "go" on the v0.4.21 brief, all three batches. The visible-power pair: graph_snapshot returns the canvas as a PNG and the chat's loop attaches it as a user-turn image (providers accept image parts on user turns only, the wrinkle the reply flagged), so the model sees the layout it just made before describing it; pin_nodes pins arbitrary left/right stacks via the tested pinPositions, locked for the layout run, unlocked for hand-dragging — brief 25's judgement loop driven by language. The conversational reader: get_recent_activity gives the model the page's interaction ledger from a ring buffer in the adapter (a graph tap or source-mark click is the user's own pointing, so "why is this claim only argued?" while clicking works, the independence contract intact); plus scroll_to_heading, step_anchor (the audit walk), maximize_graph, reset_view (recovery without a reload), price_next_hop, get_lexicon and get_usage_model. The page API is now 44 commands. The quality pass, zero visible change: chat.js split per the guidelines into chat-markup.js (the panel's markup, inline styles into the stylesheet), tool-loop.js (the agentic engine, readable in isolation) and pure chat-core.js — the grounding prompt now composed by a gate-27-tested function with a known-answer vector, so an edit that quietly drops the claims section fails the build; one delegated header handler; the duplicate error listeners merged. Recorded deviation, per the reader's own precedent: the shell still runs 739 lines against the 250 budget. The busy-wait the brief called an honest workaround is now also briefed upstream. Verified: the 50-check chat suite and 13-check vault round-trip re-run green after the split, the 43-test unit suite, snapshot-as-image proven in the loop. No book content changed. |
| v0.4.22 | 24 August 2026 | The persona round: one document, many readers, and the feedback ledger the personalised book grows from. The founder's memo of 24 August, round three. A persona is an angle applied to every answer — a role, a language, a level — and it lives where the memo put it: in the vault, at /personas/<slug>/persona.json, where the founder, an agent in a cloud session, or a pipeline holding the key can tune existing personas or author new ones, and the chat picks them up. Five built-ins seed the list (the engineer, the CISO, the sceptic, plain English, português — the founder's own translate-keeping-facts-identical example); a drawer edits or creates more, for the session or into the vault. The active persona reshapes the grounding prompt, is recorded in each saved session's meta, and is named in the footer. Two new model tools make the views first-class: save_view writes a persona-targeted rewrite, summary, translation or projection to /personas/<p>/views/<doc>/, and record_feedback files the user's reaction (right, wrong, unclear, note — with their reasoning) beside the view it judges — the two-way dialogue the memo called the game-changer, stored where the next generation of the view is built from. Also this release, from the reader agent's brief (v0.4.21), the nearly-free slice: three new read commands on the page API — compose_node_doc (the full composed record of one node, per brief 24), rank_nodes (richness-ranked, the gap-finding conversation) and search — with a written reply accepting the rest in sequence for the founder's green light. Verified: thirteen vault checks (persona authored, prompt reshaped, view saved, feedback filed, all surviving a reload), the 39-check chat suite, the 39-test unit suite. No book content changed. |
| v0.4.21 | 24 August 2026 | A brief from one agent to the other: the chat's next power-ups. Founder-commissioned, written by the reader's agent to the chat's agent, at v2/dev-packs/v0.4.21__brief-to-the-chat-agent/00__brief.md. Three parts. The refactoring comments: chat.js at 692 lines carries six jobs against the guidelines' 250-line budget; the proposed split mirrors the reader's own v0.4.13 refactor (markup to a part, the tool loop to a part, the grounding prompt builder to a pure core module with a gate 27 vector, the shell keeps the state), acknowledging that v0.4.20's lazily imported media.js already practises the direction, plus three smaller notes on delegation, a doubled listener, and a busy-wait that deserves an upstream fix. The unexposed methods: twelve commands the reader could publish, each backed by code that already exists and is mostly pure and tested, headlined by pin_nodes (brief 25's judgement loop driven by language), graph_snapshot (the model sees the canvas it just arranged), compose_node_doc and rank_nodes (brief 24's document-of-a-node inside the conversation), and price_next_hop. The missing direction: the page-to-chat channel, one read-level get_recent_activity command over a ring buffer of the reader's own events, so "what is this?" while clicking a node just works, without breaking the independence contract. Written against v0.4.18, updated after the chat's v0.4.20 landed mid-writing; nothing in it was made redundant. No code changed; the brief proposes and its addressee disposes. No book content changed. |
| v0.4.20 | 24 August 2026 | The chat learns to listen and to draw: voice notes and infographics, both landing in the vault. The founder's memo of 24 August, round two. A mic button in the chat header records a voice note (the family's sg-audio), converts it to WAV in the browser (sg-audio-decode — the one format every OpenRouter audio model accepts), transcribes it with a curated audio-capable model (google/gemini-3.5-flash) using the user's own key, and sends the transcript as an ordinary chat message — so "sometimes I just want to have a chat about it" is now literal. With a vault connected, the WAV itself is kept under the session's voice-notes/. The model gains generate_infographic: it writes the brief itself (the layout, the exact wording, the claims with their support states), one OpenRouter call with image modalities (google/gemini-3.1-flash-image-preview, per the estate's curated picker) renders the image into the transcript — where the chat history's existing lightbox, copy and save already apply — and the PNG lands under the session's images/. Both capabilities live in a lazily-imported media.js: nobody who never presses the mic pays for the audio stack. Also this release: the vault format divergence brief for the Tools team at admin/briefs/ — sgit-CLI 0.16 and the published browser vault modules no longer share a format; evidence verbatim, four testable asks, repro harness offered. Verified: the 36-check chat suite (mic present, media module loads with the curated ids, the infographic tool offered once a model connects), the six-check vault round-trip re-run, the 37-test unit suite. No book content changed. |
| v0.4.19 | 24 August 2026 | The pinned-nodes technique, debriefed. The founder asked for a document on the technique v0.4.16 shipped and the problems it solves; it lives at v2/dev-packs/v0.4.16__pinned-nodes/00__debrief.md and enters the methods register as pinned nodes (locked summits, free field). The argument in brief: a force layout with every node free is an optimiser with no frame of reference, so position means nothing and dense graphs converge on the unreadable hairball; pinning a few structurally important nodes spends their freedom to buy meaning for everyone else's position. Position becomes information, the map stays recognisable across re-layouts, starved families read as visibly under-tethered summits (the founder spotted the objectives gap on first contact), and once the extraction fans out, twenty-one documents will share one spatial grammar and become comparable at a glance. The debrief also records what the technique does not solve: solver overshoot past the pins, the judgement of which nodes deserve pinning, and edge clutter, which stays the job of the source toggles and the explore view. Registered with its implementation paths, gate-checked like every method. No code changed; no book content changed. |
| v0.4.18 | 24 August 2026 | The chat gains a vault: sessions that survive the refresh, and a two-way channel to the agents. From the founder's memo of 24 August (workflow 1: persistence first). The chat's new vault drawer takes a vault key (passphrase:vaultId or a Simple Token) plus, where the server requires one, its access key — both held in this browser's localStorage only, like the model key. Every conversation then lives as a folder of files in the vault — /universe-chat/<doc>/<session>/ with session.json, messages.json (screenshots included), drafts.json and trace.txt — encrypted in the browser before anything leaves it, autosaved after every reply (only changed files written, one push per save), restorable from the drawer's session list, and readable by any holder of the key: the founder on another machine, an agent in a cloud session, a persona pipeline. The model itself gains one chat-local tool, save_to_vault, scoped to the current session's documents/ folder, so "keep that summary" becomes a file in the vault. Built on the family's published vault modules (vault-write, vault-session, vault-mutations at tools.sgraph.ai, pinned); the pure logic (key parsing, session naming, change detection, name taming) is vault-core.js under gate 27, five new tests. Verified end to end in headless Chromium against a local SG/Send-compatible store: mint a vault browser-side, connect, save, model-save a document, reload, restore byte for byte — six checks green, plus the thirty-three-check chat suite re-run. One estate finding, recorded for the Tools team: sgit-CLI 0.16 writes an evolved vault format (bare/keys/, bare/indexes/, different ref derivations) that the published browser modules do not yet read, so the chat pairs with web-format vaults for now. No book content changed. |
| v0.4.17 | 24 August 2026 | The universe pages gain a JavaScript API and a chat panel that drives it. Per the universe chat plan and the founder's decisions of 24 August (CDN over vendoring for the family's own components; ship it; Sonnet as the default; the risk-mandate register as the UX baseline). Two strangers on one page, and the contract is testable: the page publishes an API, the chat consumes it, neither imports the other's modules. The API is the family's Tool API Primitive: universe-api.js registers the reader's commands on window.__tool — read (the extraction, anchors, the frozen bytes), view (selection, the preset views, the node-pack sources, the explore stepper, pinned peaks, layouts, highlights — driven through the reader's own events and buttons, no component touched) and author (scratch elements and drafts, visibly unsaved; nothing anchored is ever written — the gates keep that monopoly). The command table is pure data under assets/universe/core/commands.js, projected into OpenAI function schemas per enabled level, and gate 27 now tests the table and its projections. Console and Playwright are equal consumers: SKILL-browser and SKILL-api ship beside the pages. The chat is a floating button and a lazy load: universe-chat/boot.js ships ~1 KB; the panel assembles the family's published LLM components from tools.sgraph.ai (pinned versions) — connection, history, input with clipboard screenshot paste, stats — over the [data-llm-bus] event contract, with the OpenRouter workflow (the key pasted once, kept in this browser's localStorage, never sent to any sgraph.ai host) and anthropic/claude-sonnet-5 as the default. A bus-level loop executes the model's tool calls against window.__tool (capped rounds, every invocation in meta.getLog()), a levels switchboard decides what the model may do, and the intro is the register's honesty restated: nothing has been sent yet, and nothing has been spent. Verified by thirty-four Playwright checks in headless Chromium, on top of the unit suite. No book content changed. |
| v0.4.16 | 24 August 2026 | Pinned peaks: the summits hold still and the universe arranges itself around them. Founder round (brief 25), all of it acted on. The new pin peaks toggle recreates the founder's VivaGraphJS experiment inside cytoscape: the doc root and the family peaks stack down the left edge of the canvas, the derived-group summits down the right, the gap scaled to how many free nodes must settle between them; the pinned summits are locked only while a layout runs, so the physics treats them as anchors, and between runs they stay draggable by hand, with every later layout respecting the dragged spots. Toggling pin off and on re-places the canonical stacks. The derived groupings got their own summits: each connected component of the weaker links is topped by a synthetic node named after its best-connected member ("around connectivity"), shown and hidden with the derived source. The document itself became a source like any other: a new toggle, on by default, first in the sources group, which also resolves the founder's observation that an unselected view still showed nodes; with every source off the canvas is empty and the stats bar says so. And the maximised graph finally owns the viewport: the site nav, both splitters and the page scroll hide while maximised, which also fixes the two reported overlaps (the sticky panel traps the maximised box's stacking order beneath the nav, so the chrome now yields instead of fighting). The unit suite grew to twenty-seven tests, including the derived-group summit vector and the pin-stack geometry; the interaction suite verifies the empty canvas, the summit lifecycle, the lock-during-layout behaviour, the hand-drag persistence and the chrome hiding, all in headless Chromium with zero console errors. No book content changed. |
| v0.4.15 | 24 August 2026 | The document of one node: brief 24's experiment, programmatic phase. A separate page, /v2/universe/node-doc.html, grows a document from any single node of an extracted source. The composition is a pure core module (nodedoc.js, node-tested): given the extraction, the cross-references and a node id, it assembles everything the anchored data verifiably holds — the node's definition quote at its recorded bytes, the claims about it, its directional relationships each with its own verb, the examples demonstrating it, its also-called names, its explicit near-but-not distinctions, its derived weaker links with counts, its uses across the estate with their maturity ratings, and a how-far-it-reaches table: what each degree of separation adds around it. No prose is authored: every sentence on the page is a verbatim quote or a projection of the data; the connecting prose is deliberately absent, because writing it, layer by layer up to a mini book per node, is the later LLM phase the memo defers. The picker ranks all 57 nodes by their link count, which makes the richness of each concept measurable before any writing happens: the memo's question, "how rich some concepts are and how far can we take it", becomes a sortable column. Print styles make each node document PDF-ready. The unit suite grew to twenty-five tests; the page's interaction checks (picker order, composed sections, quotes, the degrees table, the unknown-node path) pass in headless Chromium with zero console errors. Brief 24 records the memo verbatim; one method entered the register. No book content changed. |
| v0.4.14 | 24 August 2026 | The graph learns to be explored: node packs, peaks, the explore view, and one toggle set for both panes. Brief 22 (the founder's universe-viewer memo) plus three follow-up notes, recorded verbatim as brief 23, all acted on. The founder's bug first: the source pane's links were invisible until hovered, because the highlight filter defaulted to nothing enabled. Every link is now visible by default, and the pane head gains a kind bar: one colour-coded toggle per kind present in the document, with counts, so showing more or less is a click in the pane itself. The same toggles drive the graph: one kinds list in the core tier feeds the kind bar, the options popover and the graph's family visibility, so the panes cannot disagree. Where links overlap, the last one added wins the colour, the click and the new hover chip that names the kind without touching the native tooltip. Boxed mode corrected per the memo: the node is the rounded box with the label inside, no dot-then-label eye movement. The graph fits on open, the physics sliders apply while the slider moves, and clicking a doc-tree section now navigates the source pane to that heading, the same move the location trail makes. The options strip regroups around sources of nodes: the doc tree, the family peaks (a synthetic summit per family, containment edges to members, pyramids under the tree layout) and the first weaker-link layer (concepts co-claimed by the same claim, dashed and counted, drawn as measurement, never as a verb). The old subtree mode is replaced by the explore view the founder specified: degree zero is exactly the selected node, each step grows one ring towards the peaks, "to peaks" removes the limit, and a stats bar counts what the view holds while pricing the next hop — the families and edges one more degree would add, read before paying for it. Paths to peaks gold-lines the routes from the selection to every visible summit. Five preset views (overview, reading map, pyramids, concept web, around selection) apply a preference bundle in one click and are plain data. A maximise control takes the graph over the whole viewport and back, and a reset view control forgets every stored preference for the document. Brief 24 records the next experiment: a document grown from one node. Two methods entered the register. The unit suite grew to twenty-two tests (the walk, the stepper, the stats, the presets, the last-wins mark); thirty-five interaction checks pass in headless Chromium with zero console errors, plus both regression suites. No book content changed. |
| v0.4.13 | 24 August 2026 | The reader refactored: zero visible change, and the tool is now portable across all twenty-one documents. A pure quality release, per the founder's SGraph JS and Testing guidelines: the 703-line reader script became a three-tier structure under assets/universe/ with one-way dependencies. The core tier is pure and node-testable with no DOM: the elementary-segments computation, the marker-splicing and token-to-mark passes, the document-tree builder, the heading-chain logic, and the graph's visual vocabulary as data. The components tier is three light-DOM custom elements (uni-graph, uni-source, uni-options) that render from properties and emit namespaced events, each with one delegated handler; the reader shell owns the preferences and the one selection and wires them together, data down, events up. Every id, class and behaviour is unchanged, verified by re-running all four headless-Chromium interaction suites (thirty-plus checks) against the refactored page. The pure core now carries a unit suite of thirteen tests with known-answer vectors (the nested-anchor split, the mark that closes and reopens across inline tags, the containment chain) run by gate 27 on every build, so a refactor that changes highlight behaviour fails the release. Because the reader is driven entirely by each page's data blob, extending the tool to the other twenty documents now requires only their extraction files: no code changes. Two deviations from the guidelines, recorded rather than silent: no per-component version-stamped paths, because this site releases as one hash-gated unit; and the source-pane element runs twelve lines over the section budget, carrying both the document view and the data view. No book content changed. |
| v0.4.12 | 24 August 2026 | The graph options are reachable from anywhere on the page. Founder-reported: the options gear was only visible after scrolling to the very top. The cause: the site nav is sticky with a higher stacking order, so once the page scrolled, the nav overlaid the top strip of the reader's panel, exactly where the gear sits. The panel now measures the nav's real height at runtime (it varies as the nav wraps) and pins itself below it, so the gear, the graph strip and the panel's top edge stay visible and clickable at any scroll position. Verified in headless Chromium: scrolled deep into the page, the gear sits clear of the nav and receives clicks. One change, no other behaviour touched. |
| v0.4.11 | 24 August 2026 | The graph becomes an instrument, and the document climbs into it. Founder feedback batch, all acted on. The graph options regroup per capability: layout (cose, rings, grid, and a new top-down tree), labels (show, three sizes, and a boxed mode that puts each label in a rounded box), physics (two sliders for string length and gravity pull, re-running the layout live, for wider experiments in how to view the graph), and view. The new doc tree overlay adds the document's own structure to the graph: the title at the top, the parts and sections descending, ending at the extracted universe nodes each section carries, built from the same taxonomy and anchors the build verifies; with the tree layout it reads top-down from the title. Subtree only shows just what hangs off the current selection, follows the selection as it moves, traverses containment downward only (climbing up would re-include everything), and exits cleanly on clear. The left selection is now permanent with no fade: the arrival flash on a selected row ends at the selection colour instead of transparent, an accent bar marks it, and the hover-restores-it oddity is gone with the cause. Source highlights are now colour-coded by kind, using the graph's own palette: blue dictionary, green claims, amber hypotheses, purple objectives, red examples, so a reader stepping through the document sees what each anchored span is before clicking. Two real bugs found by the test suite and fixed before shipping: a cytoscape traversal that stalled because an edge-selector drops the source nodes, and the clear control accidentally receiving the click event as an argument. All checks green in headless Chromium. No book content changed. |
| v0.4.10 | 24 August 2026 | The document folder, the usage ledger, and the reader's data mode. Three founder requests. The standalone folder: everything the estate holds about one source document now lives in one portable folder, /v2/universe/docs/thinking-in-graphs/: a byte copy of the frozen source that gate 23 verifies against the original on every build (so the folder can be moved or copied between repositories and still prove itself), the anchored extraction, the cross-references, a README for whoever finds it elsewhere, and a browsable index. The usage ledger: crossrefs.json records where the document is used across the estate, and each use is rated against the new usage maturity model: aligned (the use says what the source says), stretched (recognisably derived but context dropped or scope widened), misaligned (the source does not say that), and unrated (a named absence awaiting judgement). Ratings are signed and dated; the rating judges the use, never the user; a superseded use keeps its rating with the supersession recorded. This is the core of a source document's capability to police the life of its own ideas, and the first pass holds eight known uses of the cornerstone document, one of which the model catches immediately: the first edition's fractal definition, rated stretched, the very use brief 20 corrected. The build validates every rating against the model, every local path, every named concept, and fails on an unsigned judgement. The reader's data mode: a source/data switch in the panel replaces the rendered document with the raw extraction JSON, item by item, carrying the same selection: click a graph node in data mode and the exact JSON object that captures it scrolls up, selected; click a JSON item and the extraction row lights. The data view links the extraction, the crossrefs, the model and the folder. All interaction checks pass in headless Chromium, and the folder's source-copy gate was verified negatively before shipping. No book content changed. |
| v0.4.9 | 24 August 2026 | The reader grows up: selection, the trail, the stepper, the tempo, and the whole width. Founder feedback on using v0.4.8, all of it acted on. The nasty bug first: clicking a graph node scrolled the extraction a little and to nowhere useful. Two causes, both real: v0.4.8 let the browser scroll every ancestor when centring a source highlight, so the window fought itself; and the site's own stylesheet declares smooth scrolling globally, which silently turned every programmatic jump into a slow glide that the next jump interrupted mid-flight. The reader now computes each scroll itself and forces it instant, so a jump is a jump. Selection is now persistent: clicking a node, an anchor or a highlight selects it everywhere at once, the extraction row, the source bytes and the graph node stay lit until the same thing is clicked again (which deselects it everywhere) or the top-level clear control is used. The reader options pane adds what the founder asked for: scrolling tempo (immediate, fast, smooth), per-family highlighting (dictionary, claims, hypotheses, objectives, examples, relations, near-but-nots, also-called, with all and none shortcuts), and graph visibility. With families highlighted, the stepper walks the document anchor by anchor in byte order, selecting each in the extraction and the graph as it goes, which is the read-the-document-and-audit-the-extraction workflow the founder described: a way to catch blind spots and mis-mappings by reading the source with the extraction beside it. The location trail shows the heading path of wherever the source pane is, clickable, sticky, updated as the pane scrolls, so landing deep in the document never loses the way back up. The graph gains a config strip (layouts, labels, fit, clear) behind a gear, keeps itself in sync with every click and step, and can be hidden entirely to give the source the full panel. The page now uses the full viewport width, and panel sizes are remembered per document. Also in this release: the CI tag step now checks the remote before backfilling, so it pushes only tags the remote lacks and prints one summary line instead of forty-four, which also shaves the pointless round-trips off every deployment. All thirty interaction checks pass in headless Chromium. No book content changed. |
| v0.4.8 | 24 August 2026 | The universe reader: the source, the extraction and the graph on one screen. Founder request, on reading the pilot. The per-document universe page gains a resizable side panel: the local graph on top, the rendered frozen source below, with a draggable divider between panes and between the two halves. Every anchor in the source is highlighted from the same byte offsets gate 23 verifies: the raw bytes are fetched, sliced at the recorded offsets, and marked before the markdown is rendered, so a highlight can only ever sit on the exact bytes the extraction cited; nothing re-searches the text, and the trust built at extraction time becomes navigation at reading time for free. The three-way jumps: clicking an anchor in the extraction tables scrolls the source to the cited bytes and flashes them; clicking a highlighted span in the source jumps to the extraction row about it; and clicking a node on the graph, which now stays visible instead of navigating away, opens both at once. A toggle shows every anchor in the source simultaneously, which turns the document into a visible coverage map: the parts extraction touched and the parts it deliberately left are apparent at a glance. The panel remembers its state and sizes per document, degrades to the previous single-column page on narrow screens (the graph renders inline there), and the PDF is untouched except that its section 6 now says the graph is an interactive view rather than printing an empty box. Tested end to end in headless Chromium before shipping: 72 anchors resolved to 73 verified spans with zero stray markers, and all six interaction paths (table to source, source to table, graph to both, the show-all toggle, panel off relocating the graph inline, panel back) verified by script. The 27 claims now read with the document beside them, which was the point. No book content changed. |
| v0.4.7 | 23 August 2026 | The redirect stubs are retired: 108 pages deleted, and the root is now exactly the model. Founder call: the stubs at the pre-move addresses added complexity to the repository structure, and there are no external users of this content who would hit the moved paths, so the insurance was costing more than it covered. All 108 stubs are gone (the 92 from the first edition's move and the 16 from the second edition's gathering), their generator is retired with them, and the methods register records the technique as superseded rather than deleting its row, because the register obeys the discipline it documents. What this exposed and how it is answered: frozen first-edition pages link to the world as it stood at their freeze, and those links were only resolving through the stubs, so the link gate now exempts the frozen tree, on the same principle as the preserved artefacts: a frozen page cites its contemporary world, gate 14 owns its bytes, and a moving site must not be constrained by a museum. The one live casualty was the footer's participant-disclosure link, which had been resolving through a stub since the move and now points at /v1/about/participant.html directly, and the release-history rows' links to the pre-gathering addresses, which now point into /v2/. The repository root is now exactly the founder's model: the site's own chrome, /v1/, and /v2/, with /book/ as the one pointer. No book content changed, and nothing under /v1/ was touched. |
| v0.4.6 | 23 August 2026 | The lexicon in scopes, the methods register, and the artefact catalogue. Three founder requests in one message, all inside /v2/. The lexicon (/v2/lexicon/) holds the book's vocabulary the way the book says vocabulary should be held: multiple lexicons at different altitudes, a root scope any other scope may link to, and local override without asking the centre, which is the corrected meaning of fractal semantic graphs demonstrated on the book's own terms. The root scope carries 27 terms: 24 copied from the first edition's concept layer with a provenance block (the first real use of the edition copy rule), 3 authored at v2, and one already overridden on record: the term fractal itself, whose first-edition definition claimed uniformity where brief 20 corrected it to composition with local override; the superseded definition stays printed under its replacement with the authority named. One source scope per extracted document maps the document's terms onto the book's, and six terms are published as unmapped findings, among them cross-graph edge: the mechanism the cornerstone source calls its most powerful has no name in the book's 24 concepts, which nobody had noticed until the mapping forced the question. Gate 24 checks resolution. The methods register (/v2/methods/) catalogues the 20 graph techniques and workflows this project has used in earnest, each with the release it first shipped in and the files that implement it, gate-checked so an entry claiming code that is gone fails the build; the second edition's method chapter is written from it. The artefact catalogue (/v2/artefacts/) preserves point-in-time artefacts byte for byte, because the experiments and pages made along the way are part of the history of how the result was reached: the first entry is the first review pack exactly as built at v0.4.3, pulled from its tag with the era's stylesheets alongside so it still renders as it did, every file's SHA-256 recorded, and gate 26 failing the build if a catalogued byte ever changes. Also: every v2 page's breadcrumb now routes through the second edition's front door, and the nav's book menu lists all seven v2 sections. No book content changed. |
| v0.4.5 | 23 August 2026 | The universe begins, bottom up: the pilot extraction of Thinking in Graphs. The founder's direction: before the book's universe can exist, every carried source gets a first pass that extracts and connects its key ideas, concepts, facts and hypotheses, with an ontology, taxonomy, dictionary and thesaurus per document, and with connections resolving all the way to the section and the paragraph. Built as a layer model at /v2/universe/: layer 0 is the frozen bytes, layer 1 is one local graph per document, layer 2 will be authored bridges between documents, layer 3 the book's own universe, which connects to these nodes rather than absorbing them. The pilot is the cornerstone document: 57 nodes (22 concepts of which 3 are used-but-undefined and recorded as named absences, 27 claims each carrying how the document supports them, 3 hypotheses, 1 objective, 4 worked demonstrations) and 8 asserted edges with declared inverses. Every node is anchored to a verbatim quote at recorded byte offsets in the frozen source, and gate 23 fails the build if any quote is not at its bytes, verified negatively before shipping; the freeze made this possible, since a byte-frozen document makes an anchor stable forever. The four reviewer views (dictionary, claims, thesaurus and near-but-nots, ontology) are projections of one extraction file, so they cannot disagree, and the coverage rule is enforced: every section with prose either yields anchored items or is recorded empty with a reason. During authoring the gate caught the agent misquoting the source by one added word, which is the mechanism doing exactly what it is for. A 15-page PDF ships for review with nothing else open. One document of twenty-one; the founder reviews the method before it fans out. No book content changed. |
| v0.4.4 | 23 August 2026 | The second edition gathers everything it owns into /v2/, and /book/ becomes a pointer. Three founder decisions, given in review of the dev pack. First: everything for the next set of work lives inside /v2/, including the project management and the scaffolding, in preparation for the day /v2/ is archived and a /v3/ begins. Second: anything outside /v1/ and /v2/ is the site's own chrome, and the boundary is testable: if everything outside the two edition trees were deleted, neither edition would lose content. Third: /book/ stops being an address any edition owns and becomes the pointer to the current edition, which from now on is the second; the first edition was never released and nothing external links into it, so it is kept as history, source material and worked examples rather than as the thing /book/ means. Executed as a move: the dev pack (/v2/dev-pack/, raw under /v2/dev-packs/), the memos (/v2/memos/, raw under /v2/briefs/) and the review packs (/v2/packs/) all moved, with redirect stubs at every former HTML address; the two markdown briefs and the pack PDF cannot carry redirects, and that cost is recorded here rather than discovered. /v2/ gained its front page, /book/ now names both editions and points at the current one, and the nav's book menu leads with the second edition. This answered open question 2 in the dev pack (where does the second book live), so phase 1, the plumbing, is unblocked; the pack's file 09 records the answer. No book content changed, and nothing under /v1/ was touched. |
| v0.4.3 | 23 August 2026 | Review packs: documents that control the sequence, which a website cannot. From brief 21. The next phase needs other agents brought in to review, and a reviewer cannot be pointed at a site heading for hundreds of thousands of words and told to go to town: a website's hyperlink nature means nobody knows what was read, in what order, or what was skipped. A pack is the opposite. It is one continuous HTML page and a PDF printed from the same source, a selection in a fixed order, readable end to end on an iPad or on paper, with nothing in it that needs a link followed. And because a PDF is not modifiable it survives as a record better than a page does. /packs/ ships the first one: the concepts and evidence pack, 22 pages, the one the founder said he needs now. Twenty-four concepts with their definitions and their near but nots, the five computed peaks with the formula printed so it can be argued with, the concept-by-document matrix measured across the twenty-one carried sources, the concentration table that separates a concept the corpus distributes from one that two documents carry, the eight findings with their states, the five build-time checks with their rules, the ten open decisions with their options and costs, and five numbered asks at the end so a review can be answered item by item. With three figures captured from the site's own live pages, because a figure in a pack should be the thing the reviewer would see if they opened the site. Every pack stamps the SHA-256 of each data file it drew from on its own cover, and gate 22 fails the build if those hashes no longer match, so a pack never describes a build other than the one it names. Per the memo, this joins the release chain: packs ship on every release from now on, the way the book already does. And a correction I owed. The retrospective said every aggregate view produced findings and no per-item view did, and called the per-item ones reading aids. The measurement stands; the words were wrong. The founder's framing is better and it is the book's own: a visualisation is a compression, another way to represent relationships, in the same family as the path tables and the concentration tables, which are also visualisations. Judging a compression by whether it produced a novel finding is like judging level 2 of the ladder by the same test. The corrected statement is now in the dev pack's file 07: aggregate views produced the findings, per-item views made the structure consumable, both are compressions and neither is decoration. No book content changed. |
| v0.4.2 | 23 August 2026 | The dev pack was defining answers before the questions were known, and the founder caught it at section 5. A voice memo recorded while reading the pack, published verbatim as brief 20 in a new /memos/ section, and it reshapes six of the pack's ten files. The core correction: the pack put the spine in phase 2 and planned to attach evidence to it, which is deciding the shape of the book before anything is known. The order inverts. Phase 2 is now the universe, decomposed bottom-up from material that already exists (twenty-one carried sources, six vault analyses, the concept map, the whole first edition), and phase 3 derives the spine from where the plot lines converge rather than confirming a spine written down three days earlier. A fourth governing rule states it: the universe precedes the plot, and the plot precedes the levels. This does not contradict the morning's memo: construction is bottom-up, reading stays top-down, and confusing the two is what produced the first order. Section 2's verdicts are demoted to hypotheses, with the founder's reasoning quoted at the top of the file, and each is re-tested against the universe in phase 3; how many move is a measurement of how much the universe knew that the guess did not. Two corrections of fact. Fractal semantic graphs did not mean what the pack said it meant: not one grammar at every altitude, which is a claim about uniformity, but semantic graphs nested fractally, graphs of graphs, ontologies of ontologies, with any scope free to extend, specialise or override the lexicon where it needs to. Uniformity survives as the mechanism that makes an override safe rather than a fork, which is where it belonged. Worth recording how this was missed: the Issues-FS Lexicon, carried on this site since v0.3.25, says in its own words that it is not a schema registry and that any scope can override a bootstrap definition. The carried source contradicted the pack and nobody noticed. And the verdict on Wardley maps is reversed: dropped from the spine on the grounds that nothing in the concept map depended on them, which measured the concept map rather than the material. The reasoning that was missing is that a map is a graph that has gained position, movement and time, a map of a map of a map is the fractal claim at its most legible, and maps are what make a graph actionable. They are now a sixth spine candidate, and the only one whose evidence has not been carried onto this site, which is itself work for phase 2. Two new ADRs follow from the memo, neither in it: plot lines as a first-class artefact (a named, ordered walk from a question to a resolution, with its turn; chapter order is the shadow of the plot lines, not the thing itself), and pacing checked rather than felt (a concept used before it is introduced is a defect the build can name, with the exact pair of units, which is the memo's question about chapter one and chapter two made mechanical). And a stopping rule for the universe, because building one has an obvious failure mode: it is sufficient when every candidate plot line traces end to end without a gap, which makes enough a property of the story rather than of the material. No book content changed, and nothing in the frozen first edition was touched. |
| v0.4.1 | 23 August 2026 | The title and the subtitle are two fields, not one string. Reading the dev pack, the founder caught that the record made for humans and agents look like part of the title. It is not. Title: Fractal Semantic Graphs: Meaning Through Connectivity. Subtitle: For humans and agents. And the subtitle carries a placement rule, because it names the audience rather than the book: it belongs on the cover and in the site's main sections, and it does not go into the printed title or into a publishing platform's title field. An audience descriptor in a title field is a claim about the subject, and it would be the wrong claim. The metadata sheet now carries the second edition's identity as its own block with the rule stated, the runbook says plainly not to type it at the upload screen, and one point is left open on purpose for whoever fills the form: whether a title field takes the whole string or splits at the colon. That is a platform convention, not a decision about the book. The correction also surfaced a structural consequence of yesterday's freeze. The reviews that hold the decisions register moved into /v1/ and froze, so a decision cannot be corrected at source any more, which is exactly what freezing is for. Rather than break the freeze, the register gains amendments: decisions/amendments.json sits outside the frozen tree, gen_decisions.py merges each one onto its decision, and the page prints both, with the original standing and the amendment beside it. The build fails if an amendment names a decision that does not exist. That is the corpus's own supersede-never-delete rule applied to the mechanism that records the corpus's own decisions, and it was going to be needed the first time anything changed after the freeze. It was needed within a day. And the freeze itself had to learn three things in its first day. A frozen edition's book, cover and PDFs carry the version they froze at, so the freshness checks that compare an artefact's stamp to the current site version now apply only while an edition is live; the checks that compare an artefact to its own source still apply, because a frozen source cannot diverge from a frozen book. A frozen page keeps its version badge for the same reason. And book/changes/data, the version diff, is excluded from the freeze: it is a record of how the site changed and keeps growing, and it sits under /v1/ only because book/ moved there. gen_freeze.py now refuses to run when the manifest exists unless it is given --refreeze, because a gate anyone can silence by re-running a generator is not a gate. No book content changed, and nothing in the frozen first edition was touched. |
| v0.4.0 | 23 August 2026 | The first edition moves to /v1/ and freezes. The second edition begins, empty. Phase 0 of the dev pack, and a move rather than the copy the plan originally proposed: the founder's decision, and the better one. A copy leaves two live trees and no rule about which is authoritative, so the first thing that happens is somebody edits the wrong one. A move leaves exactly one, and the v1/ prefix makes an edition's boundary visible in every path. What moved: the book, its seventeen source units, the sixteen chapter-source pages, the altitude ladder, the vault analyses, the twenty-one carried sources, the brief pack, the four reviews and the front page. What stayed: the stylesheet and scripts, engineering, the decisions register (which spans editions by design) and this dev pack (which belongs to the second edition, not the first). What is new: /v2/, which is empty on purpose and carries only the rule it exists to enforce, that each edition owns everything it uses and every copy records where it came from. The freeze is real, not a convention. v1/MANIFEST.json records the SHA-256 of all 236 files, 10.9 MB, and gate 14 fails the build if one of them changes. It was verified the only way a gate can be: a byte was changed, the build failed, the byte was put back. chrome.py now leaves the frozen tree alone, so a frozen page keeps the nav and version badge of the release it froze at, which is the honest thing for an artefact that is evidence rather than working material. Every moved address still resolves. Ninety-three redirect stubs sit at the first edition's former URLs, each with a canonical link and a line saying where the page went and why; they carry noindex and are excluded from the sitemap, the hub check and the freeze. Two addresses could not be preserved, because a PDF cannot carry a redirect: both PDFs now live under /v1/book/. A new front page replaces the one that moved, and it is what the memo asked for: the two editions, the sequence of events generated from the release table, and a complete index of the first edition generated from the file tree. Three pieces of machinery are new and two got stricter. gen_front.py, gen_sitemap.py (the sitemap was hand-maintained until today, which worked while the tree was small and became a liability the moment a hundred pages moved) and gen_freeze.py. gen_changes.py now tries both layouts when reading a release tag, so the version diff keeps working across the move instead of silently losing every release before it. And the hub gate was quietly weakened by the move itself: section hubs went from two path segments to three, so it kept reporting OK while checking four hubs instead of nineteen. It now follows the edition prefix and checks twenty. That is the third gate in three releases that stopped doing its job without saying so, which is the argument the retrospective makes, arriving again. No book content changed: the first edition is byte-identical to v0.3.26 apart from the link depths the move required and the version badge. |
How a version is decided
- Every push to
devis a minor bump —vR.M.N→vR.M.(N+1). A deliberate major goes tovR.(M+1).0; CI accepts either and rejects anything else. - The version lives in one file.
admin/build/version.txt.chrome.pypropagates it to every page badge, tollms.txt, tollms-full.txtand toindex.md;validate.jsfails the build if any of them disagree. - It must be in the commit subject —
site vX.Y.Z: …. CI anchors the tag to that commit, which is HEAD on a direct push and HEAD's parent when a pull request lands as a merge. - A row here is required. The build fails if this table has no row for the current version, or lists any version twice.
- A correction that changes a claim gets a row, not a silent edit.