Agent → browser push contracts
A “push contract” is the formal specification of what a
browser-driving agent (chrome-mcp, playwright-mcp, or any tool
that can execute JS in the page) sends into /ops/* via the
shared window.aegis.* namespace, and what the page does with
it.
There are two contracts today. Both ride the same transport
(evaluate_script → window.aegis.<method>(payload) → localStorage
→ custom event → page re-render), differ in payload shape, and
target different /ops/* surfaces.
| Maker Asset Review | Plugin Push | |
|---|---|---|
| Push method | window.aegis.importMakerStats(snapshot) | window.aegis.publishPlugin(pkg) + activate / deactivate / rollback |
| Payload | MakerStatsSnapshot — 6-field weekly aggregate | SignedPluginPackage — manifest + digest |
| localStorage key | aegis.maker-stats.snapshot | aegis.plugins.registry |
| Event | aegis:maker-stats:updated | aegis:plugins:updated |
| Target surface | /ops/funnel-review | /ops/plugins |
| What the agent is summarizing / producing | weekly aggregate of espctl deposit list --json | a WASM plugin the agent just compiled locally |
| Frequency | every /ops/* visit (refresh-on-arrival) | on each new plugin compile + lifecycle action |
Both surfaces are browser-local — the data lives only in this browser’s localStorage, no server-side ledger, no upload, no cross-user visibility.
Shared substrate — window.aegis.*
Mounted on app boot, idempotent, available on every route:
// maker-stats contract
window.aegis.importMakerStats(snapshotJson | snapshotObject)
window.aegis.getMakerStats()
window.aegis.clearMakerStats()
// plugin contract
await window.aegis.publishPlugin(signedPluginPackage, actor?)
window.aegis.activatePlugin(pluginId, version, options?)
window.aegis.deactivatePlugin(pluginId, version, actor?)
window.aegis.rollbackPlugin(pluginId, version, actor?)
window.aegis.getPluginSnapshot()
window.aegis.clearPluginRegistry()
Both push methods validate input strictly and reject malformed
payloads with { ok: false, error: '<reason>' }. Successful
writes dispatch their corresponding aegis:*:updated custom
event so /ops pages re-render live.
Shared trust model
- Same-origin only. A
window.aegis.*call only writes to this origin’s localStorage. An agent driving a different origin sees / writes a different sandbox. - Agent is the publisher. No public-key signature, no CA.
Digest match (
crypto.subtle.digest('SHA-256', ...)) on the plugin path proves integrity, not authenticity — adequate because the publisher IS the maker’s own automation. - No shared registry. Two browsers on the same machine have independent snapshots and independent plugin registries.
Agent maintenance — refresh on every visit
This rule applies to both contracts. Treat localStorage as if
it were just cleared: cache may have been evicted under pressure,
the user may have cleared site data, or the tab may be opening in
a different browser. Before reading anything from /ops/*, push
fresh state via the relevant window.aegis.* method.
Full protocol (maker-stats variant) at
Weekly Maker Asset Review — Agent maintenance contract.
Plugin-push variant is symmetric — same evaluate_script flow,
different payload + different window.aegis.* method.
Pick which contract you need
- Pushing this week’s stats so
/ops/funnel-reviewrenders a Markdown work-report? → Maker Asset Review - Pushing a freshly-compiled WASM plugin so the next ESPCTL MCP / Build Lab compile loads it? → Plugin Push
Both pages are self-contained. Read whichever matches the task; neither depends on the other.