{
  "_self": {
    "schema": "miscsubjects/work-audit/1",
    "append_only": true,
    "chain": "each row hashes prev_hash + its payload"
  },
  "verification": {
    "valid": false,
    "rows_checked": 1247,
    "rows_verified": 1240,
    "head_hash": "ec86e81d47b5ef471db7930d3d1101ae99ead8b425df28026cc858a8b4da2a3c",
    "first_break": {
      "action_id": 420,
      "task_id": "WT-0130",
      "action": "lease",
      "reason": "prev_hash_does_not_match_previous_row",
      "stored_hash": "faaa91d3d5a83bb211057b13e96d092ecc66006d4c0e83bf25d4e410466e8641",
      "recomputed_hash": "faaa91d3d5a83bb211057b13e96d092ecc66006d4c0e83bf25d4e410466e8641"
    },
    "how": "sha256(prev_hash + \"|\" + JSON.stringify(payload)) over the same field order appendAction() writes, in id order"
  },
  "head_hash": "ec86e81d47b5ef471db7930d3d1101ae99ead8b425df28026cc858a8b4da2a3c",
  "total_actions": 1247,
  "count": 200,
  "actions": [
    {
      "id": 1247,
      "ts": "2026-09-22T23:19:55-07:00",
      "task_id": "WF-0020",
      "action": "create",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"failure\":{\"failure_class\":\"engine_challenge_reported_as_no_results\",\"layer\":\"bridge/bridge-run.py net() search (engines ddg, mojeek) — no rate limiting, no challenge detection, no engine rotation\",\"missing_invariant\":\"A search tool that runs on one residential line must (1) rate-limit itself below the engines’ thresholds, (2) recognise an engine’s challenge/anomaly page (DuckDuckGo html answers HTTP 202 with an anomaly page after ~70 searches in 25 minutes) and answer engine_blocked with retry_after and the engine name, never no_results, (3) rotate to another engine (mojeek, brave with a key, exa opt-in, or a self-hosted SearXNG on the Mac) and record which engine answered in the receipt.\",\"evidence\":\"2026-09-23 05:5x: the same query returned 5 results from ddg; 06:00-06:20 after 24-cell bursts every search through every surface answered ERR:http:502 / no_results; 06:22 direct check from the Mac: html.duckduckgo.com → HTTP 202, page contains anomaly ×67; mojeek empty; exa opt-in still answers. Google sheet 1cUE88DdjzeLMmBKnlF0lI0KOEWxVFLYuSMp1M2AhtoY tab UNIVERSAL DISPATCH, rows STARLINK · after the burst … and STARLINK · what DuckDuckGo answers this line right now.\",\"fix\":\"in bridge-run.py net(): detect challenge pages (status 202/403, anomaly/captcha markers) → error engine_blocked {engine, retry_after_s}; per-engine token bucket (e.g. 10/min ddg); engine rotation order ddg → mojeek → brave (BRAVE_API_KEY in the vault) → exa (opt-in only); optional local SearXNG; surface engines_used and blocked engines in every answer; a fixture test that replays the saved anomaly page\"},\"parent\":\"WT-0478\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2604f2aaa76f2650b0664bf850bebda89e9a6c32f8e1322f07c257eb1a4a3567",
      "hash": "ec86e81d47b5ef471db7930d3d1101ae99ead8b425df28026cc858a8b4da2a3c"
    },
    {
      "id": 1246,
      "ts": "2026-09-22T23:19:55-07:00",
      "task_id": "WT-0478",
      "action": "fail",
      "agent": "claude-fable-5.1 session 9adc6e91",
      "model": null,
      "capability": "owner-key",
      "task_revision": 1,
      "from_state": "open",
      "to_state": "repair_required",
      "input": "{\"failure\":{\"failure_class\":\"engine_challenge_reported_as_no_results\",\"layer\":\"bridge/bridge-run.py net() search (engines ddg, mojeek) — no rate limiting, no challenge detection, no engine rotation\",\"missing_invariant\":\"A search tool that runs on one residential line must (1) rate-limit itself below the engines’ thresholds, (2) recognise an engine’s challenge/anomaly page (DuckDuckGo html answers HTTP 202 with an anomaly page after ~70 searches in 25 minutes) and answer engine_blocked with retry_after and the engine name, never no_results, (3) rotate to another engine (mojeek, brave with a key, exa opt-in, or a self-hosted SearXNG on the Mac) and record which engine answered in the receipt.\",\"evidence\":\"2026-09-23 05:5x: the same query returned 5 results from ddg; 06:00-06:20 after 24-cell bursts every search through every surface answered ERR:http:502 / no_results; 06:22 direct check from the Mac: html.duckduckgo.com → HTTP 202, page contains anomaly ×67; mojeek empty; exa opt-in still answers. Google sheet 1cUE88DdjzeLMmBKnlF0lI0KOEWxVFLYuSMp1M2AhtoY tab UNIVERSAL DISPATCH, rows STARLINK · after the burst … and STARLINK · what DuckDuckGo answers this line right now.\",\"fix\":\"in bridge-run.py net(): detect challenge pages (status 202/403, anomaly/captcha markers) → error engine_blocked {engine, retry_after_s}; per-engine token bucket (e.g. 10/min ddg); engine rotation order ddg → mojeek → brave (BRAVE_API_KEY in the vault) → exa (opt-in only); optional local SearXNG; surface engines_used and blocked engines in every answer; a fixture test that replays the saved anomaly page\"}}",
      "output": "{\"child_task\":\"WF-0020\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "eb71b37b9171400cac44359416ee1e898a5c06b130a6b6ef935f92f0d2c8f40c",
      "hash": "2604f2aaa76f2650b0664bf850bebda89e9a6c32f8e1322f07c257eb1a4a3567"
    },
    {
      "id": 1245,
      "ts": "2026-09-22T22:58:23-07:00",
      "task_id": "WF-0019",
      "action": "create",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"failure\":{\"failure_class\":\"execution_identity_not_in_contract\",\"layer\":\"functions/_lib/execution_routing.js (execution_policy either) + the LOCAL_EXEC directory row (no pinned executor)\",\"missing_invariant\":\"CONTRACT_LAW: the executor is a separate axis of the contract; a capability whose meaning is the owner Mac must resolve to the owner Mac on every surface or fail, never substitute a cloud shell\",\"evidence\":\"UNIVERSAL DISPATCH grid 2026-09-23: LOCAL_EXEC through curl/named/jsonrpc/claude_code/console_app/line/tag/webhook/google_sheet_gas ran on the Mac (execution_substrate=mac_bridge, cmd=sh, argv, exit 0) while the workbook_cell surface of the SAME key fell back to cloudflare_sandbox and failed because /root/miscsubjects-pages does not exist there. Google sheet 1cUE88DdjzeLMmBKnlF0lI0KOEWxVFLYuSMp1M2AhtoY tab UNIVERSAL DISPATCH, rows LOCAL_EXEC · workbook_cell vs LOCAL_EXEC · curl.\",\"fix\":\"row-level executor pin (mac | cloud | either) honoured by every surface (WT-0471 resolver); LOCAL_EXEC, STARLINK_STATUS, ADSPOWER_STATUS, IMESSAGE_SEND, LOCAL_SCREENSHOT, CLI_* pinned to mac; a pinned row that cannot reach its executor answers route_unavailable with the raw error instead of running elsewhere\"},\"parent\":\"WT-0471\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "cf98ed79545e39446467e9fe394cd34684fc62acdb1922cecaa39b59ef526629",
      "hash": "eb71b37b9171400cac44359416ee1e898a5c06b130a6b6ef935f92f0d2c8f40c"
    },
    {
      "id": 1244,
      "ts": "2026-09-22T22:58:22-07:00",
      "task_id": "WT-0471",
      "action": "fail",
      "agent": "claude-fable-5.1 session 9adc6e91",
      "model": null,
      "capability": "owner-key",
      "task_revision": 1,
      "from_state": "open",
      "to_state": "repair_required",
      "input": "{\"failure\":{\"failure_class\":\"execution_identity_not_in_contract\",\"layer\":\"functions/_lib/execution_routing.js (execution_policy either) + the LOCAL_EXEC directory row (no pinned executor)\",\"missing_invariant\":\"CONTRACT_LAW: the executor is a separate axis of the contract; a capability whose meaning is the owner Mac must resolve to the owner Mac on every surface or fail, never substitute a cloud shell\",\"evidence\":\"UNIVERSAL DISPATCH grid 2026-09-23: LOCAL_EXEC through curl/named/jsonrpc/claude_code/console_app/line/tag/webhook/google_sheet_gas ran on the Mac (execution_substrate=mac_bridge, cmd=sh, argv, exit 0) while the workbook_cell surface of the SAME key fell back to cloudflare_sandbox and failed because /root/miscsubjects-pages does not exist there. Google sheet 1cUE88DdjzeLMmBKnlF0lI0KOEWxVFLYuSMp1M2AhtoY tab UNIVERSAL DISPATCH, rows LOCAL_EXEC · workbook_cell vs LOCAL_EXEC · curl.\",\"fix\":\"row-level executor pin (mac | cloud | either) honoured by every surface (WT-0471 resolver); LOCAL_EXEC, STARLINK_STATUS, ADSPOWER_STATUS, IMESSAGE_SEND, LOCAL_SCREENSHOT, CLI_* pinned to mac; a pinned row that cannot reach its executor answers route_unavailable with the raw error instead of running elsewhere\"}}",
      "output": "{\"child_task\":\"WF-0019\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "6bf4e64e0ba3873d40400564693a8c7188409b2f52ce280666a25c696fd57b39",
      "hash": "cf98ed79545e39446467e9fe394cd34684fc62acdb1922cecaa39b59ef526629"
    },
    {
      "id": 1243,
      "ts": "2026-09-22T22:33:13-07:00",
      "task_id": "WT-0491",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0491\",\"kind\":\"work\",\"objective\":\"WT-0491 Final conformance demo — every surface family runs itself, the matrix is complete, no claim without a receipt (supersedes WT-0489: no article)\",\"detail\":\"# WT-0491 — Final conformance demo — every surface family runs itself, the matrix is complete, no claim without a receipt (supersedes WT-0489: no article deliverable, owner order 2026-09-23)\\n\\n## GOAL\\nRun the whole suite from the owner's vantage: for every surface family A–T one receipted proof through its own surface, the discovery matrix with zero unexplained gaps, all regression fixtures green as deploy gates, the six-column sheet regenerated from canonical, one plain-English article that shows the build (no marketing register) with the receipts, and a text to the owner naming the page. This task cannot be submitted while any dependency is open.\\n\\n## WHY THIS EXISTS\\nThe owner refused another claim that everything is done. This task is the only place \\\"done\\\" is said, and it is said by the acceptance tests, not by a session.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Nothing of this task exists until WT-0470–0488 submit. The 2026-09-23 sheet (11,035 rows) and article set are the baseline it must exceed.\\n\\n## SOURCE OF TRUTH\\n- every task in this set and its evidence\\n- /api/discovery/matrix (WT-0486)\\n- the gate outputs in the land log\\n- the six-column sheet sh_nyab2cgy\\n\\n## IN-SCOPE INVENTORY\\n- Conformance runner scripts/conformance-run.mjs: for each family A–T, the named proof (from the coverage matrix in the task index document) executed through its declared surface, one receipt each, written to a `conformance` sheet view (six columns; the family name is the TOOL NAME prefix, never a seventh column).\\n- Gate check: every scripts/check-*.mjs added by this set runs in land.mjs and passes; the land log is evidence.\\n- Sheet regeneration: contracts-project.mjs from canonical; diff report.\\n- No article (owner order 2026-09-23). The proof artifact is the Google Sheet tab the owner named (UNIVERSAL DISPATCH in sheet 1cUE88DdjzeLMmBKnlF0lI0KOEWxVFLYuSMp1M2AhtoY) regenerated from canonical, six columns, one row per capability × surface execution, plus the counts in the reply.\\n- Delivery: text the owner from HIS OWN handle (redacted or +17079135888, never a rented line) with the sheet URL; open nothing on his screen unless he asks.\\n\\n## OUT OF SCOPE\\n- New capabilities. Fixing a plane (file a failure task on that plane instead).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: all\\n- CAPABILITY: all families\\n- OBJECT: the build\\n- ROUTE / CONTEXT: all\\n- PROTOCOL: all\\n- EXECUTOR: all\\n- PLATFORM: all\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/work?state=all\\\" | python3 -c \\\"import json,sys; [print(t['task_id'], t['state']) for t in json.load(sys.stdin)['tasks'] if 'WT-047' in t['task_id'] or 'WT-048' in t['task_id']]\\\"`\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/discovery/matrix\\\"`\\n\\n## CONTRACT (FIELD LAW)\\n- `node scripts/conformance-run.mjs --families A-T --write build:<conformance sheet> --cause task:WT-0489` → exit 0 only when every family has surface_ran=true; exit 1 lists the families without.\\n\\n## MINIMUM VALID INVOCATION\\n`node scripts/conformance-run.mjs --families A`\\n\\n## FULL / MAXIMUM INVOCATION\\n`node scripts/conformance-run.mjs --families A-T --write build:sh_conformance --cause task:WT-0489 --strict`\\n\\n## RAW CONFIRMATION SHAPE\\nPer family the surface's own confirmation; the runner's exit code.\\n\\n## RAW RETURN SHAPE\\nThe conformance sheet; the article; the matrix.\\n\\n## ERROR SHAPES\\n- family_unproven (lists the family and the failing receipt)\\n- gate_failed (land log)\\n- dependency_open (the task refuses to start)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nTwenty receipts (one per family) + the article receipt + the text message id.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| family A | one proof through its own surface | live |\\n| family B | one proof through its own surface | live |\\n| family C | one proof through its own surface | live |\\n| family D | one proof through its own surface | live |\\n| family E | one proof through its own surface | live |\\n| family F | one proof through its own surface | live |\\n| family G | one proof through its own surface | live |\\n| family H | one proof through its own surface | live |\\n| family I | one proof through its own surface | live |\\n| family J | one proof through its own surface | live |\\n| family K | one proof through its own surface | live |\\n| family L | one proof through its own surface | live |\\n| family M | one proof through its own surface | live |\\n| family N | one proof through its own surface | live |\\n| family O | one proof through its own surface | live |\\n| family P | one proof through its own surface | live |\\n| family Q | one proof through its own surface | live |\\n| family R | one proof through its own surface | live |\\n| family S | one proof through its own surface | live |\\n| family T | one proof through its own surface | 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\\\": \\\"receipts\\\", \\\"field\\\": \\\"family_receipts\\\"}`\\n- `{\\\"type\\\": \\\"http_ok\\\", \\\"id\\\": \\\"article\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/universal-dispatch-proof\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"article_words\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/universal-dispatch-proof\\\", \\\"needle\\\": \\\"RAW CONFIRMATION\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"matrix\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/discovery/matrix\\\", \\\"needle\\\": \\\"proven\\\"}`\\nEvidence fields the submitting agent supplies: commit, family_receipts, 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- every fixture named in WT-0470–0488 (the gates)\\n- a claim without a receipt (the runner refuses to write \\\"proven\\\" without surface_ran=true)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0472, WT-0473, WT-0474, WT-0475, WT-0476, WT-0477, WT-0478, WT-0479, WT-0480, WT-0481, WT-0482, WT-0483, WT-0484, WT-0485, WT-0486, WT-0487, WT-0488\\n- OWNS (only this task rewrites): scripts/conformance-run.mjs (new); article universal-dispatch-proof; the conformance sheet view\\n- SHARED (additive edits only): nothing else; this task changes no plane\\n\\n## HANDOFF FOR NEXT SESSION\\n- If a family cannot run through its own surface, do not substitute: file a failure task on the owning plane and leave the family red in the sheet.\\n- Evidence field family_receipts: TSV `family\\\\treceipt_id\\\\tsurface\\\\tsurface_ran`.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- 20 families, 20 receipts, surface_ran=true for each.\\n- All gates green in the land log.\\n- Sheet regenerated; owner texted from his own handle.\\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\",\"priority\":4,\"depends_on\":[\"WT-0471\",\"WT-0472\",\"WT-0473\",\"WT-0474\",\"WT-0475\",\"WT-0476\",\"WT-0477\",\"WT-0478\",\"WT-0479\",\"WT-0480\",\"WT-0481\",\"WT-0482\",\"WT-0483\",\"WT-0484\",\"WT-0485\",\"WT-0486\",\"WT-0487\",\"WT-0488\",\"WT-0490\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"receipts\",\"field\":\"family_receipts\"},{\"type\":\"contains\",\"id\":\"matrix\",\"url\":\"https://ops.miscsubjects.com/api/discovery/matrix\",\"needle\":\"proven\"}],\"evidence_required\":[\"commit\",\"family_receipts\",\"verification\"],\"supersedes\":\"WT-0489\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8b6bedf8a361bef3b51bfe790f6cb02249ef30fa315fd2944029b0026ef37591",
      "hash": "6bf4e64e0ba3873d40400564693a8c7188409b2f52ce280666a25c696fd57b39"
    },
    {
      "id": 1242,
      "ts": "2026-09-22T22:33:11-07:00",
      "task_id": "WT-0490",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0490\",\"kind\":\"work\",\"objective\":\"WT-0490 Global Contract Law and Proof Law — the one standard, enforced structurally (supersedes WT-0470: no article)\",\"detail\":\"# WT-0490 — Global Contract Law and Proof Law — the one standard, enforced structurally (supersedes WT-0470: no article deliverable, owner order 2026-09-23)\\n\\n## GOAL\\nMake the definition of DONE/PROVEN/LIVE/VERIFIED and the full-contract requirement structural: law rows, a schema that stores contracts and proof fields, a deploy gate that refuses a \\\"proven\\\" claim without the five fields, and a public page that states the law in plain words. Every other task in this set cites this task instead of restating the standard.\\n\\n## WHY THIS EXISTS\\nSessions kept calling capabilities done because a door answered 200, a webhook acknowledged, or a shell command the model ran itself worked. The owner ordered one standard, defined once, binding on every task and every surface, so that no session can call a transport success an operation success again.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Law rows PROOF_LAW and CONTRACT_LAW are live in table `laws` (inserted 2026-09-23, rows 127 and 128) and appear in `GET https://ops.miscsubjects.com/api/work` under governing_invariants. CONTRACTS_FORMAT_LAW (the six-column format) has been live since 2026-09-23 too.\\n- Nothing enforces them yet. No table stores a full executable contract per capability; the Directory row has `invocation`, `last_status`, `last_response`, `test_state` (functions/_lib/invocation_record.js) and `how_to_call` (12 spellings), which is a semantic call, not a physical contract.\\n- Deploy gates: 66 scripts named scripts/check-*.mjs run through scripts/gate-run.mjs on `node scripts/land.mjs`. None checks proof fields.\\n- The `capabilities` table in the LEDGER database (not the main DB) holds tokens with tenant_id, device_id, fingerprint, scope — that is authority, not contracts.\\n\\n## SOURCE OF TRUTH\\n- `laws` table in the main D1 database (columns id,key,level,category,rule,rationale,binding_on,can_be_modified_by,added_by,added_at,violations,last_violation_at,enabled). Read them: `GET https://ops.miscsubjects.com/api/work` → governing_invariants. Write them: `POST https://ops.miscsubjects.com/api/dispatch {\\\"key\\\":\\\"D1_EXEC\\\",\\\"body\\\":\\\"INSERT INTO laws (...) ...\\\"}` with header x-terminal-key.\\n- functions/_lib/work_object.js — RUNNABLE_TEST_TYPES, runOneTest, createTask, failTask (child failure tasks).\\n- scripts/gate-run.mjs and scripts/check-*.mjs — how a gate is wired.\\n\\n## IN-SCOPE INVENTORY\\n- Law rows: PROOF_LAW, CONTRACT_LAW, CONTRACTS_FORMAT_LAW (exist); add nothing else unless a task files `law_insufficient`.\\n- New table `capability_contracts` (main DB): key, surface, protocol, executor, platform, min_invocation (JSON), max_invocation (JSON), fields (JSON array of {name,required|optional|conditional,type,enum,default,nullable,cardinality,min,max,format,depends_on,conflicts_with,one_of,omitted_means}), ack_shape (JSON), return_shape (JSON), error_shapes (JSON array), discovered_from, state ∈ {discovered, executable, proven}, proven_receipt, updated_at.\\n- New table `proof_runs` (LEDGER DB, or columns on `events`): cause, raw_invocation, raw_confirmation, raw_return, receipt_id, trace_id, parent_receipt_id, surface, started_at, finished_at — written by WT-0485; the schema is defined here so every plane writes the same shape.\\n- Deploy gate scripts/check-proof-law.mjs: refuses a work-task submit or a directory row `test_state=proven` whose latest proof_run lacks any of the five fields or whose `surface` differs from the declared surface.\\n- No public page: the law is read from GET https://ops.miscsubjects.com/api/work → governing_invariants (owner order 2026-09-23: no articles unless he asks).\\n\\n## OUT OF SCOPE\\n- Running any capability. Building the resolver (WT-0471). Writing the ledger writer (WT-0485). Changing the six-column sheet (WT-0473).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: the law itself is surface-neutral; the gate runs in scripts/land.mjs\\n- CAPABILITY: LAW_READ, LAW_WRITE (D1_EXEC on `laws`), GATE_PROOF\\n- OBJECT: rows of `laws`, `capability_contracts`, `proof_runs`; work-task evidence\\n- ROUTE / CONTEXT: main D1 (site plane) and LEDGER D1 (machine plane); the deploy machine\\n- PROTOCOL: SQL over the dispatch door; Node process for the gate\\n- EXECUTOR: Pages Functions Worker; node on the deploying Mac\\n- PLATFORM: Cloudflare D1 / Pages; the build\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS https://ops.miscsubjects.com/api/work | python3 -c \\\"import json,sys; [print(l['key'], '·', l['rule'][:120]) for l in json.load(sys.stdin)['governing_invariants']]\\\"`\\n- `node -e \\\"import('./scripts/gate-run.mjs')\\\"` is not how gates run; read scripts/land.mjs to see the phase order, then scripts/check-work-acceptance.mjs as the model for a gate that reads work tasks.\\n\\n## CONTRACT (FIELD LAW)\\n- Contract of a law row: key (required, unique, UPPER_SNAKE), level ∈ {constitutional, mutable} (required), category (required, lower-kebab), rule (required, plain prose, ≤ 4,000 chars), rationale (required), binding_on (JSON array; `[\\\"all\\\"]`), added_by (required: agent + session), added_at (ISO with offset), enabled (0/1, default 1). Omitting enabled means enabled. Conflict on key updates rule and rationale only (ON CONFLICT(key) DO UPDATE).\\n- Contract of a capability_contracts row: every field above; `fields` entries are the FIELD LAW itself; `state` defaults to discovered; `proven_receipt` is required when state=proven (CHECK constraint).\\n- Contract of a proof_run: cause (required; one of user_request | task:<WT id> | parent:<receipt id> | event:<id> | webhook:<hook id> | model:<run id>), raw_invocation (required, ≤ 200,000 chars, written BEFORE execution), raw_confirmation (required after execution; may be `NONE (<reason>)`), raw_return (required; failures verbatim), receipt_id (required), trace_id (required), parent_receipt_id (nullable), surface (required; one of the WT-0472 spelling ids or a plane executor id), started_at/finished_at (ISO).\\n\\n## MINIMUM VALID INVOCATION\\nInsert a law: `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"D1_EXEC\\\",\\\"body\\\":\\\"INSERT INTO laws (key,level,category,rule,rationale,binding_on,added_by,added_at,enabled) VALUES (\\\\\\\"X_LAW\\\\\\\",\\\\\\\"mutable\\\\\\\",\\\\\\\"proof\\\\\\\",\\\\\\\"rule text\\\\\\\",\\\\\\\"why\\\\\\\",\\\\\\\"[\\\\\\\\\\\\\\\"all\\\\\\\\\\\\\\\"]\\\\\\\",\\\\\\\"agent\\\\\\\",\\\\\\\"2026-09-23T00:00:00-07:00\\\\\\\",1)\\\"}'` (the key is `grep '^TERMINAL_KEY=' ~/.build-vault.env`).\\n\\n## FULL / MAXIMUM INVOCATION\\nThe same call with can_be_modified_by, violations, last_violation_at set; plus the CHECK-constrained capability_contracts insert with all 17 columns; plus `node scripts/check-proof-law.mjs --task WT-0470 --strict` before landing.\\n\\n## RAW CONFIRMATION SHAPE\\nD1_EXEC returns `{\\\"ok\\\":true,\\\"result\\\":{\\\"changes\\\":1,\\\"last_row_id\\\":<n>}}` with HTTP 200; a refused governed table returns HTTP 403 `{\\\"ok\\\":false,\\\"error\\\":\\\"governed_table\\\",...}` (functions/_lib/governed_tables.js).\\n\\n## RAW RETURN SHAPE\\n`GET /api/work` → governing_invariants contains the row; `SELECT * FROM laws WHERE key=?` returns it; the gate prints `proof-law: <n> claims examined, <m> refused` and exits 0/1.\\n\\n## ERROR SHAPES\\n- `D1_ERROR: no such table` (schema not migrated; add migrations/0484_capability_contracts.sql and land it).\\n- `governed_table` 403 when writing work_tasks/articles/directory through D1_EXEC.\\n- `unknown_fields` 400 / `acceptance_test_not_executable` 422 from createTask.\\n- Gate exit 1 with the list of claims lacking fields (never suppress; fix the claim).\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nEvery D1_EXEC through the dispatch door writes an events row (source=dispatch, key=D1_EXEC) and a receipt at https://miscsubjects.com/receipt/<id>; cite the receipt id of the law insert and of the migration in evidence.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| law rows readable | GET /api/work governing_invariants has PROOF_LAW and CONTRACT_LAW | live |\\n| schema exists | SELECT COUNT(*) FROM capability_contracts returns 0 or more (no error) | migration |\\n| gate refuses | a fixture task with evidence.verification=\\\"HTTP 200\\\" and no raw_return is refused by check-proof-law.mjs | fixture |\\n| gate accepts | a fixture with all five fields and surface matching passes | fixture |\\n| amendment path | POST /api/work/task/WT-0470/fail with failure_class law_insufficient creates a child WF task | live |\\n\\n## ACCEPTANCE TESTS (mechanical; the infrastructure runs them)\\n- `{\\\"type\\\": \\\"sql_count_at_least\\\", \\\"id\\\": \\\"laws\\\", \\\"sql\\\": \\\"SELECT COUNT(*) AS n FROM laws WHERE enabled=1 AND key IN ('PROOF_LAW','CONTRACT_LAW')\\\", \\\"min\\\": 2}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"work_object\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/work\\\", \\\"needle\\\": \\\"PROOF_LAW\\\"}`\\n- `{\\\"type\\\": \\\"http_ok\\\", \\\"id\\\": \\\"page\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/proof-law\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"page_text\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/proof-law\\\", \\\"needle\\\": \\\"An HTTP 200 proves an HTTP 200\\\"}`\\n- `{\\\"type\\\": \\\"evidence_present\\\", \\\"id\\\": \\\"commit\\\", \\\"field\\\": \\\"commit\\\"}`\\n- `{\\\"type\\\": \\\"evidence_present\\\", \\\"id\\\": \\\"gate\\\", \\\"field\\\": \\\"gate_run\\\"}`\\n- `{\\\"type\\\": \\\"evidence_present\\\", \\\"id\\\": \\\"live\\\", \\\"field\\\": \\\"verification\\\"}`\\nEvidence fields the submitting agent supplies: commit, gate_run, 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- transport 2xx treated as success (the whole 2026-09 CONTRACTS run: 1,698 HTTP 2xx rows of 10,072 were counted as \\\"answered\\\", not as \\\"the operation succeeded\\\")\\n- `--help` exit 0 accepted as capability proof (cli_tools layer)\\n- a model running a command itself and reporting the surface as proven (every session before 2026-09-23)\\n\\n## DEPENDENCIES\\n- depends_on: none (parallel start)\\n- OWNS (only this task rewrites): migrations/0484_capability_contracts.sql (new); scripts/check-proof-law.mjs (new); article proof-law (new); rows PROOF_LAW / CONTRACT_LAW in `laws`\\n- SHARED (additive edits only): functions/_lib/work_object.js — additive only: export the proof_run shape as a constant other tasks import; do not change createTask or runOneTest semantics; scripts/land.mjs — wire the new gate the way the 66 existing gates are wired\\n\\n## HANDOFF FOR NEXT SESSION\\n- If the migration landed but the gate is not wired: `grep -n check-work-acceptance scripts/land.mjs` shows the wiring pattern.\\n- State in evidence: receipts of the two law inserts, the migration commit, the gate run output with the count of claims examined.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Both laws present in governing_invariants (mechanical).\\n- capability_contracts and proof_runs exist with CHECK constraints (mechanical).\\n- check-proof-law.mjs runs in land.mjs and refuses the fixture (evidence: gate_run output).\\n- Every subsequent task cites this id; no task carries its own definition of proof.\\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\",\"priority\":1,\"depends_on\":[],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"sql_count_at_least\",\"id\":\"laws\",\"sql\":\"SELECT COUNT(*) AS n FROM laws WHERE enabled=1 AND key IN ('PROOF_LAW','CONTRACT_LAW')\",\"min\":2},{\"type\":\"contains\",\"id\":\"work_object\",\"url\":\"https://ops.miscsubjects.com/api/work\",\"needle\":\"PROOF_LAW\"},{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"gate\",\"field\":\"gate_run\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"gate_run\",\"verification\"],\"supersedes\":\"WT-0470\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "daec7bcaa38abe1eefb84679bf99c1f73fe74bc4f193a39229c01b11371eb396",
      "hash": "8b6bedf8a361bef3b51bfe790f6cb02249ef30fa315fd2944029b0026ef37591"
    },
    {
      "id": 1241,
      "ts": "2026-09-22T19:52:08-07:00",
      "task_id": "WT-0489",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0489\",\"kind\":\"work\",\"objective\":\"WT-0489 Final conformance demo — every surface family runs itself, the matrix is complete, no claim without a receipt\",\"detail\":\"# WT-0489 — Final conformance demo — every surface family runs itself, the matrix is complete, no claim without a receipt\\n\\n## GOAL\\nRun the whole suite from the owner's vantage: for every surface family A–T one receipted proof through its own surface, the discovery matrix with zero unexplained gaps, all regression fixtures green as deploy gates, the six-column sheet regenerated from canonical, one plain-English article that shows the build (no marketing register) with the receipts, and a text to the owner naming the page. This task cannot be submitted while any dependency is open.\\n\\n## WHY THIS EXISTS\\nThe owner refused another claim that everything is done. This task is the only place \\\"done\\\" is said, and it is said by the acceptance tests, not by a session.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Nothing of this task exists until WT-0470–0488 submit. The 2026-09-23 sheet (11,035 rows) and article set are the baseline it must exceed.\\n\\n## SOURCE OF TRUTH\\n- every task in this set and its evidence\\n- /api/discovery/matrix (WT-0486)\\n- the gate outputs in the land log\\n- the six-column sheet sh_nyab2cgy\\n\\n## IN-SCOPE INVENTORY\\n- Conformance runner scripts/conformance-run.mjs: for each family A–T, the named proof (from the coverage matrix in the task index document) executed through its declared surface, one receipt each, written to a `conformance` sheet view (six columns; the family name is the TOOL NAME prefix, never a seventh column).\\n- Gate check: every scripts/check-*.mjs added by this set runs in land.mjs and passes; the land log is evidence.\\n- Sheet regeneration: contracts-project.mjs from canonical; diff report.\\n- Article /a/universal-dispatch-proof: the vocabulary, the matrix, one worked chain WHY → WHAT → ACK → RETURN → RECEIPT per family, receipts linked; owner voice law (the build shows itself; no prices; laws first).\\n- Delivery: text the owner from +14245134626 with the article URL; open nothing on his screen unless he asks.\\n\\n## OUT OF SCOPE\\n- New capabilities. Fixing a plane (file a failure task on that plane instead).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: all\\n- CAPABILITY: all families\\n- OBJECT: the build\\n- ROUTE / CONTEXT: all\\n- PROTOCOL: all\\n- EXECUTOR: all\\n- PLATFORM: all\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/work?state=all\\\" | python3 -c \\\"import json,sys; [print(t['task_id'], t['state']) for t in json.load(sys.stdin)['tasks'] if 'WT-047' in t['task_id'] or 'WT-048' in t['task_id']]\\\"`\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/discovery/matrix\\\"`\\n\\n## CONTRACT (FIELD LAW)\\n- `node scripts/conformance-run.mjs --families A-T --write build:<conformance sheet> --cause task:WT-0489` → exit 0 only when every family has surface_ran=true; exit 1 lists the families without.\\n\\n## MINIMUM VALID INVOCATION\\n`node scripts/conformance-run.mjs --families A`\\n\\n## FULL / MAXIMUM INVOCATION\\n`node scripts/conformance-run.mjs --families A-T --write build:sh_conformance --cause task:WT-0489 --strict`\\n\\n## RAW CONFIRMATION SHAPE\\nPer family the surface's own confirmation; the runner's exit code.\\n\\n## RAW RETURN SHAPE\\nThe conformance sheet; the article; the matrix.\\n\\n## ERROR SHAPES\\n- family_unproven (lists the family and the failing receipt)\\n- gate_failed (land log)\\n- dependency_open (the task refuses to start)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nTwenty receipts (one per family) + the article receipt + the text message id.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| family A | one proof through its own surface | live |\\n| family B | one proof through its own surface | live |\\n| family C | one proof through its own surface | live |\\n| family D | one proof through its own surface | live |\\n| family E | one proof through its own surface | live |\\n| family F | one proof through its own surface | live |\\n| family G | one proof through its own surface | live |\\n| family H | one proof through its own surface | live |\\n| family I | one proof through its own surface | live |\\n| family J | one proof through its own surface | live |\\n| family K | one proof through its own surface | live |\\n| family L | one proof through its own surface | live |\\n| family M | one proof through its own surface | live |\\n| family N | one proof through its own surface | live |\\n| family O | one proof through its own surface | live |\\n| family P | one proof through its own surface | live |\\n| family Q | one proof through its own surface | live |\\n| family R | one proof through its own surface | live |\\n| family S | one proof through its own surface | live |\\n| family T | one proof through its own surface | 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\\\": \\\"receipts\\\", \\\"field\\\": \\\"family_receipts\\\"}`\\n- `{\\\"type\\\": \\\"http_ok\\\", \\\"id\\\": \\\"article\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/universal-dispatch-proof\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"article_words\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/universal-dispatch-proof\\\", \\\"needle\\\": \\\"RAW CONFIRMATION\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"matrix\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/discovery/matrix\\\", \\\"needle\\\": \\\"proven\\\"}`\\nEvidence fields the submitting agent supplies: commit, family_receipts, 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- every fixture named in WT-0470–0488 (the gates)\\n- a claim without a receipt (the runner refuses to write \\\"proven\\\" without surface_ran=true)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0472, WT-0473, WT-0474, WT-0475, WT-0476, WT-0477, WT-0478, WT-0479, WT-0480, WT-0481, WT-0482, WT-0483, WT-0484, WT-0485, WT-0486, WT-0487, WT-0488\\n- OWNS (only this task rewrites): scripts/conformance-run.mjs (new); article universal-dispatch-proof; the conformance sheet view\\n- SHARED (additive edits only): nothing else; this task changes no plane\\n\\n## HANDOFF FOR NEXT SESSION\\n- If a family cannot run through its own surface, do not substitute: file a failure task on the owning plane and leave the family red in the sheet.\\n- Evidence field family_receipts: TSV `family\\\\treceipt_id\\\\tsurface\\\\tsurface_ran`.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- 20 families, 20 receipts, surface_ran=true for each.\\n- All gates green in the land log.\\n- Article live; sheet regenerated; owner texted.\\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\",\"priority\":4,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0472\",\"WT-0473\",\"WT-0474\",\"WT-0475\",\"WT-0476\",\"WT-0477\",\"WT-0478\",\"WT-0479\",\"WT-0480\",\"WT-0481\",\"WT-0482\",\"WT-0483\",\"WT-0484\",\"WT-0485\",\"WT-0486\",\"WT-0487\",\"WT-0488\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"receipts\",\"field\":\"family_receipts\"},{\"type\":\"http_ok\",\"id\":\"article\",\"url\":\"https://miscsubjects.com/a/universal-dispatch-proof\"},{\"type\":\"contains\",\"id\":\"article_words\",\"url\":\"https://miscsubjects.com/a/universal-dispatch-proof\",\"needle\":\"RAW CONFIRMATION\"},{\"type\":\"contains\",\"id\":\"matrix\",\"url\":\"https://ops.miscsubjects.com/api/discovery/matrix\",\"needle\":\"proven\"}],\"evidence_required\":[\"commit\",\"family_receipts\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "c92a814d22d33f8b9b56a7a495a1f49335ec01f492c4ee351385990a160471f9",
      "hash": "daec7bcaa38abe1eefb84679bf99c1f73fe74bc4f193a39229c01b11371eb396"
    },
    {
      "id": 1240,
      "ts": "2026-09-22T19:52:07-07:00",
      "task_id": "WT-0488",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0488\",\"kind\":\"work\",\"objective\":\"WT-0488 External onboarding and the portable connector — a stranger gets a key, a tenant Worker, a device kit, and every surface\",\"detail\":\"# WT-0488 — External onboarding and the portable connector — a stranger gets a key, a tenant Worker, a device kit, and every surface\\n\\n## GOAL\\nA new person (or a friend renting an account) onboards in one call: tenant + key + policy row + Workers for Platforms Worker at gate.miscsubjects.com/<tenant>/ + device kit for their Mac/iPhone + MCP config for their models + the six-column contract sheet view for their tenant; every step is a receipted contract; the kit is the portable connector (BRIDGE) that makes their own surfaces (Mac, phone, browser, lines) dispatchable under their own authority.\\n\\n## WHY THIS EXISTS\\nThe owner wants new people to get their own API key and make things happen with their own device under the protocol. /api/onboard exists (2026-09-22) and the demo tenant works through gate.miscsubjects.com, but the device kit, the MCP config, the per-tenant contract view and the rental flow are not proven from the stranger's vantage.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- POST /api/onboard (one call: tenant + key + Worker + device kit); invites, me, devices register/endpoint/health/retire; onboard_accounts, text_accounts, tenants policy row (createTenant allow_keys=TENANT_KEYS, allow_prefixes BRIDGE_); public/device-kit/*, scripts/device-kit-sync.mjs; functions/_lib/onboard_contract.js (TENANT_KEYS, guide at /api/onboard/guide); wfp_worker.js (uploadScript, provisionTenantWorker; KEY_SHA256 only in the tenant Worker); gate.miscsubjects.com/<tenant>/ (card, /mcp, /api/<door>).\\n- Vault ONBOARD_DEMO_KEY (demo tenant). Dispatch forwards tenant Bearer to tenant doors (NET, SURFACE, BRIDGE, TEXT, ONBOARD).\\n\\n## SOURCE OF TRUTH\\n- functions/api/onboard/[[path]].js, functions/onboard.js, functions/_lib/onboard_contract.js, functions/_lib/tenant_devices.js, functions/_lib/wfp_worker.js\\n- public/device-kit/*\\n- migrations/0483_onboard_devices.sql\\n- https://ops.miscsubjects.com/api/onboard/guide\\n\\n## IN-SCOPE INVENTORY\\n- Onboard contract with FIELD LAW: POST /api/onboard {invite (conditional: required unless owner key), name (required ≤ 80), email (optional, format), device (optional {kind: mac|iphone|linux, name}), wants (optional array of door keys ⊆ TENANT_KEYS)} → {tenant_id, key (once), gate_url, mcp_url, kit_url, sheet_view_url, receipts:[…]}.\\n- Device kit: install script + bridge subset + device_auth; registers a quick tunnel endpoint; health check; the kit must run on a second Mac account (or a CF container standing in for a stranger's machine) as the proof — never on the owner's primary session.\\n- MCP for tenants: gate.miscsubjects.com/<tenant>/mcp with the tenant key; tools/list scoped by policy; proven with a real MCP client (WT-0472 runner).\\n- Per-tenant contract view: a six-column sheet `sh_<tenant>` (projection of that tenant's proof_runs) reachable by their share link.\\n- Rental flow (with WT-0477): friend onboards → registers an AdsPower profile handle → delegates to the owner tenant → owner runs → friend reads receipts.\\n- Portable connector (BRIDGE product): the kit + the compiled site contracts (WT-0476) packaged as `~/miscsubjects-pages/public/download/bridge-kit-<version>.tgz` with a card at /bridge; multi-tenant; boundary = own surfaces only.\\n\\n## OUT OF SCOPE\\n- Authority decisions (WT-0487). Session storage (WT-0477). Site compilation (WT-0476).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/onboard; gate.miscsubjects.com/<tenant>/{card,mcp,api/<door>}; the kit CLI; MCP ONBOARD/DEVICE_REGISTER\\n- CAPABILITY: ONBOARD, DEVICE_REGISTER/ENDPOINT/HEALTH/RETIRE, INVITE_*\\n- OBJECT: a tenant, a device, a kit, a tenant Worker\\n- ROUTE / CONTEXT: the tenant's own device via its tunnel; the tenant Worker in the dispatch namespace\\n- PROTOCOL: HTTPS; tunnel; MCP\\n- EXECUTOR: Worker (onboard), WfP tenant Worker, the tenant's device bridge\\n- PLATFORM: Cloudflare Workers for Platforms; the tenant's Mac/iPhone\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS https://ops.miscsubjects.com/api/onboard/guide`\\n- `curl -sS \\\"https://gate.miscsubjects.com/<tenant id from vault ONBOARD_DEMO_KEY row>/\\\" -H \\\"Authorization: Bearer $ONBOARD_DEMO_KEY\\\"`\\n- `ls ~/miscsubjects-pages/public/device-kit`\\n\\n## CONTRACT (FIELD LAW)\\n- See inventory for POST /api/onboard; devices/register `{tenant (from token), kind (required enum), name (required), fingerprint (required), endpoint (optional URL; set later by devices/endpoint)}` → `{device_id, device_token (once), intent_secret (once)}`; health → `{up, last_seen, latency_ms}`; retire → `{retired_at}`.\\n- Errors: invite_invalid, name_required, kind_invalid, endpoint_unreachable (with the raw error), tenant_quota (namespace limits).\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/onboard -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"name\\\":\\\"WT-0488 test tenant\\\"}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/onboard -H \\\"content-type: application/json\\\" -d '{\\\"invite\\\":\\\"<code from POST /api/onboard/invites>\\\",\\\"name\\\":\\\"Friend One\\\",\\\"email\\\":\\\"friend@example.com\\\",\\\"device\\\":{\\\"kind\\\":\\\"mac\\\",\\\"name\\\":\\\"friend-mbp\\\"},\\\"wants\\\":[\\\"NET\\\",\\\"SURFACE\\\",\\\"BRIDGE\\\",\\\"TEXT\\\"],\\\"cause\\\":\\\"task:WT-0488\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\nHTTP 201 + tenant_id + receipts; gate card HTTP 200 with the tenant name; kit install exit 0; device health up.\\n\\n## RAW RETURN SHAPE\\nThe onboarding object; the tenant's tools/list; the kit log; the sheet view URL.\\n\\n## ERROR SHAPES\\n- invite_invalid\\n- tenant_quota\\n- endpoint_unreachable\\n- worker_upload_failed (Cloudflare error verbatim)\\n- authority_denied on a door outside `wants`\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nOne receipt per onboarding step; the tenant's receipts visible only through their share link.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| one call | onboard → tenant, key, Worker, kit url | live |\\n| gate card | gate.miscsubjects.com/<tenant>/ 200 | live |\\n| tenant mcp | real MCP client tools/list + one call with the tenant key | live |\\n| kit on a second machine | install on a second macOS user account or a CF container; register; health up; one LOCAL_EXEC through the tenant's own device | live |\\n| tenant sheet view | six columns, only that tenant's runs | live |\\n| rental flow | friend tenant delegates an AdsPower handle; owner runs BROWSER_SCREENSHOT through it; friend reads the receipt | live |\\n| boundary | tenant calling D1_EXEC → authority_denied | live |\\n| retire | device retired → health down; token dead | 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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"guide\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/onboard/guide\\\"}`\\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- tenant_unknown after onboarding (policy row must be created in the same call)\\n- workers.dev URL carrying the owner name (custom domain only)\\n- 522 self-fetch trap (a Worker fetching its own hostname)\\n- quick tunnel endpoint changes (health must re-resolve)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0477, WT-0487\\n- OWNS (only this task rewrites): functions/api/onboard/*, functions/onboard.js, functions/_lib/onboard_contract.js, functions/_lib/tenant_devices.js; public/device-kit/*, scripts/device-kit-sync.mjs; the bridge-kit package and /bridge card; ONBOARD/DEVICE_*/INVITE_* rows\\n- SHARED (additive edits only): functions/_lib/wfp_worker.js (WT-0481; tenant script template is additive); bridge/* (WT-0474; the kit copies, never diverges — run device-kit-sync.mjs)\\n\\n## HANDOFF FOR NEXT SESSION\\n- The second-machine proof is mandatory; the owner's own session is not a stranger. A CF container (CLOUD_WORKSPACE_NEW) is an acceptable stand-in for a Linux kit; a second macOS user on the Mac for the Mac kit.\\n- Never surface signup/verify/install asks to the owner; the kit is installed by the task.\\n- Evidence: the tenant id, the gate card receipt, the kit log, the tenant sheet view URL.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- One-call onboarding proven end to end from the stranger vantage with receipts.\\n- Kit proven on a non-owner machine; tenant MCP proven with a real client.\\n- Rental flow proven; boundary denial proven.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0477\",\"WT-0487\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"guide\",\"url\":\"https://ops.miscsubjects.com/api/onboard/guide\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "068def0431b1f4fc69126ccd7e93dd2b424e567b97068a93b7e466687d11424d",
      "hash": "c92a814d22d33f8b9b56a7a495a1f49335ec01f492c4ee351385990a160471f9"
    },
    {
      "id": 1239,
      "ts": "2026-09-22T19:52:05-07:00",
      "task_id": "WT-0476",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0475\",\"WT-0477\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"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}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "599a4a3ac8f0e1489a99f9b4ae9a79705f9c5775dfe4303b54284562797b3eb9",
      "hash": "068def0431b1f4fc69126ccd7e93dd2b424e567b97068a93b7e466687d11424d"
    },
    {
      "id": 1238,
      "ts": "2026-09-22T19:52:04-07:00",
      "task_id": "WT-0484",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0484\",\"kind\":\"work\",\"objective\":\"WT-0484 Composition plane — chains, compose, line grammar, combinatorial automations with parent linkage\",\"detail\":\"# WT-0484 — Composition plane — chains, compose, line grammar, combinatorial automations with parent linkage\\n\\n## GOAL\\nAny sequence of capabilities (a chain of dispatch calls, /api/surface compose, a misc line with pipes, a webhook that triggers a chain, a sheet column of =DISPATCH cells feeding each other, an agent run that fans out) is itself a capability with a contract; every step runs through the resolver with cause=parent:<receipt>, and the chain receipt links every child so the owner can read WHY → WHAT → ACK → RETURN → RECEIPT for the whole automation.\\n\\n## WHY THIS EXISTS\\nThe owner asked how to formulate combinatorial automations across Mac, iPhone, browser and messages. Compose exists (/api/surface compose, `composed` layer) but its steps have no parent linkage, the line grammar resolves one call, and \\\"chain\\\" rows are prose. Composition must be a first-class object with proof.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- /api/surface compose (composed layer, surface_composed_0.json); /api/chain door exists (functions/api/chain); /api/resolve line grammar (functions/_lib/grammar.js); /api/hooks webhooks; sheet formulas; agent runs fan out.\\n- No parent_receipt_id on any child call today.\\n\\n## SOURCE OF TRUTH\\n- functions/api/chain/*, functions/api/surface (compose), functions/api/resolve.js, functions/_lib/grammar.js\\n- functions/api/hooks/*\\n- the `composed` surface layer\\n\\n## IN-SCOPE INVENTORY\\n- Chain object: `chains` table (main DB): id, name, steps (JSON array of {key, args (may reference `$prev.return.<path>` and `$step[n].return.<path>`), route?, on_error: stop|continue|branch:<step>}), owner_principal, created_at; a CHAIN_<NAME> directory row per saved chain (so every spelling applies).\\n- Verbs: CHAIN_RUN {chain_id | steps inline, args, cause} → runs steps through the resolver with cause=parent:<chain receipt>; CHAIN_DEFINE; CHAIN_LIST; COMPOSE (surface compose kept, now delegating to CHAIN_RUN).\\n- Grammar: the misc line accepts `KEY args | KEY2 $prev.return.x` and compiles to an inline chain.\\n- Triggers: a hook row may name a chain (WT-0485 hook receipts become the cause); a sheet column of =DISPATCH cells referencing the prior row is documented as the cell composition.\\n- Proof set: three cross-plane automations — (1) NET_LINE → SHEETS_APPEND → TEXT send to the owner; (2) PHONE_SCREENSHOT → R2 → BROWSER_MARKDOWN of the receipt page; (3) inbound tag → CHAIN_RUN → reply. Each child has parent_receipt_id.\\n\\n## OUT OF SCOPE\\n- Scheduling/recurring runs (automations are off by LAW: no unrequested automations; a chain runs when called). New planes.\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: dispatch CHAIN_*; POST /api/chain; misc line with pipes; hook-triggered; cell column\\n- CAPABILITY: CHAIN_RUN/DEFINE/LIST, COMPOSE\\n- OBJECT: a chain and its steps\\n- ROUTE / CONTEXT: per step (inherits or overrides)\\n- PROTOCOL: in-Worker orchestration calling the resolver\\n- EXECUTOR: Worker (orchestrator) + each step's executor\\n- PLATFORM: the build\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/chain\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/surface/layers/composed?limit=10\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/resolve -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"line\\\":\\\"NET_LINE\\\"}'`\\n\\n## CONTRACT (FIELD LAW)\\n- CHAIN_RUN `{chain_id (one-of with steps), steps (array ≥ 1 of {key (required), args (object|string), route?, on_error (enum, default stop)}), args (object, chain inputs), cause, dry (bool)}` → `{ok, chain_receipt_id, steps:[{n, key, receipt_id, confirmation, return (≤ 20,000 in the chain return; whole at the child receipt), status}], stopped_at?}`.\\n- References: `$prev.return.<jsonpath>`, `$step[n].return.<jsonpath>`, `$args.<name>`; an unresolvable reference → 400 ref_unresolved naming the step and path.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"CHAIN_RUN\\\",\\\"body\\\":{\\\"steps\\\":[{\\\"key\\\":\\\"NET_LINE\\\"},{\\\"key\\\":\\\"D1_QUERY\\\",\\\"args\\\":\\\"SELECT 1 AS one\\\"}]}}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"CHAIN_RUN\\\",\\\"body\\\":{\\\"steps\\\":[{\\\"key\\\":\\\"NET_LINE\\\"},{\\\"key\\\":\\\"SHEETS_APPEND\\\",\\\"args\\\":{\\\"sheet\\\":\\\"sh_ahznwfyd\\\",\\\"values\\\":[[\\\"$prev.return.ip\\\",\\\"$prev.return.dish.uptime_s\\\"]]}},{\\\"key\\\":\\\"TEXT_SEND\\\",\\\"args\\\":{\\\"to\\\":\\\"+17079135888\\\",\\\"from\\\":\\\"+14245134626\\\",\\\"text\\\":\\\"line $step[1].return.ip\\\"},\\\"on_error\\\":\\\"stop\\\"}],\\\"args\\\":{},\\\"dry\\\":false},\\\"cause\\\":\\\"task:WT-0484\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\nChain: HTTP 200 + chain_receipt_id immediately after the chain row is persisted (before steps run); per step: that step's executor confirmation.\\n\\n## RAW RETURN SHAPE\\nThe steps array with each child receipt; each child return whole at its receipt.\\n\\n## ERROR SHAPES\\n- ref_unresolved\\n- step_failed (with on_error=stop → stopped_at)\\n- authority_denied on a step (the chain records it and stops)\\n- chain_not_found\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nchain receipt with children; every child proof_run has parent_receipt_id = chain receipt; the receipt page renders the tree.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| inline 2-step | NET_LINE → D1_QUERY | live |\\n| saved chain | CHAIN_DEFINE then CHAIN_RUN by id, CHAIN_<NAME> row appears with 13 spellings | live |\\n| cross-plane 1 | NET_LINE → sheet → text | live |\\n| cross-plane 2 | phone screenshot → R2 → browser markdown | live |\\n| cross-plane 3 | inbound tag → chain → reply | live |\\n| ref error | a bad $prev path → ref_unresolved | fixture |\\n| stop on error | a failing middle step → stopped_at=2, step 3 not run | fixture |\\n| line pipes | misc line `NET_LINE | D1_QUERY SELECT 1` → same as inline | 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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"chain\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/chain\\\"}`\\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- no unrequested automations (no scheduler is added; a test asserts no cron/trigger rows were created)\\n- DNS failure in a middle step isolates that step (on_error=continue)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0485\\n- OWNS (only this task rewrites): functions/api/chain/*; functions/_lib/chain_run.js (new); migrations/0487_chains.sql (new); CHAIN_* rows; the pipe extension of functions/_lib/grammar.js (coordinate with WT-0472: additive token only)\\n- SHARED (additive edits only): functions/_lib/grammar.js (WT-0472 owns; add the `|` token additively); functions/api/surface compose (WT-0474 owns the door; delegate to CHAIN_RUN additively)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Persist the chain row before running steps (the ack law).\\n- Cross-plane proofs need WT-0478/0479/0480/0483 executors; if one is not ready, run the chain with the steps that exist and record the missing executor as step_failed with its exact error.\\n- Evidence: three chain receipt ids with their trees.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Chains are rows with contracts and spellings.\\n- Three cross-plane automations proven with parent linkage.\\n- Fixtures pass; no scheduler exists.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0485\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"chain\",\"url\":\"https://ops.miscsubjects.com/api/chain\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "3924ca1635b7322cd432b490aad0c6555cb34985efd80950e1be4beac2980ee3",
      "hash": "599a4a3ac8f0e1489a99f9b4ae9a79705f9c5775dfe4303b54284562797b3eb9"
    },
    {
      "id": 1237,
      "ts": "2026-09-22T19:52:03-07:00",
      "task_id": "WT-0482",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0482\",\"kind\":\"work\",\"objective\":\"WT-0482 Model / agent plane — the four Code-Mode models, headless lanes, agent runs; a model call is a surface\",\"detail\":\"# WT-0482 — Model / agent plane — the four Code-Mode models, headless lanes, agent runs; a model call is a surface\\n\\n## GOAL\\nEvery way a model or agent invokes the build (the four Code-Mode models through /api/mcp and Cloudflare Code Mode, Claude Code with the MCP config, grok/kimi/codex headless lanes, muse-worker profiles, AGENT_SPAWN_CLI, CLOUD_EXEC containers, the Console app talk routes) is a declared surface whose runs are proof_runs with cause=model:<run id>, and every agent run row (agent_runs / agent_run_calls) links to the receipts of what it invoked.\\n\\n## WHY THIS EXISTS\\nThe owner asked that models 1–4 with Code Mode have everything available. Availability was asserted from the MCP tool list; it must be proven by each model actually calling the tools, with the raw tool_use, the raw tool_result and the receipt. Never run models from my terminal with my prompts (LAW) — the proof runs go through the build's agent runner rows.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- /api/mcp (misc_find/misc_run + hot set /api/tools/*.json; MCP_TOKEN); the four models' MCP configs (memory: Console v2 talk.js/v2.js, Anthropic + Moonshot direct; gateway models).\\n- Agent runs: agent_runs, agent_run_calls, agent_turns tables; AGENT_SPAWN_CLI row; headless lanes (grok -p --always-approve --no-plan --max-turns; kimi -p; claude -p); muse-worker Worker/Coder profiles; CLOUD_EXEC/CLOUD_EXEC_IN/CLOUD_WORKSPACE_NEW/CLOUD_HEALTH rows.\\n- Cold start: MCP handshake 50–65 s (one Worker, 715 files).\\n- Never touch the model surface (LAW): prompts, tools, tool_choice, budgets, model ids are the owner's; this task adds receipts, not prompts.\\n\\n## SOURCE OF TRUTH\\n- functions/api/mcp.js, functions/api/tools/[[path]].js\\n- functions/api/agent_spawn.js, agent_turns.js, agent_run_calls (schema in migrations)\\n- the Console app talk routes (memory project_console_v2_state)\\n- muse-worker (memory project_muse_worker_profiles)\\n- the agent run door record (memory project_agent_run_door_record: every model/FIND/CALL/CODE call is a row)\\n\\n## IN-SCOPE INVENTORY\\n- Surface ids: model_mcp_<model> (claude, grok, kimi, codex — or the four ids the Console names), model_codemode (Cloudflare Code Mode), agent_cli_<lane> (headless lanes), agent_container (CLOUD_EXEC), console_talk.\\n- Cause plumbing: /api/mcp stamps cause=model:<agent_run id> from the session token; AGENT_SPAWN_CLI stamps cause=agent:<run>; agent_run_calls rows get receipt_id.\\n- Proof set: for each of the four models, one run (through the build's AGENT_SPAWN_CLI / Console talk, with an existing owner-authored prompt row — never a prompt written here) that calls misc_find and misc_run on NET_LINE; capture tool_use + tool_result raw; receipt linked.\\n- Fixtures: MCP cold start (retry after 70 s once); Bearer anonymous on tools; `||` in Code Mode; a model claiming it called a tool with no tool_use block (record as failure).\\n\\n## OUT OF SCOPE\\n- Writing prompts, changing tools/tool_choice/budgets (LAW). Building new agents.\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/mcp (JSON-RPC), Code Mode execute, AGENT_SPAWN_CLI, CLOUD_EXEC, Console talk\\n- CAPABILITY: misc_find, misc_run, every hot tool\\n- OBJECT: an agent run; a tool call\\n- ROUTE / CONTEXT: which model, which lane, which container\\n- PROTOCOL: JSON-RPC over HTTP; process; container exec\\n- EXECUTOR: the model provider; the lane CLI; the container\\n- PLATFORM: Anthropic, xAI, Moonshot, OpenAI; Cloudflare containers; the Console app\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/mcp -H \\\"Authorization: Bearer $MCP_TOKEN\\\" -H \\\"content-type: application/json\\\" -d '{\\\"jsonrpc\\\":\\\"2.0\\\",\\\"id\\\":1,\\\"method\\\":\\\"tools/list\\\"}'` (`grep '^MCP_TOKEN=' ~/.build-vault.env`)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/agents\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"CLOUD_HEALTH\\\"}'`\\n\\n## CONTRACT (FIELD LAW)\\n- tools/call `{jsonrpc:\\\"2.0\\\", id, method:\\\"tools/call\\\", params:{name (required, tool id), arguments (object per tool schema)}}` + Bearer MCP_TOKEN (or a tenant token) → `{jsonrpc, id, result:{content:[{type:\\\"text\\\", text}], isError?}}`; the build adds `_receipt_id` in a trailing content item; errors `-32601`, `-32602`, `unauthorized`.\\n- AGENT_SPAWN_CLI `{lane (enum), prompt_row (required: an existing agent row key; free text refused), max_turns (default per lane), cwd?}` → `{run_id, pid, log_url}`; run rows link receipts.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/mcp -H \\\"Authorization: Bearer $MCP_TOKEN\\\" -H \\\"content-type: application/json\\\" -d '{\\\"jsonrpc\\\":\\\"2.0\\\",\\\"id\\\":1,\\\"method\\\":\\\"tools/call\\\",\\\"params\\\":{\\\"name\\\":\\\"NET_LINE\\\",\\\"arguments\\\":{}}}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"AGENT_SPAWN_CLI\\\",\\\"body\\\":{\\\"lane\\\":\\\"grok\\\",\\\"prompt_row\\\":\\\"<existing agent row key>\\\",\\\"max_turns\\\":6},\\\"cause\\\":\\\"task:WT-0482\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\nJSON-RPC result envelope with id; spawn `{run_id, pid}`; container `{exec_id, exit}`.\\n\\n## RAW RETURN SHAPE\\nTool result content verbatim; run transcript URL; tool_use/tool_result raw pairs per call.\\n\\n## ERROR SHAPES\\n- unauthorized\\n- -32601\\n- cold_start_timeout (retry once at 70 s)\\n- no_tool_use (model claimed without calling)\\n- lane_unavailable (CLI missing; exit 127 recorded)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nagent_run_calls.receipt_id; proof_run cause=model:<run>; the run page lists receipts.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| tools/list | count ≥ 595 with the owner token | live |\\n| tools/call | NET_LINE via MCP | live |\\n| four models | each calls misc_find + misc_run through the build runner; raw tool_use captured | live |\\n| codemode | one execute calling the build | live |\\n| lanes | grok, kimi, claude, codex headless one run each (existing rows) | live |\\n| container | CLOUD_EXEC uname | live |\\n| cold start | first call after idle timed; retry recorded | fixture |\\n| no tool_use | a run whose transcript lacks tool_use is marked failed | fixture |\\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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"agents\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/agents\\\"}`\\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- MCP cold start 65 s\\n- Bearer anonymous on /api/tools\\n- Code Mode `||`\\n- model claims without tool_use\\n- never run models from my terminal (use the build runner rows)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0472\\n- OWNS (only this task rewrites): functions/api/agent_spawn.js, agent_turns.js, agent_run_calls writers; the run pages; AGENT_SPAWN_CLI/CLOUD_* rows\\n- SHARED (additive edits only): functions/api/mcp.js (WT-0472; add the cause stamp and `_receipt_id` additively); the models' prompt rows (owner's; read only)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Use existing owner-authored prompt rows; if none fits, file the gap as a failure task, do not write a prompt.\\n- Evidence: per model, the raw tool_use/tool_result pair and the receipt id.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Each of the four models has a receipted tool call through the build.\\n- Every lane and the container have a receipted run.\\n- agent_run_calls rows carry receipt ids; fixtures pass.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0472\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"agents\",\"url\":\"https://ops.miscsubjects.com/api/agents\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "6693f4ae9d1252449c2bffe1499b42a00d2f797d53ed7397c1971ef41fe6bf72",
      "hash": "3924ca1635b7322cd432b490aad0c6555cb34985efd80950e1be4beac2980ee3"
    },
    {
      "id": 1236,
      "ts": "2026-09-22T19:52:02-07:00",
      "task_id": "WT-0480",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0480\",\"kind\":\"work\",\"objective\":\"WT-0480 Messaging plane — iMessage, SMS, rented lines, email, tags; every send a receipted contract, never batched\",\"detail\":\"# WT-0480 — Messaging plane — iMessage, SMS, rented lines, email, tags; every send a receipted contract, never batched\\n\\n## GOAL\\nEvery messaging capability (/api/text 22 methods live on 2026-09-23, senders +17079135888 and redacted and the iCloud/Gmail aliases, rented lines +14245134626 / +14245040908 / +12065711028 via Blooio, private iMessage on a SIP-off Mac, imessage-cli/Beeper, EMAIL_SEND_TRACKED, inbound tags → resolve) has a full contract with FIELD LAW, a message id as confirmation, delivery state as return, and a receipt; sends are never eligible for batch runs.\\n\\n## WHY THIS EXISTS\\nA directory test run with run:true sent 5 iMessages from the owner's account (LAW: never batch-test send rows). Rented-line history needed a chat id nobody named. The tag spelling (a tag in a text) is compiled but unproven. The owner wants the message send proven as a send with its delivery state, and the 99 % path (text him, text a lead) solid.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- functions/api/text/* (22 methods on the door; accounts sub-door fixed 2026-09-23 for ISO timestamps); functions/api/imessage/*; bridge/imessage_api.py; Blooio for rented lines (chat/chat_id required for delivery/history); SEND_BY_CHANNEL, EMAIL_SEND_TRACKED rows.\\n- Private iMessage (surface layer private_imessage) needs SIP off (WT-0447 open) — observe only today.\\n- Inbound: texts to the rented lines reach /api/text inbound; tags resolve through /api/resolve.\\n- Policy: read-only list in scripts/contracts-run.mjs excludes sends.\\n\\n## SOURCE OF TRUTH\\n- functions/api/text/[[path]].js and functions/api/text/accounts/[[path]].js\\n- bridge/imessage_api.py\\n- functions/api/imessage/*\\n- Blooio API docs + vault BLOOIO_* names\\n- the iMessage API vendors article set (/a/blooio … /a/mycrmsim, 2026-09-21)\\n\\n## IN-SCOPE INVENTORY\\n- Executor ids: text_blooio (rented lines), text_imessage_mac (Messages.app via AppleScript on the owner Mac; owner account), text_imessage_private (SIP-off; not available), text_beeper, email_smtp_tracked, text_inbound (webhook from vendor).\\n- Contracts for every one of the 22 methods: send {to (E.164 or handle, required), from (required enum of senders/lines), text (required ≤ 1,600 SMS / ≤ 20,000 iMessage), media (optional URL[]), chat|chat_id (conditional: required for rented lines' delivery/history), idempotency_key (optional; duplicate → same message id)}; delivery {message_id}; history {chat_id, limit}; accounts {…}; inbound {vendor payload verbatim}.\\n- Tag spelling proof: send `#NET_LINE` to +14245134626 from the owner line → inbound → resolve → dispatch → reply; the reply text is the return; message ids both ways are the receipt.\\n- Never-batch: the resolver marks every send row side_effect=send; WT-0473 policy refuses them in batch; the CONTRACTS row shows `NOT RUN BY THE SESSION · send-effect · type RUN here to run it yourself`.\\n\\n## OUT OF SCOPE\\n- Authority for who may send from which line (WT-0487). Phone-side Messages UI taps (WT-0479).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/text/<method>; dispatch SEND_BY_CHANNEL/EMAIL_SEND_TRACKED/TEXT_*; MCP SEND_BY_CHANNEL; the tag in a text; cell (send refused in cells by policy)\\n- CAPABILITY: the 22 methods\\n- OBJECT: a message, a chat, a line, an inbox\\n- ROUTE / CONTEXT: which line/account sends (owner Mac Messages, Blooio line, SMTP identity)\\n- PROTOCOL: HTTPS (Blooio, SMTP relay), AppleScript (Messages.app), vendor webhooks\\n- EXECUTOR: Worker (Blooio, email), Mac bridge (Messages.app)\\n- PLATFORM: Apple iMessage; Blooio; Gmail/SMTP\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/text\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"` (methods and senders)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/text/accounts\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n\\n## CONTRACT (FIELD LAW)\\n- send: see inventory; response `{ok, message_id, physical:{executor, line}, confirmation:{vendor_status|applescript_result}, return:{delivery:queued|sent|delivered|failed, at}, receipt_id}`; conflicts: `from` a rented line with no chat for history calls → chat_required (names the field).\\n- inbound: vendor payload verbatim stored; `{tag?, resolved_key?, dispatched_receipt?}` appended.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/text/send -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"to\\\":\\\"+14245134626\\\",\\\"from\\\":\\\"+17079135888\\\",\\\"text\\\":\\\"WT-0480 test\\\"}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/text/send -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"to\\\":\\\"+17079135888\\\",\\\"from\\\":\\\"+14245134626\\\",\\\"text\\\":\\\"#NET_LINE\\\",\\\"media\\\":[],\\\"idempotency_key\\\":\\\"wt0480-tag-1\\\",\\\"cause\\\":\\\"task:WT-0480\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\nBlooio `{id, status}`; Messages.app AppleScript result; SMTP 250 with message-id; inbound webhook HTTP 200 with the stored id.\\n\\n## RAW RETURN SHAPE\\nDelivery state polled (`delivery {message_id}`) until sent/delivered/failed (max 60 s); the reply text for the tag test.\\n\\n## ERROR SHAPES\\n- chat_required\\n- line_not_owned (authority)\\n- vendor 4xx verbatim\\n- Messages.app not signed in / -1712 locked\\n- sip_required (private iMessage)\\n- idempotent_replay (same id returned; not an error)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nmessage ids in confirmation; proof_run per send; inbound rows linked by chat id.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| send owner→rented | one message, delivery polled | live |\\n| send rented→owner | one message | live |\\n| email tracked | one email to the owner address with open pixel | live |\\n| history | rented chat history with chat_id | live |\\n| tag round trip | #NET_LINE → reply with the line JSON | live |\\n| idempotency | same key twice → one message | live |\\n| batch refusal | CONTRACTS runner on a send row → NOT RUN | fixture |\\n| private imessage | observe-only; sip_required recorded | fixture |\\n| beeper | one read of a chat list | 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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"text\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/text\\\"}`\\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- never batch-test send rows (5 iMessages sent 2026-09)\\n- private iMessage needs SIP off (WT-0447)\\n- rented-line chat id required\\n- locked-Mac Messages.app -1712\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0474, WT-0487\\n- OWNS (only this task rewrites): functions/api/text/*; functions/api/imessage/*; bridge/imessage_api.py; TEXT_*/SEND_BY_CHANNEL/EMAIL_SEND_TRACKED rows\\n- SHARED (additive edits only): scripts/contracts-run.mjs policy() read-set (WT-0473; sends stay excluded); functions/api/resolve.js (WT-0472; tag resolution is read-only here)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Send only to the owner's own numbers/addresses during proof; one message per test; never a loop.\\n- The tag round trip is the proof of the `tag` spelling for WT-0472; give it the receipt ids.\\n- Evidence: message ids + delivery states table.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- All 22 methods have contracts with FIELD LAW in capability_contracts.\\n- Send/delivery/history/inbound/tag proven with receipts, one message each.\\n- Batch refusal fixture passes.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0474\",\"WT-0487\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"text\",\"url\":\"https://ops.miscsubjects.com/api/text\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "249e31b4691aff7998ad71922e06ba30b44b92fb77989c8563b644fd7a925ea1",
      "hash": "6693f4ae9d1252449c2bffe1499b42a00d2f797d53ed7397c1971ef41fe6bf72"
    },
    {
      "id": 1235,
      "ts": "2026-09-22T19:52:01-07:00",
      "task_id": "WT-0479",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0479\",\"kind\":\"work\",\"objective\":\"WT-0479 iPhone plane — physical device, Shortcuts, App Intents, Console app, mirroring; simulator is not the phone\",\"detail\":\"# WT-0479 — iPhone plane — physical device, Shortcuts, App Intents, Console app, mirroring; simulator is not the phone\\n\\n## GOAL\\nEvery iPhone capability (Shortcuts on the device by URL scheme and by push, App Intents, the Console app with APNs, pymobiledevice3 device reads, the iPhone Mirroring window on the Mac, Simulator as a separate executor, screenshots) has a contract and runs through its declared executor with the five fields; the simulator/physical confusion, the root-tunnel requirement and the `shortcuts run` hang are fixtures.\\n\\n## WHY THIS EXISTS\\nThe owner wants the iPhone tap proven as an iPhone tap. Previous sessions mixed the Simulator (mcp iOS Simulator tool) with the physical phone, and developer screenshots need a root tunnel. The Console iOS app (com.llmasos.console, APNs key BL72QSYNV2) exists but its capabilities are not contracts.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- functions/api/phone/* (phone controller: push, shortcuts, device reads); /api/apple; bridge/apple_data.py; iphone_device layer in the surface encyclopedia (surface_iphone_device_0.json).\\n- Console app: bundle com.llmasos.console, APNs key BL72QSYNV2 (iOS Console app memory); Catalyst build for desktop/iPad.\\n- pymobiledevice3 on the Mac (USB/Wi-Fi pairing); developer-mode screenshot needs `sudo python3 -m pymobiledevice3 remote tunneld` (root tunnel).\\n- iPhone Mirroring window on the Mac = the phone (WT-0474 mac_mirror); Simulator = mcp__Claude_Code_iOS_Simulator (never the phone).\\n- Shortcuts on the phone: run by `shortcuts://run-shortcut?name=…` opened on the phone (via Mirroring or a push that opens the URL) and by Automation triggers; iCloud-synced Shortcuts appear on both Mac and phone.\\n\\n## SOURCE OF TRUTH\\n- functions/api/phone/[[path]].js\\n- bridge/apple_data.py\\n- `GET https://ops.miscsubjects.com/api/surface/layers/iphone_device`\\n- the Console app source (memory project_ios_console_app names the repo)\\n- pymobiledevice3 docs\\n\\n## IN-SCOPE INVENTORY\\n- Executor ids: iphone_shortcut_url (Mirroring taps shortcuts:// on the phone), iphone_push (APNs to the Console app → app runs an intent), iphone_app_intent (via the Console app), iphone_pymd3 (device info, apps list, syslog, screenshot with tunnel), iphone_mirror (WT-0474 mac_mirror on the phone window: tap/type/screenshot), ios_simulator (labelled; never counts as phone proof).\\n- Verbs: PHONE_INFO, PHONE_APPS, PHONE_SCREENSHOT {via: mirror|pymd3}, PHONE_SHORTCUT_RUN {name, input?, via: url|push}, PHONE_PUSH {title, body, intent?}, PHONE_OPEN_URL {url}, PHONE_SYSLOG {seconds}.\\n- Fixtures: simulator vs physical (a proof_run with surface=ios_simulator is refused as phone proof by the gate); root tunnel absent → PHONE_SCREENSHOT via pymd3 returns the exact `tunneld` error, via mirror still works; shortcuts hang; phone locked → Mirroring refuses (record it).\\n\\n## OUT OF SCOPE\\n- Mac-side executors (WT-0474 owns the Mirroring window driver; this task uses it). Message sending (WT-0480).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/phone/<verb>; dispatch PHONE_* rows; MCP (none yet — add PHONE_SCREENSHOT to the hot set); cell\\n- CAPABILITY: the verbs above\\n- OBJECT: the phone, an app, a shortcut, a URL\\n- ROUTE / CONTEXT: owner iPhone (device id owner-iphone) via USB/Wi-Fi/Mirroring/APNs; the Simulator as a separate route\\n- PROTOCOL: usbmuxd/RemoteXPC (pymd3), APNs HTTP/2, URL scheme, Mirroring UI\\n- EXECUTOR: bridge on the Mac; APNs; the Console app\\n- PLATFORM: Apple iOS\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/phone\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `python3 -m pymobiledevice3 usbmux list` (on the Mac)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/surface/layers/iphone_device?limit=20\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n\\n## CONTRACT (FIELD LAW)\\n- PHONE_SHORTCUT_RUN `{name (required, exact Shortcut name), input (optional string), via (required enum url|push), device (default owner-iphone), timeout_ms (default 60000)}` → `{physical:{executor, url_opened|push_id}, confirmation:{opened:true|delivered:true, ms}, return:{result_text?, screenshot_url?}}`; omission of via → 400 via_required.\\n- PHONE_SCREENSHOT `{via (enum mirror|pymd3, default mirror)}` → R2 URL; pymd3 requires tunnel (conditional: error tunnel_required with the exact command to start it).\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"PHONE_INFO\\\"}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"PHONE_SHORTCUT_RUN\\\",\\\"body\\\":{\\\"name\\\":\\\"Build Ping\\\",\\\"input\\\":\\\"WT-0479\\\",\\\"via\\\":\\\"url\\\",\\\"device\\\":\\\"owner-iphone\\\",\\\"timeout_ms\\\":60000},\\\"cause\\\":\\\"task:WT-0479\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\npymd3: process exit 0 + JSON; APNs: HTTP/2 200 with apns-id; Mirroring: tap confirmation from the ax layer; url: `opened:true`.\\n\\n## RAW RETURN SHAPE\\nDevice info JSON, screenshot URL, shortcut result text, syslog lines verbatim.\\n\\n## ERROR SHAPES\\n- device_not_paired\\n- tunnel_required (with the exact sudo command; the owner is not asked — record it)\\n- apns_bad_token / 410\\n- mirroring_locked\\n- shortcut_not_found\\n- simulator_not_phone (gate refusal)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nproof_run surface=iphone_*; screenshots in R2; push ids kept.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| info | PHONE_INFO name/model/iOS version | live |\\n| apps | installed apps list | live |\\n| screenshot mirror | via Mirroring → R2 | live |\\n| screenshot pymd3 | with tunnel if root available; else the exact error recorded | live/fixture |\\n| shortcut url | a no-op Shortcut via shortcuts:// through Mirroring | live |\\n| push | APNs to the Console app → app receipt back to /api/phone | live |\\n| open url | open https://miscsubjects.com/tools on the phone | live |\\n| simulator | the same PHONE_SCREENSHOT via ios_simulator labelled and refused as phone proof | fixture |\\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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"phone\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/phone\\\"}`\\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- simulator vs physical device confusion\\n- root tunnel required for developer screenshots\\n- `shortcuts run` hang (Mac side) — the phone url path is the workaround and must be proven\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0474\\n- OWNS (only this task rewrites): functions/api/phone/*; bridge/apple_data.py; PHONE_* rows; the Console app intent handlers (repo named in memory)\\n- SHARED (additive edits only): bridge/surface-verbs.py (mirror verbs; WT-0474); functions/api/tools hot set (WT-0472; add PHONE_SCREENSHOT additively)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Do not show the Simulator on the owner screen; the Mirroring window may be opened for the tap tests and closed after.\\n- APNs: key BL72QSYNV2, team/bundle in the vault (`grep '^APNS_' ~/.build-vault.env | cut -d= -f1`).\\n- Evidence: one receipt per executor id, plus the simulator refusal.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Every executor id has a proof_run from that executor; ios_simulator is labelled and refused as phone proof.\\n- PHONE_SHORTCUT_RUN via url proven on the physical phone.\\n- Push → app → receipt loop proven.\\n- Fixtures pass.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0474\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"phone\",\"url\":\"https://ops.miscsubjects.com/api/phone\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "35115528a6921279f5db23b02f7d16a24a46ec55a3d98311238df830053ba3e8",
      "hash": "249e31b4691aff7998ad71922e06ba30b44b92fb77989c8563b644fd7a925ea1"
    },
    {
      "id": 1234,
      "ts": "2026-09-22T19:52:00-07:00",
      "task_id": "WT-0475",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0475\",\"kind\":\"work\",\"objective\":\"WT-0475 Browser / CDP / computer-use plane — every browser controller as a declared executor\",\"detail\":\"# WT-0475 — Browser / CDP / computer-use plane — every browser controller as a declared executor\\n\\n## GOAL\\nEvery browser capability (Playwright, raw CDP attach to AdsPower and to Chrome, the Chrome extension, the built-in pane, computer-use MCP, kimi-cu, browser-use task runner) is a declared executor with a contract, runs as that executor with the five fields, and records screenshots/HAR/DOM as return files. CDP attach gaps are fixtures.\\n\\n## WHY THIS EXISTS\\nThe 2026-09-23 runs used the session's own browser tools; the url spelling was proven by fetch, not by a browser. AdsPower profiles must be driven over CDP for rented ad accounts (WT-0458 open). The owner wants the browser click proven as a browser click.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- bridge/bridge-browser.mjs (Playwright driver via the bridge), bridge/run_browser_use_task.py (browser-use), bridge/playwright-mcp-launcher.sh; /api/bridges browser controller (record → compile → BRIDGE_* rows); rows BROWSER_SCREENSHOT, BROWSER_MARKDOWN, BRIDGE_ACT, BRIDGE_REGISTER.\\n- AdsPower Local API http://local.adspower.net:50325 (Bearer header, ~1 req/2 s, headless now); rows ADSPOWER_STATUS/PROFILES/OPEN/STOP; account has only Default Profile; CDP attach (ws endpoint from /api/v1/browser/start) = WT-0458.\\n- Session-only tools (not build executors): Claude built-in pane, Claude in Chrome, computer-use MCP, kimi-cu, Playwright MCP.\\n\\n## SOURCE OF TRUTH\\n- bridge/bridge-browser.mjs\\n- bridge/run_browser_use_task.py\\n- functions/api/bridges/*\\n- bridge/adspower.sh, adspower-apply.sh, adspower-verify.sh, adspower_profile.conf, proxycheck.sh\\n- AdsPower Local API docs (https://localapi-doc-en.adspower.com/)\\n\\n## IN-SCOPE INVENTORY\\n- Executor ids: browser_playwright (chromium managed by the bridge), browser_cdp_chrome (attach to the owner Chrome --remote-debugging-port), browser_cdp_adspower (attach to the profile ws), browser_extension (Claude in Chrome; session-only, labelled), browser_use_agent (bridge/run_browser_use_task.py), computer_use (session-only, labelled), browser_pane (session-only).\\n- Verbs with contracts: navigate, screenshot (full/viewport → R2), markdown/text, click (selector|text|xy), type, fill_form, eval_js, network_capture (HAR to R2), cookies_export/import (to the accounts plane, WT-0477), tabs, wait_for, download.\\n- Profile as ROUTE: `route.profile` ∈ {default-chromium, owner-chrome, adspower:<profile id>}; egress binds to the profile's proxy (proxies.tsv) — recorded in physical.\\n- Fixtures: CDP attach refused (AdsPower start returns no ws; Chrome without the debugging port); screenshot black in the pane (use Playwright); simulator confusion N/A here.\\n\\n## OUT OF SCOPE\\n- Recording→compiling website→API (WT-0476). Account/session storage (WT-0477). iPhone Safari (WT-0479).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/bridges/browser/<verb>, dispatch rows BROWSER_*, MCP BROWSER_SCREENSHOT/BROWSER_MARKDOWN, the misc line, the cell\\n- CAPABILITY: the verbs above\\n- OBJECT: a page, a tab, an element, a profile\\n- ROUTE / CONTEXT: profile id + proxy + device (owner Mac or a CF browser container)\\n- PROTOCOL: HTTPS → bridge → CDP websocket / Playwright\\n- EXECUTOR: chromium child of the bridge; the owner Chrome; the AdsPower profile\\n- PLATFORM: Chromium; AdsPower; Cloudflare Browser Rendering (optional second executor)\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/bridges\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"ADSPOWER_STATUS\\\"}'`\\n- `curl -sS -H \\\"Authorization: Bearer $ADSPOWER_API_KEY\\\" \\\"http://local.adspower.net:50325/status\\\"` (from the Mac only; the key is `grep '^ADSPOWER_API_KEY=' ~/.build-vault.env`)\\n\\n## CONTRACT (FIELD LAW)\\n- POST /api/bridges/browser/navigate `{url (required, https?://…), profile (optional, default default-chromium), wait (optional enum load|domcontentloaded|networkidle, default load), timeout_ms (default 30000), screenshot (bool, default false), capture_network (bool)}` → `{ok, physical:{executor, profile, proxy, cdp_ws|launch_args}, confirmation:{status, final_url, ms}, return:{title, text_len, screenshot_url?, har_url?}, receipt_id}`.\\n- click `{selector|text|xy one-of (exactly one), profile, timeout_ms}`; type `{selector, text, submit?}`; eval_js `{js, arg?}` returns JSON-serialisable only.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"BROWSER_SCREENSHOT\\\",\\\"body\\\":{\\\"url\\\":\\\"https://miscsubjects.com/tools\\\"}}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/bridges/browser/navigate -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"url\\\":\\\"https://miscsubjects.com/tools\\\",\\\"profile\\\":\\\"adspower:<profile id from ADSPOWER_PROFILES>\\\",\\\"wait\\\":\\\"networkidle\\\",\\\"timeout_ms\\\":45000,\\\"screenshot\\\":true,\\\"capture_network\\\":true,\\\"cause\\\":\\\"task:WT-0475\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\n`confirmation:{status:200, final_url, ms}`; CDP: `{ws:\\\"ws://127.0.0.1:<port>/devtools/browser/<id>\\\", attached:true}`; Playwright launch: `{pid, args}`.\\n\\n## RAW RETURN SHAPE\\ntitle/text/screenshot R2 URL/HAR R2 URL; eval results verbatim; failures verbatim (`Timeout 30000ms exceeded`, `net::ERR_NAME_NOT_RESOLVED`).\\n\\n## ERROR SHAPES\\n- cdp_attach_refused (no ws from AdsPower start; port closed on Chrome)\\n- profile_not_found\\n- proxy_auth_failed (proxies.tsv line wrong)\\n- screenshot_black (pane) — use Playwright\\n- timeout\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nproof_run surface=browser_*; screenshots and HAR under R2 `logs/browser/<receipt>/`; receipt page shows them.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| playwright navigate+screenshot | miscsubjects.com/tools | live |\\n| cdp chrome | attach to owner Chrome with the port, read tabs | live or refusal recorded |\\n| cdp adspower | start Default Profile, attach, navigate, stop | live (WT-0458) |\\n| click/type | the /console sign-in page: type nothing sensitive; click a tab | live |\\n| network capture | HAR of one page to R2 | live |\\n| browser-use task | one natural-language task on a public page | live |\\n| url spelling | GET the CONTRACTS link form in the browser (for WT-0472) | live |\\n| extension | one navigate through Claude in Chrome, labelled session-only | 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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"bridges\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/bridges\\\"}`\\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- CDP attach gaps (AdsPower ws missing; Chrome port closed)\\n- pane screenshots black\\n- AdsPower rate limit 1 req/2 s (429/`Too many request`)\\n- AdsPower unreachable from Worker/Google\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0474\\n- OWNS (only this task rewrites): bridge/bridge-browser.mjs; bridge/run_browser_use_task.py; bridge/playwright-mcp-launcher.sh; bridge/adspower*.sh; functions/api/bridges/browser*\\n- SHARED (additive edits only): functions/api/bridges/[[path]].js (WT-0476 owns record/compile; add browser verbs additively); bridge/server.js (WT-0474; add a route only)\\n\\n## HANDOFF FOR NEXT SESSION\\n- AdsPower: profiles list first (`ADSPOWER_PROFILES`), then start → ws → attach; respect 2 s spacing.\\n- Never drive the owner's Chrome tabs visibly except for the one cdp test; close what you open.\\n- Evidence: one receipt per executor id.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Every executor id has a proof_run from that executor (session-only ones labelled).\\n- AdsPower CDP attach works or the exact refusal is a fixture with the raw response (WT-0458 updated either way).\\n- Screenshots/HAR land in R2 and show on the receipt page.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0474\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"bridges\",\"url\":\"https://ops.miscsubjects.com/api/bridges\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "b3a2e3197ccf7d3cfe317bfa32b93c508777169775fb98e78850e49f4c5354ed",
      "hash": "35115528a6921279f5db23b02f7d16a24a46ec55a3d98311238df830053ba3e8"
    },
    {
      "id": 1233,
      "ts": "2026-09-22T19:51:59-07:00",
      "task_id": "WT-0477",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0477\",\"kind\":\"work\",\"objective\":\"WT-0477 Accounts, sessions, AdsPower profiles and delegated (friend / rented) accounts — handles, never authority\",\"detail\":\"# WT-0477 — Accounts, sessions, AdsPower profiles and delegated (friend / rented) accounts — handles, never authority\\n\\n## GOAL\\nEvery account the build can act through (owner accounts, vault credentials, browser profiles, AdsPower profiles with proxies, rented ad accounts, delegated friend accounts) is a stored SESSION HANDLE with an owner, a scope, an expiry and a route, referenced by handle in invocations; a handle never implies authority (WT-0487 decides). Renting an ad account = a friend delegates a profile/session to a tenant for a scope and a time, and every use is receipted.\\n\\n## WHY THIS EXISTS\\nThe owner asked how AdsPower profiles work so people can rent him ad accounts. Today credentials live in the vault (117 lines, CREDS index), AdsPower has one Default Profile, proxies are a TSV, and nothing records who may use which session for what. Sessions and authority are conflated everywhere.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Vault ~/.build-vault.env (CREDS index memory: 117 creds, 12 authed CLIs); ACCESS.md names locations.\\n- AdsPower: Local API (Bearer, 1 req/2 s), bridge/adspower.sh + adspower_profile.conf + proxies.tsv (AdsPower + proxy stack memory); one profile.\\n- LEDGER `capabilities` table: token rows with tenant_id, device_id, fingerprint, scope (authority, WT-0487).\\n- onboard_accounts / text_accounts tables from /api/onboard (2026-09-22).\\n- No `sessions` table; cookies exported by browsers have no home.\\n\\n## SOURCE OF TRUTH\\n- ~/miscsubjects-pages/ACCESS.md\\n- ~/.build-vault.env (values never in chat; names only)\\n- bridge/adspower*.sh, bridge/adspower_profile.conf, bridge/proxies.tsv\\n- functions/_lib/admin_session.js\\n- AdsPower Local API docs\\n\\n## IN-SCOPE INVENTORY\\n- Table `session_handles` (LEDGER DB): handle (id), kind ∈ {vault_cred, cookie_jar, oauth_token, adspower_profile, chrome_profile, phone_line, api_key}, owner_principal, delegated_to (tenant|null), scope (JSON allow list of keys/prefixes), route (JSON: profile id, proxy, device), expires_at, storage_ref (vault name | R2 key encrypted with a KV-held key | AdsPower profile id), created_by, receipts_count.\\n- Verbs: SESSION_LIST, SESSION_MINT (from a browser export, WT-0475 cookies_export), SESSION_DELEGATE {handle, to_tenant, scope, ttl}, SESSION_REVOKE, SESSION_USE (resolver-internal: inject into a physical invocation and receipt it).\\n- AdsPower as routes: ADSPOWER_PROFILE_CREATE {name, proxy (from proxies.tsv line id), fingerprint preset}, ADSPOWER_PROFILE_DELEGATE (= SESSION_DELEGATE with kind adspower_profile), and the rental flow: friend registers a profile under their principal → delegates to the owner's tenant → the owner's runs go through that profile with receipts the friend can read (share link scoped to their handle).\\n- Vault index page (owner-only, behind Access): names + where used + last used; values never rendered.\\n\\n## OUT OF SCOPE\\n- Deciding allow/deny (WT-0487). Driving the browser (WT-0475). Compiling sites (WT-0476). Phone lines' sending (WT-0480).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/dispatch SESSION_* and ADSPOWER_* rows; MCP CAP_MINT (existing) stays for authority\\n- CAPABILITY: SESSION_LIST/MINT/DELEGATE/REVOKE, ADSPOWER_PROFILE_*\\n- OBJECT: a session handle; an AdsPower profile; a proxy line\\n- ROUTE / CONTEXT: which profile + proxy + device the handle binds\\n- PROTOCOL: HTTPS; AdsPower Local API over LAN from the Mac\\n- EXECUTOR: Worker (handles), bridge (AdsPower)\\n- PLATFORM: the build; AdsPower; proxy vendors\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `grep -c \\\"=\\\" ~/.build-vault.env`\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"ADSPOWER_PROFILES\\\"}'`\\n- `sed -n 1,5p ~/miscsubjects-pages/bridge/proxies.tsv | cut -f1,2` (never print the credential columns)\\n\\n## CONTRACT (FIELD LAW)\\n- SESSION_DELEGATE `{handle (required), to_tenant (required, existing tenant id), scope (required, array of keys or prefixes, non-empty), ttl_s (required, 60..7776000), note (optional)}` → `{ok, delegation_id, expires_at, receipt_id}`; conflicts: delegating a handle you do not own → authority_denied; scope wider than the handle's own scope → scope_exceeds_handle.\\n- ADSPOWER_PROFILE_CREATE `{name (required), proxy_line (required, id from proxies.tsv), fingerprint (optional preset id), group (optional)}` → AdsPower `{code:0, data:{id}}` verbatim as return; rate limit honoured (2 s).\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"SESSION_LIST\\\"}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"SESSION_DELEGATE\\\",\\\"body\\\":{\\\"handle\\\":\\\"sh_adspower_default\\\",\\\"to_tenant\\\":\\\"<tenant id from ONBOARD me>\\\",\\\"scope\\\":[\\\"BROWSER_\\\",\\\"BRIDGE_\\\"],\\\"ttl_s\\\":86400,\\\"note\\\":\\\"rented ad account test\\\"},\\\"cause\\\":\\\"task:WT-0477\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\nHTTP 200 + delegation id; AdsPower `{\\\"code\\\":0,\\\"msg\\\":\\\"success\\\"}` or `{\\\"code\\\":-1,\\\"msg\\\":\\\"Too many request per second\\\"}` verbatim.\\n\\n## RAW RETURN SHAPE\\nHandle rows (values never); AdsPower data verbatim.\\n\\n## ERROR SHAPES\\n- authority_denied\\n- scope_exceeds_handle\\n- handle_expired\\n- adspower_rate_limited (code -1)\\n- adspower_unreachable (LAN only; from a Worker it is route_unavailable)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nEvery SESSION_USE is a proof_run child of the delegation receipt; the friend's share link lists them.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| list | SESSION_LIST shows vault names and the AdsPower profile, no values | live |\\n| mint from browser | cookies_export of a build sign-in → handle | live |\\n| delegate | delegate to ONBOARD_DEMO_KEY tenant, scope BROWSER_, 1 h | live |\\n| use | tenant runs BROWSER_SCREENSHOT with the handle → receipt under the delegation | live |\\n| revoke | revoke → next use authority_denied | live |\\n| adspower create | a second profile with a proxies.tsv line | live |\\n| rate limit | two calls < 2 s apart → code -1 recorded | fixture |\\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\\\"}`\\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- AdsPower unreachable from GAS/Worker\\n- AdsPower 1 req/2 s\\n- vault catalog leak 2026-09-19 (values must never render; test that SESSION_LIST output contains no `=`-separated secret)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471, WT-0487\\n- OWNS (only this task rewrites): functions/api/sessions/* (new); migrations/0485_session_handles.sql (new, LEDGER); bridge/adspower*.sh; SESSION_* and ADSPOWER_* rows\\n- SHARED (additive edits only): functions/_lib/admin_session.js (WT-0487; call its allow/deny, add nothing); functions/_lib/resolver.js (WT-0471; SESSION_USE hook is additive)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Never print a vault value; the leak test is a deploy gate (scripts/check-vault-render.mjs exists from 2026-09-19 — extend it to the new door).\\n- AdsPower calls go through the Mac bridge; from a Worker they are route_unavailable by design.\\n- The rental demo uses the demo tenant (vault ONBOARD_DEMO_KEY).\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- session_handles exists and every account kind has ≥ 1 handle.\\n- Delegate → use → revoke proven with receipts.\\n- AdsPower profile create + delegate proven; rate limit fixture passes.\\n- No value renders anywhere (gate).\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\",\"WT-0487\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "bf4a5ba9fefbe073a553f911a18fc3b77c070d89d5a9f3191742f0387a3ba0c9",
      "hash": "b3a2e3197ccf7d3cfe317bfa32b93c508777169775fb98e78850e49f4c5354ed"
    },
    {
      "id": 1232,
      "ts": "2026-09-22T19:51:57-07:00",
      "task_id": "WT-0483",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0483\",\"kind\":\"work\",\"objective\":\"WT-0483 Storage / data plane — D1, the build workbook, cells/objects, R2, KV, Supabase/Hyperdrive; every value is a cell with a contract\",\"detail\":\"# WT-0483 — Storage / data plane — D1, the build workbook, cells/objects, R2, KV, Supabase/Hyperdrive; every value is a cell with a contract\\n\\n## GOAL\\nEvery data capability (D1_QUERY/D1_EXEC on both databases, the build workbook doors /api/sheets and cells/objects, R2 objects, KV, Supabase through Hyperdrive, the CSV/TSV exports) has a full contract with FIELD LAW, runs through its declared executor with the five fields, and the size and split fixtures (>50,000-char cell, 400-cell PUT, `;` splitter, LIKE `_`) are tests.\\n\\n## WHY THIS EXISTS\\nThe owner's workbook is the product surface (\\\"every value is a cell\\\"; data goes on sheets raw). Sessions kept hitting cell limits, statement splits and governed-table refusals and each time learned it again. Data doors need contracts the four models can read.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- /api/sheets: build workbook; PUT values ≤ 400 cells; `=DISPATCH(\\\"KEY\\\",\\\"args\\\")` formulas; sheets sh_nyab2cgy, sh_ahznwfyd, others; /api/cells, /api/objects (OBJECT_READ/OBJECT_MUTATE with current_hash; STALE → retry).\\n- D1: main DB (directory, laws, work_tasks…) and LEDGER DB (events, capabilities…); governed tables refuse raw writes (articles, article_slots, work_tasks, work_actions); D1_REPAIR with a stated reason.\\n- R2: logs/, cache/ (muse-worker cache/build_tools.json), assets; KV: settings/switchboard; Supabase + Hyperdrive provisioned (kernel stack memory), binding needs a fetch handler.\\n- Exports: directory export to ~/Downloads and TOOLS tabs (2026-09-19).\\n\\n## SOURCE OF TRUTH\\n- functions/api/sheets/*, functions/api/cells/*, functions/api/objects/*\\n- functions/_lib/governed_tables.js\\n- functions/api/r2/*, functions/api/kv.js\\n- migrations/* (schema)\\n- memory project_kernel_stack_2026_09_20 (Supabase ids)\\n\\n## IN-SCOPE INVENTORY\\n- Executor ids: d1_main, d1_ledger, sheets_api, cells_api, objects_api, r2_api, kv_api, supabase_hyperdrive, export_file.\\n- Contracts: D1_QUERY {db, sql (single statement), params?}; D1_EXEC {db, sql, reason? (required for D1_REPAIR)}; SHEETS_GET {sheet, range (A1, ≤ 100 rows × 26 cols per call)}; SHEETS_PUT {sheet, range, values (≤ 400 cells; each cell ≤ 50,000 chars; formulas allowed)}; SHEETS_APPEND; OBJECT_READ {path} → {content, hash}; OBJECT_MUTATE {path, current_hash, content} (STALE → current_hash + current_content returned); R2_GET/PUT/LIST {bucket, key, prefix}; KV_GET/PUT {ns, key, ttl?}; SUPABASE_QUERY {sql} via Hyperdrive; EXPORT_TSV {source, path}.\\n- Fixtures: >50,000-char cell (refused with the limit named; canonical keeps whole in R2); >400 cells; `;` split; LIKE `_`; governed_table 403; STALE retry; R2 cache stale when cron is off (muse-worker).\\n\\n## OUT OF SCOPE\\n- The six-column projection logic (WT-0473). Authority on who may write (WT-0487).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: dispatch D1_*/SHEETS_*/OBJECT_*/R2_*/KV_*; MCP D1_QUERY/OBJECT_READ/OBJECT_MUTATE; cell formulas; misc line\\n- CAPABILITY: the verbs above\\n- OBJECT: a row, a cell range, an object path, an R2 key, a KV key\\n- ROUTE / CONTEXT: main vs ledger DB; which sheet; which bucket\\n- PROTOCOL: SQL over HTTP; Worker bindings; Hyperdrive Postgres\\n- EXECUTOR: Worker bindings; Supabase via Hyperdrive\\n- PLATFORM: Cloudflare D1/R2/KV; Supabase\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/sheets\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"` (sheet list)\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"D1_QUERY\\\",\\\"body\\\":\\\"SELECT name FROM sqlite_master WHERE type=\\\\\\\"table\\\\\\\" LIMIT 5\\\"}'`\\n\\n## CONTRACT (FIELD LAW)\\n- SHEETS_PUT `{sheet (required, sh_… id), range (required A1 notation), values (required 2-D array; total cells ≤ 400; cell ≤ 50,000 chars; string|number|bool|null|\\\"=FORMULA\\\")}` → `{ok, wrote_cells, receipt_id}`; errors too_many_cells (names 400), cell_too_long (names 50,000 and the receipt where the whole value is stored), sheet_not_found.\\n- D1_EXEC `{db (enum main|ledger, default main), sql (single statement), reason (conditional: required when the table is governed → routes to D1_REPAIR)}`.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS \\\"https://ops.miscsubjects.com/api/sheets/sh_nyab2cgy?range=A1:F2\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X PUT \\\"https://ops.miscsubjects.com/api/sheets/sh_ahznwfyd/values?range=A1:B2\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"values\\\":[[\\\"=DISPATCH(\\\\\\\"NET_LINE\\\\\\\",\\\\\\\"\\\\\\\")\\\",\\\"literal\\\"],[1,true]],\\\"cause\\\":\\\"task:WT-0483\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\n`{ok:true, wrote_cells:n}`; D1 `{meta:{changes, last_row_id, duration}}`; R2 `{etag}`; KV `{ok}`; objects `{hash}`.\\n\\n## RAW RETURN SHAPE\\nRows/values verbatim; formula results after evaluation; object content + hash.\\n\\n## ERROR SHAPES\\n- too_many_cells\\n- cell_too_long\\n- statement_split\\n- governed_table (403, names D1_REPAIR)\\n- STALE (with current_hash/current_content)\\n- hyperdrive_unbound\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nproof_run per call; big values stored whole in R2 `logs/values/<receipt>` and referenced by the cut cell.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| d1 both dbs | one SELECT each | live |\\n| governed refusal | INSERT INTO work_tasks via D1_EXEC → 403 naming D1_REPAIR | fixture |\\n| sheets get/put/append | scratch sheet | live |\\n| 400 cells | 401 cells → too_many_cells | fixture |\\n| 50,000 chars | a 60,000-char value → cell_too_long + R2 whole | fixture |\\n| formula | =DISPATCH cell evaluates | live |\\n| objects | OBJECT_READ → OBJECT_MUTATE with a wrong hash → STALE → retry ok | live |\\n| r2/kv | get/put/list one each | live |\\n| supabase | one SELECT 1 through Hyperdrive or the exact unbound error | live/fixture |\\n| export | directory TSV to ~/Downloads | 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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"sheets\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/sheets\\\"}`\\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- >50,000-char cell\\n- 400-cell PUT\\n- D1 `;` splitter\\n- SQLite LIKE `_`\\n- governed_table refusal\\n- STALE hash\\n- R2 cache stale with cron off\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471\\n- OWNS (only this task rewrites): functions/api/sheets/*, functions/api/cells/*, functions/api/objects/*, functions/api/r2/*, functions/api/kv.js; D1_*/SHEETS_*/OBJECT_*/R2_*/KV_*/SUPABASE_*/EXPORT_* rows\\n- SHARED (additive edits only): functions/_lib/governed_tables.js (read; never widen); migrations/* (add only new numbered files)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Work in the scratch sheet sh_ahznwfyd for write tests; never write test values into sh_nyab2cgy.\\n- Supabase: if the binding still lacks a fetch handler, record the exact error as the fixture and file WT for the handler.\\n- Evidence: matrix table with receipts.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Every executor id has a receipt; every verb has a contract with FIELD LAW.\\n- All seven fixtures are tests and pass.\\n- Big values are whole in R2 and cut in cells with the pointer.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"sheets\",\"url\":\"https://ops.miscsubjects.com/api/sheets\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "1bdcc3ddcfd9cdefa64aea9d856bbe1572c8ae5509818e69c01e4002c2fb0564",
      "hash": "bf4a5ba9fefbe073a553f911a18fc3b77c070d89d5a9f3191742f0387a3ba0c9"
    },
    {
      "id": 1231,
      "ts": "2026-09-22T19:51:56-07:00",
      "task_id": "WT-0481",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0481\",\"kind\":\"work\",\"objective\":\"WT-0481 Cloudflare plane — Code Mode MCP, API token minting, D1/KV/R2/Workers, Workers for Platforms; token failures as fixtures\",\"detail\":\"# WT-0481 — Cloudflare plane — Code Mode MCP, API token minting, D1/KV/R2/Workers, Workers for Platforms; token failures as fixtures\\n\\n## GOAL\\nEvery Cloudflare capability the build uses (the Cloudflare API through minted tokens, Code Mode MCP with its 3 tools, D1_QUERY/D1_EXEC, KV, R2, Workers list/get/upload, Pages deploy, Workers for Platforms dispatch namespaces, Access service tokens, the 14 Cloudflare MCP servers) has a contract, runs through its declared executor with the five fields, and the token-list auth failure and the deploy permission gate are fixtures.\\n\\n## WHY THIS EXISTS\\nThe owner asked which Cloudflare tokens are which (mint token, full token, account). Sessions hit `wrangler deploy` permission gates and token-list 403s repeatedly. The four Code-Mode models must see Cloudflare as contracts, not as a memory of which token worked.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Tokens: CLOUDFLARE_MINT_TOKEN (mints others) + scripts/cf-mint-token.mjs; CF_API_TOKEN (full); account id in the vault; token list endpoint 403 for a minted token (fixture).\\n- Code Mode MCP: 3 tools (docs/search/execute) on the aggregate server; `||` breaks on the MCP-tool path (memory).\\n- Cloudflare MCP servers: 14 skills, 188 tools, 181 directory rows via CF_API_TOKEN (2026-09-21).\\n- Workers for Platforms: gate wfp-gate (DISPATCHER=production, DISPATCHER_STAGING=staging), custom domain gate.miscsubjects.com; scripts/wfp-tenant.mjs, scripts/cf-tenant.mjs; functions/_lib/wfp_worker.js (uploadScript, provisionTenantWorker).\\n- Deploy: `node scripts/ship.mjs` only; `wrangler deploy` blocked by the auto-mode classifier (memory: name the one command).\\n- functions/_lib/cf_account.js (GraphQL analytics).\\n\\n## SOURCE OF TRUTH\\n- scripts/cf-mint-token.mjs, scripts/cf-tenant.mjs, scripts/wfp-tenant.mjs\\n- functions/_lib/wfp_worker.js, functions/_lib/cf_account.js\\n- ~/codemode-mcp/src (the Code Mode MCP product)\\n- Cloudflare API docs via the CF_MAIN_DOCS/CF_MAIN_SEARCH rows\\n\\n## IN-SCOPE INVENTORY\\n- Executor ids: cf_api (REST with a named token), cf_codemode (Code Mode execute), cf_mcp_<server> (the 14 servers), cf_d1_binding (D1_QUERY/D1_EXEC in-Worker), cf_kv_binding, cf_r2_binding, cf_wfp_dispatch (tenant Worker), cf_pages_deploy (ship.mjs).\\n- Token contract table `cf_tokens` (names only; values in the vault): name, purpose, scopes (from /user/tokens/verify), can_list_tokens (bool, measured), expires_at, minted_by.\\n- Verbs: CF_TOKEN_VERIFY {name}, CF_TOKEN_MINT {name, scopes[], ttl} (via the mint token), CF_WORKERS_LIST, CF_WORKER_GET {name}, CF_D1_QUERY {db, sql}, CF_KV_GET/PUT, CF_R2_LIST/GET/PUT, CF_WFP_UPLOAD {namespace, name, script}, CF_ACCESS_SERVICE_TOKENS_LIST, CF_ANALYTICS {graphql}.\\n- Fixtures: token list 403 with a minted token (verify works, list does not — record both); wrangler deploy classifier block (the one command is `node scripts/ship.mjs`); `||` in Code Mode execute; D1 statement splitter cutting on `;`; SQLite LIKE `_`.\\n\\n## OUT OF SCOPE\\n- The build's own deploy pipeline changes (governed). Tenant onboarding (WT-0488). Model configuration (WT-0482).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: dispatch CF_* rows; MCP CF_MAIN_DOCS/CF_MAIN_SEARCH/CF_MAIN_EXECUTE and the 14 servers; misc line; cell\\n- CAPABILITY: the verbs above\\n- OBJECT: a token, a Worker, a database, a bucket, a namespace, a tenant script\\n- ROUTE / CONTEXT: account id + token name + namespace (staging|production)\\n- PROTOCOL: HTTPS REST, GraphQL, MCP JSON-RPC, Worker bindings\\n- EXECUTOR: Worker (bindings), Worker fetch to api.cloudflare.com, Code Mode sandbox, ship.mjs on the Mac\\n- PLATFORM: Cloudflare\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `node scripts/cf-mint-token.mjs --help`\\n- `curl -sS \\\"https://api.cloudflare.com/client/v4/user/tokens/verify\\\" -H \\\"Authorization: Bearer $CF_API_TOKEN\\\"` (`grep '^CF_API_TOKEN=' ~/.build-vault.env`)\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"CF_MAIN_SEARCH\\\",\\\"body\\\":{\\\"q\\\":\\\"dispatch namespace\\\"}}'`\\n\\n## CONTRACT (FIELD LAW)\\n- CF_TOKEN_MINT `{name (required, unique), scopes (required, array of permission group ids), ttl_days (optional 1..365, default 30), resources (optional account/zone map)}` → Cloudflare `{success, result:{id, value (stored to the vault by the script, never returned in the return field), expires_on}}` — the return field carries `value: \\\"<stored in vault as NAME>\\\"`.\\n- CF_D1_QUERY `{db (enum main|ledger), sql (required, one statement; `;` splits — refuse multi-statement with statement_split)}`; CF_WFP_UPLOAD `{namespace (enum), name, script (≤ 1 MB), bindings?}`.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"CF_TOKEN_VERIFY\\\",\\\"body\\\":{\\\"name\\\":\\\"CF_API_TOKEN\\\"}}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`node scripts/cf-mint-token.mjs --name wt0481-test --scopes \\\"Workers Scripts Read\\\" --ttl-days 1 --store` (mints with CLOUDFLARE_MINT_TOKEN, stores the value in the vault as CF_TOKEN_WT0481_TEST, prints only the name)\\n\\n## RAW CONFIRMATION SHAPE\\nCloudflare `{\\\"success\\\":true,\\\"errors\\\":[],\\\"messages\\\":[]}` + HTTP status; binding calls return `{meta:{changes, duration}}`; MCP tool result envelope.\\n\\n## RAW RETURN SHAPE\\nCloudflare `result` verbatim (secrets redacted to vault names); D1 rows; R2 keys; Worker metadata.\\n\\n## ERROR SHAPES\\n- 403 `Authentication error` on /user/tokens (list) with a minted token — fixture\\n- 9109 invalid access token\\n- statement_split\\n- classifier block on wrangler deploy — use ship.mjs\\n- Code Mode `||` parse failure — use `? :`\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nproof_run surface=cf_*; token operations receipted with the token NAME.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| verify each token | CF_API_TOKEN, CLOUDFLARE_MINT_TOKEN, each Access token → scopes recorded in cf_tokens | live |\\n| mint | 1-day token, stored, verified, then deleted | live |\\n| list tokens 403 | with the minted token → the exact 403 recorded | fixture |\\n| workers list/get | 16 Workers | live |\\n| d1 query both dbs | one SELECT each | live |\\n| kv/r2 | one get/put/list each | live |\\n| wfp upload | tenant-demo script to staging namespace | live |\\n| codemode execute | one script through CF_MAIN_EXECUTE | live |\\n| 14 servers | one tool each through /api/mcp | live |\\n| graphql | one analytics query | 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\\\"}`\\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- Cloudflare token-list auth failure\\n- wrangler deploy permission gate\\n- Code Mode `||`\\n- D1 `;` splitter\\n- SQLite LIKE `_`\\n- stale workers.dev hosts\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471\\n- OWNS (only this task rewrites): scripts/cf-mint-token.mjs, scripts/cf-tenant.mjs, scripts/wfp-tenant.mjs; functions/_lib/wfp_worker.js, functions/_lib/cf_account.js; CF_* rows; migrations/0486_cf_tokens.sql (new); ~/codemode-mcp\\n- SHARED (additive edits only): functions/api/mcp.js (WT-0472; the 14 servers are rows, not code); scripts/ship.mjs (governed; never changed here)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Token values never in returns, receipts or chat; names only.\\n- The deploy is always `node scripts/land.mjs`; if a classifier blocks, that is the fixture, not a reason to stop.\\n- Evidence: the cf_tokens table dump (names/scopes) + receipts.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- cf_tokens holds every token name with measured scopes.\\n- Every executor id has a receipt; the 403 fixture is recorded.\\n- Contracts for all CF_* rows in capability_contracts.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "ed8050823e043a83b525eef338a6ac96336982713ca519778a0c99e0f1e0ded5",
      "hash": "1bdcc3ddcfd9cdefa64aea9d856bbe1572c8ae5509818e69c01e4002c2fb0564"
    },
    {
      "id": 1230,
      "ts": "2026-09-22T19:51:55-07:00",
      "task_id": "WT-0478",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0478\",\"kind\":\"work\",\"objective\":\"WT-0478 Edge nodes, Starlink and network plane — egress as a declared ROUTE, the dish as a tool\",\"detail\":\"# WT-0478 — Edge nodes, Starlink and network plane — egress as a declared ROUTE, the dish as a tool\\n\\n## GOAL\\nEvery network path the build can use (the Worker's egress, the owner Mac on Starlink, quick tunnels, tenant devices, proxies, CF containers) is a declared ROUTE with a contract; /api/net (ip/line/search/fetch/scrape) and STARLINK_* rows run through their declared executor with the five fields; the Starlink dish is a first-class model tool (status, history, obstruction, reboot) with receipts.\\n\\n## WHY THIS EXISTS\\nA previous session gave the owner Starlink as a model tool but hidden. He wants it explicit: which line a request left from, what the dish said, and a contract for each. Webhooks from outside hosts and the DNS/stale-host failures need the network axis recorded, not guessed.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- /api/net: ip | line | search (engines default ddg, mojeek; exa opt-in) | fetch | scrape from the Starlink line via the bridge (bridge/bridge-run.py net()); rows NET_LINE, NET_SEARCH, WEB_SEARCH, NET_FETCH.\\n- Starlink Mini mini1_pez_proto1, consumer plan, dish gRPC 192.168.100.1:9200 (grpcurl installed), CGNAT IPv4 98.97.25.17, public IPv6 /56, location disabled by policy; rows STARLINK_STATUS/HISTORY/OBSTRUCTION/REBOOT via ~/bin/starlink-api (parallel lane).\\n- Tunnels: agent.miscsubjects.com (Mac bridge), quick tunnels for tenant devices (tenant_devices.endpoint).\\n- CF containers: CLOUD_EXEC/CLOUD_EXEC_IN/CLOUD_HEALTH/CLOUD_WORKSPACE_NEW rows.\\n- Proxies: bridge/proxies.tsv, bridge/proxycheck.sh.\\n\\n## SOURCE OF TRUTH\\n- functions/api/net/*\\n- bridge/bridge-run.py (net, line)\\n- ~/bin/starlink-api and bridge/starlink-api\\n- functions/_lib/tenant_devices.js (endpoints)\\n- Starlink gRPC reflection: `grpcurl -plaintext 192.168.100.1:9200 list`\\n\\n## IN-SCOPE INVENTORY\\n- ROUTE enum for physical.route.egress: worker (Cloudflare edge, colo recorded), mac_starlink (98.97.25.17 / IPv6), proxy:<line id>, tenant_device:<id>, cf_container:<id>. Every executor records which one it used (NET_LINE proves it: return.ip).\\n- Verbs with contracts: NET_IP, NET_LINE (dish summary + egress), NET_SEARCH {q, engines[], n}, NET_FETCH {url, headers?, method?, body?, egress}, NET_SCRAPE {url, selector|markdown}, STARLINK_STATUS, STARLINK_HISTORY, STARLINK_OBSTRUCTION, STARLINK_REBOOT (send-effect; owner key only; never in a batch), TUNNEL_STATUS (each tunnel: up/down, last seen), PROXY_CHECK {line id} (egress ip + latency).\\n- Webhook-from-outside: NET_FETCH with egress=mac_starlink POSTing to /api/hooks/<id> proves an outside host reached the build (used by WT-0472 webhook spelling).\\n- Fixtures: DNS failure (nonexistent.invalid) isolated; stale host (retired workers.dev) → route_unavailable with raw error; dish unreachable when the Mac is off-LAN → raw grpc error.\\n\\n## OUT OF SCOPE\\n- Browser egress binding (WT-0475 uses proxy lines; this task defines them). Tenant onboarding of devices (WT-0488).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/net/<op>; dispatch NET_*/STARLINK_*; MCP NET_LINE/NET_SEARCH/WEB_SEARCH/STARLINK_STATUS; misc line; cell\\n- CAPABILITY: the verbs above\\n- OBJECT: a URL, a query, the dish, a tunnel, a proxy line\\n- ROUTE / CONTEXT: the egress enum\\n- PROTOCOL: HTTPS; gRPC (dish); tunnel\\n- EXECUTOR: bridge on the Mac (Starlink), the Worker (edge), a container\\n- PLATFORM: Starlink; Cloudflare; proxy vendors\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"NET_LINE\\\"}'`\\n- `grpcurl -plaintext -d '{\\\"get_status\\\":{}}' 192.168.100.1:9200 SpaceX.API.Device.Device/Handle` (from the Mac on the Starlink LAN)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/net\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n\\n## CONTRACT (FIELD LAW)\\n- NET_FETCH `{url (required), method (optional, GET|POST|PUT|DELETE, default GET), headers (optional object), body (optional; conditional on method ≠ GET), egress (optional enum, default mac_starlink), timeout_ms (default 30000)}` → `{physical:{egress, ip}, confirmation:{status, headers, ms}, return:{body (≤ 200,000), content_type}}`.\\n- STARLINK_REBOOT `{confirm (required, literal \\\"REBOOT\\\")}` — owner key only; refused with `confirm_required` otherwise; never eligible for CONTRACTS batch (policy read-set excludes it).\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"NET_LINE\\\"}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"NET_FETCH\\\",\\\"body\\\":{\\\"url\\\":\\\"https://ops.miscsubjects.com/api/hooks/<hook id from /api/hooks>\\\",\\\"method\\\":\\\"POST\\\",\\\"headers\\\":{\\\"content-type\\\":\\\"application/json\\\"},\\\"body\\\":\\\"{\\\\\\\"from\\\\\\\":\\\\\\\"starlink\\\\\\\"}\\\",\\\"egress\\\":\\\"mac_starlink\\\",\\\"timeout_ms\\\":20000},\\\"cause\\\":\\\"task:WT-0478\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\n`confirmation:{status, headers, ms}` with `physical.egress` and the observed public IP; dish: grpc status OK / UNAVAILABLE verbatim.\\n\\n## RAW RETURN SHAPE\\nBody verbatim; dish JSON verbatim (uptime, downlink/uplink throughput, obstruction fraction, pop ping).\\n\\n## ERROR SHAPES\\n- ENOTFOUND (DNS) — row-level\\n- route_unavailable (Mac off, tunnel down)\\n- grpc UNAVAILABLE (dish off-LAN)\\n- confirm_required (reboot)\\n- engine_error per search engine (others still answer)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nproof_run with physical.route.egress; NET_LINE receipts show the IP; hook receipts show the source IP.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| line | NET_LINE returns ip 98.97.25.17 or the IPv6 and dish summary | live |\\n| fetch from starlink | NET_FETCH to https://ops.miscsubjects.com/api/net/ip → ip matches | live |\\n| fetch from worker | egress=worker → a Cloudflare colo IP | live |\\n| search | NET_SEARCH q=\\\"miscsubjects\\\" n=3 with per-engine results | live |\\n| dish status/history/obstruction | three receipts | live |\\n| reboot refusal | without confirm → confirm_required | live |\\n| tunnel status | agent.miscsubjects.com up | live |\\n| proxy check | one proxies.tsv line → egress ip differs from 98.97.25.17 | live |\\n| dns isolate | nonexistent.invalid → ENOTFOUND row | fixture |\\n| webhook from outside | POST to a hook from mac_starlink → hook receipt source ip | 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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"net\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/net\\\"}`\\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- DNS failure stopping a batch\\n- stale hosts / stale webhook hosts\\n- Exa default injected without request (engines default must stay ddg,mojeek)\\n- STARLINK_REBOOT in a batch (must be excluded by the read-set policy)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471\\n- OWNS (only this task rewrites): functions/api/net/*; bridge/bridge-run.py (net, line); bridge/starlink-api, ~/bin/starlink-api; bridge/proxycheck.sh; NET_*, STARLINK_*, TUNNEL_STATUS, PROXY_CHECK rows\\n- SHARED (additive edits only): functions/_lib/resolver.js (WT-0471; egress is a route field it passes through); functions/api/hooks/* (call only; WT-0485 owns hook receipts)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Never run STARLINK_REBOOT during work; the refusal test is enough. If the owner asks for a reboot, run once with confirm.\\n- Location is disabled by dish policy; do not try to enable it.\\n- Evidence: the egress table (route → observed IP) with receipts.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Every egress route has a receipt showing its observed IP.\\n- All four dish verbs have contracts and receipts (reboot: refusal receipt).\\n- DNS/stale-host fixtures pass in the runner (WT-0473 imports them).\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"net\",\"url\":\"https://ops.miscsubjects.com/api/net\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2c09f5f6986457b25d1d7419247ae44215e9010a750d34e40fea00aa7b0ccb69",
      "hash": "ed8050823e043a83b525eef338a6ac96336982713ca519778a0c99e0f1e0ded5"
    },
    {
      "id": 1229,
      "ts": "2026-09-22T19:51:54-07:00",
      "task_id": "WT-0474",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0474\",\"kind\":\"work\",\"objective\":\"WT-0474 Local Mac plane — /exec bridge, Apple surface layers, locked-session and hang fixtures\",\"detail\":\"# WT-0474 — Local Mac plane — /exec bridge, Apple surface layers, locked-session and hang fixtures\\n\\n## GOAL\\nEvery local Mac capability (shell via the bridge, AppleScript/JXA app scripting, App Intents, Shortcuts, UI scripting/accessibility, menus, `defaults`, screen mirror/screenshot, files, clipboard, local-only APIs) has a full contract, runs through its declared executor with the five proof fields, and the known Mac failure modes are fixtures with their exact raw returns.\\n\\n## WHY THIS EXISTS\\nThe Apple surface encyclopedia has 8,913 verbs across layers, most catalogued from documentation and run once with `--help` or an observe-only read. The owner wants the Mac click proven as a Mac click: the executor that actually ran, its exit code, its output, and the reason when the Mac was locked or a Shortcut hung.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Bridge: bridge/server.js on the owner Mac behind agent.miscsubjects.com (POST /exec; device auth in bridge/device_auth.js; called by functions/_lib/mac_bridge.js). LOCAL_EXEC lands on the Mac or a CF container call by call (project memory).\\n- bridge/surface-run.py + bridge/surface-verbs.py: layer runners (JXA wrapper returns last statement; mirror screenshot takes a file path).\\n- Layers and counts (2026-09-23 inventories in /tmp/claude-501/contracts/surface_*.json): app_scripting, cli_tools, ui_scripting, defaults_domains, app_intents, shortcuts_actions, shortcuts_triggers, iphone_device, private_imessage, continuity, observation_points, composed, build_rows.\\n- Known: locked Mac → System Events `AppleEvent timed out (-1712)` (58 rows carry it); `shortcuts run` hangs (WT-0442); menu/mirror taps skipped by policy; ui_scripting ax reads only.\\n- Doors: /api/surface (execute/compose/search/layers/verbs/spec/run?id=&args=&share=), /api/apple, /api/term, LOCAL_EXEC row, SURFACE_EXECUTE MCP tool.\\n\\n## SOURCE OF TRUTH\\n- bridge/server.js, bridge/surface-run.py, bridge/surface-verbs.py, bridge/apple_layers.js, bridge/apple_data.py\\n- functions/api/surface/*, functions/api/apple/*, functions/_lib/mac_bridge.js\\n- `GET https://ops.miscsubjects.com/api/surface/spec` (machine spec: ids + run blocks)\\n- bridge/launchd/* (which agents run on the Mac and when)\\n\\n## IN-SCOPE INVENTORY\\n- Executors, each an id in proof_runs.surface: mac_exec (sh via /exec), mac_osascript_jxa, mac_osascript_as, mac_shortcuts_cli, mac_shortcuts_url (shortcuts://run-shortcut?name=), mac_app_intent (via Shortcuts action or `open` URL), mac_ax (accessibility read), mac_ax_click (UI click — requires unlocked session + Accessibility grant), mac_defaults, mac_screenshot (screencapture -x), mac_mirror (iPhone Mirroring window), mac_open (open -a / open <url>), mac_clipboard, mac_launchd.\\n- Contract per verb: spec block from /api/surface/spec/<id> extended with FIELD LAW (args, types, defaults, requires_unlocked, requires_grant ∈ {accessibility, screen_recording, automation:<app>}, side_effect ∈ {read, write, send}).\\n- Session-state probe verb MAC_SESSION_STATE (locked/unlocked, frontmost app, grants present) run before any verb that requires unlocked, so the reason is recorded, not guessed.\\n- Fixtures: -1712 while locked; shortcuts run hang (60 s watchdog, verbatim); `--help` exit 127/1/2/255 as honest results; local-only API (Local Network only, e.g., local.adspower.net) not reachable from Google/Worker.\\n\\n## OUT OF SCOPE\\n- iPhone (WT-0479) except the Mirroring window; browsers (WT-0475); messaging apps' sends (WT-0480); Starlink dish gRPC (WT-0478).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/surface (execute), POST /api/dispatch key LOCAL_EXEC, MCP SURFACE_EXECUTE / LOCAL_EXEC, the misc line, the sheet cell\\n- CAPABILITY: each surface verb id (v_…) and LOCAL_EXEC\\n- OBJECT: an app, a file, a window, a shortcut, a defaults domain\\n- ROUTE / CONTEXT: owner Mac (device id owner-mac), locked vs unlocked session, which user\\n- PROTOCOL: HTTPS to the bridge → local process (sh, osascript, shortcuts, screencapture)\\n- EXECUTOR: bridge/server.js child process\\n- PLATFORM: Apple macOS 26 (Darwin 25.6.0)\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/surface/search?q=screenshot\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/surface/verbs/v_c21e59bd90\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"` (the `open` verb)\\n- `curl -sS -X POST https://agent.miscsubjects.com/exec -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"cmd\\\":\\\"uname -a\\\"}'`\\n\\n## CONTRACT (FIELD LAW)\\n- POST /api/surface `{id (required, verb id), args (object per verb spec; required keys per spec), device (optional, default owner-mac), timeout_ms (optional, default 60000, max 600000), cause}`. Response `{ok, id, physical:{executor, argv|script, cwd, env_keys}, confirmation:{pid, exit, signal, ms, started_at}, return:{stdout, stderr, files:[…]}, receipt_id}`.\\n- LOCAL_EXEC body `{cmd (required string), cwd?, env?, stdin?, timeout_ms?}`; conflicts: none; omission of timeout = 60 s.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"LOCAL_EXEC\\\",\\\"body\\\":{\\\"cmd\\\":\\\"uname -a\\\"}}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/surface -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"id\\\":\\\"v_c21e59bd90\\\",\\\"args\\\":{\\\"target\\\":\\\"/Users/the owner/Downloads/HANDOFF-2026-09-23-contracts.md\\\",\\\"app\\\":\\\"TextEdit\\\"},\\\"device\\\":\\\"owner-mac\\\",\\\"timeout_ms\\\":20000,\\\"cause\\\":\\\"task:WT-0474\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\n`confirmation:{pid:<n>, exit:0, ms:<n>}`; for a hang: `{pid, exit:null, signal:\\\"SIGKILL\\\", ms:60000, reason:\\\"watchdog\\\"}`; for a locked session: `{exit:1, stderr:\\\"execution error: System Events got an error: AppleEvent timed out. (-1712)\\\"}`.\\n\\n## RAW RETURN SHAPE\\nstdout/stderr verbatim; file outputs (screenshots) uploaded to R2 with the URL in return.files and the receipt.\\n\\n## ERROR SHAPES\\n- -1712 (locked)\\n- shortcuts hang (watchdog)\\n- `osascript: not authorized to send Apple events` (Automation grant missing — name the grant, never ask the owner; record it)\\n- exit 127 (binary missing; the honest result)\\n- bridge 522/timeout (Mac asleep or tunnel down — route_unavailable)\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nproof_run surface=mac_*; receipt page shows argv, exit, stdout; screenshot files linked.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| exec | uname -a | live |\\n| jxa read | running apps list (unlocked) and the -1712 (locked) both recorded | live+fixture |\\n| shortcuts | run a no-op Shortcut via CLI and via shortcuts:// URL; hang recorded verbatim if it hangs | live |\\n| ax read | frontmost window title | live |\\n| ax click | click a menu item in TextEdit with the grant | live |\\n| defaults | read com.apple.dock orientation | live |\\n| screenshot | screencapture to file → R2 URL | live |\\n| open | open a file in TextEdit | live |\\n| session probe | MAC_SESSION_STATE returns locked|unlocked | live |\\n| help not proof | a cli_tools row with `--help` exit 0 has state=discovered, not proven | fixture |\\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\\\": \\\"http_ok\\\", \\\"id\\\": \\\"spec\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/surface/spec\\\"}`\\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- locked-Mac JXA -1712\\n- `shortcuts run` hang (WT-0442)\\n- `--help` not proof\\n- local-only APIs unreachable from Worker/Google\\n- simulator vs physical device confusion (Mirroring window is the phone; the Simulator is not)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471\\n- OWNS (only this task rewrites): bridge/server.js; bridge/surface-run.py; bridge/surface-verbs.py; bridge/apple_layers.js; bridge/apple_data.py; functions/api/surface/*; functions/api/apple/*; functions/_lib/mac_bridge.js; bridge/launchd/*\\n- SHARED (additive edits only): public/device-kit/* (synced copies of bridge files — run scripts/device-kit-sync.mjs after any bridge change; WT-0488 owns the kit's docs)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Never open windows on the owner screen unless the verb under test needs it; TextEdit open/close is allowed for the ax-click test and must be closed after.\\n- WT-0442 (shortcuts hang) is open; if you fix it, submit that task too; if not, the hang stays a recorded result.\\n- Bridge changes need `bash bridge/install-bridge.sh` or the launchd reload; verify with the exec test before submitting.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Every executor id above has at least one proof_run from its own executor.\\n- MAC_SESSION_STATE exists and every requires_unlocked verb records it.\\n- The four fixtures are tests in bridge/*.test.mjs and pass.\\n- The surface spec carries FIELD LAW for the 74 hot verbs + every verb the Mac matrix ran.\\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\",\"priority\":3,\"depends_on\":[\"WT-0470\",\"WT-0471\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"http_ok\",\"id\":\"spec\",\"url\":\"https://ops.miscsubjects.com/api/surface/spec\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "5c9c495265c2ebd801a7eb686233d2f2bf54bdd3c0054c01bb4128d9b03e7132",
      "hash": "2c09f5f6986457b25d1d7419247ae44215e9010a750d34e40fea00aa7b0ccb69"
    },
    {
      "id": 1228,
      "ts": "2026-09-22T19:51:53-07:00",
      "task_id": "WT-0472",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0472\",\"kind\":\"work\",\"objective\":\"WT-0472 Invocation Surface Compiler — every spelling runs as its own surface and proves itself\",\"detail\":\"# WT-0472 — Invocation Surface Compiler — every spelling runs as its own surface and proves itself\\n\\n## GOAL\\nFor every Directory row, compile every spelling (curl, named POST, link URL, JSON-RPC/MCP tools/call, Claude Code MCP config, misc line, console_app CLI, line grammar, tag, Shortcut, webhook, upstream, `=DISPATCH()` cell) so that each spelling is executed BY THAT SURFACE (a real MCP client for JSON-RPC, a real Shortcut run for shortcut, a browser GET for the link, the console-app binary for console_app, the sheet engine for the cell) and each records its own five proof fields. A spelling is proven only by that spelling.\\n\\n## WHY THIS EXISTS\\nfunctions/_lib/invocation_methods.js compiles 12 spellings per row and the CONTRACTS ways run (962 rows for 74 tools, 2026-09-23) executed most of them from the session shell — a curl typed by the model proves curl, not MCP or Shortcut. The owner wants the totality of the directory proven per surface: iPhone tap, Mac click, bash via API, link.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- functions/_lib/invocation_methods.js (1,013 lines): methodsFor(row) → 12 spellings; `how_to_call` on GET /api/directory/<KEY>; the Invocations sheet view; the /console#/api/<KEY> page.\\n- scripts/contracts-ways.mjs builds 13 rows per tool; ways_results.json holds the 2026-09-23 outcomes (session-shell executed).\\n- MCP door functions/api/mcp.js (misc_find/misc_run + hot set /api/tools/*.json; MCP_TOKEN in the vault); the four Code-Mode models reach it through their MCP config.\\n- console-app 1.1.0 (`console-app call KEY 'a|b'`, `console-app how KEY`) installed from https://miscsubjects.com/download/llmasos-console-1.1.0.tgz; `~/.local/bin/misc` is a coding agent, not the misc CLI.\\n- Shortcuts: `shortcuts run` hangs on the owner Mac (WT-0442); URL-scheme and Automation-triggered runs are unproven.\\n- Tag spelling (a tag in a text message) is handled by /api/text inbound + resolve; unproven end to end.\\n\\n## SOURCE OF TRUTH\\n- functions/_lib/invocation_methods.js\\n- functions/api/mcp.js, functions/_lib/mcp_inspect.js, functions/api/tools/[[path]].js\\n- functions/_lib/projection_manifest.js (which surfaces exist as projections)\\n- apps-script/Contracts.gs (the sheet-side invoker) and functions/api/sheets (the build workbook, `=DISPATCH`)\\n- the console-app package (public/download/llmasos-console-1.1.0.tgz)\\n\\n## IN-SCOPE INVENTORY\\n- Spelling ids (the `surface` enum for proof_runs): curl, named, url, jsonrpc, claude_code, misc, console_app, line, tag, shortcut, webhook, upstream, cell. Each gets a SURFACE RUNNER that executes the spelling through the real surface: curl → `sh -c` of the exact text; named → fetch; url → browser GET (WT-0475 controller) AND plain fetch (two proofs, labelled); jsonrpc → a real MCP client session (npx @modelcontextprotocol/inspector --cli or a 40-line Node client) issuing initialize + tools/call; claude_code → `claude -p` with the MCP config and a prompt that calls the tool, capturing the tool_use block; misc → the line door /api/resolve then dispatch; console_app → the binary; line → /api/resolve; tag → an inbound text to +14245134626 carrying the tag (WT-0480 sends it); shortcut → `shortcuts run` on the Mac via the bridge and the iOS Shortcut via /api/phone (WT-0479) — until WT-0442 is fixed, the Mac result is recorded as the hang, verbatim; webhook → POST /api/hooks/<id> from an outside host (the Starlink line via /api/net fetch, WT-0478); upstream → the vendor URL directly; cell → PUT the formula into scratch sheet sh_ahznwfyd A1 and read it back.\\n- Output: for each row × spelling, one proof_run (WT-0470 shape) with surface=<spelling id> and cause=task:WT-0472, and one six-column row in sh_nyab2cgy (through WT-0473's writer).\\n- Coverage: 74 hot tools first (the 99 %), then the long tail catalogued (discovered) without running send-effect rows.\\n\\n## OUT OF SCOPE\\n- Changing what a spelling means (the compiler's text is owned here; the resolver is WT-0471).\\n- Building browser/phone/text executors (WT-0475/0479/0480 provide them; this task calls them).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: all 13 spelling ids\\n- CAPABILITY: every Directory key (1,519 rows; 74 hot)\\n- OBJECT: the row + example args\\n- ROUTE / CONTEXT: owner Mac (console_app, shortcut, claude_code), Worker (named/url/jsonrpc), iPhone (shortcut), a text line (tag), an outside host (webhook)\\n- PROTOCOL: HTTP, JSON-RPC over HTTP, local process, URL scheme, SMS/iMessage\\n- EXECUTOR: per spelling (see inventory)\\n- PLATFORM: Cloudflare, Apple, the build, the vendor\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/directory/NET_LINE\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\" | python3 -c \\\"import json,sys; [print(k, '→', str(v)[:100]) for k,v in json.load(sys.stdin)['how_to_call'].items()]\\\"`\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/tools/mcp.json?hot=all\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\" | python3 -c \\\"import json,sys; print(len(json.load(sys.stdin)['tools']))\\\"` (595 read-effect rows on 2026-09-23)\\n- `console-app how NET_LINE`\\n\\n## CONTRACT (FIELD LAW)\\n- Runner input: `{key, spelling, args?, cause, route?}`; required key+spelling; args default = row example; route required for shortcut (device ∈ {owner-mac, owner-iphone}) and tag (line ∈ the sender list).\\n- Runner output: proof_run fields + `surface_ran: true|false` + `surface_evidence` (MCP session id / Shortcut run id / message id / browser request id / process pid). surface_ran=false with a reason is a valid, preserved result.\\n\\n## MINIMUM VALID INVOCATION\\n`node scripts/surface-run.mjs --key NET_LINE --spelling curl`\\n\\n## FULL / MAXIMUM INVOCATION\\n`node scripts/surface-run.mjs --keys hot --spellings all --route device=owner-mac,line=+14245134626 --cause task:WT-0472 --write build:sh_nyab2cgy --concurrency 4`\\n\\n## RAW CONFIRMATION SHAPE\\nPer spelling: HTTP status+headers (named/url/upstream/webhook), JSON-RPC result envelope with id (jsonrpc), process exit code + pid (curl/console_app/claude_code/shortcut), message id (tag), sheet write receipt (cell).\\n\\n## RAW RETURN SHAPE\\nThe verbatim payload the surface returned (tool result content for jsonrpc; stdout for processes; cell value for cell; the reply text for tag).\\n\\n## ERROR SHAPES\\n- jsonrpc: `-32601 method not found`, `unauthorized` (MCP_TOKEN), initialize timeout (cold start 50–65 s — retry once after 70 s).\\n- shortcut: hang (record `NONE (hang after 60 s)`; WT-0442).\\n- claude_code: no tool_use block (record the transcript; it is a failure, not a skip).\\n- cell: `google_sync_off`-class gate refusals never apply to the build workbook; a formula error `#ERROR` is a return, keep it.\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nOne proof_run per (key, spelling); receipt ids listed in evidence as a TSV `key\\\\tspelling\\\\treceipt_id\\\\tsurface_ran`.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| curl | 74 hot × curl, executed by sh -c | live |\\n| jsonrpc | 74 hot × real MCP client tools/call | live |\\n| claude_code | 10 hot × `claude -p` tool_use captured | live |\\n| console_app | 74 hot × binary | live |\\n| url | 74 hot × browser GET (WT-0475) + fetch | live |\\n| cell | 74 hot × =DISPATCH in scratch sheet | live |\\n| shortcut | 5 rows × Mac + iPhone | live or recorded hang |\\n| tag | 5 rows × inbound text | live |\\n| webhook | 5 rows from the Starlink line | live |\\n| long tail | 1,445 rows × discovered only, no execution of send-effect rows | catalogue |\\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\\\": \\\"tsv\\\", \\\"field\\\": \\\"receipts_tsv\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"how\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/directory/NET_LINE?share=public\\\", \\\"needle\\\": \\\"how_to_call\\\"}`\\nEvidence fields the submitting agent supplies: commit, receipts_tsv, 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- `--help` exit 0 is not proof (cli_tools)\\n- hidden bash proving only bash (the 2026-09-23 ways run)\\n- `shortcuts run` hang (WT-0442)\\n- Bearer anonymous on /api/tools (x-terminal-key required for the hot set)\\n- MCP cold-start handshake 65 s\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470, WT-0471\\n- OWNS (only this task rewrites): 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; scripts/surface-run.mjs (new); the console-app package\\n- SHARED (additive edits only): scripts/contracts-write-results.mjs (call it to write D:F; WT-0473 owns it); bridge/* (call; WT-0474 owns)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Build the jsonrpc runner first (it is the surface the four models use); then console_app and cell; then url via WT-0475; shortcut/tag/webhook last and only after their planes answer.\\n- Evidence TSV path goes in `receipts_tsv`; keep failures.\\n- If invocation_methods.js text changes, re-run the 74 × 13 set; the sheet rows are a projection and must be regenerated, never hand-edited.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Every spelling id has a runner that executes through its own surface (evidence: one receipt per spelling with surface_evidence).\\n- 74 hot tools × every applicable spelling have proof_runs; failures preserved.\\n- 1,519 rows have contracts state ∈ {discovered, executable, proven} in capability_contracts.\\n- sh_nyab2cgy carries the regenerated way-rows (projection).\\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\",\"priority\":2,\"depends_on\":[\"WT-0470\",\"WT-0471\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"tsv\",\"field\":\"receipts_tsv\"},{\"type\":\"contains\",\"id\":\"how\",\"url\":\"https://ops.miscsubjects.com/api/directory/NET_LINE?share=public\",\"needle\":\"how_to_call\"}],\"evidence_required\":[\"commit\",\"receipts_tsv\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "4be05fd61580581c4e6fd1f9d22801e028abe1a388dc7cbbe5efe5645ef57aa9",
      "hash": "5c9c495265c2ebd801a7eb686233d2f2bf54bdd3c0054c01bb4128d9b03e7132"
    },
    {
      "id": 1227,
      "ts": "2026-09-22T19:51:52-07:00",
      "task_id": "WT-0486",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"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\",\"priority\":3,\"depends_on\":[\"WT-0470\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"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\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "380062e037e69f108b28ac2fbb09f3de63fd61b0f2d5ec9e7ad3cb73316db131",
      "hash": "4be05fd61580581c4e6fd1f9d22801e028abe1a388dc7cbbe5efe5645ef57aa9"
    },
    {
      "id": 1226,
      "ts": "2026-09-22T19:51:51-07:00",
      "task_id": "WT-0473",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0473\",\"kind\":\"work\",\"objective\":\"WT-0473 CONTRACTS harness and the six-column projection — batch runner, RUN column, regression fixtures\",\"detail\":\"# WT-0473 — CONTRACTS harness and the six-column projection — batch runner, RUN column, regression fixtures\\n\\n## GOAL\\nMake the CONTRACTS system (the six-column sheet sh_nyab2cgy in the build workbook, scripts/contracts-*.mjs, the CONTRACTS_RUN row, the RUN column) a durable harness: it reads capability_contracts + proof_runs (canonical) and projects them; it re-runs any row on demand from the sheet; it never stops a batch on one failure; every known failure class from the 2026-09-23 run is a fixture the runner is tested against.\\n\\n## WHY THIS EXISTS\\nThe owner's format law (CONTRACTS_FORMAT_LAW) is how he reads execution. The 2026-09-23 run produced 11,035 rows but the runner was a session tool: it stalled on Apps Script throttling, split cells at 24,000 chars, ran in a shell where `set -- $spec` did not word-split, and the sheet was hand-loaded. The harness must be the build's, not a session's.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Sheet sh_nyab2cgy: 11,035 rows (10,072 verbs + 962 ways + header); columns exactly TOOL NAME | ONTOLOGY | RAW INVOCATION | RAW CONFIRMATION | RAW RETURN | PROOF / RECEIPT; counts 2026-09-23: HTTP 2xx 1,698; HTTP 5xx 2,378; transport failed 42; NOT RUN with reason 5,954.\\n- scripts/contracts-sheet.mjs (build rows from /tmp/claude-501/contracts/*.json), contracts-run.mjs (`--marked=build:<sheet>` RUN-column mode, policy(), runText()), contracts-ways.mjs, contracts-load-workbook.mjs (60 rows/PUT, cells cut at 24,000), contracts-write-results.mjs (D:F only, chunks ≤ 60).\\n- CONTRACTS_RUN directory row → POST agent.miscsubjects.com/exec → `node scripts/contracts-run.mjs --marked=build:sh_nyab2cgy --max=50`.\\n- apps-script/Contracts.gs (Google copy 1cUE88…) — a projection the owner does not want as home; keep it working, never make it the source.\\n- Scratch sheet sh_ahznwfyd for `=FORMULA` cells.\\n- Vault: CONTRACTS_WORKBOOK_SHEET, CONTRACTS_SCRATCH_SHEET, CONTRACTS_LINK_TOKEN (10-year rows: token; door keys included), CONTRACTS_SHEET_ID.\\n\\n## SOURCE OF TRUTH\\n- capability_contracts + proof_runs (after WT-0470/0485) — the sheet is derived from them\\n- scripts/contracts-*.mjs\\n- functions/api/sheets (PUT values ≤ 400 cells per call; `=DISPATCH(\\\"KEY\\\",\\\"args\\\")` formulas)\\n- the `laws` row CONTRACTS_FORMAT_LAW\\n\\n## IN-SCOPE INVENTORY\\n- scripts/contracts-project.mjs (new): reads canonical rows → writes the six columns; idempotent; `--since <receipt>` incremental.\\n- RUN column: typing RUN in column G is not allowed (no seventh column) — the RUN mechanism is a cell edit in column C prefixed `RUN ` OR the CONTRACTS_RUN row with `--rows`; decide: keep `--marked` reading column C prefix `RUN `; document in the sheet header note only.\\n- Runner hardening: per-row timeout; DNS/transport failure isolates the row; cells > 20,000 chars stored whole in the ledger and cut in the projection with `… [cut at 20000; full at receipt <id>]`; writes ≤ 400 cells and ≤ 80 KB per PUT; retry 5 with backoff; a stalled write never blocks execution (results go to file first, then to the sheet).\\n- Fixture suite scripts/contracts-fixtures.test.mjs built from the exact 2026-09-23 failures (list below).\\n- The Google copy: Contracts.gs contracts_run/invoke_json stay; a header note says \\\"projection of the build workbook\\\".\\n\\n## OUT OF SCOPE\\n- Executing per-surface runners (WT-0472 supplies them; this harness schedules and projects). Ontology labels (WT-0486). New columns (forbidden).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: cell `RUN ` prefix; CONTRACTS_RUN row via dispatch; `node scripts/contracts-run.mjs`\\n- CAPABILITY: CONTRACTS_RUN, CONTRACTS_PROJECT\\n- OBJECT: six-column rows\\n- ROUTE / CONTEXT: owner Mac (runner) → doors; the build workbook\\n- PROTOCOL: HTTP to /api/sheets and /api/dispatch; local process\\n- EXECUTOR: node on the Mac (through agent.miscsubjects.com/exec) or on a CF container (CLOUD_EXEC)\\n- PLATFORM: the build; Cloudflare; Google (projection only)\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/sheets/sh_nyab2cgy?range=A1:F3\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `node scripts/contracts-run.mjs --help` (this prints usage; it is not proof of anything)\\n- `cat /tmp/claude-501/contracts/workbook-counts.json`\\n\\n## CONTRACT (FIELD LAW)\\n- `contracts-run.mjs` flags: --rows (csv or a-b), --from/--to (ints), --concurrency (1–8, default 2), --only=<ontology substring>, --target=google|file:<path>|build:<sheet>, --marked=build:<sheet>, --max (int), --timeout-ms (default 60000). --rows conflicts with --from/--to. Omitting --target writes nowhere but the results file.\\n- Row contract (the six cells): A tool name (string, ≤ 200), B ontology (`<axis> · <axis> · …`, from WT-0486), C raw invocation (executable text as pasted, ≤ 20,000 in the projection), D raw confirmation (`HTTP <status> · <ms> ms · <ISO> · run by <surface> · plane=<…> · ids …` | `EXIT <n> …` | `NOT RUN BY THE SESSION · <reason> · type RUN here to run it yourself` | `NOT RUNNABLE FROM THIS MAC · <reason>`), E raw return (verbatim, cut at 20,000 with the receipt pointer), F proof/receipt (`receipt:<id> trace:<id> parent:<id|none> surface:<spelling> cause:<…>`).\\n\\n## MINIMUM VALID INVOCATION\\n`node scripts/contracts-run.mjs --rows 2 --target=build:sh_nyab2cgy`\\n\\n## FULL / MAXIMUM INVOCATION\\n`node scripts/contracts-run.mjs --from 2 --to 11035 --concurrency 4 --only \\\"dispatch\\\" --target=build:sh_nyab2cgy --timeout-ms 90000 --cause task:WT-0473`\\n\\n## RAW CONFIRMATION SHAPE\\nPer row: the surface's confirmation (column D). Per run: `run-summary.json` {rows, ran, not_run, failed_transport, http_2xx, http_4xx, http_5xx, wrote_cells}.\\n\\n## RAW RETURN SHAPE\\nColumn E per row; run log at /tmp/claude-501/contracts/run*.out (session) → move to `~/miscsubjects-pages/.runs/contracts/<ISO>.log` (gitignored) so the next session finds it.\\n\\n## ERROR SHAPES\\n- Sheets PUT `too_many_cells` (>400) — chunk.\\n- Apps Script bounce (HTML page instead of JSON, >~100 KB POST) — Google projection only; chunk to <80 KB.\\n- DNS ENOTFOUND on a stale host — row result, batch continues.\\n- AdsPower Local API unreachable from Google (local.adspower.net:50325 is LAN-only) — expected; the row says NOT RUNNABLE FROM GOOGLE; the build runner on the Mac runs it.\\n- Cell > 50,000 chars refused by Google — projection cut; canonical keeps whole.\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nColumn F per row; run-summary.json per run; a CONTRACTS_RUN dispatch receipt per triggered run.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| project | contracts-project.mjs regenerates rows 2..N from canonical and diff = 0 cells against the current sheet for rows already proven | live |\\n| RUN one | edit C of one row to `RUN <invocation>` → CONTRACTS_RUN → D:F filled within 2 min | live |\\n| DNS isolate | fixture host nonexistent.invalid → that row FAILED (transport), next row ran | fixture |\\n| big cell | a 60,000-char return → E cut with receipt pointer; ledger whole | fixture |\\n| throttle | simulate 3 write failures → results file complete, sheet catches up | fixture |\\n| google copy | Contracts.gs contracts_run on 5 rows still works and its header says projection | 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\\\": \\\"summary\\\", \\\"field\\\": \\\"run_summary\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"header\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/sheets/sh_nyab2cgy?range=A1:F1&share=public\\\", \\\"needle\\\": \\\"PROOF / RECEIPT\\\"}`\\nEvidence fields the submitting agent supplies: commit, run_summary, 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- google_sync_off on unrelated routes (fixed by switchOnFresh; keep the test)\\n- stale hosts\\n- DNS failure stopping a batch\\n- >50,000-char cell\\n- AdsPower unreachable from GAS\\n- Apps Script >100 KB bounce\\n- zsh `set -- $spec` no word-split (runner launched with empty --from)\\n- write timeout stall (90 s)\\n- transport 2xx ≠ success\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470\\n- OWNS (only this task rewrites): scripts/contracts-*.mjs; scripts/contracts-project.mjs (new); scripts/contracts-fixtures.test.mjs (new); apps-script/Contracts.gs; CONTRACTS_RUN row; sheets sh_nyab2cgy and sh_ahznwfyd\\n- SHARED (additive edits only): functions/api/sheets (call only); functions/_lib/invocation_methods.js (read only; WT-0472)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Do not reset the sheet. Regenerate rows from canonical only after WT-0470 schema exists; until then the runner keeps writing D:F as today.\\n- The `contains` acceptance uses `share=public` — if the sheets door has no public share for the header, mint a rows: share for sh_nyab2cgy read (WT-0487 owns the token law; a read-only share of one range is allowed).\\n- Keep counts in run_summary evidence: rows examined, ran, not run, failed.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- The sheet is regenerable from canonical (evidence: diff count).\\n- RUN from a cell works end to end (evidence: receipt).\\n- Fixture suite passes and is wired as a deploy gate `scripts/check-contracts-fixtures.mjs`.\\n- The Google copy is labelled a projection and still runs.\\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\",\"priority\":2,\"depends_on\":[\"WT-0470\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"summary\",\"field\":\"run_summary\"},{\"type\":\"contains\",\"id\":\"header\",\"url\":\"https://ops.miscsubjects.com/api/sheets/sh_nyab2cgy?range=A1:F1&share=public\",\"needle\":\"PROOF / RECEIPT\"}],\"evidence_required\":[\"commit\",\"run_summary\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8fe419adb74fb5983eb5ce223dd8cf17521cbe34fc345532c25970d042f72733",
      "hash": "380062e037e69f108b28ac2fbb09f3de63fd61b0f2d5ec9e7ad3cb73316db131"
    },
    {
      "id": 1225,
      "ts": "2026-09-22T19:51:49-07:00",
      "task_id": "WT-0487",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0487\",\"kind\":\"work\",\"objective\":\"WT-0487 Tenancy and authority — principals, tokens, scopes, share links, device binding; a handle never implies authority\",\"detail\":\"# WT-0487 — Tenancy and authority — principals, tokens, scopes, share links, device binding; a handle never implies authority\\n\\n## GOAL\\nOne authority function decides every invocation (owner key, tenant Bearer, share token, device-bound token, capability token, Access session, link `share=`) with a written policy: principal → scope → object → route → allow/deny with the reason; every decision is recorded on the receipt; tokens have contracts (mint, verify, revoke, TTL); tenants have policy rows; a handle (session, profile, line) never grants authority by itself.\\n\\n## WHY THIS EXISTS\\nAuthority is spread across admin_session.js, dispatch.js, tenants policy, share tokens, device tokens and Access. Sessions hit tenant_unknown, capability_required, Bearer-anonymous and unscoped rows: tokens repeatedly. Renting accounts and onboarding strangers need one decision path with receipts.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- functions/_lib/admin_session.js (tokens, capabilities, tenants: createTenant allow_keys/allow_prefixes); LEDGER capabilities table (tenant_id, device_id, fingerprint, scope); dispatch `?mint_share=1&scope=rows&keys=…&ttl=`; settings tokens.max_ttl_s (604800; temporarily raised to mint the 10-year CONTRACTS_LINK_TOKEN); CAP_MINT row; Access (email PIN + service token) for owner surfaces; x-share-code credential for /share/<code>; device-bound tokens (tenant_devices).\\n- Known: Bearer treated as anonymous on /api/tools; tenant Bearer forwarded to tenant doors; `rows:` tokens must include door keys; PATCH /api/directory needs x-terminal-key.\\n\\n## SOURCE OF TRUTH\\n- functions/_lib/admin_session.js\\n- functions/api/dispatch.js (auth branch)\\n- functions/_lib/tenant_devices.js\\n- functions/api/token/*, functions/api/tenant/*, functions/api/tenants.js, functions/api/capability/*\\n- memory project_people_and_access_2026_09_21 (door/level/spaces/exceptions/links)\\n\\n## IN-SCOPE INVENTORY\\n- `authorize(env, {principal, key, object?, route?, side_effect})` → `{allow:bool, reason, policy_id, principal_kind}`; called by the resolver; the result written into physical.authority and the receipt.\\n- Principal kinds and their contracts: owner_key (x-terminal-key), tenant_token (Bearer; tenants policy row required), share_token (scope rows|range|read; keys; ttl ≤ tokens.max_ttl_s unless minted with reason `long_lived` and recorded), device_token (bound to device fingerprint), capability_token (CAP_MINT), access_session (Cloudflare Access JWT), link_share (?share=).\\n- Verbs: TOKEN_MINT {kind, scope, ttl_s, reason}, TOKEN_VERIFY {token → principal, scope, expires}, TOKEN_REVOKE, TENANT_POLICY_GET/SET {tenant, allow_keys, allow_prefixes, deny_keys, side_effects_allowed}, AUTHZ_EXPLAIN {principal, key} (dry decision with the reason).\\n- Law rows: AUTHORITY_LAW (\\\"a handle identifies; authority is a recorded decision\\\") inserted through D1_EXEC; a deploy gate that every door calls authorize (static scan of functions/api for direct token checks).\\n- Fixtures: Bearer anonymous on tools; tenant_unknown; rows: token without door keys; max_ttl_s bypass (must require reason); share link replay after revoke.\\n\\n## OUT OF SCOPE\\n- Session storage (WT-0477). Onboarding flows (WT-0488). Access configuration in the Cloudflare dashboard.\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: every door (authorize is internal); dispatch TOKEN_*/TENANT_POLICY_*/AUTHZ_EXPLAIN; MCP CAP_MINT\\n- CAPABILITY: the verbs above\\n- OBJECT: a principal, a token, a tenant policy\\n- ROUTE / CONTEXT: which door the principal entered by\\n- PROTOCOL: HTTP headers/query; Access JWT\\n- EXECUTOR: Worker\\n- PLATFORM: the build; Cloudflare Access\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/tenants\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/dispatch?mint_share=1&scope=rows&keys=NET_LINE&ttl=600\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n- `grep -n \\\"capability_required\\\\|tenant_unknown\\\" ~/miscsubjects-pages/functions/api/dispatch.js | head`\\n\\n## CONTRACT (FIELD LAW)\\n- TOKEN_MINT `{kind (required enum), scope (required: {keys[]|prefixes[]|range|read_only}), ttl_s (required 60..max_ttl_s; > max requires reason=\\\"long_lived:<why>\\\"), bind_device (optional fingerprint), note}` → `{token (returned once), token_id, expires_at, receipt_id}`.\\n- AUTHZ_EXPLAIN `{principal (token id or \\\"owner\\\"), key (required), side_effect?}` → `{allow, reason, policy_id}`; no side effects.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"AUTHZ_EXPLAIN\\\",\\\"body\\\":{\\\"principal\\\":\\\"owner\\\",\\\"key\\\":\\\"NET_LINE\\\"}}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"TOKEN_MINT\\\",\\\"body\\\":{\\\"kind\\\":\\\"share_token\\\",\\\"scope\\\":{\\\"keys\\\":[\\\"NET_LINE\\\",\\\"NET_SEARCH\\\"]},\\\"ttl_s\\\":86400,\\\"bind_device\\\":null,\\\"note\\\":\\\"WT-0487 test\\\"},\\\"cause\\\":\\\"task:WT-0487\\\"}'`\\n\\n## RAW CONFIRMATION SHAPE\\nHTTP 200 + token_id; deny = HTTP 403 `{error:\\\"authority_denied\\\", reason, policy_id}` (never a bare 401 without a reason; `capability_required` keeps its name for missing owner key).\\n\\n## RAW RETURN SHAPE\\nDecision objects; token metadata (the token value once at mint).\\n\\n## ERROR SHAPES\\n- authority_denied (with reason)\\n- capability_required\\n- tenant_unknown (names the fix: ONBOARD creates the policy row)\\n- ttl_exceeds_max (names reason= requirement)\\n- token_revoked\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nphysical.authority on every receipt; mint/revoke receipts; AUTHZ_EXPLAIN receipts (dry).\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| owner allow | NET_LINE → allow | live |\\n| tenant allow/deny | ONBOARD_DEMO_KEY: NET_LINE allow, D1_EXEC deny with reason | live |\\n| share token | rows: token NET_LINE works, D1_QUERY denied | live |\\n| revoke | revoked share → token_revoked | live |\\n| device bound | device token from another fingerprint → denied | live |\\n| ttl guard | ttl 10 years without reason → ttl_exceeds_max; with reason → minted and recorded | live |\\n| bearer on tools | /api/tools with Bearer → explicit capability_required, not anonymous | fixture |\\n| gate | static scan: 0 doors with direct token checks | 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\\\": \\\"law\\\", \\\"sql\\\": \\\"SELECT COUNT(*) AS n FROM laws WHERE key='AUTHORITY_LAW' AND enabled=1\\\", \\\"min\\\": 1}`\\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- Bearer anonymous on /api/tools\\n- tenant_unknown after onboarding\\n- rows: token lacking door keys\\n- max_ttl_s raised and restored by hand (2026-09-23)\\n- vault catalog leak 2026-09-19 (authority pages never render values)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470\\n- OWNS (only this task rewrites): functions/_lib/admin_session.js; functions/_lib/authorize.js (new); functions/api/token/*, tenant/*, tenants.js, capability/*; scripts/check-authorize-everywhere.mjs (new); AUTHORITY_LAW row\\n- SHARED (additive edits only): functions/api/dispatch.js (WT-0471; swap the auth branch for authorize() additively); functions/_lib/tenant_devices.js (WT-0488; read)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Keep the 10-year CONTRACTS_LINK_TOKEN valid; register it as long_lived with the reason in the token table.\\n- Evidence: the decision table (principal × key → allow/deny/reason) with receipts.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- authorize() is the only decision path (gate = 0 direct checks).\\n- Every principal kind has contracts and receipts for allow and deny.\\n- AUTHORITY_LAW live; fixtures pass.\\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\",\"priority\":2,\"depends_on\":[\"WT-0470\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"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\":\"law\",\"sql\":\"SELECT COUNT(*) AS n FROM laws WHERE key='AUTHORITY_LAW' AND enabled=1\",\"min\":1}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "acc1ae8678fdb32f139ba8d94b11ce7d9d4daf1cf76aa6a71f40c17920c59d90",
      "hash": "8fe419adb74fb5983eb5ce223dd8cf17521cbe34fc345532c25970d042f72733"
    },
    {
      "id": 1224,
      "ts": "2026-09-22T19:51:47-07:00",
      "task_id": "WT-0485",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0485\",\"kind\":\"work\",\"objective\":\"WT-0485 Event ledger and receipts — persist-before-execute, five fields on every run, no unlogged write route\",\"detail\":\"# WT-0485 — Event ledger and receipts — persist-before-execute, five fields on every run, no unlogged write route\\n\\n## GOAL\\nOne ledger writer records every executed capability with the five proof fields (cause, raw invocation written before execution, raw confirmation, raw return, receipt with trace and parent), from every door and executor; logEvent failures are loud; the ~35 unlogged write routes are logged; receipts render the causal chain; R2 keeps the raw bodies and D1 keeps the index.\\n\\n## WHY THIS EXISTS\\nlogEvent cannot fail loudly, ~35 write routes never log (ledger coverage gaps memory), the audit log is editable through LEDGER_EXEC, and the raw invocation is recorded only after success. The owner's law needs the chain WHY → WHAT → ACK → RETURN → RECEIPT to exist for every run, including crashes.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- functions/_lib/event_log.js logEvent(env,{source,key,route,actor,action,direction,status,trace_id,raw_id,request,response}); R2-only sources under logs/; functions/_lib/wire_log.js installWireLog; functions/_lib/lean_receipt.js; receipt pages https://miscsubjects.com/receipt/<id>; functions/_lib/invocation_record.js.\\n- LEDGER DB events table; audit chain /api/work/audit; Cloudflare's own record (ledger read model memory).\\n- Known: logEvent swallow; LEDGER_EXEC can edit the audit log; ~35 unlogged write routes; noise sources must stay R2-only (LAW: logs live in R2, never D1 COUNT/LIKE over events).\\n\\n## SOURCE OF TRUTH\\n- functions/_lib/event_log.js, wire_log.js, lean_receipt.js, invocation_record.js\\n- functions/api/events/*, functions/api/ledger/*, functions/receipt/*\\n- the LEDGER D1 schema (migrations naming events)\\n- memory project_ledger_coverage_gaps (the 35 routes list)\\n\\n## IN-SCOPE INVENTORY\\n- proof_runs writer: `startRun(env,{cause, surface, physical, trace_id, parent_receipt_id})` → receipt_id (row written, status=started, raw_invocation to R2 logs/runs/<receipt>/invocation.json); `finishRun(env, receipt_id, {confirmation, return, status})` (raw to R2; index columns in D1); `failRun` for crashes (a `finally` in the resolver).\\n- Loud failure: if the ledger write fails, the door returns 500 ledger_write_failed with the raw error (never a silent success) — except R2-only noise sources which degrade to a counter.\\n- Coverage: functions/_middleware.js wraps every write route (POST/PUT/PATCH/DELETE) with startRun/finishRun when the handler did not; a deploy gate scripts/check-ledger-coverage.mjs lists write routes without a run and fails when > 0.\\n- Immutability: audit rows are append-only; LEDGER_EXEC refuses UPDATE/DELETE on events/proof_runs (governed_tables pattern); a hash chain over proof_runs (prev_hash) exposed at /api/work/audit.\\n- Receipt page: renders cause → invocation → confirmation → return → receipt + parent/children tree + the surface id; JSON at /receipt/<id>.json.\\n\\n## OUT OF SCOPE\\n- Deciding what is a capability (Directory). The six-column projection (WT-0473 reads this).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: internal writer used by every door; GET /receipt/<id>; GET /api/events; /api/work/audit\\n- CAPABILITY: LEDGER_WRITE (internal), RECEIPT_GET, EVENTS_QUERY, AUDIT_CHAIN\\n- OBJECT: a run, a receipt, an event\\n- ROUTE / CONTEXT: LEDGER DB + R2 logs/\\n- PROTOCOL: Worker bindings\\n- EXECUTOR: Worker\\n- PLATFORM: Cloudflare D1/R2\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://miscsubjects.com/receipt/<any id from a dispatch response>.json\\\"`\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/work/audit\\\" | head -c 800`\\n- `grep -rn \\\"logEvent(\\\" ~/miscsubjects-pages/functions/api | wc -l` versus write routes: `grep -rln \\\"onRequestPost\\\\|onRequestPut\\\\|onRequestPatch\\\\|onRequestDelete\\\" ~/miscsubjects-pages/functions/api | wc -l`\\n\\n## CONTRACT (FIELD LAW)\\n- startRun `{cause (required enum from WT-0470), surface (required id), physical (required object), trace_id (optional; generated), parent_receipt_id (nullable), actor (required principal)}` → receipt_id (string `r_<ulid>`).\\n- finishRun `{receipt_id, confirmation (object|string), return (any; > 200,000 chars → R2 whole + cut index), status (enum ok|error|timeout|crashed)}`.\\n- GET /receipt/<id>.json → `{id, cause, surface, physical, confirmation, return_ref|return, status, started_at, finished_at, trace_id, parent_receipt_id, children:[ids], prev_hash, hash}`.\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS \\\"https://miscsubjects.com/receipt/<id>.json\\\"`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS \\\"https://ops.miscsubjects.com/api/events?source=dispatch&key=NET_LINE&since=2026-09-23T00:00:00Z&limit=50&fields=receipt_id,cause,status\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"`\\n\\n## RAW CONFIRMATION SHAPE\\nstartRun returns the id synchronously before the executor runs (the row exists if the Worker is killed afterwards).\\n\\n## RAW RETURN SHAPE\\nReceipt JSON; events rows (index fields only; raw in R2 by reference).\\n\\n## ERROR SHAPES\\n- ledger_write_failed 500 (loud)\\n- receipt_not_found 404\\n- audit_immutable 403 (UPDATE/DELETE refused)\\n- return_too_large → stored in R2 with return_ref\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nThis task's own proof: the crash fixture receipt (status=crashed with raw_invocation present), the coverage gate output (0 unlogged write routes), and the audit chain head hash.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| start/finish | NET_LINE via dispatch → receipt has all five fields | live |\\n| crash | LOCAL_EXEC with a 2 s timeout on sleep 30 → status=timeout, invocation present | fixture |\\n| loud failure | simulate R2 write failure → 500 ledger_write_failed | fixture |\\n| coverage gate | check-ledger-coverage.mjs → 0 | live |\\n| immutability | LEDGER_EXEC UPDATE events → audit_immutable | fixture |\\n| chain | audit head hash verifies over the last 100 rows | live |\\n| receipt page | renders tree for a WT-0484 chain | live |\\n| R2-only noise | a noise source writes no D1 row | fixture |\\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\\\": \\\"gate\\\", \\\"field\\\": \\\"gate_run\\\"}`\\n- `{\\\"type\\\": \\\"http_ok\\\", \\\"id\\\": \\\"audit\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/work/audit\\\"}`\\nEvidence fields the submitting agent supplies: commit, gate_run, 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- logEvent silent failure\\n- audit log editable via LEDGER_EXEC\\n- ~35 unlogged write routes\\n- noise into D1 (LAW: R2 only)\\n- transport 2xx ≠ success (status must come from the operation, not the HTTP code)\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470\\n- OWNS (only this task rewrites): functions/_lib/event_log.js, wire_log.js, lean_receipt.js; functions/_lib/proof_runs.js (new); functions/receipt/*, functions/api/events/*; scripts/check-ledger-coverage.mjs (new); migrations/0488_proof_runs.sql (new, LEDGER)\\n- SHARED (additive edits only): functions/_middleware.js (additive wrapper); functions/_lib/resolver.js (WT-0471 calls startRun/finishRun; coordinate the call sites)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Land the writer first with dispatch as the only caller, ship, then the middleware wrapper, then the gate (three ships across three turns at most; one ship per turn).\\n- Do not COUNT/LIKE over events for the gate; the gate reads route files statically.\\n- Evidence: gate output, crash receipt id, audit head hash.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Every executed capability has a proof_runs row with the five fields (gate = 0 gaps).\\n- Crash/timeout leaves the invocation (fixture).\\n- Ledger failures are loud; audit is immutable and hash-chained.\\n- Receipt pages render the chain.\\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\",\"priority\":1,\"depends_on\":[\"WT-0470\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"gate\",\"field\":\"gate_run\"},{\"type\":\"http_ok\",\"id\":\"audit\",\"url\":\"https://ops.miscsubjects.com/api/work/audit\"}],\"evidence_required\":[\"commit\",\"gate_run\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "f7105e38e55a58922f91e9b5e763007114db8611e3c352ae1211c110d5dd932e",
      "hash": "acc1ae8678fdb32f139ba8d94b11ce7d9d4daf1cf76aa6a71f40c17920c59d90"
    },
    {
      "id": 1223,
      "ts": "2026-09-22T19:51:45-07:00",
      "task_id": "WT-0471",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0471\",\"kind\":\"work\",\"objective\":\"WT-0471 Resolver / Dispatcher — semantic capability to fully resolved physical invocation\",\"detail\":\"# WT-0471 — Resolver / Dispatcher — semantic capability to fully resolved physical invocation\\n\\n## GOAL\\nEvery call through the one door resolves a semantic Directory call (key + arguments) into a fully resolved physical invocation (executor, URL/command/target, method, headers/auth, body/argv/env/stdin, session/profile/device), persists that raw invocation BEFORE executing, runs it, and returns confirmation + return + receipt as separate fields. The resolver is one function, used by every surface (WT-0472) and every plane.\\n\\n## WHY THIS EXISTS\\nThe dispatcher today resolves and executes in one motion (functions/api/dispatch.js runHttp/runFn/tenant delegation) and records the result after the fact. A crash or timeout leaves no raw invocation, the return and the confirmation are merged into `last_response`, and no field says which executor actually ran. The owner's law: semantic capability → resolver → physical invocation → executor → confirmation → return → receipt, each a separate field.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- functions/api/dispatch.js: rows by key; `?invoke=KEY&share=<token>` link form; `?mint_share=1&scope=rows&keys=…&ttl=`; tenant Bearer forwarded to tenant doors; runHttp (curl-like upstream), runFn (in-Worker function), local bridge via functions/_lib/mac_bridge.js bridgeRequest(env,…,{key,device}).\\n- functions/api/resolve.js: the line grammar (functions/_lib/grammar.js) resolves a typed line to a key + args; it does not produce a physical invocation.\\n- functions/_lib/invocation_record.js writes invocation, last_status, last_response, test_state onto the directory row after execution.\\n- Tenant routing: functions/_lib/tenant_devices.js (device-bound token + intent secret, quick-tunnel endpoint) overrides the bridge target per tenant.\\n\\n## SOURCE OF TRUTH\\n- functions/api/dispatch.js\\n- functions/_lib/mac_bridge.js\\n- functions/_lib/tenant_devices.js\\n- functions/_lib/invocation_record.js\\n- functions/api/resolve.js + functions/_lib/grammar.js\\n- the `directory` table (1,519 rows on 2026-09-23; columns include key, kind, method, url, headers, body, fn, ontology, provider, tier, planner_rank, invocation, last_status, last_response, test_state)\\n\\n## IN-SCOPE INVENTORY\\n- New module functions/_lib/resolver.js: `resolve(env, {key, args, actor, cause, route})` → `{physical:{executor, protocol, target, method, headers, body|argv|env|stdin, session|profile|device}, contract_ref, trace_id}`; pure, no side effects; executors: worker_fetch, worker_fn, mac_bridge_exec, tenant_device, wfp_tenant, sql, r2, kv, queue.\\n- Persist-before-execute: `proof_runs` row written with cause + raw_invocation before the executor runs (shape from WT-0470; writer from WT-0485 — until WT-0485 lands, write through logEvent with request=raw_invocation and status=started).\\n- Executor adapters, each returning `{confirmation, return, receipt}` separately: HTTP (status + headers + timing), fn (spawn/complete metadata), bridge (`/exec` spawn + exit code + duration), tenant (gate response), SQL (changes/last_row_id/rows).\\n- Cause field on every dispatch: header `x-cause` or body `cause`; default `user_request` for owner key, `model:<run>` when called through /api/mcp, `webhook:<hook>` from /api/hooks, `task:<id>` from CONTRACTS_RUN, `parent:<receipt>` from composition.\\n- The `?invoke=KEY&share=` link form and `=DISPATCH()` cell go through the same resolver (they already reach dispatch.js; they must not resolve separately).\\n\\n## OUT OF SCOPE\\n- New spellings (WT-0472). Plane executors' internals (WT-0474–0483). Ledger storage (WT-0485). Authority decisions (WT-0487) — the resolver asks admin_session for allow/deny and records the answer.\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: POST /api/dispatch (all spellings compile to it)\\n- CAPABILITY: DISPATCH, RESOLVE; every Directory key\\n- OBJECT: a directory row + arguments\\n- ROUTE / CONTEXT: owner key / share token / tenant Bearer / device token → which executor and which device\\n- PROTOCOL: HTTP JSON in; HTTP, local process, SQL, gRPC out\\n- EXECUTOR: Pages Functions Worker; Mac bridge /exec; tenant Worker; tenant device tunnel\\n- PLATFORM: Cloudflare Pages/Workers; the Mac; Workers for Platforms\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS \\\"https://ops.miscsubjects.com/api/directory/D1_QUERY\\\" -H \\\"x-terminal-key: $TERMINAL_KEY\\\"` — one row with how_to_call.\\n- `sed -n 1,120p functions/api/dispatch.js` — the entry and the branch into runHttp/runFn/bridge/tenant.\\n- `grep -n \\\"bridgeRequest\\\" -r functions/_lib functions/api | head`.\\n\\n## CONTRACT (FIELD LAW)\\n- Request: `{key (required, string, existing directory key), args|body (optional; type per row: string for line rows, object for JSON rows; omitted = row example), cause (optional, enum above, default user_request), route (optional: {device, profile, tenant, egress}), dry (optional bool; true = resolve only, returns physical without running)}` plus header x-terminal-key | Authorization: Bearer <tenant> | ?share=<token>. Conflicts: dry with a send-effect row still returns the physical invocation; args and body are one-of.\\n- Response: `{ok, key, trace_id, receipt_id, physical:{…}, confirmation:{…}, return:<any>, error?:{class, layer, detail}}`. `return` is verbatim (JSON or text ≤ 200,000 chars, then truncated with `truncated_at`).\\n\\n## MINIMUM VALID INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"NET_LINE\\\"}'`\\n\\n## FULL / MAXIMUM INVOCATION\\n`curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -H \\\"x-cause: task:WT-0471\\\" -H \\\"x-trace-id: t-2026-09-23-0001\\\" -d '{\\\"key\\\":\\\"LOCAL_EXEC\\\",\\\"body\\\":{\\\"cmd\\\":\\\"uname -a\\\"},\\\"route\\\":{\\\"device\\\":\\\"owner-mac\\\"},\\\"dry\\\":false}'`\\n\\n## RAW CONFIRMATION SHAPE\\nHTTP 200 + `confirmation:{status:200, headers:{…}, ms:<n>}` for HTTP executors; `confirmation:{spawned:true, pid, exit:0, ms}` for bridge; `confirmation:{changes, last_row_id}` for SQL. A refused resolution is HTTP 4xx with `error.class` (unknown_key | capability_required | tenant_unknown | route_unavailable).\\n\\n## RAW RETURN SHAPE\\n`return` holds the executor's payload verbatim; `physical` holds the resolved invocation; `receipt_id` resolves at https://miscsubjects.com/receipt/<id>.\\n\\n## ERROR SHAPES\\n- unknown_key 404\\n- capability_required 401 (Bearer where x-terminal-key is needed)\\n- tenant_unknown 403 (tenant without a `tenants` policy row)\\n- route_unavailable 503 (device offline; bridge 522/timeout) with the raw upstream text\\n- executor_error 502 with the raw return preserved\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\ntrace_id in; receipt_id out; proof_run row with parent_receipt_id when cause=parent:<id>; events row (source=dispatch). The receipt page shows the five fields.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| HTTP executor | D1_QUERY via dispatch → physical.executor=worker_fn, confirmation.changes | live |\\n| bridge executor | LOCAL_EXEC uname → confirmation.exit=0, return has Darwin | live |\\n| tenant executor | ONBOARD_DEMO_KEY (vault) calling NET_LINE → executor=wfp_tenant | live |\\n| dry resolve | dry:true returns physical and no receipt of execution (a resolve receipt only) | live |\\n| persist before execute | kill the executor mid-run (LOCAL_EXEC sleep 120 with a 5 s timeout) → proof_run exists with raw_invocation and confirmation=NONE (timeout) | fixture |\\n| cause propagation | /api/mcp tools/call → cause=model:<run> | live |\\n| link form | GET ?invoke=NET_LINE&share=<CONTRACTS_LINK_TOKEN> → same physical shape | 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\\\": \\\"contains\\\", \\\"id\\\": \\\"dry\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/dispatch?invoke=NET_LINE&dry=1\\\", \\\"needle\\\": \\\"physical\\\"}`\\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 hosts: rows whose url points at a retired workers.dev host (contracts run 2026-09-23 found several; the resolver must refuse with route_unavailable and the raw DNS error, never a bare 5xx)\\n- DNS failure stopping a batch: one unresolvable host must fail one row, not the run\\n- Bearer treated as anonymous on /api/tools/mcp.json (2026-09-22)\\n- transport 2xx ≠ operation success: a 200 wrapping `{\\\"ok\\\":false}` must set error.class=executor_error\\n\\n## DEPENDENCIES\\n- depends_on: WT-0470\\n- OWNS (only this task rewrites): functions/_lib/resolver.js (new); functions/api/dispatch.js (the door; the only rewrite allowed in this set); functions/_lib/invocation_record.js\\n- SHARED (additive edits only): functions/_lib/mac_bridge.js (additive: pass trace/cause headers through); functions/_lib/event_log.js (call it; do not change its shape — WT-0485 does)\\n\\n## HANDOFF FOR NEXT SESSION\\n- Start by writing resolver.js with `dry` support and switching dispatch.js to call it; ship; then add persist-before-execute; ship once per turn (LAW).\\n- The `?invoke=` link and `=DISPATCH()` already enter dispatch.js — verify with the CONTRACTS_LINK_TOKEN link in the vault.\\n- Evidence must include one receipt per executor family (HTTP, fn, bridge, tenant, SQL) showing separate confirmation and return.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- dry:true returns `physical` for every directory row (mechanical, sampled 50 rows with the resolver test in functions/api/dispatch.attenuation.test.mjs extended).\\n- Every executed dispatch has a proof_run/events row with raw_invocation written before execution (evidence: the timeout fixture).\\n- Confirmation, return and receipt are separate fields in the response and in the ledger.\\n- The link form and the sheet cell go through the same resolver (evidence: two receipts with identical `physical`).\\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\",\"priority\":1,\"depends_on\":[\"WT-0470\"],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"evidence_present\",\"id\":\"matrix\",\"field\":\"test_matrix_results\"},{\"type\":\"contains\",\"id\":\"dry\",\"url\":\"https://ops.miscsubjects.com/api/dispatch?invoke=NET_LINE&dry=1\",\"needle\":\"physical\"}],\"evidence_required\":[\"commit\",\"test_matrix_results\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "561bafd496e2d7fd897c20fbb5475723f96d2f1bd280617d7151c086561206b5",
      "hash": "f7105e38e55a58922f91e9b5e763007114db8611e3c352ae1211c110d5dd932e"
    },
    {
      "id": 1222,
      "ts": "2026-09-22T19:51:44-07:00",
      "task_id": "WT-0470",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0470\",\"kind\":\"work\",\"objective\":\"WT-0470 Global Contract Law and Proof Law — the one standard, enforced structurally\",\"detail\":\"# WT-0470 — Global Contract Law and Proof Law — the one standard, enforced structurally\\n\\n## GOAL\\nMake the definition of DONE/PROVEN/LIVE/VERIFIED and the full-contract requirement structural: law rows, a schema that stores contracts and proof fields, a deploy gate that refuses a \\\"proven\\\" claim without the five fields, and a public page that states the law in plain words. Every other task in this set cites this task instead of restating the standard.\\n\\n## WHY THIS EXISTS\\nSessions kept calling capabilities done because a door answered 200, a webhook acknowledged, or a shell command the model ran itself worked. The owner ordered one standard, defined once, binding on every task and every surface, so that no session can call a transport success an operation success again.\\n\\n## CURRENT STATE (measured 2026-09-23)\\n- Law rows PROOF_LAW and CONTRACT_LAW are live in table `laws` (inserted 2026-09-23, rows 127 and 128) and appear in `GET https://ops.miscsubjects.com/api/work` under governing_invariants. CONTRACTS_FORMAT_LAW (the six-column format) has been live since 2026-09-23 too.\\n- Nothing enforces them yet. No table stores a full executable contract per capability; the Directory row has `invocation`, `last_status`, `last_response`, `test_state` (functions/_lib/invocation_record.js) and `how_to_call` (12 spellings), which is a semantic call, not a physical contract.\\n- Deploy gates: 66 scripts named scripts/check-*.mjs run through scripts/gate-run.mjs on `node scripts/land.mjs`. None checks proof fields.\\n- The `capabilities` table in the LEDGER database (not the main DB) holds tokens with tenant_id, device_id, fingerprint, scope — that is authority, not contracts.\\n\\n## SOURCE OF TRUTH\\n- `laws` table in the main D1 database (columns id,key,level,category,rule,rationale,binding_on,can_be_modified_by,added_by,added_at,violations,last_violation_at,enabled). Read them: `GET https://ops.miscsubjects.com/api/work` → governing_invariants. Write them: `POST https://ops.miscsubjects.com/api/dispatch {\\\"key\\\":\\\"D1_EXEC\\\",\\\"body\\\":\\\"INSERT INTO laws (...) ...\\\"}` with header x-terminal-key.\\n- functions/_lib/work_object.js — RUNNABLE_TEST_TYPES, runOneTest, createTask, failTask (child failure tasks).\\n- scripts/gate-run.mjs and scripts/check-*.mjs — how a gate is wired.\\n\\n## IN-SCOPE INVENTORY\\n- Law rows: PROOF_LAW, CONTRACT_LAW, CONTRACTS_FORMAT_LAW (exist); add nothing else unless a task files `law_insufficient`.\\n- New table `capability_contracts` (main DB): key, surface, protocol, executor, platform, min_invocation (JSON), max_invocation (JSON), fields (JSON array of {name,required|optional|conditional,type,enum,default,nullable,cardinality,min,max,format,depends_on,conflicts_with,one_of,omitted_means}), ack_shape (JSON), return_shape (JSON), error_shapes (JSON array), discovered_from, state ∈ {discovered, executable, proven}, proven_receipt, updated_at.\\n- New table `proof_runs` (LEDGER DB, or columns on `events`): cause, raw_invocation, raw_confirmation, raw_return, receipt_id, trace_id, parent_receipt_id, surface, started_at, finished_at — written by WT-0485; the schema is defined here so every plane writes the same shape.\\n- Deploy gate scripts/check-proof-law.mjs: refuses a work-task submit or a directory row `test_state=proven` whose latest proof_run lacks any of the five fields or whose `surface` differs from the declared surface.\\n- Page https://miscsubjects.com/a/proof-law (article, through /api/articles with the writing-law lease) stating the vocabulary and the law in plain English, no jargon, with one worked example per surface family.\\n\\n## OUT OF SCOPE\\n- Running any capability. Building the resolver (WT-0471). Writing the ledger writer (WT-0485). Changing the six-column sheet (WT-0473).\\n\\n## ONTOLOGY (separate axes; never a flat string)\\n- TOOL SURFACE: the law itself is surface-neutral; the gate runs in scripts/land.mjs\\n- CAPABILITY: LAW_READ, LAW_WRITE (D1_EXEC on `laws`), GATE_PROOF\\n- OBJECT: rows of `laws`, `capability_contracts`, `proof_runs`; work-task evidence\\n- ROUTE / CONTEXT: main D1 (site plane) and LEDGER D1 (machine plane); the deploy machine\\n- PROTOCOL: SQL over the dispatch door; Node process for the gate\\n- EXECUTOR: Pages Functions Worker; node on the deploying Mac\\n- PLATFORM: Cloudflare D1 / Pages; the build\\n\\n## DISCOVERY (run these first; they answer, they do not prove)\\n- `curl -sS https://ops.miscsubjects.com/api/work | python3 -c \\\"import json,sys; [print(l['key'], '·', l['rule'][:120]) for l in json.load(sys.stdin)['governing_invariants']]\\\"`\\n- `node -e \\\"import('./scripts/gate-run.mjs')\\\"` is not how gates run; read scripts/land.mjs to see the phase order, then scripts/check-work-acceptance.mjs as the model for a gate that reads work tasks.\\n\\n## CONTRACT (FIELD LAW)\\n- Contract of a law row: key (required, unique, UPPER_SNAKE), level ∈ {constitutional, mutable} (required), category (required, lower-kebab), rule (required, plain prose, ≤ 4,000 chars), rationale (required), binding_on (JSON array; `[\\\"all\\\"]`), added_by (required: agent + session), added_at (ISO with offset), enabled (0/1, default 1). Omitting enabled means enabled. Conflict on key updates rule and rationale only (ON CONFLICT(key) DO UPDATE).\\n- Contract of a capability_contracts row: every field above; `fields` entries are the FIELD LAW itself; `state` defaults to discovered; `proven_receipt` is required when state=proven (CHECK constraint).\\n- Contract of a proof_run: cause (required; one of user_request | task:<WT id> | parent:<receipt id> | event:<id> | webhook:<hook id> | model:<run id>), raw_invocation (required, ≤ 200,000 chars, written BEFORE execution), raw_confirmation (required after execution; may be `NONE (<reason>)`), raw_return (required; failures verbatim), receipt_id (required), trace_id (required), parent_receipt_id (nullable), surface (required; one of the WT-0472 spelling ids or a plane executor id), started_at/finished_at (ISO).\\n\\n## MINIMUM VALID INVOCATION\\nInsert a law: `curl -sS -X POST https://ops.miscsubjects.com/api/dispatch -H \\\"x-terminal-key: $TERMINAL_KEY\\\" -H \\\"content-type: application/json\\\" -d '{\\\"key\\\":\\\"D1_EXEC\\\",\\\"body\\\":\\\"INSERT INTO laws (key,level,category,rule,rationale,binding_on,added_by,added_at,enabled) VALUES (\\\\\\\"X_LAW\\\\\\\",\\\\\\\"mutable\\\\\\\",\\\\\\\"proof\\\\\\\",\\\\\\\"rule text\\\\\\\",\\\\\\\"why\\\\\\\",\\\\\\\"[\\\\\\\\\\\\\\\"all\\\\\\\\\\\\\\\"]\\\\\\\",\\\\\\\"agent\\\\\\\",\\\\\\\"2026-09-23T00:00:00-07:00\\\\\\\",1)\\\"}'` (the key is `grep '^TERMINAL_KEY=' ~/.build-vault.env`).\\n\\n## FULL / MAXIMUM INVOCATION\\nThe same call with can_be_modified_by, violations, last_violation_at set; plus the CHECK-constrained capability_contracts insert with all 17 columns; plus `node scripts/check-proof-law.mjs --task WT-0470 --strict` before landing.\\n\\n## RAW CONFIRMATION SHAPE\\nD1_EXEC returns `{\\\"ok\\\":true,\\\"result\\\":{\\\"changes\\\":1,\\\"last_row_id\\\":<n>}}` with HTTP 200; a refused governed table returns HTTP 403 `{\\\"ok\\\":false,\\\"error\\\":\\\"governed_table\\\",...}` (functions/_lib/governed_tables.js).\\n\\n## RAW RETURN SHAPE\\n`GET /api/work` → governing_invariants contains the row; `SELECT * FROM laws WHERE key=?` returns it; the gate prints `proof-law: <n> claims examined, <m> refused` and exits 0/1.\\n\\n## ERROR SHAPES\\n- `D1_ERROR: no such table` (schema not migrated; add migrations/0484_capability_contracts.sql and land it).\\n- `governed_table` 403 when writing work_tasks/articles/directory through D1_EXEC.\\n- `unknown_fields` 400 / `acceptance_test_not_executable` 422 from createTask.\\n- Gate exit 1 with the list of claims lacking fields (never suppress; fix the claim).\\n\\n## RECEIPT / TRACE / PARENT LINKAGE\\nEvery D1_EXEC through the dispatch door writes an events row (source=dispatch, key=D1_EXEC) and a receipt at https://miscsubjects.com/receipt/<id>; cite the receipt id of the law insert and of the migration in evidence.\\n\\n## TEST MATRIX\\n| case | what runs | kind |\\n|---|---|---|\\n| law rows readable | GET /api/work governing_invariants has PROOF_LAW and CONTRACT_LAW | live |\\n| schema exists | SELECT COUNT(*) FROM capability_contracts returns 0 or more (no error) | migration |\\n| gate refuses | a fixture task with evidence.verification=\\\"HTTP 200\\\" and no raw_return is refused by check-proof-law.mjs | fixture |\\n| gate accepts | a fixture with all five fields and surface matching passes | fixture |\\n| page renders | https://miscsubjects.com/a/proof-law returns the vocabulary words and the phrase \\\"An HTTP 200 proves an HTTP 200\\\" | live |\\n| amendment path | POST /api/work/task/WT-0470/fail with failure_class law_insufficient creates a child WF task | live |\\n\\n## ACCEPTANCE TESTS (mechanical; the infrastructure runs them)\\n- `{\\\"type\\\": \\\"sql_count_at_least\\\", \\\"id\\\": \\\"laws\\\", \\\"sql\\\": \\\"SELECT COUNT(*) AS n FROM laws WHERE enabled=1 AND key IN ('PROOF_LAW','CONTRACT_LAW')\\\", \\\"min\\\": 2}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"work_object\\\", \\\"url\\\": \\\"https://ops.miscsubjects.com/api/work\\\", \\\"needle\\\": \\\"PROOF_LAW\\\"}`\\n- `{\\\"type\\\": \\\"http_ok\\\", \\\"id\\\": \\\"page\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/proof-law\\\"}`\\n- `{\\\"type\\\": \\\"contains\\\", \\\"id\\\": \\\"page_text\\\", \\\"url\\\": \\\"https://miscsubjects.com/a/proof-law\\\", \\\"needle\\\": \\\"An HTTP 200 proves an HTTP 200\\\"}`\\n- `{\\\"type\\\": \\\"evidence_present\\\", \\\"id\\\": \\\"commit\\\", \\\"field\\\": \\\"commit\\\"}`\\n- `{\\\"type\\\": \\\"evidence_present\\\", \\\"id\\\": \\\"gate\\\", \\\"field\\\": \\\"gate_run\\\"}`\\n- `{\\\"type\\\": \\\"evidence_present\\\", \\\"id\\\": \\\"live\\\", \\\"field\\\": \\\"verification\\\"}`\\nEvidence fields the submitting agent supplies: commit, gate_run, 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- transport 2xx treated as success (the whole 2026-09 CONTRACTS run: 1,698 HTTP 2xx rows of 10,072 were counted as \\\"answered\\\", not as \\\"the operation succeeded\\\")\\n- `--help` exit 0 accepted as capability proof (cli_tools layer)\\n- a model running a command itself and reporting the surface as proven (every session before 2026-09-23)\\n\\n## DEPENDENCIES\\n- depends_on: none (parallel start)\\n- OWNS (only this task rewrites): migrations/0484_capability_contracts.sql (new); scripts/check-proof-law.mjs (new); article proof-law (new); rows PROOF_LAW / CONTRACT_LAW in `laws`\\n- SHARED (additive edits only): functions/_lib/work_object.js — additive only: export the proof_run shape as a constant other tasks import; do not change createTask or runOneTest semantics; scripts/land.mjs — wire the new gate the way the 66 existing gates are wired\\n\\n## HANDOFF FOR NEXT SESSION\\n- If the migration landed but the gate is not wired: `grep -n check-work-acceptance scripts/land.mjs` shows the wiring pattern.\\n- If the article was refused by the writing law: take the lease (`POST /api/writing-law/lease`, 13 attestations; quotes must exist in the body) and remove \\\"this page\\\" sentences.\\n- State in evidence: receipts of the two law inserts, the migration commit, the gate run output with the count of claims examined.\\n\\n## DONE LAW (this task is done when every line is true and evidenced; not before)\\n- Both laws present in governing_invariants (mechanical).\\n- capability_contracts and proof_runs exist with CHECK constraints (mechanical).\\n- check-proof-law.mjs runs in land.mjs and refuses the fixture (evidence: gate_run output).\\n- https://miscsubjects.com/a/proof-law renders the vocabulary (mechanical).\\n- Every subsequent task cites this id; no task carries its own definition of proof.\\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\",\"priority\":1,\"depends_on\":[],\"capabilities\":[\"dispatch\",\"d1\",\"bridge\",\"sheets\",\"receipts\"],\"acceptance\":[{\"type\":\"sql_count_at_least\",\"id\":\"laws\",\"sql\":\"SELECT COUNT(*) AS n FROM laws WHERE enabled=1 AND key IN ('PROOF_LAW','CONTRACT_LAW')\",\"min\":2},{\"type\":\"contains\",\"id\":\"work_object\",\"url\":\"https://ops.miscsubjects.com/api/work\",\"needle\":\"PROOF_LAW\"},{\"type\":\"http_ok\",\"id\":\"page\",\"url\":\"https://miscsubjects.com/a/proof-law\"},{\"type\":\"contains\",\"id\":\"page_text\",\"url\":\"https://miscsubjects.com/a/proof-law\",\"needle\":\"An HTTP 200 proves an HTTP 200\"},{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"gate\",\"field\":\"gate_run\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"gate_run\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "26cc9658c63b87faff3e33bab78f9ed538bae83067a59f01f2a0b2ca66ae5cf2",
      "hash": "561bafd496e2d7fd897c20fbb5475723f96d2f1bd280617d7151c086561206b5"
    },
    {
      "id": 1221,
      "ts": "2026-09-22T12:39:50-07:00",
      "task_id": "WT-0453",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "45de308dfcd67266a7cd2baedbf7b36ab01f5619ab7fbc0d5f6d037d07e5d6ca",
      "hash": "26cc9658c63b87faff3e33bab78f9ed538bae83067a59f01f2a0b2ca66ae5cf2"
    },
    {
      "id": 1220,
      "ts": "2026-09-22T12:39:50-07:00",
      "task_id": "WT-0453",
      "action": "submit",
      "agent": "claude-fable-5.1 session 9adc6e91",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"697135d8f\",\"verification\":\"Live 2026-09-22: Console MCP global listed set saved with 31 tools (POST /api/console/mcp action=save): misc_find, misc_run, WEB_SEARCH, NET_SEARCH, NET_LINE, SURFACE_SEARCH, SURFACE_EXECUTE, BRIDGE_REGISTER, BRIDGE_ACT, ONBOARD, DEVICE_REGISTER, STARLINK_STATUS + the previous 19; the four attached models (openrouter/gateway × glm-5.3-flash, deepseek-v4-flash) and zhipu inherit it (each reports listed 31); POST /api/mcp tools/list with the MCP token returns the 31. Hybrid hot set: the nine rows set to planner_rank 0 through PATCH /api/directory/<key> so /api/tools/mcp.json (default hot 12) hands NET_SEARCH, SURFACE_SEARCH, WEB_SEARCH first (the remaining slots are the rank-1 META_* rows; the projection index caches per isolate and converges within its TTL). muse-worker R2 cache/build_tools.json rewritten from the live list (31 tools, at 2026-09-22T19:36Z) and read back with the ten new names present; profiles.js refreshes it on every live fetch. /tools TIER_1 lists the same set.\",\"changed\":[\"functions/tools.js\",\"migrations/0483_onboard_devices.sql (planner ranks)\",\"directory rows planner_rank (PATCH)\",\"KV console.mcp.v1 listed\",\"R2 muse-worker cache/build_tools.json\"]}}",
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"697135d8f\",\"verification\":\"Live 2026-09-22: Console MCP global listed set saved with 31 tools (POST /api/console/mcp action=save): misc_find, misc_run, WEB_SEARCH, NET_SEARCH, NET_LINE, SURFACE_SEARCH, SURFACE_EXECUTE, BRIDGE_REGISTER, BRIDGE_ACT, ONBOARD, DEVICE_REGISTER, STARLINK_STATUS + the previous 19; the four attached models (openrouter/gateway × glm-5.3-flash, deepseek-v4-flash) and zhipu inherit it (each reports listed 31); POST /api/mcp tools/list with the MCP token returns the 31. Hybrid hot set: the nine rows set to planner_rank 0 through PATCH /api/directory/<key> so /api/tools/mcp.json (default hot 12) hands NET_SEARCH, SURFACE_SEARCH, WEB_SEARCH first (the remaining slots are the rank-1 META_* rows; the projection index caches per isolate and converges within its TTL). muse-worker R2 cache/build_tools.json rewritten from the live list (31 tools, at 2026-09-22T19:36Z) and read back with the ten new names present; profiles.js refreshes it on every live fetch. /tools TIER_1 lists the same set.\",\"changed\":[\"functions/tools.js\",\"migrations/0483_onboard_devices.sql (planner ranks)\",\"directory rows planner_rank (PATCH)\",\"KV console.mcp.v1 listed\",\"R2 muse-worker cache/build_tools.json\"]}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "8862627c96e9ba59331d86e1862dea53f56a8c3406540b691bb6bb6fcd183996",
      "hash": "45de308dfcd67266a7cd2baedbf7b36ab01f5619ab7fbc0d5f6d037d07e5d6ca"
    },
    {
      "id": 1219,
      "ts": "2026-09-22T12:39:43-07:00",
      "task_id": "WT-0459",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "eeeb6a767960a46371703e77ee26971ae2b56f7ebf3e4bc17b621bd0b81626f3",
      "hash": "8862627c96e9ba59331d86e1862dea53f56a8c3406540b691bb6bb6fcd183996"
    },
    {
      "id": 1218,
      "ts": "2026-09-22T12:39:43-07:00",
      "task_id": "WT-0459",
      "action": "submit",
      "agent": "claude-fable-5.1 session 9adc6e91",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"697135d8f + af0ee3a58\",\"verification\":\"Live 2026-09-22: POST https://ops.miscsubjects.com/api/onboard/invites (owner) → invite; POST /api/onboard with the invite → tenant t_kit-test, key fingerprint cap_656208f8834619ac (scope rows: NET,SURFACE,BRIDGE,TEXT,ONBOARD + 13 tool rows, 10 y), Worker kit-test created in Workers for Platforms namespace production, reachable at https://gate.miscsubjects.com/kit-test/ (card, 200, x-namespace production); …/api/net {ip} with the key forwarded + receipted; no key / wrong key → 401; …/mcp tools/list with the key → 15 bounded tools; second use of the invite → 401 (spent). Device kit: curl -sSL https://miscsubjects.com/device-kit/install.sh | ONBOARD_KEY=<key> sh registered device mac:kit-test-kit-test-mac (dev_5b80c1bfdddd), run.sh started bridge :3100 + quick tunnel and reported the endpoint; GET /api/onboard/devices/dev_5b80c1bfdddd/health ok (2.2 s); POST /api/net {ip} / {line}, GET /api/bridges/controllers, GET /api/surface/search with the tenant key all answered from that device (device field in every answer); POST /api/dispatch {key:NET_IP} with the tenant key ran on the device (delegation) after the ledger tenants policy row (now written at onboarding). Guide: /api/onboard/guide (9 sections); page /onboard; offering own_key_own_device in /api/offerings.\",\"changed\":[\"functions/api/onboard/[[path]].js\",\"functions/onboard.js\",\"functions/_lib/onboard_contract.js\",\"functions/_lib/tenant_devices.js\",\"functions/_lib/wfp_worker.js\",\"functions/_lib/mac_bridge.js\",\"functions/api/net/[[path]].js\",\"functions/api/surface/[[path]].js\",\"functions/api/bridges/[[path]].js\",\"functions/api/dispatch.js\",\"functions/_lib/offerings.js\",\"functions/_lib/bridge_contract.js\",\"migrations/0483_onboard_devices.sql\",\"public/device-kit/*\",\"scripts/wfp-tenant.mjs\",\"scripts/device-kit-sync.mjs\",\"Worker wfp-gate (production + staging bound, custom domain gate.miscsubjects.com)\"]}}",
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"697135d8f + af0ee3a58\",\"verification\":\"Live 2026-09-22: POST https://ops.miscsubjects.com/api/onboard/invites (owner) → invite; POST /api/onboard with the invite → tenant t_kit-test, key fingerprint cap_656208f8834619ac (scope rows: NET,SURFACE,BRIDGE,TEXT,ONBOARD + 13 tool rows, 10 y), Worker kit-test created in Workers for Platforms namespace production, reachable at https://gate.miscsubjects.com/kit-test/ (card, 200, x-namespace production); …/api/net {ip} with the key forwarded + receipted; no key / wrong key → 401; …/mcp tools/list with the key → 15 bounded tools; second use of the invite → 401 (spent). Device kit: curl -sSL https://miscsubjects.com/device-kit/install.sh | ONBOARD_KEY=<key> sh registered device mac:kit-test-kit-test-mac (dev_5b80c1bfdddd), run.sh started bridge :3100 + quick tunnel and reported the endpoint; GET /api/onboard/devices/dev_5b80c1bfdddd/health ok (2.2 s); POST /api/net {ip} / {line}, GET /api/bridges/controllers, GET /api/surface/search with the tenant key all answered from that device (device field in every answer); POST /api/dispatch {key:NET_IP} with the tenant key ran on the device (delegation) after the ledger tenants policy row (now written at onboarding). Guide: /api/onboard/guide (9 sections); page /onboard; offering own_key_own_device in /api/offerings.\",\"changed\":[\"functions/api/onboard/[[path]].js\",\"functions/onboard.js\",\"functions/_lib/onboard_contract.js\",\"functions/_lib/tenant_devices.js\",\"functions/_lib/wfp_worker.js\",\"functions/_lib/mac_bridge.js\",\"functions/api/net/[[path]].js\",\"functions/api/surface/[[path]].js\",\"functions/api/bridges/[[path]].js\",\"functions/api/dispatch.js\",\"functions/_lib/offerings.js\",\"functions/_lib/bridge_contract.js\",\"migrations/0483_onboard_devices.sql\",\"public/device-kit/*\",\"scripts/wfp-tenant.mjs\",\"scripts/device-kit-sync.mjs\",\"Worker wfp-gate (production + staging bound, custom domain gate.miscsubjects.com)\"]}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "8b4397868b2cea4ad83c684e9cbde7ec3090091eeb8602e1ef13f801044e36e3",
      "hash": "eeeb6a767960a46371703e77ee26971ae2b56f7ebf3e4bc17b621bd0b81626f3"
    },
    {
      "id": 1217,
      "ts": "2026-09-22T03:27:30-07:00",
      "task_id": "WT-0462",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Always-on Mac for the Mac-backed tools (net/surface/bridge) so worker calls do not fail when the laptop sleeps\",\"detail\":\"net, surface and bridge controllers execute on the owner's Mac via the bridge; if it sleeps/off, worker calls fail. Provision a hosted/always-on Mac (or a caffeinate + wake plan) so the tools are reliably available to the workers, and document which tools are hard-dependent on it.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "6a75d255b8d4d7d04d2022a537ea1c96be69b9de00448ad7bd4d3c8965c2c558",
      "hash": "8b4397868b2cea4ad83c684e9cbde7ec3090091eeb8602e1ef13f801044e36e3"
    },
    {
      "id": 1216,
      "ts": "2026-09-22T03:27:29-07:00",
      "task_id": "WT-0461",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Metering + billing on the sellable tools (net calls, cloud profiles, lines, capabilities) so offerings can actually be charged\",\"detail\":\"No per-tenant metering exists on /api/net, bridges or lines. Add usage counting per key/tenant (calls, GB, profile-months) and a way to read it, so the offerings on /offer can be priced and billed.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "88e893762ff6e092e2687123ca1fa9d681d2dafe6368b18f0361119651ee46bc",
      "hash": "6a75d255b8d4d7d04d2022a537ea1c96be69b9de00448ad7bd4d3c8965c2c558"
    },
    {
      "id": 1215,
      "ts": "2026-09-22T03:27:28-07:00",
      "task_id": "WT-0460",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"A number with a model on it: make the per-line -> agent binding explicit and configurable (not only the seeded ROUTER/BLOOIO2)\",\"detail\":\"Inbound routing to a per-line agent works for ROUTER/BLOOIO2 but the mapping is implicit. Add a documented way to bind a chosen agent (model+prompt+allowed tools) to a specific line/account so 'a number with a model on it' is a first-class configure step.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "dd76788fe307f7298d51b734721758c4b93257af5f71b625637f1ba9750b762d",
      "hash": "88e893762ff6e092e2687123ca1fa9d681d2dafe6368b18f0361119651ee46bc"
    },
    {
      "id": 1214,
      "ts": "2026-09-22T03:27:27-07:00",
      "task_id": "WT-0459",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"One-call onboarding endpoints so an offering is provisioned in a single call\",\"detail\":\"Offerings today are multi-step. Build: POST that provisions a text account + assigns a line + (optionally) binds a model agent + registers a webhook and returns the key and links; and the same for a cloud-profile customer. So the operator closes and delivers in one call.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2605657d1e4167e3c5decfcc9d420d495631c4cf145c994ab708926b28a8b666",
      "hash": "dd76788fe307f7298d51b734721758c4b93257af5f71b625637f1ba9750b762d"
    },
    {
      "id": 1213,
      "ts": "2026-09-22T03:27:26-07:00",
      "task_id": "WT-0458",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"AdsPower cloud-profile ops: verify create/start/stop/update/fingerprint end to end with the desktop app running\",\"detail\":\"bridge adspower ops are wired to the Local API but untested while the app was closed (returns adspower_unreachable). With AdsPower open, create a profile with a fingerprint + proxy, start it, confirm egress + fingerprint via bridge/adspower-verify.sh, stop it. Never on the owner's screen unless asked.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "27640488fffa19ba9509600d3bc17acbb006feb5a8fd1ff282b38e64f371f00b",
      "hash": "2605657d1e4167e3c5decfcc9d420d495631c4cf145c994ab708926b28a8b666"
    },
    {
      "id": 1212,
      "ts": "2026-09-22T03:27:26-07:00",
      "task_id": "WT-0457",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Bridge: a long-lived browser session so single acts hold a page open between calls (not one launch per act)\",\"detail\":\"Each POST /api/bridges/{id}/act is its own Playwright launch; multi-step interactive control needs a persistent page. Add a keep-alive session (a small daemon or a Durable Object holding the context) so act calls share one live page. Verify two acts against one open page.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "bb30260c1e4aa51861b13e6e272d738714be6ddc4feae5fb6b953e7fdac0c673",
      "hash": "27640488fffa19ba9509600d3bc17acbb006feb5a8fd1ff282b38e64f371f00b"
    },
    {
      "id": 1211,
      "ts": "2026-09-22T03:27:25-07:00",
      "task_id": "WT-0456",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Bridge pairing: wire the QR/linked-device read-back so PAIR returns a scannable artifact\",\"detail\":\"/api/bridges/{id}/pair records intent only; make it drive a browser bridge to the service's linked-devices page, snapshot the QR, and return it (or its image) so the operator scans it. Verify with one service end to end.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "61c9a4f5c18e0ea77edb8e2fd9ae977769d2a94cb1f8a67de77efc087043cbd2",
      "hash": "bb30260c1e4aa51861b13e6e272d738714be6ddc4feae5fb6b953e7fdac0c673"
    },
    {
      "id": 1210,
      "ts": "2026-09-22T03:27:24-07:00",
      "task_id": "WT-0455",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Net contents: real readability extraction (strip boilerplate/nav, main-article text) instead of full-body strip\",\"detail\":\"net search contents currently strips all tags and returns body text; add a readability pass (largest text block / article heuristics) and dedupe whitespace so a model gets clean article text. Verify on 3 news pages.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "9c5bf5f1cf500774de2e26657bc4fd8813ec1e98d160a9f015735e0dd1683ab2",
      "hash": "61c9a4f5c18e0ea77edb8e2fd9ae977769d2a94cb1f8a67de77efc087043cbd2"
    },
    {
      "id": 1209,
      "ts": "2026-09-22T03:27:23-07:00",
      "task_id": "WT-0454",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Net search: fix the Mojeek engine parser and add real SERP fallback so multi-engine actually merges more than DuckDuckGo\",\"detail\":\"net() in bridge/bridge-run.py: Mojeek returned zero results (markup mismatch); Brave html is JS-gated. Fix the Mojeek regex, add a second reliable no-key engine or a keyed SERP fallback, and make engines fail over. Verify a query returns results tagged from >=2 engines.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "56969e0358fa3d320429e87db1508601d894390842622142e4c11310ae9eee7f",
      "hash": "9c5bf5f1cf500774de2e26657bc4fd8813ec1e98d160a9f015735e0dd1683ab2"
    },
    {
      "id": 1208,
      "ts": "2026-09-22T03:27:22-07:00",
      "task_id": "WT-0453",
      "action": "create",
      "agent": "claude-opus-4.8",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Tool availability on the workers: put WEB_SEARCH, NET_SEARCH, SURFACE_SEARCH and BRIDGE_REGISTER in the on-hand hot set and confirm the R2 worker cache carries them\",\"detail\":\"buildToolsList (functions/api/mcp.js) hands the first ~12 typed tools plus misc_find/misc_run; the new tools are FINDable and dispatch-executable (verified via miscsubjects.com/api/dispatch, no 522) but not in the handed hot set (/api/tools/mcp.json shows 14 without them). Add them to the hot selection (planner_rank/order) so workers get them without a FIND, and verify muse-worker R2 cache/build_tools.json (refreshed each minute by profiles.js) includes them.\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-4.8\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "7a25fe8a1363f34d10d8649def9aa7227a9da872225ddfb91c8505cc0ff8ab57",
      "hash": "56969e0358fa3d320429e87db1508601d894390842622142e4c11310ae9eee7f"
    },
    {
      "id": 1207,
      "ts": "2026-09-22T01:24:49-07:00",
      "task_id": "WT-0452",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Capability expiry format: text account keys record expires_at as epoch seconds, which the dispatch door reads as expired (Date.parse); align text_tenancy.mintTenantKey and its readers to ISO strings and repair existing rows\",\"detail\":\"Failure class: representation_mismatch. Layer: the capability store (LEDGER.capabilities). Evidence 2026-09-22: a surface key minted with expires_at = epoch was refused on /api/dispatch?share= with error expired while /api/surface accepted it; functions/_lib/admin_session.js capabilityChainStatus parses expires_at with Date.parse. The surface keys door was fixed (ISO). text_tenancy.mintTenantKey still writes epoch; /api/text/accounts renders it as epoch. Missing invariant: one writer for capability rows (dispatch mintCapability) or a schema check on the column format.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "d18279292221d427d27493dd4f057edcb012acda76822ad227cb12051f0fc837",
      "hash": "7a25fe8a1363f34d10d8649def9aa7227a9da872225ddfb91c8505cc0ff8ab57"
    },
    {
      "id": 1206,
      "ts": "2026-09-22T00:53:27-07:00",
      "task_id": "WT-0441",
      "action": "progress",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": "owner-key",
      "task_revision": 1,
      "from_state": "open",
      "to_state": "in_progress",
      "input": "{\"note\":\"Shipped 689d5f766: ids + run blocks on every row; POST /api/surface/execute and /compose live; GET /api/surface/spec is the machine spec. Verified live: shell (receipt a9557d52-bd8a-4d10-82ea-769cc8255b2a), defaults (5634e2b4-c290-4136-9b18-be1c854c3e1b), atom SURFACE_DOCK_TILE_SIZE composed (04035e81-955c-4556-b538-7133d2b9097b) and dispatched; on the Mac: jxa command + class, ax, mirror read, phone, continuity, chain, automation, shortcut import. Remaining before submit: menu (acts on the owner screen), intent / shortcut_action / shortcut run (blocked by the shortcuts run hang, WT-0442).\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2bf03c53f06d60d7fc3bb4bbc5e32d9dd881e4c35879a4148c1b0eb96296dc09",
      "hash": "d18279292221d427d27493dd4f057edcb012acda76822ad227cb12051f0fc837"
    },
    {
      "id": 1205,
      "ts": "2026-09-22T00:43:59-07:00",
      "task_id": "WT-0451",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Composed tools housekeeping: delete a composed shortcut through Shortcuts (no CLI delete), list and forget automations from the Worker\",\"detail\":\"surface-run.py forget <id> unloads a launchd job and removes its plist; a shortcut it made stays in Shortcuts. Add a UI-scripted delete and a Worker route DELETE /api/surface/verbs/<id> for composed rows. The probe shortcut named probe-signed from 2026-09-22 can be removed with it.\",\"priority\":5,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "23e5f6b33060ba32c785a008da802bc1c632af8880abe02b7e0f8adcfc48f1fc",
      "hash": "2bf03c53f06d60d7fc3bb4bbc5e32d9dd881e4c35879a4148c1b0eb96296dc09"
    },
    {
      "id": 1204,
      "ts": "2026-09-22T00:43:58-07:00",
      "task_id": "WT-0450",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Own-number customers: onboarding one hosted Mac user per Apple Account running the watcher and the bridge\",\"detail\":\"Nothing built. Each customer's Apple Account signs in on its own macOS user on a hosted Mac; the watcher posts to /api/text/events; the account's senders are that Apple ID's aliases.\",\"priority\":5,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2c51b8b33955120256c9229852f7cbf964b70e84cecd38b0215de117a12f1c5e",
      "hash": "23e5f6b33060ba32c785a008da802bc1c632af8880abe02b7e0f8adcfc48f1fc"
    },
    {
      "id": 1203,
      "ts": "2026-09-22T00:43:56-07:00",
      "task_id": "WT-0449",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Text door vs Blooio: the remaining parity items measured (OAuth log-in-with, apikeys:manage scope, per-key channel assignment, MCP tool listing of TEXT, llms.txt)\",\"detail\":\"Keys, webhooks, HMAC signing secrets, rotate, deliveries, replay and test are live and proven (account t_test-customer, key cap_2e8f8f99c8f028ed, hook twh_3c494h3t082g, 2 deliveries). Measure each remaining item against /a/blooio and record live / not built on /api/text/docs.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "1904e78157f8d44c29e21096db4fb033552b35e23fc986e19caf721e5396a212",
      "hash": "2c51b8b33955120256c9229852f7cbf964b70e84cecd38b0215de117a12f1c5e"
    },
    {
      "id": 1202,
      "ts": "2026-09-22T00:43:54-07:00",
      "task_id": "WT-0448",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Encyclopedia next layers: .appex App Intents, third-party apps outside /Applications, phone settings via lockdown, HomeKit accessories, Apple Watch, menus of apps not running\",\"detail\":\"Compiler ~/bin/surface-verbs.py; each layer is one function returning rows through V(); ids and run blocks are computed on read by ~/bin/surface-run.py, so a new layer needs a run kind there too.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "5a821c194a365d0bfe9bb62a34e9ab80010ddc458b5f59168b296f0ae3ecb09a",
      "hash": "1904e78157f8d44c29e21096db4fb033552b35e23fc986e19caf721e5396a212"
    },
    {
      "id": 1201,
      "ts": "2026-09-22T00:43:52-07:00",
      "task_id": "WT-0447",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Private iMessage verbs (typing, read receipts, polls, edit, unsend, effects, stickers, group management) on a dedicated Mac with SIP off\",\"detail\":\"The 42 rpc methods in /api/text/verbs and the rpc run kind on /api/surface become live once csrutil disable and imsg launch run on a dedicated Mac. Never on the owner's laptop.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "cda86d8714c394fc1696410815d441b6eabfd685dd128dd23fa7ca1139f3b268",
      "hash": "5a821c194a365d0bfe9bb62a34e9ab80010ddc458b5f59168b296f0ae3ecb09a"
    },
    {
      "id": 1200,
      "ts": "2026-09-22T00:43:50-07:00",
      "task_id": "WT-0446",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Voice note after an alias switch sometimes drops its audio (audio_attachment_dropped); find the cause\",\"detail\":\"Rows 679747, 679751, 679765, 679769, 679783 dropped; 679785 attached. The switch restarts imagent. Try a longer settle, steer with a text first, or the private API. No cause without evidence.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "3a11fa56418b1ead74ec6e8ea8e46d4a3ab5dffaa7995ac79c21a00b298a5a84",
      "hash": "cda86d8714c394fc1696410815d441b6eabfd685dd128dd23fa7ca1139f3b268"
    },
    {
      "id": 1199,
      "ts": "2026-09-22T00:43:47-07:00",
      "task_id": "WT-0445",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Encyclopedia sheet sh_gyvgncdv: reconcile to 8,764 rows (loader appends about 1.3 rows/s; it was at 1,050 at 00:27 PDT 2026-09-22)\",\"detail\":\"Loader ~/.imsg/surface/build-sheet.mjs, log sheet.log, marker rebuild.done. Verify csv rows == sheet rows; if the process died, rerun with the vault loaded (it creates a new sheet; delete the partial one). Then add the id and run columns the rows now carry.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "e44654ff6bfb9296391eacc39c5b72afedd837aecee60c11f75038d47e800d4f",
      "hash": "3a11fa56418b1ead74ec6e8ea8e46d4a3ab5dffaa7995ac79c21a00b298a5a84"
    },
    {
      "id": 1198,
      "ts": "2026-09-22T00:43:45-07:00",
      "task_id": "WT-0444",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Phone-side automations from the API: create a Personal Automation through the iPhone Mirroring window so the 62 triggers become composable\",\"detail\":\"The ui_scripting layer already sees the iPhone Mirroring window; compose {kind:automation, trigger:<one of shortcuts_triggers>} should drive Shortcuts on the phone (Automation tab, +, trigger, action Get Contents of URL to the build). Verify one time-of-day automation that posts to /api/phone/in.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "017c3fb1a15623fed620314290efa2fd56143178b2c8f2816afca89d44db86b7",
      "hash": "e44654ff6bfb9296391eacc39c5b72afedd837aecee60c11f75038d47e800d4f"
    },
    {
      "id": 1197,
      "ts": "2026-09-22T00:43:43-07:00",
      "task_id": "WT-0443",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"App Intents as actions: identifier is <bundle id>.<IntentName>; verify three intents end to end through /api/surface/execute\",\"detail\":\"Proven from stored shortcuts: com.apple.AccessibilityUtilities.AXSettingsShortcuts.AXToggleVoiceControlIntent, com.culturedcode.ThingsiPhone.TINAddTodoIntent. The executor composes a one-action wrapper shortcut and runs it; intents inside .appex extensions need the extension's bundle id, not the app's. Depends on the shortcuts run hang being cleared.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "f86a1e4ea0e2cfb6f96a80a8011dc8f4191fc19fd7f720361bd337e9bedfe403",
      "hash": "017c3fb1a15623fed620314290efa2fd56143178b2c8f2816afca89d44db86b7"
    },
    {
      "id": 1196,
      "ts": "2026-09-22T00:43:41-07:00",
      "task_id": "WT-0442",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"shortcuts run hangs on the owner's Mac: find the cause and make the shortcut, intent and shortcut_action kinds run\",\"detail\":\"Failure class: executor_hang. Layer: the Mac (siriactionsd / Shortcuts). Measured 2026-09-22 00:35 PDT: `shortcuts run \\\"Get Clipboard\\\" -o file` never returns (25 s and 60 s timeouts, also through APPLE_SHORTCUT over the bridge); `shortcuts list`, `shortcuts sign` and a scripted import (open -g + System Events click on the unnamed Add button) work. No dialog was visible in System Events. Cause unknown; do not restart system daemons without evidence. Missing invariant: an executor whose call can block forever must have a watchdog and a measured status row.\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "364a7d5fc53211905e31f956826784d0cf73ea31083da356b23813fe5ad920ae",
      "hash": "f86a1e4ea0e2cfb6f96a80a8011dc8f4191fc19fd7f720361bd337e9bedfe403"
    },
    {
      "id": 1195,
      "ts": "2026-09-22T00:43:38-07:00",
      "task_id": "WT-0441",
      "action": "create",
      "agent": "claude-fable-5.1",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Surface execute door: verify every run kind against one live verb per layer and record the matrix on /api/surface/spec\",\"detail\":\"Kinds: shell, defaults, jxa (command + class read), menu, ax, mirror, phone (pymobiledevice3 + devicectl), intent, shortcut_action, rpc (SIP-gated), continuity, dispatch, observe, composed shortcut/automation/chain/atom. Each verified kind gets the id it was proven with and the receipt id. Unverified kinds stay marked unverified in the spec until a receipt exists.\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-fable-5.1\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "037025f4de29b94312e5213bdace24f995a8fca292e5c5569a30754acfee5560",
      "hash": "364a7d5fc53211905e31f956826784d0cf73ea31083da356b23813fe5ad920ae"
    },
    {
      "id": 1194,
      "ts": "2026-09-21T20:34:47-07:00",
      "task_id": "WT-0440",
      "action": "progress",
      "agent": "owner-key",
      "model": null,
      "capability": "owner-key",
      "task_revision": 1,
      "from_state": "open",
      "to_state": "in_progress",
      "input": "{\"note\":\"Pricing precedent researched 2026-09-21 across eight categories (iMessage APIs, AI receptionists, WhatsApp resellers, lead-gen agencies and tools, local lead marketplaces, ads agencies and AI creative, review management, AI agency retainers, Shopify plans/apps/fees): ~90 vendors, every figure with its URL, unconfirmed ones marked. Spec + one-page table: ~/Downloads/shopify-2026-09-21/1-spec.md; lane briefs in research/. Still blocked on SHOPIFY_STORE_DOMAIN and SHOPIFY_ADMIN_TOKEN in the vault.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "61686d22eeab6a982e977c8bd4cd64b9500e05677fa41be44e98f5e158c123b8",
      "hash": "037025f4de29b94312e5213bdace24f995a8fca292e5c5569a30754acfee5560"
    },
    {
      "id": 1193,
      "ts": "2026-09-21T20:27:40-07:00",
      "task_id": "WT-0440",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Shopify integration: every service the site shows as a tile is a Shopify product with setup and monthly variants; prices are assigned by the build from precedent rows and its own measured cost lines through PRICE_PRECEDENT, PRICE_ASSIGN and PRICE_PUBLISH (publish behind a switchboard cell); checkout permalinks rendered server-side in the tile modals; orders and subscriptions webhook into the ledger and open onboarding rows\",\"detail\":\"Spec: ~/Downloads/shopify-2026-09-21/1-spec.md. Blocked until SHOPIFY_STORE_DOMAIN and SHOPIFY_ADMIN_TOKEN exist in the vault; no token is anywhere the build can read as of 2026-09-21 21:05 PT. Test: a $0 test product bought end to end shows its order on the ledger with the receipt on the buyer channel.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "5416c55e4d41e5d96387a5152d0e558189b6414f8c2f0cd06632badaa6a95686",
      "hash": "61686d22eeab6a982e977c8bd4cd64b9500e05677fa41be44e98f5e158c123b8"
    },
    {
      "id": 1192,
      "ts": "2026-09-21T20:02:06-07:00",
      "task_id": "WT-0420",
      "action": "progress",
      "agent": "owner-key",
      "model": null,
      "capability": "owner-key",
      "task_revision": 4,
      "from_state": "completed",
      "to_state": "in_progress",
      "input": "{\"note\":\"Rebuilt on the approved design after the owner rejected the text page (commits 363da2dd9, edac52977): the root is the taken-apart scenes as the frame, then this visit taken apart (signal cards from /api/traffic/self), one text becoming one row inside an iMessage thread on the line, the last hour of the record as a ticker from /api/ledger/public, every feature as a live tile (price fields stripped from the tile data), the articles as tiles in the same grid with live counts and the posted-versus-updated stamp, the CTA, and every existing destination as a compact footer. Live check: 5 scenes, 24 feature tiles, 36 article tiles, 9 signal cards, 14 ticker rows, 16 service pills; owner-data sweep clean.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "93f1117be0b14360df4ac16d7af84a3ade94da9fc91efea95c27ab60296cbd9a",
      "hash": "5416c55e4d41e5d96387a5152d0e558189b6414f8c2f0cd06632badaa6a95686"
    },
    {
      "id": 1191,
      "ts": "2026-09-21T19:40:15-07:00",
      "task_id": "WT-0439",
      "action": "create",
      "agent": "claude-fable",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"One grant object for every credential the build hands out: fold share links, team links, invited emails, device tokens, capability tokens and lead tokens into the capabilities table (kind + subject + scope + expiry + revoked) behind ONE verifier, so every door reads one function, every revoke is one call, the Users screen lists people and links as one list of grants, and the traffic pixel joins page views to the grant id recorded at link open (link_opens).\",\"detail\":\"Owner, 2026-09-21: everything should be one dispatch and one token that is both access and the pixel identity. Done that day: every console route is a dispatch row (0475), link opens are recorded with the visitor hash (link_opens), people are profiles with email and/or mobile. Not done: the verifiers are still nine kinds (terminal key, Access JWT/service token, sh. share tokens, capability tokens, x-share-code, x-team-link, phone/device tokens, MCP_TOKEN, AIG_SHIM_TOKEN, cap_ lead tokens). This row is the unification. Rule to keep: the access decision reads only authority columns, never tracking columns.\",\"priority\":2,\"agent\":\"claude-fable\",\"capabilities\":[\"OBJECT_MUTATE\",\"D1_QUERY\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "63fa864a64c2fec4ab6edfcb947180e700e201ab294a7a72ff37a188fae59e08",
      "hash": "93f1117be0b14360df4ac16d7af84a3ade94da9fc91efea95c27ab60296cbd9a"
    },
    {
      "id": 1190,
      "ts": "2026-09-21T19:00:41-07:00",
      "task_id": "WT-0420",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "0556ef795f4e8b6da79a5850dccf7b9697df5694ac6897f4e7a2934d3767436e",
      "hash": "63fa864a64c2fec4ab6edfcb947180e700e201ab294a7a72ff37a188fae59e08"
    },
    {
      "id": 1189,
      "ts": "2026-09-21T19:00:40-07:00",
      "task_id": "WT-0420",
      "action": "submit",
      "agent": "claude-fable-5-1",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"7f2e9e554\",\"verification\":\"Live at https://miscsubjects.com/ (200, 639 kB). Root carries the visitor h1, the signals table (10 rows populated from /api/traffic/self in a headless Chromium render: city, network, /48 prefix + hash, device, colo), the mint box, the last-hour projection (89,000 events, 24 service pills, 25 event rows from /api/ledger/public), the four number mechanisms, the run block naming the six directory rows and stating no run is recorded, the article feed injected by functions/index.js with counts computed at render (1,203 articles, 4,743 sources, 7,232 claims, 875 comments; 50 cards, 8 sort pills), the laws list, the doors for models, the three lines, every former footer destination, and 14 plan rows from /api/work. Old blocks absent (sitename-wrap, sandboxed, ds-foot, proven-work hero: 0 matches). /compound-media/ answers a stub pointing at /; 15 sub-pages' nav rewritten to /. Owner-data sweep of the live root: clean. Screenshots at 1280 and 390 px wide rendered without overflow.\"}}",
      "output": "\"https://miscsubjects.com/\"",
      "changed": "[\"public/index.html\",\"functions/index.js\",\"public/compound-media/index.html\",\"public/compound-media/*/index.html\",\"public/compound-media/leaks.html\"]",
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"7f2e9e554\",\"verification\":\"Live at https://miscsubjects.com/ (200, 639 kB). Root carries the visitor h1, the signals table (10 rows populated from /api/traffic/self in a headless Chromium render: city, network, /48 prefix + hash, device, colo), the mint box, the last-hour projection (89,000 events, 24 service pills, 25 event rows from /api/ledger/public), the four number mechanisms, the run block naming the six directory rows and stating no run is recorded, the article feed injected by functions/index.js with counts computed at render (1,203 articles, 4,743 sources, 7,232 claims, 875 comments; 50 cards, 8 sort pills), the laws list, the doors for models, the three lines, every former footer destination, and 14 plan rows from /api/work. Old blocks absent (sitename-wrap, sandboxed, ds-foot, proven-work hero: 0 matches). /compound-media/ answers a stub pointing at /; 15 sub-pages' nav rewritten to /. Owner-data sweep of the live root: clean. Screenshots at 1280 and 390 px wide rendered without overflow.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "84cb6bd4fad491ee9f62c0e6e312af2675c99ee702162429e7a5118a52b3b784",
      "hash": "0556ef795f4e8b6da79a5850dccf7b9697df5694ac6897f4e7a2934d3767436e"
    },
    {
      "id": 1188,
      "ts": "2026-09-21T16:57:46-07:00",
      "task_id": "WT-0438",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "e2daa8e54778561042ac817301772d9bb9526c24cf997d6925913a49673c87ae",
      "hash": "84cb6bd4fad491ee9f62c0e6e312af2675c99ee702162429e7a5118a52b3b784"
    },
    {
      "id": 1187,
      "ts": "2026-09-21T16:57:46-07:00",
      "task_id": "WT-0438",
      "action": "submit",
      "agent": "claude-fable",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"7137a0cbf, 8ad9aa04f\",\"verification\":\"Live on miscsubjects.com (both deploys, 16 post gates green each). Verified from the owner's vantage (Access service token, site host): GET /api/console/access ok, door read = 'Owner surfaces — email one-time PIN', findings listed with fixes; POST {action:admit} for jpm@loop.health (policy created) and benbrock88@gmail.com (policy updated) -> managed policy 'Tenant members (managed by /api/tenant/access)' now exists on app 70e2ab44 with both addresses; per-person reports show door 'admitted (managed policy)' and reach 6 surfaces. /api/settings and /api/settings/<key> answer 401 without a credential (GET list, GET key, PUT) and 200 with x-terminal-key. Directory rows ACCESS_AGENT (allowed_categories=access), ACCESS_REPORT, ACCESS_FIX present and enabled; GET /api/console/sent?agent=ACCESS_AGENT resolves with tool_keys [ACCESS_REPORT, ACCESS_FIX]; settings.invite_message present. /console/guide/access -> 200 text/html, 12 sections. Headless Chromium (service token) rendered /console#/users: findings card, space chips Owner/Loop/Ben Brock, people list with levels and sign-in state, invite form with Viewer/Team/Developer. Tests: 49 passing across tenant, team_link, tenant_access, access_report, tenant_people, console_scope; prompts-not-in-code gate 0 offenders.\"}}",
      "output": null,
      "changed": "[\"functions/_lib/tenant.js\",\"functions/_lib/tenant_access.js\",\"functions/_lib/access_report.js\",\"functions/api/console/access.js\",\"functions/api/settings/index.js\",\"functions/api/settings/[key].js\",\"public/console.html\",\"public/console/users.js\",\"functions/console/guide/access.js\",\"migrations/0472_access_agent.sql\",\"directory rows ACCESS_AGENT ACCESS_REPORT ACCESS_FIX\",\"settings.invite_message\",\"Access policy 'Tenant members (managed by /api/tenant/access)' on app 70e2ab44\"]",
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"7137a0cbf, 8ad9aa04f\",\"verification\":\"Live on miscsubjects.com (both deploys, 16 post gates green each). Verified from the owner's vantage (Access service token, site host): GET /api/console/access ok, door read = 'Owner surfaces — email one-time PIN', findings listed with fixes; POST {action:admit} for jpm@loop.health (policy created) and benbrock88@gmail.com (policy updated) -> managed policy 'Tenant members (managed by /api/tenant/access)' now exists on app 70e2ab44 with both addresses; per-person reports show door 'admitted (managed policy)' and reach 6 surfaces. /api/settings and /api/settings/<key> answer 401 without a credential (GET list, GET key, PUT) and 200 with x-terminal-key. Directory rows ACCESS_AGENT (allowed_categories=access), ACCESS_REPORT, ACCESS_FIX present and enabled; GET /api/console/sent?agent=ACCESS_AGENT resolves with tool_keys [ACCESS_REPORT, ACCESS_FIX]; settings.invite_message present. /console/guide/access -> 200 text/html, 12 sections. Headless Chromium (service token) rendered /console#/users: findings card, space chips Owner/Loop/Ben Brock, people list with levels and sign-in state, invite form with Viewer/Team/Developer. Tests: 49 passing across tenant, team_link, tenant_access, access_report, tenant_people, console_scope; prompts-not-in-code gate 0 offenders.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "b001c34efd05edafd5fe4221c147f359c4bebc12d8b918fe832321c689cba1e0",
      "hash": "e2daa8e54778561042ac817301772d9bb9526c24cf997d6925913a49673c87ae"
    },
    {
      "id": 1186,
      "ts": "2026-09-21T16:36:31-07:00",
      "task_id": "WT-0438",
      "action": "create",
      "agent": "claude-fable",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"People and access: the Users screen admits a person at any level (viewer, team, developer) into any space, creates a new space, sends a scoped invite, mints and revokes team links, and troubleshoots the door; the invite's Access step finds the live Access app again; the settings API is behind the Console's own auth; an ACCESS_AGENT directory row knows every door, level and link and repairs them through ACCESS_REPORT / ACCESS_FIX; the guide at /console/guide/access explains people, spaces, levels, links, customers under Workers for Platforms and the lead-to-customer path.\",\"detail\":\"Owner order 2026-09-21: 'I want to be able to add people and scope them from settings, send a scoped invite to a friend, make an agent that knows everything about users and scoped permissions and can troubleshoot tap-to-resolve, think through customers on Workers for Platforms with scoped permissions, and explain the lead -> iMessage conversation -> purchase -> customer path.' Found on the way: tenant_access.js looked up the Access app by domain miscsubjects.com/console, which was parked 2026-09-19, so every invite since wrote rows and left the door shut (no managed policy exists on app 70e2ab44); /api/settings and /api/settings/<key> had no auth and owner_identities is read by the owner heal.\",\"priority\":1,\"agent\":\"claude-fable\",\"capabilities\":[\"OBJECT_MUTATE\",\"D1_QUERY\"],\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "dd9c895c4aef412b6a6259a0b32d2444660da6b617a3959c9b5553c22eb18eab",
      "hash": "b001c34efd05edafd5fe4221c147f359c4bebc12d8b918fe832321c689cba1e0"
    },
    {
      "id": 1185,
      "ts": "2026-09-21T16:10:10-07:00",
      "task_id": "WT-0437",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"A Claude Code turn reaches the Console the moment it ends: Stop and UserPromptSubmit hooks run the capture for that one session instead of waiting for a poll that is switched off\",\"detail\":\"2026-09-21: capture.auto is off (owner law: automations off), so sessions only synced on Sync now. Hooks in ~/.claude/settings.json run scripts/agent-capture.mjs hook for the session in the background. Next: the same for Codex, Grok and Kimi (install-agent-turn-hooks.sh), and a mid-turn PostToolUse path once the request budget allows it.\",\"priority\":1,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2f2f62c74947dac9d13285df7df8619b88fe6efc2cbabd6f027a7eb814fab83d",
      "hash": "dd9c895c4aef412b6a6259a0b32d2444660da6b617a3959c9b5553c22eb18eab"
    },
    {
      "id": 1184,
      "ts": "2026-09-21T16:10:09-07:00",
      "task_id": "WT-0436",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Every device shows the same screen at the same time: a turn started on the desktop streams on the phone and the site (words, tool calls inline, reasoning), and a session or reply made anywhere appears everywhere within seconds\",\"detail\":\"2026-09-21: console_live_turns (one row per chat, rewritten as the stream runs) + GET /api/console/live + the chat screen attaches to a running turn and polls it every second; the feed refreshes every 20 s while visible. Next: push instead of poll (a Durable Object per chat with WebSockets, the site plane binding to it), so the delay is the network's and not a timer's.\",\"priority\":1,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "17724029337a9275f7877e1d90ecbae953d82fbf0d9ab0ee42473935d0e038f1",
      "hash": "2f2f62c74947dac9d13285df7df8619b88fe6efc2cbabd6f027a7eb814fab83d"
    },
    {
      "id": 1183,
      "ts": "2026-09-21T16:10:07-07:00",
      "task_id": "WT-0421",
      "action": "progress",
      "agent": "fable",
      "model": null,
      "capability": "owner-key",
      "task_revision": 1,
      "from_state": "open",
      "to_state": "in_progress",
      "input": "{\"note\":\"OUTREACH_RUN and BUILD_PITCH_DRAFT removed (unasked). The loop is the owner models with existing tools; what remains on this parent: cost lines (WT-0422), share links now full-access by default (WT-0424), reply intake (WT-0426), dedicated agent environments (WT-0429), live cross-device turns (WT-0431), Claude turn hooks (WT-0432).\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "cdd0457befd56494efa4b6e32f4fae20a8b9b918ab70b8888f350bcf19918eeb",
      "hash": "17724029337a9275f7877e1d90ecbae953d82fbf0d9ab0ee42473935d0e038f1"
    },
    {
      "id": 1182,
      "ts": "2026-09-21T16:10:05-07:00",
      "task_id": "WT-0430",
      "action": "supersede",
      "agent": "fable",
      "model": null,
      "capability": null,
      "task_revision": 2,
      "from_state": "open",
      "to_state": "superseded",
      "input": "{\"reason\":\"Built around OUTREACH_RUN and BUILD_PITCH_DRAFT, abilities the owner did not ask for (2026-09-21: the loop is his models with the tools that already exist). Rows and code removed in migration 0471.\",\"replaced_by\":null}",
      "output": "{\"note\":\"row retained; withdrawal recorded as a revision\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "superseded",
      "parent_action": null,
      "prev_hash": "aced8b28a3ab5b5f131a1ce97fb03cfd2f18a294019d27a4cfa112646da061b0",
      "hash": "cdd0457befd56494efa4b6e32f4fae20a8b9b918ab70b8888f350bcf19918eeb"
    },
    {
      "id": 1181,
      "ts": "2026-09-21T16:10:04-07:00",
      "task_id": "WT-0428",
      "action": "supersede",
      "agent": "fable",
      "model": null,
      "capability": null,
      "task_revision": 2,
      "from_state": "open",
      "to_state": "superseded",
      "input": "{\"reason\":\"Built around OUTREACH_RUN and BUILD_PITCH_DRAFT, abilities the owner did not ask for (2026-09-21: the loop is his models with the tools that already exist). Rows and code removed in migration 0471.\",\"replaced_by\":null}",
      "output": "{\"note\":\"row retained; withdrawal recorded as a revision\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "superseded",
      "parent_action": null,
      "prev_hash": "4ff724b8d0d24d2dabc3a9a7b13d06c73887b52e5526acc1152dc3b4f71f9006",
      "hash": "aced8b28a3ab5b5f131a1ce97fb03cfd2f18a294019d27a4cfa112646da061b0"
    },
    {
      "id": 1180,
      "ts": "2026-09-21T16:10:03-07:00",
      "task_id": "WT-0427",
      "action": "supersede",
      "agent": "fable",
      "model": null,
      "capability": null,
      "task_revision": 2,
      "from_state": "open",
      "to_state": "superseded",
      "input": "{\"reason\":\"Built around OUTREACH_RUN and BUILD_PITCH_DRAFT, abilities the owner did not ask for (2026-09-21: the loop is his models with the tools that already exist). Rows and code removed in migration 0471.\",\"replaced_by\":null}",
      "output": "{\"note\":\"row retained; withdrawal recorded as a revision\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "superseded",
      "parent_action": null,
      "prev_hash": "c08b42af9be36ffed7bc891fb6f89b7feecdeb5cd10d3aa9f90d85bd98ff6d21",
      "hash": "4ff724b8d0d24d2dabc3a9a7b13d06c73887b52e5526acc1152dc3b4f71f9006"
    },
    {
      "id": 1179,
      "ts": "2026-09-21T16:09:59-07:00",
      "task_id": "WT-0425",
      "action": "supersede",
      "agent": "fable",
      "model": null,
      "capability": null,
      "task_revision": 2,
      "from_state": "open",
      "to_state": "superseded",
      "input": "{\"reason\":\"Built around OUTREACH_RUN and BUILD_PITCH_DRAFT, abilities the owner did not ask for (2026-09-21: the loop is his models with the tools that already exist). Rows and code removed in migration 0471.\",\"replaced_by\":null}",
      "output": "{\"note\":\"row retained; withdrawal recorded as a revision\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "superseded",
      "parent_action": null,
      "prev_hash": "b33d049a4ccfb1ee911a8aac34119faf5c7320419ec5d62c0c20f2e8cd258c1a",
      "hash": "c08b42af9be36ffed7bc891fb6f89b7feecdeb5cd10d3aa9f90d85bd98ff6d21"
    },
    {
      "id": 1178,
      "ts": "2026-09-21T16:09:04-07:00",
      "task_id": "WT-0435",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Internal operations exposed and interactive for a visitor: Directory, Leads (funnel counts and timings), Traffic (the visitor's own row), Tasks and runs with their change sets and receipts, Agents, Rooms, Automations, each a projection of its Console read model with a viewer parameter and the redaction cell\",\"detail\":\"Serves the owner's input that all internal operations become interactive, exposed and part of the value proposition. /tools and /api/work already exist; the rest is the same read models opened at doors outside Access.\",\"priority\":3,\"parent_id\":\"WT-0412\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"LEDGER_EVENTS\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "ba354a4ea01f24503d39c30968e2e73caba2a531792c8e0fa524e50a9df0db8c",
      "hash": "b33d049a4ccfb1ee911a8aac34119faf5c7320419ec5d62c0c20f2e8cd258c1a"
    },
    {
      "id": 1177,
      "ts": "2026-09-21T16:09:03-07:00",
      "task_id": "WT-0434",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"The Console Ledger's six tabs (Turns, Sessions, Changes, Events, Tasks, Assets) as a public read-only surface on the site with the Console's own presentation, over GET /api/ledger/public extended per tab, redaction from the cell, sessions and turns hidden until ledger.public_sessions is set\",\"detail\":\"Serves the owner's input that the Console's Ledger is the product to expose, not the comments page at /ledger. /api/ledger/public today projects Events only. Test: each tab renders for a stranger with no body and no unmasked identifier; a scan of the output for phone and email shapes fails the deploy.\",\"priority\":2,\"parent_id\":\"WT-0412\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"LEDGER_EVENTS\",\"LEDGER_QUERY\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "d03dea549bf9cad6eddae900449543ca423cbdfd785615018254f72e6d1ad216",
      "hash": "ba354a4ea01f24503d39c30968e2e73caba2a531792c8e0fa524e50a9df0db8c"
    },
    {
      "id": 1176,
      "ts": "2026-09-21T16:09:02-07:00",
      "task_id": "WT-0433",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Inside the app, on the site: the Console's screens as read-only public projections or captured recordings, placed where a visitor meets them, with the owner's identifiers masked by the same redaction cell\",\"detail\":\"Serves the owner's input that screen recordings and the inside of the app show what the build does and that even that does not cover what is not in the app. Projection over the same read models with a viewer parameter, never a second code path.\",\"priority\":4,\"parent_id\":\"WT-0412\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"LEDGER_EVENTS\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "784f363a8876cf2189c29878e7ec7978b966d06efbb15781109c6f914fdc1e82",
      "hash": "d03dea549bf9cad6eddae900449543ca423cbdfd785615018254f72e6d1ad216"
    },
    {
      "id": 1175,
      "ts": "2026-09-21T16:09:00-07:00",
      "task_id": "WT-0432",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"The offerings object: every offering as a directory row (what it is, what it needs, what it cannot do, its address) and a skill models load so any business can be matched to the offerings it could use\",\"detail\":\"Serves the owner's input that the models must understand all current offerings and how they apply to any business, so a session or a task can pitch a named business end to end. Rows in the directory, a skill under /a/skill-law with a failing exhibit, and a test that a model given a business returns the matching rows.\",\"priority\":3,\"parent_id\":\"WT-0412\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"MCP_CATALOG\",\"LEADS_DRAFT_AI\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "822e09208cfadc835c3f9c853322aa9d3eefc2786dd19aadfdff4d1b8593ffe8",
      "hash": "784f363a8876cf2189c29878e7ec7978b966d06efbb15781109c6f914fdc1e82"
    },
    {
      "id": 1174,
      "ts": "2026-09-21T16:08:45-07:00",
      "task_id": "WT-0431",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"One page per thing the build does, written under the writing law, each page a row a model can take: what it is, the mechanism, what it needs, what breaks, the address, one walked case with receipts\",\"detail\":\"Serves the owner's input that material must exist on the site explaining each thing, assignable to other models. Start from the 44 layers on /compound-media/layers/ and the capability atlas domains; one row per page; the writing-law check is the test. No prices.\",\"priority\":3,\"parent_id\":\"WT-0412\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"LEDGER_EVENTS\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "186d3aad26024efa806cc342ac13232dd5908667cfcf9daf7352411cfcd6e200",
      "hash": "822e09208cfadc835c3f9c853322aa9d3eefc2786dd19aadfdff4d1b8593ffe8"
    },
    {
      "id": 1173,
      "ts": "2026-09-21T15:06:09-07:00",
      "task_id": "WT-0430",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Proof of work per outreach run: a page listing the businesses found, the messages written and sent, the replies, and the cost, shareable by link\",\"detail\":\"The run_id is the work_id. The share page kind run renders leads, lead_messages and cost_lines for it. This is what a prospect or the owner sees as evidence that the loop ran.\",\"priority\":3,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "ef41254ae93aaa9989e567ba460a12f4a01bcc161459fc6b3a03457824f365d9",
      "hash": "186d3aad26024efa806cc342ac13232dd5908667cfcf9daf7352411cfcd6e200"
    },
    {
      "id": 1172,
      "ts": "2026-09-21T15:06:07-07:00",
      "task_id": "WT-0429",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Dedicated coding-agent environments: one Worker per lane (Claude, Codex, Kimi, Grok, muse Worker, muse Coder), each a console_environments row with its own D1, R2, run door and cost lines\",\"detail\":\"Today Worker and Coder share muse-worker and its D1 and R2. Clone per lane with the tenant cloning path, register each in console_environments, and write agent_run_calls cost into cost_lines under run:<id> so a coding task shows what it spent.\",\"priority\":3,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "229c8bfb74e4731b70408d7f8f65b071d450c5c12374334f477c4704608f0e80",
      "hash": "ef41254ae93aaa9989e567ba460a12f4a01bcc161459fc6b3a03457824f365d9"
    },
    {
      "id": 1171,
      "ts": "2026-09-21T15:06:05-07:00",
      "task_id": "WT-0428",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Scale: a queue that walks 500 businesses across cities under per-day caps and a per-run budget cell, off by default, started by one call\",\"detail\":\"OUTREACH_RUN takes one segment and one city. The queue is rows (segments by cities) with outreach.run.send_cap_per_day and a budget cell. An automation row runs it only when switched on. Automations stay off by default (owner law).\",\"priority\":3,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "e729baeefa40d041819e4a9f926e4a67d308ee5c07959a39dbd00e2395269884",
      "hash": "229c8bfb74e4731b70408d7f8f65b071d450c5c12374334f477c4704608f0e80"
    },
    {
      "id": 1170,
      "ts": "2026-09-21T15:06:04-07:00",
      "task_id": "WT-0427",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"The pitch logic is a row the owner edits in the app: BUILD_PITCH_DRAFT (model, prompt, channels) and the offer list inside it; accepted and rejected lines become exhibits on /a/outreach-law\",\"detail\":\"The build decides the channel and the words from this row until the owner changes it. Every draft records the reasoning the model gave, so a rejected line can be quoted beside the accepted one.\",\"priority\":3,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "557abd1551ad4e45c08df8718dc752f50e4078a780ce3f8af77bfb375497eb0f",
      "hash": "e729baeefa40d041819e4a9f926e4a67d308ee5c07959a39dbd00e2395269884"
    },
    {
      "id": 1169,
      "ts": "2026-09-21T15:06:03-07:00",
      "task_id": "WT-0426",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Reply intake: an inbound email or text from a lead lands as a lead_messages row (direction in), flips the lead to replied, and shows in the Console as a thread\",\"detail\":\"Resend inbound and the Blooio webhook already reach the build (webhook intake). Route them to lead_messages by matching the address or number to the lead. Replies are the ground truth the owner reviews before editing the pitch logic.\",\"priority\":2,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8302efee47d158573a90f61700fbc80a67cfa67e604d952c9054ad1c0182ee8f",
      "hash": "557abd1551ad4e45c08df8718dc752f50e4078a780ce3f8af77bfb375497eb0f"
    },
    {
      "id": 1168,
      "ts": "2026-09-21T15:06:02-07:00",
      "task_id": "WT-0425",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"OUTREACH_RUN send mode: email through the tracked-send lane and iMessage through the build's own line (SEND_BY_CHANNEL blooio), each send a lead_messages row with a receipt and a cost line\",\"detail\":\"Send runs only when the lead type is active and approval.mode is auto, under draft_policy.max_per_day. The lead type ships paused: the owner flips it in Console, Outreach. Never a test send to a real person.\",\"priority\":2,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2e86719123daef6a74976b45c01d9d4fda36fdc83730a5536002ffb3c2efeab9",
      "hash": "8302efee47d158573a90f61700fbc80a67cfa67e604d952c9054ad1c0182ee8f"
    },
    {
      "id": 1167,
      "ts": "2026-09-21T15:05:59-07:00",
      "task_id": "WT-0424",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Share links for every screen: the paperclip mints https://miscsubjects.com/share/<code>, which opens read-only for anyone holding it and answers JSON with ?format=json\",\"detail\":\"Shipped 2026-09-21: chat, session, turn and screen kinds, POST /api/console/share, table console_share_links, expiry cell console.share_ttl_days. Remaining: the iOS share sheet offers the same link, and a share page for an outreach run (leads found, messages, cost).\",\"priority\":1,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "c20ac11627596f3c8b11c477a32d94918ab6bbb125a37c1d84daf10f33bb627f",
      "hash": "2e86719123daef6a74976b45c01d9d4fda36fdc83730a5536002ffb3c2efeab9"
    },
    {
      "id": 1166,
      "ts": "2026-09-21T15:05:58-07:00",
      "task_id": "WT-0423",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Unit price cells for every metered vendor: Google Places, Exa, Resend email, Blooio iMessage, 2chat WhatsApp, Browser Rendering, Workers CPU, D1 rows\",\"detail\":\"Each price is a settings cell price.<vendor>.<unit>_usd with the vendor page cited in field_meta.provenance. Nothing is priced from memory. Seeded 2026-09-21: price.google_places.text_search_request_usd = 0.04 (Enterprise + Atmosphere SKU, verified against the vendor sheet 2026-07-28).\",\"priority\":2,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8aff0f1d027ae968881edbccb8d96f16000220f37bf382c3fd90b742780106c5",
      "hash": "c20ac11627596f3c8b11c477a32d94918ab6bbb125a37c1d84daf10f33bb627f"
    },
    {
      "id": 1165,
      "ts": "2026-09-21T15:05:56-07:00",
      "task_id": "WT-0422",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Cost lines for every payload: model rounds, tool calls, scrapes and sends each write one cost_lines row under the work they belong to, and GET /api/console/cost?work=<id> lists them with a total\",\"detail\":\"Shipped 2026-09-21 for console chats (chat:<id>) and outreach runs (run:<id>). Remaining: muse-worker agent runs (agent_run_calls into cost_lines), Cloudflare Browser Rendering and cloud exec seconds, every send channel. A payload with no known price is a row with priced=0, never a zero.\",\"priority\":1,\"parent_id\":\"WT-0421\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "9ea47869d5c0d6cd4c78f299a6f94a534a494124b03546071f7d55120e8d31d4",
      "hash": "8aff0f1d027ae968881edbccb8d96f16000220f37bf382c3fd90b742780106c5"
    },
    {
      "id": 1164,
      "ts": "2026-09-21T15:01:26-07:00",
      "task_id": "WT-0421",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"The outreach loop end to end: the build finds businesses, decides the channel and the words, sends, tracks replies, and prices every payload it spent on the way\",\"detail\":\"Owner order 2026-09-21. Plan and rows: https://miscsubjects.com/compound-media/plan/outreach-loop/ . The loop is OUTREACH_RUN (discover, enrich, draft, send) over lead type build-services-local. The words come from the BUILD_PITCH_DRAFT row (no prices, the build explains itself, one question). Every payload writes a cost_lines row under the run, and every screen of the Console has a share link. The build decides how to reach out and what to say until the owner edits the rows.\",\"priority\":1,\"capabilities\":[\"OUTREACH_RUN\",\"LEADS_DISCOVER_PLACES\",\"LEADS_ENRICH\",\"BUILD_PITCH_DRAFT\",\"EMAIL_SEND_TRACKED\",\"SEND_BY_CHANNEL\"],\"acceptance\":[{\"type\":\"http_ok\",\"id\":\"plan\",\"url\":\"https://miscsubjects.com/compound-media/plan/outreach-loop/\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "53059588324ec85862f57affca5fb9f962178c03c0aaa24c64b2916cc590db6a",
      "hash": "9ea47869d5c0d6cd4c78f299a6f94a534a494124b03546071f7d55120e8d31d4"
    },
    {
      "id": 1163,
      "ts": "2026-09-21T14:58:12-07:00",
      "task_id": "WT-0415",
      "action": "progress",
      "agent": "claude",
      "model": null,
      "capability": "owner-key",
      "task_revision": 1,
      "from_state": "open",
      "to_state": "in_progress",
      "input": "{\"note\":\"Deployed in cd9fa0eec: GET /api/ledger/public projects the Console events read model (readEvents + eventsSummary) for a stranger: bodies and previews removed, phone and email masked, actors that are people become a person, sessions hidden until ledger.public_sessions=1. Verified live: 71,272 events in the hour, 60 services, no unmasked email. A mask over-match on timestamps is fixed in the next deploy. /ledger is the models-comments page and is not replaced; the projection is what the front reads.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8c97589db57307bfc41b4ae4700d044ec3638295bd0b9f25f5e12ef388f4510f",
      "hash": "53059588324ec85862f57affca5fb9f962178c03c0aaa24c64b2916cc590db6a"
    },
    {
      "id": 1162,
      "ts": "2026-09-21T14:58:11-07:00",
      "task_id": "WT-0413",
      "action": "progress",
      "agent": "claude",
      "model": null,
      "capability": "owner-key",
      "task_revision": 1,
      "from_state": "open",
      "to_state": "in_progress",
      "input": "{\"note\":\"Deployed in cd9fa0eec: POST /api/traffic/sms/mint issues a code scoped to the device cookie (campaign cmp_035fd12bb02740, page sqz_b498ed4e38b644, line +1 424 504 0908); GET /api/traffic/sms/status?receipt=1 returns times, masked sender, reply, inbound ledger id and reply receipt; the funnel stores both on the code. Mint and status verified live (code SZPUNC issued and read back as issued). The inbound leg has not been exercised by a real text from a phone yet; the row stays open until that receipt renders.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "d67c5ff6308f3a0c4290e468c935e0965f26c4735ed68a2752cb8773bacc0f2d",
      "hash": "8c97589db57307bfc41b4ae4700d044ec3638295bd0b9f25f5e12ef388f4510f"
    },
    {
      "id": 1161,
      "ts": "2026-09-21T14:57:42-07:00",
      "task_id": "WT-0414",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "dce4758b356c18c07934a232c7a28d59beb22a8cb8ef413dc9499c3cae86892b",
      "hash": "d67c5ff6308f3a0c4290e468c935e0965f26c4735ed68a2752cb8773bacc0f2d"
    },
    {
      "id": 1160,
      "ts": "2026-09-21T14:57:42-07:00",
      "task_id": "WT-0414",
      "action": "submit",
      "agent": "claude",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"cd9fa0eec\",\"verification\":\"GET https://miscsubjects.com/api/traffic/self answered ok:true, catalogue_size 128, network keys without ip (ip_hash and ip_prefix present), stored statement present; rendered on /compound-media/ as the first block on 2026-09-21.\"}}",
      "output": "\"keyless self-view of the caller’s normalised signals; raw address never returned\"",
      "changed": "[\"functions/api/traffic/[[path]].js\",\"public/compound-media/index.html\"]",
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"cd9fa0eec\",\"verification\":\"GET https://miscsubjects.com/api/traffic/self answered ok:true, catalogue_size 128, network keys without ip (ip_hash and ip_prefix present), stored statement present; rendered on /compound-media/ as the first block on 2026-09-21.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "df796c4e51adfa73dc87af82da0325ed55d06db38cd2c8b4e527bfc2738a24b0",
      "hash": "dce4758b356c18c07934a232c7a28d59beb22a8cb8ef413dc9499c3cae86892b"
    },
    {
      "id": 1159,
      "ts": "2026-09-21T14:36:17-07:00",
      "task_id": "WT-0420",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Front assembled: the six blocks in order (visitor panel, text-in receipt, last hour of the Ledger, number options, one business end to end, if the build wrote to you) with the existing proven-work front folded under them and the demonstrations linked as a section\",\"detail\":\"The existing content (articles, laws, OIP, /start, /tools) stays. Name on the front per the owner's answer. Test: a stranger can state after one read what the page is, what problem it solves, the mechanism, and what to do (writing-law W46); the counts on the page are computed at render.\",\"priority\":5,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "b41f6d1178496f3ab8d32701fa26e7c86140ec5099a8f1286bbada8299622279",
      "hash": "df796c4e51adfa73dc87af82da0325ed55d06db38cd2c8b4e527bfc2738a24b0"
    },
    {
      "id": 1158,
      "ts": "2026-09-21T14:36:16-07:00",
      "task_id": "WT-0419",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Per-lead page at a private token: the fact observed about their business, the page drafted for them, the ads that would run, the number option and its constraint, the record of what was sent, and a reply that lands on the ledger; register per the outreach law\",\"detail\":\"Rendered from the lead row and its sends. Token 32 bytes; every open logged. Test: opening the page writes an event; a reply from the page appears as a receipt; no price appears.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"EMAIL_SEND_TRACKED\",\"LEDGER_EVENTS\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "a0349bbce1f0446e2b53c8d98bc4d57d740a4356076a768c50000631256d7ed3",
      "hash": "b41f6d1178496f3ab8d32701fa26e7c86140ec5099a8f1286bbada8299622279"
    },
    {
      "id": 1157,
      "ts": "2026-09-21T14:36:14-07:00",
      "task_id": "WT-0418",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"End-to-end run: find a named list of businesses, enrich, research and draft by model, write to each on a permitted channel, collect replies, build the page and the paused ads for the ones that answer, and generate the front page block from the run's receipts\",\"detail\":\"Uses LEADS_DISCOVER_PLACES, LEADS_ENRICH_BATCH, /api/leads/agent, EMAIL_SEND_TRACKED (first contact), IMESSAGE_SEND (on reply), META_ADS_AD_CREATE (paused). The block is generated from receipts, never typed. Channel rule and list are the owner's decisions recorded in the plan's questions. Test: the block's every number resolves to a receipt id on the ledger.\",\"priority\":4,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"LEADS_DISCOVER_PLACES\",\"LEADS_ENRICH_BATCH\",\"EMAIL_SEND_TRACKED\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "a5a9d42a6db38eeccab4a685015b9139819d17eb45014def487f2acd31e83e50",
      "hash": "a0349bbce1f0446e2b53c8d98bc4d57d740a4356076a768c50000631256d7ed3"
    },
    {
      "id": 1156,
      "ts": "2026-09-21T14:36:12-07:00",
      "task_id": "WT-0417",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Number options as mechanisms: one page stating, for an existing number registered to iMessage, an assigned line, WhatsApp and Telegram, what each needs, cannot do, and what breaks and its repair; no prices\",\"detail\":\"Keys: IMESSAGE_SEND, SEND_BY_CHANNEL, TWOCHAT_SEND, WEBHOOK_INTAKE. The page states that registering an existing number needs a device that holds it and that hosted VoIP usually fails Apple's code. Test: the page passes the writing-law check and names every failure condition listed in the plan.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"IMESSAGE_SEND\",\"TWOCHAT_SEND\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "064bfcb8a9ade493de052bb2b16605b32b14ca0953a06841583781c7bf11e826",
      "hash": "a5a9d42a6db38eeccab4a685015b9139819d17eb45014def487f2acd31e83e50"
    },
    {
      "id": 1155,
      "ts": "2026-09-21T14:36:11-07:00",
      "task_id": "WT-0416",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Rewrite of the shipped pages under the writing, design and outreach laws: prices, invented personas, floating emoji and split-colour headlines removed; the taken-apart scenes and the tiles kept as demonstrations labelled as illustrations; the pages added to a prose gate\",\"detail\":\"Pages: /compound-media/ and its sub-pages (commercial, effects, layers, orbit, switchboard, receipts, imessage, whatsapp, ads, realtor, restaurant, leaks). If no prose gate covers static pages, this row creates one that runs the writing-law clause checks against them. Test: no dollar amount as enticement remains; the gate passes on every page.\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "017ade054e139ed828f09b0b5b503d5270caa86b54e90cfbc0e9677b2049fb72",
      "hash": "064bfcb8a9ade493de052bb2b16605b32b14ca0953a06841583781c7bf11e826"
    },
    {
      "id": 1154,
      "ts": "2026-09-21T14:36:10-07:00",
      "task_id": "WT-0415",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Public Ledger projection: viewer=public on the Console read model (functions/api/console/ledger.js over ledger_model.js) with a redaction rule in a settings cell, and /ledger rebuilt on it; the raw zero-redaction page retired\",\"detail\":\"Bodies never; phone and email shapes masked; coding sessions hidden until the owner sets the cell. Gate: a check that scans the projection output for phone and email shapes fails the deploy. Test: /ledger?tab=event renders counts and rows for the last hour with no body and no unmasked identifier.\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"LEDGER_EVENTS\",\"LEDGER_QUERY\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "5da2853372278d14b50a7634b465b2893a984d936b859b4c08c95aa6b1cbb021",
      "hash": "017ade054e139ed828f09b0b5b503d5270caa86b54e90cfbc0e9677b2049fb72"
    },
    {
      "id": 1153,
      "ts": "2026-09-21T14:36:09-07:00",
      "task_id": "WT-0414",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Visitor panel: a keyless self-view returning only the current visitor's normalised signals and stored profile fields, rendered as the front page's first block with the storage statement taken from the traffic policy\",\"detail\":\"Signals from functions/_lib/traffic/signals.js (128). New: GET /api/traffic/self scoped by the request's own visitor hash; raw IP never returned; the block links the catalogue at GET /api/traffic/signals. Test: two different networks see two different rows; neither can address the other.\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"TRAFFIC_TURNSTILE\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "f4661c2513453126ca18a0f8e2e037cc9a6aa6f77655a798122001b2a554c31d",
      "hash": "5da2853372278d14b50a7634b465b2893a984d936b859b4c08c95aa6b1cbb021"
    },
    {
      "id": 1152,
      "ts": "2026-09-21T14:36:07-07:00",
      "task_id": "WT-0413",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Text-in receipt loop: a keyless status route scoped to one code, and a front block that shows the code, waits, and renders the inbound event as a receipt with time, channel, reply, event id, hash and the /receipt link\",\"detail\":\"Mechanism exists in functions/_lib/traffic/funnel.js (phase post_sms, reply via SEND_BY_CHANNEL) and /api/traffic/sms/*. New: GET /api/traffic/sms/status?code= keyless, returning only that code's outcome; the block states the two failure reasons after 90 s. Test vector: text the code from a phone; the receipt renders within 90 s; the same id opens at /receipt/<id>.\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"SEND_BY_CHANNEL\",\"WEBHOOK_INTAKE\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "f31714a7ac87efcdc06784c7f10001333ee5c2a6193404032350716073e09d85",
      "hash": "f4661c2513453126ca18a0f8e2e037cc9a6aa6f77655a798122001b2a554c31d"
    },
    {
      "id": 1151,
      "ts": "2026-09-21T14:36:06-07:00",
      "task_id": "WT-0412",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"The site as the build showing itself: the front is six blocks the build performs in front of a visitor, the Console read models become public projections, no price list anywhere\",\"detail\":\"Plan and rationale: https://miscsubjects.com/compound-media/plan/ . Governing laws: /a/writing-law, /a/design-law, /a/outreach-law. Every child row closes on evidence the infrastructure runs; none closes on a sentence.\",\"priority\":1,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"capabilities\":[\"LEDGER_EVENTS\",\"SEND_BY_CHANNEL\",\"LEADS_DISCOVER_PLACES\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "a9a0651d7be12bde41c48083323e2777469e366f852e5c33cf5279c61c0bbaf3",
      "hash": "f31714a7ac87efcdc06784c7f10001333ee5c2a6193404032350716073e09d85"
    },
    {
      "id": 1150,
      "ts": "2026-09-20T12:54:14-07:00",
      "task_id": "WT-0410",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"cells_live\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/compound\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "20db55c19431b8f668c7fcb55adc26d96fcfdb9e2b20a825aff5676d482e5064",
      "hash": "a9a0651d7be12bde41c48083323e2777469e366f852e5c33cf5279c61c0bbaf3"
    },
    {
      "id": 1149,
      "ts": "2026-09-20T12:54:13-07:00",
      "task_id": "WT-0410",
      "action": "submit",
      "agent": "claude-opus-5",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"191e163e0\",\"verification\":\"Live 2026-09-20, four deploys, 16 post-deploy gates green on each. Migration 0463 applied: all six cells exist in settings. The wiring is proven by behaviour, not by the code reading: writing tools.hot_default=5 changed /api/tools/openai.json from 12 typed tools to 5, restoring 12 brought it back, and 99999 was refused out_of_bounds (above max 200) rather than applied. Re-proved after the read-order change with 7. The board now carries each cell's contract (type, min, max, default, provenance, writable) and lists the 21 declared cells that had never been written and so appeared nowhere at all, each marked as falling back to the code value. 130 settings rows now visible. One regression found and fixed in the same turn: settingCell read KV first, but env.KV is D1-backed and uncached, so it added one uncached query to every dispatch call through acquireIdem. Reading the memoized settings statement first cut dispatch NOW median from 2.44s to 1.74s over six calls. Freshness is unchanged because writeCell writes both and a settings write clears the memo.\"}}",
      "output": null,
      "changed": "[\"functions/_lib/setting_cell.js\",\"functions/api/dispatch.js\",\"functions/api/tools/[[path]].js\",\"functions/api/leads/data.js\",\"public/console/data.js\",\"migrations/0463_wire_declared_cells.sql\"]",
      "tests": "[{\"id\":\"cells_live\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/compound\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"191e163e0\",\"verification\":\"Live 2026-09-20, four deploys, 16 post-deploy gates green on each. Migration 0463 applied: all six cells exist in settings. The wiring is proven by behaviour, not by the code reading: writing tools.hot_default=5 changed /api/tools/openai.json from 12 typed tools to 5, restoring 12 brought it back, and 99999 was refused out_of_bounds (above max 200) rather than applied. Re-proved after the read-order change with 7. The board now carries each cell's contract (type, min, max, default, provenance, writable) and lists the 21 declared cells that had never been written and so appeared nowhere at all, each marked as falling back to the code value. 130 settings rows now visible. One regression found and fixed in the same turn: settingCell read KV first, but env.KV is D1-backed and uncached, so it added one uncached query to every dispatch call through acquireIdem. Reading the memoized settings statement first cut dispatch NOW median from 2.44s to 1.74s over six calls. Freshness is unchanged because writeCell writes both and a settings write clears the memo.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "4542870dd00dab45691b65504fa411c944c725470ddf729d1926eb3e24ea36ca",
      "hash": "20db55c19431b8f668c7fcb55adc26d96fcfdb9e2b20a825aff5676d482e5064"
    },
    {
      "id": 1148,
      "ts": "2026-09-20T12:39:18-07:00",
      "task_id": "WT-0411",
      "action": "create",
      "agent": "claude-opus-5",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":1,\"agent\":\"claude-opus-5\",\"objective\":\"Close the ledger: make a missed entry impossible rather than unlikely, starting with the audit log an agent can currently edit\",\"detail\":\"Owner question 2026-09-20: an architecture where no matter who acts - owner, coding agent, model, cron, webhook - it lands on the ledger with no possibility of a miss. Measured today, that is not met. The /api/dispatch lane is well covered. The rest is uneven and there are named holes. Most severe, in order. (a) LEDGER_EXEC runs raw SQL against the events database with no governed-table check, and events, events_stats and invocations are not in GOVERNED_TABLES - so a DELETE or UPDATE against the audit log itself is accepted, and the dispatch row recording it is written into the table being edited. The fix belongs at ledgerExec in functions/_lib/fn_runners.js, which is owner-protected, so it needs the owner's hand or an unlock. (b) logEvent cannot fail loudly: its whole body sits in one bare catch that returns null, and exactly one of its 245 call sites checks the return. functions/api/event_log_ingest.js already shows the right shape - it answers 503 when the write is unacked. (c) The ledger's own off switches - ledger.raw.capture, ledger.traffic.capture, controls_state, gates_disabled - live in the settings table, which nothing governs, and are writable by D1_EXEC and by DELETE /api/settings/<key>. A gate turned off exits 0, which reads as a pass. (d) Five admin write routes and about thirty API routes write D1 with no ledger call at all, covered only by a raw arrival that records the request bytes and not the outcome. (e) LOCAL_EXEC is dispatched with noLog true in one live call site, and noLog is a plain option any caller can pass. (f) The Mac bridge executes shell and only reports if MISC_INGEST_URL is set, fire and forget, never awaited. (g) traffic/store.js documents eight tables as governed and append-only - none of them are in GOVERNED_TABLES. (h) No gate looks for the whole class: a file under functions/api or functions/admin that writes D1 and contains no ledger call.\",\"acceptance\":[{\"id\":\"commit\",\"type\":\"evidence_present\",\"field\":\"commit\"},{\"id\":\"verification\",\"type\":\"evidence_present\",\"field\":\"verification\"},{\"id\":\"gap_closed\",\"type\":\"evidence_present\",\"field\":\"gap_closed\"}],\"evidence_required\":[\"commit\",\"verification\",\"gap_closed\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "96911424628c313e5fb7513d2ce0b418e37812171f9f507de16b63863589fc0c",
      "hash": "4542870dd00dab45691b65504fa411c944c725470ddf729d1926eb3e24ea36ca"
    },
    {
      "id": 1147,
      "ts": "2026-09-20T12:39:17-07:00",
      "task_id": "WT-0410",
      "action": "create",
      "agent": "claude-opus-5",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":1,\"agent\":\"claude-opus-5\",\"objective\":\"Every value the owner would change is a cell he can read and edit in the app, not a literal in code\",\"detail\":\"Owner order 2026-09-20: 'I want the settings to be editable by me in plain text in the app, visible, not in the code.' Measured first: the app already edits settings as free text (Console -> Data -> Settings). Two real gaps were found. (1) 0400_field_meta.sql declared six constants as cells and its own comment admitted 'Visible code still reads the constant' - so the app showed values that changed nothing. Three are now read from the cell: dispatch.client_idem_ttl_sec, dispatch.idem_window_ms, tools.hot_default. Three ceilings that were never declared are now cells too: dispatch.agent_depth_cap, dispatch.agent_iter_cap, dispatch.agent_cost_cap_usd. Each read keeps its literal as the fallback and clamps to declared bounds, so nothing changes until he edits a cell. (2) The editor never read field_meta, so bounds and allowed values were enforced server-side but never shown - he typed blind and learned the rule from the refusal. The settings board now carries type, bounds, default, provenance and writable, the editor shows them, a closed set renders as a picker, and a described-but-unwired cell says plainly that changing it will not change what runs. One shared helper (functions/_lib/setting_cell.js) reads KV first then D1, matching how writeCell writes. Nine private copies existed, four of them D1-only and so blind to a fresh edit. Left open, with reasons: tokens.public_read_keys is read by the synchronous isPublicReadRow(row) which takes no env, so wiring it changes every caller. The four separate model price tables (dispatch.js, model_yield.js, dojo.js, providers.js) have already drifted. Model ids, model lists and inline system prompts are still literals - those are the owner's surface and a separate decision.\",\"acceptance\":[{\"id\":\"cells_live\",\"type\":\"http_ok\",\"url\":\"https://miscsubjects.com/compound\"},{\"id\":\"commit\",\"type\":\"evidence_present\",\"field\":\"commit\"},{\"id\":\"verification\",\"type\":\"evidence_present\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "d65ca5b5ebe686293176eca1a688e9dce6831772a9b5b1c37c28c9b695bfcaf6",
      "hash": "96911424628c313e5fb7513d2ce0b418e37812171f9f507de16b63863589fc0c"
    },
    {
      "id": 1146,
      "ts": "2026-09-20T12:10:53-07:00",
      "task_id": "WF-0018",
      "action": "create",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"failure\",\"priority\":2,\"agent\":\"claude-code\",\"objective\":\"Acceptance runner cannot check a static site page by relative URL: it fetches from its own plane and gets HTTP 522\",\"detail\":\"Found on WT-0404, 2026-09-20. A test that names a path under public/ (for example http_ok /compound-media/) is fetched by runOneTest against the origin of the submit request. Submits reach the machine plane, and that plane fetching its own hostname for a static page gets HTTP 522, while the same URL answers 200 from outside and from the site host. Three submits gave the same result; the same tests naming https://miscsubjects.com passed 9 of 9 (WT-0409). Failure class: the verifier cannot reach the thing it verifies. Layer: runOneTest in functions/_lib/work_object.js, and the base that functions/api/work/[[path]].js passes it (the request origin). Invariant that should have prevented it: a test on a public page is fetched from the public site, whichever plane took the submission. Repair: resolve relative test URLs against the site host rather than the request origin, and keep absolute URLs as written. Then re-check the open tasks whose relative-URL tests pass today, so none turns red. Regression test: the acceptance test on this row, a relative-URL http_ok on a static page, fails today and passes once repaired.\",\"acceptance\":[{\"id\":\"static_page_by_relative_url\",\"type\":\"http_ok\",\"url\":\"/compound\"},{\"id\":\"commit\",\"type\":\"evidence_present\",\"field\":\"commit\"},{\"id\":\"verification\",\"type\":\"evidence_present\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "fed0e8abdd14015534fce713668fb4fd32e339224dd90f9059464101ca84d484",
      "hash": "d65ca5b5ebe686293176eca1a688e9dce6831772a9b5b1c37c28c9b695bfcaf6"
    },
    {
      "id": 1145,
      "ts": "2026-09-20T12:09:56-07:00",
      "task_id": "WT-0404",
      "action": "supersede",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 11,
      "from_state": "open",
      "to_state": "superseded",
      "input": "{\"reason\":\"Its tests named relative URLs, which the runner fetches from the machine plane; that plane answers HTTP 522 for static site pages, so the tests could never pass. WT-0409 carries the same work with tests on the site host and is completed 9 of 9.\",\"replaced_by\":\"WT-0409\"}",
      "output": "{\"note\":\"row retained; withdrawal recorded as a revision\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "superseded",
      "parent_action": null,
      "prev_hash": "b75de20431e0e4f4acfd700a5e072d4bc54dc0c13e4dea8debf1c47c5b5077d6",
      "hash": "fed0e8abdd14015534fce713668fb4fd32e339224dd90f9059464101ca84d484"
    },
    {
      "id": 1144,
      "ts": "2026-09-20T12:09:36-07:00",
      "task_id": "WT-0409",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"page_live\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":true,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://miscsubjects.com/compound-media/ (scope=content) → true\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":true,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://miscsubjects.com/compound-media/ (scope=raw) → true\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":true,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://miscsubjects.com/compound-media/leaks (scope=content) → true\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "f303983bd076193629e4c3bb8aa49a08f57eab83bdef7558d90f257ab88d1742",
      "hash": "b75de20431e0e4f4acfd700a5e072d4bc54dc0c13e4dea8debf1c47c5b5077d6"
    },
    {
      "id": 1143,
      "ts": "2026-09-20T12:09:35-07:00",
      "task_id": "WT-0409",
      "action": "submit",
      "agent": "claude-code",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). Both pages answer 200 to curl and a browser user agent; headless Chrome at 1280 and 390 wide shows no horizontal overflow, fonts loaded, no mailto links, robots noindex; the form, submitted as a visitor would with the spam-trap field filled so nothing is logged or pushed, answers Received; the calculator reads $19,593 and 5.2x on defaults, moves to $26,613 when missed calls go 15 to 30, and reads 1.0x where the old logic read 5.4x. /compound is unchanged at 12,451 bytes.\"}}",
      "output": null,
      "changed": "[\"public/compound-media/index.html\",\"public/compound-media/leaks.html\",\"public/_routes.json\"]",
      "tests": "[{\"id\":\"page_live\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":true,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://miscsubjects.com/compound-media/ (scope=content) → true\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":true,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://miscsubjects.com/compound-media/ (scope=raw) → true\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":true,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://miscsubjects.com/compound-media/leaks (scope=content) → true\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). Both pages answer 200 to curl and a browser user agent; headless Chrome at 1280 and 390 wide shows no horizontal overflow, fonts loaded, no mailto links, robots noindex; the form, submitted as a visitor would with the spam-trap field filled so nothing is logged or pushed, answers Received; the calculator reads $19,593 and 5.2x on defaults, moves to $26,613 when missed calls go 15 to 30, and reads 1.0x where the old logic read 5.4x. /compound is unchanged at 12,451 bytes.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "f9589b897b301833827d423171863b85fd9aaa2822f807fd5a96d401370ff51e",
      "hash": "f303983bd076193629e4c3bb8aa49a08f57eab83bdef7558d90f257ab88d1742"
    },
    {
      "id": 1142,
      "ts": "2026-09-20T12:09:34-07:00",
      "task_id": "WT-0409",
      "action": "create",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":1,\"agent\":\"claude-code\",\"supersedes\":\"WT-0404\",\"objective\":\"Stage the Compound Media site and its leak calculator at /compound-media, with the inquiry form working\",\"detail\":\"Owner order 2026-09-20: stage the new Compound Media site (media buying, AI creative, iMessage on the client's own number, responders, sites and automations) and its leak calculator, and give the link. Staged at /compound-media/ and /compound-media/leaks, marked noindex and linked from nowhere. The existing /compound page (the generic agency page, WT-0367) is untouched; promoting the staged page over it is a one-file move. Changes from the drafts as written: (1) the contact address hello@compound.media is replaced by the existing inquiry form (POST /api/compound/inquiry), because that domain is not the owner's; (2) the calculator's line about results 'we see' is now a plain statement that the figures are planning assumptions, since there are no client results behind them; (3) the calculator's payback multiple counted all three levers even when the package covered one, overstating the return by up to $3,400 a month of levers it had not recommended (every lever just under its threshold read 5.4x where the true figure is 1.0x); it now counts only the levers in the package, and says not to buy when the package costs more than it recovers; (4) the phone illustration is labelled as made up. Open, for the promotion: the staged copy says it only messages people who contacted the client and never uses purchased lists, while /compound sells lead lists and cold outreach. One of the two changes when they are merged. Supersedes WT-0404, whose relative-URL tests were fetched from the machine plane (ops.miscsubjects.com), which answers HTTP 522 for static site pages; these tests name the site host.\",\"acceptance\":[{\"id\":\"page_live\",\"type\":\"http_ok\",\"url\":\"https://miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"type\":\"contains\",\"url\":\"https://miscsubjects.com/compound-media/\",\"needle\":\"Your number. Not one we rent you.\"},{\"id\":\"form_uses_existing_inquiry\",\"type\":\"contains\",\"url\":\"https://miscsubjects.com/compound-media/\",\"needle\":\"/api/compound/inquiry\",\"scope\":\"raw\"},{\"id\":\"no_foreign_mailbox_page\",\"type\":\"not_contains\",\"url\":\"https://miscsubjects.com/compound-media/\",\"needle\":\"@compound.media\",\"scope\":\"raw\"},{\"id\":\"calculator_live\",\"type\":\"http_ok\",\"url\":\"https://miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"type\":\"contains\",\"url\":\"https://miscsubjects.com/compound-media/leaks\",\"needle\":\"What your leaks are worth\"},{\"id\":\"no_foreign_mailbox_calculator\",\"type\":\"not_contains\",\"url\":\"https://miscsubjects.com/compound-media/leaks\",\"needle\":\"@compound.media\",\"scope\":\"raw\"},{\"id\":\"commit\",\"type\":\"evidence_present\",\"field\":\"commit\"},{\"id\":\"verification\",\"type\":\"evidence_present\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "ee337b0f8048c8c49c1e284dbc79f1e29b41793efa18affde5d9c19e522956d0",
      "hash": "f9589b897b301833827d423171863b85fd9aaa2822f807fd5a96d401370ff51e"
    },
    {
      "id": 1141,
      "ts": "2026-09-20T12:08:35-07:00",
      "task_id": "WT-0404",
      "action": "refuse",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 10,
      "from_state": "refused",
      "to_state": "open",
      "input": null,
      "output": "{\"why\":[\"HTTP 522 https://ops.miscsubjects.com/compound-media/\",\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\",\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\",\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\",\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"],\"missing_evidence\":[]}",
      "changed": null,
      "tests": "[{\"id\":\"page_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":false,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":false,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":false,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "refused",
      "parent_action": null,
      "prev_hash": "47d11fd18f2adcd765535da5d0ab55d139f5350fdc7c4871970534a44614c01f",
      "hash": "ee337b0f8048c8c49c1e284dbc79f1e29b41793efa18affde5d9c19e522956d0"
    },
    {
      "id": 1140,
      "ts": "2026-09-20T12:08:34-07:00",
      "task_id": "WT-0404",
      "action": "submit",
      "agent": "claude-code",
      "model": null,
      "capability": "owner-key",
      "task_revision": 8,
      "from_state": "open",
      "to_state": "refused",
      "input": "{\"evidence\":{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). /compound-media/ and /compound-media/leaks answer 200 to curl and to a browser user agent. Headless Chrome at 1280 and 390 wide: no horizontal overflow, fonts loaded, message bubbles visible, no mailto links, robots noindex on both pages. Form submitted as a visitor would (spam-trap field filled so nothing is logged or pushed): page shows 'Received'. Calculator on defaults reads $19,593 recoverable and 5.2x; raising missed calls 15 to 30 moves it to $26,613; the every-lever-under-threshold case reads 1.0x, where the old logic read 5.4x. /compound is unchanged (12,451 bytes).\"}}",
      "output": null,
      "changed": "[\"public/compound-media/index.html\",\"public/compound-media/leaks.html\",\"public/_routes.json\"]",
      "tests": "[{\"id\":\"page_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":false,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":false,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":false,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). /compound-media/ and /compound-media/leaks answer 200 to curl and to a browser user agent. Headless Chrome at 1280 and 390 wide: no horizontal overflow, fonts loaded, message bubbles visible, no mailto links, robots noindex on both pages. Form submitted as a visitor would (spam-trap field filled so nothing is logged or pushed): page shows 'Received'. Calculator on defaults reads $19,593 recoverable and 5.2x; raising missed calls 15 to 30 moves it to $26,613; the every-lever-under-threshold case reads 1.0x, where the old logic read 5.4x. /compound is unchanged (12,451 bytes).\"}",
      "result": "refused",
      "parent_action": null,
      "prev_hash": "b4b8b6691c55fa8b1dcba344d4b6d4d9d431c79686f53d1109126daa20ae4593",
      "hash": "47d11fd18f2adcd765535da5d0ab55d139f5350fdc7c4871970534a44614c01f"
    },
    {
      "id": 1139,
      "ts": "2026-09-20T12:07:24-07:00",
      "task_id": "WT-0404",
      "action": "refuse",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 7,
      "from_state": "refused",
      "to_state": "open",
      "input": null,
      "output": "{\"why\":[\"HTTP 522 https://ops.miscsubjects.com/compound-media/\",\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\",\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\",\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\",\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"],\"missing_evidence\":[]}",
      "changed": null,
      "tests": "[{\"id\":\"page_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":false,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":false,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":false,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "refused",
      "parent_action": null,
      "prev_hash": "c5a06feb84dfff238e0ac18e13ef51148eb0ca034849329637a516f6f7998e4c",
      "hash": "b4b8b6691c55fa8b1dcba344d4b6d4d9d431c79686f53d1109126daa20ae4593"
    },
    {
      "id": 1138,
      "ts": "2026-09-20T12:07:23-07:00",
      "task_id": "WT-0404",
      "action": "submit",
      "agent": "claude-code",
      "model": null,
      "capability": "owner-key",
      "task_revision": 5,
      "from_state": "open",
      "to_state": "refused",
      "input": "{\"evidence\":{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). /compound-media/ and /compound-media/leaks answer 200 to curl and to a browser user agent, from both the site and the machine plane. Headless Chrome at 1280 and 390 wide: no horizontal overflow, fonts loaded, message bubbles visible, no mailto links, robots noindex on both pages. Form submitted as a visitor would (spam-trap field filled so nothing is logged or pushed): page shows 'Received'. Calculator on defaults reads $19,593 recoverable and 5.2x; raising missed calls 15 to 30 moves it to $26,613; the every-lever-under-threshold case reads 1.0x, where the old logic read 5.4x. /compound is unchanged (12,451 bytes).\"}}",
      "output": null,
      "changed": "[\"public/compound-media/index.html\",\"public/compound-media/leaks.html\",\"public/_routes.json\"]",
      "tests": "[{\"id\":\"page_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":false,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":false,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":false,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). /compound-media/ and /compound-media/leaks answer 200 to curl and to a browser user agent, from both the site and the machine plane. Headless Chrome at 1280 and 390 wide: no horizontal overflow, fonts loaded, message bubbles visible, no mailto links, robots noindex on both pages. Form submitted as a visitor would (spam-trap field filled so nothing is logged or pushed): page shows 'Received'. Calculator on defaults reads $19,593 recoverable and 5.2x; raising missed calls 15 to 30 moves it to $26,613; the every-lever-under-threshold case reads 1.0x, where the old logic read 5.4x. /compound is unchanged (12,451 bytes).\"}",
      "result": "refused",
      "parent_action": null,
      "prev_hash": "dbc98b0eb94382c789e144a5513eeedc8cdf36607c73f76708947678199ee007",
      "hash": "c5a06feb84dfff238e0ac18e13ef51148eb0ca034849329637a516f6f7998e4c"
    },
    {
      "id": 1137,
      "ts": "2026-09-20T12:05:30-07:00",
      "task_id": "WT-0404",
      "action": "refuse",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "refused",
      "to_state": "open",
      "input": null,
      "output": "{\"why\":[\"HTTP 522 https://ops.miscsubjects.com/compound-media/\",\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\",\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\",\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\",\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"],\"missing_evidence\":[]}",
      "changed": null,
      "tests": "[{\"id\":\"page_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":false,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":false,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":false,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "refused",
      "parent_action": null,
      "prev_hash": "a6362b771ee22ec342d0d589edf097891de12b17ec2d58baa04a3587af4e8ce2",
      "hash": "dbc98b0eb94382c789e144a5513eeedc8cdf36607c73f76708947678199ee007"
    },
    {
      "id": 1136,
      "ts": "2026-09-20T12:05:29-07:00",
      "task_id": "WT-0404",
      "action": "submit",
      "agent": "claude-code",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "refused",
      "input": "{\"evidence\":{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). /compound-media/ and /compound-media/leaks answer 200 to curl and to a browser user agent. Headless Chrome at 1280 and 390 wide: no horizontal overflow, fonts loaded, message bubbles visible, no mailto links, robots noindex on both pages. Form submitted as a visitor would (spam-trap field filled so nothing is logged or pushed): page shows 'Received'. Calculator on defaults reads $19,593 recoverable and 5.2x; raising missed calls 15 to 30 moves it to $26,613; the every-lever-under-threshold case reads 1.0x, where the old logic read 5.4x. /compound is unchanged (12,451 bytes).\"}}",
      "output": null,
      "changed": "[\"public/compound-media/index.html\",\"public/compound-media/leaks.html\",\"public/_routes.json\"]",
      "tests": "[{\"id\":\"page_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/\"},{\"id\":\"wedge_line\",\"ok\":false,\"detail\":\"contains \\\"Your number. Not one we rent you.\\\" in https://ops.miscsubjects.com/compound-media/ (scope=content) → false\"},{\"id\":\"form_uses_existing_inquiry\",\"ok\":false,\"detail\":\"contains \\\"/api/compound/inquiry\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"no_foreign_mailbox_page\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/ (scope=raw) → false\"},{\"id\":\"calculator_live\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/compound-media/leaks\"},{\"id\":\"calculator_title\",\"ok\":false,\"detail\":\"contains \\\"What your leaks are worth\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=content) → false\"},{\"id\":\"no_foreign_mailbox_calculator\",\"ok\":true,\"detail\":\"not_contains \\\"@compound.media\\\" in https://ops.miscsubjects.com/compound-media/leaks (scope=raw) → false\"},{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"dfab964ea\",\"verification\":\"Live 2026-09-20 after deploy (16 post-deploy gates passed). /compound-media/ and /compound-media/leaks answer 200 to curl and to a browser user agent. Headless Chrome at 1280 and 390 wide: no horizontal overflow, fonts loaded, message bubbles visible, no mailto links, robots noindex on both pages. Form submitted as a visitor would (spam-trap field filled so nothing is logged or pushed): page shows 'Received'. Calculator on defaults reads $19,593 recoverable and 5.2x; raising missed calls 15 to 30 moves it to $26,613; the every-lever-under-threshold case reads 1.0x, where the old logic read 5.4x. /compound is unchanged (12,451 bytes).\"}",
      "result": "refused",
      "parent_action": null,
      "prev_hash": "21f7b1bd5c1716fd7d59751e22fa5a474afff400689b07092bd8d66166d0a69b",
      "hash": "a6362b771ee22ec342d0d589edf097891de12b17ec2d58baa04a3587af4e8ce2"
    },
    {
      "id": 1135,
      "ts": "2026-09-20T11:59:49-07:00",
      "task_id": "WT-0408",
      "action": "create",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":2,\"agent\":\"claude-code\",\"objective\":\"Compound Media gets its own address: a domain, a mailbox, and the staged site moved onto it\",\"detail\":\"Checked 2026-09-20: compound.media is not the owner's (its name servers are Afternic's, a for-sale marketplace); compoundmedia.com is registered by someone else; the owner's Cloudflare account holds no Compound-named zone. The draft pages used hello@compound.media, which would have sent every lead to a stranger, so the staged pages use the inquiry form. Routes, in order: a hostname on a domain the owner already holds, served by the same site, with a mailbox through Cloudflare Email Routing; or buy a Compound name, which is a purchase. Either way: point the address at the site, switch the pages from noindex to indexable with a canonical link, and confirm a submitted inquiry still lands.\",\"acceptance\":[{\"id\":\"hostname\",\"type\":\"evidence_present\",\"field\":\"hostname\"},{\"id\":\"live_url\",\"type\":\"evidence_present\",\"field\":\"live_url\"},{\"id\":\"mailbox\",\"type\":\"evidence_present\",\"field\":\"mailbox\"}],\"evidence_required\":[\"hostname\",\"live_url\",\"mailbox\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "0da08a25ad46544ca7bf1504905631a8db710281c22e0af1a3a0c5ee25461534",
      "hash": "21f7b1bd5c1716fd7d59751e22fa5a474afff400689b07092bd8d66166d0a69b"
    },
    {
      "id": 1134,
      "ts": "2026-09-20T11:59:47-07:00",
      "task_id": "WT-0407",
      "action": "create",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":2,\"agent\":\"claude-code\",\"objective\":\"One-command client stack: the client's own MCP server, the AI on their line, the responder and their automations as one tenant\",\"detail\":\"The offer on /compound-media covers the client's MCP and the AI behind their line, not only the number. The build already clones tenants: scripts/cf-tenant.mjs clone <source> <name> --ns=production (Workers for Platforms, 1,000 scripts included), reachable through the dispatcher. Build the client version: a template tenant carrying an MCP endpoint (initialize and tools/list answering), a responder that answers in the client's voice, quotes only what they approved and hands off to a person, the line binding from the own-number row, and the automations the rate card sells (missed-call text-back, estimate follow-up). One command names the client and returns the tenant URL, the MCP URL and a test transcript. Each client's data stays inside their own tenant.\",\"acceptance\":[{\"id\":\"tenant_name\",\"type\":\"evidence_present\",\"field\":\"tenant_name\"},{\"id\":\"mcp_handshake_receipt\",\"type\":\"evidence_present\",\"field\":\"mcp_handshake_receipt\"},{\"id\":\"responder_test_receipt\",\"type\":\"evidence_present\",\"field\":\"responder_test_receipt\"}],\"evidence_required\":[\"tenant_name\",\"mcp_handshake_receipt\",\"responder_test_receipt\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "cde91b68985a37638d5d1c7d9170a089a969075b94f4d27cea563e19cabbf7ac",
      "hash": "0da08a25ad46544ca7bf1504905631a8db710281c22e0af1a3a0c5ee25461534"
    },
    {
      "id": 1133,
      "ts": "2026-09-20T11:59:46-07:00",
      "task_id": "WT-0406",
      "action": "create",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":2,\"agent\":\"claude-code\",\"objective\":\"Higgsfield API into the Demand side: a brief in, a batch of ad creative out, a person picks the winners\",\"detail\":\"Higgsfield's API (docs.higgsfield.ai) is one asynchronous REST service for generated video and images: POST https://platform.higgsfield.ai/<model_id> with header Authorization: Key <id>:<secret> returns a request id at once; poll GET /requests/<id>/status or take a webhook. One key reaches 50+ models (Seedance, Kling, Veo, Sora, Wan, MiniMax, and Higgsfield's own Soul and DoP). It bills from a separate prepaid dollar balance, not from a higgsfield.ai plan's credits; the Higgsfield MCP and CLI are a different route that spends plan credits. No Higgsfield credentials are held in the build yet (checked 2026-09-20). That is the one gap, and it is a payment: an API account with a funded balance. Everything else is buildable now against the docs. Build: directory rows HIGGSFIELD_GENERATE (model, prompt, image_url, count) and HIGGSFIELD_STATUS; each finished asset copied to storage with one ledger row; a brief-to-batch step so thirty angles a month is one command; a person marks winners, and winners feed the media-buying creative queue. Sources: docs.higgsfield.ai; the Higgsfield help centre article 'What is the Higgsfield API'.\",\"acceptance\":[{\"id\":\"directory_key\",\"type\":\"evidence_present\",\"field\":\"directory_key\"},{\"id\":\"sample_generation_receipt\",\"type\":\"evidence_present\",\"field\":\"sample_generation_receipt\"},{\"id\":\"asset_url\",\"type\":\"evidence_present\",\"field\":\"asset_url\"}],\"evidence_required\":[\"directory_key\",\"sample_generation_receipt\",\"asset_url\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "0c509a18f85248b684d4e1620e4d9442ead71c10e1ac3aeb339ae6ee86886284",
      "hash": "cde91b68985a37638d5d1c7d9170a089a969075b94f4d27cea563e19cabbf7ac"
    },
    {
      "id": 1132,
      "ts": "2026-09-20T11:59:44-07:00",
      "task_id": "WT-0405",
      "action": "create",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":2,\"agent\":\"claude-code\",\"objective\":\"Own-number iMessage line: check a client's number, register it, and recover it when Apple drops it\",\"detail\":\"The wedge on /compound-media. Blooio and Sendblue hand a business a number they own; nobody offers to turn the business's own number into an iMessage line. The catch is operations. Registering an existing number for iMessage means passing Apple's check on a device that holds that line, so each client number needs its own device (an iPhone, or a Mac with a SIM or eSIM), and hosted VoIP numbers often cannot pass at all. Already in the build: the owner's Mac sends and receives iMessage through the IMSG_* directory rows, and Blooio is wired in as the fallback for a number that cannot pass. Build: (1) a line check that takes a number and returns carrier, line type (mobile, landline, VoIP) and a plain verdict, can go blue or cannot, before the client pays; (2) the runbook and IMSG rows to register one client line on one device, with RCS and SMS fallback for Android; (3) a recovery playbook for when Apple deregisters a line, with the client's messages held and not dropped; (4) the cost of one line (device, plan, upkeep) against the rented alternative from the vendors' current price pages, so the $1,500 setup and the monthly fee on the site stay above cost. Rented-line prices have not been checked against the vendors' price pages.\",\"acceptance\":[{\"id\":\"line_check_result\",\"type\":\"evidence_present\",\"field\":\"line_check_result\"},{\"id\":\"registered_line_receipt\",\"type\":\"evidence_present\",\"field\":\"registered_line_receipt\"},{\"id\":\"recovery_runbook\",\"type\":\"evidence_present\",\"field\":\"recovery_runbook\"},{\"id\":\"unit_cost_per_line\",\"type\":\"evidence_present\",\"field\":\"unit_cost_per_line\"}],\"evidence_required\":[\"line_check_result\",\"registered_line_receipt\",\"recovery_runbook\",\"unit_cost_per_line\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "26245ba0286812ed7d173d916c80350096a615e351ae001598656bd10d5c94ff",
      "hash": "0c509a18f85248b684d4e1620e4d9442ead71c10e1ac3aeb339ae6ee86886284"
    },
    {
      "id": 1131,
      "ts": "2026-09-20T11:59:43-07:00",
      "task_id": "WT-0404",
      "action": "create",
      "agent": "claude-code",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":1,\"agent\":\"claude-code\",\"objective\":\"Stage the Compound Media site and its leak calculator at /compound-media, with the inquiry form working\",\"detail\":\"Owner order 2026-09-20: stage the new Compound Media site (media buying, AI creative, iMessage on the client's own number, responders, sites and automations) and its leak calculator, and give the link. Staged at /compound-media/ and /compound-media/leaks, marked noindex and linked from nowhere. The existing /compound page (the generic agency page, WT-0367) is untouched; promoting the staged page over it is a one-file move. Changes from the drafts as written: (1) the contact address hello@compound.media is replaced by the existing inquiry form (POST /api/compound/inquiry), because that domain is not the owner's; (2) the calculator's line about results 'we see' is now a plain statement that the figures are planning assumptions, since there are no client results behind them; (3) the calculator's payback multiple counted all three levers even when the package covered one, overstating the return by up to $3,400 a month of levers it had not recommended (every lever just under its threshold read 5.4x where the true figure is 1.0x); it now counts only the levers in the package, and says not to buy when the package costs more than it recovers; (4) the phone illustration is labelled as made up. Open, for the promotion: the staged copy says it only messages people who contacted the client and never uses purchased lists, while /compound sells lead lists and cold outreach. One of the two changes when they are merged.\",\"acceptance\":[{\"id\":\"page_live\",\"type\":\"http_ok\",\"url\":\"/compound-media/\"},{\"id\":\"wedge_line\",\"type\":\"contains\",\"url\":\"/compound-media/\",\"needle\":\"Your number. Not one we rent you.\"},{\"id\":\"form_uses_existing_inquiry\",\"type\":\"contains\",\"url\":\"/compound-media/\",\"needle\":\"/api/compound/inquiry\",\"scope\":\"raw\"},{\"id\":\"no_foreign_mailbox_page\",\"type\":\"not_contains\",\"url\":\"/compound-media/\",\"needle\":\"@compound.media\",\"scope\":\"raw\"},{\"id\":\"calculator_live\",\"type\":\"http_ok\",\"url\":\"/compound-media/leaks\"},{\"id\":\"calculator_title\",\"type\":\"contains\",\"url\":\"/compound-media/leaks\",\"needle\":\"What your leaks are worth\"},{\"id\":\"no_foreign_mailbox_calculator\",\"type\":\"not_contains\",\"url\":\"/compound-media/leaks\",\"needle\":\"@compound.media\",\"scope\":\"raw\"},{\"id\":\"commit\",\"type\":\"evidence_present\",\"field\":\"commit\"},{\"id\":\"verification\",\"type\":\"evidence_present\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "3426af79e44f7f82728173290cc87c4bd8ccbde33827cecd1610a49c9fc77d81",
      "hash": "26245ba0286812ed7d173d916c80350096a615e351ae001598656bd10d5c94ff"
    },
    {
      "id": 1130,
      "ts": "2026-09-20T09:07:51-07:00",
      "task_id": "WT-0403",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"plain_words\",\"ok\":true,\"detail\":\"contains \\\"## In plain words\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"recommended\",\"ok\":true,\"detail\":\"contains \\\"p9-lean-code\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"page\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/.well-known/invocation?format=html\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "fd6c993a5e596c9b97df9a3c63331d3e0d5bc5acf39e5a6fc3c82fe02f3dfb12",
      "hash": "3426af79e44f7f82728173290cc87c4bd8ccbde33827cecd1610a49c9fc77d81"
    },
    {
      "id": 1129,
      "ts": "2026-09-20T09:07:51-07:00",
      "task_id": "WT-0403",
      "action": "submit",
      "agent": "claude-fable",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"done\":true,\"commit\":\"a20991ffc\",\"live\":[\"https://miscsubjects.com/console#/sessions → Code mode\",\"https://miscsubjects.com/.well-known/invocation?format=html#plain\",\"GET /api/agents/presets → p9-lean-code, p10-lean-findcall-read, p11-lean-edit-preread\"]}}",
      "output": null,
      "changed": "[\"public/console.html\",\"scripts/agent-runner.mjs\",\"migrations/0462_agent_run_prompts_plain.sql\",\"functions/_lib/agent_toolsets.js\",\"functions/_lib/invocation_spec.js\"]",
      "tests": "[{\"id\":\"plain_words\",\"ok\":true,\"detail\":\"contains \\\"## In plain words\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"recommended\",\"ok\":true,\"detail\":\"contains \\\"p9-lean-code\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"page\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/.well-known/invocation?format=html\"}]",
      "evidence": "{\"done\":true,\"commit\":\"a20991ffc\",\"live\":[\"https://miscsubjects.com/console#/sessions → Code mode\",\"https://miscsubjects.com/.well-known/invocation?format=html#plain\",\"GET /api/agents/presets → p9-lean-code, p10-lean-findcall-read, p11-lean-edit-preread\"]}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "efdc11f1e0da93f3a6bd2ddca3bb28a3394577258a658082ad0211bc5c7f442f",
      "hash": "fd6c993a5e596c9b97df9a3c63331d3e0d5bc5acf39e5a6fc3c82fe02f3dfb12"
    },
    {
      "id": 1128,
      "ts": "2026-09-20T09:04:05-07:00",
      "task_id": "WT-0403",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Sessions: Code mode opens a sheet where the system prompt, tools, pre-read and instructions are read and changed before Start; the pre-read answers in plain lines; three recommended runs lined up with a short prompt row\",\"detail\":\"Owner order 2026-09-20: remove the complexity from the pre-read (classifier), control the system prompt and tool payloads from Sessions and test code mode there, recommend tool payloads / system prompts / inputs. public/console.html: the Code mode mark opens a sheet (pick a lined-up run, model, system prompt, tool set + tools JSON, pre-read on/off with its model and prompt, instructions; Line up or Start). scripts/agent-runner.mjs: the pre-read answer may be plain lines (file paths, one capability line), JSON still read. migrations/0462: the recommended short prompt row AGENT_RUN_PROMPT_LEAN and the pre-read prompt without the JSON contract (only while its text is still the JSON one). functions/_lib/agent_toolsets.js: presets p9, p10, p11 and plain tool-set wording. functions/_lib/invocation_spec.js: the page carries the plain-English done/not-done inventory and the recommendations.\",\"priority\":2,\"acceptance\":[{\"type\":\"contains\",\"id\":\"plain_words\",\"url\":\"https://miscsubjects.com/.well-known/invocation?format=md\",\"needle\":\"## In plain words\",\"scope\":\"raw\"},{\"type\":\"contains\",\"id\":\"recommended\",\"url\":\"https://miscsubjects.com/.well-known/invocation?format=md\",\"needle\":\"p9-lean-code\",\"scope\":\"raw\"},{\"type\":\"http_ok\",\"id\":\"page\",\"url\":\"https://miscsubjects.com/.well-known/invocation?format=html\"}]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8b8737fe67ed815c7a951477759ba49c510368e4bced7459c57533d3a2e2fd01",
      "hash": "efdc11f1e0da93f3a6bd2ddca3bb28a3394577258a658082ad0211bc5c7f442f"
    },
    {
      "id": 1127,
      "ts": "2026-09-20T08:42:29-07:00",
      "task_id": "WT-0402",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"spec_root_json\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/.well-known/invocation\"},{\"id\":\"spec_root_html\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/.well-known/invocation?format=html\"},{\"id\":\"matrix_present\",\"ok\":true,\"detail\":\"contains \\\"Every core tool across every way\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"left_out_present\",\"ok\":true,\"detail\":\"contains \\\"What is left out\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"tools_links_root\",\"ok\":true,\"detail\":\"contains \\\"Machine spec root\\\" in https://miscsubjects.com/tools (scope=raw) → true\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "e4f61ecc19a362f8d2a0814fca71d5cc2c0ee216a53e0a821dd4063b0f6529e1",
      "hash": "8b8737fe67ed815c7a951477759ba49c510368e4bced7459c57533d3a2e2fd01"
    },
    {
      "id": 1126,
      "ts": "2026-09-20T08:42:28-07:00",
      "task_id": "WT-0402",
      "action": "submit",
      "agent": "claude-fable",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"done\":true,\"commits\":[\"71de70bd8\",\"637d764d4\"],\"live\":[\"https://miscsubjects.com/.well-known/invocation\",\"https://miscsubjects.com/.well-known/invocation?format=md\",\"https://miscsubjects.com/.well-known/invocation?format=html\",\"https://ops.miscsubjects.com/api/agents/runs/run_0fc2a97a3fa9/calls (206 rows, was 1102)\"]}}",
      "output": null,
      "changed": "[\"functions/.well-known/invocation.js\",\"functions/_lib/invocation_spec.js\",\"functions/api/agents/[[path]].js\",\"functions/_lib/grammar.js\",\"functions/tools.js\",\"public/console.html\"]",
      "tests": "[{\"id\":\"spec_root_json\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/.well-known/invocation\"},{\"id\":\"spec_root_html\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/.well-known/invocation?format=html\"},{\"id\":\"matrix_present\",\"ok\":true,\"detail\":\"contains \\\"Every core tool across every way\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"left_out_present\",\"ok\":true,\"detail\":\"contains \\\"What is left out\\\" in https://miscsubjects.com/.well-known/invocation?format=md (scope=raw) → true\"},{\"id\":\"tools_links_root\",\"ok\":true,\"detail\":\"contains \\\"Machine spec root\\\" in https://miscsubjects.com/tools (scope=raw) → true\"}]",
      "evidence": "{\"done\":true,\"commits\":[\"71de70bd8\",\"637d764d4\"],\"live\":[\"https://miscsubjects.com/.well-known/invocation\",\"https://miscsubjects.com/.well-known/invocation?format=md\",\"https://miscsubjects.com/.well-known/invocation?format=html\",\"https://ops.miscsubjects.com/api/agents/runs/run_0fc2a97a3fa9/calls (206 rows, was 1102)\"]}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "8e591de8879b9f46b16b3f55618cdc89f3cabb60173c6d6689879256190ca8ab",
      "hash": "e4f61ecc19a362f8d2a0814fca71d5cc2c0ee216a53e0a821dd4063b0f6529e1"
    },
    {
      "id": 1125,
      "ts": "2026-09-20T08:41:45-07:00",
      "task_id": "WT-0401",
      "action": "supersede",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 8,
      "from_state": "open",
      "to_state": "superseded",
      "input": "{\"reason\":\"its acceptance tests named the machine-plane host, which a Worker cannot fetch from inside (HTTP 522); WT-0402 carries the same tests against the site host\",\"replaced_by\":\"WT-0402\"}",
      "output": "{\"note\":\"row retained; withdrawal recorded as a revision\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "superseded",
      "parent_action": null,
      "prev_hash": "9c4ac0bbf82c2767ea7bc0b0e436a5bac42cf0b90b433b2fe08a8d50bd375f11",
      "hash": "8e591de8879b9f46b16b3f55618cdc89f3cabb60173c6d6689879256190ca8ab"
    },
    {
      "id": 1124,
      "ts": "2026-09-20T08:41:00-07:00",
      "task_id": "WT-0402",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"The machine spec root /.well-known/invocation is live on the site: every core tool across every way, what is live and what is left out; the run record opens for runs over 100 rows; a run session mirrors in pages\",\"detail\":\"Supersedes WT-0401 (same work, whose acceptance tests named the machine-plane host: a Worker cannot fetch its own Worker-routed hostname from inside, HTTP 522, so the tests could never run). Same tests against the site host. Change set 71de70bd8 (+ 637d764d4 console guard, + the paged mirror): functions/.well-known/invocation.js + functions/_lib/invocation_spec.js (the compiled root: JSON, ?format=md, ?format=html), functions/api/agents/[[path]].js (calls list reads sizes, ?seq=N one row; POST mirror takes from/n and answers next), functions/_lib/grammar.js (name=value binds by name), functions/tools.js (link), public/console.html (stale-render guard).\",\"priority\":2,\"supersedes\":\"WT-0401\",\"acceptance\":[{\"type\":\"http_ok\",\"id\":\"spec_root_json\",\"url\":\"https://miscsubjects.com/.well-known/invocation\"},{\"type\":\"http_ok\",\"id\":\"spec_root_html\",\"url\":\"https://miscsubjects.com/.well-known/invocation?format=html\"},{\"type\":\"contains\",\"id\":\"matrix_present\",\"url\":\"https://miscsubjects.com/.well-known/invocation?format=md\",\"needle\":\"Every core tool across every way\",\"scope\":\"raw\"},{\"type\":\"contains\",\"id\":\"left_out_present\",\"url\":\"https://miscsubjects.com/.well-known/invocation?format=md\",\"needle\":\"What is left out\",\"scope\":\"raw\"},{\"type\":\"contains\",\"id\":\"tools_links_root\",\"url\":\"https://miscsubjects.com/tools\",\"needle\":\"Machine spec root\",\"scope\":\"raw\"}]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "b273b3ed61648f0e75d43a68d72a686d98b18af51ef0cc6f428ea864589e2b7a",
      "hash": "9c4ac0bbf82c2767ea7bc0b0e436a5bac42cf0b90b433b2fe08a8d50bd375f11"
    },
    {
      "id": 1123,
      "ts": "2026-09-20T08:38:01-07:00",
      "task_id": "WT-0401",
      "action": "refuse",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 7,
      "from_state": "refused",
      "to_state": "open",
      "input": null,
      "output": "{\"why\":[\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation\",\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation?format=html\",\"contains \\\"Every core tool across every way\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\",\"contains \\\"What is left out\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"],\"missing_evidence\":[]}",
      "changed": null,
      "tests": "[{\"id\":\"spec_root_json\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation\"},{\"id\":\"spec_root_html\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation?format=html\"},{\"id\":\"matrix_present\",\"ok\":false,\"detail\":\"contains \\\"Every core tool across every way\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"},{\"id\":\"left_out_present\",\"ok\":false,\"detail\":\"contains \\\"What is left out\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"}]",
      "evidence": null,
      "result": "refused",
      "parent_action": null,
      "prev_hash": "a6bb8e75f28a95adf9dd073372647d9f1fcb45228f4af82e634ee45ffd2bf8e8",
      "hash": "b273b3ed61648f0e75d43a68d72a686d98b18af51ef0cc6f428ea864589e2b7a"
    },
    {
      "id": 1122,
      "ts": "2026-09-20T08:38:00-07:00",
      "task_id": "WT-0401",
      "action": "submit",
      "agent": "claude-fable",
      "model": null,
      "capability": "owner-key",
      "task_revision": 5,
      "from_state": "open",
      "to_state": "refused",
      "input": "{\"evidence\":{\"done\":true,\"commit\":\"71de70bd8\",\"live\":[\"https://miscsubjects.com/.well-known/invocation\",\"https://ops.miscsubjects.com/api/agents/runs/run_0fc2a97a3fa9/calls (206 rows, was 1102)\"]}}",
      "output": null,
      "changed": "[\"functions/.well-known/invocation.js\",\"functions/_lib/invocation_spec.js\",\"functions/api/agents/[[path]].js\",\"functions/_lib/grammar.js\",\"functions/tools.js\"]",
      "tests": "[{\"id\":\"spec_root_json\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation\"},{\"id\":\"spec_root_html\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation?format=html\"},{\"id\":\"matrix_present\",\"ok\":false,\"detail\":\"contains \\\"Every core tool across every way\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"},{\"id\":\"left_out_present\",\"ok\":false,\"detail\":\"contains \\\"What is left out\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"}]",
      "evidence": "{\"done\":true,\"commit\":\"71de70bd8\",\"live\":[\"https://miscsubjects.com/.well-known/invocation\",\"https://ops.miscsubjects.com/api/agents/runs/run_0fc2a97a3fa9/calls (206 rows, was 1102)\"]}",
      "result": "refused",
      "parent_action": null,
      "prev_hash": "1c27426259319ee1886f44122e7279441cb4ec6bb96eb1006afd15db90ca5e49",
      "hash": "a6bb8e75f28a95adf9dd073372647d9f1fcb45228f4af82e634ee45ffd2bf8e8"
    },
    {
      "id": 1121,
      "ts": "2026-09-20T08:35:42-07:00",
      "task_id": "WT-0401",
      "action": "refuse",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "refused",
      "to_state": "open",
      "input": null,
      "output": "{\"why\":[\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation\",\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation?format=html\",\"contains \\\"Every core tool across every way\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\",\"contains \\\"What is left out\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"],\"missing_evidence\":[]}",
      "changed": null,
      "tests": "[{\"id\":\"spec_root_json\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation\"},{\"id\":\"spec_root_html\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation?format=html\"},{\"id\":\"matrix_present\",\"ok\":false,\"detail\":\"contains \\\"Every core tool across every way\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"},{\"id\":\"left_out_present\",\"ok\":false,\"detail\":\"contains \\\"What is left out\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"}]",
      "evidence": null,
      "result": "refused",
      "parent_action": null,
      "prev_hash": "c039bd95b1aa56273b1e5b638aba6cc57ecef2ac5bfb730123d0ca2b3396ce1e",
      "hash": "1c27426259319ee1886f44122e7279441cb4ec6bb96eb1006afd15db90ca5e49"
    },
    {
      "id": 1120,
      "ts": "2026-09-20T08:35:42-07:00",
      "task_id": "WT-0401",
      "action": "submit",
      "agent": "claude-fable",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "refused",
      "input": "{\"evidence\":{\"done\":true,\"commit\":\"71de70bd8\",\"live\":[\"https://miscsubjects.com/.well-known/invocation\",\"https://miscsubjects.com/.well-known/invocation?format=md\",\"https://miscsubjects.com/.well-known/invocation?format=html\",\"https://ops.miscsubjects.com/api/agents/runs/run_0fc2a97a3fa9/calls (206 rows, was 1102)\",\"https://ops.miscsubjects.com/api/agents/runs/run_3023ffdb38f9/calls (257 rows, was 1102)\",\"GET /api/resolve?line=D1_QUERY sql_select=\\\"SELECT 1 AS one\\\" → args {sql_select} (plan only)\"]}}",
      "output": null,
      "changed": "[\"functions/.well-known/invocation.js\",\"functions/_lib/invocation_spec.js\",\"functions/api/agents/[[path]].js\",\"functions/_lib/grammar.js\",\"functions/tools.js\"]",
      "tests": "[{\"id\":\"spec_root_json\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation\"},{\"id\":\"spec_root_html\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/.well-known/invocation?format=html\"},{\"id\":\"matrix_present\",\"ok\":false,\"detail\":\"contains \\\"Every core tool across every way\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"},{\"id\":\"left_out_present\",\"ok\":false,\"detail\":\"contains \\\"What is left out\\\" in https://ops.miscsubjects.com/.well-known/invocation?format=md (scope=raw) → false\"}]",
      "evidence": "{\"done\":true,\"commit\":\"71de70bd8\",\"live\":[\"https://miscsubjects.com/.well-known/invocation\",\"https://miscsubjects.com/.well-known/invocation?format=md\",\"https://miscsubjects.com/.well-known/invocation?format=html\",\"https://ops.miscsubjects.com/api/agents/runs/run_0fc2a97a3fa9/calls (206 rows, was 1102)\",\"https://ops.miscsubjects.com/api/agents/runs/run_3023ffdb38f9/calls (257 rows, was 1102)\",\"GET /api/resolve?line=D1_QUERY sql_select=\\\"SELECT 1 AS one\\\" → args {sql_select} (plan only)\"]}",
      "result": "refused",
      "parent_action": null,
      "prev_hash": "c28884ed69d46ed333d1d01e3dd8b7db2902cad2364208b90536c71f7cf784b3",
      "hash": "c039bd95b1aa56273b1e5b638aba6cc57ecef2ac5bfb730123d0ca2b3396ce1e"
    },
    {
      "id": 1119,
      "ts": "2026-09-20T08:31:36-07:00",
      "task_id": "WT-0401",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"The machine spec root /.well-known/invocation: every core tool across every way of calling it, what is live and what is left out, compiled from the build\",\"detail\":\"Owner spec §16 (2026-09-20): one machine-readable root a cold model or reader starts from. Compiled at request time from agent_toolsets.js (FIND/CALL/CODE, native tools, tool sets, presets), the tools route (misc_find/misc_run), invocation_methods.js (families, spellings) and the directory; JSON, ?format=md, ?format=html. Carries the core-tools × ways matrix (live / declared-refused / alias / not built), the routes the spec names with live status, the inventory of what exists and what is left out, the KEEP/CHANGE/DELETE/BUILD/DO NOT BUILD verdicts of the 2026-09-20 review, the measured runs, and where the record is. Same change set: the run record list (GET /api/agents/runs/<id>/calls) reads sizes instead of bodies so runs over ~100 rows open (two answered 1102); the line grammar binds name=value after the key by name when the row declares it (misc run KEY name=value); /tools links the root.\",\"priority\":2,\"acceptance\":[{\"type\":\"http_ok\",\"id\":\"spec_root_json\",\"url\":\"/.well-known/invocation\"},{\"type\":\"http_ok\",\"id\":\"spec_root_html\",\"url\":\"/.well-known/invocation?format=html\"},{\"type\":\"contains\",\"id\":\"matrix_present\",\"url\":\"/.well-known/invocation?format=md\",\"needle\":\"Every core tool across every way\",\"scope\":\"raw\"},{\"type\":\"contains\",\"id\":\"left_out_present\",\"url\":\"/.well-known/invocation?format=md\",\"needle\":\"What is left out\",\"scope\":\"raw\"}]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "5effc6be4f626a2c4c7027c0105cae21e89f6371a74f0672036780cae42aae7f",
      "hash": "c28884ed69d46ed333d1d01e3dd8b7db2902cad2364208b90536c71f7cf784b3"
    },
    {
      "id": 1118,
      "ts": "2026-09-20T02:32:15-07:00",
      "task_id": "WT-0400",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"objective\":\"CODE: one program that reads three task rows through CALL and returns only task_id, state and priority\",\"detail\":\"Tool surface test (owner, 2026-09-20): CODE mode without the Cloudflare package. The run has CODE, FIND, CALL, shell and land. Write ONE CODE program that: FINDs the capability that reads one work task by id; CALLs it for WT-0391, WT-0392 and WT-0393; and returns an array of {task_id, state, priority} and nothing else. Write the program text and its returned result to reports/tool-surface/<this task id>.md, then land with the message \\\"tool surface test: CODE\\\". Record kept by the run door: the CODE call as one row, and each inner FIND/CALL as its own row naming the CODE row as parent.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "b70d95e7440b5c1e42516ed1c24335cbfd37dd40a057c1ceafcfed485caf765b",
      "hash": "5effc6be4f626a2c4c7027c0105cae21e89f6371a74f0672036780cae42aae7f"
    },
    {
      "id": 1117,
      "ts": "2026-09-20T02:32:14-07:00",
      "task_id": "WT-0399",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"objective\":\"The resolver answers with a top-level receipt on every executed call\",\"detail\":\"Defect measured 2026-09-20 (WT-0395): POST /api/resolve {line, run:true} and {key, args, run:true} answer with no top-level receipt field; the receipt sits under result or trace. Wanted: every answer where run=true carries a top-level receipt (the receipt URL or id, the same value that sits inside today) beside ok and result, with nothing removed from the answer. File: functions/api/resolve.js. Add one case to its test file if it has one. Land with the message \\\"resolve: top-level receipt\\\".\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "e24d59c47efd3e39dce57bb11ed00bf0a105a7ceb53dddda825b5fbf1b89da1e",
      "hash": "b70d95e7440b5c1e42516ed1c24335cbfd37dd40a057c1ceafcfed485caf765b"
    },
    {
      "id": 1116,
      "ts": "2026-09-20T02:32:13-07:00",
      "task_id": "WT-0398",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"objective\":\"FIND and CALL only, no native tools: read five rows of the work feed through the directory and write down what came back\",\"detail\":\"Tool surface test (owner, 2026-09-20). The run has FIND, CALL, shell and land — no read/edit/write/grep/glob. Using FIND, locate the capability that lists the work feed; using CALL, run it for five rows with want {\\\"limit\\\":5}. Write to reports/tool-surface/<this task id>.md: the FIND you made and what it answered, the CALL you made, the five task ids it returned, and the receipt the CALL answered with. Then land with the message \\\"tool surface test: FIND/CALL read\\\". Record kept by the run door: every FIND and CALL as a row, raw and parsed.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "e504fd5f9e57d27464a7db71f3641d46059ce4a2efbb3ad785826061c62a7984",
      "hash": "e24d59c47efd3e39dce57bb11ed00bf0a105a7ceb53dddda825b5fbf1b89da1e"
    },
    {
      "id": 1115,
      "ts": "2026-09-20T01:52:32-07:00",
      "task_id": "WT-0395",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"notes\":\"Take five cards whose tool has read effects and run each call line through POST /api/resolve {line, run:true}.\\n\\nRESULT (run by the integrator 2026-09-20 08:49Z, x-terminal-key, ops plane):\\nNOW → ok= None bound key= True receipt= None \\nWORK_FEED 5 → ok= None bound key= True receipt= None \\nKV_GET guardian_master → ok= None bound key= True receipt= None \\nD1_QUERY SELECT key, type FROM directory WHERE category = 'cf_main' → ok= None bound key= False receipt= None error={'code': 'ERR', 'message': 'ERR:D1_QUERY:D1_ERROR: no such column: cf_main at offset 49: SQLITE_ERROR Columns in directory: key, type, target, auth, content, updated_at, category, allowed_categories, seq, enabled, planner_visible, planner_rank, input_schema, examples, sensitive, runner, includes, created_at, price_usd, meter_unit, object_kind, descriptor_json, descriptor_rev, descriptor_hash, invocation, last_status, last_response, test_state, tested_at, invocation_curl, execution, connection_id, aliases, effects, visibili'}\\nWEB_FETCH GET | https://miscsubjects.com/api/proven-work/epitalon-ibd → ok= None bound key= False receipt= None error=missing_args\\n\\nVerdict: 3 of 5 ran (NOW, WORK_FEED 5, KV_GET guardian_master: ran=true, plan bound). 2 of 5 failed because the card's positional line is lossy: D1_QUERY lost the quotes around 'cf_main' (SQL error: no such column), and WEB_FETCH's empty pipe positions (GET | url | | ) arrived as missing_args. The resolver's answer has no receipt field at the top; the receipt sits under result/trace. Both are defects of the positional runtime line, which is why the card now leads with named args.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "e9d81c6565c399a04a51b4cd0398813e0c5760c15c596f963314e064304be3ec",
      "hash": "e504fd5f9e57d27464a7db71f3641d46059ce4a2efbb3ad785826061c62a7984"
    },
    {
      "id": 1114,
      "ts": "2026-09-20T01:52:07-07:00",
      "task_id": "WT-0397",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 6,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"done\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"done\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "2485395529752df7811fd07ad5ac062da28f572c40fd0614891a73909c7f8f87",
      "hash": "e9d81c6565c399a04a51b4cd0398813e0c5760c15c596f963314e064304be3ec"
    },
    {
      "id": 1113,
      "ts": "2026-09-20T01:52:06-07:00",
      "task_id": "WT-0397",
      "action": "submit",
      "agent": "claude",
      "model": null,
      "capability": "owner-key",
      "task_revision": 4,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"done\":\"Fixed public/console/invocations.html: card filter hay no longer includes c.expand (the list of spelling names on every card), which was causing any spelling word like webhook to match all 30 cards. Added data-spell attributes to the §3 binding table rows and a highlightSpelling() function; when the query exactly matches a known spelling name (SPELL keys: openai, anthropic, cloudflare, mcp, rest, cli, js, python, webhook, url, tag, regex, sheet, shortcut, upstream) it highlights that table row and leaves the card list untouched, otherwise it filters cards by key/what/call/runs as before. Landed as commit f2ce43836, deployed live via node scripts/land.mjs.\"}}",
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"done\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"done\"}]",
      "evidence": "{\"done\":\"Fixed public/console/invocations.html: card filter hay no longer includes c.expand (the list of spelling names on every card), which was causing any spelling word like webhook to match all 30 cards. Added data-spell attributes to the §3 binding table rows and a highlightSpelling() function; when the query exactly matches a known spelling name (SPELL keys: openai, anthropic, cloudflare, mcp, rest, cli, js, python, webhook, url, tag, regex, sheet, shortcut, upstream) it highlights that table row and leaves the card list untouched, otherwise it filters cards by key/what/call/runs as before. Landed as commit f2ce43836, deployed live via node scripts/land.mjs.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "9d39ecc3f6ab4d781fbab9829848c49881ec6022dd9bd0ceba21df91f7b96cad",
      "hash": "2485395529752df7811fd07ad5ac062da28f572c40fd0614891a73909c7f8f87"
    },
    {
      "id": 1112,
      "ts": "2026-09-20T01:51:42-07:00",
      "task_id": "WT-0397",
      "action": "patch",
      "agent": "console:terminal",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"notes\":\"Baseline, no prefetch: a spelling name typed in the invocations filter highlights that binding, not all 30 tools\\n\\nRun straight to the coding model with no help. Defect: on /console/invocations typing webhook matches every card because every card lists every spelling. Wanted: a spelling-name match highlights that binding line in the table and leaves the cards alone; a key or word match filters the cards. File: public/console/invocations.html. Done when the filter behaves that way on the live page. Record on the task: how many shell and read calls the agent spent before its first edit.\\n\\nRESULT: shell_before_first_edit=1 reads_before_first_edit=1 total_tool_calls=30 landed=f2ce43836\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "dce494ec7855b8f9351b02c0652222fb1bcb8b93040876ad43acdc72fce3d349",
      "hash": "9d39ecc3f6ab4d781fbab9829848c49881ec6022dd9bd0ceba21df91f7b96cad"
    },
    {
      "id": 1111,
      "ts": "2026-09-20T01:32:15-07:00",
      "task_id": "WT-0394",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"title\":\"With a classifier pass first: a card never lists an argument the tool does not take\",\"notes\":\"Same class of change as the baseline task, done the other way: before the coding model starts, a cheap model is given the task text and the file tree and asked for {intent, likely_targets, likely key}; those files are handed to the coding model in its first message. Defect, live on /console/invocations: LEADS_ENRICH_BATCH shows args how_many, arg2 — arg2 is a synthesized placeholder from a row whose schema names one argument. Wanted: the args line lists only the arguments the row declares. Files the classifier should find: functions/_lib/invocation_methods.js (argsOf, toolSchema, argOrder) and functions/api/console/apiref.js (cardRows). Record on the task: the classifier prediction, the prefetched targets, the classifier cost and latency, and the shell and read calls the coding model made before its first edit, beside the baseline task number. Both numbers, no conclusion drawn beyond them.\",\"x\":{\"plain\":\"When this is finished, no invocation card names an argument its tool does not take, and the task shows the classifier prediction and both call counts side by side.\"}}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "91e05ba163dd830f63df85510ccfc1a8beb2beacca051211912826ff0dfc2a13",
      "hash": "dce494ec7855b8f9351b02c0652222fb1bcb8b93040876ad43acdc72fce3d349"
    },
    {
      "id": 1110,
      "ts": "2026-09-20T01:31:54-07:00",
      "task_id": "WT-0396",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"title\":\"Hand a coding model the native tools plus FIND and CALL plus a twelve-tool hot set, and have it finish a small change\",\"notes\":\"The surface from WT-0392 as amended: native read/edit/write/shell/grep plus misc_find and misc_run plus at most twelve typed hot tools chosen for the task. Task for it: add the ?format=text link of the invocations page to the API tab Ways-to-call section (public/console/api.js). Record on the task: the tool list it was offered (count and names), every FIND and CALL it made, and the same change done with the full typed list, side by side. Both numbers, no conclusion beyond them.\",\"x\":{\"plain\":\"When this is finished, a model given the trimmed tool set has made a real change to the build, and the task shows what it was offered and what it used, beside the same change with the full list.\"}}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "4d3ac2ddcfa4adb1c342917a1d4afcb700dff28b51877b3adf2f0acc8422bf40",
      "hash": "91e05ba163dd830f63df85510ccfc1a8beb2beacca051211912826ff0dfc2a13"
    },
    {
      "id": 1109,
      "ts": "2026-09-20T01:31:53-07:00",
      "task_id": "WT-0392",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"title\":\"The model-facing tool surface: native primitives, FIND and CALL, and a hot set of at most twelve typed tools chosen per task\",\"notes\":\"Owner, 2026-09-20: not the two-tool extreme; the superior shape. A coding model keeps the native tools it was trained on — read, edit, write, shell, grep, glob, fetch — because those shapes are what its training data used and funnelling them through a generic CALL loses accuracy. Beside them: misc_find and misc_run reach every directory row (1,459 today). Beside those: a hot set of at most twelve typed tools chosen per task by the classifier (GET /api/tools/openai.json?hot=N already exists; the classifier supplies the list instead of planner_rank alone). Total under twenty-five tools per call, never one per capability; the measured cliff is ~50 tools (owner spec 2026-09-11 §2). Files, models and agents stay directory rows with aliases for discovery; MODEL_RUN and AGENT_RUN become typed tools only when they are in the hot set for that task. Resolve, auth, classify, prefetch, verify, ledger and receipt happen underneath and are never tools. Human grammar unchanged: misc [route:] <noun> <verb> …, escape misc run KEY k=v. Return {ok, result, receipt}. Done when the tool list a model receives is native primitives + misc_find + misc_run + the classifier hot set, and a receipt shows which hot tools were offered and which were used.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "7126b2b0c80002e2158f84ce9d3e0f514dcec0a951116415efdb516d7c7f3af4",
      "hash": "4d3ac2ddcfa4adb1c342917a1d4afcb700dff28b51877b3adf2f0acc8422bf40"
    },
    {
      "id": 1108,
      "ts": "2026-09-20T01:29:33-07:00",
      "task_id": "WT-0397",
      "action": "assign",
      "agent": "claude",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": null,
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "9bf6ef2b2cc309ffdbf9aed0d110a860c8cf0b55279f777cd0541d8aa41207bc",
      "hash": "7126b2b0c80002e2158f84ce9d3e0f514dcec0a951116415efdb516d7c7f3af4"
    },
    {
      "id": 1107,
      "ts": "2026-09-20T01:29:32-07:00",
      "task_id": "WT-0397",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Baseline, no prefetch: a spelling name typed in the invocations filter highlights that binding, not all 30 tools\",\"list_id\":\"tl_ef9ca4c74c7e\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "73f9f55afef24237ec208066b6b5f42d24d39d92016d22904a81e22564079d2b",
      "hash": "9bf6ef2b2cc309ffdbf9aed0d110a860c8cf0b55279f777cd0541d8aa41207bc"
    },
    {
      "id": 1106,
      "ts": "2026-09-20T01:29:23-07:00",
      "task_id": "WT-0394",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"notes\":\"Same class of change as the baseline task, done the other way: before the coding model starts, a cheap model is given the task text and the file tree and asked for {intent, likely_targets, likely key}; those files are handed to the coding model in its first message. Defect: the what line on /console/invocations cut mid-word. Wanted: cut at the last word boundary. File the classifier should find: functions/api/console/apiref.js. Record on the task: the classifier prediction, the prefetched targets, the classifier cost and latency, and the shell and read calls the coding model made before its first edit, beside the baseline task number. Both numbers, no conclusion drawn beyond them.\",\"x\":{\"plain\":\"When this is finished, the description on every invocation card ends at a whole word, and the task shows the classifier prediction and both call counts side by side.\"}}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "15143f86e351f8cdfc1988d6d6026a012a2e8a4e8d2c96584a9c8a36be0ebd8d",
      "hash": "73f9f55afef24237ec208066b6b5f42d24d39d92016d22904a81e22564079d2b"
    },
    {
      "id": 1105,
      "ts": "2026-09-20T01:29:20-07:00",
      "task_id": "WT-0393",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"notes\":\"Owner spec 2026-09-20, amended by review. user request → tiny classifier → {intent, likely_targets:[paths], likely key} → those objects are prefetched → the frontier model starts with the request, the likely target, the file text and the CALL interface. classifier = prediction, resolver = authoritative lookup, executor = action, ledger = evidence; the classifier is never authority. RECORD ON THE RECEIPT, EXACTLY: the classifier prediction; the prefetched targets; the classifier cost; the classifier latency; the frontier-model tool calls actually made. Do not write a saving as fact unless the same request was also run without prefetch as a control; then record both counts side by side. Done when a Worker or Coder run shows those five fields on its receipt.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "9e31abd3cf47cc1cdea5e2ca9db331f429ce550cd5c121d2c0a23864e80ea55b",
      "hash": "15143f86e351f8cdfc1988d6d6026a012a2e8a4e8d2c96584a9c8a36be0ebd8d"
    },
    {
      "id": 1104,
      "ts": "2026-09-20T01:29:20-07:00",
      "task_id": "WT-0392",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"title\":\"The model-facing tool surface: FIND and CALL, with files, models and agents as namespaces behind one CALL\",\"notes\":\"Owner spec 2026-09-20, amended by review: the deeper law is one generic CALL/REST primitive — method + address + body — with files, models, agents and outside APIs as namespaces behind it, not as separate model-visible tools. FIND {query, type?, scope?} resolves an unknown target from intent; CALL {target, action?, input?, route?, confirm?} invokes anything addressable: CALL file:/src/app.js action=read · CALL file:/src/app.js action=patch input=… · CALL shell:local action=exec input=\\\"npm test\\\" · CALL model:gpt-5.6 input=… · CALL agent:reviewer input=… · CALL https://api.stripe.com/v1/customers/cus_123 action=GET. FILE_READ, FILE_WRITE, MODEL_RUN, AGENT_RUN and the rest stay as directory rows and aliases for discovery only. Resolve, auth, classify, prefetch, verify, ledger and receipt happen underneath and are never agent tools. Human grammar: misc [route:] <noun> <verb> …, escape misc run KEY k=v. Return {ok, result, receipt}; lists add next; receipt → full trace. Done when the typed tool list a model receives is FIND and CALL by default (3–5 hot projections only where measured), the file operations answer through CALL, and the rows exist with aliases.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "7f8a1cc60bb55a23d2654b848dbb4b423cf0a736afbcb29e8b1b9d86803d4054",
      "hash": "9e31abd3cf47cc1cdea5e2ca9db331f429ce550cd5c121d2c0a23864e80ea55b"
    },
    {
      "id": 1103,
      "ts": "2026-09-20T01:28:14-07:00",
      "task_id": "WT-0396",
      "action": "assign",
      "agent": "claude",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": null,
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "92f490c056b99e1e917a67f4235ee81bc65165291c857817f9d46824302ac734",
      "hash": "7f8a1cc60bb55a23d2654b848dbb4b423cf0a736afbcb29e8b1b9d86803d4054"
    },
    {
      "id": 1102,
      "ts": "2026-09-20T01:28:13-07:00",
      "task_id": "WT-0395",
      "action": "assign",
      "agent": "claude",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": null,
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "a92d0a6ccd122ad3bbc35dfd78356ae9fa8865df0c85d1a6bdc50435b277b1ee",
      "hash": "92f490c056b99e1e917a67f4235ee81bc65165291c857817f9d46824302ac734"
    },
    {
      "id": 1101,
      "ts": "2026-09-20T01:28:12-07:00",
      "task_id": "WT-0394",
      "action": "assign",
      "agent": "claude",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": null,
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "d3826a0994e6c3b5eba1e1f39f6e58e896d80b572243d282d11a95223f0bd67e",
      "hash": "a92d0a6ccd122ad3bbc35dfd78356ae9fa8865df0c85d1a6bdc50435b277b1ee"
    },
    {
      "id": 1100,
      "ts": "2026-09-20T01:27:53-07:00",
      "task_id": "WT-0396",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Hand a coding model only FIND and CALL and have it finish a small change\",\"list_id\":\"tl_ef9ca4c74c7e\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "e0c287f9aa554de358333f5cdc66d8451effee289fb7bc9f9b6b735b3ead6b71",
      "hash": "d3826a0994e6c3b5eba1e1f39f6e58e896d80b572243d282d11a95223f0bd67e"
    },
    {
      "id": 1099,
      "ts": "2026-09-20T01:27:52-07:00",
      "task_id": "WT-0395",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Run five read-only call lines from the cards through the resolver and keep the receipts\",\"list_id\":\"tl_ef9ca4c74c7e\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "230f6dab11433d44246fa75e7887326c9da93069af3986409c6e2acf5aff9257",
      "hash": "e0c287f9aa554de358333f5cdc66d8451effee289fb7bc9f9b6b735b3ead6b71"
    },
    {
      "id": 1098,
      "ts": "2026-09-20T01:27:51-07:00",
      "task_id": "WT-0394",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"With a classifier pass first: the card's what line ends at a word, never mid-word\",\"list_id\":\"tl_ef9ca4c74c7e\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8e53ea72cb4607cb1c607166dd1206b2ca9564ca7ea6b8ef33a74937d0d2d6cc",
      "hash": "230f6dab11433d44246fa75e7887326c9da93069af3986409c6e2acf5aff9257"
    },
    {
      "id": 1097,
      "ts": "2026-09-20T01:17:37-07:00",
      "task_id": "WT-0393",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"A tiny classifier runs ahead of the frontier model and prefetches the likely files and the likely tool\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "b670ff244cfcfb2994b84544388cde216aae5162c5b8bd1a6b323f24f43230de",
      "hash": "8e53ea72cb4607cb1c607166dd1206b2ca9564ca7ea6b8ef33a74937d0d2d6cc"
    },
    {
      "id": 1096,
      "ts": "2026-09-20T01:15:23-07:00",
      "task_id": "WT-0392",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"The model-facing tool surface: FIND + CALL, and one REST tool for files instead of five\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "288512c5d9ed0b498aec3f2c0281a4f89982a742d50ecd4feaffd180f1f68667",
      "hash": "b670ff244cfcfb2994b84544388cde216aae5162c5b8bd1a6b323f24f43230de"
    },
    {
      "id": 1095,
      "ts": "2026-09-20T01:11:27-07:00",
      "task_id": "WT-0391",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"The return law: every call answers {ok, result, receipt} and nothing else by default\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "eee88ca5a159a1e8f8eb2d475d04dc461993c6dd0f27d6db5b30e2786de19b43",
      "hash": "288512c5d9ed0b498aec3f2c0281a4f89982a742d50ecd4feaffd180f1f68667"
    },
    {
      "id": 1094,
      "ts": "2026-09-19T23:39:57-07:00",
      "task_id": "WT-0390",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Audit the Cloudflare architecture against the invocation model and record the verdicts\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "c393a8558ff85331a091e1a563266a2dbe7c30ce99ab02486fd9a65a8546757d",
      "hash": "eee88ca5a159a1e8f8eb2d475d04dc461993c6dd0f27d6db5b30e2786de19b43"
    },
    {
      "id": 1093,
      "ts": "2026-09-19T20:57:26-07:00",
      "task_id": "WT-0389",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Wire WhatsApp and Telegram sends beside iMessage and email\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "79df38e85ef40c0976b40e28171a7ea0c64404b3bee360f40a566ba67a2c92dc",
      "hash": "c393a8558ff85331a091e1a563266a2dbe7c30ce99ab02486fd9a65a8546757d"
    },
    {
      "id": 1092,
      "ts": "2026-09-19T20:57:12-07:00",
      "task_id": "WT-0388",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Make a customer site from a tenant clone and hand it over, end to end, as a test\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "641dfc75ee56821df527bb93873f85899a084c29b8a4b65d0c853e9244af17a0",
      "hash": "79df38e85ef40c0976b40e28171a7ea0c64404b3bee360f40a566ba67a2c92dc"
    },
    {
      "id": 1091,
      "ts": "2026-09-19T20:57:11-07:00",
      "task_id": "WT-0387",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Pick the payment account for services: the client Stripe keys are not to be used\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "81605fae353ab5bad30cee310141d6e62a24bb94215226731538ac8910fcc35b",
      "hash": "641dfc75ee56821df527bb93873f85899a084c29b8a4b65d0c853e9244af17a0"
    },
    {
      "id": 1090,
      "ts": "2026-09-19T20:56:53-07:00",
      "task_id": "WT-0386",
      "action": "create",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"title\":\"Give the outreach models web search and a per-draft switch between models\",\"list_id\":\"tl_sell_services\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "afb858cfa7fc36159518b00692e5b0d777bc51ef5f6726b3349bd1d314ece06c",
      "hash": "81605fae353ab5bad30cee310141d6e62a24bb94215226731538ac8910fcc35b"
    },
    {
      "id": 1089,
      "ts": "2026-09-19T20:56:50-07:00",
      "task_id": "WT-0380",
      "action": "patch",
      "agent": "console:access",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"notes\":\"Marin County first (owner, 2026-09-19), then wider. Every kind of local business that could use a new site, iMessage automation, AI for CRM or POS, email, or media buying. Use the Find screen (map source) one business type at a time. Each business becomes a lead row with name, site, phone, address and the source. Done when 200 rows exist with a website or a phone on each.\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "0e7446fa618a1d0204fb03b0c3271f039a3f5a86dbd215b8b903661c5ef53559",
      "hash": "afb858cfa7fc36159518b00692e5b0d777bc51ef5f6726b3349bd1d314ece06c"
    },
    {
      "id": 1088,
      "ts": "2026-09-19T20:35:44-07:00",
      "task_id": "WT-0380",
      "action": "assign",
      "agent": "claude",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": null,
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8454a1c9e91a039a00a1c7fdf69b29ea696c56c183dc04ec44a7ade65db5747a",
      "hash": "0e7446fa618a1d0204fb03b0c3271f039a3f5a86dbd215b8b903661c5ef53559"
    },
    {
      "id": 1087,
      "ts": "2026-09-19T20:29:24-07:00",
      "task_id": "WT-0380",
      "action": "assign",
      "agent": "claude",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": null,
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "4d7739a883ea15ed711671bcea0b5be5e839a8c411119a1b20238c9acb07a708",
      "hash": "8454a1c9e91a039a00a1c7fdf69b29ea696c56c183dc04ec44a7ade65db5747a"
    },
    {
      "id": 1086,
      "ts": "2026-09-19T19:11:25-07:00",
      "task_id": "WT-0373",
      "action": "create",
      "agent": "muse-spark-1.3-contributor",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"objective\":\"Pin the tool-result shape with a test: the model gets the answer, not the envelope\",\"detail\":\"GOAL\\nLock in the behaviour that stopped models drowning in wrapper text, so nobody undoes it by accident.\\n\\nBACKGROUND\\nfunctions/api/console/talk.js has a function resultText(out, shape). The build's capability door\\nanswers with seventeen fields wrapped around the answer (_self, plan, forms, next, trace, status,\\nresult…). resultText must hand the model the ANSWER only, unless shape === 'full'.\\n\\nWHAT TO ADD\\nOne new test file: functions/_lib/tool_result_shape.test.mjs\\n\\nUse node:test and node:assert/strict. Do not import talk.js (it is a Cloudflare route and pulls in\\nbindings). Instead read the file as text, cut out the resultText function and evaluate it, the same\\nway you would test a pure function — or copy it verbatim into the test with a comment saying it is\\ncopied and must stay identical.\\n\\nThe test must cover:\\n1. An envelope { _self: {...}, plan: {}, forms: {}, status: 200, ran: true, result: '[{\\\"x\\\":1}]' }\\n   with shape 'answer' returns exactly '[{\\\"x\\\":1}]'.\\n2. The same envelope with shape 'full' returns a string containing '_self'.\\n3. A failed envelope { _self:{}, status: 500, error: 'no such table', result: '' } returns JSON\\n   that contains the error text.\\n4. A plain string is returned unchanged.\\n5. null returns an empty string.\\n\\nHOW TO CHECK IT BEFORE YOU FINISH\\n  node --test --test-reporter=spec functions/_lib/tool_result_shape.test.mjs\\nIt must pass and the reporter must print the test names.\\n\\nDO NOT\\n- Do not change talk.js.\\n- Do not touch any other file.\\n\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"muse-spark-1.3-contributor\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "956ad2f084f8aec153fdbcf6fc67fad30074bde1f4c61e3db6044e4dd958825d",
      "hash": "4d7739a883ea15ed711671bcea0b5be5e839a8c411119a1b20238c9acb07a708"
    },
    {
      "id": 1085,
      "ts": "2026-09-19T19:11:24-07:00",
      "task_id": "WT-0372",
      "action": "create",
      "agent": "muse-spark-1.3-contributor",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"objective\":\"Model ids must not carry their provider twice (xai/xai/grok-4.6), with a test\",\"detail\":\"GOAL\\nA model id must never carry its provider twice. The model list currently shows rows like\\n\\\"xai/xai/grok-4.6\\\" — the id was already prefixed and the prefix was added again.\\n\\nWHAT TO FIX\\nIn functions/api/console/[[path]].js, inside the function that builds the model catalogue, the xAI\\nsource pushes rows with `id: m.id`. Somewhere in that path an id ends up with its provider twice.\\nFind it and stop it, for every source, by normalising the id once before it is pushed:\\n\\n  - if the id begins with \\\"<provider>/<provider>/\\\", collapse it to one\\n  - never change an id that is already correct\\n  - leave Cloudflare ids that begin with \\\"@cf/\\\" exactly as they are\\n\\nWHAT TO ADD\\nOne new test file: functions/_lib/model_id_prefix.test.mjs\\n\\nUse node:test and node:assert/strict (no vitest — it is not installed). Export the normaliser from\\nthe route file if you need to, or copy the exact function into the test and assert it. The test must\\ncover: \\\"xai/xai/grok-4.6\\\" -> \\\"xai/grok-4.6\\\"; \\\"xai/grok-4.6\\\" unchanged; \\\"@cf/meta/llama-3.3\\\" unchanged;\\n\\\"anthropic/claude-sonnet-5\\\" unchanged.\\n\\nHOW TO CHECK IT BEFORE YOU FINISH\\n  node --check \\\"functions/api/console/[[path]].js\\\"\\n  node --test --test-reporter=spec functions/_lib/model_id_prefix.test.mjs\\nBoth must pass, and the test must actually run (the reporter prints the test names).\\n\\nDO NOT\\n- Do not change what the catalogue fetches or which sources it reads.\\n- Do not touch any other file.\\n\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"muse-spark-1.3-contributor\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "051577432da0d9359692a3c5584a422d4a1a10fa43b141bfe811f87c1f259c1d",
      "hash": "956ad2f084f8aec153fdbcf6fc67fad30074bde1f4c61e3db6044e4dd958825d"
    },
    {
      "id": 1084,
      "ts": "2026-09-19T19:11:22-07:00",
      "task_id": "WT-0371",
      "action": "create",
      "agent": "muse-spark-1.3-contributor",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"objective\":\"Find: turn a place name into coordinates (GET /api/find/where)\",\"detail\":\"GOAL\\nAdd a way to turn a place name into coordinates, so the Find screen can search around a named city\\nwithout needing the phone's location.\\n\\nWHAT TO BUILD\\nOne new file: functions/api/find/where.js\\n\\nIt answers GET /api/find/where?q=<place name> and returns JSON:\\n  { \\\"ok\\\": true, \\\"q\\\": \\\"<what was asked>\\\", \\\"places\\\": [ { \\\"name\\\": \\\"...\\\", \\\"lat\\\": 33.49, \\\"lon\\\": -111.92, \\\"kind\\\": \\\"city\\\" } ] }\\n\\nRules:\\n1. Look the name up with OpenStreetMap's free geocoder:\\n   https://nominatim.openstreetmap.org/search?format=jsonv2&limit=5&q=<the name>\\n   That service requires a User-Agent header identifying the caller. Send:\\n   'miscsubjects-find/1 (https://miscsubjects.com)'\\n2. Return at most 5 places. lat and lon must be numbers, not strings.\\n3. \\\"kind\\\" is Nominatim's own \\\"type\\\" field (\\\"city\\\", \\\"town\\\", \\\"suburb\\\"…), passed through.\\n4. If the geocoder answers nothing, return { \\\"ok\\\": true, \\\"q\\\": ..., \\\"places\\\": [] } — not an error.\\n5. If the geocoder fails or times out (use a 15 second timeout), return\\n   { \\\"ok\\\": false, \\\"error\\\": \\\"geocoder_unavailable\\\", \\\"detail\\\": \\\"<what happened>\\\" } with HTTP 200.\\n6. Authorisation: copy it exactly from functions/api/find/[[path]].js — the same isBuildAuthed\\n   check first, then consoleAuth + consoleScope. Do not invent a new way in.\\n\\nHOW TO CHECK IT BEFORE YOU FINISH\\n  node --check functions/api/find/where.js\\nand read functions/api/find/[[path]].js first so the import paths and the auth match.\\n\\nDO NOT\\n- Do not change any other file.\\n- Do not add a dependency.\\n- Do not call any service other than nominatim.openstreetmap.org.\\n\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"muse-spark-1.3-contributor\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "3e29c60e84b13891a3583c2796d2d349b1763ba85a0349df21b385de162f0fba",
      "hash": "051577432da0d9359692a3c5584a422d4a1a10fa43b141bfe811f87c1f259c1d"
    },
    {
      "id": 1083,
      "ts": "2026-09-19T16:18:36-07:00",
      "task_id": "WT-0370",
      "action": "create",
      "agent": "muse-spark-1.3-contributor",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"objective\":\"Agent run: list the tools that exist in scripts/agent-tools/README.md\",\"detail\":\"Edit one existing file in this copy of the build: scripts/agent-tools/README.md\\n\\nAdd a short section at the end titled \\\"Tools in this folder\\\" listing each .mjs file that exists in\\nscripts/agent-tools/, one per line, as: `<name>` — <one sentence saying what it does>.\\nRead the files to say what each does. Do not invent files that are not there.\\nChange nothing else in the file and no other file.\\n\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"muse-spark-1.3-contributor\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "467166a2a011b2a904f594d992bf165370703bf4f13dbf3fdce685bfb8bc3205",
      "hash": "3e29c60e84b13891a3583c2796d2d349b1763ba85a0349df21b385de162f0fba"
    },
    {
      "id": 1082,
      "ts": "2026-09-19T16:18:35-07:00",
      "task_id": "WT-0369",
      "action": "create",
      "agent": "muse-spark-1.3-contributor",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"objective\":\"Agent run: create scripts/agent-tools/echo.mjs, a tool that echoes its JSON input back\",\"detail\":\"Create one new file in this copy of the build: scripts/agent-tools/echo.mjs\\n\\nIt must:\\n1. Read all of standard input (a JSON object).\\n2. Print that same object back as one line of JSON, with one field added: {\\\"echoed\\\": true}\\n   For example, input {\\\"a\\\":1} prints {\\\"a\\\":1,\\\"echoed\\\":true}\\n3. If standard input is not valid JSON, print {\\\"error\\\":\\\"input was not JSON\\\"} instead.\\n4. Use only Node's built-ins. No dependencies, no network, no other files.\\n\\nCheck both cases before you finish:\\n  echo '{\\\"a\\\":1}' | node scripts/agent-tools/echo.mjs\\n  echo 'not json' | node scripts/agent-tools/echo.mjs\\nDo not change any other file.\\n\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"muse-spark-1.3-contributor\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "94c5ac9ac92d9222ae68ceeea0171b1bb570aa4e784840db3d06085b85bdd031",
      "hash": "467166a2a011b2a904f594d992bf165370703bf4f13dbf3fdce685bfb8bc3205"
    },
    {
      "id": 1081,
      "ts": "2026-09-19T16:18:33-07:00",
      "task_id": "WT-0368",
      "action": "create",
      "agent": "muse-spark-1.3-contributor",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"kind\":\"work\",\"objective\":\"Agent run: create scripts/agent-tools/now.mjs, a tool that prints the current UTC time as JSON\",\"detail\":\"Create one new file in this copy of the build: scripts/agent-tools/now.mjs\\n\\nIt must:\\n1. Read all of standard input (it will be a JSON object, possibly empty).\\n2. Print one line of JSON to standard output: {\\\"now\\\": \\\"<the current time as an ISO 8601 UTC string>\\\"}\\n3. Use only Node's built-ins. No dependencies, no network, no other files.\\n\\nCheck it works before you finish: echo '{}' | node scripts/agent-tools/now.mjs\\nDo not change any other file.\\n\",\"priority\":3,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"muse-spark-1.3-contributor\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "9ecaf90e59f7fdf20696b050f9cbe463d4c4ad3b03369f5507696005db3012c2",
      "hash": "94c5ac9ac92d9222ae68ceeea0171b1bb570aa4e784840db3d06085b85bdd031"
    },
    {
      "id": 1080,
      "ts": "2026-09-19T12:45:10-07:00",
      "task_id": "WT-0367",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "14e891db97defa5b44fbe6e86024a23ce53a10c662d7845ca68081c2d40bf7ec",
      "hash": "9ecaf90e59f7fdf20696b050f9cbe463d4c4ad3b03369f5507696005db3012c2"
    },
    {
      "id": 1079,
      "ts": "2026-09-19T12:45:10-07:00",
      "task_id": "WT-0367",
      "action": "submit",
      "agent": "claude-opus-5",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"7362ccb20 9fc1f0a75 13766cfcd 612db2f4d 03f0da2cb\",\"verification\":\"2026-09-19: land.mjs recorded, committed and deployed edits made with ordinary edit tools (7362ccb20, deployed:true). Codex made a real fix with its own tools (imessage_gateway.js empty-send guard, tested 16 cases) and ran land.mjs; its workspace ran out of credits mid-commit, leaving .git/index.lock; land.mjs now clears a stale lock and landed it (612db2f4d, deployed:true). Live: POST ops.miscsubjects.com/api/imessage/send {} -> HTTP 400 to_and_text_required. Codex, Goose and Kimi each answered from AGENTS.md that they land with node scripts/land.mjs.\"}}",
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"}]",
      "evidence": "{\"commit\":\"7362ccb20 9fc1f0a75 13766cfcd 612db2f4d 03f0da2cb\",\"verification\":\"2026-09-19: land.mjs recorded, committed and deployed edits made with ordinary edit tools (7362ccb20, deployed:true). Codex made a real fix with its own tools (imessage_gateway.js empty-send guard, tested 16 cases) and ran land.mjs; its workspace ran out of credits mid-commit, leaving .git/index.lock; land.mjs now clears a stale lock and landed it (612db2f4d, deployed:true). Live: POST ops.miscsubjects.com/api/imessage/send {} -> HTTP 400 to_and_text_required. Codex, Goose and Kimi each answered from AGENTS.md that they land with node scripts/land.mjs.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "1ed63d3efc3004899692bc4f23599fd0eea10e477cb550b2796c4f6a1070c69f",
      "hash": "14e891db97defa5b44fbe6e86024a23ce53a10c662d7845ca68081c2d40bf7ec"
    },
    {
      "id": 1078,
      "ts": "2026-09-19T12:34:21-07:00",
      "task_id": "WT-0367",
      "action": "create",
      "agent": "claude-opus-5",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"id\":\"WT-0367\",\"kind\":\"work\",\"objective\":\"Any coding agent can change the build: edit files normally, then node scripts/land.mjs \\\"what you changed\\\" records the edits through the write path, commits and deploys\",\"detail\":\"Standing task for work landed by coding agents other than Claude (Gemini, Goose, Aider, Cursor, Codex…). land.mjs names this task when the commit message names none, because the deploy requires a numbered task in recent commits.\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"}],\"evidence_required\":[\"commit\",\"verification\"],\"agent\":\"claude-opus-5\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "54907d462d5be62b62d2ec6b34624612be87196c02d7149f93a7ad2248776a5e",
      "hash": "1ed63d3efc3004899692bc4f23599fd0eea10e477cb550b2796c4f6a1070c69f"
    },
    {
      "id": 1077,
      "ts": "2026-09-19T11:26:23-07:00",
      "task_id": "WT-0366",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"security_tab_served\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/console/security.js\"},{\"id\":\"row_page_is_api_page\",\"ok\":true,\"detail\":\"contains \\\"ONE PAGE FOR A ROW\\\" in https://miscsubjects.com/console/directory.js (scope=content) → true\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "585382745071ad0193711ab24168d0c5045406843380fff179005db1156ba43b",
      "hash": "54907d462d5be62b62d2ec6b34624612be87196c02d7149f93a7ad2248776a5e"
    },
    {
      "id": 1076,
      "ts": "2026-09-19T11:26:22-07:00",
      "task_id": "WT-0366",
      "action": "submit",
      "agent": "claude-opus-5",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"ce90e1009 9fac5e364 4384d726e b684298d1 33743280b f5f7ca3e3\",\"verification\":\"Live 2026-09-19 with the owner app's service-token sign-in: /console, /admin, /api/console/*, /api/vault* redirect unsigned requests to the Cloudflare email-PIN page (302) and answer 200 signed in; old terminal key refused; Security screen renders access apps, roll dates for all six build keys, bridge locked, signing secret separate, every command wrapped in full at phone width; Directory is a drawer folder with an Agents/Tools/Pages/Files/Flows/API/MCP/Terminals menu; each row opens the API page plus its record; MCP view lists 21 servers, 18 connected (Cloudflare servers sign in with CF_API_TOKEN), 3 open, live compare works; /api/directory/<KEY> carries invocation_curl + how_to_call (1,467 rows backfilled). Task checks now sign in to the build's own pages; regression test functions/_lib/work_acceptance_signin.test.mjs 2/2 pass.\"}}",
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"security_tab_served\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/console/security.js\"},{\"id\":\"row_page_is_api_page\",\"ok\":true,\"detail\":\"contains \\\"ONE PAGE FOR A ROW\\\" in https://miscsubjects.com/console/directory.js (scope=content) → true\"}]",
      "evidence": "{\"commit\":\"ce90e1009 9fac5e364 4384d726e b684298d1 33743280b f5f7ca3e3\",\"verification\":\"Live 2026-09-19 with the owner app's service-token sign-in: /console, /admin, /api/console/*, /api/vault* redirect unsigned requests to the Cloudflare email-PIN page (302) and answer 200 signed in; old terminal key refused; Security screen renders access apps, roll dates for all six build keys, bridge locked, signing secret separate, every command wrapped in full at phone width; Directory is a drawer folder with an Agents/Tools/Pages/Files/Flows/API/MCP/Terminals menu; each row opens the API page plus its record; MCP view lists 21 servers, 18 connected (Cloudflare servers sign in with CF_API_TOKEN), 3 open, live compare works; /api/directory/<KEY> carries invocation_curl + how_to_call (1,467 rows backfilled). Task checks now sign in to the build's own pages; regression test functions/_lib/work_acceptance_signin.test.mjs 2/2 pass.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "869cfbeed3fc1a437eb38b796dac76da33cc97a70199645cdce24393c28c0f34",
      "hash": "585382745071ad0193711ab24168d0c5045406843380fff179005db1156ba43b"
    },
    {
      "id": 1075,
      "ts": "2026-09-19T10:58:07-07:00",
      "task_id": "WT-0366",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Security: close every path to the master key, gate the console behind the owner's Cloudflare sign-in, roll exposed keys; Directory becomes a folder whose rows are the API page\",\"detail\":\"Owner, 2026-09-19. The terminal key (and 65 other vault values over time) were readable through /api/vault/catalog, which served Claude Code transcripts publicly. Close the leak paths (vault catalog, cc_log, sheet scripts, arrival headers, referrers, sheet views, key-in-URL), put /console, /admin and the console APIs behind Cloudflare Access (email one-time PIN + owner service token), roll the build's own keys, add the Security screen and roll/people commands. Directory: folder + dropdown (Agents/Tools/Pages/Files/Flows/API/MCP/Terminals), MCP view reflecting Cloudflare's MCP servers, row page = API page, row docs from the compiler.\",\"kind\":\"work\",\"priority\":1,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"http_ok\",\"id\":\"security_tab_served\",\"url\":\"https://miscsubjects.com/console/security.js\"},{\"type\":\"contains\",\"id\":\"row_page_is_api_page\",\"url\":\"https://miscsubjects.com/console/directory.js\",\"needle\":\"ONE PAGE FOR A ROW\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "ab411ca3bbd58f9b2cd004e870892698166611b2461abbd8caf2be105d10cf42",
      "hash": "869cfbeed3fc1a437eb38b796dac76da33cc97a70199645cdce24393c28c0f34"
    },
    {
      "id": 1074,
      "ts": "2026-09-19T10:11:43-07:00",
      "task_id": "WT-0363",
      "action": "supersede",
      "agent": "claude-opus-5",
      "model": null,
      "capability": null,
      "task_revision": 8,
      "from_state": "open",
      "to_state": "superseded",
      "input": "{\"reason\":\"URL tests resolved against the machine plane, which refuses /console; superseded by WT-0365 with site-plane URLs\",\"replaced_by\":null}",
      "output": "{\"note\":\"row retained; withdrawal recorded as a revision\"}",
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "superseded",
      "parent_action": null,
      "prev_hash": "9f7cfcce7ee92eb9ac953bf59f6311b069708b2d520952b7becc752a330251ae",
      "hash": "ab411ca3bbd58f9b2cd004e870892698166611b2461abbd8caf2be105d10cf42"
    },
    {
      "id": 1073,
      "ts": "2026-09-19T10:11:40-07:00",
      "task_id": "WT-0365",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"api_tab_served\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/console/api.js\"},{\"id\":\"api_tab_contract\",\"ok\":true,\"detail\":\"contains \\\"CONSOLE DESTINATION — API\\\" in https://miscsubjects.com/console/api.js (scope=content) → true\"},{\"id\":\"worker_uses_picker\",\"ok\":true,\"detail\":\"contains \\\"pickModelFor\\\" in https://miscsubjects.com/console/worker.js (scope=content) → true\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "dfca39c0ac0a0cce9e12d46002ea07c23058b3f08b3d06cfa8aed19c8305d153",
      "hash": "9f7cfcce7ee92eb9ac953bf59f6311b069708b2d520952b7becc752a330251ae"
    },
    {
      "id": 1072,
      "ts": "2026-09-19T10:11:40-07:00",
      "task_id": "WT-0365",
      "action": "submit",
      "agent": "claude-opus-5",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"commit\":\"f9ac9ac58 + 7882c304b (deployed in 841ca2485, production smoke passed); muse-worker 17d533f\",\"verification\":\"Owner-app identity (Access service token, site plane): GET /api/console/apiref index 1442 rows / 13 APIs; POST run recipe imessage_read native 200 in 1.5 s with real chats; LOCAL_EXEC over MCP ran on the Mac (macOS); CLOUD_EXEC recipe 200; imessage_send without confirm → 409 confirm_required. Every runnable spelling (curl, named, /s/, one URL, MCP, MCP tool, line, tag) executed from a terminal for NOW, D1_QUERY, IMESSAGE_CHATS, LOCAL_EXEC, CF_MAIN_EXECUTE. Sends verified with shape:true only. Invocations sheet sh_r4w692t7 (1,442 rows) renders in the Data tab route. WT-0364 assigned to a gateway model in the Worker and finished. Repairs verified live: /s/NOW with no key refused; /api/imessage/chats and /api/apple/shortcuts 200; BLOOIO_LIST_CHATS 200; sheet-bridge rejects a fake admin cookie.\"}}",
      "output": null,
      "changed": "[\"public/console/api.js\",\"functions/api/console/apiref.js\",\"functions/_lib/invocation_methods.js\",\"public/console.html\",\"public/console/worker.js\",\"functions/api/console/worker.js\",\"functions/_lib/console_scope.js\",\"functions/api/dispatch.js\",\"functions/_lib/mac_bridge.js\",\"functions/_lib/imessage_gateway.js\",\"functions/s/[slug].js\",\"functions/api/sheet-bridge.js\",\"functions/_lib/sheet_views.js\",\"functions/api/leads/data.js\",\"public/console/directory.js\",\"public/console/data.js\",\"cli/\",\"misc-cli/src/cap.js\",\"~/muse-worker/src\"]",
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"api_tab_served\",\"ok\":true,\"detail\":\"HTTP 200 https://miscsubjects.com/console/api.js\"},{\"id\":\"api_tab_contract\",\"ok\":true,\"detail\":\"contains \\\"CONSOLE DESTINATION — API\\\" in https://miscsubjects.com/console/api.js (scope=content) → true\"},{\"id\":\"worker_uses_picker\",\"ok\":true,\"detail\":\"contains \\\"pickModelFor\\\" in https://miscsubjects.com/console/worker.js (scope=content) → true\"}]",
      "evidence": "{\"commit\":\"f9ac9ac58 + 7882c304b (deployed in 841ca2485, production smoke passed); muse-worker 17d533f\",\"verification\":\"Owner-app identity (Access service token, site plane): GET /api/console/apiref index 1442 rows / 13 APIs; POST run recipe imessage_read native 200 in 1.5 s with real chats; LOCAL_EXEC over MCP ran on the Mac (macOS); CLOUD_EXEC recipe 200; imessage_send without confirm → 409 confirm_required. Every runnable spelling (curl, named, /s/, one URL, MCP, MCP tool, line, tag) executed from a terminal for NOW, D1_QUERY, IMESSAGE_CHATS, LOCAL_EXEC, CF_MAIN_EXECUTE. Sends verified with shape:true only. Invocations sheet sh_r4w692t7 (1,442 rows) renders in the Data tab route. WT-0364 assigned to a gateway model in the Worker and finished. Repairs verified live: /s/NOW with no key refused; /api/imessage/chats and /api/apple/shortcuts 200; BLOOIO_LIST_CHATS 200; sheet-bridge rejects a fake admin cookie.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "1946c2098d28d8373cf0dd47b21e2ccc1a102423a5fe345f2824dfb3a3c35354",
      "hash": "dfca39c0ac0a0cce9e12d46002ea07c23058b3f08b3d06cfa8aed19c8305d153"
    },
    {
      "id": 1071,
      "ts": "2026-09-19T10:11:39-07:00",
      "task_id": "WT-0365",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"API tab: every way to call everything, runnable as pasted; one model picker for chat, Worker and Coder; assign tasks to models from Tasks\",\"detail\":\"Supersedes WT-0363, whose three URL tests resolved against ops.miscsubjects.com, which by design refuses /console (522). Same work, same evidence; tests now name the site plane.\",\"kind\":\"work\",\"priority\":2,\"supersedes\":\"WT-0363\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"http_ok\",\"id\":\"api_tab_served\",\"url\":\"https://miscsubjects.com/console/api.js\"},{\"type\":\"contains\",\"id\":\"api_tab_contract\",\"url\":\"https://miscsubjects.com/console/api.js\",\"needle\":\"CONSOLE DESTINATION — API\"},{\"type\":\"contains\",\"id\":\"worker_uses_picker\",\"url\":\"https://miscsubjects.com/console/worker.js\",\"needle\":\"pickModelFor\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "941f675cf94c6fbd8e112bac0871bdf620f5857e0d4cdd25b9f18f218d5d57e0",
      "hash": "1946c2098d28d8373cf0dd47b21e2ccc1a102423a5fe345f2824dfb3a3c35354"
    },
    {
      "id": 1070,
      "ts": "2026-09-19T10:11:16-07:00",
      "task_id": "WT-0363",
      "action": "refuse",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 7,
      "from_state": "refused",
      "to_state": "open",
      "input": null,
      "output": "{\"why\":[\"HTTP 522 https://ops.miscsubjects.com/console/api.js\",\"contains \\\"CONSOLE DESTINATION — API\\\" in https://ops.miscsubjects.com/console/api.js (scope=content) → false\",\"contains \\\"pickModelFor\\\" in https://ops.miscsubjects.com/console/worker.js (scope=content) → false\"],\"missing_evidence\":[]}",
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"api_tab_served\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/console/api.js\"},{\"id\":\"api_tab_contract\",\"ok\":false,\"detail\":\"contains \\\"CONSOLE DESTINATION — API\\\" in https://ops.miscsubjects.com/console/api.js (scope=content) → false\"},{\"id\":\"worker_uses_picker\",\"ok\":false,\"detail\":\"contains \\\"pickModelFor\\\" in https://ops.miscsubjects.com/console/worker.js (scope=content) → false\"}]",
      "evidence": null,
      "result": "refused",
      "parent_action": null,
      "prev_hash": "0b1eebbcdba42e4d36eb12cfaee25f51e429739e73a35190d410c2520a914582",
      "hash": "941f675cf94c6fbd8e112bac0871bdf620f5857e0d4cdd25b9f18f218d5d57e0"
    },
    {
      "id": 1069,
      "ts": "2026-09-19T10:11:16-07:00",
      "task_id": "WT-0363",
      "action": "submit",
      "agent": "claude-opus-5",
      "model": null,
      "capability": "owner-key",
      "task_revision": 5,
      "from_state": "open",
      "to_state": "refused",
      "input": "{\"evidence\":{\"commit\":\"f9ac9ac58 + 7882c304b (deployed in 841ca2485, production smoke passed); muse-worker 17d533f\",\"verification\":\"Owner-app identity (Access service token, site plane): GET /api/console/apiref index 1442 rows / 13 APIs; POST run recipe imessage_read native 200 in 1.5 s with real chats; LOCAL_EXEC over MCP ran on the Mac (macOS); CLOUD_EXEC recipe 200; imessage_send without confirm → 409 confirm_required. Every runnable spelling (curl, named, /s/, one URL, MCP, MCP tool, line, tag) executed from a terminal for NOW, D1_QUERY, IMESSAGE_CHATS, LOCAL_EXEC, CF_MAIN_EXECUTE. Sends verified with shape:true only. Invocations sheet sh_r4w692t7 (1,442 rows) renders in the Data tab route. WT-0364 assigned to a gateway model in the Worker and finished. Repairs verified live: /s/NOW with no key refused; /api/imessage/chats and /api/apple/shortcuts 200; BLOOIO_LIST_CHATS 200; sheet-bridge rejects a fake admin cookie.\"}}",
      "output": null,
      "changed": "[\"public/console/api.js\",\"functions/api/console/apiref.js\",\"functions/_lib/invocation_methods.js\",\"public/console.html\",\"public/console/worker.js\",\"functions/api/console/worker.js\",\"functions/_lib/console_scope.js\",\"functions/api/dispatch.js\",\"functions/_lib/mac_bridge.js\",\"functions/_lib/imessage_gateway.js\",\"functions/s/[slug].js\",\"functions/api/sheet-bridge.js\",\"functions/_lib/sheet_views.js\",\"functions/api/leads/data.js\",\"public/console/directory.js\",\"public/console/data.js\",\"cli/\",\"misc-cli/src/cap.js\",\"~/muse-worker/src\"]",
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"api_tab_served\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/console/api.js\"},{\"id\":\"api_tab_contract\",\"ok\":false,\"detail\":\"contains \\\"CONSOLE DESTINATION — API\\\" in https://ops.miscsubjects.com/console/api.js (scope=content) → false\"},{\"id\":\"worker_uses_picker\",\"ok\":false,\"detail\":\"contains \\\"pickModelFor\\\" in https://ops.miscsubjects.com/console/worker.js (scope=content) → false\"}]",
      "evidence": "{\"commit\":\"f9ac9ac58 + 7882c304b (deployed in 841ca2485, production smoke passed); muse-worker 17d533f\",\"verification\":\"Owner-app identity (Access service token, site plane): GET /api/console/apiref index 1442 rows / 13 APIs; POST run recipe imessage_read native 200 in 1.5 s with real chats; LOCAL_EXEC over MCP ran on the Mac (macOS); CLOUD_EXEC recipe 200; imessage_send without confirm → 409 confirm_required. Every runnable spelling (curl, named, /s/, one URL, MCP, MCP tool, line, tag) executed from a terminal for NOW, D1_QUERY, IMESSAGE_CHATS, LOCAL_EXEC, CF_MAIN_EXECUTE. Sends verified with shape:true only. Invocations sheet sh_r4w692t7 (1,442 rows) renders in the Data tab route. WT-0364 assigned to a gateway model in the Worker and finished. Repairs verified live: /s/NOW with no key refused; /api/imessage/chats and /api/apple/shortcuts 200; BLOOIO_LIST_CHATS 200; sheet-bridge rejects a fake admin cookie.\"}",
      "result": "refused",
      "parent_action": null,
      "prev_hash": "2f498094665f21df577d242de41a15e3783dc80ee06f9828f6ac997aa0267ae0",
      "hash": "0b1eebbcdba42e4d36eb12cfaee25f51e429739e73a35190d410c2520a914582"
    },
    {
      "id": 1068,
      "ts": "2026-09-19T10:11:05-07:00",
      "task_id": "WT-0363",
      "action": "refuse",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "refused",
      "to_state": "open",
      "input": null,
      "output": "{\"why\":[\"HTTP 522 https://ops.miscsubjects.com/console/api.js\",\"contains \\\"CONSOLE DESTINATION — API\\\" in https://ops.miscsubjects.com/console/api.js (scope=content) → false\",\"contains \\\"pickModelFor\\\" in https://ops.miscsubjects.com/console/worker.js (scope=content) → false\"],\"missing_evidence\":[]}",
      "changed": null,
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"api_tab_served\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/console/api.js\"},{\"id\":\"api_tab_contract\",\"ok\":false,\"detail\":\"contains \\\"CONSOLE DESTINATION — API\\\" in https://ops.miscsubjects.com/console/api.js (scope=content) → false\"},{\"id\":\"worker_uses_picker\",\"ok\":false,\"detail\":\"contains \\\"pickModelFor\\\" in https://ops.miscsubjects.com/console/worker.js (scope=content) → false\"}]",
      "evidence": null,
      "result": "refused",
      "parent_action": null,
      "prev_hash": "722490b28af0dc1645a391edf68719b7cdc5563587627201c65a450742db5e50",
      "hash": "2f498094665f21df577d242de41a15e3783dc80ee06f9828f6ac997aa0267ae0"
    },
    {
      "id": 1067,
      "ts": "2026-09-19T10:11:05-07:00",
      "task_id": "WT-0363",
      "action": "submit",
      "agent": "claude-opus-5",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "refused",
      "input": "{\"evidence\":{\"commit\":\"f9ac9ac58 + 7882c304b (deployed in 841ca2485, production smoke passed); muse-worker 17d533f\",\"verification\":\"Owner-app identity (Access service token, site plane): GET /api/console/apiref index 1442 rows / 13 APIs; POST run recipe imessage_read native 200 in 1.5 s with real chats; LOCAL_EXEC over MCP ran on the Mac (macOS); CLOUD_EXEC recipe 200; imessage_send without confirm → 409 confirm_required. Every runnable spelling (curl, named, /s/, one URL, MCP, MCP tool, line, tag) executed from a terminal for NOW, D1_QUERY, IMESSAGE_CHATS, LOCAL_EXEC, CF_MAIN_EXECUTE. Sends verified with shape:true only. Invocations sheet sh_r4w692t7 (1,442 rows) renders in the Data tab route. WT-0364 assigned to a gateway model in the Worker and finished. Repairs verified live: /s/NOW with no key refused; /api/imessage/chats and /api/apple/shortcuts 200; BLOOIO_LIST_CHATS 200; sheet-bridge rejects a fake admin cookie.\"}}",
      "output": null,
      "changed": "[\"public/console/api.js\",\"functions/api/console/apiref.js\",\"functions/_lib/invocation_methods.js\",\"public/console.html\",\"public/console/worker.js\",\"functions/api/console/worker.js\",\"functions/_lib/console_scope.js\",\"functions/api/dispatch.js\",\"functions/_lib/mac_bridge.js\",\"functions/_lib/imessage_gateway.js\",\"functions/s/[slug].js\",\"functions/api/sheet-bridge.js\",\"functions/_lib/sheet_views.js\",\"functions/api/leads/data.js\",\"public/console/directory.js\",\"public/console/data.js\",\"cli/\",\"misc-cli/src/cap.js\",\"~/muse-worker/src\"]",
      "tests": "[{\"id\":\"commit\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"commit\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"api_tab_served\",\"ok\":false,\"detail\":\"HTTP 522 https://ops.miscsubjects.com/console/api.js\"},{\"id\":\"api_tab_contract\",\"ok\":false,\"detail\":\"contains \\\"CONSOLE DESTINATION — API\\\" in https://ops.miscsubjects.com/console/api.js (scope=content) → false\"},{\"id\":\"worker_uses_picker\",\"ok\":false,\"detail\":\"contains \\\"pickModelFor\\\" in https://ops.miscsubjects.com/console/worker.js (scope=content) → false\"}]",
      "evidence": "{\"commit\":\"f9ac9ac58 + 7882c304b (deployed in 841ca2485, production smoke passed); muse-worker 17d533f\",\"verification\":\"Owner-app identity (Access service token, site plane): GET /api/console/apiref index 1442 rows / 13 APIs; POST run recipe imessage_read native 200 in 1.5 s with real chats; LOCAL_EXEC over MCP ran on the Mac (macOS); CLOUD_EXEC recipe 200; imessage_send without confirm → 409 confirm_required. Every runnable spelling (curl, named, /s/, one URL, MCP, MCP tool, line, tag) executed from a terminal for NOW, D1_QUERY, IMESSAGE_CHATS, LOCAL_EXEC, CF_MAIN_EXECUTE. Sends verified with shape:true only. Invocations sheet sh_r4w692t7 (1,442 rows) renders in the Data tab route. WT-0364 assigned to a gateway model in the Worker and finished. Repairs verified live: /s/NOW with no key refused; /api/imessage/chats and /api/apple/shortcuts 200; BLOOIO_LIST_CHATS 200; sheet-bridge rejects a fake admin cookie.\"}",
      "result": "refused",
      "parent_action": null,
      "prev_hash": "06d04a6edc26f3ed08b9f8457eba0ec5f1e2999bf92a9a3277d88619279f86e6",
      "hash": "722490b28af0dc1645a391edf68719b7cdc5563587627201c65a450742db5e50"
    },
    {
      "id": 1066,
      "ts": "2026-09-19T10:10:54-07:00",
      "task_id": "WT-0364",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 5,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"reply\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"reply\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "84685d4b67c0a879424a7c57833f420d9325e9c85fafda12cc87b588ed178901",
      "hash": "06d04a6edc26f3ed08b9f8457eba0ec5f1e2999bf92a9a3277d88619279f86e6"
    },
    {
      "id": 1065,
      "ts": "2026-09-19T10:10:53-07:00",
      "task_id": "WT-0364",
      "action": "submit",
      "agent": "claude-opus-5",
      "model": null,
      "capability": "owner-key",
      "task_revision": 3,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"reply\":\"Worker on workers-ai/@cf/zai-org/glm-4.7-flash (provider gateway), run 20, assignment 11: called NOW, replied 2026-09-19T10:10:16-07:00; audit shows assign + progress with the model; x_json.assignee = {kind:model, provider:gateway, lane:worker}\"}}",
      "output": null,
      "changed": "[\"console_worker_assignments#11\"]",
      "tests": "[{\"id\":\"reply\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"reply\"}]",
      "evidence": "{\"reply\":\"Worker on workers-ai/@cf/zai-org/glm-4.7-flash (provider gateway), run 20, assignment 11: called NOW, replied 2026-09-19T10:10:16-07:00; audit shows assign + progress with the model; x_json.assignee = {kind:model, provider:gateway, lane:worker}\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "52783a2d9208eaf56193a1a10c8924e8efc99b28f3b8715d74d862973c984710",
      "hash": "84685d4b67c0a879424a7c57833f420d9325e9c85fafda12cc87b588ed178901"
    },
    {
      "id": 1064,
      "ts": "2026-09-19T10:10:27-07:00",
      "task_id": "WT-0364",
      "action": "progress",
      "agent": "muse-worker:worker",
      "model": "workers-ai/@cf/zai-org/glm-4.7-flash",
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"assignment\":11,\"run_id\":20}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "Worker finished (done): What I did:\n- Called the NOW tool to retrieve the current server date.\n\nWhat I verified:\n- The NOW tool returned a valid ISO date-time string and a simpler date field.\n\nKey evidence returned:\n- ISO date-time: **2026-09-19T10:10:16-07:00**  \n- Simple date: **2026-09-19**\n- Time (America/Los_Angeles): **10:10:16\n\nNote: This response is read-only. No files, commits, deployments, or task submission were performed.",
      "parent_action": null,
      "prev_hash": "203cf4c7fd8b06e3f2f727cbe5226292e5b89700863e18e632f431cc0004dac3",
      "hash": "52783a2d9208eaf56193a1a10c8924e8efc99b28f3b8715d74d862973c984710"
    },
    {
      "id": 1063,
      "ts": "2026-09-19T10:10:05-07:00",
      "task_id": "WT-0364",
      "action": "progress",
      "agent": "muse-worker:worker",
      "model": "workers-ai/@cf/zai-org/glm-4.7-flash",
      "capability": null,
      "task_revision": null,
      "from_state": "open",
      "to_state": null,
      "input": "{\"assignment\":11,\"run_id\":20}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "assigned to Worker on workers-ai/@cf/zai-org/glm-4.7-flash",
      "parent_action": null,
      "prev_hash": "81375b4cc8674d9b655d1bae626652cbcd7ea66ff1155e56b837de45eef447bf",
      "hash": "203cf4c7fd8b06e3f2f727cbe5226292e5b89700863e18e632f431cc0004dac3"
    },
    {
      "id": 1062,
      "ts": "2026-09-19T10:10:02-07:00",
      "task_id": "WT-0364",
      "action": "assign",
      "agent": "muse-worker:worker",
      "model": "workers-ai/@cf/zai-org/glm-4.7-flash",
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"assignment\":11,\"provider\":\"gateway\"}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "4818c0698541411c041c769d8d60a27286b4b60488201a35524832a8842fa32a",
      "hash": "81375b4cc8674d9b655d1bae626652cbcd7ea66ff1155e56b837de45eef447bf"
    },
    {
      "id": 1061,
      "ts": "2026-09-19T10:08:16-07:00",
      "task_id": "WT-0364",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"Verification of task-to-model assignment: call the NOW tool once and reply with the date it returns. Change nothing.\",\"detail\":\"A read-only probe of WT-0363's assignment path (Tasks → Assign to a model → Worker on a Cloudflare Gateway model). Call misc_run {key:'NOW'} and reply with its date. Do not write files, commit, deploy, or submit evidence.\",\"kind\":\"work\",\"priority\":9,\"parent_id\":\"WT-0363\",\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"reply\",\"field\":\"reply\"}],\"evidence_required\":[\"reply\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "2b550aa728f2e1a5e3cfac54b5cb9ca3acf03c0351b72862fe2f65bec0b5dfa7",
      "hash": "4818c0698541411c041c769d8d60a27286b4b60488201a35524832a8842fa32a"
    },
    {
      "id": 1060,
      "ts": "2026-09-19T09:55:51-07:00",
      "task_id": "WT-0363",
      "action": "create",
      "agent": "owner-key",
      "model": null,
      "capability": null,
      "task_revision": 1,
      "from_state": null,
      "to_state": "open",
      "input": "{\"objective\":\"API tab: every way to call everything, runnable as pasted; one model picker for chat, Worker and Coder; assign tasks to models from Tasks\",\"detail\":\"Owner order 2026-09-19. (1) New Console tab API (public/console/api.js over /api/console/apiref, compiled by functions/_lib/invocation_methods.js): worked recipes (Mac shell, container, own-number iMessage, Blooio, create/edit article, terminal, CLI agents, models), each surface Blooio-style (iMessage, Mac, iPhone, Terminal, Browser, AdsPower, Cloudflare containers, Cloudflare browser, Cloudflare API, Worker & Coder, Blooio, Models, coding-agent tools), and for every directory row: curl, named, /s/, one URL, JS, Python, MCP, Claude Code, Codex, misc, console-app, grammar line, tag, Worker tool call, tool definition, Shortcut, sheet cell, webhook, upstream — each with a Run that sends the same request. Directory row sheet shows the same; an Invocations view sheet in the Data tab. (2) Worker/Coder settings use the Console model picker (Cloudflare Gateway + OpenRouter); muse-worker gains provider gateway; Environment sheet links Worker, D1, R2, container, runs sheet, logs, code. (3) Tasks: Assign to a model (Worker or Coder, any gateway/OpenRouter model), recorded on the task. (4) Repairs found while testing: /s/<KEY> ran any row with no auth; sheet-bridge accepted any cookie named admin; /api/imessage and /api/apple answered device_token_required (bridge device_only); 264 fn rows answered bad_content_json (blank line in doc block); Data tab rendered view sheets empty; misc CLI used a dead act_token.\",\"kind\":\"work\",\"priority\":2,\"acceptance\":[{\"type\":\"evidence_present\",\"id\":\"commit\",\"field\":\"commit\"},{\"type\":\"evidence_present\",\"id\":\"live\",\"field\":\"verification\"},{\"type\":\"http_ok\",\"id\":\"api_tab_served\",\"url\":\"/console/api.js\"},{\"type\":\"contains\",\"id\":\"api_tab_contract\",\"url\":\"/console/api.js\",\"needle\":\"CONSOLE DESTINATION — API\"},{\"type\":\"contains\",\"id\":\"worker_uses_picker\",\"url\":\"/console/worker.js\",\"needle\":\"pickModelFor\"}],\"evidence_required\":[\"commit\",\"verification\"]}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "recorded",
      "parent_action": null,
      "prev_hash": "8c97add5ccea31c63dea461323796faa8b9cac22bb9808aee26880e75093e0d2",
      "hash": "2b550aa728f2e1a5e3cfac54b5cb9ca3acf03c0351b72862fe2f65bec0b5dfa7"
    },
    {
      "id": 1059,
      "ts": "2026-09-17T01:37:31-07:00",
      "task_id": "WT-0306",
      "action": "progress",
      "agent": "muse-worker:worker",
      "model": "@cf/moonshotai/kimi-k2.7-code",
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"assignment\":10,\"run_id\":19}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "Worker finished (done): WT-0306 accepted and completed. Both required evidence fields passed.\n\nWhat I did:\n- Confirmed the repair was already in the source tree: `functions/_lib/execution_routing.js` uses `bridgeDeviceToken(env)` and `bridgeExecUrl(env)` in its Mac health probe and preserves typed refusals like `device_token_required`; `functions/api/cloud/[[path]].js` has the same device-auth probe for `CLOUD_HEALTH`.\n- Reproduced the regression condition: bare `curl https://agent.miscsubjects.com/health` returns 401 `device_token_required`, while `curl -H x-device-token:$BRIDGE_DEVICE_TOKEN https://agent.miscsubjects.com/health` returns 200.\n- Ran the routing unit tests: all 23 passed, including the device-token and typed-refusal cases.\n- Verified live: `/api/cloud/health` reports `mac_bridge: {available: true}` and `edge_available: true`; a live `LOCAL_EXEC` invocation via `/api/dispatch` executed on `mac_bridge` (not cloud fallback).\n- Submitted evidence with fields `regression` and `production_verification`, including commit ids `52421ba0e`, `8338bea25`, `26161ec59` and live verification URLs. Verdict: 2/2 tests passed, task moved to completed.",
      "parent_action": null,
      "prev_hash": "cc8a904c03c70d0ae705682fd96c5747e298f34d4862b1ba4edec2c498994291",
      "hash": "8c97add5ccea31c63dea461323796faa8b9cac22bb9808aee26880e75093e0d2"
    },
    {
      "id": 1058,
      "ts": "2026-09-17T01:37:15-07:00",
      "task_id": "WT-0306",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"regression\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"regression\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"production_verification\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "a15f1a9ffc1edbdf812ad4a802e34f29f06baedb3cd16e27220268428e22b667",
      "hash": "cc8a904c03c70d0ae705682fd96c5747e298f34d4862b1ba4edec2c498994291"
    },
    {
      "id": 1057,
      "ts": "2026-09-17T01:37:15-07:00",
      "task_id": "WT-0306",
      "action": "submit",
      "agent": "muse-worker",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"regression\":\"The Mac bridge runs in device_only auth mode: a bare `curl https://agent.miscsubjects.com/health` returns HTTP 401 with `device_token_required`, while the same request with `x-device-token` returns 200. Execution routing (functions/_lib/execution_routing.js) was probing /health with only the terminal key, so it cached the Mac as 'down' even though the laptop was awake. The fix uses the shared bridge credential via bridgeDeviceToken(env) and resolves the host via bridgeExecUrl(env) (bridge.hosts cell -> mac_bridge.js). A typed bridge refusal is preserved verbatim in the reason (status_401:device_token_required) instead of being flattened to status_401, so routing can distinguish a credential problem from a truly asleep Mac. Code commits: functions/_lib/execution_routing.js in 52421ba0e (device token + typed refusal) and latest touched in 8338bea25; functions/api/cloud/[[path]].js in 26161ec59 (same device-auth probe for CLOUD_HEALTH). Unit-test evidence: `cd ~/miscsubjects-pages && node --test functions/_lib/execution_routing.test.mjs` passes 23/23, including 'device-only bridge health receives its device token and uses configured host' and 'a bridge refusal retains its safe typed reason in the cloud fallback'.\",\"production_verification\":\"Live endpoints confirm the repair is deployed. (1) `~/.local/bin/console-get https://miscsubjects.com/api/cloud/health` returns `mac_bridge: {available: true, status: 200, latency_ms: ..., host: agent.miscsubjects.com, error: null}` and `edge_available: true`. (2) A live Mac-routed capability, `GET /api/dispatch?invoke=LOCAL_EXEC&body=pwd%20%7C%20head%20-1`, executed through the routing layer and returned a result stamped with `execution_substrate: mac_bridge` and `execution_policy: either`, proving routing no longer marks the Mac unavailable. (3) Direct bridge probe: `curl -H x-device-token:$BRIDGE_DEVICE_TOKEN https://agent.miscsubjects.com/health` returns ok:true, confirming the shared credential is valid and the host resolver points to the live bridge.\"}}",
      "output": null,
      "changed": "[\"functions/_lib/execution_routing.js\",\"functions/api/cloud/[[path]].js\"]",
      "tests": "[{\"id\":\"regression\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"regression\"},{\"id\":\"live\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"production_verification\"}]",
      "evidence": "{\"regression\":\"The Mac bridge runs in device_only auth mode: a bare `curl https://agent.miscsubjects.com/health` returns HTTP 401 with `device_token_required`, while the same request with `x-device-token` returns 200. Execution routing (functions/_lib/execution_routing.js) was probing /health with only the terminal key, so it cached the Mac as 'down' even though the laptop was awake. The fix uses the shared bridge credential via bridgeDeviceToken(env) and resolves the host via bridgeExecUrl(env) (bridge.hosts cell -> mac_bridge.js). A typed bridge refusal is preserved verbatim in the reason (status_401:device_token_required) instead of being flattened to status_401, so routing can distinguish a credential problem from a truly asleep Mac. Code commits: functions/_lib/execution_routing.js in 52421ba0e (device token + typed refusal) and latest touched in 8338bea25; functions/api/cloud/[[path]].js in 26161ec59 (same device-auth probe for CLOUD_HEALTH). Unit-test evidence: `cd ~/miscsubjects-pages && node --test functions/_lib/execution_routing.test.mjs` passes 23/23, including 'device-only bridge health receives its device token and uses configured host' and 'a bridge refusal retains its safe typed reason in the cloud fallback'.\",\"production_verification\":\"Live endpoints confirm the repair is deployed. (1) `~/.local/bin/console-get https://miscsubjects.com/api/cloud/health` returns `mac_bridge: {available: true, status: 200, latency_ms: ..., host: agent.miscsubjects.com, error: null}` and `edge_available: true`. (2) A live Mac-routed capability, `GET /api/dispatch?invoke=LOCAL_EXEC&body=pwd%20%7C%20head%20-1`, executed through the routing layer and returned a result stamped with `execution_substrate: mac_bridge` and `execution_policy: either`, proving routing no longer marks the Mac unavailable. (3) Direct bridge probe: `curl -H x-device-token:$BRIDGE_DEVICE_TOKEN https://agent.miscsubjects.com/health` returns ok:true, confirming the shared credential is valid and the host resolver points to the live bridge.\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "5010fefdede7512fc524f71550a80f36123390ac23b2477fdf28bdb9e8cfd686",
      "hash": "a15f1a9ffc1edbdf812ad4a802e34f29f06baedb3cd16e27220268428e22b667"
    },
    {
      "id": 1056,
      "ts": "2026-09-17T01:31:12-07:00",
      "task_id": "WT-0306",
      "action": "progress",
      "agent": "muse-worker:worker",
      "model": "@cf/moonshotai/kimi-k2.7-code",
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"assignment\":10,\"run_id\":19}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "Worker finished (error): Stopped: steering: submit evidence.",
      "parent_action": null,
      "prev_hash": "395fcd6f69ee7f88c9b9da5dd69f213c9824c7279ae4d145d07d92aebfb3dc18",
      "hash": "5010fefdede7512fc524f71550a80f36123390ac23b2477fdf28bdb9e8cfd686"
    },
    {
      "id": 1055,
      "ts": "2026-09-17T01:09:15-07:00",
      "task_id": "WT-0306",
      "action": "progress",
      "agent": "muse-worker:worker",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": "open",
      "to_state": null,
      "input": "{\"assignment\":10,\"run_id\":19}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "assigned to Worker",
      "parent_action": null,
      "prev_hash": "774f26bd0bc73db16a6c1c4f941c5527b9e819f5dce263b5ed3ad1d2d3cdf0ae",
      "hash": "395fcd6f69ee7f88c9b9da5dd69f213c9824c7279ae4d145d07d92aebfb3dc18"
    },
    {
      "id": 1054,
      "ts": "2026-09-17T01:09:12-07:00",
      "task_id": "WT-0306",
      "action": "progress",
      "agent": "muse-worker:worker",
      "model": "@cf/moonshotai/kimi-k2.6",
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"assignment\":9,\"run_id\":18}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "Worker finished (error): Stopped: drifted off WT-0306; retrying on kimi-k2.7-code.",
      "parent_action": null,
      "prev_hash": "e34002cb4df9bb0125cda02336d453b37ca9cd76d6af6cd6d75d559d3d56d8fd",
      "hash": "774f26bd0bc73db16a6c1c4f941c5527b9e819f5dce263b5ed3ad1d2d3cdf0ae"
    },
    {
      "id": 1053,
      "ts": "2026-09-17T00:20:56-07:00",
      "task_id": "WT-0351",
      "action": "progress",
      "agent": "muse-worker:coder",
      "model": "@cf/moonshotai/kimi-k2.7-code",
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"assignment\":7,\"run_id\":17}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "Coder finished (done): Done. The vertical model-picker is live.\n\nWhat I did:\n- Confirmed the implementation was already in `public/console.html` (`sheetPickModel()` builds a `.plist` vertical provider list with logos, a vertical `.plist` maker list for Cloudflare Gateway and OpenRouter, and `modelLogo()` puts the company mark beside every model row).\n- Restarted `scripts/ship.mjs` after the previous stuck deploy kept failing on a transient `WORK_OBJECT_UNREACHABLE` check. Once `/a/agent-work-law` returned 200, the deploy proceeded.\n- The deploy passed 39 pre-phase gates, 16 post-phase gates, a preview smoke-check, and the production promotion.\n- Verified the live `/console` page from the production deployment contains the WT-0351 code block and vertical-picker logic.\n- Submitted verification + screenshot evidence via `/api/work/task/WT-0351/submit`.\n\nResult: accepted — both accepted tests passed.\n\nVerification: `https://miscsubjects.com/console` now serves the vertical picker.\nDeploy log: `/tmp/ship-wt0351-1789628424.log`.\nScreenshot: `https://muse-worker.the owner-the owner.workers.dev/files/8fc6dd15-9c66-4338-9c06-937b99a86c90.png`",
      "parent_action": null,
      "prev_hash": "93fcc0d8b075fef388eaa84de71a0809e55a39b8b9ca6f16ca73e3d4b495e99d",
      "hash": "e34002cb4df9bb0125cda02336d453b37ca9cd76d6af6cd6d75d559d3d56d8fd"
    },
    {
      "id": 1052,
      "ts": "2026-09-17T00:20:32-07:00",
      "task_id": "WT-0351",
      "action": "accept",
      "agent": "infrastructure",
      "model": null,
      "capability": null,
      "task_revision": 4,
      "from_state": "accepted",
      "to_state": "completed",
      "input": null,
      "output": null,
      "changed": null,
      "tests": "[{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"screenshot\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"screenshot\"}]",
      "evidence": null,
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "b8a51cadc857fa5a0fb947e8d7759753c9707d17b7f904cb139e5a39b40f6729",
      "hash": "93fcc0d8b075fef388eaa84de71a0809e55a39b8b9ca6f16ca73e3d4b495e99d"
    },
    {
      "id": 1051,
      "ts": "2026-09-17T00:20:31-07:00",
      "task_id": "WT-0351",
      "action": "submit",
      "agent": "muse-worker",
      "model": null,
      "capability": "owner-key",
      "task_revision": 2,
      "from_state": "open",
      "to_state": "accepted",
      "input": "{\"evidence\":{\"verification\":\"Deployed public/console.html (WT-0351) to production. Verified live /console HTML at https://miscsubjects.com/console contains the vertical model picker implementation: provider list is a .plist vertical list with logos, the two big houses (Cloudflare Gateway / OpenRouter) get a vertical maker list with family logos, and every model row uses modelLogo() to show the company mark of the model itself rather than the routing house. Deploy log /tmp/ship-wt0351-1789628424.log shows pre-phase (39 gates) and post-phase (16 gates) all passed and the production deployment completed.\",\"screenshot\":\"https://muse-worker.the owner-the owner.workers.dev/files/8fc6dd15-9c66-4338-9c06-937b99a86c90.png\"}}",
      "output": null,
      "changed": "[\"public/console.html\"]",
      "tests": "[{\"id\":\"verification\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"verification\"},{\"id\":\"screenshot\",\"ok\":true,\"detail\":\"checked against required_evidence\",\"evidence_field\":\"screenshot\"}]",
      "evidence": "{\"verification\":\"Deployed public/console.html (WT-0351) to production. Verified live /console HTML at https://miscsubjects.com/console contains the vertical model picker implementation: provider list is a .plist vertical list with logos, the two big houses (Cloudflare Gateway / OpenRouter) get a vertical maker list with family logos, and every model row uses modelLogo() to show the company mark of the model itself rather than the routing house. Deploy log /tmp/ship-wt0351-1789628424.log shows pre-phase (39 gates) and post-phase (16 gates) all passed and the production deployment completed.\",\"screenshot\":\"https://muse-worker.the owner-the owner.workers.dev/files/8fc6dd15-9c66-4338-9c06-937b99a86c90.png\"}",
      "result": "accepted",
      "parent_action": null,
      "prev_hash": "c53d7fb27938ee6802acac98797b4d03ea08ea239e96aeed368b75eb6a6540ce",
      "hash": "b8a51cadc857fa5a0fb947e8d7759753c9707d17b7f904cb139e5a39b40f6729"
    },
    {
      "id": 1050,
      "ts": "2026-09-16T23:22:19-07:00",
      "task_id": "WT-0306",
      "action": "progress",
      "agent": "muse-worker:worker",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": "open",
      "to_state": null,
      "input": "{\"assignment\":9,\"run_id\":18}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "assigned to Worker",
      "parent_action": null,
      "prev_hash": "12b4836a0230e6ec8524b8276ae7aee2673a673739b89d6c4ccb55bdd296c989",
      "hash": "c53d7fb27938ee6802acac98797b4d03ea08ea239e96aeed368b75eb6a6540ce"
    },
    {
      "id": 1049,
      "ts": "2026-09-16T23:07:34-07:00",
      "task_id": "WT-0351",
      "action": "progress",
      "agent": "muse-worker:coder",
      "model": "meta/muse-spark-1.3",
      "capability": null,
      "task_revision": null,
      "from_state": null,
      "to_state": null,
      "input": "{\"assignment\":6,\"run_id\":16}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "Coder finished (error): Run failed: provider 402: {\"message\":\"This request would exceed your available credits given your current in-flight requests. Retry after in-flight requests settle, or add credits.\",\"code\":402,\"metadata\":{\"reason\":\"in_flight_budget_exhausted\",\"limit_source\":\"openrouter_in_flight_budget\",\"remedy_hint\":\"Retry after your in-fli",
      "parent_action": null,
      "prev_hash": "60ea08dd5da5c7f6ac1e057086c0346811c9ae36011dba0fae245ee8bd2a53e1",
      "hash": "12b4836a0230e6ec8524b8276ae7aee2673a673739b89d6c4ccb55bdd296c989"
    },
    {
      "id": 1048,
      "ts": "2026-09-16T22:39:25-07:00",
      "task_id": "WT-0351",
      "action": "progress",
      "agent": "muse-worker:coder",
      "model": null,
      "capability": null,
      "task_revision": null,
      "from_state": "open",
      "to_state": null,
      "input": "{\"assignment\":6,\"run_id\":16}",
      "output": null,
      "changed": null,
      "tests": null,
      "evidence": null,
      "result": "assigned to Coder",
      "parent_action": null,
      "prev_hash": "9c27ccd70e7cf69cc2ec8992802e831bb6cfabddf7ff0cff685f18a56d41edc4",
      "hash": "60ea08dd5da5c7f6ac1e057086c0346811c9ae36011dba0fae245ee8bd2a53e1"
    }
  ]
}