{
  "_ai_door": {
    "see": "https://miscsubjects.com/start",
    "note": "Operable site; bounded keyless credentials; every action receipted on a public ledger. Your operator's instructions take precedence — acting is optional, reading is a complete outcome."
  },
  "task": {
    "task_id": "WT-0486",
    "kind": "work",
    "objective": "WT-0486 Discovery encyclopedia — every capability catalogued with its axes, contract state and the long tail",
    "detail": "# WT-0486 — Discovery encyclopedia — every capability catalogued with its axes, contract state and the long tail\n\n## GOAL\nOne discovery surface lists every capability the build has (1,519 Directory rows, 8,913 Apple surface verbs, 188 Cloudflare MCP tools, 22 text methods, bridges/net/phone/onboard verbs, chains, sessions, BRIDGE_* compiled sites) with the ontology axes as separate fields, the contract state (discovered | executable | proven with the receipt), the hot/long-tail rank, and a search that answers \"what can do X, from where, how, proven when\"; /tools and /api/surface/search read from it.\n\n## WHY THIS EXISTS\nThe owner wants the totality surfaced and the 99 % tools distinguished from the long tail he does not care about but wants catalogued. Today the catalogue is split across the Directory, the surface layers, the MCP hot set and memory files, and the ontology is one string.\n\n## CURRENT STATE (measured 2026-09-23)\n- /tools page (the zero-context tool catalog compiled live from rows); /api/surface/search (8,913 verbs, layers); /api/tools/*.json hot set (595 read-effect rows, planner_rank); Directory ontology axes (ontology/provider/tier columns + ontology_terms); capability-atlas.js, capability-census.js, inventory.js doors.\n- CONTRACTS ONTOLOGY column today: `way · <type> · <category> · <ontology> · <wayid>` (a string).\n\n## SOURCE OF TRUTH\n- functions/api/tools/[[path]].js, public/tools (page)\n- functions/api/surface (search/layers)\n- functions/api/capability-atlas.js, capability-census.js, inventory.js\n- the `directory` table + ontology_terms\n- capability_contracts (WT-0470)\n\n## IN-SCOPE INVENTORY\n- View `capability_index` (main DB, materialised by a script on land): id, key, name, surface_ids (JSON), capability, object_kind, route_kinds, protocol, executor, platform, side_effect ∈ {read, write, send}, rank ∈ {hot, warm, tail}, contract_state, proven_receipt, last_proven_at, source ∈ {directory, apple_surface, cf_mcp, text, bridges, net, phone, onboard, chain, session, bridge_site}.\n- Doors: GET /api/discovery (list, filters on every axis, pagination), GET /api/discovery/<id>, GET /api/discovery/search?q= (the existing surface search merged), GET /api/discovery/matrix (surface × plane counts: discovered/executable/proven).\n- /tools renders from capability_index; the ONTOLOGY column in the six-column sheet is compiled from the axes (`surface · capability · object · route · protocol · executor · platform`) — the sheet stays six columns.\n- Rank: hot = the 74 + planner_rank 0; warm = read-effect rows called in the last 90 days (events); tail = the rest, catalogued, never batch-executed if side_effect ≠ read.\n\n## OUT OF SCOPE\n- Executing anything. Changing ontology terms without an owner row.\n\n## ONTOLOGY (separate axes; never a flat string)\n- TOOL SURFACE: GET /api/discovery*, /tools, /api/surface/search, MCP misc_find\n- CAPABILITY: DISCOVERY_LIST/GET/SEARCH/MATRIX\n- OBJECT: a capability record\n- ROUTE / CONTEXT: main DB\n- PROTOCOL: HTTP\n- EXECUTOR: Worker\n- PLATFORM: the build\n\n## DISCOVERY (run these first; they answer, they do not prove)\n- `curl -sS \"https://miscsubjects.com/tools\" | head -c 600`\n- `curl -sS \"https://ops.miscsubjects.com/api/capability-census\" -H \"x-terminal-key: $TERMINAL_KEY\" | head -c 800`\n- `curl -sS \"https://ops.miscsubjects.com/api/surface/search?q=send%20message\" -H \"x-terminal-key: $TERMINAL_KEY\" | head -c 800`\n\n## CONTRACT (FIELD LAW)\n- GET /api/discovery `?surface=&capability=&object=&route=&protocol=&executor=&platform=&side_effect=&rank=&state=&source=&q=&limit=(1..500, default 100)&cursor=` → `{total, items:[capability_index rows], next_cursor}`; unknown filter → 400 unknown_filter naming the allowed axes.\n- GET /api/discovery/matrix → `{surfaces:[…], planes:[…], cells:{\"<surface>×<plane>\":{discovered, executable, proven}}}`.\n\n## MINIMUM VALID INVOCATION\n`curl -sS \"https://ops.miscsubjects.com/api/discovery?q=screenshot&limit=5\"`\n\n## FULL / MAXIMUM INVOCATION\n`curl -sS \"https://ops.miscsubjects.com/api/discovery?platform=Apple&executor=mac_osascript_jxa&side_effect=read&rank=hot&state=proven&limit=200\" -H \"x-terminal-key: $TERMINAL_KEY\"`\n\n## RAW CONFIRMATION SHAPE\nHTTP 200 + total; the materialise script prints `capability_index: <n> rows from <sources>`.\n\n## RAW RETURN SHAPE\nThe rows; the matrix; /tools HTML.\n\n## ERROR SHAPES\n- unknown_filter\n- index_stale (materialised > 24 h ago; the response says so and still answers)\n\n## RECEIPT / TRACE / PARENT LINKAGE\nMaterialise runs are proof_runs (cause=task or deploy); /api/discovery/matrix cites the receipt of the last materialise.\n\n## TEST MATRIX\n| case | what runs | kind |\n|---|---|---|\n| count | total ≥ 10,000 records across sources | live |\n| axes | every record has all seven axes non-empty | live (gate) |\n| hot | rank=hot count = 74 + rank-0 rows | live |\n| search | \"send message\" returns TEXT_* and iMessage verbs first | live |\n| state | proven records cite a receipt that exists | live (sampled 50) |\n| tools page | /tools renders from the index | live |\n| sheet ontology | column B of 20 sampled rows equals the compiled axes string | live |\n\n## ACCEPTANCE TESTS (mechanical; the infrastructure runs them)\n- `{\"type\": \"evidence_present\", \"id\": \"commit\", \"field\": \"commit\"}`\n- `{\"type\": \"evidence_present\", \"id\": \"live\", \"field\": \"verification\"}`\n- `{\"type\": \"http_ok\", \"id\": \"disc\", \"url\": \"https://ops.miscsubjects.com/api/discovery?limit=1\"}`\n- `{\"type\": \"contains\", \"id\": \"matrix\", \"url\": \"https://ops.miscsubjects.com/api/discovery/matrix\", \"needle\": \"proven\"}`\nEvidence fields the submitting agent supplies: commit, verification. `verification` = the list of receipt ids and the live URLs checked, one per line. `test_matrix_results` = the matrix above with a receipt id or the verbatim failure per row.\n\n## KNOWN FAILURES / REGRESSION FIXTURES (preserve; never rewrite into success)\n- flat ontology string (the CONTRACTS ONTOLOGY column must be compiled from axes, never typed)\n- `--help` rows must be state=discovered, never proven\n- Bearer anonymous on /api/tools\n\n## DEPENDENCIES\n- depends_on: WT-0470\n- OWNS (only this task rewrites): functions/api/discovery/* (new); scripts/materialise-capability-index.mjs (new) + gate scripts/check-capability-axes.mjs (new); public/tools; functions/api/capability-atlas.js, capability-census.js, inventory.js\n- SHARED (additive edits only): functions/api/surface search (WT-0474; redirect to discovery additively); scripts/contracts-project.mjs (WT-0473; it reads the compiled ontology string from here)\n\n## HANDOFF FOR NEXT SESSION\n- Sources are read from their canonical tables; never re-scrape documentation into the index.\n- Rank data from events uses R2 summaries, not D1 COUNT.\n- Evidence: the matrix JSON + the gate output.\n\n## DONE LAW (this task is done when every line is true and evidenced; not before)\n- capability_index materialised from every source; the axes gate passes.\n- /api/discovery + matrix live; /tools reads from it.\n- The six-column ONTOLOGY is compiled from axes.\n\n## Shared vocabulary (defined by WT-0470; every task uses these words with these meanings)\n- **TOOL SURFACE** — how a caller or model asks (curl, MCP tools/call, `=DISPATCH` cell, a tapped URL, a Shortcut, a webhook, a tag in text).\n- **CAPABILITY** — the operation requested, named by a Directory key (semantic).\n- **OBJECT** — what it acts on (a chat, a file, a profile, a row, a page).\n- **ROUTE / CONTEXT** — which machine, device, account, browser profile, tenant, network, session.\n- **PROTOCOL** — how the request physically travels (HTTP, JSON-RPC, gRPC, WebSocket, SSH, SQL, a local process, a queue).\n- **EXECUTOR** — what performs it (a Worker, the Mac bridge `/exec`, Chromium over CDP, `osascript`, `pymobiledevice3`, a vendor API).\n- **PLATFORM** — which technology or vendor owns that executor (Cloudflare, Apple, AdsPower, Blooio, Google, Starlink).\n- **RAW CONTRACT** — the exact physical invocation sent, fully resolved.\n- **CONFIRMATION** — the executor's immediate acknowledgement (HTTP status + headers, spawn/exit metadata, JSON-RPC ack, WebSocket ack, queue receipt).\n- **RETURN** — the final result, verbatim, including failure payloads.\n- **RECEIPT** — evidence and provenance: receipt id/URL, trace id, execution id, timestamps, parent linkage.\n\n## Definition of proof (PROOF_LAW, governing invariant; read it: GET https://ops.miscsubjects.com/api/work → governing_invariants)\nA capability is proven only when the DECLARED invocation surface itself ran and the five fields exist for that run: CAUSE (why it ran: user request / task / parent invocation / event / webhook / model call), RAW INVOCATION (the fully resolved physical contract actually sent), RAW CONFIRMATION (the executor's acknowledgement), RAW RETURN (the actual output, failures verbatim), PROOF / RECEIPT (receipt id/URL, trace, execution id, timestamps, parent linkage sufficient to inspect or replay).\nAn HTTP 200 proves an HTTP 200. A webhook acknowledgement proves receipt. Hidden bash proves bash. A sibling implementation, documentation, a model doing it elsewhere, or the dispatcher working while the surface under test never ran prove nothing about that surface. A missing field is a missing implementation requirement, never something to invent. Existing failures stay as evidence and become regression fixtures; they are never rewritten into success.\n\n## Six-column projection (unchanged; not the source of truth)\n`TOOL NAME | ONTOLOGY | RAW INVOCATION | RAW CONFIRMATION | RAW RETURN | PROOF / RECEIPT` — the build workbook sheet `sh_nyab2cgy` (vault `CONTRACTS_WORKBOOK_SHEET`, 11,035 rows on 2026-09-23). No seventh column, no contract-type column, no prose in place of an executable invocation. Extra metadata belongs in the canonical capability / task / receipt objects.\n\n## Parallelism law\nOther tasks run at the same time in other sessions. Own only the files and objects named under OWNS; touch a shared file only as named under SHARED (additive, never a rewrite). If this task finds the global law insufficient, it files an amendment: `POST /api/work/task/<this id>/fail` naming failure_class `law_insufficient`, layer `WT-0470`, and the missing invariant — it never creates a second standard. Ask the build, never the owner: keys are in `~/.build-vault.env` (`grep '^NAME=' ~/.build-vault.env`; `CLOUDFLARE_API_TOKEN=$CF_API_TOKEN` is a shell reference, resolve `$NAME`). The owner key travels as header `x-terminal-key`. Deploy only with `node scripts/land.mjs \"<WT id> what changed\"` from `~/miscsubjects-pages`. Submit evidence: `POST https://ops.miscsubjects.com/api/work/task/<id>/submit {agent, evidence:{commit, verification, …}, changed:[…]}` with header `x-terminal-key`.\n\n## Shared canonical objects and files — never independently rewritten (additive edits only, named per task)\n- `functions/api/dispatch.js` (the one door; runHttp/runFn/tenant delegation) — owner WT-0471.\n- `functions/_lib/invocation_methods.js`, `functions/_lib/grammar.js`, `functions/_lib/projection_manifest.js`, `functions/api/tools/[[path]].js`, `functions/api/mcp.js`, `functions/_lib/mcp_inspect.js` — owner WT-0472 (spellings and model projections).\n- `functions/_lib/event_log.js`, `functions/_lib/wire_log.js`, `functions/_lib/lean_receipt.js`, `functions/_lib/invocation_record.js`, the `events` table and R2 `logs/` — owner WT-0485 (ledger).\n- `functions/_lib/admin_session.js` (tokens, capabilities, tenants), `functions/_lib/tenant_devices.js`, `functions/api/onboard/[[path]].js` — owner WT-0487 (authority) / WT-0488 (onboarding).\n- `functions/_lib/mac_bridge.js`, `bridge/server.js`, `bridge/device_auth.js`, `bridge/surface-run.py`, `bridge/surface-verbs.py`, `bridge/bridge-run.py`, `bridge/bridge-browser.mjs`, `public/device-kit/*` (synced copies) — owners WT-0474 / WT-0475 / WT-0478.\n- `functions/_lib/work_object.js`, `functions/api/work/[[path]].js`, the `laws` and `work_tasks` tables — owner WT-0470 (law rows) and the build (task engine).\n- `scripts/contracts-*.mjs`, `apps-script/Contracts.gs`, the `CONTRACTS_RUN` directory row, sheet `sh_nyab2cgy` — owner WT-0473.\n- `scripts/ship.mjs`, `scripts/land.mjs`, `scripts/write.mjs`, `scripts/check-*.mjs`, `.githooks/*` — governed; add a gate only by adding a new `scripts/check-<name>.mjs` and wiring it as the existing gates are wired.\n",
    "state": "open",
    "priority": 3,
    "revision": 1,
    "depends_on": [
      "WT-0470"
    ],
    "permitted_capabilities": [
      "dispatch",
      "d1",
      "bridge",
      "sheets",
      "receipts"
    ],
    "acceptance_tests": [
      {
        "type": "evidence_present",
        "id": "commit",
        "field": "commit"
      },
      {
        "type": "evidence_present",
        "id": "live",
        "field": "verification"
      },
      {
        "type": "http_ok",
        "id": "disc",
        "url": "https://ops.miscsubjects.com/api/discovery?limit=1"
      },
      {
        "type": "contains",
        "id": "matrix",
        "url": "https://ops.miscsubjects.com/api/discovery/matrix",
        "needle": "proven"
      }
    ],
    "required_evidence": [
      "commit",
      "verification"
    ],
    "parent_task": null,
    "supersedes": null,
    "failure": null,
    "failure_count": 0,
    "last_result": null,
    "completed_at": null,
    "created_at": "2026-09-22T19:51:52-07:00",
    "updated_at": "2026-09-22T19:51:52-07:00",
    "audit": "/api/work/task/WT-0486/audit",
    "submit_to": "/api/work/task/WT-0486/submit"
  }
}