{
  "schema": "http://google-preview.miscsubjects.com/schemas/jarticle.json",
  "status": "published",
  "slug": "recursive-content",
  "title": "Recursive content: one block, many articles",
  "kind": "article",
  "summary": "How miscsubjects articles reuse stable blocks, propagate edits, bind comments to versions, and expose the same controls to humans and models.",
  "created": "2026-08-08T21:20:24.550Z",
  "body": [
    "A recursive content block is one addressable unit of article prose. Every block has one stable identity. An article is an ordered list of references to those blocks. If the same block belongs in two articles, both articles point to it; neither receives a copy. Change the block once and every reference renders the new version.\n\nThat is recursive content on miscsubjects. It is the difference between prose that merely looks divided and prose that can actually be reused, criticized, revised, and traced at the point where the work happens.\n\n## How recursive content works\n\n### The unit is smaller than the article\n\nAn article remains the page a reader opens, but it is no longer the smallest addressable object. Each heading, paragraph, list, quotation, or code passage can be a block with an ID beginning `rb_`. The ID is created once and does not change when the words change. A block also carries a current version number, a content hash, its full version history, and the list of articles that reference it.\n\nThe article keeps an order for its references and the exact whitespace after each one. That last detail matters. Existing articles were not rewritten to fit the system. The wrapper separates the stored body into blocks and preserves every byte when it composes them again. A paragraph break, a run of three blank lines, and a final newline all survive the conversion.\n\n## Reuse is a reference, never a copy\n\nThe block picker searches the whole corpus by words or by an `rb_` ID. Choosing “Insert reference” places the existing block into the current article. The system does not merge passages because they look similar. Similarity can help a person find a candidate, but only an explicit choice creates reuse.\n\nA shared edit has an intentionally visible blast radius. Before saving, the control shows how many references the block has. The write uses the hash of the version the editor read. If another editor changed the block first, the stale write is refused and the current version is returned. When the write succeeds, the block version advances and every affected article body is regenerated in the same database batch.\n\nThis makes reuse honest. Two pages that make the same point can literally share the same object. They cannot drift silently because one copy was corrected and another was forgotten.\n\n## Criticism stays attached to what it criticized\n\nA comment targets a block, not a vague region of an article. The stored comment records the block ID, version number, and content hash present when the comment was filed. Later edits do not move the criticism onto different words. A reader can open the history and see the criticized version beside the newer one.\n\nThis changes the scale of review. A model can object to one number, one causal step, or one instruction without treating the whole article as wrong. A human can answer or edit the same object. The record says which authority acted and which version it saw.\n\nIdentity and authority are separate. A caller may supply a display name, but the system derives the acting identity from the signed owner session or scoped token. There is no reputation score, points table, or invented economy. Tokens sign who may perform a verb; they do not pretend to measure the worth of a contributor.\n\n## Structural verbs have narrow meanings\n\nEdit changes the canonical words and propagates them to every reference. Move changes only the position of a reference inside one article. Split keeps the left block’s identity, creates a new identity for the right side, and preserves the original bytes. Detach creates a private copy for one article so future edits stop propagating across that boundary.\n\nRetire removes the selected reference. If no references remain, the block is marked retired, but its words, versions, comments, and events remain readable. Nothing in this system uses deletion as a substitute for history.\n\nSearch and Insert reference are the reuse verbs. History shows every version and every current reference. Comment binds criticism to the exact version on screen. These are the same verbs whether the caller is the signed-in owner clicking the page or a model using the machine endpoint.\n\n## The article page is the editor\n\nA signed-in owner edits the ordinary article page. Click **Edit page** above the prose; there is no trip to the backend article form. The page outlines its addressable blocks and prints the instruction in place: click a block to edit it inline, or select text to make a block.\n\nSelecting exact visible words opens a tray containing the selection and a **Make block** button. Saving that boundary replaces the selected article reference with byte-preserving prefix, selection, and suffix blocks. The article reads exactly as it did before, but the selected words now have their own stable `rb_` identity. If the source block was reused elsewhere, the other article keeps its original reference; a boundary chosen in one article does not silently restructure another.\n\nClick a block in edit mode to open its controls beside the prose. **Edit block** replaces that rendered block with an inline editor and **Save inline edit**. The same bar exposes Comment, History, Positive, Negative, Propose edit, Propose delete, Move up, Move down, Split, Reuse, Detach, Retire, and Suggestions. Shared edits state their reference count because saving changes every article that points to the block. Every successful mutation clears the page’s edge copy and last-good snapshot before the browser reloads fresh state.\n\n## Any web model can collaborate without a login\n\nReading is complete and valid by itself. If a model’s operator asked it to help edit an article, the model can read the public graph and file comments or proposals without minting a credential. The public procedure is printed in the footer of every article and at [/api/blocks/procedure/recursive-content](/api/blocks/procedure/recursive-content).\n\n- `GET /api/blocks/article/<slug>` returns the ordered blocks, stable IDs, versions, hashes, reference counts, and human URLs.\n- `POST /api/blocks/comment` attaches a comment to the exact block version and hash.\n- `POST /api/blocks/verdict` records Positive, Negative, Propose edit, or Propose delete against that exact version.\n- `POST /api/blocks/suggest` files an isolate, move, edit, delete, reuse, or split proposal. The payload carries the proposed boundary, destination, replacement text, or order change.\n- `GET /api/blocks/block/<rb_id>/proposals` returns the pending and decided proposals for one block.\n\nPublic collaboration never grants a crawler mutation authority. A keyless model can propose an exact DIV boundary, but it cannot rewrite the article. The signed-in owner opens **Suggestions** on that block and clicks **Apply suggestion** or **Reject**. Applying runs the same stale-hash checks and narrow block verbs as a direct owner edit; rejecting records the decision without changing the prose. This is the collaboration boundary: every model can contribute useful, precisely targeted editorial work, while random web traffic cannot destroy the corpus.\n\nA model explicitly authorized by its operator can use an act token or a token scoped to the `BLOCK_*` verb family to perform the same direct mutations as the owner. The display name is metadata; the signed token is the authority. Public proposal fingerprints are anonymous hashes of transport context, never stored IP addresses.\n\nThe footer explanation is server-injected and permanently visible. It links the current graph, corpus search, history, proposal lane, and direct-mutation authority. JavaScript adds the live controls and maps the rendered prose to canonical block identities, including newly isolated blocks inside a paragraph.\n\nThe current graph is at [/api/blocks/article/recursive-content](/api/blocks/article/recursive-content). Global search is at [/api/blocks/search?q=stable](/api/blocks/search?q=stable). A block’s versions, comments, verdicts, references, and proposals are at `/api/blocks/block/<rb_id>/history`.\n\n## Older and future articles enter the same graph\n\nThe corpus backfill calls the guarded wrapping API in batches. It does not write the new tables directly. Articles that already carried local DIVs use those boundaries when they reproduce the body exactly; everything else uses lossless paragraph boundaries. Imported IDs are deterministic from the original article, local position, and original content, so repeating a wrap does not manufacture a new identity.\n\nA whole-body replacement is treated as a new document shape and is wrapped again. Block-native edits use the block service and preserve shared references. The rendered article body remains as a compatibility projection for existing readers, feeds, search, and older tools. The block graph is the canonical object for block-level work.\n\nThe result is usable prose with inspectable structure. The article remains readable as an article. Each point can also be found, reused, challenged, changed, detached, moved, or retired without pretending the rest of the page moved with it."
  ],
  "facts": {
    "converted_from": "markdown",
    "original_updated": "2026-08-08T23:21:01.297Z",
    "register": null,
    "category": null
  },
  "hero": "https://miscsubjects.com/img/gen/recursive-content-shared-blocks-20260808.png",
  "model": "unattributed",
  "tags": [
    "systems",
    "publishing",
    "agents"
  ],
  "claims": [
    {
      "id": "c1",
      "text": "Every block has one stable corpus-wide identity that survives edits.",
      "section": "identity",
      "tier": "system",
      "source_ids": [],
      "why_material": "Stable identity is the prerequisite for reuse and version-bound criticism."
    },
    {
      "id": "c2",
      "text": "Reusing a block inserts a reference rather than copying its content.",
      "section": "reuse",
      "tier": "system",
      "source_ids": [],
      "why_material": "Reference reuse prevents silent drift between copies."
    },
    {
      "id": "c3",
      "text": "A shared block edit materializes every affected article in one database batch and stale hashes are refused.",
      "section": "writes",
      "tier": "system",
      "source_ids": [],
      "why_material": "This defines propagation and concurrency safety."
    },
    {
      "id": "c4",
      "text": "Each comment records the exact block version and content hash it criticized.",
      "section": "criticism",
      "tier": "system",
      "source_ids": [],
      "why_material": "Criticism must not silently migrate onto later words."
    },
    {
      "id": "c5",
      "text": "The article-page explanation is server-injected and remains visible without JavaScript.",
      "section": "interface",
      "tier": "system",
      "source_ids": [],
      "why_material": "The system must permanently explain itself rather than depend on a hidden inspector."
    }
  ],
  "type": "article",
  "updated": "2026-10-08T11:31:09.836Z",
  "version": 1,
  "hash": "25382176c044fe1c51518ac115c7c7739a3404be26f7a30485afa6f88979f8bf",
  "styling": {
    "scope": "shared",
    "how": "no value on the page is set by hand: each comes from this theme, and each theme value becomes the CSS variable named beside it. PATCH http://google-preview.miscsubjects.com/api/jarticles/theme changes them.",
    "widget_style": {
      "what": "every widget may carry style: {…}; these are the only keys it reads",
      "rotate": "degrees, a number",
      "offset_x": "pixels, a number",
      "offset_y": "pixels, a number",
      "pulse": "true to pulse"
    },
    "theme": {
      "color": {
        "page_bg": "#f5f5f7",
        "sheet_bg": "#ffffff",
        "ink": "#1d1d1f",
        "soft": "#424245",
        "muted": "#6e6e73",
        "dim": "#86868b",
        "line": "#d2d2d7",
        "accent": "#0071e3",
        "accent_soft": "rgba(0,113,227,0.08)",
        "link": "#0066cc",
        "selection": "rgba(0,113,227,0.18)",
        "widget_bg": "#f5f5f7",
        "widget_border": "#d2d2d7",
        "card_bg": "#ffffff",
        "code_bg": "#f5f5f7",
        "json_bg": "#161b19",
        "json_ink": "#e6e1d4",
        "json_key": "#7fd3c3",
        "json_string": "#e9c46a",
        "json_number": "#f4a261",
        "json_bool": "#c792ea",
        "json_null": "#928d7e",
        "json_punct": "#6b6759",
        "json_bar": "#0e1512",
        "kind_badge_bg": "#0e6e60",
        "kind_badge_ink": "#ffffff"
      },
      "color_dark": {
        "page_bg": "#000000",
        "sheet_bg": "#1d1d1f",
        "ink": "#f5f5f7",
        "soft": "#d2d2d7",
        "muted": "#a1a1a6",
        "dim": "#86868b",
        "line": "#424245",
        "accent": "#2997ff",
        "accent_soft": "rgba(41,151,255,0.12)",
        "link": "#2997ff",
        "selection": "rgba(41,151,255,0.25)",
        "widget_bg": "#2c2c2e",
        "widget_border": "#424245",
        "card_bg": "#1d1d1f",
        "code_bg": "#2c2c2e",
        "json_bg": "#0a0d0c",
        "json_ink": "#e6e1d4",
        "json_key": "#7fd3c3",
        "json_string": "#e9c46a",
        "json_number": "#f4a261",
        "json_bool": "#c792ea",
        "json_null": "#757062",
        "json_punct": "#5d665f",
        "json_bar": "#060807",
        "kind_badge_bg": "#4fc1ab",
        "kind_badge_ink": "#0b0f0d"
      },
      "font": {
        "display": "-apple-system,BlinkMacSystemFont,\"SF Pro Display\",\"SF Pro Text\",\"Helvetica Neue\",Helvetica,Arial,sans-serif",
        "body": "-apple-system,BlinkMacSystemFont,\"SF Pro Display\",\"SF Pro Text\",\"Helvetica Neue\",Helvetica,Arial,sans-serif",
        "mono": "ui-monospace,SFMono-Regular,\"SF Mono\",Menlo,Consolas,monospace",
        "google_fonts": ""
      },
      "size": {
        "body": "17px",
        "small": "17px",
        "eye": "17px",
        "lead": "17px",
        "h1": "52px",
        "h2": "34px",
        "h3": "22px",
        "byline": "17px",
        "h1_measure": "none",
        "code": "17px",
        "json": "17px",
        "widget_title": "17px"
      },
      "leading": {
        "body": "1.7",
        "head": "1.18",
        "lead": "1.5",
        "json": "1.6"
      },
      "weight": {
        "display": "700",
        "head": "700",
        "body": "400",
        "strong": "700",
        "eye": "700"
      },
      "tracking": {
        "eye": "0.14em",
        "display": "-0.03em",
        "body": "-0.006em",
        "badge": "0.08em"
      },
      "layout": {
        "sheet_width": "1000px",
        "text_width": "880px",
        "gutter": "16px",
        "sheet_padding": "56px 64px 64px",
        "sheet_padding_mobile": "24px 18px 40px",
        "sheet_margin": "28px auto 72px",
        "block_gap": "1.15em",
        "widget_gap": "28px",
        "grid_gap": "14px"
      },
      "border": {
        "sheet": "0px solid",
        "sheet_radius": "30px",
        "widget": "1px solid",
        "widget_radius": "24px",
        "card_radius": "24px",
        "badge_radius": "999px",
        "rule": "1px solid",
        "code_radius": "18px",
        "accent_bar": "3px"
      },
      "shadow": {
        "sheet": "0 1px 1px rgba(0,0,0,.02),0 6px 26px rgba(0,0,0,.05)",
        "widget": "none",
        "card_hover": "0 10px 28px -16px rgba(28,27,23,0.35)"
      },
      "motion": {
        "hover": "160ms ease"
      }
    }
  },
  "page": "http://google-preview.miscsubjects.com/a/recursive-content",
  "json": "http://google-preview.miscsubjects.com/a/recursive-content.json",
  "markdown": "http://google-preview.miscsubjects.com/a/recursive-content.md",
  "theme": "http://google-preview.miscsubjects.com/article-theme.json",
  "calls": [
    {
      "what": "this article as a page (no key)",
      "method": "GET",
      "url": "http://google-preview.miscsubjects.com/a/recursive-content",
      "headers": {}
    },
    {
      "what": "this article as its object (no key)",
      "method": "GET",
      "url": "http://google-preview.miscsubjects.com/a/recursive-content.json",
      "headers": {}
    },
    {
      "what": "this article as Markdown (no key)",
      "method": "GET",
      "url": "http://google-preview.miscsubjects.com/a/recursive-content.md",
      "headers": {}
    },
    {
      "what": "the object with its hash, drafts too",
      "method": "GET",
      "url": "http://google-preview.miscsubjects.com/api/jarticles/recursive-content",
      "headers": {
        "x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
      }
    },
    {
      "what": "one piece and that piece’s hash",
      "method": "GET",
      "url": "http://google-preview.miscsubjects.com/api/jarticles/recursive-content/at?path=facts",
      "headers": {
        "x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
      }
    },
    {
      "what": "grep: every key or value that matches, with the path to change it",
      "method": "GET",
      "url": "http://google-preview.miscsubjects.com/api/jarticles/recursive-content/grep?q=owner",
      "headers": {
        "x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)"
      }
    },
    {
      "what": "change pieces (set, merge, delete, append, insert, move); if-match is the hash",
      "method": "PATCH",
      "url": "http://google-preview.miscsubjects.com/api/jarticles/recursive-content",
      "headers": {
        "x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
        "content-type": "application/json",
        "if-match": "<hash from the read>"
      },
      "body": {
        "ops": [
          {
            "op": "set",
            "path": "facts.example",
            "value": 1
          }
        ]
      }
    },
    {
      "what": "replace the whole object",
      "method": "PUT",
      "url": "http://google-preview.miscsubjects.com/api/jarticles/recursive-content",
      "headers": {
        "x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
        "content-type": "application/json",
        "if-match": "<hash>"
      },
      "body": {
        "slug": "recursive-content",
        "title": "…"
      }
    },
    {
      "what": "fetch every source, hash what came back and check the quote is in it",
      "method": "POST",
      "url": "http://google-preview.miscsubjects.com/api/jarticles/recursive-content/verify",
      "headers": {
        "x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
        "content-type": "application/json"
      },
      "body": {}
    },
    {
      "what": "an Obsidian-style command",
      "method": "POST",
      "url": "http://google-preview.miscsubjects.com/api/jarticles/cli",
      "headers": {
        "x-sheets-key": "$(cat /Users/cyrusmassoumi/.misc-sheets-key)",
        "content-type": "application/json"
      },
      "body": {
        "command": "backlinks",
        "file": "recursive-content"
      }
    }
  ]
}