> For the complete documentation index, see [llms.txt](https://docs.getvenora.tech/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.getvenora.tech/runtime-architecture.md).

# Plugin runtime architecture

Status: the Phase 2.5 runtime, with Plugin API version 1 (Phase 3.2), plugin code in a worker (Phase 3.3), and resource limits (Phase 3.4). Every plugin, bundled or imported, runs in a sandbox and acts only through permission-checked capabilities.

This document describes how the runtime is built. The contract plugins rely on is the [Community Plugin API specification](/plugin-api.md).

## Summary

```
Fermo page (fermo.sbar.fyi)
 └─ Venora content script (isolated world, extension APIs)       ← Plugin Manager, trusted
     ├─ runtime/host.js          frames, lifecycle, timeouts
     ├─ runtime/capabilities.js  capability + event registry, permission checks
     ├─ runtime/plugin-storage.js  plugin-scoped storage: one entry and one queue per plugin, quotas
     ├─ runtime/resource-governor.js  per-plugin request, event, and in-flight limits; watchdog limits
     ├─ runtime/plugin-commands.js  commands registered by running plugins, per plugin
     ├─ runtime/secret-guard.js  blocks the session token in anything sent to plugins
     ├─ content.js services      trusted implementations (settings, notices, avatars, commands, CSS)
     ├─ Venora's UI              open shadow roots; dialogs and notices in the top layer
     └─ closed shadow root
         └─ <iframe sandbox="allow-scripts" src="runtime/sandbox.html#nonce">  ← one per plugin
             ├─ runtime/sandbox-boot.js    nonce handshake, then hands the port to the worker
             └─ dedicated worker (data: URL, inherits the sandbox CSP)
                 ├─ bridge.js + plugin-runtime.js   request/response, events, error capture
                 └─ plugin module (imported as a data: URL)                 ← untrusted
```

Every plugin has its own sandboxed extension page:

* the page has an opaque origin and no extension APIs;
* its content security policy blocks all network loads.

The page only performs the handshake; the plugin itself runs in a dedicated worker that the page creates.

* The worker has no window, document, or navigable location, so the plugin cannot touch any DOM or navigate its frame to send data out.
* It reaches Venora only through a private `MessagePort`.
* The worker's code is the exact source of `bridge.js` and `plugin-runtime.js`, made from the modules' own functions by `createWorkerSource`.

**Content script scope.** The content script runs only in Fermo's top-level page:

* the manifest does not inject into frames;
* `content.js` checks `window.top` and the origin again.

The host refuses every start, request, and event unless the page is still Fermo's own top-level `/channels/` page, in its original document (SEC-11 in [plugin-security.md](/plugin-api/plugin-security.md)).

## Why this architecture

Requirements: Chrome and Firefox, Manifest V3, untrusted code from ZIP files, no access to the Fermo session token, per-plugin isolation, and a place to enforce permissions.

| Option                                                    | Result                                                                                                                                                                                                                                                                                                                                    |
| --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Sandboxed extension page in an iframe** (chosen)        | Supported by Chrome and Firefox through the `sandbox` manifest key and `content_security_policy.sandbox`. Sandboxed pages get a unique opaque origin and no extension APIs, can run dynamically supplied code under their own CSP, and talk to their embedder only with `postMessage`. The CSP is ours, so it does not depend on Fermo's. |
| `chrome.userScripts`                                      | Rejected. From Chrome 138 it needs a per-extension **Allow User Scripts** toggle that users must enable manually, and the API is `undefined` otherwise. User scripts run in the Fermo origin, so they share `localStorage`, which holds the session token. Firefox's implementation differs, so this would be a Chrome-first design.      |
| Inline `srcdoc`/`data:` iframe created in the page        | Rejected. It inherits Fermo's CSP (currently `script-src 'self' 'unsafe-inline' 'unsafe-eval' …`, `connect-src 'self' https: wss:`), so plugin behaviour would change whenever Fermo changes its headers, and network access would follow Fermo's policy, not ours.                                                                       |
| `eval` or `new Function` in the content script            | Not possible: Manifest V3 blocks it, and the code would run with full extension privileges.                                                                                                                                                                                                                                               |
| Web Worker from the content script                        | Rejected. A blob worker runs with the Fermo origin (cookies, IndexedDB, network).                                                                                                                                                                                                                                                         |
| Offscreen document, JS realm libraries (SES), ShadowRealm | Chrome-only, still under the extension CSP, require a large dependency, or not shipped in browsers.                                                                                                                                                                                                                                       |

Because Chrome and Firefox both support the same manifest keys, there is one implementation and no browser abstraction layer. Browser-specific code is limited to `createBrowserFrameFactory` in `runtime/host.js` if one becomes necessary.

## Message bridge

`runtime/bridge.js` defines protocol version 1. All messages are plain, JSON-compatible data: no functions, class instances, cycles, or `Date`/`Map` values. Depth, string length, entry count, and code size are bounded. Both sides validate every message they receive.

Handshake:

1. The host creates the frame with a random 128-bit nonce in the URL hash. The frame is inside a closed shadow root, so Fermo's scripts cannot read the URL.
2. On `load`, the host posts `{type: "venora:connect", protocol: 1, nonce}` with one transferred `MessagePort`.
3. The runtime accepts exactly one connect message, and only if its source is the embedding window, the nonce matches, and one port is attached.
4. Everything else uses the port. The host sends `{v: 1, type: "start", plugin: {id, version}, code}`.

Plugin to host:

```js
{v: 1, type: "request", id: "r1", capability: "test.echo", payload: {message: "hello"}}
{v: 1, type: "lifecycle", event: "started" | "failed" | "error" | "stopped", error?: {name, message}}
{v: 1, type: "pong", id: "p1"}                                            // answers a watchdog ping
```

Host to plugin:

```js
{v: 1, type: "response", id: "r1", ok: true, result: {...}}
{v: 1, type: "response", id: "r1", ok: false, error: {code, message}}
{v: 1, type: "event", event: "settings.changed", payload: {key, value}}   // subscribed events only
{v: 1, type: "stop"}
{v: 1, type: "ping", id: "p1"}                                            // every 2 s while running
```

Every message is also bounded as a whole: at most 50,000 values and 1,000,000 characters of strings and keys. The host stops a plugin that sends a larger one.

Error codes: `invalid_message`, `unknown_capability`, `unknown_event`, `permission_denied`, `invalid_payload`, `quota_exceeded`, `rate_limited`, `capability_failed`, `sensitive_data_blocked`, `timeout`, `runtime_stopped`. Their meaning for plugins is specified in [plugin-api.md §8](/plugin-api.md#8-errors).

**Plugin identity is bound to the port.** Requests do not carry a plugin ID; a request that includes one is rejected. The host passes its own record of the plugin's ID and validated permissions to the capability dispatcher.

## Capabilities and permissions

`runtime/capabilities.js` is the single list of what plugins can ask for. Each capability lists the permissions (from `permissions.js`) a plugin must declare, validates its payload, and runs on the Plugin Manager side. Where it needs the browser, it uses the trusted services in `content.js`. `dispatchRequest` checks, in order:

1. the capability exists (own properties only);
2. every required permission was declared;
3. the payload is valid;
4. the capability's own rate limit, if it declares one.

Before dispatch, the host has already checked the plugin's in-flight and general rate limits (see [Lifecycle and errors](#lifecycle-and-errors)).

Internal errors are logged and returned to the plugin only as a generic `capability_failed`.

| Capability                                                      | Permissions                | Behaviour                                                                                                                                                                 |
| --------------------------------------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `settings.get`                                                  | `storage`                  | One of the plugin's own declared settings, or its default                                                                                                                 |
| `storage.get`, `storage.set`, `storage.remove`, `storage.clear` | `storage`                  | The plugin's own key-value data, through `runtime/plugin-storage.js`, keyed by the plugin ID bound to its port. Quotas: 64 KiB per value, 1 MiB and 1,000 keys per plugin |
| `ui.toast`                                                      | `ui`                       | A short text notice. Imported plugins' notices are labelled with the plugin's name so they cannot pose as Venora; bundled plugins' are shown as written                   |
| `mentions.showAvatar`                                           | `ui`, `account`, `network` | Venora looks up the mentioned user's avatar with the signed-in session and shows it. Returns only `{shown}`                                                               |
| `mentions.setAvatarSize`                                        | `ui`                       | Size of the avatars this plugin shows                                                                                                                                     |
| `commands.register`, `commands.unregister`                      | `ui`                       | The plugin's own commands, shown as buttons on its card on the Plugins page while it runs (`runtime/plugin-commands.js`). Removed when the plugin stops                   |
| `events.subscribe`, `events.unsubscribe`                        | per event                  | Manage the plugin's own subscriptions                                                                                                                                     |
| `test.echo`, `test.permissionEcho`                              | none, `storage`            | Bridge and permission-enforcement tests                                                                                                                                   |

Venora applies a plugin's declared `css` while the plugin runs, but only if the plugin declares `ui` and the CSS passes `checkPluginCss` (`plugin-ui-safety.js`):

* no resource loads or escapes, which could leak page content;
* no quoted text and no `@counter-style`, which could write text onto the page;
* at most 131,072 characters.

The full rules are in [plugin-api.md §5.5](/plugin-api.md#55-plugin-css).

The plugin receives a frozen `venora` object (`createVenoraApi` in `runtime/plugin-runtime.js`) with:

* `pluginId`, `apiVersion`, and `protocolVersion`;
* `request(capability, payload)` and `on(event, listener)`;
* the frozen `ui`, `settings`, `storage`, and `mentions` namespaces.

Each namespaced method only calls `request`, so it goes through exactly the same checks.

## Events (Venora → plugin)

`EVENTS` in `runtime/capabilities.js` lists every event, and plugins cannot subscribe to anything else:

| Event              | Permissions | Delivery                                                                                                                   |
| ------------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `settings.changed` | `storage`   | `{key, value}`, only to the plugin that owns the setting                                                                   |
| `mentions.added`   | `ui`        | `{mentions: [{mentionId, userId}]}` to every subscriber; a new subscriber gets the mentions already on the page, each once |
| `commands.invoked` | `ui`        | `{id}`, only to the plugin that registered the command, when the user presses its button                                   |

* `venora.on()` subscribes through the `events.subscribe` capability, which checks the event and its permissions.
* Subscriptions are stored per plugin instance, so one plugin cannot add, remove, or observe another's.
* The host sends an event only to subscribed plugins, only as plain data, and only after the token check below.
* A listener that throws is reported as a plugin error; other listeners still run.

## Session token protection

No capability response or event can carry the Fermo session token to plugin code.

* **One send path:** every message the host sends to a plugin after startup goes through one function, `post()` in `runtime/host.js`.
* **Blocks the token anywhere:** `post()` reads the current tokens from Fermo's account store (`readFermoSessionTokens`) and blocks any message containing one: in values, in keys, or inside longer strings such as `Bearer …` or an error message.
* **What happens when blocked:** blocked responses become `sensitive_data_blocked` and blocked events are dropped. The token is never logged.
* **Fails closed:** if the tokens cannot be read, nothing is sent. Tokens are read for each message, so a new sign-in is protected immediately.
* **Where the token is read:** only in two places, both checked by tests:

  * the avatar lookup service in `content.js`, which uses it for one authenticated request and returns only `{shown}`;
  * the guard's own token source.

  Plugin code, sandbox code, and the runtime never reference it.
* **Storage:** plugins cannot read extension storage themselves. Their own `venora.storage` data is returned through the same guard, so a stored value containing the token is blocked like any other response. A setting the user sets to the token is blocked the same way.

The guard is a central backstop. Capabilities must still be written to return only what plugins need.

## Security boundary

The boundary is the sandboxed frame plus the port. Inside the frame the plugin controls everything, so nothing there is trusted; the host validates everything that crosses.

| Resource                                                    | Plugin                                                                                                                                                                       |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Fermo session token, Fermo `localStorage`/cookies/IndexedDB | No access: opaque-origin worker, plus the token guard                                                                                                                        |
| Fermo page DOM, Venora's UI, `window`/`document`            | None: plugin code runs in a worker. Page changes happen only through `ui` capabilities and CSS, and CSS cannot reach Venora's UI, which is in shadow roots and the top layer |
| Navigating the frame (to send data in a URL)                | Not possible: the worker has no frame or window to navigate                                                                                                                  |
| `chrome.*` / `browser.*`, extension storage                 | No access: sandboxed pages have no extension APIs                                                                                                                            |
| Other plugins' settings, state, subscriptions, or frames    | No access. Capabilities and events are scoped to the plugin bound to the port                                                                                                |
| Network (`fetch`, XHR, WebSocket, images, frames, forms)    | Blocked by the sandbox CSP `default-src 'none'`. Only Venora's own requests inside capabilities                                                                              |
| Install, uninstall, or enable plugins                       | Not exposed                                                                                                                                                                  |
| CPU and memory                                              | Not limited; see limitations                                                                                                                                                 |

**Bundled plugins have no exceptions.** Venora reads them from the extension package and starts them through the same runtime, with only their declared permissions:

| Plugin                               | Before                                                                                                                      | Now                                                                                                            |
| ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `ui-fixes`                           | Content script; CSS injected directly                                                                                       | Sandbox; Venora applies its CSS under `ui`                                                                     |
| `venora-status` (formerly `welcome`) | Content script; built its own DOM banner; registered an unused command                                                      | Sandbox; `ui.toast`. The command was dropped because nothing ran it. Now required                              |
| `mention-avatars`                    | Content script; read the token from `localStorage`, called Fermo's API itself, edited the DOM, used the shared settings API | Sandbox; `settings.get`, `settings.changed`, `mentions.added`, `mentions.showAvatar`, `mentions.setAvatarSize` |

The bundled `api` object was removed: `api.on`, `emit`, `getSetting`, `setSetting`, `registerCommand`, `runCommand`, `listPlugins`, `setPluginEnabled`, `installPlugin` and `uninstallPlugin`.

## Lifecycle and errors

`host.start()` resolves with the plugin's state and never rejects for plugin errors. States: `starting → running`, or `failed`; `running → stopping → stopped`.

* **Syntax errors, init exceptions, rejected promises, missing default export:** the start is reported as `failed` with `{name, message}` and the frame is removed. Other plugins continue.
* **Uncaught errors after start:** captured in the sandbox, reported as `lifecycle: error`, and recorded as `lastError`. The plugin keeps running.
* **No response within 10 s,** including a frame blocked by the browser: `failed` with `TimeoutError`, and the frame is removed.
* **Stop:** the host sends `stop`, the runtime runs the plugin's cleanup and rejects pending requests with `runtime_stopped`, then the host removes the frame after the acknowledgement or a 2 s timeout. Removing the frame terminates the plugin.
* **Malformed messages:** answered with `invalid_message` when they have a request ID; after 20 the plugin is terminated.
* **Resource limits** (`runtime/resource-governor.js`):
  * Each running plugin has an account in the host for its in-flight requests, request rate, per-capability rate (the `rateLimit` declared in `capabilities.js`), and event rate.
  * The in-flight cap and the general rate are checked in the host for every request.
  * A capability's own rate is checked by the dispatcher after permissions and validation, so it counts only real work.
  * A capability that has not answered in 30 s is answered with `timeout`.
* **Watchdog:** the host pings each running plugin's worker every 2 s and stops a plugin that has not answered within 5 s.
* **Repeated problems:** plugins stopped for misbehaviour are counted per page. After 3 stops, a plugin is not restarted until the page reloads or the plugin is uninstalled.
* **Invalid IDs and duplicate instances** are rejected by `host.start()`.
* **Plugin requests** time out after 30 s.

Plugins start when a `/channels/` page loads and stop on other routes, alongside bundled plugins. The plugin card shows the runtime state, for example "Running in sandbox" or "Failed to run: …". A page reload ends every frame without running cleanup, as with any page script.

**Extension reloads and updates:** the old content script keeps running in open Fermo tabs, but its extension APIs throw "Extension context invalidated". It now detects this on the next page change, Plugins click, or storage call, then stops its plugins and removes its UI. A page reload loads the new version.

## Chrome and Firefox

The same `manifest.json` keys are used by both browsers: `sandbox.pages`, `content_security_policy.sandbox`, and `web_accessible_resources`.

**Tested:** Microsoft Edge 154 (Chromium 154) and, in Phase 3.4.1, Brave 155, using `tests/browser/chromium-e2e.mjs` (see below). Google Chrome uses the same engine and extension platform, but the test has not been run in Google Chrome itself, so Chrome compatibility is not verified.

Not yet verified in Firefox:

* the minimum Firefox version with `sandbox` support (Mozilla bug 1398662);
* whether `import()` of a `data:` module is allowed under the sandbox CSP;
* loading a `moz-extension://` sandboxed frame into a page whose CSP has `frame-src 'self' …`;
* whether a `data:` worker created by the sandboxed page inherits its CSP.
  * Verified in Chromium, where the browser test confirms the policy blocks the worker's requests.
  * If Firefox does not do this, the worker must not be used there until it does, because it would have network access.

Venora's UI uses `<dialog>.showModal()` and the popover top layer, both supported by current Chrome and Firefox. Notices fall back to a fixed layer if the popover API is missing.

A Firefox build also needs `browser_specific_settings.gecko.id`.

## Known limitations

* **CPU and memory:** browsers offer no per-worker CPU or memory quota.
  * The watchdog stops a plugin whose worker stops answering, which also ends an infinite loop.
  * A plugin that stays responsive can still use CPU and memory in its own worker.
  * Whether the frame and worker run in a separate process depends on the browser's site isolation.
* **Plugin CSS and Fermo's page:** plugin CSS (with `ui`) can hide or restyle parts of Fermo's own page, including the settings area that holds the Plugins page.
  * It cannot reach Venora's dialogs, notices, or the toolbar popup.
  * The popup (`manage/popup.html`) is always the way back: its safe mode stops every imported plugin and removes its CSS in open tabs, without a reload.
* **Fermo's page** can see that the frames exist and can post messages to them, but it cannot read the nonce or the port. A page that sends a forged connect message first can only prevent that plugin from starting.
* **Single-file plugins only:** the module is imported from a `data:` URL, so relative imports do not resolve.
* **Not tested against the real, signed-in Fermo app.** The automated browser test uses a stand-in page with Fermo's production CSP on the real origin. Fermo's own DOM, routing, and account data are only covered by the manual test.

## Plugin API on this runtime

Phase 3.1 defined the Plugin API on top of this runtime, and Phase 3.2 implemented it, without redesigning it.

* Every API method is a capability in `CAPABILITIES`.
* Each namespaced method on the `venora` object is a thin wrapper around `venora.request`.
* Every public event is an entry in `EVENTS`.

These points were settled in Phase 3.1:

* **Mentions:** the `mentions` capabilities stay as a narrow, stable version 1 namespace. They are not generalized into a DOM API.
* **Network:** there is no general network capability in version 1.
* **API version:** `compatibility.apiVersion` is the Plugin API's major version. It is checked against the list of API versions Venora supports, **not** against the bridge's `PROTOCOL_VERSION`. The two change independently.

What is implemented, and what is left, is listed in [plugin-api-status.md](/plugin-api-status.md).

## Automated browser test

```bash
node tests/browser/chromium-e2e.mjs [path-to-chrome-or-msedge]
```

This needs Chromium 126 or later and no packages. The script looks for Google Chrome in its usual Windows, Linux, and macOS locations, Chromium on Linux, and Edge on Windows. For any other Chromium-based browser, pass its executable path or set `CHROMIUM_PATH`. For example, the Phase 3.4.1 runs used `CHROMIUM_PATH="/Applications/Brave Browser.app/Contents/MacOS/Brave Browser"`.

It launches a headless browser with a temporary profile and loads the unpacked extension over the DevTools protocol. Requests to `https://fermo.sbar.fyi/*` are answered with a stand-in page that carries Fermo's production CSP. The test then drives the real UI: it installs ZIPs through the real file chooser, and it checks the runtime's isolation, permissions, lifecycle, sensitive warnings, updates, uninstall, and extension reload. The page and sandbox console output is written to `tests/browser/last-run-console.log`.

## Manual browser test

Run this against the real, signed-in Fermo app.

1. Load `venora-chrome/` unpacked in `chrome://extensions` and reload Fermo.
2. Compress `examples/hello-runtime/` into a ZIP and install it with **Settings > Plugins > Add plugin**. No sensitive-permission warning appears.
3. Open any `/channels/…` page with DevTools open. The console should show:

   ```
   [hello-runtime] Plugin started.
   [hello-runtime] Plugin Manager replied: {"message":"hello","pluginId":"hello-runtime"}
   [hello-runtime] Extension APIs available: false
   [hello-runtime] localStorage: blocked (ReferenceError)
   [hello-runtime] Fermo page DOM: blocked (ReferenceError)
   [hello-runtime] Network: blocked (TypeError)
   [hello-runtime] Unknown capability rejected: unknown_capability
   [hello-runtime] Permission-gated capability denied: permission_denied
   ```
4. Open **Settings > Plugins**. The card should say "Running in sandbox".
5. Navigate away from `/channels/` and back: the plugin stops and then logs "Plugin started." again. Its "Plugin stopped." line may not appear, because the frame is removed right after cleanup.
6. Failure checks: install a copy whose `index.js` contains a syntax error, or which throws in its default export. The card should say "Failed to run: …", and other plugins should keep working.

If step 3 shows nothing and the card says "Failed to run: The plugin runtime did not start in time", the browser blocked the frame or the module import. Check the console for CSP errors.

**Commands (Venora 0.2.0).** Use `examples/hello-commands/`, which needs no sensitive permission.

1. Compress `examples/hello-commands/` into a ZIP and install it with **Add plugin**. Open a `/channels/…` page, then **Settings > Plugins**.
2. Its card shows "Commands" with **Say hello** and **Remove this command**. Hovering a button shows its description. No other card shows these buttons.
3. Press **Say hello**: a badged "Plugin" notice says "Hello from a command (press 1)." Press it again: "(press 2)".
4. Press **Remove this command**, then reopen the Plugins page: only **Say hello** is left.
5. Turn on safe mode on the Plugins page and reopen it: the card has no commands and says "Not running: safe mode is on". Turn safe mode off and reopen it: both commands are back.
6. Untick the plugin (the page reloads): no commands. Tick it again: they are back.
7. Optional, because the automated browser test covers it: if Fermo has a page outside `/channels/` you can open without signing out, open the Plugins page on `/channels/`, go to that page, and press **Say hello**. The page says the command is no longer available, and no notice appears.
8. Uninstall the plugin: its card and buttons are gone.
9. Throughout, the browser console shows no errors from Venora, and the session token never appears in any plugin output.

## Sources

* Chrome sandbox manifest key: <https://developer.chrome.com/docs/extensions/reference/manifest/sandbox>
* Chrome extension CSP: <https://developer.chrome.com/docs/extensions/reference/manifest/content-security-policy>
* Chrome `userScripts` toggle change: <https://developer.chrome.com/blog/chrome-userscript>
* Firefox `sandbox` key: <https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/sandbox>
* Firefox extension CSP: <https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/content_security_policy>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.getvenora.tech/runtime-architecture.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
