Tags: addressing, index, dx
Coordinates are a developer-facing way to name record sets by
application surface. They sit above the record/fact/interlace core: a
coordinate is useful input to get, list,
store, selector DSLs, indexes, command-line tools, and UI
displays, but it is not the source of truth. Lace truth remains
validated record bytes, record hashes, record facts, Datalog policy,
exchange plans, and store-machine boundaries.
This document defines coordinate syntax and the raw local index ordering used before application policy chooses selected versions.
Hash addresses, coordinates, surfaces, version selectors, and raw tip ordering.
A Unified Resource Coordinate (URC) can name an immutable record by hash or name a coordinate in an application surface:
hash-address = "////" hash-text
coordinate = "//" group-path "//" app-path "//" name-path [version-selector]
Implementations MUST parse hash addresses before coordinate addresses
because ////<hash> also starts with
//.
////<hash>.//<group-path>//<app-path>//<name-path>.Hash addresses are immutable record identifiers. Coordinates resolve through a local index of validated record facts and may identify many candidate versions. Applications that need selected truth apply lacegram, exchange-policy, or application evaluation after candidate discovery.
Coordinates may appear in developer APIs such as:
get(target, "//u//ding//links/server-one")
list(target, "//u//ding//links/")
store(target, records, options)
Those APIs must still operate through Lace’s normal authority boundaries:
Record store operation;A public coordinate API MUST NOT become raw store inspection or mutation. A runtime or store MAY maintain coordinate indexes internally to answer bounded store reads and porcelain operations, but applications should receive records through interlace event streams or operation results, not through unrestricted store iteration.
Coordinate terms:
group-path: community, namespace, device, or local
scope path, written root-to-leaf.app-path: application or app-defined contract path
inside the group.name-path: app-local hierarchical name.app coordinate:
//<group-path>//<app-path>//.coordinate:
//<group-path>//<app-path>//<name-path>.The two // field delimiters separate Group from App and
App from Name. These field delimiters are coordinate syntax and are not
stored in record Group, App, or
Name headers. Single / bytes inside each field
are segment delimiters for that field’s path.
A record indexed at a coordinate has record facts whose
Group, App, and Name fields match
that coordinate. The index does not make the coordinate authoritative;
it is a materialized view over validated record facts.
Rules:
group-path MUST be one or more slash-separated Group
segments as defined by 010;app-path MUST be one or more slash-separated App
segments as defined by 010;name-path MUST be one or more slash-separated Name
segments as defined by 010;// field
delimiters after the leading // coordinate marker;/,
or contain an empty segment;| is forbidden in Group, App, and Name segments, so
/|/ unambiguously starts version selection after the Name
path.Examples:
| Coordinate | Group | App | Name |
|---|---|---|---|
//u//docs//index.html |
u |
docs |
index.html |
//u//ding//links/server-one |
u |
ding |
links/server-one |
//eu/lab//chat/message//room-7/1 |
eu/lab |
chat/message |
room-7/1 |
//eu/lab//chat//message/room-7/1 |
eu/lab |
chat |
message/room-7/1 |
//eu/lab/research//forum//post/2026/06/14/1 |
eu/lab/research |
forum |
post/2026/06/14/1 |
Malformed examples:
//g////key has empty App.//g//api// has empty Name.//g//api//key//extra has an extra field delimiter
inside Name.//g//bad//api//key has too many field delimiters.//g/..//api//key has an invalid Group segment.Developer surfaces often need a coordinate prefix, such as all record
names under //u//ding//links/. A prefix is not an exact
coordinate and not a record address. It is selector input that compiles
to policy over Field(P,'Group',...),
Field(P,'App',...), and Field(P,'Name',...)
facts, possibly with string-shape or path-prefix predicates.
For example, a first-follow style selector for
//u//ding//links/ becomes policy that selects records
with:
Field(P, 'Group', _, 'u')
Field(P, 'App', _, 'ding')
Field(P, 'Name', _, K)
TextShape(K, 'links/', '', '')
The exact lowered lacegram is an implementation detail of the selector DSL, but it must preserve the same query-view and store-machine boundaries as a hand-written policy.
A top coordinate has no version selector and resolves to the raw
coordinate tip when a raw tip is needed. A version-selector coordinate
includes /|/... and may select a narrower version set or
one exact record.
Common forms:
| Coordinate form | Meaning |
|---|---|
//g//a//k |
raw coordinate tip candidate |
//g//a//k/|/plex/<tai>/<hash> |
exact Plex record version |
//g//a//k/|/seal/<verifier>/<tai>/<hash> |
exact Seal record version |
The raw local index tip is highest TAI, then highest
hash. This raw tip rule is only deterministic candidate ordering. It
does not replace lacegram, exchange policy, query-view rules,
signature/application authority, or interlace convergence.
Interlace event streams are record/lifecycle streams. They report records, record hashes, completion, fixed points, closure, and errors. They should not report coordinate-index internals as normal events.
Porcelain may accept coordinates or prefixes as friendly inputs and may include the requested coordinate in an operation result for correlation. The operation’s observable record results must still be records selected by policy and persisted through store machines. A duplicate save, policy-refused or invalid input record, stale scope, or incomplete result is reported as an operation outcome, not as a coordinate-index mutation event.
Coordinates make Lace easier to use, search, display, and debug. They remain a layer above core truth. When in doubt, expose coordinates as inputs to policy and porcelain, keep raw indexes store/runtime-internal, and let interlace event streams expose record/lifecycle outcomes.