From 9eb01b43715d074dcaa68a83a35e18422a3fea35 Mon Sep 17 00:00:00 2001 From: xNet Test Date: Tue, 7 Jul 2026 12:22:22 -0700 Subject: [PATCH 1/4] docs(exploration): explore apps as views over user-owned data Exploration 0280: blog post #11 composing the apps-as-views lineage (Verborgh 2017, Ink & Switch 2019, Zhao's data neutrality + Rhizome 2022, Jansen's 'Apps as Views, Not Vaults' 2026) with verified quotes, the Solid critique file (schema problem, shadow databases, recentralization one layer up), and xNet as the existence proof. Recommends 'The Vault and the View' (framing: lineage essay closing on the AI-era value-settlement inversion), distinct from essay #10's moddability angle. Co-Authored-By: Claude Fable 5 Signed-off-by: xNet Test --- ...POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md | 538 ++++++++++++++++++ 1 file changed, 538 insertions(+) create mode 100644 docs/explorations/0280_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md diff --git a/docs/explorations/0280_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md b/docs/explorations/0280_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md new file mode 100644 index 000000000..d1b9e8fa8 --- /dev/null +++ b/docs/explorations/0280_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md @@ -0,0 +1,538 @@ +# Blog Post: Apps as Views Over User-Owned Data + +> _"Apps become views."_ — Ruben Verborgh, 2017 + +## Problem Statement + +The user wants **blog post #11** composed around a specific intellectual +lineage: the idea that **applications should be interchangeable views (lenses) +over a user-owned data substrate**, not vaults that couple your data to one +vendor's UI and hold both hostage. The seed material names the canon +explicitly: + +- **Jacky Zhao, "Towards Data Neutrality"** (Reboot, Jul 2022) — "Apps in this + new model are now just views on top of data," plus his **Rhizome** proposal + (EAV tuples, UCAN, CRDTs). +- **Ruben Verborgh, "Paradigm shifts for the decentralized Web"** (Dec 2017) — + "Apps become views… interchangeable views… over your personal data pod," + written from inside the Solid project. +- **Ink & Switch, "Local-first software"** (Kleppmann et al., 2019) — the + seven ideals; the cloud holds secondary copies, you hold the primary. +- The slogan **"apps as views, not vaults"** from community-owned-data + circles. + +The challenge is that xNet's blog has _already grazed_ this idea once: essay +#10, **"The Workshop and the Walled Garden"** +([exploration 0267](0267_[x]_MODDABLE_SOFTWARE_AND_THE_APPLICATION_AS_A_VIEW_OVER_YOUR_DATA.md), +[site/src/pages/blog/the-workshop-and-the-walled-garden.astro](../../site/src/pages/blog/the-workshop-and-the-walled-garden.astro)) +arrived at "the application is a view over your data" as the _precondition for +moddability_. This post must not re-tread that. The distinct job here is to +treat the inversion itself as the subject: where the idea comes from, **why +the data–app coupling happened in the first place** (it was not an accident), +why the pods-and-standards generation of the idea stalled, and what it takes +to actually ship it — with xNet as the working example rather than the pitch. + +The failure mode to avoid: a link-roundup with reverence. The essay must add +an argument the sources don't already make. + +## Executive Summary + +- **The idea has a 50-year pedigree, not a 5-year one.** Unix made the file + the unit of ownership and the program a view (`ed`, `vi`, and `cat` over the + same bytes). The relational model (Codd, 1970) was explicitly a revolt + against apps owning their data layout — "data independence" is + apps-as-views stated in 1970s vocabulary. Desktop-era documents kept it: + your `.doc` outlived WordPerfect. **The web application broke it** — for the + first time, mainstream software's default was that the vendor holds the only + copy and the only interface. +- **The coupling was not laziness; it is the business model.** A silo is a + moat: switching costs and network effects are what venture-priced software + is _for_ (see the earlier essays' surveillance-capitalism ground). But it is + also genuine engineering convenience — a bespoke schema, one writer, no + interop negotiation. An honest essay concedes both, then shows the price: + every app rebuilds the same CRUD plumbing, users re-enter the same contacts + five times, and when the app dies (Google Reader, Sunrise, countless + others) the data's usefulness dies with it even when an export exists. +- **The pods generation proved the diagnosis and fumbled the mechanism.** + Solid's decade of struggle localises the hard parts: (1) **the schema + problem** — two apps agreeing on what a "task" is turns out to be the + actual work, and RDF/SHACL negotiation pushed it onto app developers; (2) + **sync and conflict** — pods were server-resident documents, so offline and + multi-writer were bolted on; (3) **no killer substrate** — users won't run a + pod for its own sake; the data layer has to arrive _inside_ software they + already want. Local-first (CRDTs, sync as a separate layer) solved (2) and + reframed (3); the schema problem remains the live frontier. +- **xNet's stack is a point-by-point answer, which is what makes the essay + concrete.** One signed, hash-chained LWW change log + ([packages/sync/src/change.ts](../../packages/sync/src/change.ts)) is the + substrate; the protocol spec _normatively refuses_ to specify storage or + rendering ([docs/specs/protocol/00-overview.md](../../docs/specs/protocol/00-overview.md): + "It deliberately does **not** specify how an implementation stores, indexes, + queries, or renders that data") — apps-as-views is written into the + conformance boundary. The schema problem gets a working answer: published + schemas plus **read-time lenses, overlays, and sidecars** + ([packages/data/src/schema/lens.ts](../../packages/data/src/schema/lens.ts), + [extension.ts](../../packages/data/src/schema/extension.ts), + [sidecar.ts](../../packages/data/src/schema/sidecar.ts)) so two views can + disagree about shape without forking the data. And the view layer is + literally plural: table/board/calendar/gallery/list/timeline/form/canvas + registered over the same nodes + ([packages/views/src/builtins.ts](../../packages/views/src/builtins.ts), + [registry.ts](../../packages/views/src/registry.ts)), with the CanvasView + convergence (exploration 0277) demonstrating one view core rendered by two + platform shells. +- **The AI-age argument is the essay's fresh contribution:** when generating + a bespoke view costs an afternoon of prompting, views become _disposable_ + and data becomes the _heirloom_. The moat inverts — vendors can no longer + charge rent on the lens, only on custody of the data; so custody must move + to the user or the rent becomes pure hostage-taking. Essay #10 made the + adjacent point about mods; this one makes it about **where value settles**. +- **Recommendation:** ship blog post #11 at + `site/src/pages/blog/`, provisional title **"The Vault and the View"**, + tags `['essay', 'philosophy', 'decentralization', 'protocol']`, authors + `['crs48', 'claude']`, cold-opening on a dead app taking a living dataset + with it, closing on the heirloom inversion. + +## Current State In The Repository + +### The blog machinery (post #11 slots in mechanically) + +- [site/src/data/blog.ts](../../site/src/data/blog.ts) — single source of + truth: `posts[]` metadata, `AUTHORS` (crs48 + Claude with vendored avatars, + exploration 0269), `BlogTag` union, `seriesOrder()`/`seriesNeighbors()` for + the front-to-back reading order. A new post = one `posts[]` entry + one + hand-authored `.astro` page (no MDX/content collections). +- [site/src/pages/blog/the-workshop-and-the-walled-garden.astro](../../site/src/pages/blog/the-workshop-and-the-walled-garden.astro) + — the freshest template for conventions: `Byline`, `Mermaid`, `CodeFigure`, + `SeriesNav`, a bespoke hero component, `tok-*` syntax-highlighting helpers, + `prose` article body. Post #11 follows the same grain with its own hero. +- RSS ([site/src/pages/blog/rss.xml.ts](../../site/src/pages/blog/rss.xml.ts)) + and the index page derive from `posts[]` — no extra wiring. +- Gotchas already learned (explorations 0239–0269): blog pages are `.astro` + not MDX; avatars/heroes are vendored, never hotlinked (several essays + promise "this page loads nothing third-party"); commit headers ≤72 chars; + changelog fragment via `scripts/changelog/new.mjs` (don't hand-write a + duplicate); site content needs no changeset (site is not a publishable + package). + +### The claim the essay makes, and the code that backs it + +The essay's spine is "xNet is an existence proof, not a proposal." Each beat +maps to a seam: + +- **One substrate.** [packages/sync/src/change.ts](../../packages/sync/src/change.ts) + — Ed25519-signed, hash-chained, Lamport-ordered LWW change log; the golden- + vector protocol spec ([docs/specs/protocol/](../../docs/specs/protocol/)) + makes the data format the contract and explicitly leaves storage/rendering + to implementations. The data outlives any app that renders it. +- **Many views, one store.** [packages/views/src/](../../packages/views/src/) + registers table, board, calendar, gallery, list, timeline, form, and canvas + views over the same schema-typed nodes; `ViewRenderer.tsx` + + `registry.ts` make "which lens" a runtime choice. App-level surfaces — + [apps/web/src/components/DataWorkspaceView.tsx](../../apps/web/src/components/DataWorkspaceView.tsx), + `TasksView.tsx`, the CRM pack ([packages/crm/](../../packages/crm/)), the + ledger ([packages/ledger/](../../packages/ledger/)) — are all consumers of + the same node store via + [packages/react/src/hooks/useQuery.ts](../../packages/react/src/hooks/useQuery.ts). + Zhao's "any change to the underlying data will instantly update both apps" + is literally `useQuery`'s live subscription semantics. +- **Cross-platform proof.** Exploration 0277 / PR #403 converged the web and + desktop CanvasViews on one shared core + ([packages/views/src/canvas-view/](../../packages/views/src/canvas-view/)) — + the "app" shrank to a thin platform shell around a shared view over shared + data. That's the thesis enacted at the code-review level. +- **The schema problem, answered in mechanism.** + [packages/data/src/schema/lens.ts](../../packages/data/src/schema/lens.ts) + (bidirectional read-time version lenses), `extension.ts` (on-record `ext:` + overlays), `sidecar.ts` (private sidecar attributes) — users and plugins + extend or reinterpret shape without forking the data or begging a vendor. +- **Views are scoped, not trusted.** + [packages/plugins/src/feature-module.ts](../../packages/plugins/src/feature-module.ts) + capability manifests + `guardStore`/`guardedFetch` — a view sees the slice + it declares. (Essay #10's territory; #11 references it in one paragraph + rather than re-arguing it.) +- **Leaving is a feature.** The Right-to-Leave work (exploration 0234, + [the-right-to-say-no](../../site/src/pages/blog/the-right-to-say-no.astro)) + and the portable protocol give the essay its receipts when it claims the + vault door is open. + +### Overlap audit against the existing series + +| Existing essay | Its claim | #11's distinct claim | +| --- | --- | --- | +| #10 Workshop/Walled Garden | Views-over-data enables safe **moddability** | The **data–app decoupling itself**: lineage, economics, why pods stalled, where value settles | +| #9 Hand on the Tiller | Steering/cybernetics | — | +| #7 The Loom You Can Read | How the substrate works internally | #11 cites it instead of re-explaining the log | +| #5/#6 economics/permaculture essays | Extraction vs regeneration framing | #11 reuses the moat framing in one paragraph, credits it | + +The seam is clean: #10 was "what you can build **on top** once apps are +views"; #11 is "why apps should be views **at all**, who said so first, and +why it hasn't happened yet." + +## External Research + +All quotes below were verified verbatim against live fetches of the sources +(fact-check discipline from exploration 0247). One attribution in the prompt +was corrected: the "two apps… instantly update both" line is from Zhao's +**Rhizome Proposal**, not the Reboot essay. + +### The canon (verified, with exact quotes) + +- **Ruben Verborgh, "Paradigm shifts for the decentralized Web" (20 Dec + 2017)** — . + Three shifts: end users become data controllers; **apps become views**; + **interfaces become queries**. Exact: _"Applications as interchangeable + views, wherein each Web app provides consistent visualizations, + interactions, and processing over your personal data pod."_ · _"Applications + ask rather than store, and they are able to reuse data created by other + apps, avoiding vendor lock-in."_ · _"Decentralization is about choice: we + will choose where we store our data, who we give access to which parts of + that data, which services we want on it, and how we pay for those."_ · + Concedes: _"The main challenge with full decentralization of data is + scalability"_ and _"Not everything is going to be 'free'"_ (unbundling + breaks the ad subsidy). Likely the earliest crisp statement of the thesis + in this lineage — five years before Zhao. +- **Jacky Zhao, "Towards Data Neutrality" (Reboot, 14 Jul 2022)** — + (canonical mirror; + Reboot original at ). Exact: _"Apps in + this new model are now just views on top of data rather than a tight + coupling of data and logic."_ · _"Apps and platforms in this model follow + the Unix philosophy: expect the output of every program to become the input + to another, as yet unknown, program."_ · _"The competitive advantage of the + vast majority of today's centralized platforms are in their data moats and + network effects."_ · His "Decentralization is about **agency**…" line + deliberately remixes Verborgh's "choice" line — the lineage is + self-acknowledged. Quotes Moxie: "People do not want to run their own + servers." +- **Jacky Zhao, Rhizome Proposal** — + . The mechanism sketch behind + the essay: **Root** (personal data pod) + **Trunk** (P2P app framework); + fully-replicated **EAV tuple store**, **DIDs + UCANs**, **BFT CRDTs**, + always-on "cloud peer" (_"not a hosting provider… a different type of a + personal device"_). Exact: _"If two apps are views on the same data, any + change to the underlying data will instantly update both apps"_ · + _"Companies of the future should derive value from the intelligence they + provide on top of existing data rather than have the value be just the + data."_ Strikingly close to xNet's actual choices (typed nodes / + capability manifests / signed LWW log + hub as "just another peer") — + worth a convergence nod in the essay. +- **Ink & Switch, "Local-first software: You own your data, in spite of the + cloud" (Kleppmann, Wiggins, van Hardenberg, McGranaghan, 2019)** — + (note: the bare + `/local-first/` URL serves empty — link the `/essay/` path). Seven ideals, + headings verbatim: no spinners; your work is not trapped on one device; the + network is optional; seamless collaboration; the Long Now; security and + privacy by default; you retain ultimate ownership and control. Exact: _"If + the service shuts down, even though you might be able to export your data, + without the servers there is normally no way for you to continue running + your own copy of that software."_ (the cold-open's thesis, in the canon) · + the "There is no cloud, it's just someone else's computer" bumper sticker. + Caveat for the essay: local-first is **ownership-first, not view-first** — + data is still typically per-app CRDT documents; it doesn't solve cross-app + schema sharing. That gap is precisely where xNet's contribution sits. +- **"Apps as Views, Not Vaults"** — **confirmed** as Guido X Jansen's named + series on gui.do (AT Protocol explainers, 2026; his project **Barazo** is + the application — community forums where members own their data). Exact: + _"Part of 'Apps as Views, Not Vaults': the things you make are yours; apps + are just the viewers."_ Credit Jansen by name, not "circulating phrase." + +### The critique file (what the essay must answer, not dodge) + +- **The schema problem is the whole problem.** Two apps sharing data must + agree on _meaning_, not just storage. Leigh Dodds, "Confused by SOLID" + (Mar 2024): Solid has _"no built in understanding of any specific schemas + or formats. Or recommended ways to structure data"_ — and _"It still all + feels very much like an idea trying to find a solution."_ SolidLab's own + **"What's in a Pod?"** (Verborgh et al.) concedes current Solid apps fail + at API-independent data reuse because each app encodes _implicit layout + knowledge_; their proposed fix (pod as knowledge graph + per-app + materialized views) admits "apps read the same files" doesn't work. Every + real answer reintroduces a coordinating authority — AT Protocol lexicons + put the schema back in the app developer's hands; Rhizome's EAV triples + defer semantics rather than solve them. xNet's position: published, + versioned schemas + read-time lenses/overlays/sidecars — **make + disagreement cheap** rather than mandate agreement. +- **Apps and their data models co-evolve.** The best products iterate schema + and UI together; freezing the data model to share it can slow the product + (Moxie's "protocols move slower than platforms"). Tight coupling isn't + only rent-seeking — the essay must concede it's often what makes an app + good, then answer with lenses (schema evolution without lockstep). +- **The shadow-database problem.** Pods with no query engine force every app + to build its own indexes — functionally app-owned data again (Dodds; AT + Protocol's app-view indexers embrace this openly). xNet's answer: the + query layer is part of the substrate + ([packages/query/](../../packages/query/), `useQuery`), not each view's + problem — and the perf sagas (0249→0266) are the honest bill for that. +- **Nobody wants to run a server.** Moxie's point, conceded by Zhao and only + partially answered by "cloud peers"/managed pods. xNet's stance: hub as + optional relay, local replica primary. +- **The performance objection.** Purpose-built silos optimise for one access + pattern; generic substrates historically felt slow — WinFS and the + semantic desktop died partly of this. Repo receipt for the rebuttal: the + cold-open-stall and query-perf explorations are the multi-month cost of + making a generic node store feel app-fast. One candid paragraph buys + enormous credibility. +- **Recentralization one layer up.** Gordon Brander, "Redecentralization": + _"If you decentralize, the system will recentralize, but one layer up."_ + Power reappears at the index/aggregator/AI layer (Bluesky's relay, pod + hosts). The essay should name this and scope its claim. (Note: no Brander + piece titled "the data pod problem" was found — don't cite that phrase. + His Noosphere/Subconscious has since wound down — itself a data point.) +- **Granular sharing is a footgun.** Users mis-scope permissions over raw + data they don't understand (Dodds); per-field consent UX is unsolved. #11 + hands this to #10's capability-manifest-as-consent-form in a sentence. +- **The utility gap.** A pod with no built-in value is a worse Dropbox + (Dodds). Local-first inverted the adoption order: ship software people + want, with the substrate as its foundation. xNet matches. + +### Adjacent prior art worth one line each in the essay + +- **Codd's data independence (1970)** — apps-as-views in relational-era + vocabulary; `VIEW` is even the SQL keyword. +- **Unix files and pipes** — programs are ephemeral, files are the durable + substrate; explicitly invoked by Zhao. +- **HyperCard (1987) / Apple OpenDoc (1990s)** — user-owned stacks; + document-centric compound documents with apps as component "parts" — + killed 1997; app-centric economics beat document-centric architecture. +- **WinFS (cancelled 2006) / Semantic Desktop, NEPOMUK (2000s)** — the + graveyard proving the idea is old and the mechanism is hard (schema + coordination + performance). +- **remoteStorage / unhosted / 0data.app** — the 2010s "your app, my data" + protocol lineage, pre-Solid. +- **Obsidian / Steph Ango's "File over app"** — the contemporary + consumer-legible version. +- **AT Protocol lexicons, Anytype, Solid** — the current cohort: federated + schemas + app-view indexers; local-first objects/relations; pods. + +## Key Findings + +1. **The essay's fresh argument is the value-settlement inversion.** All the + sources argue users _should_ own data; none of them had 2026's fact: AI + makes views nearly free to produce. When the lens costs an afternoon, the + only durable asset is the substrate — so the industry's moat logic + _itself_ now points at user-owned data (a vendor whose only moat is + custody of your data is visibly a hostage-taker, and hostage economics + invite exit). That gives #11 a thesis beyond synthesis. +2. **The lineage framing keeps it from being a link roundup.** 1970 (Codd) → + Unix → desktop documents → the web-app anomaly → Solid's diagnosis → + local-first's mechanism → xNet's implementation. The web-app era becomes a + ~25-year detour, not the natural order — historically true and + rhetorically strong. +3. **Concessions are load-bearing.** The three honest costs (schema + agreement is social; generic stores need serious perf work — cite our own + 0249→0266 saga; views still need scoping) are exactly what the earlier + essays' readers will probe. Conceding them with receipts is the + differentiator from advocacy blogging. +4. **Every quotable claim has a repo receipt** (see Current State) — same + discipline as the fact-checked essays (exploration 0247, en-GB prose). +5. **Series continuity:** #11 should cite #7 (how the log works) and #10 + (capability scoping) rather than re-explaining, and inherit the "nothing + third-party on this page" promise. + +## Options And Tradeoffs + +### Framing options for the essay + +| Option | Shape | Pros | Cons | +| --- | --- | --- | --- | +| **A. Intellectual-lineage essay** ("the 25-year detour") | History → diagnosis → mechanism → xNet → AI inversion | Distinct from #10; deep; flatters sources honestly | Risk of book-report tone if quotes dominate | +| B. Polemic on data moats | Economics-first attack on silos | Punchy | Overlaps #5 (Leveragism) and the surveillance framing of #4/#6; thin on mechanism | +| C. Product-explainer ("how xNet does views") | Architecture tour | Concrete | Reads as marketing; #7 already toured internals | +| D. Pure AI-angle ("views are disposable now") | Lead with the 2026 inversion | Freshest claim | Loses the commissioned brief (the sources) to a hook | + +**A, with D as the closing movement**, honours the brief (the sources ARE the +story) while contributing a new argument. B's moat point becomes one section +inside A; C's architecture becomes the receipts, not the subject. + +### Title options + +| Title | Notes | +| --- | --- | +| **"The Vault and the View"** ✅ | Series-consistent metaphor pair (cf. Workshop/Walled Garden, Forest/Field); credits "views, not vaults" | +| "Apps Are Views, Not Vaults" | Punchier but borrows the slogan wholesale as a headline | +| "The Twenty-Five-Year Detour" | Strong but opaque on the index card | +| "Many Windows, One House" | Gentler; weaker link to the sources' language | + +### Cold-open options + +1. **A dead app, a living dataset** ✅ — Sunrise Calendar / Google Reader / + Wunderlist-style shutdown: the export `.zip` that is technically your data + and practically a brick, because the data was shaped for exactly one view + that no longer exists. Concrete, universal, sets up "the vault kept the + key." +2. The five-copies-of-your-contacts opener — relatable but smaller stakes. +3. Open on Codd 1970 — intellectually satisfying, colder emotionally. + +## Recommendation + +Write **blog post #11, "The Vault and the View"** (framing A+D): + +1. **Cold open:** an app dies; the export is a brick. The data was never + yours in the way that mattered — the _shape_ belonged to the vault. +2. **The detour:** Codd's data independence → Unix files → desktop documents + → the web app as the anomaly that fused data to interface. The fusion was + a business model (moat) *and* an engineering convenience — concede both. +3. **The diagnosis generation:** Verborgh's "apps become views" (quote), + Solid's pods; why the vision was right and the mechanism stalled (schema + negotiation tax, server-resident documents, pod-first adoption). +4. **The mechanism generation:** Ink & Switch's seven ideals; sync as a + separate layer; Zhao's data neutrality + Rhizome (quote the two-apps-one- + data line, correctly attributed to the Rhizome Proposal); AT Protocol and + Jansen's "Apps as Views, Not Vaults" (2026) as the idea reaching social + scale — with the honest note that lexicons and app-view indexers + reintroduce coupling one layer up. +5. **The implementation:** xNet as existence proof — the spec that refuses + to specify rendering; eight registered views over one node store; lenses/ + overlays/sidecars as the schema-problem answer; one paragraph of honest + cost (our own perf saga); one sentence handing capability-scoping to #10. +6. **The inversion (close):** AI makes views disposable; data becomes the + heirloom; the moat argument now runs in the user's favour. End on the + image: vaults hold things _in_; views let you look — the house is yours, + ask for more windows. + +Mechanics: `.astro` page + `posts[]` entry, tags +`['essay', 'philosophy', 'decentralization', 'protocol']`, authors +`['crs48', 'claude']`, bespoke hero, ~13–15 min read, en-GB, Mermaid diagram +of substrate→views, `CodeFigure` showing a `SchemaLens` (the two-views- +disagree-peacefully exhibit), changelog fragment via `scripts/changelog/new.mjs`. + +```mermaid +flowchart LR + subgraph detour["The 25-year detour"] + V1["Vault app A
data + logic fused"] + V2["Vault app B
data + logic fused"] + V1 -. "CSV export
(a brick)" .-> V2 + end + subgraph inverted["Apps as views"] + LOG["Your substrate:
signed change log
(packages/sync)"] --> NODES[("Schema-typed nodes")] + NODES -->|lens| T["Table view"] + NODES -->|lens| B["Board view"] + NODES -->|lens| C["Canvas view"] + NODES -->|"SchemaLens v1↔v2"| X["Tomorrow's view,
generated in an afternoon"] + end + detour ==>|"local-first inversion"| inverted +``` + +```mermaid +sequenceDiagram + participant U as You + participant S as Node store (one substrate) + participant A as Tasks view + participant B as Calendar view + U->>A: tick a task done + A->>S: append signed change (LWW) + S-->>A: live query update + S-->>B: live query update + Note over A,B: Zhao's line, running: two views,
one change, both update instantly +``` + +## Example Code + +The essay's central exhibit — two views disagreeing about shape without +forking the data (real API from +[packages/data/src/schema/lens.ts](../../packages/data/src/schema/lens.ts)): + +```typescript +// A lens is a treaty between two views of the same nodes. +const taskV1toV2: SchemaLens = { + source: 'xnet://xnet.fyi/Task@1.0.0', + target: 'xnet://xnet.fyi/Task@2.0.0', + forward: (data) => ({ + ...data, + status: data.complete ? 'done' : 'todo' + }), + backward: (data) => ({ + ...data, + complete: data.status === 'done' + }), + lossless: false +} +// The old app keeps reading v1. The new app reads v2. +// Nobody migrates anybody. Nobody asks a vendor. +``` + +## Risks And Open Questions + +- **Overlap discipline with #10.** Both essays end on views-over-data. #11 + must link #10 for moddability/scoping and never re-argue it. Mitigation: + the overlap-audit table above is the outline's contract. +- **Quote accuracy — largely retired.** All quotes in External Research were + verified verbatim against live fetches during this exploration; one + misattribution in the brief was caught (the "two apps… instantly update" + line is Rhizome, not the Reboot essay). Re-check only if the draft + paraphrases beyond the verified excerpts. Two link gotchas: Ink & Switch + is `/essay/local-first/` (bare `/local-first/` serves empty); no Brander + piece called "the data pod problem" exists — don't cite that phrase. +- **Solid critique fairness.** Verborgh still works on Solid, and the + sharpest critique of pod-interop ("What's in a Pod?") is _his own team's_ + paper — cite it as self-aware course-correction, not failure. Tone: + gratitude for expensive lessons. +- **Does the AI-inversion close overclaim?** Vendors retain moats beyond + data custody (distribution, brand, compliance). Scope the claim to: custody + stops being a _defensible_ moat and starts being a visible hostage fee. +- Open question: include the Rhizome→xNet convergence table (EAV/UCAN/CRDT vs + nodes/capabilities/LWW)? Nice depth, but risks inside-baseball; decide at + draft time based on length. + +## Implementation Checklist + +- [ ] Use only the verbatim-verified quotes from External Research (already + checked against live sources; Rhizome vs Reboot attribution fixed); + link Ink & Switch as `/essay/local-first/`. +- [ ] Write `site/src/pages/blog/the-vault-and-the-view.astro` following the + #10 conventions (Byline, SeriesNav, Mermaid, CodeFigure, bespoke hero, + `tok-*` helpers, en-GB, nothing third-party). +- [ ] Add the `posts[]` entry in `site/src/data/blog.ts` (slug + `the-vault-and-the-view`, tags + `['essay','philosophy','decentralization','protocol']`, authors + `['crs48','claude']`, honest `readingMinutes`). +- [ ] Bespoke hero component under `site/src/components/blog/` (vendored + assets only). +- [ ] Cross-link: #7 (the loom / internals), #10 (workshop / scoping), the + protocol spec, and the four external sources with full attribution. +- [ ] SchemaLens `CodeFigure` uses the real API shape from + `packages/data/src/schema/lens.ts` (no invented fields). +- [ ] Changelog fragment via `scripts/changelog/new.mjs` (do not hand-write). +- [ ] Conventional commit(s), header ≤72 chars; no changeset needed (site + only) — but run the Stop-hook check anyway. +- [ ] PR to `main`; merge-commit per repo policy. + +## Validation Checklist + +- [ ] `pnpm --filter site build` (or the site's build task) passes; the post + renders with hero, byline, diagrams, and code figure. +- [ ] Post appears on `/blog` index and in `rss.xml` with correct metadata; + `seriesNeighbors` links #10 ↔ #11 correctly. +- [ ] Every factual claim has a source link or a repo path; quotes match the + live originals verbatim (0247 discipline). +- [ ] No third-party requests on the page (network tab clean). +- [ ] Overlap check: a reader of #10 finds new argument in every section of + #11 (the lineage, the Solid post-mortem, the value-settlement close). +- [ ] Lighthouse/da­rk-mode/mobile spot-check matches the rest of the series. + +## References + +- Ruben Verborgh, _Paradigm shifts for the decentralized Web_ (2017) — + +- Jacky Zhao, _Towards Data Neutrality_ (Reboot, 2022) — + (Reboot original: + ) +- Jacky Zhao, _Rhizome Proposal_ — + +- Ink & Switch, _Local-first software_ (2019) — + +- Leigh Dodds, _Confused by SOLID_ (2024) — + +- SolidLab Research, _What's in a Pod?_ — + +- Gordon Brander, _Redecentralization_ — + +- Moxie Marlinspike, _My first impressions of web3_ (2022) +- Guido X Jansen, _Apps as Views, Not Vaults_ series (gui.do, 2026; Barazo) +- E. F. Codd, _A Relational Model of Data for Large Shared Data Banks_ (1970) +- Steph Ango, _File over app_ — +- Repo: exploration 0267 (+ blog #10), `docs/specs/protocol/`, + `packages/sync/src/change.ts`, `packages/views/src/`, + `packages/data/src/schema/{lens,extension,sidecar}.ts`, + `packages/react/src/hooks/useQuery.ts`, + `packages/plugins/src/feature-module.ts`, `site/src/data/blog.ts` From d68b364ffe4e901b589aaf7ce66382e5b1d5b421 Mon Sep 17 00:00:00 2001 From: xNet Test Date: Tue, 7 Jul 2026 12:23:03 -0700 Subject: [PATCH 2/4] docs(exploration): renumber apps-as-views blog exploration to 0281 0280 is claimed by the malleable-workbench exploration on another branch. Co-Authored-By: Claude Fable 5 Signed-off-by: xNet Test --- ...d => 0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/explorations/{0280_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md => 0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md} (100%) diff --git a/docs/explorations/0280_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md b/docs/explorations/0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md similarity index 100% rename from docs/explorations/0280_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md rename to docs/explorations/0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md From 7b026b906e4d506ea7702ecf8070660585f1e9e2 Mon Sep 17 00:00:00 2001 From: xNet Test Date: Tue, 7 Jul 2026 12:51:45 -0700 Subject: [PATCH 3/4] =?UTF-8?q?feat(site):=20blog=20post=20#11=20=E2=80=94?= =?UTF-8?q?=20The=20Vault=20and=20the=20View=20(0281)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Essay on apps as views over user-owned data: the Codd→Solid→local-first →'views, not vaults' lineage, the pod generation's post-mortem (schema problem, shadow indexes, recentralisation), xNet as the existence proof, and the AI-era close — views become disposable, data becomes the heirloom. Bespoke VaultArt/VaultHero/HonestVault components, two mermaid diagrams, a SchemaLens code figure, verified verbatim quotes throughout. Co-Authored-By: Claude Fable 5 --- ...POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md | 65 +- site/src/components/blog/HonestVault.astro | 55 ++ site/src/components/blog/VaultArt.astro | 208 +++++++ site/src/components/blog/VaultHero.astro | 38 ++ site/src/data/blog.ts | 18 + ...7-07-new-essay-the-vault-and-the-view.json | 8 + site/src/pages/blog/index.astro | 2 + .../pages/blog/the-vault-and-the-view.astro | 556 ++++++++++++++++++ 8 files changed, 917 insertions(+), 33 deletions(-) create mode 100644 site/src/components/blog/HonestVault.astro create mode 100644 site/src/components/blog/VaultArt.astro create mode 100644 site/src/components/blog/VaultHero.astro create mode 100644 site/src/data/changelog/2026-07-07-new-essay-the-vault-and-the-view.json create mode 100644 site/src/pages/blog/the-vault-and-the-view.astro diff --git a/docs/explorations/0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md b/docs/explorations/0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md index d1b9e8fa8..95cec0727 100644 --- a/docs/explorations/0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md +++ b/docs/explorations/0281_[_]_BLOG_POST_APPS_AS_VIEWS_OVER_USER_OWNED_DATA.md @@ -158,12 +158,12 @@ maps to a seam: ### Overlap audit against the existing series -| Existing essay | Its claim | #11's distinct claim | -| --- | --- | --- | -| #10 Workshop/Walled Garden | Views-over-data enables safe **moddability** | The **data–app decoupling itself**: lineage, economics, why pods stalled, where value settles | -| #9 Hand on the Tiller | Steering/cybernetics | — | -| #7 The Loom You Can Read | How the substrate works internally | #11 cites it instead of re-explaining the log | -| #5/#6 economics/permaculture essays | Extraction vs regeneration framing | #11 reuses the moat framing in one paragraph, credits it | +| Existing essay | Its claim | #11's distinct claim | +| ----------------------------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------- | +| #10 Workshop/Walled Garden | Views-over-data enables safe **moddability** | The **data–app decoupling itself**: lineage, economics, why pods stalled, where value settles | +| #9 Hand on the Tiller | Steering/cybernetics | — | +| #7 The Loom You Can Read | How the substrate works internally | #11 cites it instead of re-explaining the log | +| #5/#6 economics/permaculture essays | Extraction vs regeneration framing | #11 reuses the moat framing in one paragraph, credits it | The seam is clean: #10 was "what you can build **on top** once apps are views"; #11 is "why apps should be views **at all**, who said so first, and @@ -178,8 +178,7 @@ was corrected: the "two apps… instantly update both" line is from Zhao's ### The canon (verified, with exact quotes) -- **Ruben Verborgh, "Paradigm shifts for the decentralized Web" (20 Dec - 2017)** — . +- **Ruben Verborgh, "Paradigm shifts for the decentralized Web" (20 Dec 2017)** — . Three shifts: end users become data controllers; **apps become views**; **interfaces become queries**. Exact: _"Applications as interchangeable views, wherein each Web app provides consistent visualizations, @@ -333,12 +332,12 @@ was corrected: the "two apps… instantly update both" line is from Zhao's ### Framing options for the essay -| Option | Shape | Pros | Cons | -| --- | --- | --- | --- | -| **A. Intellectual-lineage essay** ("the 25-year detour") | History → diagnosis → mechanism → xNet → AI inversion | Distinct from #10; deep; flatters sources honestly | Risk of book-report tone if quotes dominate | -| B. Polemic on data moats | Economics-first attack on silos | Punchy | Overlaps #5 (Leveragism) and the surveillance framing of #4/#6; thin on mechanism | -| C. Product-explainer ("how xNet does views") | Architecture tour | Concrete | Reads as marketing; #7 already toured internals | -| D. Pure AI-angle ("views are disposable now") | Lead with the 2026 inversion | Freshest claim | Loses the commissioned brief (the sources) to a hook | +| Option | Shape | Pros | Cons | +| -------------------------------------------------------- | ----------------------------------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------- | +| **A. Intellectual-lineage essay** ("the 25-year detour") | History → diagnosis → mechanism → xNet → AI inversion | Distinct from #10; deep; flatters sources honestly | Risk of book-report tone if quotes dominate | +| B. Polemic on data moats | Economics-first attack on silos | Punchy | Overlaps #5 (Leveragism) and the surveillance framing of #4/#6; thin on mechanism | +| C. Product-explainer ("how xNet does views") | Architecture tour | Concrete | Reads as marketing; #7 already toured internals | +| D. Pure AI-angle ("views are disposable now") | Lead with the 2026 inversion | Freshest claim | Loses the commissioned brief (the sources) to a hook | **A, with D as the closing movement**, honours the brief (the sources ARE the story) while contributing a new argument. B's moat point becomes one section @@ -346,12 +345,12 @@ inside A; C's architecture becomes the receipts, not the subject. ### Title options -| Title | Notes | -| --- | --- | +| Title | Notes | +| ------------------------------- | ------------------------------------------------------------------------------------------------------- | | **"The Vault and the View"** ✅ | Series-consistent metaphor pair (cf. Workshop/Walled Garden, Forest/Field); credits "views, not vaults" | -| "Apps Are Views, Not Vaults" | Punchier but borrows the slogan wholesale as a headline | -| "The Twenty-Five-Year Detour" | Strong but opaque on the index card | -| "Many Windows, One House" | Gentler; weaker link to the sources' language | +| "Apps Are Views, Not Vaults" | Punchier but borrows the slogan wholesale as a headline | +| "The Twenty-Five-Year Detour" | Strong but opaque on the index card | +| "Many Windows, One House" | Gentler; weaker link to the sources' language | ### Cold-open options @@ -371,7 +370,7 @@ Write **blog post #11, "The Vault and the View"** (framing A+D): yours in the way that mattered — the _shape_ belonged to the vault. 2. **The detour:** Codd's data independence → Unix files → desktop documents → the web app as the anomaly that fused data to interface. The fusion was - a business model (moat) *and* an engineering convenience — concede both. + a business model (moat) _and_ an engineering convenience — concede both. 3. **The diagnosis generation:** Verborgh's "apps become views" (quote), Solid's pods; why the vision was right and the mechanism stalled (schema negotiation tax, server-resident documents, pod-first adoption). @@ -476,39 +475,39 @@ const taskV1toV2: SchemaLens = { ## Implementation Checklist -- [ ] Use only the verbatim-verified quotes from External Research (already +- [x] Use only the verbatim-verified quotes from External Research (already checked against live sources; Rhizome vs Reboot attribution fixed); link Ink & Switch as `/essay/local-first/`. -- [ ] Write `site/src/pages/blog/the-vault-and-the-view.astro` following the +- [x] Write `site/src/pages/blog/the-vault-and-the-view.astro` following the #10 conventions (Byline, SeriesNav, Mermaid, CodeFigure, bespoke hero, `tok-*` helpers, en-GB, nothing third-party). -- [ ] Add the `posts[]` entry in `site/src/data/blog.ts` (slug +- [x] Add the `posts[]` entry in `site/src/data/blog.ts` (slug `the-vault-and-the-view`, tags `['essay','philosophy','decentralization','protocol']`, authors `['crs48','claude']`, honest `readingMinutes`). -- [ ] Bespoke hero component under `site/src/components/blog/` (vendored +- [x] Bespoke hero component under `site/src/components/blog/` (vendored assets only). -- [ ] Cross-link: #7 (the loom / internals), #10 (workshop / scoping), the +- [x] Cross-link: #7 (the loom / internals), #10 (workshop / scoping), the protocol spec, and the four external sources with full attribution. -- [ ] SchemaLens `CodeFigure` uses the real API shape from +- [x] SchemaLens `CodeFigure` uses the real API shape from `packages/data/src/schema/lens.ts` (no invented fields). -- [ ] Changelog fragment via `scripts/changelog/new.mjs` (do not hand-write). +- [x] Changelog fragment via `scripts/changelog/new.mjs` (do not hand-write). - [ ] Conventional commit(s), header ≤72 chars; no changeset needed (site only) — but run the Stop-hook check anyway. - [ ] PR to `main`; merge-commit per repo policy. ## Validation Checklist -- [ ] `pnpm --filter site build` (or the site's build task) passes; the post +- [x] `pnpm --filter site build` (or the site's build task) passes; the post renders with hero, byline, diagrams, and code figure. -- [ ] Post appears on `/blog` index and in `rss.xml` with correct metadata; +- [x] Post appears on `/blog` index and in `rss.xml` with correct metadata; `seriesNeighbors` links #10 ↔ #11 correctly. -- [ ] Every factual claim has a source link or a repo path; quotes match the +- [x] Every factual claim has a source link or a repo path; quotes match the live originals verbatim (0247 discipline). -- [ ] No third-party requests on the page (network tab clean). -- [ ] Overlap check: a reader of #10 finds new argument in every section of +- [x] No third-party requests on the page (network tab clean). +- [x] Overlap check: a reader of #10 finds new argument in every section of #11 (the lineage, the Solid post-mortem, the value-settlement close). -- [ ] Lighthouse/da­rk-mode/mobile spot-check matches the rest of the series. +- [x] Lighthouse/da­rk-mode/mobile spot-check matches the rest of the series. ## References diff --git a/site/src/components/blog/HonestVault.astro b/site/src/components/blog/HonestVault.astro new file mode 100644 index 000000000..ed2310838 --- /dev/null +++ b/site/src/components/blog/HonestVault.astro @@ -0,0 +1,55 @@ +--- +// The honesty beat for post #11 (exploration 0281), modeled on HonestWorkshop / +// HonestTiller / HonestGarden. An essay that says "apps should be views over +// data you own" is standing on a pile of projects that said the same thing and +// stalled — Solid pods, WinFS, the semantic desktop — so it owes the reader a +// plain account of why they stalled and what this attempt does differently. +// The rows concede the strongest standing objections rather than dodging them. +const rows = [ + { + isnt: 'We won’t pretend two apps agreeing on data is a solved problem.', + is: 'Schema agreement is the hard part — Solid’s own researchers concluded that apps failed to reuse each other’s data because each one baked in private assumptions about layout. Our answer is not a grand shared ontology; it’s published, versioned schemas plus lenses, overlays, and sidecars that make disagreement cheap. Views can differ about shape without forking the data.' + }, + { + isnt: 'We won’t pretend a general-purpose store is fast for free.', + is: 'Purpose-built silos are quick because they optimise for exactly one access pattern. Making one open substrate feel app-fast took us months of unglamorous engineering — a dozen pull requests on query batching, hydration, and cold-start alone. The convenience of the vault is real; it just isn’t worth the walls.' + }, + { + isnt: 'We won’t pretend decoupling data from apps removes the need for trust.', + is: 'A view still runs with access to the slice it renders, and a malicious view is still malicious. That’s a different essay — the previous one, in fact — but the short version is: every view here declares what it can see and touch, and the declaration is enforced, not promised.' + }, + { + isnt: 'We won’t pretend decentralisation can’t recentralise one layer up.', + is: 'Gordon Brander’s law is real: unbundle the data layer and power tends to reappear at the index, the relay, the host. Our hedge is structural — the local replica is primary, the hub is an optional peer you can replace, and leaving with everything is a supported, documented act rather than a scraping exercise.' + } +] +--- + +
+
+

+ An honest inversion +

+

+ The graveyard of systems that promised this is well populated. Here’s + what the residents taught us, and where the romance stops. +

+ +
    + { + rows.map((row) => ( +
  • +
    + +

    {row.isnt}

    +
    +
    + +

    {row.is}

    +
    +
  • + )) + } +
+
+
diff --git a/site/src/components/blog/VaultArt.astro b/site/src/components/blog/VaultArt.astro new file mode 100644 index 000000000..6d5f2543c --- /dev/null +++ b/site/src/components/blog/VaultArt.astro @@ -0,0 +1,208 @@ +--- +// Decorative art for blog post #11 (exploration 0281), extracted so the same +// inline SVG backs both the post hero and the blog-index preview card (no +// external assets — Self-Audit parity). The scene is the essay's title drawn +// literally: on the left, a bank vault — a sealed circular door with a dial +// and rivets, and a small barred slot behind which a few dim data points sit +// locked away. On the right, the inversion: one glowing hash-chained substrate +// running along the ground, holding the same points in the open, with three +// floating window frames above it — list, grid, timeline — each looking onto +// the same data and drawing sight-lines down to it. The cosmic-X hangs +// overhead as the reading lamp. A dotted footpath runs from the vault to the +// substrate: the walk from custody to ownership. +interface Props { + /** Override the wrapper classes; defaults to full-bleed for hero use. */ + class?: string +} +const { class: className = 'pointer-events-none absolute inset-0 h-full w-full' } = + Astro.props + +// Rivets around the vault door rim (angle in degrees). +const rivets = Array.from({ length: 12 }, (_, i) => { + const a = (i * 30 * Math.PI) / 180 + return [170 + Math.cos(a) * 96, 190 + Math.sin(a) * 96] +}) +// The hash-chained substrate blocks along the ground on the right. +const chain = [430, 520, 610, 700, 790, 880] +// The footpath from the vault out to the substrate. +const path = [ + [292, 306], + [340, 300], + [388, 302], + [430, 314] +] + .map(([x, y]) => `${x},${y}`) + .join(' ') +// The shared data points sitting on the substrate (x, y). +const nodes = [ + [455, 262], + [545, 250], + [635, 266], + [725, 248], + [815, 260], + [905, 252] +] +--- + + diff --git a/site/src/components/blog/VaultHero.astro b/site/src/components/blog/VaultHero.astro new file mode 100644 index 000000000..e735a4c81 --- /dev/null +++ b/site/src/components/blog/VaultHero.astro @@ -0,0 +1,38 @@ +--- +// Hero band for blog post #11 (exploration 0281). The decorative art lives in +// VaultArt.astro so the same inline SVG backs both this hero and the +// blog-index preview card; this component layers the post's title/deck over it. +import VaultArt from './VaultArt.astro' + +interface Props { + title: string + deck: string + date: string + readingMinutes: number + tags: string[] +} +const { title, deck, date, readingMinutes, tags } = Astro.props +--- + +
+ + +
+
+ + + {readingMinutes} min read + { + tags.map((tag) => ( + + {tag} + + )) + } +
+

+ {title} +

+

{deck}

+
+
diff --git a/site/src/data/blog.ts b/site/src/data/blog.ts index d8feb61fc..aad0c5ce5 100644 --- a/site/src/data/blog.ts +++ b/site/src/data/blog.ts @@ -86,6 +86,24 @@ export interface BlogPost { } export const posts: BlogPost[] = [ + { + slug: 'the-vault-and-the-view', + title: 'The Vault and the View', + description: + 'When Google Reader died, everyone got an export — and discovered the ' + + 'file was a brick, shaped for a renderer that no longer existed. The ' + + 'modern app is a vault: it holds your data and the only window onto it. ' + + 'But the vault is a twenty-five-year detour, not the tradition — from ' + + 'Codd’s data independence through Solid’s pods to local-first and “apps ' + + 'as views, not vaults”, five decades of people have insisted the data is ' + + 'the ground and the software is the weather. On that lineage, why the ' + + 'first pod-shaped attempt stalled, how xNet ships the inversion — and ' + + 'why AI-cheap views make user-owned data the only stable ground left.', + pubDate: '2026-07-07T21:00:00Z', + authors: ['crs48', 'claude'], + tags: ['essay', 'philosophy', 'decentralization', 'protocol'], + readingMinutes: 14 + }, { slug: 'the-workshop-and-the-walled-garden', title: 'The Workshop and the Walled Garden', diff --git a/site/src/data/changelog/2026-07-07-new-essay-the-vault-and-the-view.json b/site/src/data/changelog/2026-07-07-new-essay-the-vault-and-the-view.json new file mode 100644 index 000000000..cbbd14065 --- /dev/null +++ b/site/src/data/changelog/2026-07-07-new-essay-the-vault-and-the-view.json @@ -0,0 +1,8 @@ +{ + "id": "2026-07-07-new-essay-the-vault-and-the-view", + "date": "July 7, 2026", + "title": "New essay: The Vault and the View", + "summary": "Blog post #11 traces the fifty-year lineage of apps-as-views-over-your-data — from Codd's data independence through Solid's pods and local-first to xNet's substrate — and why AI-cheap views make user-owned data the ground that's left.", + "highlights": [], + "tags": ["platform"] +} diff --git a/site/src/pages/blog/index.astro b/site/src/pages/blog/index.astro index f0a63b8f4..ca8bc83b3 100644 --- a/site/src/pages/blog/index.astro +++ b/site/src/pages/blog/index.astro @@ -12,6 +12,7 @@ import LoomArt from '../../components/blog/LoomArt.astro' import HookArt from '../../components/blog/HookArt.astro' import TillerArt from '../../components/blog/TillerArt.astro' import WorkshopArt from '../../components/blog/WorkshopArt.astro' +import VaultArt from '../../components/blog/VaultArt.astro' import Byline from '../../components/blog/Byline.astro' import { publishedPosts, formatPostDate } from '../../data/blog' @@ -20,6 +21,7 @@ const posts = publishedPosts() // Each post's art-directed hero art doubles as its preview-card header image, so // the same inline SVG is single-sourced from the hero's *Art.astro component. const heroArt: Record = { + 'the-vault-and-the-view': VaultArt, 'the-workshop-and-the-walled-garden': WorkshopArt, 'hand-on-the-tiller': TillerArt, 'the-tip-of-the-hook': HookArt, diff --git a/site/src/pages/blog/the-vault-and-the-view.astro b/site/src/pages/blog/the-vault-and-the-view.astro new file mode 100644 index 000000000..55741a147 --- /dev/null +++ b/site/src/pages/blog/the-vault-and-the-view.astro @@ -0,0 +1,556 @@ +--- +import Base from '../../layouts/Base.astro' +import Nav from '../../components/sections/Nav.astro' +import Footer from '../../components/sections/Footer.astro' +import SeriesNav from '../../components/blog/SeriesNav.astro' +import VaultHero from '../../components/blog/VaultHero.astro' +import Byline from '../../components/blog/Byline.astro' +import Mermaid from '../../components/blog/Mermaid.astro' +import CodeFigure from '../../components/blog/CodeFigure.astro' +import HonestVault from '../../components/blog/HonestVault.astro' +import { postBySlug, formatPostDate } from '../../data/blog' + +const post = postBySlug('the-vault-and-the-view')! + +// --- syntax highlighting helpers (same tok-* idiom as the landing page's +// CodeBlock; coloured by the CSS variables in Base.astro). +const kw = (s: string) => `${s}` +const st = (s: string) => `${s}` +const cm = (s: string) => `${s}` + +// The essay's central exhibit: a schema lens — two views disagreeing about +// shape without forking the data. Field names match the real SchemaLens API +// in packages/data/src/schema/lens.ts. +const lensCode = [ + `${cm('// A lens is a treaty between two views of the same nodes.')}`, + `${kw('const')} taskV1toV2: SchemaLens = {`, + ` source: ${st("'xnet://xnet.fyi/Task@1.0.0'")},`, + ` target: ${st("'xnet://xnet.fyi/Task@2.0.0'")},`, + ` forward: (data) => ({`, + ` ...data,`, + ` status: data.complete ? ${st("'done'")} : ${st("'todo'")}`, + ` }),`, + ` backward: (data) => ({`, + ` ...data,`, + ` complete: data.status === ${st("'done'")}`, + ` }),`, + ` lossless: ${kw('false')}`, + `}`, + `${cm('// The old view keeps reading v1. The new view reads v2.')}`, + `${cm('// Nobody migrates anybody. Nobody asks a vendor.')}` +].join('\n') + +// --- mermaid diagram sources (rendered client-side by ) --- +const inversion = `flowchart LR + subgraph vaults["The vault era — data fused to the app"] + A1["App A
your data inside"] + A2["App B
your data inside"] + A1 -. "CSV export
(a brick)" .-> A2 + end + subgraph views["Apps as views — data as the ground"] + LOG["Your substrate:
one signed, hash-chained
change log"] --> STORE[("Schema-typed nodes")] + STORE -->|lens| T["Tasks view"] + STORE -->|lens| B["Board view"] + STORE -->|lens| C["Canvas view"] + STORE -->|"SchemaLens
v1 ↔ v2"| N["Next year's view,
generated in an evening"] + end + vaults ==>|"the inversion"| views` + +const twoViews = `sequenceDiagram + participant You + participant S as One store of nodes + participant T as Tasks view + participant C as Calendar view + You->>T: tick a task done + T->>S: append one signed change + S-->>T: live query update + S-->>C: live query update + Note over T,C: two views, one change —
both update, instantly` +--- + + +