{
  "schema": "https://miscsubjects.com/schemas/jarticle.json",
  "status": "published",
  "slug": "the-graph",
  "title": "The Graph",
  "kind": "article",
  "body": [
    "# The Graph\n\nOne store. Every object in it is stored once, under one slug, and every page is a rendering of its object. A page embeds other objects by reference; editing the referenced object changes every page that embeds it. Nothing is copied between pages.\n\nWrites go through one REST contract (linked below): add, read, edit, delete, query. Every edit is checked against the object's current hash. Every object carries a SHA-256 hash, and the export manifest lists all of them.",
    "## The demo — two objects, four surfaces\n\nBelow are two stored objects embedded by reference: a person and a house. On the person's own page, the house appears under \"Prior address.\" On the house's own page, the person appears under \"Prior resident.\" One person object, one house object, one stored relationship — rendered from both sides. The house's Zillow, Redfin, and realtor listings are three further objects, stored separately from the house.",
    {
      "type": "entity",
      "ref": "cyrus-massoumi"
    },
    {
      "type": "entity",
      "ref": "337-melrose-avenue"
    },
    "## Scale — measured 2026-11-04\n\nCanonical layer: **582 published objects in 61 kinds.** Largest kinds: standard 88, procedure 85, article 58, essay 35, technical 32, life-event 24, publication 24, collection 21, systems 21, social_profile 18.\n\nAtlas layer, counted by kind through the query API: **permits 356,695 · parcels 96,253 · people 6,658 · organizations 938 · counties 59 · cities 27.**\n\nTotal queryable objects: **461,212 or more** — the Atlas has no kind census, so its kinds were counted by querying 30 kind names; any kind not queried is not in this sum. Draft and unpublished records are excluded from every count above.",
    "## Live queries — these pages are query results, not documents\n\n- [Current residents of Vichy Avenue](https://miscsubjects.com/graph/query/people-on-vichy-avenue) — executes against the graph; returns 0, because the stored Vichy residence is prior and the query asks for current.\n- [All Gmail addresses on the graph](https://miscsubjects.com/graph/query/gmail-addresses) — returns 1.\n- [All LinkedIn profiles on the graph](https://miscsubjects.com/graph/query/linkedin-profiles)\n- [People at DSCO](https://miscsubjects.com/a/dsco-people)\n- [Export manifest — every published object's id, kind, and hash](https://miscsubjects.com/graph/manifest.json)",
    "## The contract\n\n`POST /api/jarticles` adds an object (201; duplicate slug 409). `GET /api/jarticles/<slug>` returns the record and its hash. `PATCH /api/jarticles/<slug>` edits it, carrying the current hash in `If-Match` (stale hash: 412). `DELETE` removes it under the same rule. `POST /api/jarticles/query` queries by kind, by field, and by typed relationship — for example, people connected by `resides_at` to houses on a named street, current relationships only.\n\nFull contract: [graph-rest-contract/1](https://miscsubjects.com/graph/contract.json). The same operations run from any Google Sheet: [the Sheets guide](https://miscsubjects.com/a/graph-from-google-sheets).",
    "## Receipt — the write cycle, executed 2026-11-04\n\nA test person was added through the contract (HTTP 201, version 1, hash issued), read back, appended to by PATCH (HTTP 200, version 2, new hash; the appended fact verified in the record), deleted under its hash (HTTP 200), and read again (HTTP 404). Add, read, append, delete — each step confirmed by the next."
  ],
  "type": "article",
  "created": "2026-11-05T02:20:37.032Z",
  "updated": "2026-11-05T02:20:37.032Z",
  "version": 1,
  "hash": "7e8ea59fd4f451889dd6fd65f773b5fa497f7838ab58b0f85c4e905dd00f3572",
  "theme": "https://miscsubjects.com/article-theme.json",
  "styling": {
    "scope": "shared",
    "theme_ref": "https://miscsubjects.com/article-theme.json"
  },
  "page": "https://miscsubjects.com/a/the-graph",
  "json": "https://miscsubjects.com/a/the-graph.json",
  "markdown": "https://miscsubjects.com/a/the-graph.md",
  "calls": [
    {
      "what": "this article as a page (no key)",
      "method": "GET",
      "url": "https://miscsubjects.com/a/the-graph",
      "headers": {}
    },
    {
      "what": "this article as its object (no key)",
      "method": "GET",
      "url": "https://miscsubjects.com/a/the-graph.json",
      "headers": {}
    },
    {
      "what": "this article as Markdown (no key)",
      "method": "GET",
      "url": "https://miscsubjects.com/a/the-graph.md",
      "headers": {}
    },
    {
      "what": "the object with its hash, drafts too",
      "method": "GET",
      "url": "https://miscsubjects.com/api/jarticles/the-graph",
      "headers": {
        "x-terminal-key": "<YOUR_TERMINAL_KEY>"
      }
    },
    {
      "what": "one piece and that piece’s hash",
      "method": "GET",
      "url": "https://miscsubjects.com/api/jarticles/the-graph/at?path=facts",
      "headers": {
        "x-terminal-key": "<YOUR_TERMINAL_KEY>"
      }
    },
    {
      "what": "grep: every key or value that matches, with the path to change it",
      "method": "GET",
      "url": "https://miscsubjects.com/api/jarticles/the-graph/grep?q=owner",
      "headers": {
        "x-terminal-key": "<YOUR_TERMINAL_KEY>"
      }
    },
    {
      "what": "change pieces (set, merge, delete, append, insert, move); if-match is the hash",
      "method": "PATCH",
      "url": "https://miscsubjects.com/api/jarticles/the-graph",
      "headers": {
        "x-terminal-key": "<YOUR_TERMINAL_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": "https://miscsubjects.com/api/jarticles/the-graph",
      "headers": {
        "x-terminal-key": "<YOUR_TERMINAL_KEY>",
        "content-type": "application/json",
        "if-match": "<hash>"
      },
      "body": {
        "slug": "the-graph",
        "title": "…"
      }
    },
    {
      "what": "fetch every source, hash what came back and check the quote is in it",
      "method": "POST",
      "url": "https://miscsubjects.com/api/jarticles/the-graph/verify",
      "headers": {
        "x-terminal-key": "<YOUR_TERMINAL_KEY>",
        "content-type": "application/json"
      },
      "body": {}
    },
    {
      "what": "an Obsidian-style command",
      "method": "POST",
      "url": "https://miscsubjects.com/api/jarticles/cli",
      "headers": {
        "x-terminal-key": "<YOUR_TERMINAL_KEY>",
        "content-type": "application/json"
      },
      "body": {
        "command": "backlinks",
        "file": "the-graph"
      }
    }
  ],
  "entities": {
    "the-graph": {
      "id": "the-graph",
      "label": "The Graph",
      "type": "article",
      "page": "https://miscsubjects.com/a/the-graph",
      "json": "https://miscsubjects.com/a/the-graph.json"
    },
    "cyrus-massoumi": {
      "id": "cyrus-massoumi",
      "label": "Cyrus Geav Massoumi",
      "type": "person",
      "page": "https://miscsubjects.com/a/cyrus-massoumi",
      "json": "https://miscsubjects.com/a/cyrus-massoumi.json"
    },
    "337-melrose-avenue": {
      "id": "337-melrose-avenue",
      "label": "337 Melrose Avenue, Mill Valley",
      "type": "house",
      "page": "https://miscsubjects.com/a/337-melrose-avenue",
      "json": "https://miscsubjects.com/a/337-melrose-avenue.json"
    }
  },
  "relationships": {
    "upward": {
      "total": 0,
      "offset": 0,
      "limit": 50,
      "items": [],
      "next": null
    },
    "downward": {
      "total": 0,
      "offset": 0,
      "limit": 50,
      "items": [],
      "next": null
    },
    "sideways": {
      "total": 0,
      "offset": 0,
      "limit": 50,
      "items": [],
      "next": null
    },
    "references": {
      "total": 2,
      "offset": 0,
      "limit": 50,
      "items": [
        {
          "ref": "337-melrose-avenue",
          "predicate": "references",
          "subject": "the-graph",
          "object": "337-melrose-avenue"
        },
        {
          "ref": "cyrus-massoumi",
          "predicate": "references",
          "subject": "the-graph",
          "object": "cyrus-massoumi"
        }
      ],
      "next": null
    },
    "referenced_by": {
      "total": 0,
      "offset": 0,
      "limit": 50,
      "items": [],
      "next": null
    }
  },
  "hierarchy": {
    "paths": [],
    "order": "subject to parent to ancestor",
    "complete": true,
    "cycles": [],
    "limits": {
      "depth": 12,
      "objects": 250
    },
    "unresolved_refs": []
  },
  "reference_contract": {
    "canonical_id": "slug",
    "entity_lookup": "entities[ref]; # resolves to this object via self_ref",
    "self_ref": "the-graph",
    "entity_fields": "page and json are canonical object links; source_url is the external source",
    "directions": {
      "upward": "Parents and collections containing this object; predicate distinguishes location from membership.",
      "downward": "Objects naming this object as their parent, container or collection.",
      "sideways": "Associations and objects sharing a direct parent.",
      "references": "Objects referenced by this record.",
      "referenced_by": "Published articles referencing this record."
    },
    "predicates": {
      "part_of": "Declared parent hierarchy.",
      "located_in": "Location asserted on this object.",
      "associated_parcel": "Associated parcel, a separate object with its own jurisdiction and facts.",
      "member_of": "Collection membership, not geographic containment.",
      "included_in": "Editorial nesting, not geographic containment.",
      "shares_parent": "Shares the identified parent; no other relationship is implied.",
      "related_to": "An association with no more specific predicate recorded."
    },
    "scope": "Published article objects; Atlas inventories have their own counted, paged links. An association does not transfer facts or jurisdiction. An absent neighborhood means no neighborhood relationship is recorded."
  },
  "hash_spec": {
    "algorithm": "sha256",
    "encoding": "lowercase hexadecimal",
    "scope": "stored record; hash is also the write concurrency token",
    "included_keys": [
      "body",
      "created",
      "kind",
      "schema",
      "slug",
      "status",
      "title",
      "type",
      "updated",
      "version"
    ],
    "field_overrides": {
      "schema": "jarticle/1"
    },
    "canonicalization": "Select included_keys from this response, apply field_overrides, recursively sort object keys using JavaScript Object.keys().sort(), retain array order, serialize primitives with JSON.stringify, join without whitespace, hash UTF-8 bytes.",
    "updated_included": true,
    "generated_fields": "All fields absent from included_keys are excluded. Relationship counts and theme references are generated and can change without changing the stored-record hash."
  }
}