{
  "service": "Nomos Cloud",
  "by": "Captain App",
  "url": "https://nomos.cafe",
  "description": "Local-first domains on edge holons. Ledgers are git (custody, not truth); holons verify everything they run.",
  "start": {
    "what": "Author a domain in TypeScript (aggregates + directives on @githolon/dsl), compile it to content-addressed law, run it on an edge holon here. Clients work OFFLINE against the same byte-identical wasm runtime and sync through git; the edge re-verifies every write (admission), trusts nothing.",
    "quickstart": [
      "npm create githolon@latest my-app && cd my-app && npm install",
      "npx githolon compile          # your law package + deploy body + a typed TS client -> build/",
      "npx githolon proof            # a proof GENERATED from your own law - no test rewriting",
      "npx githolon login --agent    # a VERIFIED identity in one command - no browser, no signup form",
      "npx githolon ws create <ws>   # birth a workspace; its one-time secret is saved to ~/.holon for you",
      "npx githolon deploy <ws>      # install your law (Active + content hash back)",
      "npm run e2e                # the full loop, live: offline write -> sync -> edge admission -> cloud query"
    ],
    "localFirst": [
      "npx githolon ledger init holon   # mint a REAL holon locally: genesis + your law, under YOUR identity, verified by the SAME wasm gate this cloud runs",
      "cd holon && npx githolon git remote <ws> && git push nomos main   # the upload birth: the cloud replay-verifies your chain and re-derives your exact local verdict"
    ],
    "authoring": {
      "model": "You write exactly TWO things: aggregates (typed fields, each tagged with a MERGE DRIVER) and directives (a zod payload -> a PURE plan emitting ops). Never apply/fold/merge code - the kernel owns folding. Declared reads (query/count/derived) are auto-discovered from your module's exports.",
      "example": [
        "import { z } from \"zod\";",
        "import { aggregate, t, Lww, AddWins, MapOf, directive, create, instance, set, addToSet, setEntry, query, count } from \"@githolon/dsl\";",
        "",
        "export const Book = aggregate(\"Book\", {",
        "  title: t.string().merge(Lww),             // last write wins",
        "  shelf: t.string().merge(Lww),",
        "  tags:  t.set(t.string()).merge(AddWins),  // concurrent adds ALL survive the merge",
        "  notes: t.map(t.string()).merge(MapOf(Lww)), // per-key LWW",
        "}).public(); // deliberate public catalogue; use .owned() for private business records",
        "",
        "export const addBook = directive(\"addBook\").creates(Book)   // the id is MINTED - payloads never carry one",
        "  .payload(z.object({ title: z.string(), shelf: z.string(), addedAt: z.string() })) // timestamps ride IN the payload",
        "  .plan((p) => { const b = create(Book); b.set(\"title\", p.title); b.set(\"shelf\", p.shelf); return []; });",
        "",
        "export const tagBook = directive(\"tagBook\").mutates(Book)",
        "  .payload(z.object({ bookId: z.string(), tags: z.array(z.string()) }))",
        "  .plan((p) => [addToSet(instance(Book, p.bookId), \"tags\", p.tags)]); // addToSet, NOT set - see planOps",
        "",
        "export const booksByShelf = query(\"booksByShelf\").key(\"shelf\").returns(Book);",
        "export const booksPerShelf = count(\"booksPerShelf\").of(Book).by(\"shelf\");"
      ],
      "planOps": "Plan ops: set (scalars/refs) | addToSet (the ONLY additive write to an AddWins set - set() on a set field is REFUSED at type level and runtime) | setEntry (map key) | strike. Drivers: Lww | AddWins | MapOf(Lww) | Conflict (fail-closed default). Full reference = hover any @githolon/dsl export in your editor.",
      "rules": "Determinism or death: plans are PURE fns of (payload) - timestamps ride IN the payload as ISO strings; ids are MINTED by create()."
    },
    "client": {
      "surface": "@githolon/client ships full TypeScript types - hover connect()/sync()/deadLetters() in your editor for the semantics (e.g. sync() returns admission: null when there was nothing to push - normal, not an error). `githolon compile` emits build/<name>.client.ts (typed methods per directive, accessors per query/count, the law hash baked in) and build/<name>.summary.txt describing exactly what you built.",
      "concurrency": "The scaffold's test/e2e.mts DEMONSTRATES the whole loop live - including two clients with different clientIds tagging the same entry offline and the AddWins union keeping every add. Run npm run e2e; read that file as the tutorial."
    },
    "proof": "`npm run e2e` in a scaffolded app IS the canonical proof of the whole loop: offline write -> sync -> edge admission -> cloud query. Path A (ws create + deploy) and Path B (ledger init + git push) end in the same place - all holons are equal in authority; the chain proves itself either way.",
    "reference": "No separate docs site yet - BY DESIGN the scaffold README is the tutorial and the installed @githolon/dsl + @githolon/client SOURCE is the reference. Reading it is the intended path (the license covers use, not redistribution). Gaps, questions, or want the kernel source? jack@captainapp.co.uk",
    "help": "`npx githolon --help` works ANYWHERE (no install needed) and lists every lane; every refusal names its remedy. The raw HTTP/git surface is the endpoint map below - everything the CLI does, curl and stock git can do."
  },
  "endpoints": {
    "POST /v1/workspaces/:ws": "create a workspace (boots a holon: bootstrap → nomos controller). Placement is AUTOMATIC — a workspace runs on the 12GiB container iff its folded projection outgrows the 128MB edge box; the shell measures, never asks",
    "POST /v1/workspaces/:ws/domains": "deploy a model — the first becomes Active; every successor is committed Pending until its generated client calls model.adopt(); returns content hash + lifecycle installation",
    "GET  /v1/workspaces/:ws": "status",
    "ANY  /v1/ws/:ws/...": "short alias for /v1/workspaces/:ws/... (same status, query, git, admit, subscribe, etc.)",
    "GET  /v1/workspaces/:ws/domains": "the installed law — every domain-installation with phase/hash/lifecycle",
    "POST /v1/workspaces/:ws/domains?dryRun=1": "validate a package WITHOUT installing (open)",
    "POST /v1/workspaces/:ws/retire": "owner-gated retirement — stops quota contribution, data retained per the license (deploys + session pushes refuse; reads keep serving)",
    "GET  /v1/workspaces/:ws/dead-letters": "the workspace DLQ — domain-rejected intents, full provenance (owner)",
    "POST /v1/workspaces/:ws/dead-letters/retry?id=": "re-admit dead-lettered intents after a law fix — the unjam (owner)",
    "DELETE /v1/workspaces/:ws/dead-letters?id=": "explicitly discard dead letters (owner)",
    "GET  /v2/workspaces/:ws/dlq-summary": "O(1) DLQ summary — {count, latestParkedAt}; the cheap per-node read the fleet sweep composes",
    "GET  /v2/workspaces/:ws/dlq-sweep?depth=&full=1": "sweep the workspace's SUBTREE of DLQs via the registry (workspacesByParent — never a chain walk); full entries only for jammed nodes",
    "GET  /v1/workspaces/:ws/counts/:countId?group=": "a declared count's maintained O(1) value",
    "GET  /v1/workspaces/:ws/sums/:sumId?group=": "a declared sum's maintained O(1) total",
    "GET  /v1/workspaces/:ws/extremums/:id?kind=min|max&group=": "a declared min/max's maintained O(1) extremum (null = empty group)",
    "POST /v1/root/governance": "author a governance directive (grants, revocations, lifecycle) — admin AdminGrant required; the cloud governs itself",
    "GET  /v1/root/workspaces": "the law-state workspace registry (admin)",
    "GET  /v1/root/creation-grants": "the grant audit surface — every CreationGrant on the record + the cloud's invite posture (admin)",
    "GET  /health": "liveness",
    "POST /v2/admin/roll-containers[?workspace=]": "roll the container fleet onto the current app image (staggered restarts; open, rate-limited 1/5min; ?workspace= rolls one workspace's slot). Compute placement only — restarts decide nothing",
    "GET  /v1/workspaces/:ws/aggregates/:id": "read an aggregate from the projection",
    "GET  /v1/workspaces/:ws/query?queryId=&params=": "run a domain query",
    "GET  /v1/workspaces/:ws/snapshot": "pull the holon state (browser-holon hydration bytes)",
    "GIT  /v1/workspaces/:ws/git": "the workspace ledger as a git remote — clone/pull/push with any git client",
    "GIT  push-to-create (the upload birth)": "pushing refs/heads/main to an UNBORN workspace births it FROM YOUR REPO: `githolon git remote <ws> && git push nomos main` (the CLI's credential helper answers the 401 challenge: username = your session token, password = a secret YOU choose). Raw lane: `git remote add cloud https://<accessToken>:<yourChosenSecret>@…/v2/workspaces/<ws>/git && git push cloud main`. The holon replay-verifies the WHOLE chain from genesis (it executes, and thus validates, itself) before the workspace serves anything; a refused chain is archived under refs/heads/refused/. sha256(password) becomes the owner credential bound IN THE CHAIN (the law record) — no host-held secret; no password = born open"
  }
}
