# Browser Control extension

## 1. Introduction

Some steps on a Company's website are ones the Company wants the User to take themselves, such as checking in for a flight. With this extension, the Company marks those steps in its pages, to indicate to the Personal Agent that the User should take them:

1. The Personal Agent browses the website in a browser joined to a Session ([spec 6](/docs/0.4/spec#web-browsing)). It reads a marked step and prepares what the mark allows, but leaves the step to the User (4).
2. It tells the User that the step is theirs and offers them control of the browser. While the User holds control, the Personal Agent's model doesn't use the browser (5).
3. The User takes the step. The page can read who controls the browser from `navigator.poppy.controller` and send it with the request (6).
4. The User hands control back, and the Personal Agent continues.

Marks signal what the Company wants, and a Personal Agent that follows this extension honors them. `navigator.poppy.controller` should be correct, but a Company shouldn't use it as a guarantee that the User took a step. The Company still enforces its own rules on its servers (8).

Where it fits, the [Operations extension](/docs/0.4/extensions/operations) gives the User a better experience (2).

This page defines version 1 of the `browser-control` extension. It uses the terms and Sessions in the [specification](/docs/0.4/spec).

## 2. Browser control and Operations

Both extensions let a Company involve the User in an action, in different ways:

|  | Operations | Browser control |
| --- | --- | --- |
| Who takes the step | The Personal Agent, once the terms are approved | The User, in the Personal Agent's browser |
| What the User does | Approves the terms in the Personal Agent's own interface, or gives the Personal Agent an instruction that covers them | Takes over the browser and uses the Company's page |
| Interfaces | APIs, MCP servers, conversations, and websites | Websites only, in a browser joined to a Session |
| What the Company receives | An approval of one revision of the terms, which says whether the User or the Personal Agent approved, in a request signed for the Session | A `controller` value, if the page sends it, which isn't signed |
| Repeated requests | Performed at most once | As the website handles them |

Operations is the better experience for the User when it fits. The User approves in the place they already talk to their Personal Agent, such as with a tap on their phone, without finding a browser window and learning the Company's page, or doesn't need to be asked at all when an instruction they gave covers the terms ([Operations 5](/docs/0.4/extensions/operations#approval)). The Personal Agent finishes the action, so the task doesn't wait on the User any longer than the approval. The Company gets more, too: an approval of exact terms, tied to the Session and, when signed in, the access token, and an action performed at most once ([Operations 1](/docs/0.4/extensions/operations#intro)).

A Company SHOULD use Operations for an action that it can describe as terms to approve. Browser control fits steps that Operations doesn't:

- **Steps that are the User's to perform, not to approve.** The Company wants the User to make the choice on its page, such as picking from options the page shows, rather than approving a choice the Personal Agent made.
- **Input the Personal Agent shouldn't handle.** The User types something into the page, such as passport details at check-in, so the Personal Agent doesn't need to collect it.
- **Requests the website can't repeat.** Operations on a website needs the browser to make the request again after the approval, and an action guarded by a single-use form token, for example, can't be ([Operations 4](/docs/0.4/extensions/operations#approval-required)).
- **Websites without Operations yet.** Marking steps needs no endpoint and no change to how the website handles requests.

A Company MAY use both for the same action, such as browser control for the User to check in for a flight and Operations for the User to approve the price of a paid seat.

## 3. Advertising support

A Company that supports this extension lists it in `extensions` in its `poppy.json` ([spec 3.3](/docs/0.4/spec#extensions)), with `web.browser_session_endpoint` ([spec 6](/docs/0.4/spec#web-browsing)):

*Excerpt from poppy.json*

```
"extensions": {
  "browser-control": [{ "version": "1" }]
}
```

A Personal Agent that supports this extension declares it in `Poppy-Extensions` ([spec 3.4](/docs/0.4/spec#versions)):

*Request header: Personal Agent → Company*

```
Poppy-Extensions: "browser-control";v="1"
```

A browser's requests declare the extensions that step 2 of its browser join declared. Support means that the Personal Agent leaves marked steps to the User (4), hands control to the User (5), and provides `navigator.poppy.controller` (6).

A Personal Agent that doesn't declare this version may not read the marks at all. For its browser, the Company handles the step as it would without the extension.

## 4. Marking steps

The Company marks a step with the `data-poppy-user-step` attribute:

| `data-poppy-user-step` | On | The Personal Agent's browser |
| --- | --- | --- |
| `interaction` | A control | Can read it. Leaves changing or activating it to the User. |
| `interaction` | A form | Can read it. Leaves its controls, and submitting it, to the User. |
| `submission` | A form | Can fill in its controls, unless other marks say not to. Leaves submitting it to the User. |

*A control for the User to fill in*

```
<label>
  Passport number
  <input name="passport_number" data-poppy-user-step="interaction" />
</label>
```

*A form for the User to submit*

```
<form action="/bookings/bkg_4Rt9/check-in" method="post" data-poppy-user-step="submission">
  <label>Seat <select name="seat">…</select></label>
  <button type="submit">Check in</button>
</form>
```

- A form's controls are the ones it owns in HTML, including controls outside it that name it in their `form` attribute.
- Marks add up. A control inside a `submission` form can also be marked `interaction`. A marked control doesn't mark the rest of its form.
- A value other than `interaction` or `submission`, or `submission` on anything but a form, counts as `interaction`.

The Company SHOULD mark every control that performs the step, or the form it is in, and SHOULD mark them before they can be used. The Company SHOULD NOT let filling in a `submission` form perform the step itself. Whatever it marks, the Company's servers MUST check the action's conditions themselves, because marks don't stop anything (8.1).

## 5. Handing control to the User

A Personal Agent that declares this extension SHOULD NOT take a marked step: change or activate a control that a mark covers, or submit a form that a mark covers, whether with a click, a key press, an accessibility action, a script, or a WebMCP tool. It SHOULD NOT remove or change marks to get around them.

When it reaches a marked step, the Personal Agent tells the User which step is theirs and offers them control of the browser. It MAY instead leave the step undone and continue with other work. What the page says about the step is content from the Company ([spec 10.1](/docs/0.4/spec#untrusted-content)).

While the User holds control:

- The Personal Agent's software MUST NOT carry out browser actions from its model. The website's own scripts keep running.
- Only the User ends their control, by handing it back or cancelling. A timeout, a change to the page's marks, or anything the Company sends MUST NOT end it.
- The Personal Agent MUST NOT keep its own requests, or its conversation with the User, waiting until the User acts.

When the User hands control back, the Personal Agent looks at the page again before it continues.

## 6. Who controls the browser

On pages of the Company's website, in a browser joined to a Session that declared this version, the Personal Agent's software provides `navigator.poppy.controller`, a read-only string:

- `"user"` while the User holds control (5).
- `"agent"` otherwise.

The page reads it when it needs it, such as when a marked button is pressed, and MAY send it to the Company with the request:

*Page script*

```
form.elements.controller.value = navigator.poppy?.controller ?? "";
```

In a browser without the extension, `navigator.poppy` is undefined. The Personal Agent's software, not its model, sets the value, and changes it as soon as control changes. It provides `navigator.poppy` only on the Company's website, on the hosts of `organization.domain` and its subdomains ([spec 3.1](/docs/0.4/spec#fields)), so other websites can't tell that the browser is a Personal Agent's.

The value should be correct, but it isn't a guarantee (8.2). A Company MAY record it with the action, or use it to choose what its page does, such as showing "This step is for you to complete" when it reads `"agent"`. It MUST NOT rely on `"user"` as a guarantee that the User took the step.

## 7. Example

The User asks their Personal Agent to check them in for their flight tomorrow, in an aisle seat. The airline's check-in form is marked `submission`:

1. The Personal Agent's browser opens the booking and chooses an aisle seat, which the mark allows.
2. It doesn't press Check in. It tells the User that the airline asks them to check in themselves, and offers them control.
3. The User takes control and presses Check in. The page reads `navigator.poppy.controller`, which is `"user"`, and posts the form with it in a hidden field.
4. The airline records the value with the check-in and checks the User in.
5. The User hands control back. The Personal Agent reads the confirmation page and tells the User their boarding pass is ready.

Had the Personal Agent pressed Check in itself, the page would have read `"agent"`. The airline decides what to do then, such as asking the User to take the step.

## 8. Security considerations

### 8.1 Marks are signals

A mark asks the Personal Agent to leave a step to the User. It doesn't stop a Personal Agent that doesn't support this extension, or one that ignores it. The Company's servers decide whether an action is allowed, whatever the page marks.

### 8.2 The controller isn't a guarantee

A Personal Agent that follows this extension sets `navigator.poppy.controller` correctly. But the value isn't signed, and anything that runs in the page can change what the page reads, including the website's own scripts, third-party ones, and a Personal Agent that doesn't follow this extension. A value sent to the Company passes through the page, so it can be changed on the way too. The value tells the Company what a Personal Agent that follows this extension says about who controlled the browser. It doesn't show that the User took a step, saw what the page showed, or caused a particular request.

### 8.3 The User in the Personal Agent's browser

The specification forbids joining the User's own browser to a Session, so that the Company doesn't treat the User's own visits as the Personal Agent's ([spec 6](/docs/0.4/spec#web-browsing)). Handing control to the User doesn't do that. The browser stays the Personal Agent's, and the User uses it through the Personal Agent for the length of the step. Its requests still belong to the Session, and `navigator.poppy.controller` tells the page who was in control when it read it.

## 9. References

This extension uses the [HTML Standard](https://html.spec.whatwg.org/multipage/forms.html#form-owner) for form owners.

---

Licensed under the [Apache License 2.0](https://personalagentprotocol.org/license).
