{
  "$comment": "SOURCE OF TRUTH for which branch deploys which surface. Edit this file ONLY. Run `node scripts/gen-deploy-triggers.mjs` to sync the deploy-*.yml trigger blocks, and `node scripts/lint-deploy-registry.mjs` to validate. INVARIANT: every surface maps to exactly ONE feature branch (plus main). A branch MAY own many surfaces (one Claude consciously taking several). A surface owned by two branches, or any wildcard branch, is forbidden. To claim a surface, change its `branch` field to your branch. Full pipeline + the golden rule (worker name must match the domain-owning worker): docs/DEPLOYS.md. Repo layout: docs/REPO-STRUCTURE.md.",
  "trunk": "main",
  "hero": "claude/landing-projects-takeover-pKkmW",
  "surfaces": [
    {
      "surface": "fable",
      "dir": "fable",
      "endpoint": "fable.mino.mobi",
      "type": "frontend",
      "branch": "claude/artifact-website-deploy-x8aiuq",
      "uses": [],
      "provides": null,
      "paths": [
        "fable/**"
      ],
      "serves": [
        "puzz",
        "knack",
        "flux",
        "gyre",
        "morph",
        "drift",
        "forge",
        "deal",
        "tetro"
      ],
      "note": "The generative / interestingness-engine wing (worker `fable`, custom_domain fable.mino.mobi). Thin assets Worker, no build, no secrets\u2026 (full description: fable/CLAUDE.md)"
    },
    {
      "surface": "moji",
      "dir": "moji",
      "endpoint": "moji.mino.mobi",
      "type": "frontend",
      "branch": "claude/emoji-wiki-platform-support-v6ubju",
      "uses": [],
      "provides": null,
      "paths": [
        "moji/**"
      ],
      "note": "The emoji wiki. Thin assets Worker (worker `moji`, custom_domain moji.mino.mobi) \u2014 no build, no D1, no AI, no secrets. Home page is every Unicode emoji in one pastable, searchable table (click a glyph to copy)\u2026 (full description: moji/CLAUDE.md)"
    },
    {
      "surface": "uni",
      "dir": "uni",
      "endpoint": "uni.mino.mobi",
      "type": "frontend",
      "branch": "claude/emoji-wiki-platform-support-v6ubju",
      "uses": [],
      "provides": null,
      "paths": [
        "uni/**"
      ],
      "note": "The Unicode browser (sibling to moji). Thin assets Worker (worker `uni`, custom_domain uni.mino.mobi) \u2014 no build, no D1/AI/secrets\u2026 (full description: uni/CLAUDE.md)"
    },
    {
      "surface": "unit",
      "dir": "unit",
      "endpoint": "unit.mino.mobi",
      "type": "frontend",
      "branch": "claude/wavelength-color-calc-nsew9x",
      "uses": [],
      "provides": null,
      "paths": [
        "unit/**"
      ],
      "note": "The unit converter (reference wing, sibling to moji + uni). Thin assets Worker (worker `unit`, custom_domain unit.mino.mobi) - no build/D1/AI/secrets\u2026 (full description: unit/CLAUDE.md)"
    },
    {
      "surface": "fix",
      "dir": "fix",
      "endpoint": "fix.mino.mobi",
      "type": "frontend",
      "branch": "claude/fix-message-parser-yndbht",
      "uses": [],
      "provides": null,
      "paths": [
        "fix/**"
      ],
      "note": "The FIX (Financial Information eXchange) message parser (reference wing, sibling to moji/uni/unit). Thin assets Worker (worker `fix`, custom_domain fix.mino.mobi) \u2014 no build/D1/AI/secrets\u2026 (full description: fix/CLAUDE.md)"
    },
    {
      "surface": "root",
      "dir": ".",
      "endpoint": "minomobi.com / mino.mobi (landing)",
      "type": "frontend",
      "branch": "claude/landing-page-architecture-1igui5",
      "uses": [],
      "provides": "landing",
      "status": "MANAGED — Cloudflare Pages project agent01, Direct Upload, production branch main. Deployed by .github/workflows/deploy-root.yml, which stages the tree with .assetsignore applied by hand before uploading (wrangler pages deploy does not honour .assetsignore).",
      "serves": [
        "(landing index)",
        "cluster",
        "density",
        "echo",
        "judge",
        "novelty",
        "seek",
        "ternary",
        "music",
        "sweat",
        "noise",
        "flows",
        "phylo",
        "wiki",
        "hoop-history",
        "office",
        "spec"
      ],
      "note": "Assets worker `minomobi` serving directory '.'. Bundles the landing page + ~19 pure-static subsites into ONE deploy. Ships via .github/workflows/deploy-root.yml (Pages Direct Upload); main does not deploy it. WARNING: the bundled static subsites cannot be deployed independently of each other — see tension note in the chat. /office is the fractal 'office of offices' site map (office/*.js + office/surfaces.json, generated by scripts/build-office.mjs from index.html's PROJECTS array). /stats is the self-analytics surface (stats/*, stats/data.json, generated by scripts/build-git-stats.mjs from the full git history; needs a full clone). /spec is the site-wide technical spec sheet (spec/*.js + spec/data.js, generated by scripts/build-spec.mjs from deploy-registry.json + index.html's PROJECTS array + curated descriptions; client-side live-status probe per endpoint).",
      "paths": [
        "index.html",
        "styles.css",
        "scripts/generate-search-catalog.mjs",
        "functions/**",
        "hoop-history/**",
        "office/**",
        "scripts/build-office.mjs",
        "spec/**",
        "scripts/build-spec.mjs",
        "catalogue.json",
        "git-graph.json",
        "stats/**",
        "scripts/build-git-stats.mjs",
        "scripts/catalogue-coverage.mjs",
        "scripts/lib/**",
        "rethink/**",
        "scripts/build-rethink.mjs",
        "procgen/**",
        "next/**",
        "archive/**",
        "mino.css",
        "eigensite/**"
      ]
    },
    {
      "surface": "ai-edu",
      "dir": "ai-edu",
      "endpoint": "ai.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "ai-edu/**"
      ]
    },
    {
      "surface": "airchat",
      "dir": "airchat",
      "endpoint": "airchat.mino.mobi, yapchat.mino.mobi",
      "type": "fullstack",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "atpolls-db"
      ],
      "provides": null,
      "paths": [
        "airchat/**",
        "poll/apps/api/migrations/0018_airchat.sql",
        "poll/apps/api/migrations/0019_airchat_oauth.sql",
        "poll/apps/api/migrations/0020_airchat_reply_cids.sql",
        "poll/apps/api/migrations/0021_airchat_segments.sql"
      ]
    },
    {
      "surface": "b",
      "dir": "b",
      "endpoint": "b.mino.mobi",
      "type": "frontend",
      "branch": "claude/bsky-follow-grooming-gjkops",
      "uses": [],
      "provides": null,
      "paths": [
        "b/**"
      ],
      "serves": [
        "disk",
        "spark",
        "dyad",
        "gc",
        "squares",
        "feedgen",
        "tetr",
        "map",
        "unique",
        "thread",
        "sleuth",
        "palm",
        "groom"
      ],
      "note": "Portal to every Bluesky tool here\u2014feeds, network maps, account analysis, and the shared OAuth worker in one place. (full description: b/CLAUDE.md) Also hosts palm at /palm (six stylometric lines off a whole repo, as percentiles against an offline pool \u2014 explicitly not an AI detector; b/palm/car-stream.js is a pure-JS streaming CAR reader that handles a 90MB repo where the buffering paths OOM) and thread at /thread (paste a post URL, read the whole reply tree with the author's own chain kept unbroken, plus a wall of every post it quoted) and sleuth at /sleuth (a thousand of any account's posts indexed in-tab with TF-IDF for instant keyless search; bring your own API key and the retrieved posts become RAG context, or generate a dossier of themes, narrative arcs and a personality read with every claim cited back to a post). Both moved here from photo, where they had been filed as image tools by accident \u2014 photo 301s /thread and /sleuth here and translates the old fragment deep links (#/thread/<url> -> ?p=, #/sleuth/<handle> -> ?u=).",
      "status": "RECONCILED 2026-08-15 \u2014 two branches developed b/ in parallel. Owner is claude/ai-detection-browser-aw7kq5, whose tree this candidate's b/ matches byte for byte (75 files, palm at 2026-08-06). claude/image-manipulation-platform-g5puxy has the older b/ (66 files, 21 of them behind) and contributed the registry record for palm, not the code \u2014 deploying b from it would regress the surface."
    },
    {
      "surface": "auth",
      "dir": "workers/auth",
      "endpoint": "auth.mino.mobi",
      "type": "backend",
      "branch": "claude/bsky-app-view-feasibility-8sdflz",
      "uses": [
        "mino-auth-db"
      ],
      "provides": "auth.mino.mobi",
      "status": "RECONCILED 2026-08-15 \u2014 one owner: claude/farmville-atproto-game-745mcr. It is the only claimant whose tree carries all 75 WRITE_COLLECTIONS; claude/atproto-infinite-whiteboard-usdpzx has 70 (no com.minomobi.farm.*), so giving it the surface would make the next auth deploy a silent narrowing of the ceiling. BEFORE THE NEXT AUTH DEPLOY THE OWNER MUST PULL main: only main now has both the full 75 and all three of the farm.mino.mobi, farm-next.mino.mobi and loop.mino.mobi origins \u2014 farmville's tree is still missing the loop origin.",
      "paths": [
        "workers/auth/**"
      ],
      "note": "The one shared OAuth worker (confidential client \u2014 PKCE + DPoP + PAR + private_key_jwt). This merge candidate unioned the two competing trees: 75 collections, deduplicated (the doubled lab.doc/lab.score pair that tripped check-auth-scope is gone), plus the farm, farm-next and loop origins together. Superset verified against main (69), farmville (75) and atproto-infinite-whiteboard (70) \u2014 nothing dropped from any of them. Full ownership history and the deploy caveat: workers/auth/CLAUDE.md."
    },
    {
      "surface": "autopilot",
      "dir": "auto",
      "endpoint": "auto",
      "type": "backend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "auto/**"
      ]
    },
    {
      "surface": "bakery",
      "dir": "bakery",
      "endpoint": "bake.mino.mobi",
      "status": "AUDIT 2026-07-16: endpoint corrected bakery.mino.mobi -> bake.mino.mobi (probe-verified: bake 200, bakery unresolvable). wrangler.jsonc has NO custom_domain route \u2014 bake.mino.mobi is dashboard-attached (golden-rule risk; add a routes entry on next touch).",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "paths": [
        "bakery/**"
      ]
    },
    {
      "surface": "bisk",
      "dir": "bisk",
      "endpoint": "bisk.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "bisk/**"
      ]
    },
    {
      "surface": "mappa",
      "dir": "mappa",
      "endpoint": "mappa.mino.mobi",
      "type": "frontend",
      "branch": "claude/civ-deploy-unification-vt35ju",
      "uses": [],
      "provides": null,
      "paths": [
        "mappa/**",
        "packages/atproto/pds.js",
        "packages/oauth-client/auth.js"
      ],
      "note": "The world engine + atlas (worker `mappa`, custom_domain mappa.mino.mobi) \u2014 MOVED OFF the root surface so it deploys with the world-engine suite (third suite surface with civ + polis). Assets-only worker\u2026 (full description: mappa/CLAUDE.md)"
    },
    {
      "surface": "polis",
      "dir": "polis",
      "endpoint": "polis.mino.mobi",
      "type": "frontend",
      "branch": "claude/civ-deploy-unification-vt35ju",
      "uses": [
        "civ"
      ],
      "provides": null,
      "paths": [
        "polis/**",
        "mappa/engine.js",
        "mappa/climate-forcing.js"
      ],
      "note": "The city cascade (worker `polis`, custom_domain polis.mino.mobi) \u2014 MOVED OFF the root surface so it deploys with the world-engine suite. `/` is the cascade charter (civ \u00fcber-macro \u2192 hinterland mesoscale \u2192 city micro)\u2026 (full description: polis/CLAUDE.md)"
    },
    {
      "surface": "civ",
      "dir": "civ",
      "endpoint": "civ.mino.mobi",
      "type": "backend",
      "branch": "claude/civ-deploy-unification-vt35ju",
      "uses": [],
      "provides": "civ",
      "paths": [
        "civ/**",
        "mappa/civ/**",
        "mappa/engine.js",
        "mappa/lib/world-share.js",
        "rite/names/engine.js",
        "rite/org/person.js"
      ],
      "note": "Coevolutionary agent-based civilization simulation on a mappa world (worker civ, custom_domain civ.mino.mobi)\u2026 (full description: civ/CLAUDE.md)"
    },
    {
      "surface": "biome",
      "dir": "biome",
      "endpoint": "biome.mino.mobi",
      "type": "frontend",
      "branch": "claude/biome-forest-creep-sprites-wnxo6h",
      "uses": [],
      "provides": null,
      "note": "The ECOSYSTEM wing of the O'Neill cylinder modelling package (game=hoop, structure=rind, thermodynamics=tide, ecosystem=biome). Assets worker `biome` serving directory 'biome', narrowed to the closed-ecology food-web box model (cycles/): a deterministic, element-exact, data-driven engine + Kleiber allometry + real-organism roster (iNaturalist/GloBI) + a community-matrix stability lab (cycles/stability.html). Rust/WASM stability kernel under cycles/solver (built by build-biome-solver.yml). Also serves the gacha (roll a viable ecosystem), the sprite/muscle/balance labs, and OVER (over/ \u2192 biome.mino.mobi/over): roll a biome and walk a living forest whose animals are cast from the gacha catalogue as pixel sprites \u2014 arthropods/pollinators swarm as creeps, vertebrates amble as quadrupeds \u2014 using the mega/sprite critter kernels (vendored under over/sprite/) and the hoop/over eden forest generator (vendored as over/eden.js). Pure static \u2014 model runs client-side, no D1/DO/secrets. The thermodynamics half (atmosphere/fountain/systems) split out to the `tide` surface.",
      "paths": [
        "biome/**"
      ]
    },
    {
      "surface": "rind",
      "dir": "rind",
      "endpoint": "rind.mino.mobi",
      "type": "frontend",
      "branch": "claude/upperrind-thread-styling-p7dhwu",
      "uses": [],
      "provides": null,
      "note": "The STRUCTURE wing of the O'Neill cylinder modelling package (split out of hoop). Assets worker `rind` serving directory 'rind'. The foam space-frame shell: cylinder.html (structural + radiative scratchpad, sizes the shell with a frame solver), foamview.html (3D read of the layered foam + wayfinding: drivable spiral-ramp / azimuthal-road routes through the chamber graph), walk.html (walk a planar cut through the foam). rind/ops/ is the OPS WEAVE: the 6 white-collar surfaces woven over the 8 production engines as the complete bipartite K(6,8) (a plain weave, not the old gyroid). Its one-door endpoint (rind/ops/onedoor.html, kernel onedoor.js) re-poses the weave as two door-free concourses joined only by the 48 zero-grade K-doors, so any room to any room is one door incl. the hubs (proven, onedoor.selftest.mjs). Geometry generated in JS (foam.js/foam3d.js/wayfind.js); structural scoring is the optional Rust/WASM frame solver under rind/solver (built by build-cylinder-solver.yml) with a pure-JS fallback. Pure static \u2014 no D1/DO/secrets.",
      "paths": [
        "rind/**",
        ".github/workflows/deploy-rind.yml"
      ]
    },
    {
      "surface": "foam",
      "dir": "foam",
      "endpoint": "foam.mino.mobi",
      "type": "frontend",
      "branch": "claude/foam-dungeon-generator-aoaz0j",
      "uses": [],
      "provides": null,
      "note": "First-person interactive space inside the rind's voronoi foam (game-side sibling of the rind structure wing). Two pages: `/` is the tight certified puzzle pocket; `/macro/` is the same mechanics in halls ~10x the volume plus the PLANT tool \u2014 insert a voronoi node and the whole lattice reforms around it (kernel reformPocket, membrane state carried by chamber pair). Membranes toggle, shatter and re-weave via the shiva tools; movement is walking only (no jumps, max grade \u224846\u00b0) and foamworld.js proves every published seed solvable with an explicit oracle (path + shiva sequence) before it ships. WebGL2, pure static, no build, no D1/DO/secrets. Assets worker `foam`, custom_domain foam.mino.mobi.",
      "paths": [
        "foam/**",
        ".github/workflows/deploy-foam.yml"
      ]
    },
    {
      "surface": "perp",
      "dir": "perp",
      "endpoint": "perp.mino.mobi",
      "type": "frontend",
      "branch": "claude/futures-finance-learning-r7p47e",
      "uses": [],
      "provides": null,
      "note": "Learning surface for perpetual futures. Two linked canvas time-series: BTC-USD spot candles (Coinbase, daily from 2015-07-20, with 6h and 1h resolutions swapped in by zoom level) and the Hyperliquid BTC perp's hourly premium and funding rate from 2023-05-12, drawn against the ±5bp clamp corridor inside which funding is mathematically blind to premium. Static column-encoded JSON in data/ built by scripts/backfill.mjs (both upstreams paginate — 300 candles and 500 hours per request); scripts/analyse.mjs derives every statistic the prose quotes into data/stats.json so the copy cannot drift from the series. The page tops the static history up with a live tail fetched straight from the browser (both APIs send CORS *), with bounded timeouts so an unreachable endpoint degrades to committed data. Refreshed daily by refresh-perp-data.yml, which commits and deploys. Pure static + assets worker, no build, no D1/DO/secrets.",
      "paths": [
        "perp/**",
        ".github/workflows/deploy-perp.yml"
      ]
    },
    {
      "surface": "tide",
      "dir": "tide",
      "endpoint": "tide.mino.mobi",
      "type": "frontend",
      "branch": "claude/nave-unified-web-6plmae",
      "uses": [],
      "provides": null,
      "note": "The THERMODYNAMICS wing of the O'Neill cylinder modelling package (split out of biome). Assets worker `tide` serving directory 'tide'. The interior climate: profile/ (the centrifugal barometer \u2014 radial gravity g(r)=\u03c9\u00b2r + isothermal pressure P(r)=P_axis\u00b7e^{S(r/R)\u00b2} from radius/spin/non-spinning-pressure), atmosphere/ (1-D radial column \u2014 temp/humidity/CO\u2082 vs altitude, Mie fog optics), fountain/ (azimuthal cross-section \u2014 rotating-frame ballistic fountain + linear-sun luminous-flux budget), systems/ (water & energy ledger \u2014 reactors\u2192light+jets, conserving water box model, fish). Shares the canonical cylinder geometry in tide/shared/geometry.mjs. Also hosts goss/ (tide.mino.mobi/goss) \u2014 the civic web viewer over the hoop econ society (vendored kernel): NPCs + their relationships to places, emergent tribes, romance, and the two tension axes (tribalism, narcissism of small differences) emitting social-drama seeds. Pure static \u2014 every model runs client-side, no D1/DO/secrets.",
      "paths": [
        "tide/**",
        ".github/workflows/deploy-tide.yml"
      ]
    },
    {
      "surface": "iris",
      "dir": "iris",
      "endpoint": "iris.mino.mobi",
      "type": "frontend",
      "branch": "claude/oneill-cylinder-solver-djdpdm",
      "uses": [],
      "provides": null,
      "note": "The END-ON cross-section view of an O'Neill cylinder \u2014 looking down the axis at a small ring habitat (4 km floor inside a 5 km radiator skin). Assets worker `iris` serving directory 'iris'. One coupled steady-state solve (iris/sim/section.mjs): the lights are the only heat in, the radiator skin the only heat out, the habitat's heat carried there through the floor's water reservoirs + heat pipes \u2014 that balance pins every temperature. Switchable gradient views over the circle (temperature / pressure / humidity / wind), toggleable fog (RH\u22651) and fountain jets, the inner-rim ratchet topography (iris/sim/ratchet.mjs). Companion to the tide thermodynamics wing; its own geometry (iris/shared/geometry.mjs), not tide's. Pure static \u2014 every model runs client-side, no D1/DO/secrets.",
      "paths": [
        "iris/**",
        ".github/workflows/deploy-iris.yml"
      ]
    },
    {
      "surface": "borges",
      "dir": "borges",
      "endpoint": "borges.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "borges/**"
      ]
    },
    {
      "surface": "chat",
      "dir": "chat",
      "endpoint": "chat.mino.mobi",
      "type": "fullstack",
      "branch": "claude/conversation-practice-website-he3t8x",
      "uses": [],
      "provides": null,
      "paths": [
        "chat/**"
      ],
      "note": "Conversation-practice dojo. Robo trainer (AI partner + theory-grounded scoring rubric) at /robo/, theory + rubric-development docs at /docs/, landing at /. Worker + Workers AI (llama-3.3-70b), no D1, no secrets beyond shared Cloudflare creds. Multiplayer (DO rooms, lobby, peer-rated scoreboard) is roadmap."
    },
    {
      "surface": "idol",
      "dir": "idol",
      "endpoint": "idol.mino.mobi",
      "type": "frontend",
      "branch": "claude/anime-waifu-generator-9QwRt",
      "uses": [],
      "provides": null,
      "paths": [
        "idol/**"
      ],
      "note": "The waifu generator \u2014 an AI-safety piece about beguilement, built as the thing it's about\u2026 (full description: idol/CLAUDE.md)"
    },
    {
      "surface": "duck",
      "dir": "duck",
      "endpoint": "duck.mino.mobi",
      "type": "frontend",
      "branch": "claude/feature-merge-candidate-l4dkwq",
      "uses": [],
      "provides": null,
      "paths": [
        "duck/**"
      ],
      "note": "Two WebGPU games on one worker (`duck`, custom_domain duck.mino.mobi). Pure-static, no build, no secrets. (1) duck.mino.mobi/ \u2014 the spin-gravity DUCK FLIGHT SIM: fly an aerodynamic duck under uniform Earth gravity vs\u2026 (full description: duck/CLAUDE.md)"
    },
    {
      "surface": "bounty",
      "dir": "bounty",
      "endpoint": "bounty-minomobi",
      "type": "backend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "bounty-board"
      ],
      "provides": null,
      "paths": [
        "bounty/**"
      ]
    },
    {
      "surface": "cable",
      "dir": "cable",
      "endpoint": "cable.mino.mobi, cable.ascential.work",
      "type": "frontend",
      "branch": "claude/cable-definition-website-yrwv41",
      "uses": [],
      "provides": null,
      "note": "Progressive cable-drawing solver for custom instrument cabling. Walks the 7-layer stack (component \u2192 connector \u2192 pin set \u2192 cable \u2192 pin \u2192 connector \u2192 board), propagating constraints across layers\u2026 (full description: cable/CLAUDE.md)",
      "paths": [
        "cable/**"
      ]
    },
    {
      "surface": "cards",
      "dir": "cards",
      "endpoint": "cards.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "cards/**"
      ],
      "cohesion": "integrated"
    },
    {
      "surface": "ar",
      "dir": "ar",
      "endpoint": "ar.mino.mobi",
      "type": "fullstack",
      "branch": "claude/3d-crystal-diffraction-B5YhB",
      "uses": [],
      "provides": null,
      "note": "Worker + Room Durable Object (WebSocket relay) + static assets (public/). Two-phone AR Laue diffraction at /crystal/.",
      "paths": [
        "ar/**",
        ".github/workflows/deploy-ar.yml"
      ]
    },
    {
      "surface": "cron",
      "dir": "workers/cron",
      "endpoint": "minomobi-cron",
      "type": "backend",
      "branch": "claude/minomobi-landing-page-vg37b8",
      "uses": [],
      "provides": null,
      "paths": [
        "workers/cron/**"
      ]
    },
    {
      "surface": "duffel-proxy",
      "dir": "workers/duffel-proxy",
      "endpoint": "air.mino.mobi",
      "status": "AUDIT 2026-07-16: endpoint corrected duffel-proxy -> air.mino.mobi (custom_domain route in wrangler.toml, probe-verified 200).",
      "type": "backend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "workers/duffel-proxy/**"
      ]
    },
    {
      "surface": "empathy",
      "dir": "empathy",
      "endpoint": "empath.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "empathy/**"
      ]
    },
    {
      "surface": "feed",
      "dir": "workers/feed",
      "endpoint": "feed.mino.mobi",
      "type": "backend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "atpolls-db"
      ],
      "provides": "feed.mino.mobi",
      "paths": [
        "workers/feed/**",
        "poll/apps/api/migrations/0010_feed_communities.sql",
        "poll/apps/api/migrations/0013_feed_liked_posts.sql"
      ]
    },
    {
      "surface": "fipo",
      "dir": "fipo",
      "endpoint": "fipo.mino.mobi",
      "type": "frontend",
      "branch": "claude/fipo-pitch-genome-Qm7Xp2",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 new surface via deploy-fipo.yml (Worker `fipo`, custom_domain fipo.mino.mobi). Assets-only static worker; engine selftest gates the deploy.",
      "op": "create",
      "note": "The bad sci-fi pitch archive. /pitch \u2014 the pitch-GENOME engine (fipo/pitch/engine.js): a deterministic seeded sampler (xmur3+mulberry32, a seed is a permalink) over the phase space of earnest failure\u2026 (full description: fipo/CLAUDE.md)",
      "paths": [
        "fipo/**"
      ]
    },
    {
      "surface": "fluoddity",
      "dir": "fluoddity",
      "endpoint": "fluoddity.mino.mobi",
      "type": "frontend",
      "branch": "claude/fluoddity-param-space-viz-9d5g4b",
      "uses": [],
      "provides": null,
      "paths": [
        "fluoddity/**"
      ],
      "status": "MANAGED \u2014 FIXED: added custom_domain route (fluoddity.mino.mobi) to make the binding declarative. Name kept (fluoddity-minomobi); no twin worker found, so it was already deploying the right worker."
    },
    {
      "surface": "fred-proxy",
      "dir": "workers/fred-proxy",
      "endpoint": "fred.mino.mobi",
      "status": "AUDIT 2026-07-16: endpoint corrected fred-proxy -> fred.mino.mobi (custom_domain route in wrangler.toml, probe-verified 200).",
      "type": "backend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "workers/fred-proxy/**"
      ]
    },
    {
      "surface": "games",
      "dir": "games",
      "endpoint": "games.mino.mobi",
      "type": "frontend",
      "branch": "claude/tempest-procgen-game-vwj0f1",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "note": "Multiplayer party games for Bluesky, with real-time rooms orchestrated by Durable Objects. Also home to the /pressure/ family of single-player decision games — newest is /tempest/, whose Rust core proves every procedural wave holdable before it ships. (full description: games/CLAUDE.md)",
      "paths": [
        "games/**",
        "packages/oauth-client/**"
      ]
    },
    {
      "surface": "ink",
      "dir": "ink",
      "endpoint": "ink.mino.mobi",
      "type": "frontend",
      "branch": "claude/p5js-procgen-exploration-efdhws",
      "uses": [],
      "provides": null,
      "paths": [
        "ink/**"
      ],
      "status": "NEW — ink.mino.mobi was unattached (verified: nothing answered it). wrangler.jsonc declares the custom_domain route, so the first deploy creates worker `ink` and binds the domain. UNVERIFIED FROM THE SANDBOX: the sandbox cannot reach Cloudflare, so the binding must be confirmed from the deploy log (`ink.mino.mobi (custom domain)`) and /api/health."
    },
    {
      "surface": "io",
      "dir": "io",
      "endpoint": "io.mino.mobi",
      "type": "fullstack",
      "branch": "claude/landing-page-architecture-1igui5",
      "uses": [
        "atpolls-db",
        "auth.mino.mobi"
      ],
      "provides": null,
      "paths": [
        "io/**",
        "packages/oauth-client/**",
        "js/typeahead.js",
        "scripts/vendor-io.sh",
        "scripts/generate-sites-json.mjs",
        "poll/apps/api/migrations/0030_io_tickets.sql"
      ]
    },
    {
      "surface": "j",
      "dir": "j",
      "endpoint": "j.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "j/**"
      ]
    },
    {
      "surface": "photo",
      "dir": "photo",
      "endpoint": "photo.mino.mobi",
      "type": "frontend",
      "branch": "claude/usda-fruit-paintings-dashboard-kxn1c1",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "paths": [
        "photo/**"
      ],
      "cohesion": "integrated",
      "status": "HANDOVER 2026-08-17 — owner moved claude/image-manipulation-platform-g5puxy -> claude/usda-fruit-paintings-dashboard-kxn1c1, so /pom can ship. Checked before the move, because a handover to a branch whose tree is behind is a silent regression (see the `b` entry for the case that taught this): the new owner's photo/ was BYTE-IDENTICAL to the old owner's at the commit before /pom was added, so this deploys the old owner's work plus /pom and drops nothing. The old branch owned no other surface, so nothing else was stranded. IMPORTANT: claude/image-manipulation-platform-g5puxy no longer deploys photo — anything still in flight there has to come here (or the branch field has to come back) or it goes live never.",
      "note": "The image-tools surface. Adds /pom (2026-08-17): the USDA Pomological Watercolor Collection, 7,581 plates, as a filterable wall that hosts no pixels — every tile is a direct upload.wikimedia.org hotlink built from the NAL barcode, with a committed 600 kB catalogue and an Internet Archive fallback. (full description: photo/CLAUDE.md)"
    },
    {
      "surface": "phylofiction",
      "dir": "phylofiction",
      "endpoint": "phylofiction.mino.mobi",
      "type": "frontend",
      "branch": "claude/phylofiction-world-generation-3zd33u",
      "uses": [],
      "provides": null,
      "note": "Seeded deterministic tree-of-life generator: a Rust/WASM evolution engine (engine-rs/, artifact committed by build-phylofiction-wasm.yml) drives a microbial phylogeny that any page-seed reproduces identically. Static reader (assets worker `phylofiction` owns phylofiction.mino.mobi); all computation client-side, no D1/DO/secrets. JS engine mirrored against the wasm in test/parity.test.mjs.",
      "paths": [
        "phylofiction/**"
      ]
    },
    {
      "surface": "jurassic",
      "dir": "jurassic",
      "endpoint": "jurassic.mino.mobi",
      "type": "frontend",
      "branch": "claude/jurassic-forest-sounds-iym7ya",
      "uses": [],
      "provides": null,
      "status": "MANAGED and LIVE — jurassic.mino.mobi did not exist before this surface; the first deploy provisioned the custom domain and its DNS record from the routes[] declaration (run 33092852852, log binds `jurassic.mino.mobi (custom domain)`). DNS did not resolve for ~10 s on that first run, which is normal and only happens once. Verified live: page, engine/jurassic.wasm served as application/wasm, test/ excluded from the bundle.",
      "note": "The Daohugou soundscape, walkable — a companion to Gu et al. 2026 (PNAS 123:e2615107123, open access), whose nine fossil ensiferans it plays. A zero-dependency Rust/WASM kernel (engine-rs/, artifact committed by build-jurassic-wasm.yml) synthesises each call from that species' PUBLISHED stridulatory file — a bandlimited tooth-strike train, driven by the paper's tooth-by-tooth spacing profile, into a two-pole wing resonator at its published Q — then propagates it with ISO 9613-1 absorption plus ISO 9613-2 foliage scattering for a listener walking a 180 m plot. Rendered from an AudioWorklet; no wasm-bindgen, no allocator on the audio thread, and NO JS fallback — the module is the audio. The map's audible-radius circles and the mixer's distance gains come from ONE model so they cannot disagree. The kernel holds no palaeontology: the roster is js/fauna.js, every value tagged published/digitised/modelled/hypothesis. Pure static, no D1/DO/secrets. (full description: jurassic/CLAUDE.md)",
      "paths": [
        "jurassic/**",
        ".github/workflows/deploy-jurassic.yml"
      ]
    },
    {
      "surface": "ocr",
      "dir": "ocr",
      "endpoint": "ocr.mino.mobi, ocr.ascential.work",
      "type": "frontend",
      "branch": "claude/image-text-extraction-gH8UH",
      "uses": [],
      "provides": null,
      "note": "Standalone client-side OCR (pull text / activation codes off an image). Vanilla HTML/JS + pure-Rust wasm (os/crates/codescan-ocr, artifact committed to ocr/wasm/)\u2026 (full description: ocr/CLAUDE.md)",
      "paths": [
        "ocr/**"
      ]
    },
    {
      "surface": "poll",
      "dir": "poll",
      "endpoint": "poll.mino.mobi",
      "type": "fullstack",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "atpolls-db"
      ],
      "provides": "atpolls-db",
      "paths": [
        "poll/**"
      ]
    },
    {
      "surface": "read",
      "dir": "read",
      "endpoint": "read.mino.mobi",
      "type": "frontend",
      "branch": "claude/portrait-artist-mythograph-pi5umf",
      "uses": [],
      "provides": null,
      "paths": [
        "read/**"
      ],
      "cohesion": "integrated"
    },
    {
      "surface": "rite",
      "dir": "rite",
      "endpoint": "rite.mino.mobi",
      "type": "fullstack",
      "branch": "claude/procedural-name-generator-2qqwfq",
      "uses": [
        "atpolls-db"
      ],
      "provides": null,
      "paths": [
        "rite/**",
        "poll/apps/api/migrations/0014_fodder.sql",
        "poll/apps/api/migrations/0015_ask.sql",
        "poll/apps/api/migrations/0016_ask_map.sql",
        "poll/apps/api/migrations/0017_signal.sql"
      ],
      "cohesion": "integrated"
    },
    {
      "surface": "pod",
      "dir": "pod",
      "endpoint": "pod.mino.mobi",
      "type": "fullstack",
      "branch": "claude/podcast-studio-architecture-711cke",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 live (AUDIT 2026-07-16: pod.mino.mobi probe-verified 200; the domain has been attached since the 'pending attach' note was written).",
      "paths": [
        "pod/**",
        ".github/workflows/deploy-pod.yml"
      ],
      "cohesion": "self-contained",
      "note": "Podcast studio on ATProto: record in a WebRTC lobby (/room), edit multitrack clips and publish (/prod), listen per-show (/listen) or in a general RSS client (/app)\u2026 (full description: pod/CLAUDE.md)"
    },
    {
      "surface": "hoop",
      "dir": "hoop",
      "endpoint": "hoop.mino.mobi",
      "type": "frontend",
      "branch": "claude/hoop-mino-mobi-deploy-3au5qn",
      "uses": [],
      "provides": null,
      "status": "PREVIEW \u2014 the GAME wing of the O'Neill cylinder modelling package (main site; structure=rind, thermodynamics=tide, ecosystem=biome). ONE live version (v110 = v109 + the keeper-stacking fix: one keeper per room so a co-seated pair can never swallow each other's click, plus the dev upper-rind start) mirrored at the domain root by worker.js, plus its runtime closure \u2014 the v099 engine snapshot, the nave/rind floor builders, forge, chunkroller, paint, econ, the worker-side story lane (story/), vendor/auth. The mirrored root document MUST carry <base href=\"/v110/\">. Static Worker (ASSETS) + HoopRoom presence DO, no D1. Auth via shared workers/auth. Everything older (the first-pass room, v2\u2013v8, v090\u2013v109) lives on the hoop-archive surface; this worker 301-redirects archived paths there. To promote a new version: see hoop/CLAUDE.md.",
      "paths": [
        "hoop/**",
        ".github/workflows/deploy-hoop.yml"
      ],
      "cohesion": "standalone"
    },
    {
      "surface": "hoop-archive",
      "dir": "hoop-archive",
      "endpoint": "hoop-archive.mino.mobi",
      "type": "frontend",
      "branch": "claude/hoop-mino-mobi-deploy-3au5qn",
      "uses": [],
      "provides": null,
      "status": "LIVE \u2014 the hoop museum, so mainline hoop can stay at one live version. Serves the original first-pass room (the root @-glyph forum game) at /, the early engine passes v2\u2013v8, and every frozen version snapshot v090\u2013v109 with their records/feed/spine/quests/plan rewrites; bare aliases (/quests, /plan, /over, /alch, /smith, /garden/plot) resolve to v109, the newest archived version. Carries FROZEN same-origin copies of the shared dirs the old versions import at runtime (v099 engine, nave, rind, forge, chunkroller, paint, vendor, story, lexicons) \u2014 never evolve them here; the living copies are in hoop/. Own HoopRoom presence DO for the first-pass room; guarded /api/story lane kept but keyless (everything procedural). /docs and /econ redirect to mainline. Mainline hoop 301-redirects archived paths here.",
      "paths": [
        "hoop-archive/**",
        ".github/workflows/deploy-hoop-archive.yml"
      ],
      "cohesion": "standalone"
    },
    {
      "surface": "scores",
      "dir": "workers/scores",
      "endpoint": "scores.mino.mobi",
      "type": "backend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "mino-scores-db",
        "auth.mino.mobi"
      ],
      "provides": "scores.mino.mobi",
      "paths": [
        "workers/scores/**"
      ]
    },
    {
      "surface": "splice",
      "dir": "splice",
      "endpoint": "splice.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "paths": [
        "splice/**"
      ]
    },
    {
      "surface": "zoom",
      "dir": "zoom",
      "endpoint": "zoom.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "feed.mino.mobi"
      ],
      "provides": null,
      "paths": [
        "zoom/**"
      ],
      "status": "MANAGED \u2014 FIXED: config name corrected mino-zoom -> zoom so `wrangler deploy` updates the WORKER that owns zoom.mino.mobi (was deploying a separate stray Worker `mino-zoom` on workers.dev; the live `zoom` Worker languished ~2mo). custom_domain route now declared in config. CLEANUP: delete the orphan `mino-zoom` Worker in the dashboard.",
      "note": "Vite/React build -> ./dist, Worker `zoom` with custom_domain zoom.mino.mobi (canvas/math/g/torus pattern). NB: zoom is a Worker, not a Pages project (verified: no Pages project named zoom)."
    },
    {
      "surface": "time",
      "dir": "time",
      "endpoint": "time.mino.mobi",
      "type": "frontend",
      "branch": "claude/audit-time-deploy-ag144t",
      "uses": [],
      "provides": null,
      "op": "encapsulation",
      "paths": [
        "time/**",
        "scripts/build-time-index.mjs"
      ],
      "status": "MANAGED \u2014 new surface via deploy-time.yml (Worker `time`, custom_domain time.mino.mobi). Carved out of the root bundle; assets-only static, deploy step regenerates index.json. Sources stay in time/; also mirrored at mino.mobi/time until fully removed from root.",
      "note": "The Mino Times \u2014 a two-desk paper (Modulo = data desk, Morphyx = institutional desk). Repo-native front page renders from time/index.json (built from time/articles/*.html by scripts/build-time-index.mjs), so no Bluesky-account suspension can blank it. Running series: The LDT Reckoning. Legacy time.minomobi.com is dead; canonical is now time.mino.mobi."
    },
    {
      "surface": "math",
      "dir": "geometry",
      "dirs": [
        "geometry",
        "conjectures",
        "erdos",
        "guthkatz",
        "hadwiger",
        "heilbronn",
        "kakeya",
        "runner",
        "szemeredi-trotter",
        "viazovska",
        "capset",
        "borsuk",
        "elements",
        "prop",
        "cohomology",
        "voronoi",
        "arnold"
      ],
      "endpoint": "math.mino.mobi",
      "type": "frontend",
      "branch": "claude/holder-continuous-procgen-arqnj4",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 additive launch via deploy-math.yml (Worker `math`, custom_domain math.mino.mobi). Members are STAGED from root at build time, not moved; root still serves the canonical mino.mobi/<x>/ URLs so nothing breaks.",
      "op": "encapsulation",
      "note": "Hub for the extremal-geometry pack. Family-resemblance table sortable by era, technique, status \u2014 and an explicit roadmap of next entries (szemer\u00e9di\u2013trotter, heilbronn, borsuk, viazovska, ...)\u2026 (full description: geometry/CLAUDE.md)",
      "paths": [
        "geometry/**",
        "conjectures/**",
        "erdos/**",
        "guthkatz/**",
        "hadwiger/**",
        "heilbronn/**",
        "kakeya/**",
        "runner/**",
        "szemeredi-trotter/**",
        "viazovska/**",
        "capset/**",
        "borsuk/**",
        "elements/**",
        "prop/**",
        "cohomology/**",
        "voronoi/**",
        "arnold/**"
      ]
    },
    {
      "surface": "canvas",
      "dir": "draw",
      "dirs": [
        "draw",
        "curve",
        "paint",
        "mmo",
        "pizza"
      ],
      "endpoint": "canvas.mino.mobi",
      "type": "frontend",
      "branch": "claude/pizza-cutting-game-7VvX2",
      "uses": [
        "atpolls-db",
        "scores.mino.mobi",
        "auth.mino.mobi"
      ],
      "provides": null,
      "status": "MANAGED \u2014 additive launch via deploy-canvas.yml (Worker `canvas`, custom_domain canvas.mino.mobi + thin canvas/index.html hub). Members STAGED from root, not moved; backends untouched (absolute origins). Root still serves canonical mino.mobi/<x>/.",
      "op": "encapsulation",
      "note": "draw+paint+mmo frontends are backed by poll worker /api/{draw,mmo}; curve+pizza submit to scores \u2014 all ABSOLUTE origins, so the frontends move cleanly. One deploy unit; backends stay in poll/scores. pizza is a standalone static canvas game (no backend beyond the shared scores+auth workers). DEFERRED: carve these dirs out of root once canvas.mino.mobi is the home.",
      "paths": [
        "draw/**",
        "curve/**",
        "paint/**",
        "mmo/**",
        "pizza/**"
      ]
    },
    {
      "surface": "board",
      "dir": "board",
      "endpoint": "board.mino.mobi",
      "type": "frontend",
      "branch": "claude/atproto-infinite-whiteboard-usdpzx",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "status": "MANAGED \u2014 verified prod. Run #1 (2026-07-28) created Worker `board` and bound `board.mino.mobi (custom domain)`; wrangler attached the new subdomain itself, no dashboard step was needed. Live: index + /lexicons/*.json serve 200.",
      "op": "create",
      "note": "The infinite whiteboard. Spatial canvas holding pictures, voice notes, links, files and text snips \u2014 and other whiteboards: a selection folds into a child board (\u2318G) leaving a portal behind, and connectors that crossed the boundary re-point at it. One board = one com.minomobi.board.canvas record in the user's own repo, media as blobs on their PDS; no backend, no database\u2026 (full description: board/CLAUDE.md)",
      "paths": [
        "board/**",
        "packages/oauth-client/**",
        "js/typeahead.js",
        "scripts/vendor-board.sh"
      ]
    },
    {
      "surface": "tjs",
      "dir": "tjs",
      "endpoint": "tjs.mino.mobi",
      "type": "frontend",
      "branch": "claude/threejs-procgen-buildings-mprgs6",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 new surface via deploy-tjs.yml (Worker `tjs`). Self-contained static three.js workbench surface; stages tjs/ into dist at build time. Owning branch reassigned to claude/dragonfly-pursuit-sim-pv3e8p (dragonfly aerial-combat sim take-over; the /dragon bench adds a Rust\u2192wasm two-body visual-bearing pursuit solver + a head-cam POV).",
      "op": "create",
      "note": "tjs.mino.mobi \u2014 three.js workbenches\u2026 (full description: tjs/CLAUDE.md)",
      "paths": [
        "tjs/**"
      ]
    },
    {
      "surface": "golem",
      "dir": "golem",
      "endpoint": "golem.mino.mobi",
      "type": "frontend",
      "branch": "claude/cube3d-browser-port-ufh9gy",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 new surface via deploy-golem.yml (Worker `golem`). Assets-only static worker, selftest gate before deploy.",
      "op": "create",
      "note": "golem.mino.mobi \u2014 Minecraft-like builder world over cube3D's smart cellular bricks (sequel to tjs.mino.mobi/cube/)\u2026 (full description: golem/CLAUDE.md)",
      "paths": [
        "golem/**"
      ]
    },
    {
      "surface": "reef",
      "dir": "reef",
      "endpoint": "reef.mino.mobi",
      "type": "fullstack",
      "branch": "claude/cube3d-browser-port-ufh9gy",
      "uses": [
        "atpolls-db"
      ],
      "provides": null,
      "status": "MANAGED \u2014 new surface via deploy-reef.yml (Worker `reef`). Species selftest gate + idempotent D1 migration before deploy.",
      "op": "create",
      "note": "reef.mino.mobi \u2014 Tinder-style crowd judging of procedurally generated voxel sea creatures (fish/eel/ray/jellyfish/turtle/coral/anemone; reef/js/species.js, seeded + connected + morphologically exaggerated at 15^3)\u2026 (full description: reef/CLAUDE.md)",
      "paths": [
        "reef/**",
        "poll/apps/api/migrations/0032_reef.sql"
      ]
    },
    {
      "surface": "g",
      "dir": "g",
      "endpoint": "g.mino.mobi",
      "type": "frontend",
      "branch": "claude/morphhdl-sonification-graphs-s9t2qo",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 deploy-g.yml (Worker `g`, custom_domain g.mino.mobi) stages a mirror of clock/ into g/dist at build time; sources stay in clock/. clock.mino.mobi still serves the same toys until its dashboard redirect lands.",
      "op": "encapsulation",
      "note": "The WebGPU gallery. Simulation toys that each own a canvas \u2014 bearings (self-assembling wire: DEM + Kirchhoff solver in Rust/wasm), morph (recursive-HDL circuits that grow and sonify themselves; Rust/wasm rewrite engine + Barnes-Hut layout), hourglass, mol, globe, the toroidal games, the fractal zooms. Sources live in clock/, one directory per toy. (full description: g/CLAUDE.md)",
      "paths": [
        "clock/**",
        "g/**"
      ],
      "serves": [
        "bearings",
        "morph",
        "hourglass",
        "helix",
        "mol",
        "globe",
        "stretch",
        "scape",
        "ship",
        "fluoddity",
        "garden",
        "horned",
        "antoine",
        "lattice",
        "basket",
        "syllis",
        "soil",
        "geocast",
        "tablet"
      ]
    },
    {
      "surface": "torus",
      "dir": "clock",
      "dirs": [
        "clock/corn",
        "clock/emsim",
        "clock/inpac",
        "clock/knotpac",
        "clock/pac",
        "clock/torpac",
        "clock/toruschess"
      ],
      "endpoint": "torus.mino.mobi",
      "type": "frontend",
      "branch": "claude/fractal-torus-webgpu-97gxv4",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 additive launch via deploy-torus.yml (Worker `torus`). The toroidal games staged from clock/<toy>, not moved; g + clock still serve them.",
      "op": "encapsulation",
      "note": "Toroidal game family split out of the deprecated clock surface: corn, emsim, inpac, knotpac, pac, torpac, toruschess + a torus/index.html hub, plus fortress (WebGPU fractal, torus/fortress/).",
      "paths": [
        "clock/corn/**",
        "clock/emsim/**",
        "clock/inpac/**",
        "clock/knotpac/**",
        "clock/pac/**",
        "clock/torpac/**",
        "clock/toruschess/**",
        "torus/**"
      ]
    },
    {
      "surface": "labglass",
      "dir": "labglass",
      "endpoint": "glass.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 onboarded to Actions (deploy-labglass.yml). First QB pass: brought an Action-less independent site onto the deploy conveyor. (Was deploying via CF git integration / manual wrangler; disconnect git once this Action is confirmed canonical.)",
      "note": "DuckDB + Pyodide biotech data workbench. Static worker-assets (Worker `glass`). Needs COOP/COEP headers (labglass/_headers). Different registrable domain (minomobi.com) \u2014 outside the .mino.mobi SSO cookie.",
      "paths": [
        "labglass/**"
      ]
    },
    {
      "surface": "mega",
      "dir": "mega",
      "endpoint": "mega.mino.mobi",
      "type": "frontend",
      "branch": "claude/integrate-v091-v092-v093-4yie2i",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 owned by claude/integrate-v091-v092-v093-4yie2i (the v091\u00d7v092 synthesis: /v093). Worker `mega` + custom_domain route (mega.mino.mobi). CLEANUP: delete the orphan `mega-minomobi` worker.",
      "note": "Interactive map of global megaprojects\u2014construction, timelines, costs, and deep context on a 3D globe. (full description: mega/CLAUDE.md)",
      "paths": [
        "mega/**"
      ]
    },
    {
      "surface": "pm",
      "dir": "pm",
      "endpoint": "pm.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 onboarded to Actions (deploy-pm.yml). First QB pass: brought an Action-less independent site onto the deploy conveyor. (Was deploying via CF git integration / manual wrangler; disconnect git once this Action is confirmed canonical.)",
      "note": "Mino PM \u2014 earned-value project management. Static worker-assets (Worker `pm`).",
      "paths": [
        "pm/**"
      ]
    },
    {
      "surface": "pokemon",
      "dir": "pokemon",
      "endpoint": "poke.mino.mobi",
      "type": "frontend",
      "branch": "claude/microbial-locomotion-flagellation-uj0l09",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 FIXED (zoom-bucket): config renamed mino-poke -> poke + custom_domain route, so wrangler deploy updates the worker that owns poke.mino.mobi. Was deploying stray worker mino-poke. CLEANUP: delete the orphan `mino-poke` worker in the dashboard.",
      "note": "Critter Red \u2014 Pokemon-style game. Static worker-assets (Worker `mino-poke`).",
      "paths": [
        "pokemon/**"
      ]
    },
    {
      "surface": "finance",
      "dir": "finance",
      "endpoint": "fin.mino.mobi",
      "type": "frontend",
      "branch": "claude/speculative-feedback-playground-t0yiaq",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 onboarded to Actions (deploy-finance.yml). Surface taken over for the speculative-feedback research playground; the personal-finance SPA was relocated under /pm.",
      "note": "Worker `fin` (main: worker.js + ASSETS) serving two apps from one dist/: the speculative-feedback playground at / (TS/React, Vite multipage) and the personal-finance planning SPA at /pm. worker.js does subtree-aware SPA fallback and reserves /api/* for the M2 backend (experiment store + server-side runs).",
      "paths": [
        "finance/**"
      ]
    },
    {
      "surface": "org",
      "dir": "org",
      "endpoint": "org.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 onboarded to Actions (deploy-org.yml). First QB pass: brought an Action-less independent site onto the deploy conveyor. (Was deploying via CF git integration / manual wrangler; disconnect git once this Action is confirmed canonical.)",
      "note": "Org SPA (Vite + tsc -> ./dist, Worker `org`). Has inline OAuth in org/src/pds.ts (migration to shared oauth-client pending).",
      "paths": [
        "org/**"
      ]
    },
    {
      "surface": "wave",
      "dir": "wave",
      "endpoint": "wave.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "status": "MANAGED \u2014 onboarded to Actions (deploy-wave.yml). First QB pass: brought an Action-less independent site onto the deploy conveyor. (Was deploying via CF git integration / manual wrangler; disconnect git once this Action is confirmed canonical.)",
      "note": "Wave SPA (Vite + tsc -> ./dist, Worker `wave`). Uses shared oauth-client wrapper (wave/src/lib/auth.ts) -> auth.mino.mobi.",
      "paths": [
        "wave/**"
      ]
    },
    {
      "surface": "wars",
      "dir": "wars",
      "endpoint": "war.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 FIXED (zoom-bucket): config renamed wars-minomobi -> war + custom_domain route (war.mino.mobi). Was deploying stray worker wars-minomobi. CLEANUP: delete the orphan `wars-minomobi` worker.",
      "note": "War Factor Analysis \u2014 Correlates of War dataset explorer. Static worker-assets (Worker `wars-minomobi`). Live at war.mino.mobi (probe-verified); also bundled at mino.mobi/wars.",
      "paths": [
        "wars/**"
      ]
    },
    {
      "surface": "answers",
      "dir": "answers",
      "endpoint": "ask.mino.mobi",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 FIXED (zoom-bucket): the answers/ site is live at ask.mino.mobi via a worker named `ask` (not answers.mino.mobi). Config renamed mino-answers -> ask + custom_domain route, so the Action now updates the live worker (was deploying stray mino-answers; ask sat ~45 days). CLEANUP: delete the orphan `mino-answers` worker.",
      "note": "\"Answers \u2014 powered by ATProto\". Static worker-assets. Live subdomain is ask.mino.mobi (worker `ask`); also bundled at mino.mobi/answers/. Has inline OAuth (answers/assets/answers.js) \u2014 migrate to shared oauth-client later.",
      "paths": [
        "answers/**"
      ]
    },
    {
      "surface": "crm",
      "dir": "crm",
      "endpoint": "crm.mino.mobi (pending attach)",
      "type": "frontend",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "status": "MANAGED (domain pending) \u2014 onboarded to Actions (deploy-crm.yml) as an ADDITIVE own-worker deploy. Non-breaking: still served via its current path; attach the custom domain in the Cloudflare dashboard to complete the carve-out, then drop from the root bundle.",
      "note": "Vault CRM SPA (Vite + tsc -> ./dist, Worker `crm`). Currently served via root bundle at mino.mobi/crm/; own subdomain not attached.",
      "paths": [
        "crm/**"
      ]
    },
    {
      "surface": "audio",
      "dir": "audio",
      "endpoint": "audio.mino.mobi (pending attach)",
      "type": "fullstack",
      "branch": "claude/landing-projects-takeover-pKkmW",
      "uses": [],
      "provides": null,
      "status": "MANAGED (domain pending) \u2014 onboarded to Actions (deploy-audio.yml) as an ADDITIVE own-worker deploy. Non-breaking: still served via its current path; attach the custom domain in the Cloudflare dashboard to complete the carve-out, then drop from the root bundle.",
      "note": "Audio Rooms \u2014 voice-room app. Vite monorepo (apps/web -> audio/dist) + Worker `audio-rooms-api` with Durable Object RoomCoordinator. Domain audio.mino.mobi not yet attached; first deploy stands up the worker+DO at workers.dev. Attach domain in dashboard to launch.",
      "paths": [
        "audio/**"
      ]
    },
    {
      "surface": "os",
      "dir": "os",
      "endpoint": "os.mino.mobi",
      "type": "frontend",
      "branch": "claude/os-deploy-surface-474bz3",
      "uses": [
        "os-api.minomobi.com"
      ],
      "provides": null,
      "status": "MANAGED (frontend) \u2014 standalone PDS shell ships and works with no backend (login + ls/cat/find/du/blob/curl/sync/sql, all client-side XRPC + WASM CAR parse + DuckDB). `kimi` takes --model (kimi3 | ds4-flash | ds4-pro) and --harness (claude | opencode) \u2014 the cell matrix. public/arena/ serves published bake-off runs; public/_headers gives entries an opaque origin (CSP sandbox allow-scripts) so model-written HTML cannot reach the .mino.mobi SSO cookie or the Anthropic key in localStorage. The `kimi`/`container` commands probe the os-api backend at RUNTIME (/health, 4s timeout) and report exactly what's missing instead of dangling a dead WebSocket \u2014 no build-time gating variable needed (VITE_CONTAINER_API_URL remains an optional override). Worker name `os` owns os.mino.mobi via custom_domain route (golden rule OK). CLEANUP: delete the orphan `pds-os` worker.",
      "note": "Browser-based terminal for your ATProto PDS (XRPC commands, DuckDB SQL, AI chat) and the front end of the cross-model/cross-harness agent platform: `kimi --model= --harness=` boots any (harness, model) cell in the os-api container. Serves published bake-off runs at /arena/<run-id>/. (full description: os/CLAUDE.md)",
      "paths": [
        "os/**",
        "!os/api/**"
      ]
    },
    {
      "surface": "os-api",
      "dir": "os/api",
      "endpoint": "os-api.minomobi.com",
      "type": "backend",
      "branch": "claude/os-deploy-surface-474bz3",
      "uses": [],
      "provides": "os-api.minomobi.com",
      "status": "MANAGED \u2014 SELF-PROVISIONING deploy (deploy-os-api.yml, create-mmo-db pattern): every run idempotently wrangler-deploys worker os-mino-api (Docker image built on the runner; custom_domain route binds os-api.minomobi.com \u2014 golden rule), syncs worker secrets from GitHub (CAP_SIGNING_KEY auto-generated once; MOONSHOT_API_KEY + DEEPSEEK_API_KEY <- GH secrets; GITHUB_TOKEN <- GH secret OS_AGENT_GITHUB_TOKEN), then health-checks the live domain. NO R2 (unavailable on this plan, CF 10042 \u2014 learned from run #1): workspace persistence is chunked tarballs in the ContainerShell DO's own SQLite storage. ALLOWED_DIDS is committed [vars] config (morphyx service DID). Un-automatable human prereqs (once): enable Cloudflare Containers on the account + mint the Moonshot key/PAT into GH secrets \u2014 see os/RUNBOOK.md.",
      "note": "The agent-platform backend for os.mino.mobi: per-DID Cloudflare Container running TWO agent harnesses (Claude Code + OpenCode) against N model profiles (kimi3, ds4-flash, ds4-pro, native claude) via worker-injected AGENT_PROFILES, PTY over WebSocket, DO-storage-synced\u2026 (full description: os/api/CLAUDE.md)",
      "paths": [
        "os/api/**",
        ".github/workflows/deploy-os-api.yml"
      ]
    },
    {
      "surface": "aub",
      "dir": "aub",
      "endpoint": "aub.mino.mobi",
      "type": "frontend",
      "branch": "claude/game-website-deploy-2ffuu2",
      "uses": [],
      "provides": null,
      "paths": [
        "aub/**"
      ],
      "note": "Ecdysium (aubrika/ecdysium) \u2014 a Rust + macroquad sci-fi horror roguelike vendored under aub/game and compiled to wasm32-unknown-unknown\u2026 (full description: aub/CLAUDE.md)"
    },
    {
      "surface": "human",
      "dir": "human",
      "endpoint": "human.mino.mobi",
      "type": "fullstack",
      "branch": "claude/human-machinery-Hm7qX2",
      "uses": [
        "atpolls-db"
      ],
      "provides": null,
      "status": "MANAGED \u2014 new surface via deploy-human.yml (Worker `human`, custom_domain human.mino.mobi). Idempotent D1 migration (0033_human_stats) before deploy; health-check curl after.",
      "op": "create",
      "note": "human.mino.mobi \u2014 HUMAN MACHINERY, the bias arcade: an explorable museum of cognitive biases where every exhibit is a 60-second game rigged by your own brain (play \u2192 fail \u2192 learn \u2192 verify \u2192 wormhole)\u2026 (full description: human/CLAUDE.md)",
      "paths": [
        "human/**",
        "poll/apps/api/migrations/0033_human_stats.sql"
      ]
    },
    {
      "surface": "wormhole",
      "dir": "wormhole",
      "endpoint": "wormhole.mino.mobi",
      "type": "frontend",
      "branch": "claude/academic-wormhole-roulette-lpuqfq",
      "uses": [],
      "provides": null,
      "paths": [
        "wormhole/**"
      ],
      "note": "Academic Wormhole Roulette. Thin assets Worker (worker `wormhole`, custom_domain wormhole.mino.mobi) \u2014 no build, no D1, no AI, no secrets\u2026 (full description: wormhole/CLAUDE.md)"
    },
    {
      "surface": "bismuth",
      "dir": "bismuth",
      "endpoint": "bismuth.mino.mobi",
      "type": "frontend",
      "branch": "claude/bismuth-crystal-procgen-g6t0dh",
      "uses": [],
      "provides": null,
      "paths": [
        "bismuth/**",
        "packages/bismuth/**",
        "packages/tilings/**",
        "scripts/sync-dataviz.mjs",
        ".github/workflows/deploy-bismuth.yml"
      ],
      "note": "Bismuth hopper crystals grown brick by brick by a seeded colony of mason agents (Kossel kinetics + the Berg effect as local rules) on a substrate — the cubic lattice, or any plane tiling from packages/tilings stacked into prisms (Penrose = a decagonal quasicrystal) — rendered in WebGL with per-pixel thin-film interference. Thin assets Worker (worker `bismuth`, custom_domain bismuth.mino.mobi) — no build, no D1, no AI, no secrets. /c/<seed> cubic and /q/<seed> quasicrystal permalinks; /lab the playground; /api/crystal… (full description: bismuth/CLAUDE.md)"
    },
    {
      "surface": "hopper",
      "dir": "hopper",
      "endpoint": "hopper.mino.mobi",
      "type": "frontend",
      "branch": "claude/bismuth-crystal-procgen-g6t0dh",
      "uses": [],
      "provides": null,
      "paths": [
        "hopper/**",
        "packages/bismuth/**",
        "packages/tilings/**",
        "scripts/sync-dataviz.mjs",
        ".github/workflows/deploy-hopper.yml"
      ],
      "note": "hopper — a first-person puzzle platformer on the bismuth engine: a slab in the void, a bucket above, a pocket of mason packs. Deploy a pack on a plane and it grows a hopper crystal from there (freezing what was growing — the plane is the next platform), climb it as it grows, drop into the bucket. Every level number is a permalink; the bucket sits where the engine's own survey says a stack of the packs reaches; /l/<n>/<tiling> plays the same level on prisms over any of the ten plane tilings (Penrose included). Thin assets Worker (worker `hopper`, custom_domain hopper.mino.mobi) — no build, no D1, no AI, no secrets. /l/<n> levels; /api/level?n=…&t=… (full description: hopper/CLAUDE.md)"
    },
    {
      "surface": "neuro",
      "dir": "neuro",
      "endpoint": "neuro.mino.mobi",
      "type": "frontend",
      "branch": "claude/website-hidden-paper-8vum5k",
      "uses": [],
      "provides": null,
      "status": "LIVE \u2014 first deploy 2026-07-25 bound `neuro.mino.mobi (custom domain)` and the site answered. The hostname was new and did not resolve beforehand; wrangler created the custom domain itself, no dashboard step required (mino.mobi is a zone on this account). Golden rule still applies to later deploys: confirm the log binds the custom domain.",
      "note": "Cognitive-science models reimplemented from their papers in Rust\u2192WASM and made runnable in the browser, each shown against the published result it replicates. Assets-only worker `neuro`, staged to ../.neuro-stage (engine-rs sources excluded). First resident: /homeostasis/ \u2014 the reservoir of Falandays, Nguyen & Spivey 2021\u2026 (full description: neuro/CLAUDE.md)",
      "paths": [
        "neuro/**"
      ],
      "serves": [
        "homeostasis"
      ]
    },
    {
      "surface": "sci",
      "dir": "sci",
      "endpoint": "sci.mino.mobi",
      "type": "frontend",
      "branch": "claude/sci-surface-mri-research-ji1xf9",
      "uses": [],
      "provides": null,
      "status": "LIVE — first deploy 2026-08-15 bound `sci.mino.mobi (custom domain)` and the site answered. The hostname was new and did not resolve beforehand; wrangler created the custom domain itself, no dashboard step required (mino.mobi is a zone on this account). Golden rule still applies to later deploys: confirm the log binds the custom domain.",
      "note": "Scientific instruments taken apart, one page per instrument, each built around a Rust→WASM solver the visitor drives and each mechanism claim traced to a primary source. Assets-only worker `sci`, staged to ../.sci-stage (engine-rs/ and research/ excluded). First instrument, MRI, in four parts plus a capstone console: /mri/ the detection chain (reciprocity, coil sensitivity, spin echo, the B0^2 law), /mri/kspace/ the spatial encoding (analytic phantom, real acquisition, FFT reconstruction, EPI distortion), /mri/contrast/ the tissue properties and sequence equations (Stanisz 2005 relaxation times, closed forms validated against a Bloch simulation, the Ernst angle, the TR-TE curve where two tissues become invisible), and /mri/acoustics/ why it screams (Lorentz force on the gradient windings, the acoustic comb locked to the sequence clock, synthesised live via Web Audio), and /mri/console/ all four at once (the SNR scaling law with receiver noise added in k-space, so every knob's cost is visible in one image). Engine known-answer tested against closed-form physics: sci/engine-rs, 52 tests. (full description: sci/CLAUDE.md)",
      "paths": [
        "sci/**"
      ],
      "serves": [
        "mri",
        "mri/kspace",
        "mri/contrast",
        "mri/acoustics",
        "mri/console"
      ]
    },
    {
      "surface": "rant",
      "dir": "rant",
      "endpoint": "rant.mino.mobi",
      "type": "fullstack",
      "branch": "claude/standard-site-blog-page-319rod",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "paths": [
        "rant/**",
        "packages/oauth-client/auth.js",
        ".github/workflows/deploy-rant.yml"
      ],
      "note": "The standard.site publication engine \u2014 written entirely in Rust (workers-rs worker + wasm-bindgen browser module, one shared rant-core engine). Posts are site.standard.document records in the author\u2019s own PDS; subscribe/recommend write graph records to the reader\u2019s repo. Eleven server-rendered \u201cpredicate\u201d views (?view=skeleton+bionic) descended from read.mino.mobi\u2019s reading modes. Edge-rasterised OG cards, RSS/JSON Feed/llms.txt, and an MCP endpoint. (full description: rant/CLAUDE.md)",
      "status": "MANAGED \u2014 verified prod (deploy log binds rant.mino.mobi (custom domain); auth worker carries the site.standard.* scope)"
    },
    {
      "surface": "fifty",
      "dir": "fifty",
      "endpoint": "fifty.mino.mobi",
      "type": "fullstack",
      "branch": "claude/fifty-microsites-deploy-fyjk1q",
      "uses": [],
      "provides": null,
      "paths": [
        "fifty/**",
        ".github/workflows/deploy-fifty.yml"
      ],
      "note": "Fifty ATProto app pitches, one deploy surface: a landing index at / and one page per concept at /c/<n>. Thirty are working tools; twenty render an honest write-up of why they were not built\u2026 (full description: fifty/CLAUDE.md)"
    },
    {
      "surface": "farm",
      "dir": "farm",
      "endpoint": "farm.mino.mobi",
      "type": "frontend",
      "branch": "claude/farmville-atproto-game-745mcr",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "op": "create",
      "status": "NEW \u2014 first deploy pending. Worker `farm` + custom_domain route (farm.mino.mobi); wrangler creates the subdomain itself on run #1 (neuro/board precedent). Requires the auth worker deployed with the com.minomobi.farm.* collections FIRST (same branch owns both; auth deploys on the same push).",
      "note": "Harvestople \u2014 farming on ATProto (the board pattern: no backend, the player's PDS is the database). Real-organism crops vendored from the hoop ag pack, wall-clock growth, gacha seed desk per-DID biome, a planetary-metals mine, the Galenic alchemy bench, public achievement records with one-tap bsky share, and friend-to-friend tends/gifts as public records in each side's own repo. (full description: farm/CLAUDE.md)",
      "paths": [
        "farm/**",
        ".github/workflows/deploy-farm.yml"
      ]
    },
    {
      "surface": "farm-next",
      "dir": "farm",
      "endpoint": "farm-next.mino.mobi",
      "type": "frontend",
      "branch": "claude/farm-next",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": null,
      "op": "create",
      "status": "NEW \u2014 first deploy pending. Worker `harvestople-next` + custom_domain route (farm-next.mino.mobi) via farm/wrangler.next.jsonc; wrangler provisions the subdomain on run #1 (farm precedent, same zone).",
      "note": "THE TESTING TABLE \u2014 the same farm/ code deployed from claude/farm-next, where granted petitions go live immediately so the petitioner can play their idea within the hour. Shares the plot record with mainline under the save covenant (farm.x pocket, frozen v \u2014 test/covenant.selftest.mjs gates both worlds); next-scope.mjs keeps the rails (store/auth/wrangler/lexicons/sims) out of experiments' reach. Features graduate at the merge party or retire. (full description: farm/CLAUDE.md)",
      "paths": [
        "farm/**",
        ".github/workflows/deploy-farm-next.yml"
      ]
    },
    {
      "surface": "bsky-bot",
      "dir": "workers/bsky-bot",
      "endpoint": "mino-bsky-bot",
      "type": "backend",
      "branch": "claude/minomobi-landing-page-vg37b8",
      "uses": [],
      "provides": null,
      "status": "NEW \u2014 the lab factory's outer loop. Cron-polls listNotifications, routes mentions deterministically on reply.root.uri, registers the site in the SlotRegistry Durable Object, and fires repository_dispatch at lab-build.yml. FAIL-CLOSED on both axes: an empty WHITELIST admits nobody and BOT_ENABLED != \"true\" means observe-and-reply with no dispatch and no spend. Headless \u2014 no custom domain. Human prereqs: KV namespace id, Bluesky app password, and a PAT scoped to actions:write.",
      "note": "The Bluesky bot behind the lab factory. A whitelisted mention becomes a leased slot and a dispatched build; thread root is the identity key, so iteration needs no model call. (full description: workers/bsky-bot/CLAUDE.md)",
      "paths": [
        "workers/bsky-bot/**",
        ".github/workflows/deploy-bsky-bot.yml"
      ]
    },
    {
      "surface": "words",
      "dir": "words",
      "endpoint": "words.mino.mobi",
      "type": "fullstack",
      "branch": "claude/procedural-crossword-generation-p8hv2q",
      "uses": [
        "atpolls-db"
      ],
      "provides": null,
      "status": "MANAGED — deploy-words.yml (Worker `words`, custom_domain words.mino.mobi). OWNERSHIP MOVED to claude/procedural-crossword-generation-p8hv2q, which added the crossword at /cross/; the word game at the root is unchanged and its selftests still gate the deploy. Engine, worker, push and crossword selftests plus a lexicon-freshness check gate the deploy; idempotent D1 migrations 0035_words and 0036_words_push before it.",
      "op": "create",
      "note": "words.mino.mobi — TWO APPS ON ONE SURFACE. / is the word game: Words With Friends without the ads, accounts or nagging, 1-4 seats and any of them a bot, on boards with five squares of our own — quad letter, MIRE (scores zero), HALF (halves the word after every multiplier), TOLL (a flat 8 off the play) and STONE, a hole words break on like the edge. The opponent is a deterministic Appel-Jacobson generator over a committed DAWG of ENABLE; installable PWA, so bot games play entirely offline; turn notifications are real Web Push implemented on WebCrypto. /cross/ is procedurally generated crosswords: a puzzle is a pure function of (seed, size, difficulty, lexicon) generated in the browser, so nothing is stored and the permalink IS the puzzle. Symmetric grids under a min-entry rule that makes every square checked; the fill is a CSP over a separate 50,000-answer clued lexicon, solved with MRV and AC-3 at the level of letters. Difficulty is block density — both vocabulary knobs were built, measured and rejected. (full description: words/CLAUDE.md, words/cross/CLAUDE.md)",
      "paths": [
        "words/**",
        "poll/apps/api/migrations/0035_words.sql",
        "poll/apps/api/migrations/0036_words_push.sql",
        ".github/workflows/deploy-words.yml"
      ],
      "cohesion": "self-contained"
    },
    {
      "surface": "zest",
      "dir": "zest",
      "endpoint": "zest.mino.mobi",
      "type": "fullstack",
      "branch": "claude/3d-feed-embedding-geometry-uiveyf",
      "uses": [
        "atpolls-db"
      ],
      "provides": null,
      "status": "MANAGED — new surface via deploy-zest.yml (Worker `zest`, custom_domain zest.mino.mobi). zest.mino.mobi did not resolve before this branch, so the first deploy creates the worker and attaches the domain itself (the `words` / `neuro` precedent — mino.mobi is a zone on this account). Two pure-module selftests gate the deploy; idempotent D1 migration 0037_zest before it. UNVERIFIED FROM THE SANDBOX: the domain binding, Workers AI quota, and the first basis build all need the deploy log and a live check.",
      "op": "create",
      "note": "zest.mino.mobi — legibility of embeddings, as a fruit-ninja game. A post's 768-dim embedding is used as the SPECTRUM of a surface: r(θ,φ) = R·(1 + amp·Σ ĉ_lm·Y_l^m), where the 24 loudest corpus dimensions take harmonic bands l=1..4 one-for-one (the lobes), l=0 is reserved for ‖z‖ (ordinary posts are small pebbles, strange ones big), and the ~740 quiet dimensions fold into bands 5..10 by a seeded Johnson–Lindenstrauss projection (the grain). The map is linear and the harmonics orthonormal, so Parseval makes the L² distance between two surfaces exactly the distance between their vectors — checked against a Gauss–Legendre quadrature. Posts rain down and you slice them; Hunt mode scores you with a one-sided exact binomial test, so the page can tell you that you were indistinguishable from guessing. Text-only posts by design. Workers AI bge-base-en-v1.5, cached by content hash on D1; the corpus basis is versioned and shared, with an announced session-local fallback. /atlas is the reading room, /how is the map and its three measured failure modes. (full description: zest/CLAUDE.md)",
      "paths": [
        "zest/**",
        "poll/apps/api/migrations/0037_zest.sql",
        "poll/apps/api/migrations/0038_zest_status.sql",
        ".github/workflows/deploy-zest.yml"
      ],
      "cohesion": "self-contained"
    },
    {
      "surface": "lab",
      "dir": "lab/www",
      "endpoint": "minomobi.com",
      "type": "frontend",
      "branch": "claude/lab-www",
      "uses": [],
      "provides": "minomobi.com",
      "status": "MANAGED \u2014 the whole lab factory on one surface. Worker `lab` owns minomobi.com (lab.minomobi.com kept as an alias) and serves every agent-built site at minomobi.com/<name>/, an index over them, and /.well-known/atproto-did from a BOT_DID var for the service account handle. ONE surface, not three: Workers Static Assets allows 100,000 files per version on the Paid plan, so the slot sharding was routing around a limit two orders of magnitude away. Names are permanent \u2014 no lease, no recycler. The whole domain is agent-generated content, quarantined from mino.mobi, which shares neither cookie scope nor reputation with it.",
      "note": "The lab factory. Tag the Bluesky service account and an agent builds you a site at minomobi.com/<name>/, permanently. (full description: lab/www/CLAUDE.md)",
      "paths": [
        "lab/www/**",
        "lab/_kit/**",
        "scripts/gen-lab-tenants.mjs",
        ".github/workflows/deploy-lab.yml"
      ]
    },
    {
      "surface": "loop",
      "dir": "loop",
      "endpoint": "loop.mino.mobi",
      "type": "frontend",
      "branch": "claude/loop-graph-ticketing-surface-7qxu7c",
      "uses": [],
      "provides": null,
      "status": "MANAGED and LIVE \u2014 the viewing surface for the agent loop's ticket graph. loop.mino.mobi was created by the first deploy from the routes[] declaration (run 30875224557 logged \"loop.mino.mobi (custom domain)\") and answers /health 200. It did not exist before that run; DEPLOYS.md \u00a77's dashboard-only rule covers detaching and moving a domain, not creating a new one on a zone already in the account.",
      "note": "The loop apparatus: the ticket graph, the ready queue, the governor, and the quality-against-turn-count curve. Reads loop/data/graph.json, generated from the ledger in .github/loop/. (full description: loop/CLAUDE.md)",
      "paths": [
        "loop/**",
        ".github/workflows/deploy-loop.yml"
      ]
    },
    {
      "surface": "ken",
      "dir": "ken",
      "endpoint": "ken.mino.mobi",
      "type": "frontend",
      "branch": "claude/repo-study-fields-0ftd34",
      "uses": [],
      "provides": null,
      "paths": [
        "ken/**",
        ".github/workflows/deploy-ken.yml",
        ".github/loop/turns.jsonl",
        ".github/loop/runs.jsonl",
        "bakeoff/results/**",
        "os/public/arena/**"
      ],
      "status": "MANAGED — verified prod 2026-08-22. First deploy (run #1) bound ken.mino.mobi automatically: wrangler created the custom domain from the routes block, so the dashboard step docs/DEPLOYS.md §7 warns about was NOT needed here — the zone is in the account and the API token could attach it. Verified live: / , /syllabus and /protocol all 200 with the expected content, and the selftest ran green as the deploy gate.",
      "note": "The study programme behind loop/plant and bakeoff: the measurement of unattended work, as a field. Thin assets Worker, no build/D1/AI/secrets. Thirteen pages: / masthead and roadmap DAG; /syllabus curriculum; /methods the house standard (16 rules); /lab the design calculator; /run the procedure in ASD-STE100; /shapes an explorer over the shape space to 7 turns; /wp1-/wp4 the working papers, the last two with live calculators; /register the hypothesis register (12, with status and evidence); /log the findings log (152 entries); /protocol a registered-report skeleton. TWO code dirs, and the split matters: ken/graph/ is pure ES modules SERVED to the browser, so /shapes runs the code the selftests gate rather than a copy (rewrite-rule plans, nine roles by degree, orbits, the ken ratio, layer profiles, exhaustive enumeration, ancestry digests, regimes, attenuation, the exchange rate, the gate, hypotheses as data); ken/lab/ is node-only and assetsignored. ken.selftest.mjs plus thirteen lab selftests gate citations, three prose registers, roadmap coherence and every published number. (full: ken/CLAUDE.md)"
    },
    {
      "surface": "plant",
      "dir": "plant",
      "endpoint": "plant.minomobi.com",
      "type": "frontend",
      "branch": "claude/loop-graph-ticketing-surface-7qxu7c",
      "uses": [],
      "provides": null,
      "status": "MANAGED and LIVE \u2014 the agent loop's WORK PRODUCT, deployed so people outside the loop can judge it. plant.minomobi.com was created by the first deploy from the routes[] declaration (run 30959458804) and answers /health 200 with {\"ok\": true}. The domain is NOT plant.mino.mobi and that is a security decision: workers/auth sets its session cookie with Domain=.mino.mobi and isAllowedOrigin() allowlists any hostname ending .mino.mobi, so agent-written JS on such a host could call auth.mino.mobi/pds/* with a signed-in visitor's session. CLOSED-LOOP.md \u00a76.1. Provisioning on that first run is worth knowing: DNS did not resolve at all for ~10s, then Cloudflare served error 1104 for ~60s while the certificate issued, then it worked. Only a first deploy sees that.",
      "note": "Written by loop turns, not by hand \u2014 this is the tree the fleet may edit, and the only place its output reaches a stranger. Deliberately separate from foam/ (hand-authored, different domain, different workflow): the comparison between them is worth nothing if the trees are contaminated. Currently serves the summon inspector \u2014 Platonic cells in an anisotropic foam, with the naive-placement trap flippable so a visitor can see the 22\u00b0 rather than be told about it. (full description: plant/CLAUDE.md)",
      "paths": [
        "plant/**",
        ".github/workflows/deploy-plant.yml"
      ]
    },
    {
      "surface": "table",
      "dir": "table",
      "endpoint": "table.mino.mobi",
      "type": "frontend",
      "branch": "claude/ttrpg-character-sheet-gen-886np4",
      "uses": [],
      "provides": null,
      "status": "MANAGED \u2014 NEW SURFACE, domain not yet provisioned. table.mino.mobi is declared in table/wrangler.jsonc routes[] and is created by the first deploy (the same path plant.minomobi.com took: DNS misses for ~10s, then Cloudflare 1104 for ~60s while the cert issues, then it works). Until that first run lands, treat the endpoint as pending and verify the log binds `table.mino.mobi (custom domain)`.",
      "note": "Procedural character sheets for RPGs whose rules text is openly licensed \u2014 only open text can ship as a generator. Thin assets Worker (`table`), no build, no D1, no secrets, all in-browser from a seed. /cairn \u2014 Cairn 2e (Yochai Gal, CC BY-SA 4.0) chargen, slot-accurate, print sheet, measured party radar. /cairn/encounter \u2014 an oracle: Cairn has no challenge rating, so it simulates the fight, abilities included. /cairn/arena \u2014 one fight replayed turn by turn, or piloted. /cairn/kit \u2014 hands a haul round by measurement: each item to whoever averts most casualties, error bars shown. /cairn/trials \u2014 a ladder of 8 real fights carrying wounds between them; two modes, one reward-invariant by construction. /cairn/run \u2014 the roguelite: pilot every fight, rest or loot between, advance on the Scars table. /cairn/items \u2014 items priced per slot. Toll/swing, the delve model and the loot table are ours, labelled. /srd5 \u2014 SRD 5.2.1 (CC BY 4.0; fixed attribution, trademarks unlicensed, so no branding): 330 stat blocks parsed from the official PDF with attack dice, reach and damage type, plus the XP budget. Ten selftests gate the deploy. Read table/CLAUDE.md first. (full description: table/CLAUDE.md)",
      "serves": [
        "cairn",
        "cairn/kit",
        "cairn/trials",
        "cairn/run",
        "cairn/encounter",
        "cairn/arena",
        "cairn/items",
        "srd5",
        "srd5/corpus"
      ],
      "paths": [
        "table/**",
        ".github/workflows/deploy-table.yml"
      ]
    },
    {
      "surface": "silk",
      "dir": "silk",
      "endpoint": "silk.mino.mobi",
      "type": "frontend",
      "branch": "claude/spiderweb-physarium-agent-ta17v4",
      "uses": [],
      "provides": null,
      "paths": [
        "silk/**",
        ".github/workflows/deploy-silk.yml"
      ],
      "note": "The stigmergic orb-web weaver. An agent with no plan and no map builds a web from local rules and the silk it has already laid; the page then measures what it produced\u2014 one boundary admits a FAMILY of webs, tight in the numbers a field biologist takes off a photograph and uncorrelated in geometry, and the spread is construction order rather than noise. Static assets worker, no build, no backends. Two node selftests gate the deploy because they are the page's claims (full description: silk/CLAUDE.md)."
    },
    {
      "surface": "hose",
      "dir": "workers/hose",
      "endpoint": "hose.mino.mobi",
      "type": "backend",
      "branch": "claude/txt-airports-bluesky-feed-pu4pbh",
      "uses": [],
      "provides": "hose.mino.mobi",
      "paths": [
        "workers/hose/**",
        "packages/feedgen/**"
      ],
      "note": "Bluesky feed-generator service whose input is the firehose itself — the other half of b.mino.mobi/feedgen. A feed defined only by what it excludes (\"not politics, not porn, not video, not a reply, not in this bot list\") has no query you can ask the AppView for, so a single Durable Object SAMPLES Jetstream: it wakes hourly, holds the socket open 20s, runs every post create through each registered feed's filters as it arrives, and appends matches to a chunked ring that getFeedSkeleton pages. Sampling not streaming is deliberate — the firehose measures 38.8 creates/sec, and holding it open permanently costs ~84% of the account-wide duration allowance to observe posts nobody reads; at 20s/hour it still collects ~680 matches a day and stays inside the free allowances. The ring is keyed by absolute chunk index, so an append writes ONE key and ageing out is a delete. Definitions come off the owner's PDS as a native com.minomobi.feedgen.def record OR a SkyFeed-era skyfeedBuilder, so a SkyFeed feed moves here by repointing one field. The filter predicate is shared with b/ via packages/feedgen/match.js, so b's preview cannot drift from what hose serves."
    },
    {
      "surface": "bsky",
      "dir": "bsky",
      "endpoint": "bsky.mino.mobi",
      "type": "frontend",
      "branch": "claude/bsky-app-view-feasibility-8sdflz",
      "uses": [],
      "provides": null,
      "paths": [
        "bsky/**",
        "packages/atproto/jetstream.js",
        "packages/atproto/constellation.js",
        "packages/atproto/bsky.js"
      ],
      "note": "An AppView with no database… (full description: bsky/CLAUDE.md)",
      "status": "NEW 2026-09-05 — scaffold. Domain bsky.mino.mobi did not resolve before this branch; the custom-domain route is attached by the first wrangler deploy. VERIFY the run log binds `bsky.mino.mobi (custom domain)` before believing it (golden rule)."
    },
    {
      "surface": "atlas",
      "dir": "atlas",
      "endpoint": "atlas.mino.mobi",
      "type": "frontend",
      "branch": "claude/county-level-data-maps-s9u3qx",
      "uses": [],
      "provides": null,
      "paths": [
        "atlas/**",
        "packages/geoviz/**",
        "packages/geohier/**",
        ".github/workflows/deploy-atlas.yml"
      ],
      "note": "County-level North America (worker `atlas`, custom_domain atlas.mino.mobi). Thin routing worker over static assets — no build, no D1, no secrets. Geometry is a real topology (shared arcs) built from Census, StatCan, CONABIO/INEGI and Natural Earth by atlas/etl; data comes from BEA, Census PEP, USDA ERS, IRS SOI, StatCan and INEGI, all keyless. Only stocks are stored; every rate is recomputed at the level on screen. Imports packages/geoviz + packages/geohier, vendored into atlas/lib by scripts/sync-dataviz.mjs."
    },
    {
      "surface": "fold",
      "dir": "fold",
      "endpoint": "fold.mino.mobi",
      "type": "frontend",
      "branch": "claude/protein-folding-rust-wasm-dyceu3",
      "uses": [],
      "provides": null,
      "status": "NEW — first deploy. fold.mino.mobi did not resolve beforehand; wrangler is expected to create the custom domain itself, as it did for neuro (mino.mobi is a zone on this account). Confirm the run binds `fold.mino.mobi (custom domain)` — green alone is not proof.",
      "note": "Watch a protein fold. A Clementi–Onuchic structure-based (Gō) C-alpha model under Langevin dynamics, written in Rust and compiled to wasm32-unknown-unknown with no wasm-bindgen; hand-written WebGL2 renderer with an HDR bloom pass. Nine deposited structures ship with the site… (full description: fold/CLAUDE.md)",
      "paths": [
        "fold/**"
      ]
    },
    {
      "surface": "tape",
      "dir": "tape",
      "endpoint": "tape.mino.mobi",
      "type": "frontend",
      "branch": "claude/rfid-book-reader-design-ainq0k",
      "uses": [],
      "provides": null,
      "paths": [
        "tape/**"
      ],
      "note": "The open-source NFC card audio player — a Toniebox you build for the price of the tags. Thin assets Worker (worker `tape`, custom_domain tape.mino.mobi) — no build/D1/AI/secrets… (full description: tape/CLAUDE.md)"
    },
    {
      "surface": "clef",
      "dir": "clef",
      "endpoint": "clef.mino.mobi",
      "type": "frontend",
      "branch": "claude/sheet-music-viewer-composer-qb4ljl",
      "uses": [
        "auth.mino.mobi"
      ],
      "provides": "sheet-music",
      "status": "MANAGED — verified prod (clef.mino.mobi bound as a custom domain on run #1, 2026-09-05)",
      "note": "Sheet-music viewer and composer. Reads a working subset of LilyPond notation (Dutch/English/German note names, \\transpose, ornaments), engraves it as classical notation in SVG with its own glyph outlines and no music font, plays it back through a small WebAudio patch bank, and exports .ly/.mid/.svg/.wav. Browse opens the Mutopia Project's ~2,300 LilyPond-source scores through a narrow read proxy in this surface's own worker at /mutopia/* (one origin, GET only, two path shapes, edge-cached) — Mutopia sends no CORS header. Publishing writes one com.minomobi.clef.piece record to the reader's own PDS; the site stores nothing. Full notes in clef/CLAUDE.md.",
      "paths": [
        "clef/**",
        ".github/workflows/deploy-clef.yml"
      ]
    }
  ],
  "unmanaged": {
    "$comment": "Have a wrangler config but NO deploy workflow. `sites` here are all currently BUNDLED into the root Pages project (served at mino.mobi/<name>/) \u2014 their own-subdomain workers are not attached. Each needs a CARVE-OUT (own worker deploy + domain attach + drop from root bundle), not just a workflow. `in_progress` + `reference_workers` as before.",
    "sites": [],
    "in_progress": [],
    "reference_workers": [
      "workers/cards-mint",
      "workers/cluster-batch"
    ]
  }
}
