YAML schema (full)
Status: spec stream 1, project semver 0.1.0 (pre-1.0). In-place tightening allowed until the project hits 1.0.0. See the Versioning policy.
A sightmap is a directory of YAML files at the root of a project, under .sightmap/. It describes the app’s views, components, and requests, with optional memory entries that carry notes agents can use at runtime.
This document is the human-readable reference. The machine-readable contract is sightmap.schema.json.
File discovery
Section titled “File discovery”- Every
*.yamland*.ymlfile under.sightmap/is discovered recursively. - All files are loaded and merged at load time. The directory layout is a convenience for authors; it has no semantic meaning.
- Every file must begin with
version: 1. - Merging is shallow-append per top-level collection (
views,components,requests). Two files may define the same view; the runtime behavior in that case is implementation-defined and SDKs SHOULD emit a warning.
File root
Section titled “File root”version: 1memory: # optional, string[] — file-level notes (see "Memory")views: # optional, View[]components: # optional, Component[] — global, matched on every viewrequests: # optional, Request[] — global, matched on every view| Field | Type | Required | Description |
|---|---|---|---|
version | integer | yes | Must be 1. |
memory | string[] | no | File-level memory entries. Surfaced as context to the agent for any view in this file. |
views | View[] | no | Views defined in this file. |
components | Component[] | no | Global components — matched against every view. |
requests | Request[] | no | Global requests — matched against every view. |
A named screen in the app, identified by a URL route.
- name: FlightSearch route: /search description: Main search page with date and origin/destination pickers source: src/pages/FlightSearch.tsx memory: - The search form lives inside a modal on mobile; selectors differ components: [...] requests: [...]| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Shown in the snapshot header. Should be unique across the sightmap. |
route | string | yes | Glob pattern matched against the URL pathname. See Route matching. |
description | string | no | Free-text. Not surfaced at runtime but useful for PR review and future maintenance. |
source | string | no | Relative path to the source file. |
memory | string[] | no | View-level memory entries. |
components | Component[] | no | View-scoped components. Additive with globals. |
requests | Request[] | no | View-scoped requests. Additive with globals. |
Component
Section titled “Component”A named DOM subtree, identified by one or more CSS selectors.
- name: DepartureDatePicker selector: '[data-picker="departure"]' source: src/components/DatePicker.tsx description: Departure date picker, calendar + typed input memory: - Accepts typed YYYY-MM-DD — skips the calendar - Past dates render but are aria-disabled children: - name: date-input selector: input - name: day selector: '[role="gridcell"]'| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Replaces the generic a11y role in enriched snapshots. |
selector | string | string[] | yes | CSS selector, or a list of alternatives. First match wins. |
source | string | no | Path to the source file. Rendered inline as [src: …] in enriched snapshots. |
description | string | no | Free-text. Not surfaced at runtime. |
memory | string[] | no | Component-level memory entries. |
children | Component[] | no | Nested components. Child selectors are scoped to the parent’s subtree. |
Selector semantics
Section titled “Selector semantics”- A single string is a standard CSS selector.
- A list of strings is tried in order; the first selector that matches wins.
- Selectors in
childrenare evaluated within their parent’s matched subtree, not globally. This scoping is how Sightmap avoids naming collisions between, say, two different card components that both contain abutton.primary. - Selectors are not required to be unique at their level. If a selector matches multiple elements, all matches are named.
Request
Section titled “Request”A named API endpoint.
- name: SearchFlights route: /api/flights/search method: POST description: Run a flight search and return results source: src/api/flights.ts request: fields: - name: origin type: string - name: destination type: string - name: departureDate type: string description: ISO-8601 date response: fields: - name: results type: array headers: [x-request-id] memory: - 429s on more than 10 requests/min per user| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Shown in network list and detail output. |
route | string | yes | Glob pattern. Express-style :param segments are normalized to *. See Route matching. |
method | string | no | HTTP method filter (GET, POST, …). Match-any if omitted. |
description | string | no | What the endpoint does. |
source | string | no | Relative path to the source file. |
request | Payload | no | Expected payload shape. |
response | Payload | no | Expected response shape. |
headers | string[] | no | Notable header names to highlight in the network detail view. |
memory | string[] | no | Request-level memory entries. |
Payload
Section titled “Payload”request: fields: - name: origin type: string description: IATA code| Field | Type | Required | Description |
|---|---|---|---|
fields | Field[] | no | Expected fields. Not exhaustive; extra fields are not rejected. |
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | The field name. |
type | string | no | Free-text type label: string, number, boolean, array, object, or anything else an SDK author finds useful. |
description | string | no | Free-text description. |
Memory
Section titled “Memory”Memory entries are short freeform notes attached to any definition — file, view, component, or request. They exist so that agents can carry forward context that isn’t recoverable from the source code: quirks, invariants, workarounds, “you have to click this twice” lore.
memory: - Past dates render but are aria-disabled - Range: 1st click = start, 2nd = end, 3rd resetsDesign points:
- Each entry is a single human-readable sentence or short bullet.
- Entries on a component apply whenever that component is matched on the current view.
- Entries on a view apply whenever the current URL matches that view’s route.
- File-level entries apply whenever any definition from that file is active.
- Entries on a request apply in the network-trace detail view.
- Conforming SDKs SHOULD surface applicable memory entries in a
[Guide]section at the top of enriched output.
Route matching
Section titled “Route matching”Routes use glob patterns against the URL pathname.
*matches exactly one path segment:/users/*matches/users/42, not/users/42/edit**matches any depth of segments:/admin/**matches/admin,/admin/users,/admin/users/42/edit- Literal segments match themselves
- Matching is case-sensitive
- Query string and fragment are ignored
- Trailing slashes are normalized away before matching
For requests, Express-style :param segments are normalized to *. These are equivalent:
- route: /api/users/:id/orders # same as below- route: /api/users/*/ordersFirst match wins. Definition order is priority order. Authors should list more-specific routes before more-general ones.
Global vs view-scoped
Section titled “Global vs view-scoped”Components and requests can be declared at the file root or nested inside a view.
- Global (
components:orrequests:at file root): matched against every view. - View-scoped (nested inside a
view): matched only when that view is active. - They are additive. A view that defines its own components receives both the global components and its own.
components: - name: Navigation # global — matched everywhere selector: 'nav[data-component="Navigation"]'
views: - name: Dashboard route: /dashboard components: - name: DashboardLayout # scoped — only on /dashboard selector: '[data-component="DashboardLayout"]'Conformance
Section titled “Conformance”A conforming SDK:
- MUST accept any file that validates against
sightmap.schema.json - MUST reject any file that does not
- MUST implement route matching as specified
- MUST implement global vs view-scoped precedence as specified
- SHOULD surface
memoryentries to the agent when the parent definition is active - MAY ignore fields it doesn’t use (e.g.
descriptionis never surfaced at runtime by Subtext today) - MAY implement additional, non-standard behavior as long as it doesn’t change the meaning of conforming inputs
See Conformance fixtures for the language-agnostic test suite.
Open questions
Section titled “Open questions”These are explicitly unresolved in v1 and candidates for SEPs:
- Inheritance or import across files (today the only merge is implicit directory-level concatenation)
- Parameterized memory — interpolating runtime values into memory entries
- Schema for validating the shape of
response.fieldsagainst real responses (todayfieldsis documentary, not enforced) - Macros — learned trajectories that replay and heal when the site changes (teased in the website; not yet in the spec)
See seps/README.md to propose.