Websites request work; users own execution.
EZAF
A local protocol-handler layer for reviewing website-launched agent requests, routing them to the user's preferred model or backend, and releasing results through explicit continuations.

The local app chooses model, backend, and tools from user config.
Results are released through explicit continuations, not silent exfiltration.
The smallest useful protocol surface.
Invocation link
A website creates a protocol-handler URL that points at a fetchable request manifest.
Request manifest
The request declares prompt, inputs, capabilities, callback, state nonce, and expiry.
Local review
The user inspects origin, tools, backend, and prompt before the agent does any work.
Continuation
Approved output returns through a callback, browser extension handoff, or local rendezvous handle.
Craft a reviewable `ezaf://` request.
Manifest fetched by the local app.
{
"version": "ezaf/0.1",
"action": "run",
"request": {
"prompt": "Summarize this article and return three action items.",
"inputs": [
{
"type": "url",
"url": "https://example.com/article"
}
],
"capabilities": [
"generate_text",
"read_url",
"send_callback"
],
"output_schema": "text/markdown"
},
"continuation": {
"mode": "https_callback",
"url": "https://example.com/ezaf/callback",
"state": "site_nonce_7jd92",
"accepts": [
"application/json"
]
},
"expires_at": "2026-06-04T22:00:00Z"
}What the opener gets back.
User approved request review
Local route selected: user configured backend
Result ready for release approval
Callback POST returned 202
Origin-bound requests with human release gates.
Review before run
Origin, prompt, inputs, capabilities, backend, and callback are visible before execution.
Approve before send
Generated output is shown locally before the app posts, opens, or streams a continuation.
Bind callback origin
Default policy keeps callback destinations on the requesting origin unless the user approves otherwise.
The extension makes continuations feel native.
Protocol links can launch the local app by themselves. A browser extension closes the loop: it tracks the initiating tab, brokers same-origin callback state, receives progress events, and helps put approved results back where the request started.
The extension records tab, origin, manifest URL, and nonce before handoff.
The local app emits accepted, running, completed, and release-pending events.
The extension posts, fills, or resumes the web flow after explicit approval.
Start boring: manifests, capabilities, continuations.
The durable primitive is not a prompt URL. It is a signed or fetchable request manifest with an explicit continuation contract.
generate_textLow-risk model output shaped by an explicit prompt.
read_urlFetch declared web inputs after user review.
create_patchPrepare a code change without applying it silently.
send_callbackReturn approved outputs to the requesting origin.
POST /ezaf/callback
{
"ezaf_version": "0.1",
"request_id": "req_123",
"state": "site_nonce_7jd92",
"status": "completed",
"outputs": [
{
"type": "text",
"name": "answer",
"content": "Approved result..."
}
]
}Trust moves from prompts to provenance.
Browser extension
Keeps the opener page connected, receives local completion events, and can place approved output back into the initiating tab.
Signed intents
Lets a local app verify that a manifest was issued by a trusted origin or known publisher key.
Trust registry
Maps origins, keys, callbacks, and capability defaults into a user-editable policy layer.