<!-- Generated from sources/appendices/v1/appendix-spans.aeon; do not edit. -->

<a id="appendix-spans"></a>
# Appendix — Spans

Canonical topic owners: AEOS Specification v1 and AEON v1 Comments and Annotations Reference.

If this appendix conflicts with the canonical v1 spec set, the canonical v1 spec set wins.

<a id="definition"></a>
## 1. Definition

A span identifies a half-open byte range in one exact AEON source artifact.

```ts
span: [start, end]
```

- `start` and `end` are non-negative integers
- both are zero-based offsets into the UTF-8 bytes of the source artifact
- `start` is inclusive
- `end` is exclusive
- `start` MUST be less than or equal to `end`
- when the source is valid UTF-8, both endpoints MUST fall on Unicode scalar boundaries

A diagnostic span MAY be empty, with `start == end`, for an insertion point or end-of-input condition. A profile may impose a narrower rule; for example, portable AES v1 requires a non-empty span when a span is transported.

<a id="exact-source-contract"></a>
## 2. Exact Source Contract

Span offsets are measured against the exact, unnormalised UTF-8 source bytes accepted by the producer.

Producers MUST NOT remove a byte-order mark, normalise Unicode, translate newlines, or otherwise rewrite the source before calculating offsets. Consequently:

- a UTF-8 byte-order mark occupies three bytes
- CRLF occupies two bytes
- a combining sequence occupies the bytes of each scalar in that sequence
- an astral scalar occupies four UTF-8 bytes

When source text is supplied directly in a local call, that input binds the span to its source artifact implicitly. A span transported outside that source-bound call requires an origin identity under the applicable transport profile. Portable AES uses `origin` for this purpose.

<a id="purpose"></a>
## 3. Purpose

Spans provide deterministic source linkage for:

- diagnostics
- auditing
- tooling/editor highlighting

Spans are metadata and do not change AEON semantics.

<a id="authority"></a>
## 4. Authority

- Spans are produced by AEON Core.
- Validators and downstream processors propagate spans.
- Validators must not invent replacement spans for existing source-backed values.

<a id="required-output-behavior"></a>
## 5. Required Output Behavior

For AEOS/CTS-style diagnostics:

- diagnostics should include a span when the target source region exists
- `span: null` is allowed only when no source region exists (for example missing required path)

<a id="targeting-rule"></a>
## 6. Targeting Rule

A span should identify the narrowest source fragment responsible for the diagnostic (for example the offending literal or reference token).

<a id="non-goals"></a>
## 7. Non-Goals

Spans are not:

- semantic values
- canonical paths
- semantic identities
- mutation addresses

Line and column values are optional implementation conveniences, not the portable span coordinate system. An implementation exposing them MUST document their units. They MUST NOT override the UTF-8 byte offsets carried by `span`.

<a id="determinism"></a>
## 8. Determinism

Given identical source and policy, diagnostics should carry stable spans.

<a id="implementation-note"></a>
## 9. Implementation Note

Native lexer positions may carry richer location data. Portable consumers use the UTF-8 byte interval defined by this appendix and the event-specific source boundaries defined by the AES event model.

---

## Related documents

- [AEOS Specification v1](./aeos-v1.md)
- [AEON v1 Comments and Annotations Reference](./aeon-core-v1-comments-annotations.md)
- [Appendix — Error Model](./appendix-error-model-v1.md)
