Open a session and read what it reached
Driving a browser and observing one are different jobs. This guide does both in one sitting: act on a page by handle, then read back the decision record the engine wrote as it went.
A session is the whole agent-facing surface: one page state, one cookie jar, one request log, one policy. open makes one, every verb that follows acts on it, close ends it. You do not type a session id: the opaque one in --json and in the receipts is a durable reference, not an interface. Nothing else is a concept the agent has to learn, which is what lets the placement change later without changing a single command.
1. Open a session
$ h5i browser open https://docs.rs/ --allow docs.rsRead the two lines it prints back before anything else. The placement line says where this session runs, and the requests line says who saw its network. Both are printed on every status afterwards, so you never have to infer either.
placed : this machine (no containment beyond the engine)
requests : engine-claimed (fail-closed, and the engine's own account of what it fetched)That first line is the honest one. A session started this way is not sandboxed, and h5i says so rather than letting the word browser imply a boundary. What you get without one is the record.
2. Read the page the way a model reads it
$ h5i browser snapshotWhat comes back is an outline with @ref handles rather than pixels or raw HTML: headings, paragraphs, and the things that can be acted on, each with a handle to act on it by. It arrives inside a fence marking everything within as page content, which is the difference between text the model treats as information and text it treats as an instruction.
Two things are stripped on the way through, both because the page composed them. Escape sequences never survive: ESC in a page title is a page repainting the terminal it is printed into, and nothing a browser has to say needs one. Long values are capped with the truncation stated in the value, because an answer silently shortened is one an agent reasons about as if it were complete.
3. Act by handle, not by guess
$ h5i browser click @e3
$ h5i browser snapshot --delta
$ h5i browser type @e5 "serde"
$ h5i browser submit @e5Use --delta once the loop is running. Re-reading three hundred lines after every click is the wrong shape for an agent, and when the page has changed too much for a difference to be the shorter answer the full outline arrives instead and the reply says which it is.
A handle from a reading the page has moved on from is refused rather than resolved against whatever now sits in that position. That refusal is the feature: a mis-click on a page that changed underneath is the failure that is hardest to see afterwards.
4. Watch a request get refused
The session was started with one origin allowed. Follow a link that leaves it.
$ h5i browser click @e9
denied by policy: origin `https://tracker.example` is not in the allowlistRedirects are checked at every hop, so a server cannot route the session out of its allowlist by answering with a 302. The refusal is an answer with a reason, not a silent no-op, and it is in the log.
5. Read back what it reached
$ h5i browser requestsThis is the part that is different. The engine is the HTTP client, so this list is a decision record it wrote before the bytes moved rather than a trace assembled beside the network. The order is fixed: check the policy, write the record, then touch the wire. When the record cannot be written, the fetch is refused.
Two consequences worth stating plainly. A request that is not in this list did not happen. And a denied request is in the list, with its reason, so the log shows what was attempted and not only what succeeded.
Pass the cursor from a previous answer back as --since to see only what is new, the same way --delta works on a snapshot.
6. Read the whole session back
requests is the network layer, and the verb to poll inside a loop. When you are writing up what happened, read the timeline instead.
$ h5i browser auditIt merges three sources: the verbs you asked for, the decision the engine made about every fetch, and the moments a human took the controls. Ordered across all of them, so the question a review actually asks — was a person driving when that form was submitted — has an answer. A current-holder field cannot give one.
Every row says which lane it came from. The engine’s rows are its own account of itself; the handovers and the ending are h5i’s, written from outside. They are printed apart because a claim rendered as an observation is the one error this product cannot afford.
Read the sources line before the rows. Each log is read, empty, or unavailable. An empty timeline over a log h5i could not see looks exactly like a session that did nothing, and those are different findings.
7. End it, and keep the record
$ h5i browser close
$ h5i browser list --allClosing writes the ending into the session's record instead of deleting it, which is what makes “how did this end” answerable afterwards and what makes the id impossible to reuse. The states are closed, died, expired and evicted, and they are kept apart because they are different facts about the run.
Send a verb to a session that is not live and it is refused with exit code 69 rather than silently restarted. That distinct code is the point of the design: an agent whose retry cannot tell “the session is gone” from “the click did not work” quietly starts a second browser and loses both the page it was reasoning about and the record of losing it.
8. When you want a boundary too
$ h5i box --profile browser --engine h5i --name web
$ h5i browser open https://example.com --in webEvery verb above works unchanged. What changes is the requests line: the box enforces its egress allowlist at its own boundary, outside the browser being described, so the lane goes from engine-claimed to host-observed.
Being inside a box does not earn that on its own. A box whose policy lets the browser reach the whole network corroborates nothing, and h5i keeps calling that session engine-claimed. What earns the upgrade is enforcement outside the engine.
Reference
- The session reference: verbs, states, and where sessions live.
- Watch the page, then take the controls.
- Why browser authority changes the injection threat model.
- The engine implementation.
Questions that come up
Is the session sandboxed?
What does engine-claimed mean?
What happens if the browser dies mid-task?
Does the engine run page JavaScript?
Watch the page, then take the controls
Put the browser beside the dev server and hand control between agent and human.
Open a session in one command
No project, no repository, no configuration. h5i browser open takes a URL and gives you an id.