> For the complete documentation index, see [llms.txt](https://bsv.brc.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bsv.brc.dev/peer-to-peer/0141.md).

# Fountain-Coded Air-Gap Transport for Arbitrary Payloads

Darren Kellenschwiler (<deggen@kschw.com>)

**Wire protocol version: 1** (header `ver` = `0x01`). Status: **experimental** — the format is versioned and conformance-fixed, but no independent second implementation has passed the shared vectors yet. This revision supersedes the earlier unversioned 14-byte draft framing, which no released software emits or accepts.

## Abstract

This standard defines a payload-agnostic, one-directional optical transport that carries an arbitrary byte string across an air gap as a sequence of QR codes. Each QR decodes to a single US-ASCII string beginning with the fixed prefix `air-gap:`, followed by unpadded URL-safe base64 of a versioned binary header and one fixed-size block. Parts are produced by a systematic Luby-transform fountain: the first *K* sequence numbers are the source blocks themselves, and later sequence numbers are deterministic XOR mixtures of those blocks, selected by an exactly specified integer-arithmetic ideal-soliton sampler so every language reproduces identical parts bit for bit. A receiver assembles the payload from distinct parts in any order, with duplicates tolerated, so a missed camera frame does not force a full animation cycle of waiting; recovery from *K* + ε distinct parts is highly probable but not guaranteed, and a sender that loops its sequence makes eventual recovery certain. An 8-byte session identity in every header lets a receiver lock onto one sender and ignore stray frames from another. Integrity is checked with the IEEE CRC-32 of the complete payload, carried in every part header and re-verified before bytes are emitted. The scheme is deliberately independent of payment, signing, or wallet semantics: applications supply and interpret the payload. Symbol rendering, camera capture, and animation cadence are out of scope.

## Motivation

Air-gapped and phone-to-phone workflows share a common constraint: there is no bidirectional socket, only a screen on one device and a camera on the other. Realistic payloads (unsigned extended transactions, AtomicBEEF, cosigning envelopes, BRC-100 call blobs) routinely exceed the capacity of a single QR symbol. Prior art on BSV includes:

* **BRC-225 (TKQR1)** — fixed-order indexed frames with a truncated SHA-256 set tag. Simple and fully deterministic, but every missed frame costs a full cycle until that exact index reappears.
* **Application demos** (for example colon-delimited `CHUNK:` string splitters) — workable for small demos, but non-interoperable, non-byte-oriented, and without a strong integrity gate.
* **BC-UR** on other chains — fountain-capable animated QR using bytewords and CBOR; no shared wire format with this BRC.

This BRC standardises the **fountain** approach for general air-gap use: miss-tolerant reassembly, a single wire prefix for every payload size (including the single-part case *K* = 1), tunable block size for different screens and error-correction budgets, and a small versioned binary header that is easy to implement in multiple languages. It is a **peer alternative** to BRC-225, not a revision of it. Implementations MAY support both; they MUST NOT treat the wire formats as interchangeable.

The reference TypeScript package is `@bsv/air-gap` (codec only: no camera, no QR renderer). Applications such as mobile wallets, air-gapped signers, and payment demos own presentation and scanning.

## Specification

The key words MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are to be interpreted as in RFC 2119.

### 1. Terminology

* **Payload**: the arbitrary sequence of bytes to be transported, `1 .. 65536` octets. This BRC imposes no structure on the payload. Authenticity and confidentiality are the responsibility of the enclosed payload.
* **Block**: a fixed-length slice of the payload (zero-padded on the final source block).
* **Part**: one QR-decodable US-ASCII string encoding one fountain part (header plus one block-sized body).
* **K** (*block count*): `ceil(msgLen / blockBytes)`, the number of source blocks, `1 .. 65535`.
* **seq**: the part sequence number, an unsigned 32-bit integer. Values `0 .. K-1` are systematic; values `≥ K` are coded.
* **blockBytes**: the fixed body size of every part for a given encode, `1 .. 2048`. Tunable by the application; not carried as an explicit header field (it is inferred from the decoded body length).
* **sessionId**: 8 octets naming one encoder's stream. Chosen once at encoder construction — random unless the application supplies a value (deterministic test vectors do).

### 2. Wire grammar

A part is:

```
part = PREFIX base64url( header ‖ body )
PREFIX = "air-gap:"   ; literal US-ASCII, case-sensitive
header = ver ‖ sessionId ‖ seq ‖ K ‖ msgLen ‖ crc32   ; 23 octets, big-endian (see §3)
body   = blockBytes octets                            ; see §4–§5
```

Requirements:

* The part MUST be a single line with no surrounding whitespace in the canonical form.
* `base64url` is RFC 4648 §5 (URL- and filename-safe alphabet), **unpadded**. Encoders MUST omit `=` padding. Decoders MUST reject padding characters, embedded whitespace, characters outside the base64url alphabet, and any body whose length ≡ 1 (mod 4). (Lenient base64 handling differs across runtimes; rejecting uniformly is what keeps the soft-fail contract identical everywhere.)
* The part uses characters outside the QR alphanumeric set (`:`, lowercase letters, `-`, `_`), so symbols MUST be rendered in **QR byte mode**.
* A decoder MUST soft-reject (no state change) any string that does not begin with the literal prefix `air-gap:`, and — before any base64 decoding — any string longer than the longest legal part (2,770 characters, see §9), so hostile input costs no allocation.

### 3. Binary header

All multi-byte integers are **big-endian**.

| Offset | Type       | Field       | Description                                                                  |
| ------ | ---------- | ----------- | ---------------------------------------------------------------------------- |
| 0      | `uint8`    | `ver`       | Wire protocol version. MUST be `0x01`; a decoder MUST reject any other value |
| 1      | `8 octets` | `sessionId` | Stream identity chosen by the encoder (§1)                                   |
| 9      | `uint32`   | `seq`       | Part sequence number                                                         |
| 13     | `uint16`   | `K`         | Source block count                                                           |
| 15     | `uint32`   | `msgLen`    | Payload length in octets                                                     |
| 19     | `uint32`   | `crc32`     | IEEE CRC-32 of the full payload (§6)                                         |
| 23     | …          | `body`      | Exactly `blockBytes` octets                                                  |

Header length is always 23 octets. `blockBytes` is not stored in the header: it equals `len(decoded_bytes) - 23` and MUST be identical for every part of one session.

### 4. Chunking and source blocks

Input: `payload` (bytes), `blockBytes` (integer).

1. `blockBytes` MUST be an integer in `1 .. 2048`. The ceiling keeps every legal part inside the byte-mode capacity of a version-40 QR symbol at error-correction level L, and doubles as the decoder's resource bound (§8).
2. If `len(payload) = 0`, the encoder MUST fail (empty payloads are not representable). Applications that need a typed empty record MUST wrap it in a non-empty envelope.
3. If `len(payload) > maxMessageBytes`, the encoder MUST fail. Conforming implementations MUST enforce `maxMessageBytes = 65536` unless a profile document specifies a lower bound; implementations MUST NOT raise the bound above 65536 without a new wire version.
4. `K = ceil(len(payload) / blockBytes)`. `K` MUST be ≤ 65535 (the `uint16` field); the encoder MUST fail rather than truncate. When `blockBytes ≥ len(payload)`, `K = 1` and a single systematic part carries the entire payload (zero-padded to `blockBytes`).
5. Source block *i* for `i` in `0 .. K-1` is a `blockBytes`-octet buffer: copy `payload[i·blockBytes : min((i+1)·blockBytes, len)]` into the start of the buffer; remaining octets are `0x00`.

Default `blockBytes` SHOULD be **1200** unless the application has measured reasons to differ (smaller screens, higher ECC, logo overlays). Smaller blocks yield more parts but lower per-symbol density; larger blocks reduce part count but push QR capacity.

### 5. Fountain part construction

Part body for sequence number `seq`:

* If `seq < K`: body is source block `seq` (as constructed in §4).
* If `seq ≥ K`: body is the XOR of source blocks whose indices are `blocksForPart(seq, K)` (§5.1).

The complete part bytes are `header ‖ body` with all §3 fields set, then base64url-encoded and prefixed with `air-gap:`. `partAt(seq)` MUST be a pure function of `(payload, blockBytes, sessionId, seq)`.

`seq` is a finite `uint32`, not unbounded. Encoders used for animation SHOULD loop — for example cycling `seq` over a window a few multiples of *K* wide — until the receiver signals success out of band: re-emitting the systematic prefix is what makes eventual recovery deterministic rather than merely probable (§7a).

#### 5.1. `blocksForPart(seq, K)` (normative)

Used only when `seq ≥ K`. Every operation is exact integer arithmetic; all intermediate products stay below 2⁴⁰, so 64-bit integer (or IEEE double) arithmetic reproduces it exactly. Pseudo-code:

```
makeRng(seed):
  x ← seed as uint32
  if x = 0: x ← 0x6d2b79f5
  return function:
    x ← x XOR (x << 13); x as uint32
    x ← x XOR (x >> 17); x as uint32
    x ← x XOR (x << 5);  x as uint32
    return x

draw23(rng):
  return rng() >> 9                      // top 23 bits: integer in [0, 2^23)

blocksForPart(seq, K):
  rng ← makeRng( (seq × 0x9e3779b1) mod 2^32 )   // 32-bit modular product — see warning
  r ← draw23(rng)
  degree ← floor((2^23 + r) / (r + 1))           // = ceil(2^23 / (r+1))
  if degree > K: degree ← 1
  pool ← [0, 1, …, K-1]
  for i in 0 .. degree-1:
    j ← i + floor( draw23(rng) × (K - i) / 2^23 )
    swap pool[i], pool[j]
  return pool[0 .. degree-1]
```

The degree draw is an exact inverse-CDF sample of the **ideal soliton distribution** over `1 .. K` — ρ(1) = 1/K, ρ(d) = 1/(d(d−1)) for d ≥ 2 — because the truncated tail `degree > K` carries total probability ≈ 1/K, exactly the mass ρ(1) requires. (For K = 1 every part is block 0.)

> **Seed-precision warning (JavaScript and other double-based languages).** The seed is the 32-bit modular product `seq × 0x9e3779b1`. In JavaScript this MUST be computed as `Math.imul(seq, 0x9e3779b1) >>> 0`. The expression `(seq * 0x9e3779b1) >>> 0` is **wrong**: IEEE-754 doubles lose low product bits once `seq ≥ 3,393,265`, silently selecting different blocks than a native uint32 implementation (at `seq = 0x7fffffff` the double path seeds 3,788,015,616 where the correct u32 product is 3,788,015,183). The shared conformance vectors pin parts on both sides of that boundary and at `0xffffffff`; a port that fails them is not conforming. The zero-seed substitution is unreachable on the wire (`seq = 0` is systematic) but is normative for any code path that exposes the mapping directly.

### 6. CRC-32

`crc32` is the IEEE CRC-32 (ISO 3309 / ITU-T V.42 / Ethernet polynomial `0xEDB88320` reflected), as produced by the standard table algorithm with initial value `0xFFFFFFFF` and final XOR `0xFFFFFFFF`. The well-known check value is:

```
CRC32(ASCII "123456789") = 0xCBF43926
```

The field covers the **entire payload** (all `msgLen` bytes), not individual blocks. It is an integrity check against camera misreads, never an authenticator (§ Security Considerations).

### 7. Reassembly (decode)

A receiver maintains session state. The reference models this as a stateful decoder.

**Per-part ingest (`accept`):**

1. If the string is not a well-formed version-1 `air-gap:` part (wrong prefix, over-length per §2, invalid base64url, decoded length ≤ 23 or > 23 + 2048, `ver ≠ 1`), return soft failure and leave state unchanged. A decoder used with a live camera MUST NOT throw on stray scans.
2. Parse header fields and body. Let `blockBytes = len(body)`.
3. Reject if `K = 0`, `msgLen = 0`, or `msgLen > maxMessageBytes`.
4. Reject if `ceil(msgLen / blockBytes) ≠ K` (header and body disagree on message shape).
5. The session identity is the quadruple `(sessionId, K, msgLen, crc32)`. The decoder **locks** onto the first identity it accepts. A part carrying a different identity MUST NOT disturb the locked session; only **3 consecutive** parts of the *same* foreign identity switch the decoder to that session, resetting state (a camera genuinely re-pointed at a new sender produces them back to back). A part of the locked session, or of a different foreign identity, restarts the count; unusable reads do not affect it.
6. On the first accepted part of a session, pin `blockBytes`. Later parts whose body length differs MUST be rejected (soft-fail) without changing solved state.
7. Once the session is complete (§ below), further parts of its identity MUST be acknowledged without any state change.
8. If `seq` was already seen in this session, ignore the duplicate.
9. Determine block indices: if `seq < K`, indices = `{seq}`; else indices = `blocksForPart(seq, K)`.
10. Ingest via peeling: XOR out already-solved blocks from the body; if one index remains, solve that block; cascade until fixpoint. Parts still mixing several unsolved blocks are buffered subject to the §8 budgets.

**Completeness:** the session is complete when all *K* source blocks are solved.

**Finalize (`message`):**

1. If incomplete, return no payload.
2. Concatenate solved blocks `0 .. K-1` and trim to `msgLen`.
3. Recompute CRC-32 over the trimmed bytes and require equality with the session `crc32`. On mismatch, reset the session and return no payload (the sender is expected to still be looping).
4. Return the trimmed bytes.

A conforming decoder MUST NOT emit a truncated or blended payload.

#### 7a. Recovery characteristics (informative, binding on documentation)

Distinct coded parts are **not** guaranteed to be linearly independent, so recovery from any *K* + ε distinct parts is probabilistic; documentation of this transport MUST NOT present it as absolute. Deterministic example: for K = 3, the six distinct parts `seq = 4, 27, 38, 56, 63, 72` all reduce to source block 0, leaving progress at 1/3. Receivers simply keep scanning; senders keep looping. Measured with the reference implementation (400 deterministic trials per cell): a repair-only receiver that missed the entire systematic prefix completes at ≈1.4–1.5 K parts at the median and ≈3.8–4.6 K at the 99th percentile (K = 5..55); a receiver watching a sender that loops over an 8 K-wide window completes within ≈1.5 K reads at the median, bounded by the next systematic pass.

### 8. Mixed-stream, fail and resource rules (normative summary)

| Condition                                         | Behaviour                                                              |
| ------------------------------------------------- | ---------------------------------------------------------------------- |
| Not `air-gap:` / over-length / bad base64 / short | Soft-reject; no state change                                           |
| `ver ≠ 1`                                         | Soft-reject                                                            |
| `K`, `msgLen` out of range                        | Soft-reject                                                            |
| `ceil(msgLen/blockBytes) ≠ K`                     | Soft-reject                                                            |
| Body length > 2048                                | Soft-reject                                                            |
| Different `(sessionId, K, msgLen, crc32)`         | Soft-reject; switch only after 3 consecutive parts of one new identity |
| Body length ≠ pinned `blockBytes`                 | Soft-reject                                                            |
| Duplicate `seq`                                   | Acknowledge; no reprocessing                                           |
| Part of a completed session                       | Acknowledge; no state change                                           |
| Finalize with incomplete set                      | No emit                                                                |
| Final CRC mismatch                                | Reset; no emit                                                         |

Decoder state MUST be bounded against hostile or broken senders. The reference bounds (RECOMMENDED values; implementations MAY tune them but MUST bound): duplicate tracking ≤ 65,536 sequence numbers (past the cap, repeats are re-processed — idempotent, so correctness is unaffected); buffered unsolved mixes ≤ 1,024 parts and ≤ 4,096 total unresolved block references (a mix that would exceed either budget is soft-rejected). Systematic and degree-1 parts are never buffered, so the budgets cannot starve an honest looping sender.

### 9. Presentation guidance (non-normative)

* Animation cadence is **not** part of this BRC. Applications commonly use \~200 ms per part (\~5/s) on phone cameras; slower is more reliable under motion blur.
* For *K* = 1, applications MAY show a single static QR (never advance `seq`).
* Every part for a given `blockBytes` renders at exactly `8 + 4·floor((23 + blockBytes)/3) + tail` characters (tail = 0, 2, or 3 for remainder 0, 1, 2). Because base64url forces **byte mode**, compare part length directly against byte-mode capacity tables: the default `blockBytes = 1200` yields 1,639 characters — inside a version-40 symbol at every ECC level up to Q (1,663 bytes) with 44 % headroom at L (2,953) — and the `blockBytes` ceiling of 2,048 yields 2,770 characters, inside version 40-L.
* Centre logos and colour styling consume error-correction budget; prefer ECC level M or higher and reduce `blockBytes` if overlays are used.

### 10. Interoperability contract

Two implementations are interoperable if and only if, for the same `(payload, blockBytes, sessionId)`, they produce identical part strings for every `seq`, and each can reassemble the other's stream to the exact original payload. Determinism is total: there is no timestamp or locale dependence, and the only randomness — the default `sessionId` — is an explicit input. Shared test vectors are the conformance oracle; the machine-readable corpus lives in the ts-stack repository at [`conformance/vectors/transport/air-gap-optical.json`](https://github.com/bsv-blockchain/ts-stack/blob/main/conformance/vectors/transport/air-gap-optical.json) and includes encode vectors at the §5.1 seed-precision boundaries, decode and session-locking streams, the K = 3 linear-dependence stall, and hostile-input rejections. Vectors are append-only; a change that breaks one requires a new `ver` value.

## Test Vectors

All vectors below use `sessionId = 0102030405060708` (hex).

### Vector A — CRC-32 check value

* Input: ASCII `123456789`
* Output: `crc32 = 0xCBF43926`

### Vector B — Single-part (*K* = 1)

* Payload: ASCII `Hello, air-gap!` (15 bytes)
* `blockBytes = 64`
* `K = 1`, `msgLen = 15`, `crc32 = 0x8614FD1F`
* Systematic part `seq = 0` (body is 15 payload bytes then 49 zero bytes):

```
air-gap:AQECAwQFBgcIAAAAAAABAAAAD4YU_R9IZWxsbywgYWlyLWdhcCEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
```

Reassembly: accept that single part → payload 15 bytes; CRC matches.

### Vector C — Two systematic parts

* Payload: ASCII `Hello, air-gap!` (15 bytes)
* `blockBytes = 8`
* `K = 2`, `msgLen = 15`, `crc32 = 0x8614FD1F`
* Source blocks: `Hello, a` and `ir-gap!\0`

```
air-gap:AQECAwQFBgcIAAAAAAACAAAAD4YU_R9IZWxsbywgYQ
air-gap:AQECAwQFBgcIAAAAAQACAAAAD4YU_R9pci1nYXAhAA
```

Reassembly in either order, with optional duplicates, yields the original 15 bytes. Presenting only one part MUST NOT emit a payload.

### Vector D — Behavioural (implementation tests)

Conforming decoders MUST:

1. Soft-reject strings that are not version-1 `air-gap:` parts, including any `ver ≠ 1` and any string longer than 2,770 characters (the latter before base64 decoding).
2. Complete from the systematic set alone when no frames are missed.
3. Complete when some systematic parts are missing but enough coded parts (`seq ≥ K`) arrive to peel the remainder.
4. Keep the locked session when a single part with a different `(sessionId, K, msgLen, crc32)` arrives, and switch only after 3 consecutive parts of one new identity.
5. Soft-reject a part whose body length differs from the first accepted part of the session.
6. On final CRC mismatch (for example after a body bit-flip with header left intact), discard the assembly and continue accepting.
7. Stall at 1/3 progress after the K = 3 parts `4, 27, 38, 56, 63, 72` (linear dependence), then complete from subsequent parts.

The complete machine-readable set — including the `seq = 3,393,264 / 3,393,265`, `0x7fffffff` and `0xffffffff` seed-boundary encodings — is the ts-stack conformance corpus referenced in §10.

## Implementations

* **Reference (TypeScript):** [`@bsv/air-gap`](https://www.npmjs.com/package/@bsv/air-gap) — pure codec (`AirGapEncoder` / `AirGapDecoder`), no camera or QR dependencies. Intended for browsers, React Native, and Node. Source: [bsv-blockchain/ts-stack — `packages/helpers/air-gap`](https://github.com/bsv-blockchain/ts-stack/tree/main/packages/helpers/air-gap), with the repository-local wire spec at [`specs/transport/air-gap-optical.md`](https://github.com/bsv-blockchain/ts-stack/blob/main/specs/transport/air-gap-optical.md) and shared vectors at [`conformance/vectors/transport/air-gap-optical.json`](https://github.com/bsv-blockchain/ts-stack/blob/main/conformance/vectors/transport/air-gap-optical.json).
* Operational precursor: the Luby-transform fountain previously embedded in BSV mobile wallet code for oversized nearby-payment frames (payment-specific prefixes; not part of this wire format, and its coding — a JavaScript float-precision seed and a mis-sampled degree distribution — is deliberately not reproduced by this revision).

## Mathematical basis

**Systematic fountain.** The first *K* parts are an exact partition of the (padded) payload. Coded parts are linear combinations over GF(2) of whole blocks. The peel decoder solves degree-1 equations and substitutes, which recovers the source whenever the collected set spans the message — with high probability after roughly *K* distinct parts for the ideal-soliton draw, though never with certainty (§7a).

**CRC-32** detects accidental corruption and distinguishes unrelated streams with low cost on constrained devices. It is not an authenticator: an adversary who can inject frames can forge a consistent CRC. Payload authenticity MUST be provided by the application layer (signatures, MACs, or verified transaction structure).

## Security Considerations

* **No authenticity.** CRC-32 does not authenticate the sender, and the `sessionId` is an accident guard, not a security boundary — an active optical attacker can read it off the sender's screen. Sign or encrypt at the payload layer when required.
* **No confidentiality.** Parts are plaintext on a screen. Sensitive material MUST be encrypted before framing.
* **Fail closed.** Decoders MUST NOT return partial payloads. Mixed streams soft-reject (with the 3-consecutive switch rule); CRC failure discards the assembly.
* **Resource bounds.** §8 bounds decoder memory and per-frame work against hostile headers and hostile senders; the pre-decode length gate caps allocation for non-part garbage at zero.
* **No freshness.** Duplicate-tolerant reassembly implies anti-replay lives in the payload (nonces, request IDs, expiry).
* **Optical threat model.** Shoulder-surfing and nearby cameras can capture the stream; treat the channel as public.

## Relationship to other standards

| Standard                   | Relationship                                                                            |
| -------------------------- | --------------------------------------------------------------------------------------- |
| BRC-225 TKQR1              | Peer alternative (indexed frames). No shared wire format.                               |
| BRC-100                    | Online wallet interface; this BRC is the optical path when that channel is unavailable. |
| BRC-62 BEEF                | Example payload this transport can carry.                                               |
| BC-UR (Blockchain Commons) | Prior art on another chain; no shared format.                                           |

## References

* BRC-225, Animated-QR Air-Gap Transport for Arbitrary Payloads (TKQR1).
* BRC-100, Wallet-to-Application Interface.
* BRC-62, Background Evaluation Extended Format (BEEF).
* RFC 4648, Base16/32/64 encodings (§5 URL-safe base64).
* ISO/IEC 18004, QR Code symbology (byte mode; Reed-Solomon levels).
* RFC 2119, Key words for use in RFCs.
* Luby, M. "LT Codes." *Proceedings of the 43rd Symposium on Foundations of Computer Science*, 2002 (fountain degree distribution inspiration; this BRC specifies an exact ideal-soliton draw, not a full LT standard).
* Blockchain Commons, UR: Uniform Resources (BCR-2020-005), cited as prior art only.
* IEEE CRC-32 / ISO 3309.
* ts-stack conformance corpus: [`conformance/vectors/transport/air-gap-optical.json`](https://github.com/bsv-blockchain/ts-stack/blob/main/conformance/vectors/transport/air-gap-optical.json).


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bsv.brc.dev/peer-to-peer/0141.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
