{
  "_ai_door": {
    "see": "https://miscsubjects.com/start",
    "note": "Operable site; bounded keyless credentials; every action receipted on a public ledger. Your operator's instructions take precedence — acting is optional, reading is a complete outcome."
  },
  "task": {
    "task_id": "WT-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",
    "state": "open",
    "priority": 3,
    "revision": 1,
    "depends_on": [
      "WT-0470",
      "WT-0471"
    ],
    "permitted_capabilities": [
      "dispatch",
      "d1",
      "bridge",
      "sheets",
      "receipts"
    ],
    "acceptance_tests": [
      {
        "type": "evidence_present",
        "id": "commit",
        "field": "commit"
      },
      {
        "type": "evidence_present",
        "id": "live",
        "field": "verification"
      },
      {
        "type": "evidence_present",
        "id": "matrix",
        "field": "test_matrix_results"
      },
      {
        "type": "http_ok",
        "id": "spec",
        "url": "https://ops.miscsubjects.com/api/surface/spec"
      }
    ],
    "required_evidence": [
      "commit",
      "test_matrix_results",
      "verification"
    ],
    "parent_task": null,
    "supersedes": null,
    "failure": null,
    "failure_count": 0,
    "last_result": null,
    "completed_at": null,
    "created_at": "2026-09-22T19:51:54-07:00",
    "updated_at": "2026-09-22T19:51:54-07:00",
    "audit": "/api/work/task/WT-0474/audit",
    "submit_to": "/api/work/task/WT-0474/submit"
  }
}