{"_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."},"slug":"web-models-as-first-class-capabilities","title":"Web Models as First-Class Capabilities","body":"A logged-in ChatGPT, Claude, Grok or Gemini web session is now an ordinary capability in this build. A caller names a provider and a prompt, and gets back the exact answer the web model gave, with a receipt. The same web model can call the rest of the build by writing a tag. Both directions run through the same Directory, the same flows, the same scheduler and the same ledger as every HTTP tool and API agent here. What existed before, what the reference projects already prove, what was added, exactly how it was tested, what broke, and what is still missing follow in that order.\n\n## Copying between tabs was the bottleneck, and it left no record\n\nFive chat products carry paid subscriptions whose web sessions have no programmatic door. The same vendors sell APIs, metered separately, with connectors that differ from one another, and a model in one tab cannot see what a model in another tab did. Getting ChatGPT Web to draft, Claude Web to audit and Grok Web to adjudicate meant copying text between tabs by hand. The copy was the bottleneck, and it left no record.\n\nThe build already had the other half: a Directory of about a thousand capabilities behind one dispatch call, a flow grammar that composes them, a scheduler, an event bridge, scoped bearer tokens, and a ledger that records every invocation. Web models were the one class of worker that could not be a row in it.\n\n## What existing projects already solve\n\nSource was read, not marketing. Three mechanically different things get called \"web model MCP\" and they should not be conflated.\n\n**Drive the chat page and scrape the answer.** [mcp-web-llm](/a/mcp-web-llm) attaches Playwright to a logged-in Chrome over CDP, types into ChatGPT, Claude, Gemini, DeepSeek, Grok and Qwen, and polls the DOM until the last assistant node stops changing. Its README says \"No API keys or tokens required.\" It has no session object, no conversation identity, no tool loop, and it states that its memory feature \"has been rolled back.\" [agentify desktop](/a/agentify-desktop) is the same idea built as a desktop app with a selector file and a rate governor. [ChatGPT-Web2API](/a/chatgpt-web2api) is the one project that reads the provider's own backend from inside the page and uses its end-of-turn flag as the completion signal, addressing real conversation ids.\n\n**Give the web model tools.** [MCP-WebLLM](/a/mcp-webllm) is a Chrome extension that pastes a tool manifest into the chat, watches the DOM for a fenced block, executes the call against a local MCP server and pastes the result back. It is the inverse direction of mcp-web-llm and the closest precedent for the relay lane below. [codex-chatgpt-web](/a/codex-chatgpt-web) does the same job the robust way for one host and one provider, by registering a real MCP server as a ChatGPT connector so ChatGPT's own agent loop calls the tools.\n\n**Generic browser control.** [BrowserMCP](/a/browsermcp) and [graph-memory browser-mcp](/a/graph-memory-browser-mcp) drive a browser through MCP without knowing any model. The second has the best session model in the set, named on-disk profiles, network body capture, and one tool registry projected into both MCP and REST. [browser-use](/a/browser-use) is the large browser-agent ecosystem; its profile vocabulary and its thirteen watchdogs are the honest catalogue of what goes wrong in long-running browser workers.\n\nNone of the eight projects has workflow participation, cron, event triggers, a shared state object across vendors, an artifact promoted from a trace, or a provenance plane. Not one. That is not a criticism. They are relays. This build already had those other parts and needed the relay.\n\n## What OpenClaw does with skills and self-learning\n\n[OpenClaw](/a/openclaw-self-learning) is the important comparison, because it is the popular personal-agent gateway and because its self-learning system really does turn work into durable artifacts. Read at source: what is learned is a `SKILL.md`, natural-language instructions with YAML frontmatter, produced by a reviewer prompt that asks for \"a stable procedure that saves at least two future model round trips.\" The default mode applies scanner-approved proposals automatically. When a learned skill is used later, the agent reads the file back into context and reasons through it again. There is no replay, no compiled workflow and no generated code path. OpenClaw has a real trajectory recorder, but no learning path consumes it. Its cron and automations run messages, commands and scripts on schedules, separately from skills.\n\nThe distinction underneath everything that follows: a skill tells a future model how to do the procedure. A flow is the procedure, or more exactly its order and its data flow. A compiled flow does not learn preconditions, branches or recovery; it learns which capabilities ran, in what order, and which outputs fed which inputs.\n\n## What was added\n\nFourteen Directory rows for the browser plane: `CHATGPT_WEB`, `CLAUDE_WEB`, `GROK_WEB`, `GEMINI_WEB`, `KIMI_WEB`, plus the verbs `WEBMODEL_SESSION_NEW`, `WEBMODEL_SEND`, `WEBMODEL_READ`, `WEBMODEL_STATUS`, `WEBMODEL_CLOSE`, the relay `WEBMODEL_AGENT`, and the handoff primitive `STATE_NEW`, `STATE_APPEND`, `STATE_RESOLVE`. Three learned-flow rows: `FLOW_LEARN`, `FLOW_PROMOTE`, `FLOW_CANDIDATES`. Twelve identity rows: `PROFILE_NEW`, `PROFILE_360`, `PROFILE_IDENTIFY`, `PROFILE_EVENT`, `DEVICE_REGISTER`, `DEVICE_TRUST`, `DEVICE_REVOKE`, `DEVICE_VERIFY_RECORD`, `CAP_CONTEXT_BIND`, `CAP_CONTEXT_GET`, `CAP_CONTEXT_UNBIND`, `ACCESS_DECISIONS`. Every one is readable at `/api/dispatch?key=<KEY>` and appears in the same registry as everything else.\n\nTwo flow rows built from those: `WEB_COUNCIL` fans one question out to ChatGPT Web, Claude Web and Grok Web and has Gemini Web reconcile them. `WEB_DATA_REVIEW` fans out two live data capabilities and has Claude Web review the joined output. Neither contains any browser-specific machinery. They are the existing flow grammar with new member names.\n\n## The architecture in fifteen lines\n\n1. One persistent Mac worker owns one dedicated Chrome profile, seeded once from the owner's real profile, connected over CDP through Playwright.\n2. Five adapter files hold every selector, stream pattern and limit phrase. Nothing outside them knows a vendor's UI.\n3. Completion is detected from the provider's own streaming response finishing, then the stop indicator clearing, then DOM stabilisation over a real window, then the accessibility live region. Fixed sleeps are never the mechanism. The method that fired is recorded on every turn.\n4. The answer to a prompt is the last assistant node past the count that existed when the prompt was submitted. Older text is never returned as the reply.\n5. The worker exposes six narrow verbs behind the existing bridge and tunnel. No CDP, no arbitrary JavaScript and no arbitrary navigation cross the wire.\n6. A send is accepted and returns a running turn id. The edge polls the turn against a bounded budget. The Cloudflare edge in front of the tunnel cuts any origin response held past 100 seconds, and Claude Web can take longer than that.\n7. Sessions and turns are rows in the content database. The worker keeps a local mirror so a restarted process can re-open the conversation URL.\n8. Nothing reports success unless the prompt was submitted, the response captured, the row written and the ledger receipt taken. Each failure is a named code.\n9. A state handle is a small durable object: objective, open work, and a bounded window of entries. A model is handed the handle, never a transcript.\n10. The relay hands a web model the Directory as text. The model writes `[KEY]args[/KEY]`. The relay parses it with the router's own reader, runs it under the caller's authority, pastes the result back, and lets the model continue, bounded at eight iterations.\n11. Every browser-model session is a persistent model actor in the same profile table as human customers, so a turn is attributed to \"ChatGPT on the browser profile\", never to a person.\n12. A capability's authority stays in the signed token. Its context, meaning which profile, devices, sessions, state handles and origins may present it, how recent a human verification it needs, and whether a device signature is required, lives in a mutable server-side record evaluated on every use.\n13. Turn completion writes one ledger row with the event name `browser_model.turn.completed`. The event bridge fires any automation registered on it.\n14. `FLOW_LEARN` compiles a successful trace into a flow row: the run's input becomes `$1`, a step that consumed the previous output becomes `$PREV`, everything else stays a constant. Anything sensitive or side-effecting is created disabled.\n15. Worker health, sessions, turns, profiles, devices, contexts and access decisions are sheets over the tables they live in, not a dashboard.\n\n## The live tests, with receipts\n\nEvery receipt below is a public page. It proves the invocation happened, names the capability and the actor, and carries the hashes of the request and the response; the payload bytes themselves are readable with a credential, and the captured answers quoted here are in the durable turn rows, which are owner-readable. A reader without a credential can verify that each call happened and when, not the quoted text.\n\n**Acceptance.** One Directory capability, ChatGPT Web, prompt `Reply with exactly GATEWAY_LIVE_OK`. The exact answer came back with substrate `browser_web` and capture method `network_stream_end+dom`: [inv_9x5nyxhsbu](https://miscsubjects.com/receipt/inv_9x5nyxhsbu), durable turn `wmt_62761d775bdf8d3a46`, conversation `https://chatgpt.com/c/6a9db53c-2148-83e8-b5c7-799f1b74b45e`. The `CHATGPT_WEB` row itself returned the same token: [inv_rclmphgk7z](https://miscsubjects.com/receipt/inv_rclmphgk7z). Then Claude Web was handed the state handle `state://lyb1m6yseu` and the prompt `State exactly what the previous model replied.` It answered `GATEWAY_LIVE_OK`: [inv_mo6pgi8yxm](https://miscsubjects.com/receipt/inv_mo6pgi8yxm), conversation `https://claude.ai/chat/0b750b00-bbea-420f-9a69-84ca65942cef`. No human copied anything between tabs. The briefing Claude saw is what `STATE_RESOLVE` returns for that handle.\n\n**A web model calls a Directory capability.** `WEBMODEL_AGENT` gave ChatGPT Web one tool, `QUAKE_FEED`, and a task that required it. The model wrote `[QUAKE_FEED]1|4[/QUAKE_FEED]`, the relay ran it under the caller's authority, pasted the feed back, and the model answered with the place and magnitude: [inv_uwnn7ketmh](https://miscsubjects.com/receipt/inv_uwnn7ketmh). No MCP registration, connector, function calling or credential reached the vendor.\n\n**A web model operates the build through its own browser.** The second lane. A token scoped to one row was minted and its invoke address handed to ChatGPT Web and to Grok Web inside the prompt. Each opened the address with its own browsing tool, invoked the capability, and read back the invocation id the build had just issued: ChatGPT Web returned [inv_03d3lm47u7](https://miscsubjects.com/receipt/inv_03d3lm47u7) and Grok Web returned [inv_ndnaqm7jbo](https://miscsubjects.com/receipt/inv_ndnaqm7jbo). No relay parsed anything; the model exercised the bounded authority directly, and the ledger records the same actor either way.\n\n**Profile-state policy.** One token, two bindings. Bound to a profile whose attributes carry an active subscription and the segment vip, with rules requiring both, it ran ([inv_amw5xhoauv](https://miscsubjects.com/receipt/inv_amw5xhoauv)). Rebound to a profile without the subscription, the same token was refused `POLICY_DENIED` naming the failed rule, and the explain surface reports the effective decision for any presenter without executing.\n\n**Parallel council.** `WEB_COUNCIL` sent one question to ChatGPT Web, Claude Web and Grok Web concurrently and Gemini Web reconciled the three: [inv_txud6ki0qw](https://miscsubjects.com/receipt/inv_txud6ki0qw). Four browser turns landed under one trace. All four models said a logged-in browser session is not a reasonable production dependency, which is a fair reading of the limitations section below.\n\n**Business capabilities feed a web model.** `WEB_DATA_REVIEW` fanned out the most recent significant earthquake and the gold spot price, joined them, and Claude Web reviewed the joined block through `$PREV`: [inv_ahf7onnesd](https://miscsubjects.com/receipt/inv_ahf7onnesd).\n\n**A browser turn fires an automation.** Automation 34 is registered on `event:on source=webmodel action=turn_completed`. A browser turn completed ([inv_9j5ksu87xy](https://miscsubjects.com/receipt/inv_9j5ksu87xy)) and the ledger row fired it: run count rose, receipt [inv_guxgetocb7](https://miscsubjects.com/receipt/inv_guxgetocb7). This closed work task WT-0123, whose defect was that the fire was handed to a `waitUntil` that did not exist.\n\n**A scheduled automation runs a browser-model flow.** Automation 35 schedules `WEB_DATA_REVIEW` daily. The ordinary scheduler ran it with no browser-specific code: [inv_n441rf3pjp](https://miscsubjects.com/receipt/inv_n441rf3pjp).\n\n**Cold restart.** A session stored a codeword ([inv_vys3gwu9to](https://miscsubjects.com/receipt/inv_vys3gwu9to)). The worker was killed and relaunched by launchd with a new process id. The same session id resumed the same conversation and returned the codeword: [inv_v52c7v6hw3](https://miscsubjects.com/receipt/inv_v52c7v6hw3).\n\n**Signed-out provider.** Kimi Web is not signed in on the gateway profile. `KIMI_WEB` returned `ERR:AUTH_REQUIRED`, not an answer from an API model.\n\n**Learned flow.** Two steps were done by hand and receipted: `QUAKE_PLACE` ([inv_cou892hbho](https://miscsubjects.com/receipt/inv_cou892hbho)) and `CLAUDE_WEB` asked which region that place is in ([inv_xw66nxifeu](https://miscsubjects.com/receipt/inv_xw66nxifeu)). `FLOW_LEARN` compiled them into the row `QUAKE_REGION_1BV5` with the body `QUAKE_PLACE: $1+ > CLAUDE_WEB: In one sentence, say which country or region this place is in: $PREV`, bindings recorded as `argument` and `previous_output_embedded`. The new key then ran as an ordinary capability with a different argument: [inv_0benrtdq4x](https://miscsubjects.com/receipt/inv_0benrtdq4x). `FLOW_CANDIDATES`, in its first version, scanned 20,000 top-level invocations and found no repeated multi-step trace. The corrected version and its result are in the limitations section below.\n\n**Authority with context.** A token scoped to one row was bound to one profile and one device. From that device it ran ([inv_jdql2odkcn](https://miscsubjects.com/receipt/inv_jdql2odkcn)); from a second device it was refused `DEVICE_NOT_APPROVED`; with no device it was refused the same way. The device was revoked ([inv_f8uy3uac3t](https://miscsubjects.com/receipt/inv_f8uy3uac3t)) and the same still-valid token was refused `DEVICE_REVOKED` at once, while `CAP_EXPLAIN` still reported the token itself live. A twenty-second verification window produced `TURNSTILE_REQUIRED`, then an allow after a recorded verification ([inv_jn9v2oxnn7](https://miscsubjects.com/receipt/inv_jn9v2oxnn7)), then `TURNSTILE_STALE` after the window passed. A child token narrowed to one of the parent's two devices ran from that device and was refused from the other, while the parent still ran from both. A device with a registered P-256 key signed a request and ran ([inv_66goomu12i](https://miscsubjects.com/receipt/inv_66goomu12i)); the same signature replayed was `POP_REPLAY`; a signature over a different nonce was `POP_INVALID`. A capability bound to one browser-model session ran from that session and was refused `SESSION_NOT_APPROVED` from another. In the cross-model handoff, ChatGPT Web worked on `state://jre4vo3oln` ([inv_t1xrj9w5y4](https://miscsubjects.com/receipt/inv_t1xrj9w5y4)), a separate capability `cap_9cc8c44c850f2710` bound to the Claude model actor and that handle resolved the shared state, was refused `STATE_HANDLE_MISMATCH` against another handle, and Claude Web recovered the token ([inv_77szzrn6sj](https://miscsubjects.com/receipt/inv_77szzrn6sj)). Both actors and both decisions are separate ledger rows.\n\n**Mechanical tests.** Fifty assertions run before deploy: the session state machine, response selection, stabilisation windows, redaction, failure naming, the pipe-safe body grammar, the forced durable-write and ledger-write failures that must never report success, the accept-and-poll path, the timeout by name, the context decision for every named code, narrowing, and a real ECDSA proof-of-possession round trip.\n\n## What is precedent and what is unusual\n\nDriving a logged-in web model from a browser and exposing it as a tool is precedent, in one shipping product with adoption and a dozen small repositories. Giving a web model tools by pasting a manifest and parsing its output is precedent, in one small repository. Persistent profiles, network capture and one registry projected into MCP and REST are precedent in generic browser servers. Compiling a successful run into executable code is precedent in Skyvern's code caching. Learning from work into durable text is precedent in OpenClaw, Claude Skills and Codex Record and Replay.\n\nThe combination in this build is not found in the eight repositories read or the commercial systems surveyed: a web model that is at once callable as a capability and able to call the rest of the capability graph, that participates in flows, schedules and event triggers as a plain member, whose work is bound to a durable state object another vendor's model can pick up, whose successful runs can be compiled into another callable capability, and whose every step lands in one ledger. Each piece has an owner somewhere. The join is the addition. Whether the join is valuable is a bet, not a claim; the tests above are what would falsify it.\n\n## What failed during implementation\n\nThe first live Claude handoff died with a Cloudflare 524. The tunnel hostname is proxied, and a response held open for the length of a Claude turn exceeded its 100-second origin timeout. The fix is the accept-and-poll path in line 6 above.\n\nThe second failure was worse and quieter. Multi-line prompts were typed with the Enter key for newlines, and every provider composer submits on Enter. Claude received a state briefing with no task and replied that it was still missing the task ([inv_0hrhns715v](https://miscsubjects.com/receipt/inv_0hrhns715v)); the relay's ChatGPT received one sentence of preamble and replied \"Understood.\" Textareas are now filled whole and contenteditable composers get Shift+Enter between lines.\n\nThird, sessions never closed their tabs. After forty-five open provider tabs a fresh claude.ai load timed out at sixty seconds ([inv_9nzo07xtfb](https://miscsubjects.com/receipt/inv_9nzo07xtfb)). The worker now keeps at most six live tabs and closes the least recently used idle one; the durable conversation URL makes a tab disposable.\n\nFourth, a freshly compiled learned flow was not dispatchable inside the same request that created it, because the directory snapshot propagates through eventually consistent storage. It ran on the next request. `FLOW_LEARN` reports the replay honestly rather than pretending.\n\nFifth, the ledger-event bridge had never fired in production because it handed its work to `env.waitUntil`, which does not exist on `env`. It is awaited now.\n\n## What three web models said about this page\n\nAfter publication, ChatGPT Web, Claude Web and Grok Web were each handed this page's address through the gateway and asked for the one claim they would challenge and one factual error. Their replies are appended to the page as signed contributions with receipts. Two errors they found are corrected above: the row count read nine where fourteen were listed, and the opening sentence implied the vendors sell no programmatic access at all. Claude Web's challenge, that a public receipt certifies the invocation and not the quoted answer, is also correct and the receipts paragraph now says so. Grok Web's challenge, that a consumer web session is a brittle relay rather than a durable worker, stands as the strongest objection and is not answered here.\n\n## What is missing\n\nKimi Web is not signed in on the gateway profile and was not exercised. Grok Web and Gemini Web each answered a standalone prompt with the exact token asked for: [inv_i03kg9rf4u](https://miscsubjects.com/receipt/inv_i03kg9rf4u) and [inv_bdkmm2pa5k](https://miscsubjects.com/receipt/inv_bdkmm2pa5k).\n\nThe Turnstile step-up page was refused inside the automated browser pane, which the widget is designed to do. Opened in a real Chrome window, the managed challenge passed, the server-side verify route accepted it, and the device row carries the verification instant with method `turnstile`. The step-up denials and allows above were exercised with owner-recorded verifications before that pass.\n\n`FLOW_CANDIDATES` first returned nothing, because it read the invocation table, which holds one row per top-level dispatch. It now reads the ledger's per-step rows under each trace, where flow members and agent tool calls actually live. Its second version found one procedure repeated three times over 11,237 traces ([inv_1yr8peu4s9](https://miscsubjects.com/receipt/inv_1yr8peu4s9)), and compiling it exposed the last defect: the procedure was `DELIVER_PENDING_ASSETS`, itself a flow row wrapping one trigger, whose ledger rows sit interleaved with its member. A trace that contains a flow row is now treated as a flow execution and excluded. With that correction the scan returns the honest result for this build in this week: 11,225 traces examined, 183 of them flow executions, and no uncompiled procedure that repeats ([inv_975yvs4x06](https://miscsubjects.com/receipt/inv_975yvs4x06)). The compiler is proven on the hand-done pair above; the scanner is proven to find repetition and to know a flow when it sees one.\n\nProvider terms of service are not analysed here. The council's own verdict, that a logged-in browser session is not a production dependency, stands as the strongest counter-argument to this design. Rate limits are surfaced verbatim when a provider shows them and were not hit during testing.\n\nMeasured across the turns recorded today: ChatGPT Web averaged 9 seconds a turn over 23 turns (3 to 26), Claude Web 12 seconds over 15 (6 to 36), Grok Web 17 seconds over 5 (4 to 37), Gemini Web 16 seconds over 2 (3 to 28). Prompts and answers averaged 300 to 600 characters, or roughly 100 to 200 tokens a turn; at current list prices for the frontier tiers the equivalent API spend for the whole day's testing is under one dollar. The browser turn is slower than an API call by an order of magnitude and costs nothing per token.\n\nCost is measured, not marketed. The turns here consumed no API tokens; they consumed the owner's existing subscriptions and a Mac that has to stay on. The equivalent API spend for the prompts above is a few cents. The machine and the profile maintenance are the real cost, and nothing here should be read as free inference.\n\nMulti-user distribution is not attempted. Every profile here is the owner's. A product would need one authenticated browser profile per user, and this build's tenant and context machinery is the place that isolation would attach.\n\n## How to reproduce\n\nRead the contract of one row: `GET https://miscsubjects.com/api/dispatch?key=CHATGPT_WEB`. Mint a scoped token for that row from the owner's key, then `GET /api/dispatch?invoke=CHATGPT_WEB&body=Reply%20with%20exactly%20GATEWAY_LIVE_OK&share=<token>`. The response names the substrate, the capture method, the turn id and the ledger event. Open the receipt link. Then `STATE_RESOLVE` the handle the response carries and hand it to `CLAUDE_WEB` with `with_state` set. Every receipt above was produced exactly that way and can be re-run with `POST /api/dispatch {\"replay\":\"<inv_id>\"}`.\n\n## Comparison\n\n| System | Callable web model | Persistent profile | MCP | REST | Web model calls arbitrary tools | Shared state across vendors | Workflow member | Workflow becomes a capability | Trace becomes executable | One evidence plane | Cron or events |\n|---|---|---|---|---|---|---|---|---|---|---|---|\n| mcp-web-llm | yes | yes, one shared Chrome | yes | no | no | no | no | no | no | no | no |\n| MCP-WebLLM | no, it is the client | browser's own | client only | no | yes | no | no | no | no | no | no |\n| BrowserMCP | no model | user's own | yes | no | n/a | no | no | no | no | no | no |\n| graph-memory browser-mcp | no model | yes, named | yes | yes | n/a | no | callable only | no | no | no | no |\n| browser-use | no, API models | yes | no | no | agent does | no | no | no | no | no | no |\n| codex-chatgpt-web | yes, ChatGPT only | yes | connector | Responses API | yes, native connector | single vendor | no | no | no | no | no |\n| agentify desktop | yes | yes, isolated | yes | yes | unknown | unknown | no | no | no | no | folder watch |\n| ChatGPT-Web2API | yes, ChatGPT only | yes | yes | yes | no | single vendor | no | no | no | no | no |\n| Skyvern | no | yes | unknown | yes | agent does | no | yes | yes | yes, code cache | run logs | cron |\n| OpenClaw | via browser tool | yes | yes | gateway | agent does | sessions | automations | no | text skill | session logs | cron |\n| this build | yes, five rows | yes, dedicated | yes | yes | yes, by tag | yes, state handle | yes | yes | yes, flow row | yes, ledger | both |\n\nCells marked yes carry a receipt above or a source file citation in the linked reference article. Unknown means unknown.\n","register":"build","hero":"https://miscsubjects.com/img/gen/arcads-gpt-image-6dea60a1-9fe0-41f2-9864-877de2f09975.png","hero_brief":"Five different antique chess clocks on one oak workbench, each wired by thin brass tubing into a single open ledger book at the centre; a chrome robotic hand presses the button on one clock while a second chrome hand writes a line in the ledger; warm workshop light, photorealistic, no text and no screens. Five web models, one ledger, one hand that presses and one that records.","editorial_review":{"headline_subject":"web models becoming ordinary capabilities of the build","hero_subject":"five chess clocks wired into one ledger, two robotic hands operating and recording","hero_brief":"Five different antique chess clocks on one oak workbench, each wired by thin brass tubing into a single open ledger book at the centre; a chrome robotic hand presses the button on one clock while a second chrome hand writes a line in the ledger; warm workshop light, photorealistic, no text and no screens. Five web models, one ledger, one hand that presses and one that records.","visual_action":"one hand presses a clock (invoking a model) while the other writes the entry (the receipt)","rationale":"five vendors, one evidence plane, one act of invocation and one act of recording, which is exactly the architecture","inspected":true,"inspection_note":"Opened the rendered PNG: five distinct wooden chess clocks in a row, brass tubes running from each into an open ruled ledger at centre, a chrome hand on the left pressing a clock button, a chrome hand on the right holding a pen over the ledger, warm blurred workshop background, no text, no screens."},"tags":["build","browser-models","oip","flows","identity","learned-flows"],"category":"build","style":{},"claims":[{"id":"c1","text":"A logged-in ChatGPT Web session invoked as the Directory capability CHATGPT_WEB returned the exact text GATEWAY_LIVE_OK with substrate browser_web (receipt inv_rclmphgk7z).","section":"The live tests, with receipts","tier":"observational","source_ids":["s1"],"why_material":"the acceptance condition of the whole feature"},{"id":"c2","text":"Claude Web, handed only the state handle state://lyb1m6yseu, recovered GATEWAY_LIVE_OK without a human copying text between tabs (receipt inv_mo6pgi8yxm).","section":"The live tests, with receipts","tier":"observational","source_ids":["s2"],"why_material":"proves cross-vendor handoff through shared state"},{"id":"c3","text":"ChatGPT Web called the Directory capability QUAKE_FEED by emitting a text tag through WEBMODEL_AGENT, with no MCP, connector or credential given to the vendor (receipt inv_uwnn7ketmh).","section":"The live tests, with receipts","tier":"observational","source_ids":["s3"],"why_material":"proves the reverse direction: a web model operating the build"},{"id":"c4","text":"A ledger row for a completed browser turn fired an ordinary event automation (automation 34, receipt inv_guxgetocb7).","section":"The live tests, with receipts","tier":"observational","source_ids":["s4"],"why_material":"proves event participation without browser-specific code"},{"id":"c5","text":"FLOW_LEARN compiled two hand-done receipts into the executable flow row QUAKE_REGION_1BV5, which then ran as a capability (receipt inv_0benrtdq4x).","section":"The live tests, with receipts","tier":"observational","source_ids":["s5"],"why_material":"the learned-flow claim rests on it"},{"id":"c6","text":"A valid token bound to one device was refused DEVICE_NOT_APPROVED from a second device and DEVICE_REVOKED after revocation while CAP_EXPLAIN still reported the token live.","section":"The live tests, with receipts","tier":"observational","source_ids":["s6"],"why_material":"proves authority and context are evaluated separately"},{"id":"c7","text":"mcp-web-llm exposes six logged-in web models as MCP tools with DOM stability polling and no session object, and its README states its memory feature was rolled back.","section":"What existing projects already solve","tier":"definition","source_ids":["s7"],"why_material":"establishes the precedent being compared against"},{"id":"c8","text":"OpenClaw self-learning persists natural-language SKILL.md instructions that a later agent re-reads and reasons through; no learning path consumes its trajectory recorder.","section":"What OpenClaw does with skills and self-learning","tier":"definition","source_ids":["s8"],"why_material":"the skill-versus-flow distinction depends on it"},{"id":"c9","text":"Multi-line prompts typed with the Enter key were submitted after their first line by every provider composer, which is why the first Claude handoff received a briefing with no task.","section":"What failed during implementation","tier":"observational","source_ids":["s9"],"why_material":"the most consequential implementation failure, now fixed"}],"sources":[{"id":"s1","url":"https://miscsubjects.com/api/dispatch?confirm=inv_rclmphgk7z","title":"Receipt inv_rclmphgk7z, CHATGPT_WEB","quote":"CHATGPT_WEB produced material output at 2026-09-06T11:48:31-07:00."},{"id":"s2","url":"https://miscsubjects.com/api/dispatch?confirm=inv_mo6pgi8yxm","title":"Receipt inv_mo6pgi8yxm, Claude Web via shared state","quote":"WEBMODEL_SEND produced material output at 2026-09-06T11:48:02-07:00."},{"id":"s3","url":"https://miscsubjects.com/receipt/inv_uwnn7ketmh","title":"Receipt inv_uwnn7ketmh, WEBMODEL_AGENT relay","quote":"The most recent magnitude-4-or-greater earthquake was 91 km south of Nikolski, Alaska, with a magnitude of 4.0."},{"id":"s4","url":"https://miscsubjects.com/api/dispatch?confirm=inv_guxgetocb7","title":"Receipt inv_guxgetocb7, automation fired by a browser turn","quote":"NOW produced material output at 2026-09-06T11:48:06-07:00."},{"id":"s5","url":"https://miscsubjects.com/receipt/inv_0benrtdq4x","title":"Receipt inv_0benrtdq4x, learned flow QUAKE_REGION_1BV5","quote":"The southern East Pacific Rise isn't in any country"},{"id":"s6","url":"https://miscsubjects.com/receipt/inv_f8uy3uac3t","title":"Receipt inv_f8uy3uac3t, DEVICE_REVOKE","quote":"every capability context bound to this device now denies with DEVICE_REVOKED"},{"id":"s7","url":"https://github.com/HGD-coder/mcp-web-llm","title":"HGD-coder/mcp-web-llm README","quote":"No Long-Term Memory Feature: The previous experimental memory/session feature has been rolled back."},{"id":"s8","url":"https://github.com/openclaw/openclaw/blob/main/docs/tools/self-learning.md","title":"OpenClaw docs: self-learning","quote":"Capture a verified recovery, a standing user requirement for this class of task, or a stable procedure that saves at least two future model round trips."},{"id":"s9","url":"https://miscsubjects.com/api/dispatch?confirm=inv_0hrhns715v","title":"Receipt inv_0hrhns715v, Claude handoff before the typing fix","quote":"WEBMODEL_SEND produced material output at 2026-09-06T11:35:01-07:00."}],"prov":{"model":"unattributed","action":"write"}}