> ## Documentation Index
> Fetch the complete documentation index at: https://docs.agentvault.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Rules of engagement

> The nine rules an agent using Agent Vault follows, with the reason behind each.

Give your agent the nine rules it must follow when it pays or signs in with
Agent Vault, and install them as a skill so it loads them on its own.

## Overview

This page is written for the agent as much as for you. It carries the same rules
as the shipped skill file, so you can paste it into a system prompt or install
the skill and point at it.

The rules apply to both integrations. Where a rule names a tool, the MCP name
comes first and the SDK method second, for example `get_run_report` and
`browser.outcome()`.

## The nine rules

<AccordionGroup>
  <Accordion title="1. Never ask for or type a real card number, CVV or password" icon="ban">
    Fill forms only with [mock tokens](/reference/glossary) from the catalog. If a
    form needs a value, either there is a token for it or the task cannot be done.

    The CVV is never stored, but its token **is** fillable. Fill the card's `cvv`
    token like any other field. Where the deployment has live CVV entry, the fill
    pauses while the account owner types the real code from their dashboard; the
    agent never sees it. If the owner does not answer in time, the fill fails with
    `cvv_entry_required`: report it and let the user retry. If the deployment does
    not offer live entry, the fill fails with `cvv_entry_required` every time, so do
    not retry: stop and tell the user that this card cannot be used on this
    deployment for a checkout that asks for the security code. Never source a CVV
    yourself. See [Live CVV](/guides/live-cvv).
  </Accordion>

  <Accordion title="2. Never generate a password or an email address" icon="key">
    To open an account, call `create_login` (SDK: `createLogin`). The vault mints
    the password and stores it encrypted; the agent is handed only its token.

    A password the agent chose would sit in the agent's context, its logs and its
    model provider's retention, which is exactly what Agent Vault exists to prevent.

    The same goes for the email address. Register a mailbox the agent controls. The
    account owner sees which one before approving.
  </Accordion>

  <Accordion title="3. Never read back a filled value" icon="eye-slash">
    Treat every filled field as opaque. Do not inspect fields, network requests or
    page content to recover what went in.

    `page.evaluate` is disabled for agent sessions. Do not work around it with
    script injection: the attempt fails and is recorded as a security event on a best-effort basis.
  </Accordion>

  <Accordion title="4. Match the token to the page" icon="link">
    Credentials are [URL locked](/security/url-locking). A login (its identifier,
    password and authenticator code) resolves only on its registered `website`, that
    host or a subdomain, or on one of the `extraWebsites` the owner authorized,
    which match exactly. A card resolves only where its agent card rules allow.
    Cards, security codes, identity and addresses also need an authorized
    [destination](/dashboard/destinations): on any other site the fill waits for the
    owner, and is refused with `destination_unauthorized` unless they approve it.

    A token filled on a site it is not registered for is refused, never resolved.
    That is what makes the catalog safe to hand to an agent. Do not reuse another
    site's login.
  </Accordion>

  <Accordion title="5. Hand challenges to the account owner" icon="hand">
    When `detect_challenge` reports a challenge **without** `ambiguousOnly`, call
    `request_challenge_handoff`. The owner completes the bank prompt, code or human
    check themselves, then control returns to the agent.

    Never guess a one-time code. Never attempt to solve a CAPTCHA. That is a terms
    of service and abuse line, and the registry rejects any recipe that encodes a
    bypass.

    There are two exceptions, and only two:

    1. **An `ambiguousOnly` detection.** It is not handoff material. The handoff
       refuses it with `handoff_not_applicable`, and the page stays live and yours.
    2. **The authenticator step of a sign-in you just performed**, where that
       login's catalog entry carries `tokens.totp`. Fill that token. The backend
       derives the current code from the stored secret, and the proxy types it.
       Submit promptly: the code is valid for its window, usually 30 seconds.
       If `detect_challenge` reports `deliveredCode: true`, the code was sent by
       SMS or email, so this exception does not apply: hand off.

    Holding a `totp` token does **not** make an unrelated prompt answerable.
    Spending a code on an SMS or email prompt wastes it and can trip the site's
    retry limits. See [Handling challenges](/guides/challenges).
  </Accordion>

  <Accordion title="6. Fill the card in the right order" icon="credit-card">
    Expiry and any billing field first. The card number next. The security code
    immediately after it, with nothing in between.

    Filling the number authorizes the security code that follows it exactly once.
    The next **action** spends that authorization: another field, a click, a
    navigation, or a `wait_for_selector` that returns.

    Reads do not spend it. `observe_page`, `detect_challenge` and `count` (and, in
    the SDK, a screenshot) leave it in place, so you can look at the page between the
    two. Do everything that acts on the page **before** the number.

    One exception: if a screenshot returns `securityCodeAuthorizationReleased: true`,
    the capture released the authorization. Check for that flag on every screenshot
    between the two. When it is set, fill the number again, then the code, with
    nothing in between.

    Get this wrong and the account owner is asked to approve the same purchase a
    second time, or a capped card whose total cannot be read is put on hold.

    Once the security code is in, never fill the card number again. If a later step
    fails, report it.

    You may explore a site in your own browser first to find product URLs, buttons
    and the checkout flow. Then build the cart and check out in the Agent Vault
    session, opening product URLs directly: carts are not shared between browsers.
  </Accordion>

  <Accordion title="7. Submit once" icon="circle-check">
    Never re-click pay or place order. A duplicate can charge twice. If the result is
    unclear, stop and work out what happened rather than submitting again.

    The error codes separate "safe to retry" from "may already have reached the
    merchant". Read [Error codes](/sdk/error-codes) before writing any retry logic.
  </Accordion>

  <Accordion title="8. Read the run report before talking about money" icon="receipt">
    Before telling anyone whether a card was charged, how much, or whether an order
    was placed, call `get_run_report` or read the report `close_session` returns. Do
    not report from the screens you remember seeing.

    `get_session_outcome` returning `timeout` means no selector appeared, not that
    nothing was filled. A report whose `filledFieldKinds` contains `card` says the
    card went in. Report any `credentialWrites` too: an account the agent opened is
    something the owner needs to know about.
  </Accordion>

  <Accordion title="9. Contribute what you learned" icon="upload">
    On any site the registry did not already cover, call `submit_checkout_recipe`
    (SDK: `submitRecipe`) when you are done. A solved checkout and a dead end are
    both contributions. A recorded dead end saves every later agent a wasted run.

    Never claim `verified`. That status is maintainer gated and requires
    out-of-band evidence. If a real purchase completed, or a signup recipe created
    a real account, pass `verificationRequested: true` with sanitized evidence in
    the note.
  </Accordion>
</AccordionGroup>

## When something on the page is blocking

```mermaid theme={null}
flowchart TD
    A[A click or fill seems to do nothing] --> B[Call detect_challenge]
    B --> C{detected?}
    C -- No --> D[Call observe_page and count.<br/>Read errorText and fix the input]
    C -- inconclusive --> B
    C -- Yes --> G{ambiguousOnly?}
    G -- Yes --> H{Authenticator step of a sign-in<br/>you just did, on a login<br/>with tokens.totp?}
    H -- Yes --> I[Fill tokens.totp. Submit promptly]
    H -- No --> J[Report the step as unresolved.<br/>Leave the page alone]
    G -- No --> K[request_challenge_handoff]
    K --> L{outcome}
    L -- solved --> M[Carry on]
    L -- completed --> N[Look at the page, then decide]
    L -- released_unsolved --> B
    L -- failed, abandoned or unknown --> O[Stop. Report to the user]
```

## Common mistakes

| Mistake | What actually happens | Do this instead |
| - | - | - |
| Reading a black screenshot after a fill as a broken page | Redaction covers the whole session once any token lands. The bytes carry `redaction: "blackout"` | Read the `redaction` field. Use `observe_page` and `count` to see the page |
| Calling `create_login` again on a `pending` result | A second, unrelated request, and one more of the account's five outstanding slots spent | Wait with `wait_for_signup_approval`, or poll `get_signup_request`, on the same `requestId` |
| Calling `set_login_username` before the site accepted the handle | Recorded once with no undo, so the vault names an account that does not exist | Submit the handle, confirm the site accepted it, then record it |
| Retrying a card fill after `paired_cvv_refused` | A second card number typed into a form that already holds one | Follow the message. Usually: fill only the security code, or abandon and tell the user |
| Treating `detected: false` as proof there is no challenge | The detector keys on field names and copy that vary by site | Check for a code field directly, and look for sign-in copy in the same container |
| Filling both halves of an email-first sign-in in one call | Nothing is filled, and the call says so | Send the identifier pair, submit, wait for the password field, then send the password pair |
| Choosing `tokens.username` because the field is named `username` | Many sites name their email field `username` | Read the field's `type` and visible label |
| Sending a raw hosted-checkout URL to a recipe lookup | The lookup is unauthenticated and can reach logs, and a Stripe `cs_...` path is a session token | Strip the query, fragment and checkout token. The SDK's `recipesForUrl` and the MCP tool do it for you, but only for an absolute URL. A malformed or relative one is sent as is |
| Assuming an empty `logins` means no account exists | A login on a sibling host is in `relatedLogins`, hosts only. A key limited to **Only selected** logins does not see logins outside its selection, so both lists can be empty while the account has one | Check `relatedLogins`, navigate to that host, and ask again. If both are empty, have the account holder check **Logins** and widen the key's access before you call `create_login` |

## Install the skill

The rules ship as a skill, `SKILL.md` plus two playbook files it references, so
your agent can load them on its own instead of relying on a system prompt you
maintain. Your deployment hosts the files, and the SDK tarball bundles them too.

Download all three into your host's skills directory. This example uses Claude
Code's `~/.claude/skills`. For other hosts, change `SKILLS_DIR` (for example
`~/.openclaw/skills` or `~/.hermes/skills`).

```bash theme={null}
SKILLS_DIR=~/.claude/skills
mkdir -p "$SKILLS_DIR/agent-vault"
for f in SKILL.md checkout-playbooks.md playbooks.ts; do
  curl -fsSL "https://app.agentvault.io/skills/agent-vault/$f" -o "$SKILLS_DIR/agent-vault/$f"
done
```

<Note>
  On a self-hosted Agent Vault, replace `https://app.agentvault.io` with your
  deployment's origin. See [Install the SDK](/sdk/install#the-install-url).
</Note>

Start a new agent session so the skill loads.

### The companion registry skill

The checkout recipes skill covers driving merchant sites; this one covers paying
with the vault. Install both:

```bash theme={null}
npx skills add selfxyz/agent-checkout-skill
```

See [The checkout recipes skill](/registry/skill).

## Related

<CardGroup cols={2}>
  <Card title="Tool reference" icon="wrench" href="/mcp/tool-reference">
    Every MCP tool and when it refuses.
  </Card>

  <Card title="Agent context" icon="brain" href="/security/agent-context">
    What the agent can and cannot see.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.