Markers
The six data-guide attributes, what each one does, and exactly what the action guard checks before Docent clicks, fills or submits anything.
Six attributes, written on your own elements. They are the whole annotation surface.
| Attribute | Value | What it does |
|---|---|---|
data-guide | a stable name | Names an element so the guide can point at it by name rather than by guessing. |
data-guide-allow | click, fill, submit, space separated | Grants the guide permission to act on this element. Nothing is actable without it. |
data-guide-mask | none | Keeps this subtree out of every snapshot. Its accessible names are replaced before anything leaves the browser. |
data-guide-readable | none | Re-exposes one element inside a mask, so a plan name can be readable inside a masked account panel. |
data-guide-forbid | none | Makes this element and everything inside it permanently untouchable. |
data-guide-primary | none | Marks your main call to action. The mascot treats it as a keep-out area when it picks a corner. |
data-guide
<button data-guide="create-project">New project</button>Anchors resolve in one order and only this order, and each way of finding one carries its own confidence:
| How it matched | Confidence |
|---|---|
data-guide | 1 |
| Accessibility role plus an exact name | 0.9 |
| Accessibility role plus a partial name | 0.7 |
| Visible text | 0.6 |
| Position alone | 0.4 |
The default threshold is 0.6, and a resolution below it is refused. So a text match sits exactly at the threshold and is the weakest one that passes, and a position-only match is always refused at the default. A refusal is not silence: the tool hands back a description of where the thing is, so the guide says "the button below the account panel" rather than pointing at the wrong element.
act is stricter again. It resolves at Math.max(threshold, 0.6), so it never touches anything
found by position, and raising the threshold raises it for acting too.
The name is also what the analytics record. Only this token is ever reported for a pointing hit or miss, never an accessible name, because a name is page text.
data-guide-allow
<button data-guide="dark-mode" data-guide-allow="click">Dark mode</button>
<input data-guide="project-name" data-guide-allow="fill" />
<button type="submit" data-guide="save" data-guide-allow="submit">Save project</button>The grant is per action. click lets the guide press. fill lets it type into a text input, a
textarea or a contenteditable element, and nothing else. submit is the grant to submit the
form the element belongs to.
submit is not implied by click. Pressing a button and submitting a form are different
promises to make about an app, and a host that wrote click on a button that happens to be
type="submit" has not made the second one. The reverse does hold: a submit grant is also the
grant to press the button carrying it, so data-guide-allow="submit" on its own is enough for a
save button.
data-guide-mask and data-guide-readable
<section data-guide-mask>
<p>alex@acme.com</p>
<p data-guide-readable>Plan: Growth</p>
</section>A masked element's accessible name is replaced with a placeholder in the snapshot, and the node
is flagged as masked. The mask travels through labels too: an element that draws its name from an
aria-labelledby target, an explicit label, or a wrapping label inside a mask is masked as
well.
data-guide-readable re-exposes an element inside a mask. It has to be inside the masked
subtree to mean anything.
Three things are true of masking regardless of what you mark:
- Input values are never captured at all. The snapshot carries roles, accessible names, states, rectangles and the route, and no field contents.
- Email addresses, card numbers and phone numbers are replaced wherever they appear, including in the route and its query string.
- Masking fails closed. If the masker throws, the capture returns nothing and nothing is sent.
data-guide-forbid
<button data-guide-forbid>Delete workspace</button>Every action on this element and everything inside it is refused, whatever else the element
carries. It is checked before the allowlist, so a data-guide-allow on the same element does not
override it.
data-guide-primary
<a data-guide-primary href="/projects/new">Start a project</a>The mascot treats these as keep-out rectangles and places itself away from them. It is the attribute to write on the one control on the page you least want covered.
What the guard checks
The action guard runs in the browser, on every act, before anything touches your page, and it
cannot be switched off by configuration. In order:
- The element is inside the Docent overlay itself. Refused.
- The element or an ancestor carries
data-guide-forbid. Refused. - The action is
click, and pressing the element would submit a form, and the element does not carrysubmitin itsdata-guide-allow. Refused. - The action is
click, and the element's accessible name or text matches the destructive pattern: buy, pay, purchase, checkout, order now, subscribe, upgrade, delete, remove, destroy, erase, wipe, cancel subscription, cancel account, cancel plan, unsubscribe, transfer, withdraw, send money, confirm purchase. Refused. This is checked after the submit grant on purpose: opting a form in must not become a way to reach "Delete account". - The action is
fill, and the element is not a textarea, a text-like input or acontenteditable. Refused as unsupported. Checkboxes, radios, files, colours, ranges and hidden inputs are not fillable. - The element does not carry the grant for this action. Refused.
- The user did not ask for this in the current turn. Refused.
A refusal is returned to the model as a reason it can read and say out loud, not as a silent failure. Docent guides by default: it spotlights, points, scrolls and navigates with no annotation at all, and the attributes above are only about acting.
The Docent component
Every prop of the Docent component with its type and default, the hooks it provides, the events it emits, and the handle it puts on React context.
CLI
The Docent CLI. sync uploads routes and Markdown knowledge, crawl reads a docs site, with every flag, every limit and what each command prints.
