<!-- SANSA -->

# Portable paths and selectors for semantic namespaces.

SANSA means Semantic Address NameSpace Abstraction. It is the address language AEON uses when a document needs to carry a path or selector as data, and when tools need to select locations from an assignment stream.

An exact path identifies one location. A selector can match many locations. AEON references are related, but narrower: they use exact target paths after ~ or ~>, while SANSA values can carry richer selector syntax for consumers.

```aeon
path:sansa = $.contact.name
selector:sansa = $.inventory.items.*.sku
deep:sansa = $.inventory.**
attribute:sansa = $.reading.@.unit

copy:string = ~contact.name
pointer:object = ~>contact
```

[Read syntax](#paths)  
[Open playground](/sansa-playground.php)

<!-- Exact Paths -->

## Use exact paths when one location is intended.

A SANSA exact path begins at a root and follows member, quoted member, index, or attribute-space segments. Exact paths are the right form for canonical target identity and schema rules that name one location.

```aeon
root:sansa = $
contact:sansa = $.contact
name:sansa = $.contact.name
firstSku:sansa = $.inventory.items[0].sku
quoted:sansa = $.inventory.["items.with.dots"][2]
contextual:sansa = ?.name
```

### Absolute root
- **Syntax:** `$`
- **When to use:** Starts from the root of the exposed namespace.

### Contextual root
- **Syntax:** `?`
- **When to use:** Starts from a consumer-supplied context rather than the global root.

### Member
- **Syntax:** `.name`
- **When to use:** Selects a bare member name.

### Quoted member
- **Syntax:** `.["name.with.dots"]`
- **When to use:** Selects one member whose key contains punctuation, whitespace, or otherwise non-bare text.

### Position
- **Syntax:** `[0]`
- **When to use:** Selects a zero-based ordered position in a list, tuple, or node child space.

<!-- Selectors -->

## Use selectors when a consumer should match a set.

Selectors are still addresses, but they describe a set of possible matches rather than one exact target. They are useful for schema rules, extraction tools, and resolver/query layers.

```aeon
items:sansa = $.inventory.items.*
skus:sansa = $.inventory.items.*.sku
everythingBelowInventory:sansa = $.inventory.**
matchingItems:sansa = $.items.("item?*").sku
literalStar:sansa = $.items.("item\\*").sku
literalQuestion:sansa = $.items.("item\\?").sku
```

SANSA uses .* for direct child expansion and .** for descendant expansion. It deliberately does not use JSONPath-style [*].

### Direct expansion
- **Syntax:** `*`
- **When to use:** Matches direct children of the current location.

### Descendant expansion
- **Syntax:** `**`
- **When to use:** Matches descendants below the current location.

### Name pattern
- **Syntax:** `("item?*")`
- **When to use:** Matches member names by pattern. ? matches one character; * matches zero or more characters. Use \? and \* inside the decoded pattern for literal wildcard characters.

<!-- Attributes -->

## Attributes live in their own address space.

SANSA uses .@. to enter the attribute address space. That keeps attributes distinct from ordinary data members while allowing ordinary navigation to continue inside attribute values.

```aeon
unit:sansa = $.reading.@.unit
display:sansa = $.contact.name.@.["display.label"]
allReadingAttributes:sansa = $.reading.@.*
deepAttributes:sansa = $.record.**.@.*
```

Compact forms such as $.reading@unit are not valid SANSA v1 addresses. Use .@.attribute for attribute-space traversal.

<!-- Filters -->

## Filters narrow selectors without changing the path shape.

SANSA supports filter syntax that consumers can evaluate when they understand the relevant metadata. Current AEON tooling distinguishes representation kind filters from semantic datatype filters.

```aeon
strings:sansa = $.inventory.items.*%string
objects:sansa = $.inventory.items.*%object
declaredStrings:sansa = $.inventory.items.*#string
```

### Representation kind filter
- **Syntax:** `%kind`
- **When to use:** Filters by observed value kind such as string, number, object, list, or boolean.

### Semantic type filter
- **Syntax:** `#type`
- **When to use:** Filters by declared datatype or semantic type where the source exposes one.

Parsing a filter is not the same as evaluating it. A consumer may interpret, ignore, or reject filters depending on its authority and capability surface.

<!-- Qualifiers -->

## Qualified address literals carry structured possibility claims.

A SANSA address can carry an optional qualifier expression after a colon. The qualifier is syntax preserved with the address; SANSA does not force one global meaning for every qualifier term.

```aeon
numberOrNan:sansa = $.result:number|nan
tupleAddress:sansa = $.point:tuple<x><y>
csvAddress:sansa = $.inventory:csv[","]
external:sansa = $.value:type<type>[arg]
```

AEON can preserve SANSA qualifier syntax even when the qualifier is meant for another system. Host implementations still define the qualifier surface they accept.

<!-- AEON Boundary -->

## A SANSA value is not an AEON reference.

The sansa datatype stores an address literal. It does not resolve anything by itself. AEON reference values use ~ and ~>, and those references must target already-bound exact paths.

```aeon
target:sansa = $.contact.name

contact:object = {
  name:string = "Bob"
}

copy:string = ~contact.name
pointer:object = ~>contact
```

Use SANSA when an address or selector needs to be transported, stored, validated by a schema, or handed to a resolver. Use AEON references when the document itself declares a relationship to an existing value.

[Try in playground](/sansa-playground.php)  
[Open type reference](/type-reference.php)
View as HTML