{
  "_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-0476",
    "kind": "work",
    "objective": "WT-0476 Website → API compiler — record a browser session, compile it to a replayable BRIDGE_* capability",
    "detail": "# WT-0476 — Website → API compiler — record a browser session, compile it to a replayable BRIDGE_* capability\n\n## GOAL\nAny website the owner (or a tenant) can use in a browser becomes a Directory capability: record the network/DOM actions of a session, compile the minimal HTTP contract (endpoints, auth headers/cookies, CSRF, pagination), store it as a BRIDGE_<SITE>_<VERB> row with a full contract, replay it through the resolver with the five fields, and re-record when it drifts.\n\n## WHY THIS EXISTS\nThe BRIDGE product (project memory 2026-09-22) promised record → compile → replay; today /api/bridges has the controllers and BRIDGE_REGISTER/BRIDGE_ACT rows but no compiled contract for any real site, and no drift detection. Delegated friend accounts and rented ad accounts depend on this.\n\n## CURRENT STATE (measured 2026-09-23)\n- functions/api/bridges/* — browser/adspower/surface/phone controllers; BRIDGE_REGISTER (register a site), BRIDGE_ACT (act through a controller); bridges_openapi.json (in /tmp/claude-501/contracts) is the 2026-09-23 discovery.\n- Session storage: cookies/tokens have no home except the capabilities table (LEDGER) and the vault.\n- No compiled site exists.\n\n## SOURCE OF TRUTH\n- functions/api/bridges/[[path]].js\n- bridge/bridge-browser.mjs (network capture → HAR)\n- the `directory` table BRIDGE_* rows\n- WT-0477 for where sessions live\n\n## IN-SCOPE INVENTORY\n- Recorder: `POST /api/bridges/record/start {site, profile}` → browser session with HAR + DOM event capture; `…/stop` → recording id (R2).\n- Compiler: `POST /api/bridges/compile {recording_id}` → candidate contracts (per distinct endpoint: method, url template, required headers, cookie names, body schema inferred with FIELD LAW markers `inferred`), stored in capability_contracts with state=discovered and a BRIDGE_<SITE>_<VERB> directory row per verb.\n- Replayer: the resolver executor `bridge_http` that injects the session (WT-0477 handle) and runs the compiled request; return verbatim; drift detector compares the response schema to the recording and marks state back to discovered on mismatch.\n- Three reference sites compiled and proven: (1) the build itself (miscsubjects.com/console sign-in page → an API); (2) AdsPower Local API (documented; compile from docs + one recording); (3) one public site with login the owner already holds in the vault (pick from CREDS index; read-only verbs only).\n\n## OUT OF SCOPE\n- Storing credentials (WT-0477). The browser executors themselves (WT-0475). Any write/send verb on a third-party site without the owner's explicit row naming it.\n\n## ONTOLOGY (separate axes; never a flat string)\n- TOOL SURFACE: POST /api/bridges/{record,compile,replay}; dispatch BRIDGE_* rows; MCP BRIDGE_ACT\n- CAPABILITY: BRIDGE_<SITE>_<VERB>\n- OBJECT: a site endpoint + a session\n- ROUTE / CONTEXT: profile/proxy/tenant\n- PROTOCOL: HTTP(S) replay; CDP for recording\n- EXECUTOR: bridge_http in the Worker (or through the Mac when the site is LAN-only)\n- PLATFORM: the target site; Chromium for recording\n\n## DISCOVERY (run these first; they answer, they do not prove)\n- `curl -sS \"https://ops.miscsubjects.com/api/bridges/openapi.json\" -H \"x-terminal-key: $TERMINAL_KEY\"`\n- `curl -sS \"https://ops.miscsubjects.com/api/directory?prefix=BRIDGE_\" -H \"x-terminal-key: $TERMINAL_KEY\"`\n\n## CONTRACT (FIELD LAW)\n- record/start `{site (required, origin), profile (optional), max_minutes (default 10)}` → `{recording_id, ws_or_pane}`; stop `{recording_id}` → `{har_url, events_url, requests:<n>}`.\n- compile `{recording_id, include (optional regex on url), exclude (optional)}` → `{contracts:[{key, method, url_template, headers:{name:required|optional|session}, cookies:[…], body_schema, fields:[FIELD LAW], ack_shape, return_shape, error_shapes}], rows_created:[…]}`.\n- replay = dispatch of the BRIDGE_* key with args matching body_schema; `session` resolved from WT-0477 by handle; conflicts: a session handle of another tenant → authority_denied.\n\n## MINIMUM VALID INVOCATION\n`curl -sS -X POST https://ops.miscsubjects.com/api/bridges/record/start -H \"x-terminal-key: $TERMINAL_KEY\" -H \"content-type: application/json\" -d '{\"site\":\"https://miscsubjects.com\"}'`\n\n## FULL / MAXIMUM INVOCATION\n`curl -sS -X POST https://ops.miscsubjects.com/api/bridges/compile -H \"x-terminal-key: $TERMINAL_KEY\" -H \"content-type: application/json\" -d '{\"recording_id\":\"rec_…\",\"include\":\"^https://miscsubjects.com/api/\",\"exclude\":\"\\\\.(png|css|js)$\",\"cause\":\"task:WT-0476\"}'`\n\n## RAW CONFIRMATION SHAPE\nHTTP 200 + recording id / contracts count; replay ack = the site's HTTP status + headers.\n\n## RAW RETURN SHAPE\nCompiled contract JSON; replay return verbatim (site payload).\n\n## ERROR SHAPES\n- recording_empty (no requests matched include)\n- session_required (compiled contract needs a session handle)\n- drift_detected (schema mismatch; state → discovered)\n- authority_denied\n- site 4xx/5xx verbatim\n\n## RECEIPT / TRACE / PARENT LINKAGE\nrecording and compile receipts; each replay a proof_run with parent_receipt_id = compile receipt.\n\n## TEST MATRIX\n| case | what runs | kind |\n|---|---|---|\n| record build | 10 requests on miscsubjects.com | live |\n| compile build | ≥ 3 BRIDGE_MISCSUBJECTS_* rows with FIELD LAW | live |\n| replay | one compiled read verb → same shape as recording | live |\n| adspower compile | ADSPOWER profiles/start/stop as BRIDGE_ADSPOWER_* | live |\n| drift | alter the fixture response → drift_detected | fixture |\n| third site | one read verb on a vault-held site | 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\": \"evidence_present\", \"id\": \"matrix\", \"field\": \"test_matrix_results\"}`\n- `{\"type\": \"sql_count_at_least\", \"id\": \"rows\", \"sql\": \"SELECT COUNT(*) AS n FROM directory WHERE key LIKE 'BRIDGE\\\\_%' ESCAPE '\\\\'\", \"min\": 3}`\nEvidence fields the submitting agent supplies: commit, test_matrix_results, 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- stale webhook hosts (compiled contracts pointing at retired hosts must drift, not 5xx silently)\n- CSRF token rotation (record twice; compile must mark the token field `session`)\n- SQLite LIKE underscore (escape `_` in BRIDGE_ queries)\n\n## DEPENDENCIES\n- depends_on: WT-0470, WT-0471, WT-0475, WT-0477\n- OWNS (only this task rewrites): functions/api/bridges/record*, compile*, replay*; functions/_lib/bridge_compile.js (new); BRIDGE_* directory rows\n- SHARED (additive edits only): functions/api/bridges/[[path]].js (additive routes); capability_contracts (WT-0470 schema; write rows, never alter columns)\n\n## HANDOFF FOR NEXT SESSION\n- Read-only verbs only on third-party sites; a write verb needs an owner-named row.\n- Store sessions only through WT-0477's handle API; never in the row.\n- Evidence: the three compiled sites with receipts.\n\n## DONE LAW (this task is done when every line is true and evidenced; not before)\n- record → compile → replay proven on three sites with receipts.\n- Drift detection is a fixture that passes.\n- Every BRIDGE_* row has a capability_contracts row with FIELD LAW.\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",
      "WT-0471",
      "WT-0475",
      "WT-0477"
    ],
    "permitted_capabilities": [
      "dispatch",
      "d1",
      "bridge",
      "sheets",
      "receipts"
    ],
    "acceptance_tests": [
      {
        "type": "evidence_present",
        "id": "commit",
        "field": "commit"
      },
      {
        "type": "evidence_present",
        "id": "live",
        "field": "verification"
      },
      {
        "type": "evidence_present",
        "id": "matrix",
        "field": "test_matrix_results"
      },
      {
        "type": "sql_count_at_least",
        "id": "rows",
        "sql": "SELECT COUNT(*) AS n FROM directory WHERE key LIKE 'BRIDGE\\_%' ESCAPE '\\'",
        "min": 3
      }
    ],
    "required_evidence": [
      "commit",
      "test_matrix_results",
      "verification"
    ],
    "parent_task": null,
    "supersedes": null,
    "failure": null,
    "failure_count": 0,
    "last_result": null,
    "completed_at": null,
    "created_at": "2026-09-22T19:52:05-07:00",
    "updated_at": "2026-09-22T19:52:05-07:00",
    "audit": "/api/work/task/WT-0476/audit",
    "submit_to": "/api/work/task/WT-0476/submit"
  }
}