journal · operations surface
Bindings
| Primary | http |
|---|---|
| HTTP | prefix /v1 |
Operations
| Name | Kind | Binding | Request | Response | Parameters | Refusals |
|---|---|---|---|---|---|---|
create | mutation | POST /v1/create |
CreateRequest | CreateResult | invalid, not_found, exists, conflict, idempotency_mismatch, unavailable, internal | |
resolve | read | POST /v1/resolve |
ResolveRequest | ResolveResult | invalid, not_found, unavailable, internal | |
children | read | POST /v1/children |
ChildrenRequest | ChildrenResult | invalid, not_found, limit_exceeded, unavailable, internal | |
head | read | POST /v1/head |
HeadRequest | HeadResult | invalid, not_found, unavailable, internal | |
append | mutation | POST /v1/append |
AppendRequest | AppendResult | invalid, not_found, conflict, idempotency_mismatch, limit_exceeded, unavailable, internal | |
read | read | POST /v1/read |
ReadRequest | ReadResult | invalid, not_found, limit_exceeded, unavailable, internal | |
query | read | POST /v1/query |
QueryRequest | QueryResult | invalid, not_found, limit_exceeded, unavailable, internal | |
livez | operational | GET /livez |
Health | invalid | ||
health | operational | GET /healthz |
Health | invalid | ||
describe | operational | GET /describe |
Describe | invalid | ||
describe_file | operational | GET /describe/{file...} |
file: string (required) | invalid, not_found |
Refusals
| Code | HTTP | Meaning |
|---|---|---|
invalid | 400 | a value is outside its grammar, encoding, structural rule or selection; a cutoff inside a batch or in the future; a continuation that does not fit its request |
not_found | 404 | the root or exact space does not exist, or the requested contract file is not listed |
exists | 409 | the child key is already occupied under that parent |
conflict | 409 | expected_cutoff differs from the committed cutoff |
idempotency_mismatch | 409 | the scoped operation ID already committed a different normalized request |
limit_exceeded | 413 | a declared resource bound would be exceeded: a value, a batch, a page, a snapshot or a continuation |
unavailable | 503 | the engine, a selected history or a required observation cannot currently be served |
internal | 500 | an unexpected implementation failure occurred; a mutation's outcome may be uncertain |
Files served
- SURFACE.md
- HTTP.md
- operations.json
- openapi.json
- schema/AppendRequest.schema.json
- schema/AppendResult.schema.json
- schema/ChildrenRequest.schema.json
- schema/ChildrenResult.schema.json
- schema/CreateRequest.schema.json
- schema/CreateResult.schema.json
- schema/Describe.schema.json
- schema/Entry.schema.json
- schema/EntryRef.schema.json
- schema/Error.schema.json
- schema/Filter.schema.json
- schema/HeadRequest.schema.json
- schema/HeadResult.schema.json
- schema/Health.schema.json
- schema/QueryRequest.schema.json
- schema/QueryResult.schema.json
- schema/ReadRequest.schema.json
- schema/ReadResult.schema.json
- schema/ResolveRequest.schema.json
- schema/ResolveResult.schema.json
- schema/Snapshot.schema.json
- schema/Space.schema.json
- schema/SpaceRef.schema.json
SURFACE.md
The Journal surface
Status: semantic contract, 2026-09-12 — the space-scoped surface of proposal 0016, adopted by order 0002. This lane (J0) implements it on an in-memory engine; the durable provider is J1.
Journal retains one tree of spaces under a root. Every space, the root and every intermediate node included, owns one append-only journal of facts. Creating a child space is recorded in the parent's journal, so the tree replays through ordinary reads. This is the complete semantic contract. The HTTP binding carries it without adding operations or changing their meaning. Implementation and verification status belong in the service's README.
Boundary
Journal does not interpret a fact. It prescribes no predicate grammar, types, references, signatures, attribution, retractions or current-value rules. A consumer's withdrawal is another fact; nothing removes an earlier entry. Journal enforces no authority: it is an identity-blind backend behind a deployment boundary and an explicitly selected higher layer.
There is no deletion, renaming, moving or replacement of spaces (the lifecycle is additive), no transaction across journals or across Bytes and Journal, no total order across spaces, and no global snapshot. Retention, collection, subscriptions, joins, traversal and full-text search are above this contract.
Values and limits
| Value | Definition |
|---|---|
| Root ID | rt_ followed by 32 lowercase hexadecimal digits; the logical hierarchy, independent of any endpoint |
| Space ID | spc_ followed by 32 lowercase hexadecimal digits; one continuing space and its journal, allocated at creation |
| Instance ID | jinst_ followed by 32 lowercase hexadecimal digits; the store lineage, reported operationally |
| Key | 1..255 bytes of UTF-8 with no Unicode control character (C0, DEL and C1) and no /; compared byte for byte, never normalized. . and .. are ordinary keys |
| Path | An array of keys under the root; the empty array is the root |
| Operation ID | 1..128 ASCII characters from [A-Za-z0-9._:-] |
| Position | Integer from 1 through 9,007,199,254,740,991 (2^53-1), meaningful within one journal |
| Cutoff | 0, or the final position of a committed batch |
| Fact | One canonical Ontos value under the profile below, at most 1 MiB of canonical bytes |
| Append batch | 1..128 facts; at most 4 MiB of canonical fact bytes in total. An empty batch is a malformed shape (invalid); exceeding either bound is limit_exceeded |
| Page | Default 64, at most 128 entries or children; at most 4 MiB of canonical fact bytes; at most 4,096 entry candidates and 16 MiB of fact bytes examined |
| Snapshot | At most 4,096 spaces and 4 MiB of canonical JSON; the same inspection budget for its topology, across the whole scope |
| Cursor | At most 4 KiB; opaque; restart-safe |
| Request envelope | At most 8 MiB of JSON, including a complete query continuation |
MiB means 1,048,576 bytes. Byte limits count decoded values, never transport
encoding. These limits are an operational admission profile, advertised by
/describe; they do not narrow Ontos's semantics or equality. Exceeding a
declared bound is limit_exceeded and does not certify the remainder.
SpaceRef = {root_id, space_id}
Space = {root_id, space_id, path}
EntryRef = {root_id, space_id, position}
Entry = {ref, fact, origin, batch: {first, last}}
/ is the one character a key may not carry, and the reason is rendering
rather than storage: a path is an array on the wire, but diagnostics, logs and
command lines render it as text, and ["a/b"] and ["a", "b"] would render
alike. A consumer needing / inside one name encodes it; every reader of a
path keeps an unambiguous one. . and .. carry no meaning here — this
interface has no filesystem and never resolves a path relative to another.
IDs compare byte for byte; clients treat them as opaque and never derive them
from content. A space's identity never changes; its path is its location
under the current topology and, under the additive lifecycle, never changes
either. Equal facts at different positions are distinct occurrences. Every
operation that selects a space takes an exact SpaceRef; only resolve
accepts a path.
Facts
The profile is ulab-journal-facts-v1: the existing Ontos L0 value model,
the frozen L1 compound reading and the frozen ontos-codec-v1 encoding. A
fact is a non-empty tuple whose first child is any atom, the predicate; the
remaining children are arbitrary values. Labels may be empty or non-UTF-8;
Journal adds no grammar for them. Equality is Ontos structural identity,
equivalently equality of the canonical codec bytes. Decoding a submitted value
and re-encoding it must reproduce the submitted bytes; any other encoding is
invalid. Values are decoded under depth ≤ 256 (the root at 0, each
tuple-child edge adding 1), tuple arity ≤ 65,536 and atom payload ≤ 1 MiB.
The service produces one value itself. When a child is created, the parent's journal receives the creation fact
creation(key, id) = Tuple(Atom("ulab.journal.child_created.v1"), text(key), text(id))
with text the Ontos utf8-text embedding. A caller may append a value equal
to it; that entry has origin append and creates nothing.
Origins and batches
Every entry carries its origin: create for the creation entry the service
appended, append for everything a caller appended. Every entry carries its
batch, the contiguous range committed together with it; a batch's last is
a cutoff. The current cutoff of a space is the end of its latest committed
batch, or 0 when empty. It is also the observation of the space's immediate
children: the child set at cutoff c is exactly the set of creation entries
at positions ≤ c, in position order.
Operations
| Operation | Request | Result |
|---|---|---|
create |
parent, key, operation_id, optional expected_cutoff |
child, parent_entry, parent_cutoff, replayed |
resolve |
space, or root_id with path |
space or null |
children |
space, optional through, cursor, limit |
space, through, children, optional next_cursor |
head |
space |
space, cutoff |
append |
space, facts, operation_id, optional expected_cutoff |
space, first, last, cutoff, replayed |
read |
space, optional after, through, limit, filter |
space, through, entries, scanned_through, optional next_after |
query |
space, optional filter, max_depth, snapshot, cursor, limit |
snapshot, entries, optional next_cursor |
create
create(parent, key, operation_id, expected_cutoff?) creates a child space
and its empty journal under an existing parent in one atomic mutation: it
allocates the child's identity, establishes its key uniquely among the
parent's children, appends the creation fact to the parent's journal with
origin create, and stores the receipt. The result names the child, the
creation entry in the parent and the parent's cutoff after it, which equals
the entry's position.
An absent parent is not_found; a key already occupied under that parent is
exists; a supplied expected_cutoff that differs from the parent's
committed cutoff at the commit decision is conflict. An absent or null
expected_cutoff is unconditional. The root is provisioned with the
hierarchy and advertised by /describe; create makes descendants only.
The create operation-ID scope is the parent: (root_id, parent, "create", operation_id). A repeated request with an equal normalized body returns the
original result with replayed = true, even after the parent's journal grew;
a different body under the same scoped identifier is idempotency_mismatch.
Receipt replay precedes re-evaluation of expected_cutoff.
resolve
resolve(space) returns the space of an exact identity, with its path;
an unknown identity or root is not_found. resolve(root_id, path)
returns the current occupant of a path under current committed topology, or
null when the path is unoccupied — absence is an ordinary answer to "who
is here". Exactly one form is given. Resolution never creates a space.
children
children(space, through?, cursor?, limit?) enumerates the immediate
children visible at the cutoff through: the fold of the parent's creation
entries at positions ≤ through, in creation order, each with its key, its
space and the creation entry. When neither through nor cursor is given,
the current committed cutoff is captured once. An explicit through must be
a cutoff of that journal: an interior position or a future position is
invalid, never rounded. Pages enumerate exactly the selected set, each
child once; a cursor binds the space and the cutoff, and an explicit
through that disagrees with a cursor is invalid. Later creations cannot
enter an earlier observation. An existing space with no children returns an
empty list with its cutoff; an absent space is not_found.
Enumeration obeys the page's inspection budget; non-creation entries are
nonmatches. A non-final page returns an advancing next_cursor, never
passing an undelivered child; its absence means the entire selected set has
been enumerated. An empty page may carry an advancing cursor.
head
head(space) returns the committed cutoff from one committed snapshot: 0 for
an empty journal, else the end of the latest batch. It does not lock the
journal. An unknown space is not_found.
append
append(space, facts, operation_id, expected_cutoff?) appends the supplied
non-empty batch, in input order, as one atomic mutation. Every fact receives
a position; every entry has origin append; cutoff equals last. No
partial batch becomes visible. The service validates the representation and
the resource bounds only.
If expected_cutoff is absent or null, the append is unconditional; if an
integer is present it must equal the current cutoff at the commit decision,
and 0 requires an empty journal. A mismatch is conflict, with the
expected and actual cutoffs, and appends nothing. Concurrent successful
appends to one journal have one committed order and occupy non-overlapping
contiguous ranges. There is no ordering guarantee between journals.
The append operation-ID scope is the space: (root_id, space, "append", operation_id). For an existing successful receipt the service compares the
normalized request and returns the original result with replayed = true;
the returned bounds are the original receipt's, even if later appends exist.
A different normalized request under the same scoped identifier is
idempotency_mismatch and appends nothing.
read
read(space, after?, through?, limit?, filter?) returns one page of the
fixed prefix (after, through] of one journal, ordered by position.
after defaults to 0 and is exclusive. through is inclusive; when omitted
it is captured from the current cutoff once. An explicit through must be a
cutoff of that journal — 0 or the end of a committed batch: an interior or
future position is invalid, never rounded. The request must satisfy
0 ≤ after ≤ through ≤ current cutoff; a continuation (after > 0) must
resend through, since omitting it would select a new cutoff. limit
defaults to 64 and is at most 128.
A page stops at its output bounds (entries and fact bytes) or its inspection
bounds (candidates and fact bytes examined). A position is accounted for
only when its entry was returned or established not to match; an inspected
match that does not fit the remaining page is not passed — the next page
delivers it. scanned_through is the last accounted position, satisfying
after ≤ scanned_through ≤ through. Every non-final page advances beyond
after and returns next_after = scanned_through; a final page omits
next_after, and scanned_through then equals through. With
after = through, including an empty journal at 0, the page is empty with no
continuation. Entries is always an array.
To reconstruct a stable prefix, keep the first response's through and pass
it on every continuation, using next_after as after. Concurrent appends
raise the current cutoff but cannot change the selected prefix. There is no
server-side cursor state for reads.
filters
A filter is a conjunction of structural conditions, compared by Ontos
equality, inferring nothing: predicate, which must encode an atom;
arguments, each requiring the argument at index (0 is the first argument
after the predicate) to equal a canonical value — an index outside the declared
tuple-arity domain is invalid, since no value under the profile has one, and
a request that cannot match is a malformed coordinate rather than an empty
result; origin; and positions,
bounding matches to (after, through]. Filtered results keep their
original references, order and batches. Each encoded filter value obeys the
fact value bounds.
The normalized filter — every member present, absent predicate and origin as
null, conditions sorted by index then by unsigned canonical bytes with
identical conditions collapsed, absent position bounds as 0 and 2^53-1 —
has a digest: the normalized JSON document projected through
ontos-data-json/1, wrapped as Tuple(Atom("ulab.journal.filter.v1"), document), encoded with ontos-codec-v1 and hashed with SHA-256 over the
raw codec bytes. Query cursors bind that digest.
query
query(space, filter?, max_depth?, snapshot?, cursor?, limit?) reads the
space and its descendants over an explicit snapshot — a recursively
complete selection of journal prefixes. Without a snapshot the service
captures one before returning any page:
- record the selected space's cutoff;
- derive its children at that cutoff;
- record each child's cutoff and repeat, within
max_depthmeasured from the selected space at depth 0 (0selects only that space; absent or null selects all descendants); - complete the manifest within the space-count, canonical-JSON-size and
topology-inspection bounds, and within a complete continuation's request
size, or refuse
limit_exceeded— never a partial manifest.
The manifest lists every covered space in depth-first preorder by child
creation — the scope first, then each child's entire selected subtree —
including intermediate spaces and empty journals, so "no matches" and "not
examined" are distinguishable. The normalized choice of depth is always
retained in snapshot.max_depth. Entries follow the manifest's space order
and position order within each space, each with its reference, origin and
batch. Pages obey the same output, inspection and accounted-for rules as
read; an empty page may carry an advancing cursor, including progress
across completed empty spaces; no cursor means every selected prefix is
exhausted.
A continuation resubmits the manifest, the unchanged filter and the cursor.
The request's space must equal snapshot.scope; an omitted max_depth
uses the manifest's value and an explicit one must equal it. The cursor
binds the manifest's digest, the filter's digest and the traversal position;
any disagreement is invalid. A retained manifest can restart a query
without a cursor, including with a different filter.
A submitted manifest is validated against the creation records: it lists the
scope exactly once and, below the depth bound, every child visible at each
listed parent's cutoff, in creation order; no duplicate, unreachable or
out-of-scope space; paths and identities agreeing with the creation records;
every cutoff 0 or a committed batch boundary of its journal. An inconsistent
manifest is invalid; a listed space that does not exist is not_found.
Another internally valid selection, with older cutoffs, is accepted: a
manifest is an explicit input, not an attestation of who captured it.
The snapshot's digest follows the filter's construction with the tag
ulab.journal.snapshot.v1 over the normalized manifest (every path an array,
max_depth present). The result is reproducible over an explicit set of
prefixes; it is not a simultaneous global snapshot. The provider may
serve from indexes derived from its own journals; consumers never mirror
facts into ancestors.
Retry, failure and persistence
Successful mutation receipts are retained for the lifetime of their scope and are returned through retries, never through a separate lookup. The normalized body compares semantic values: facts as bytes, order significant, the effective precondition included, absent and null preconditions the same, explicit zero different; JSON whitespace and member order are immaterial. Rejected requests reserve no operation IDs.
A successful mutation acknowledges the complete atomic commit, including its receipt. Reads observe only committed state. Cancellation before commit can prevent a mutation; cancellation, timeout, a lost reply or a service failure does not prove that it did. Resolve uncertainty by retrying the same scoped operation ID and exact request against the same continuing history; never switch to a new operation ID because a response was lost.
Identity continuity preserves acknowledged history, not only identifiers: a
supported restart or restore serves the same root_id, space_ids,
positions, origins, batch boundaries, receipts and cursors, and the same
identity never exposes divergent committed histories. A public export through
read is not a provider migration. The in-memory engine of this lane
retains nothing across a restart and says so; the durable provider's
guarantees are stated with its acceptance.
Refusals
| Code | Meaning and stable details |
|---|---|
invalid |
Malformed or out-of-range input; details.field names the input when available. An interior or future cutoff, a continuation that does not fit its request, and an inconsistent manifest are invalid |
not_found |
The root or exact space does not exist; details.subject names the missing selection |
exists |
The child key is occupied under that parent; details.key |
conflict |
The precondition failed; details.expected_cutoff and details.actual_cutoff are integers |
idempotency_mismatch |
A successful receipt exists for the scoped operation ID with a different normalized request |
limit_exceeded |
A declared resource bound would be exceeded; details.limit names it |
unavailable |
The engine, a selected history or a required observation cannot currently be served |
internal |
An unexpected service failure prevented a normal result; a mutation's outcome may be uncertain |
Every operation can refuse invalid, unavailable or internal. Every
operation that selects a space can refuse not_found. create additionally
refuses exists, conflict and idempotency_mismatch; append refuses
conflict, idempotency_mismatch and limit_exceeded; children, read
and query refuse limit_exceeded. Clients decide from the code and the
documented details, never from message prose.
Authority
This implementation is an identity-blind backend. It neither authenticates callers nor enforces access rules: any caller that can reach its listener can create spaces and read or append to any space whose identity it knows. Payload bytes that resemble identities, signatures or grants receive no privileged treatment. Deployment boundaries and an explicitly selected higher layer — Dawn, in the ULab deployment — provide access control. Space and root identities, health checks and possession of a receipt grant no authority.
HTTP.md
Journal over HTTP
Status: primary binding of the 2026-09-12 surface.
HTTP request and response is Journal's binding in this lane; a WebSocket peer
binding of the same operation table is deferred (proposal 0016 §8). The
service name is journal; application routes use /v1. Standalone
operation defaults to http://127.0.0.1:8092. Clients select an explicit
endpoint using --server, then ULAB_JOURNAL_SERVER, then that default.
TLS and network access are deployment concerns; this listener authenticates
no request, including self-description requests.
Routes below are native listener paths. ULab deployment mounts operations at
/api/operations, stripping that prefix before forwarding. Management uses
the separate /api/management prefix, following the
family contract.
This document describes the operations listener. The independently bound
management listener defaults to 127.0.0.1:8093 and
has its own contract files and Ulab-Surface: management discriminator.
Common rules
Every response, including router failures, carries:
Ulab-Service: journal
Ulab-Surface: operations
Ulab-Contract: 2026-09-12
Every semantic operation is a POST to /v1/<operation> whose JSON body is
the request object; there are no query parameters on application routes.
A request may omit Content-Type. When present, its parsed media type must
be application/json, with no parameter other than an optional UTF-8
charset. JSON requests contain one object with exactly the documented
members, followed only by whitespace. Required members are present and
non-null; optional members are omitted or, where the surface allows null,
null. Unknown members, case variants of member names, duplicate member names,
malformed UTF-8, unpaired Unicode surrogates and trailing data are refused.
The request envelope is limited to 8 MiB (8,388,608 bytes), independently of
the decoded value bounds. Oversized envelopes return status 413 and
invalid; a value exceeding its declared bound returns 413 and
limit_exceeded. Facts, filter predicates and filter values travel as
canonical padded standard base64 (RFC 4648 §4) of their canonical Ontos
bytes, without whitespace; decoding and re-encoding must reproduce the string
exactly, so missing or unnecessary padding, nonzero unused pad bits and the
URL-safe alphabet are refused. Paths are JSON arrays of keys, never joined
strings. Numeric controls are canonical nonnegative integers at most
9007199254740991; fractions, exponents and signs are refused. Cursors are
opaque strings the service issued.
Responses use application/json, except a served description file's
documented media type. Clients may tolerate unknown optional response members
but must validate required members, identities, positions and mutually
consistent bounds. They must reject a missing or different Ulab-Service as
a protocol error, separate from a service refusal. A different contract date
is exposed to the caller rather than automatically rejected.
Application routes
| Operation | Method and route | Request | Success |
|---|---|---|---|
create |
POST /v1/create |
CreateRequest |
201 new, 200 replay; CreateResult |
resolve |
POST /v1/resolve |
ResolveRequest |
200; ResolveResult, whose space may be null |
children |
POST /v1/children |
ChildrenRequest |
200; ChildrenResult |
head |
POST /v1/head |
HeadRequest |
200; HeadResult |
append |
POST /v1/append |
AppendRequest |
201 new, 200 replay; AppendResult |
read |
POST /v1/read |
ReadRequest |
200; ReadResult |
query |
POST /v1/query |
QueryRequest |
200; QueryResult |
The operation table and schemas are published as operations.json,
openapi.json and schema/<Type>.schema.json. The surface's
semantics govern where generated shape descriptions are silent.
POST /v1/create
POST /v1/create HTTP/1.1
Content-Type: application/json
{"parent":{"root_id":"rt_11111111111111111111111111111111","space_id":"spc_22222222222222222222222222222222"},"key":"projects","operation_id":"create-projects-1"}
A new child returns status 201:
{
"child": {"root_id": "rt_11111111111111111111111111111111", "space_id": "spc_33333333333333333333333333333333", "path": ["projects"]},
"parent_entry": {"root_id": "rt_11111111111111111111111111111111", "space_id": "spc_22222222222222222222222222222222", "position": 1},
"parent_cutoff": 1,
"replayed": false
}
Retrying the same request returns status 200 and the same result with
replayed: true. expected_cutoff is the only optional member; omitted or
null means unconditional. A taken key is 409 exists; a stale precondition
is 409 conflict; an absent parent is 404 not_found.
POST /v1/resolve
Either {"space": {"root_id": …, "space_id": …}} or
{"root_id": …, "path": ["projects", "claude-cli"]}; the empty array is the
root. Status 200 carries {"space": Space} or {"space": null} for an
unoccupied path. An unknown exact identity or root is 404 not_found.
POST /v1/children
POST /v1/children HTTP/1.1
Content-Type: application/json
{"space":{"root_id":"rt_1111…","space_id":"spc_2222…"},"limit":2}
Status 200 returns one page of the child set at the selected cutoff:
{
"space": {"root_id": "rt_1111…", "space_id": "spc_2222…"},
"through": 3,
"children": [
{"key": "projects", "space": {"root_id": "rt_1111…", "space_id": "spc_3333…", "path": ["projects"]}, "created_at": {"root_id": "rt_1111…", "space_id": "spc_2222…", "position": 1}},
{"key": "ledger", "space": {"root_id": "rt_1111…", "space_id": "spc_4444…", "path": ["ledger"]}, "created_at": {"root_id": "rt_1111…", "space_id": "spc_2222…", "position": 2}}
],
"next_cursor": "eyJr…"
}
Continue with {"space": …, "cursor": "eyJr…", "limit": 2}; a final page
omits next_cursor. through and cursor may be combined only when they
agree. An interior or future through is 400 invalid.
POST /v1/head
{"space": SpaceRef} returns {"space": SpaceRef, "cutoff": N}.
POST /v1/append
POST /v1/append HTTP/1.1
Content-Type: application/json
{"space":{"root_id":"rt_1111…","space_id":"spc_3333…"},"operation_id":"append-1","expected_cutoff":0,"facts":["AQEAAXA=","AQIAAXAAAf8="]}
If the journal is empty, the result is status 201:
{"space": {"root_id": "rt_1111…", "space_id": "spc_3333…"}, "first": 1, "last": 2, "cutoff": 2, "replayed": false}
An exact semantic retry returns status 200, the original bounds and
replayed: true. facts is a non-null array of 1..128 base64 strings, each
one canonical Ontos fact of at most 1 MiB, at most 4 MiB in total. A failed
precondition returns:
HTTP/1.1 409 Conflict
Content-Type: application/json
{"error":"conflict","message":"the committed cutoff differs from the expected cutoff","details":{"expected_cutoff":0,"actual_cutoff":2}}
POST /v1/read
POST /v1/read HTTP/1.1
Content-Type: application/json
{"space":{"root_id":"rt_1111…","space_id":"spc_3333…"},"through":2,"limit":1,"filter":{"predicate":"AAFw"}}
Status 200 returns one page:
{
"space": {"root_id": "rt_1111…", "space_id": "spc_3333…"},
"through": 2,
"entries": [{"ref": {"root_id": "rt_1111…", "space_id": "spc_3333…", "position": 1}, "fact": "AQEAAXA=", "origin": "append", "batch": {"first": 1, "last": 2}}],
"scanned_through": 1,
"next_after": 1
}
Continue with after: 1, through: 2 and the same filter. A continuation
without through is 400 invalid. A filter object carries any of
predicate, arguments ([{"index", "equals"}]), origin and
positions ({"after", "through"}).
POST /v1/query
POST /v1/query HTTP/1.1
Content-Type: application/json
{"space":{"root_id":"rt_1111…","space_id":"spc_2222…"},"max_depth":1,"limit":64}
Status 200 returns the captured snapshot and the first page:
{
"snapshot": {
"scope": {"root_id": "rt_1111…", "space_id": "spc_2222…"},
"max_depth": 1,
"spaces": [
{"space": {"root_id": "rt_1111…", "space_id": "spc_2222…", "path": []}, "through": 3},
{"space": {"root_id": "rt_1111…", "space_id": "spc_3333…", "path": ["projects"]}, "through": 2},
{"space": {"root_id": "rt_1111…", "space_id": "spc_4444…", "path": ["ledger"]}, "through": 0}
]
},
"entries": ["…"],
"next_cursor": "eyJr…"
}
Continue with the same space, the returned snapshot, the unchanged
filter and the cursor. A capture that would exceed the snapshot bounds or
the 8 MiB request budget of a complete continuation is 413 limit_exceeded.
An inconsistent submitted manifest is 400 invalid.
Refusal and router mapping
Errors use this envelope; details is present when documented data is available:
{"error":"invalid","message":"space.space_id must be spc_ followed by 32 lowercase hexadecimal digits","details":{"field":"space.space_id"}}
| Code | HTTP status | Meaning |
|---|---|---|
invalid |
400 | Invalid member, value, encoding, cutoff, continuation, manifest or request shape |
not_found |
404 | Unknown root, exact space or route |
exists |
409 | The child key is occupied |
conflict |
409 | The expected cutoff differs from the committed cutoff |
idempotency_mismatch |
409 | The scoped operation ID already has a different successful request |
limit_exceeded |
413 | A declared resource bound would be exceeded |
unavailable |
503 | The service cannot presently complete the operation |
internal |
500 | Unexpected service failure |
invalid also maps to 413 for an oversized request envelope and to 405 for
an unsupported method on a known route; a 405 includes Allow naming the
supported method. Unknown paths return 404 not_found; reserved but
unimplemented /metrics and /statusz also return 404. Clients must not
parse message text to distinguish errors. A transport failure, truncated
response or invalid service header is a client-side protocol failure, not a
refusal.
Losing a mutation response leaves its outcome uncertain. Retry the original request and operation ID against the original service. A successful response means the complete mutation and its receipt were committed; an interrupted connection is not proof that they were not.
Operational routes
These implement the ULab operational profile and are not semantic operations. They accept no body or query parameters.
| Method and route | Successful response | Refusals |
|---|---|---|
GET /livez |
200, health envelope with empty checks |
Invalid request shape; never readiness status 503 |
GET /healthz |
200 when all checks are ok, health envelope |
503 with status: "failing" when a dependency check fails |
GET /describe |
200, embedded description JSON | Invalid request shape |
GET /describe/{file} |
200, listed contract file verbatim | 404 not_found for an unlisted file; invalid request shape |
The health envelope contains status, service, contract, build,
time, checks and identity. identity carries root_id,
root_space_id and journal_instance_id; build carries the full source
revision, dirty and go; time is informational UTC time. Health has an
engine check and an identity check.
The build reads version-control information from the executable when available. Builders that disable or cannot supply that information stamp these string variables at link time:
nightforge.lab/ulab-journal/internal/buildinfo.Revision
nightforge.lab/ulab-journal/internal/buildinfo.Dirty
/describe reports the service, contract, build, identity, bindings, the
operation table, the refusal table, the declared limits, the pinned profiles
and the served file list. Its primary binding is http, with prefix /v1.
/describe/{file} serves exactly the files it lists, embedded at build time:
SURFACE.md, HTTP.md, operations.json, openapi.json and the generated
schema/*.schema.json files. Markdown is text/markdown; JSON is
application/json. Paths outside that list are never read from the host
filesystem.
Schemas
schema/AppendRequest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"facts": {
"items": {
"type": "string",
"contentEncoding": "base64"
},
"type": "array",
"maxItems": 128,
"minItems": 1
},
"operation_id": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"pattern": "^[A-Za-z0-9._:-]+$"
},
"expected_cutoff": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"facts",
"operation_id"
],
"title": "AppendRequest",
"description": "AppendRequest appends Facts as one atomic batch."
}
schema/AppendResult.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"first": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"last": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"cutoff": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"replayed": {
"type": "boolean"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"first",
"last",
"cutoff",
"replayed"
],
"title": "AppendResult",
"description": "AppendResult identifies the committed batch; Cutoff equals Last."
}
schema/ChildrenRequest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"through": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"cursor": {
"type": "string",
"maxLength": 4096
},
"limit": {
"type": "integer",
"maximum": 128,
"minimum": 0
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space"
],
"title": "ChildrenRequest",
"description": "ChildrenRequest enumerates a space's immediate children at the cutoff Through (omitted: captured once), continuing with Cursor."
}
schema/ChildrenResult.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"Child": {
"properties": {
"key": {
"type": "string"
},
"space": {
"$ref": "#/$defs/Space"
},
"created_at": {
"$ref": "#/$defs/EntryRef"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"key",
"space",
"created_at"
],
"description": "Child is one child at the parent's selected cutoff, with its creation entry."
},
"EntryRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"position": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"position"
],
"description": "EntryRef is the occurrence identity of one entry: a position in one journal."
},
"Space": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"path"
],
"description": "Space is a space's identity together with its path from the root."
},
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"through": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"children": {
"items": {
"$ref": "#/$defs/Child"
},
"type": "array"
},
"next_cursor": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"through",
"children"
],
"title": "ChildrenResult",
"description": "ChildrenResult is one page of the fixed child set."
}
schema/CreateRequest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"parent": {
"$ref": "#/$defs/SpaceRef"
},
"key": {
"type": "string",
"maxLength": 255,
"minLength": 1
},
"operation_id": {
"type": "string",
"maxLength": 128,
"minLength": 1,
"pattern": "^[A-Za-z0-9._:-]+$"
},
"expected_cutoff": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"required": [
"parent",
"key",
"operation_id"
],
"title": "CreateRequest",
"description": "CreateRequest creates a child space and its empty journal under Parent."
}
schema/CreateResult.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"EntryRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"position": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"position"
],
"description": "EntryRef is the occurrence identity of one entry: a position in one journal."
},
"Space": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"path"
],
"description": "Space is a space's identity together with its path from the root."
}
},
"properties": {
"child": {
"$ref": "#/$defs/Space"
},
"parent_entry": {
"$ref": "#/$defs/EntryRef"
},
"parent_cutoff": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"replayed": {
"type": "boolean"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"child",
"parent_entry",
"parent_cutoff",
"replayed"
],
"title": "CreateResult",
"description": "CreateResult is the original creation, including on replay: the child, the creation entry in the parent, and the parent's cutoff after it."
}
schema/Describe.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"BindingHTTP": {
"properties": {
"prefix": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"prefix"
],
"description": "BindingHTTP describes the HTTP binding in the describe document."
},
"Bindings": {
"properties": {
"primary": {
"type": "string"
},
"http": {
"oneOf": [
{
"$ref": "#/$defs/BindingHTTP"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"required": [
"primary"
],
"description": "Bindings names the primary binding and describes each offered one."
},
"Build": {
"properties": {
"revision": {
"type": "string"
},
"dirty": {
"type": "boolean"
},
"go": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"revision",
"dirty",
"go"
],
"description": "Build identifies the binary: the revision it was built from, whether that tree was dirty, and the Go version."
},
"HTTPBinding": {
"properties": {
"method": {
"type": "string"
},
"path": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"method",
"path"
],
"description": "HTTPBinding carries one operation over HTTP."
},
"Identity": {
"properties": {
"root_id": {
"type": "string"
},
"root_space_id": {
"type": "string"
},
"journal_instance_id": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"root_space_id",
"journal_instance_id"
],
"description": "Identity is the service-specific identity member of the health envelope and the describe document: the logical root, its space, and the store lineage."
},
"Limits": {
"properties": {
"max_position": {
"type": "integer"
},
"max_key_bytes": {
"type": "integer"
},
"max_fact_bytes": {
"type": "integer"
},
"max_append_facts": {
"type": "integer"
},
"max_append_bytes": {
"type": "integer"
},
"max_body_bytes": {
"type": "integer"
},
"max_page_entries": {
"type": "integer"
},
"default_page_entries": {
"type": "integer"
},
"max_page_bytes": {
"type": "integer"
},
"max_inspect_candidates": {
"type": "integer"
},
"max_inspect_bytes": {
"type": "integer"
},
"max_snapshot_spaces": {
"type": "integer"
},
"max_snapshot_bytes": {
"type": "integer"
},
"max_cursor_bytes": {
"type": "integer"
},
"max_value_depth": {
"type": "integer"
},
"max_tuple_arity": {
"type": "integer"
},
"max_atom_bytes": {
"type": "integer"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"max_position",
"max_key_bytes",
"max_fact_bytes",
"max_append_facts",
"max_append_bytes",
"max_body_bytes",
"max_page_entries",
"default_page_entries",
"max_page_bytes",
"max_inspect_candidates",
"max_inspect_bytes",
"max_snapshot_spaces",
"max_snapshot_bytes",
"max_cursor_bytes",
"max_value_depth",
"max_tuple_arity",
"max_atom_bytes"
],
"description": "Limits is the advertised operational admission profile."
},
"Operation": {
"properties": {
"name": {
"type": "string"
},
"kind": {
"type": "string"
},
"doc": {
"type": "string"
},
"params": {
"items": {
"$ref": "#/$defs/Param"
},
"type": "array"
},
"request": {
"type": "string"
},
"response": {
"type": "string"
},
"errors": {
"items": {
"type": "string"
},
"type": "array"
},
"http": {
"$ref": "#/$defs/HTTPBinding"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"name",
"kind",
"doc",
"params",
"errors"
],
"description": "Operation is the shared operation table row consumed by bindings and clients."
},
"Param": {
"properties": {
"name": {
"type": "string"
},
"kind": {
"type": "string"
},
"required": {
"type": "boolean"
},
"repeated": {
"type": "boolean"
},
"doc": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"name",
"kind",
"required",
"repeated",
"doc"
],
"description": "Param is a named input outside a JSON body."
},
"Profiles": {
"properties": {
"facts": {
"type": "string"
},
"codec": {
"type": "string"
},
"compound": {
"type": "string"
},
"data": {
"type": "string"
},
"data_json": {
"type": "string"
},
"equality": {
"type": "string"
},
"creation_predicate": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"facts",
"codec",
"compound",
"data",
"data_json",
"equality",
"creation_predicate"
],
"description": "Profiles names the frozen value, encoding and projection profiles the continuing history is pinned to."
},
"Refusal": {
"properties": {
"name": {
"type": "string"
},
"http": {
"type": "integer"
},
"meaning": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"name",
"http",
"meaning"
],
"description": "Refusal is one row of the refusal table: the surface's name for it, the status the HTTP binding maps it to, and its one-line meaning."
}
},
"properties": {
"service": {
"type": "string"
},
"contract": {
"type": "string"
},
"build": {
"$ref": "#/$defs/Build"
},
"identity": {
"oneOf": [
{
"$ref": "#/$defs/Identity"
},
{
"type": "null"
}
]
},
"bindings": {
"$ref": "#/$defs/Bindings"
},
"operations": {
"items": {
"$ref": "#/$defs/Operation"
},
"type": "array"
},
"refusals": {
"items": {
"$ref": "#/$defs/Refusal"
},
"type": "array"
},
"limits": {
"$ref": "#/$defs/Limits"
},
"profiles": {
"$ref": "#/$defs/Profiles"
},
"files": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"service",
"contract",
"build",
"bindings",
"operations",
"refusals",
"limits",
"profiles",
"files"
],
"title": "Describe",
"description": "Describe is the document of GET /describe: who this is, the root, which contract, which build, which bindings, which operations, which refusals, the limits and profiles, and which committed contract files GET /describe/{file} serves verbatim."
}
schema/Entry.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"Batch": {
"properties": {
"first": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"last": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"first",
"last"
],
"description": "Batch is the committed batch an entry belongs to."
},
"EntryRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"position": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"position"
],
"description": "EntryRef is the occurrence identity of one entry: a position in one journal."
}
},
"properties": {
"ref": {
"$ref": "#/$defs/EntryRef"
},
"fact": {
"type": "string",
"contentEncoding": "base64"
},
"origin": {
"type": "string",
"enum": [
"append",
"create"
]
},
"batch": {
"$ref": "#/$defs/Batch"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"ref",
"fact",
"origin",
"batch"
],
"title": "Entry",
"description": "Entry is one fact occurrence."
}
schema/EntryRef.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"position": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"position"
],
"title": "EntryRef",
"description": "EntryRef is the occurrence identity of one entry: a position in one journal."
}
schema/Error.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
},
"details": {
"type": "object"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"error",
"message"
],
"title": "Error",
"description": "Error is a refusal."
}
schema/Filter.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"ArgumentCondition": {
"properties": {
"index": {
"type": "integer",
"maximum": 65535,
"minimum": 0
},
"equals": {
"type": "string",
"contentEncoding": "base64"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"index",
"equals"
],
"description": "ArgumentCondition requires the argument at Index (0 is the first argument after the predicate) to equal the canonical Ontos value Equals."
},
"PositionRange": {
"properties": {
"after": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"through": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"description": "PositionRange bounds a filter to positions in (After, Through]."
}
},
"properties": {
"predicate": {
"type": "string",
"contentEncoding": "base64"
},
"arguments": {
"items": {
"$ref": "#/$defs/ArgumentCondition"
},
"type": "array"
},
"origin": {
"type": "string",
"enum": [
"append",
"create"
]
},
"positions": {
"oneOf": [
{
"$ref": "#/$defs/PositionRange"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"title": "Filter",
"description": "Filter is a conjunction of structural conditions compared by Ontos equality."
}
schema/HeadRequest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space"
],
"title": "HeadRequest",
"description": "HeadRequest selects one space's committed cutoff."
}
schema/HeadResult.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"cutoff": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"cutoff"
],
"title": "HeadResult",
"description": "HeadResult is the cutoff: 0 for an empty journal, else the end of the latest committed batch."
}
schema/Health.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"Build": {
"properties": {
"revision": {
"type": "string"
},
"dirty": {
"type": "boolean"
},
"go": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"revision",
"dirty",
"go"
],
"description": "Build identifies the binary: the revision it was built from, whether that tree was dirty, and the Go version."
},
"Check": {
"properties": {
"name": {
"type": "string"
},
"status": {
"type": "string",
"description": "ok | failing"
},
"detail": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"name",
"status",
"detail"
],
"description": "Check is one dependency the service needs in order to serve its contract."
},
"Identity": {
"properties": {
"root_id": {
"type": "string"
},
"root_space_id": {
"type": "string"
},
"journal_instance_id": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"root_space_id",
"journal_instance_id"
],
"description": "Identity is the service-specific identity member of the health envelope and the describe document: the logical root, its space, and the store lineage."
}
},
"properties": {
"status": {
"type": "string"
},
"service": {
"type": "string"
},
"contract": {
"type": "string"
},
"build": {
"$ref": "#/$defs/Build"
},
"time": {
"type": "string"
},
"checks": {
"items": {
"$ref": "#/$defs/Check"
},
"type": "array"
},
"identity": {
"oneOf": [
{
"$ref": "#/$defs/Identity"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"required": [
"status",
"service",
"contract",
"build",
"time",
"checks"
],
"title": "Health",
"description": "Health is the envelope of GET /livez and GET /healthz."
}
schema/QueryRequest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"ArgumentCondition": {
"properties": {
"index": {
"type": "integer",
"maximum": 65535,
"minimum": 0
},
"equals": {
"type": "string",
"contentEncoding": "base64"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"index",
"equals"
],
"description": "ArgumentCondition requires the argument at Index (0 is the first argument after the predicate) to equal the canonical Ontos value Equals."
},
"Filter": {
"properties": {
"predicate": {
"type": "string",
"contentEncoding": "base64"
},
"arguments": {
"items": {
"$ref": "#/$defs/ArgumentCondition"
},
"type": "array"
},
"origin": {
"type": "string",
"enum": [
"append",
"create"
]
},
"positions": {
"oneOf": [
{
"$ref": "#/$defs/PositionRange"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"description": "Filter is a conjunction of structural conditions compared by Ontos equality."
},
"PositionRange": {
"properties": {
"after": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"through": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"description": "PositionRange bounds a filter to positions in (After, Through]."
},
"Snapshot": {
"properties": {
"scope": {
"$ref": "#/$defs/SpaceRef"
},
"max_depth": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"spaces": {
"items": {
"$ref": "#/$defs/SnapshotSpace"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"scope",
"max_depth",
"spaces"
],
"description": "Snapshot is a recursively complete selection of journal prefixes under a scope, to a depth bound."
},
"SnapshotSpace": {
"properties": {
"space": {
"$ref": "#/$defs/Space"
},
"through": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"through"
],
"description": "SnapshotSpace is one covered space and the cutoff its facts were selected through."
},
"Space": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"path"
],
"description": "Space is a space's identity together with its path from the root."
},
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"filter": {
"oneOf": [
{
"$ref": "#/$defs/Filter"
},
{
"type": "null"
}
]
},
"max_depth": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"snapshot": {
"oneOf": [
{
"$ref": "#/$defs/Snapshot"
},
{
"type": "null"
}
]
},
"cursor": {
"type": "string",
"maxLength": 4096
},
"limit": {
"type": "integer",
"maximum": 128,
"minimum": 0
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space"
],
"title": "QueryRequest",
"description": "QueryRequest reads Space and its descendants over an explicit Snapshot, which the service captures when absent."
}
schema/QueryResult.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"Batch": {
"properties": {
"first": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"last": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"first",
"last"
],
"description": "Batch is the committed batch an entry belongs to."
},
"Entry": {
"properties": {
"ref": {
"$ref": "#/$defs/EntryRef"
},
"fact": {
"type": "string",
"contentEncoding": "base64"
},
"origin": {
"type": "string",
"enum": [
"append",
"create"
]
},
"batch": {
"$ref": "#/$defs/Batch"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"ref",
"fact",
"origin",
"batch"
],
"description": "Entry is one fact occurrence."
},
"EntryRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"position": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"position"
],
"description": "EntryRef is the occurrence identity of one entry: a position in one journal."
},
"Snapshot": {
"properties": {
"scope": {
"$ref": "#/$defs/SpaceRef"
},
"max_depth": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"spaces": {
"items": {
"$ref": "#/$defs/SnapshotSpace"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"scope",
"max_depth",
"spaces"
],
"description": "Snapshot is a recursively complete selection of journal prefixes under a scope, to a depth bound."
},
"SnapshotSpace": {
"properties": {
"space": {
"$ref": "#/$defs/Space"
},
"through": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"through"
],
"description": "SnapshotSpace is one covered space and the cutoff its facts were selected through."
},
"Space": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"path"
],
"description": "Space is a space's identity together with its path from the root."
},
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"snapshot": {
"$ref": "#/$defs/Snapshot"
},
"entries": {
"items": {
"$ref": "#/$defs/Entry"
},
"type": "array"
},
"next_cursor": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"snapshot",
"entries"
],
"title": "QueryResult",
"description": "QueryResult is one page over the snapshot, in depth-first preorder then position."
}
schema/ReadRequest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"ArgumentCondition": {
"properties": {
"index": {
"type": "integer",
"maximum": 65535,
"minimum": 0
},
"equals": {
"type": "string",
"contentEncoding": "base64"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"index",
"equals"
],
"description": "ArgumentCondition requires the argument at Index (0 is the first argument after the predicate) to equal the canonical Ontos value Equals."
},
"Filter": {
"properties": {
"predicate": {
"type": "string",
"contentEncoding": "base64"
},
"arguments": {
"items": {
"$ref": "#/$defs/ArgumentCondition"
},
"type": "array"
},
"origin": {
"type": "string",
"enum": [
"append",
"create"
]
},
"positions": {
"oneOf": [
{
"$ref": "#/$defs/PositionRange"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"description": "Filter is a conjunction of structural conditions compared by Ontos equality."
},
"PositionRange": {
"properties": {
"after": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"through": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"description": "PositionRange bounds a filter to positions in (After, Through]."
},
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"after": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"through": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"limit": {
"type": "integer",
"maximum": 128,
"minimum": 0
},
"filter": {
"oneOf": [
{
"$ref": "#/$defs/Filter"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space"
],
"title": "ReadRequest",
"description": "ReadRequest reads (After, Through] of one journal, optionally filtered."
}
schema/ReadResult.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"Batch": {
"properties": {
"first": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"last": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"first",
"last"
],
"description": "Batch is the committed batch an entry belongs to."
},
"Entry": {
"properties": {
"ref": {
"$ref": "#/$defs/EntryRef"
},
"fact": {
"type": "string",
"contentEncoding": "base64"
},
"origin": {
"type": "string",
"enum": [
"append",
"create"
]
},
"batch": {
"$ref": "#/$defs/Batch"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"ref",
"fact",
"origin",
"batch"
],
"description": "Entry is one fact occurrence."
},
"EntryRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"position": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"position"
],
"description": "EntryRef is the occurrence identity of one entry: a position in one journal."
},
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"$ref": "#/$defs/SpaceRef"
},
"through": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"entries": {
"items": {
"$ref": "#/$defs/Entry"
},
"type": "array"
},
"scanned_through": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"next_after": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"through",
"entries",
"scanned_through"
],
"title": "ReadResult",
"description": "ReadResult is one page."
}
schema/ResolveRequest.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"space": {
"oneOf": [
{
"$ref": "#/$defs/SpaceRef"
},
{
"type": "null"
}
]
},
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"title": "ResolveRequest",
"description": "ResolveRequest selects a space exactly by Space, or the current occupant of Path under RootID."
}
schema/ResolveResult.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"Space": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"path"
],
"description": "Space is a space's identity together with its path from the root."
}
},
"properties": {
"space": {
"oneOf": [
{
"$ref": "#/$defs/Space"
},
{
"type": "null"
}
]
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space"
],
"title": "ResolveResult",
"description": "ResolveResult is the space, or null when the path is unoccupied."
}
schema/Snapshot.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$defs": {
"SnapshotSpace": {
"properties": {
"space": {
"$ref": "#/$defs/Space"
},
"through": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
}
},
"additionalProperties": false,
"type": "object",
"required": [
"space",
"through"
],
"description": "SnapshotSpace is one covered space and the cutoff its facts were selected through."
},
"Space": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"path"
],
"description": "Space is a space's identity together with its path from the root."
},
"SpaceRef": {
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
},
"properties": {
"scope": {
"$ref": "#/$defs/SpaceRef"
},
"max_depth": {
"oneOf": [
{
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
{
"type": "null"
}
]
},
"spaces": {
"items": {
"$ref": "#/$defs/SnapshotSpace"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"scope",
"max_depth",
"spaces"
],
"title": "Snapshot",
"description": "Snapshot is a recursively complete selection of journal prefixes under a scope, to a depth bound."
}
schema/Space.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
},
"path": {
"items": {
"type": "string"
},
"type": "array"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id",
"path"
],
"title": "Space",
"description": "Space is a space's identity together with its path from the root."
}
schema/SpaceRef.schema.json
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"root_id": {
"type": "string",
"pattern": "^rt_[0-9a-f]{32}$"
},
"space_id": {
"type": "string",
"pattern": "^spc_[0-9a-f]{32}$"
}
},
"additionalProperties": false,
"type": "object",
"required": [
"root_id",
"space_id"
],
"title": "SpaceRef",
"description": "SpaceRef is the exact identity of one continuing space and its journal."
}
OpenAPI
openapi.json (raw)
{
"components": {
"schemas": {
"AppendRequest": {
"additionalProperties": false,
"description": "AppendRequest appends Facts as one atomic batch.",
"properties": {
"expected_cutoff": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
},
"facts": {
"items": {
"contentEncoding": "base64",
"type": "string"
},
"maxItems": 128,
"minItems": 1,
"type": "array"
},
"operation_id": {
"maxLength": 128,
"minLength": 1,
"pattern": "^[A-Za-z0-9._:-]+$",
"type": "string"
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
}
},
"required": [
"space",
"facts",
"operation_id"
],
"title": "AppendRequest",
"type": "object"
},
"AppendResult": {
"additionalProperties": false,
"description": "AppendResult identifies the committed batch; Cutoff equals Last.",
"properties": {
"cutoff": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"first": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"last": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"replayed": {
"type": "boolean"
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
}
},
"required": [
"space",
"first",
"last",
"cutoff",
"replayed"
],
"title": "AppendResult",
"type": "object"
},
"ArgumentCondition": {
"additionalProperties": false,
"description": "ArgumentCondition requires the argument at Index (0 is the first argument after the predicate) to equal the canonical Ontos value Equals.",
"properties": {
"equals": {
"contentEncoding": "base64",
"type": "string"
},
"index": {
"maximum": 65535,
"minimum": 0,
"type": "integer"
}
},
"required": [
"index",
"equals"
],
"type": "object"
},
"Batch": {
"additionalProperties": false,
"description": "Batch is the committed batch an entry belongs to.",
"properties": {
"first": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"last": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
}
},
"required": [
"first",
"last"
],
"type": "object"
},
"BindingHTTP": {
"additionalProperties": false,
"description": "BindingHTTP describes the HTTP binding in the describe document.",
"properties": {
"prefix": {
"type": "string"
}
},
"required": [
"prefix"
],
"type": "object"
},
"Bindings": {
"additionalProperties": false,
"description": "Bindings names the primary binding and describes each offered one.",
"properties": {
"http": {
"oneOf": [
{
"$ref": "#/components/schemas/BindingHTTP"
},
{
"type": "null"
}
]
},
"primary": {
"type": "string"
}
},
"required": [
"primary"
],
"type": "object"
},
"Build": {
"additionalProperties": false,
"description": "Build identifies the binary: the revision it was built from, whether that tree was dirty, and the Go version.",
"properties": {
"dirty": {
"type": "boolean"
},
"go": {
"type": "string"
},
"revision": {
"type": "string"
}
},
"required": [
"revision",
"dirty",
"go"
],
"type": "object"
},
"Check": {
"additionalProperties": false,
"description": "Check is one dependency the service needs in order to serve its contract.",
"properties": {
"detail": {
"type": "string"
},
"name": {
"type": "string"
},
"status": {
"description": "ok | failing",
"type": "string"
}
},
"required": [
"name",
"status",
"detail"
],
"type": "object"
},
"Child": {
"additionalProperties": false,
"description": "Child is one child at the parent's selected cutoff, with its creation entry.",
"properties": {
"created_at": {
"$ref": "#/components/schemas/EntryRef"
},
"key": {
"type": "string"
},
"space": {
"$ref": "#/components/schemas/Space"
}
},
"required": [
"key",
"space",
"created_at"
],
"type": "object"
},
"ChildrenRequest": {
"additionalProperties": false,
"description": "ChildrenRequest enumerates a space's immediate children at the cutoff Through (omitted: captured once), continuing with Cursor.",
"properties": {
"cursor": {
"maxLength": 4096,
"type": "string"
},
"limit": {
"maximum": 128,
"minimum": 0,
"type": "integer"
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
},
"through": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
}
},
"required": [
"space"
],
"title": "ChildrenRequest",
"type": "object"
},
"ChildrenResult": {
"additionalProperties": false,
"description": "ChildrenResult is one page of the fixed child set.",
"properties": {
"children": {
"items": {
"$ref": "#/components/schemas/Child"
},
"type": "array"
},
"next_cursor": {
"type": "string"
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
},
"through": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"required": [
"space",
"through",
"children"
],
"title": "ChildrenResult",
"type": "object"
},
"CreateRequest": {
"additionalProperties": false,
"description": "CreateRequest creates a child space and its empty journal under Parent.",
"properties": {
"expected_cutoff": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
},
"key": {
"maxLength": 255,
"minLength": 1,
"type": "string"
},
"operation_id": {
"maxLength": 128,
"minLength": 1,
"pattern": "^[A-Za-z0-9._:-]+$",
"type": "string"
},
"parent": {
"$ref": "#/components/schemas/SpaceRef"
}
},
"required": [
"parent",
"key",
"operation_id"
],
"title": "CreateRequest",
"type": "object"
},
"CreateResult": {
"additionalProperties": false,
"description": "CreateResult is the original creation, including on replay: the child, the creation entry in the parent, and the parent's cutoff after it.",
"properties": {
"child": {
"$ref": "#/components/schemas/Space"
},
"parent_cutoff": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"parent_entry": {
"$ref": "#/components/schemas/EntryRef"
},
"replayed": {
"type": "boolean"
}
},
"required": [
"child",
"parent_entry",
"parent_cutoff",
"replayed"
],
"title": "CreateResult",
"type": "object"
},
"Describe": {
"additionalProperties": false,
"description": "Describe is the document of GET /describe: who this is, the root, which contract, which build, which bindings, which operations, which refusals, the limits and profiles, and which committed contract files GET /describe/{file} serves verbatim.",
"properties": {
"bindings": {
"$ref": "#/components/schemas/Bindings"
},
"build": {
"$ref": "#/components/schemas/Build"
},
"contract": {
"type": "string"
},
"files": {
"items": {
"type": "string"
},
"type": "array"
},
"identity": {
"oneOf": [
{
"$ref": "#/components/schemas/Identity"
},
{
"type": "null"
}
]
},
"limits": {
"$ref": "#/components/schemas/Limits"
},
"operations": {
"items": {
"$ref": "#/components/schemas/Operation"
},
"type": "array"
},
"profiles": {
"$ref": "#/components/schemas/Profiles"
},
"refusals": {
"items": {
"$ref": "#/components/schemas/Refusal"
},
"type": "array"
},
"service": {
"type": "string"
}
},
"required": [
"service",
"contract",
"build",
"bindings",
"operations",
"refusals",
"limits",
"profiles",
"files"
],
"title": "Describe",
"type": "object"
},
"Entry": {
"additionalProperties": false,
"description": "Entry is one fact occurrence.",
"properties": {
"batch": {
"$ref": "#/components/schemas/Batch"
},
"fact": {
"contentEncoding": "base64",
"type": "string"
},
"origin": {
"enum": [
"append",
"create"
],
"type": "string"
},
"ref": {
"$ref": "#/components/schemas/EntryRef"
}
},
"required": [
"ref",
"fact",
"origin",
"batch"
],
"title": "Entry",
"type": "object"
},
"EntryRef": {
"additionalProperties": false,
"description": "EntryRef is the occurrence identity of one entry: a position in one journal.",
"properties": {
"position": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"root_id": {
"pattern": "^rt_[0-9a-f]{32}$",
"type": "string"
},
"space_id": {
"pattern": "^spc_[0-9a-f]{32}$",
"type": "string"
}
},
"required": [
"root_id",
"space_id",
"position"
],
"title": "EntryRef",
"type": "object"
},
"Error": {
"additionalProperties": false,
"description": "Error is a refusal.",
"properties": {
"details": {
"type": "object"
},
"error": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"error",
"message"
],
"title": "Error",
"type": "object"
},
"Filter": {
"additionalProperties": false,
"description": "Filter is a conjunction of structural conditions compared by Ontos equality.",
"properties": {
"arguments": {
"items": {
"$ref": "#/components/schemas/ArgumentCondition"
},
"type": "array"
},
"origin": {
"enum": [
"append",
"create"
],
"type": "string"
},
"positions": {
"oneOf": [
{
"$ref": "#/components/schemas/PositionRange"
},
{
"type": "null"
}
]
},
"predicate": {
"contentEncoding": "base64",
"type": "string"
}
},
"title": "Filter",
"type": "object"
},
"HTTPBinding": {
"additionalProperties": false,
"description": "HTTPBinding carries one operation over HTTP.",
"properties": {
"method": {
"type": "string"
},
"path": {
"type": "string"
}
},
"required": [
"method",
"path"
],
"type": "object"
},
"HeadRequest": {
"additionalProperties": false,
"description": "HeadRequest selects one space's committed cutoff.",
"properties": {
"space": {
"$ref": "#/components/schemas/SpaceRef"
}
},
"required": [
"space"
],
"title": "HeadRequest",
"type": "object"
},
"HeadResult": {
"additionalProperties": false,
"description": "HeadResult is the cutoff: 0 for an empty journal, else the end of the latest committed batch.",
"properties": {
"cutoff": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
}
},
"required": [
"space",
"cutoff"
],
"title": "HeadResult",
"type": "object"
},
"Health": {
"additionalProperties": false,
"description": "Health is the envelope of GET /livez and GET /healthz.",
"properties": {
"build": {
"$ref": "#/components/schemas/Build"
},
"checks": {
"items": {
"$ref": "#/components/schemas/Check"
},
"type": "array"
},
"contract": {
"type": "string"
},
"identity": {
"oneOf": [
{
"$ref": "#/components/schemas/Identity"
},
{
"type": "null"
}
]
},
"service": {
"type": "string"
},
"status": {
"type": "string"
},
"time": {
"type": "string"
}
},
"required": [
"status",
"service",
"contract",
"build",
"time",
"checks"
],
"title": "Health",
"type": "object"
},
"Identity": {
"additionalProperties": false,
"description": "Identity is the service-specific identity member of the health envelope and the describe document: the logical root, its space, and the store lineage.",
"properties": {
"journal_instance_id": {
"type": "string"
},
"root_id": {
"type": "string"
},
"root_space_id": {
"type": "string"
}
},
"required": [
"root_id",
"root_space_id",
"journal_instance_id"
],
"type": "object"
},
"Limits": {
"additionalProperties": false,
"description": "Limits is the advertised operational admission profile.",
"properties": {
"default_page_entries": {
"type": "integer"
},
"max_append_bytes": {
"type": "integer"
},
"max_append_facts": {
"type": "integer"
},
"max_atom_bytes": {
"type": "integer"
},
"max_body_bytes": {
"type": "integer"
},
"max_cursor_bytes": {
"type": "integer"
},
"max_fact_bytes": {
"type": "integer"
},
"max_inspect_bytes": {
"type": "integer"
},
"max_inspect_candidates": {
"type": "integer"
},
"max_key_bytes": {
"type": "integer"
},
"max_page_bytes": {
"type": "integer"
},
"max_page_entries": {
"type": "integer"
},
"max_position": {
"type": "integer"
},
"max_snapshot_bytes": {
"type": "integer"
},
"max_snapshot_spaces": {
"type": "integer"
},
"max_tuple_arity": {
"type": "integer"
},
"max_value_depth": {
"type": "integer"
}
},
"required": [
"max_position",
"max_key_bytes",
"max_fact_bytes",
"max_append_facts",
"max_append_bytes",
"max_body_bytes",
"max_page_entries",
"default_page_entries",
"max_page_bytes",
"max_inspect_candidates",
"max_inspect_bytes",
"max_snapshot_spaces",
"max_snapshot_bytes",
"max_cursor_bytes",
"max_value_depth",
"max_tuple_arity",
"max_atom_bytes"
],
"type": "object"
},
"Operation": {
"additionalProperties": false,
"description": "Operation is the shared operation table row consumed by bindings and clients.",
"properties": {
"doc": {
"type": "string"
},
"errors": {
"items": {
"type": "string"
},
"type": "array"
},
"http": {
"$ref": "#/components/schemas/HTTPBinding"
},
"kind": {
"type": "string"
},
"name": {
"type": "string"
},
"params": {
"items": {
"$ref": "#/components/schemas/Param"
},
"type": "array"
},
"request": {
"type": "string"
},
"response": {
"type": "string"
}
},
"required": [
"name",
"kind",
"doc",
"params",
"errors"
],
"type": "object"
},
"Param": {
"additionalProperties": false,
"description": "Param is a named input outside a JSON body.",
"properties": {
"doc": {
"type": "string"
},
"kind": {
"type": "string"
},
"name": {
"type": "string"
},
"repeated": {
"type": "boolean"
},
"required": {
"type": "boolean"
}
},
"required": [
"name",
"kind",
"required",
"repeated",
"doc"
],
"type": "object"
},
"PositionRange": {
"additionalProperties": false,
"description": "PositionRange bounds a filter to positions in (After, Through].",
"properties": {
"after": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
},
"through": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
}
},
"type": "object"
},
"Profiles": {
"additionalProperties": false,
"description": "Profiles names the frozen value, encoding and projection profiles the continuing history is pinned to.",
"properties": {
"codec": {
"type": "string"
},
"compound": {
"type": "string"
},
"creation_predicate": {
"type": "string"
},
"data": {
"type": "string"
},
"data_json": {
"type": "string"
},
"equality": {
"type": "string"
},
"facts": {
"type": "string"
}
},
"required": [
"facts",
"codec",
"compound",
"data",
"data_json",
"equality",
"creation_predicate"
],
"type": "object"
},
"QueryRequest": {
"additionalProperties": false,
"description": "QueryRequest reads Space and its descendants over an explicit Snapshot, which the service captures when absent.",
"properties": {
"cursor": {
"maxLength": 4096,
"type": "string"
},
"filter": {
"oneOf": [
{
"$ref": "#/components/schemas/Filter"
},
{
"type": "null"
}
]
},
"limit": {
"maximum": 128,
"minimum": 0,
"type": "integer"
},
"max_depth": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
},
"snapshot": {
"oneOf": [
{
"$ref": "#/components/schemas/Snapshot"
},
{
"type": "null"
}
]
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
}
},
"required": [
"space"
],
"title": "QueryRequest",
"type": "object"
},
"QueryResult": {
"additionalProperties": false,
"description": "QueryResult is one page over the snapshot, in depth-first preorder then position.",
"properties": {
"entries": {
"items": {
"$ref": "#/components/schemas/Entry"
},
"type": "array"
},
"next_cursor": {
"type": "string"
},
"snapshot": {
"$ref": "#/components/schemas/Snapshot"
}
},
"required": [
"snapshot",
"entries"
],
"title": "QueryResult",
"type": "object"
},
"ReadRequest": {
"additionalProperties": false,
"description": "ReadRequest reads (After, Through] of one journal, optionally filtered.",
"properties": {
"after": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"filter": {
"oneOf": [
{
"$ref": "#/components/schemas/Filter"
},
{
"type": "null"
}
]
},
"limit": {
"maximum": 128,
"minimum": 0,
"type": "integer"
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
},
"through": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
}
},
"required": [
"space"
],
"title": "ReadRequest",
"type": "object"
},
"ReadResult": {
"additionalProperties": false,
"description": "ReadResult is one page.",
"properties": {
"entries": {
"items": {
"$ref": "#/components/schemas/Entry"
},
"type": "array"
},
"next_after": {
"maximum": 9007199254740991,
"minimum": 1,
"type": "integer"
},
"scanned_through": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
"space": {
"$ref": "#/components/schemas/SpaceRef"
},
"through": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"required": [
"space",
"through",
"entries",
"scanned_through"
],
"title": "ReadResult",
"type": "object"
},
"Refusal": {
"additionalProperties": false,
"description": "Refusal is one row of the refusal table: the surface's name for it, the status the HTTP binding maps it to, and its one-line meaning.",
"properties": {
"http": {
"type": "integer"
},
"meaning": {
"type": "string"
},
"name": {
"type": "string"
}
},
"required": [
"name",
"http",
"meaning"
],
"type": "object"
},
"ResolveRequest": {
"additionalProperties": false,
"description": "ResolveRequest selects a space exactly by Space, or the current occupant of Path under RootID.",
"properties": {
"path": {
"items": {
"type": "string"
},
"type": "array"
},
"root_id": {
"pattern": "^rt_[0-9a-f]{32}$",
"type": "string"
},
"space": {
"oneOf": [
{
"$ref": "#/components/schemas/SpaceRef"
},
{
"type": "null"
}
]
}
},
"title": "ResolveRequest",
"type": "object"
},
"ResolveResult": {
"additionalProperties": false,
"description": "ResolveResult is the space, or null when the path is unoccupied.",
"properties": {
"space": {
"oneOf": [
{
"$ref": "#/components/schemas/Space"
},
{
"type": "null"
}
]
}
},
"required": [
"space"
],
"title": "ResolveResult",
"type": "object"
},
"Snapshot": {
"additionalProperties": false,
"description": "Snapshot is a recursively complete selection of journal prefixes under a scope, to a depth bound.",
"properties": {
"max_depth": {
"oneOf": [
{
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
},
{
"type": "null"
}
]
},
"scope": {
"$ref": "#/components/schemas/SpaceRef"
},
"spaces": {
"items": {
"$ref": "#/components/schemas/SnapshotSpace"
},
"type": "array"
}
},
"required": [
"scope",
"max_depth",
"spaces"
],
"title": "Snapshot",
"type": "object"
},
"SnapshotSpace": {
"additionalProperties": false,
"description": "SnapshotSpace is one covered space and the cutoff its facts were selected through.",
"properties": {
"space": {
"$ref": "#/components/schemas/Space"
},
"through": {
"maximum": 9007199254740991,
"minimum": 0,
"type": "integer"
}
},
"required": [
"space",
"through"
],
"type": "object"
},
"Space": {
"additionalProperties": false,
"description": "Space is a space's identity together with its path from the root.",
"properties": {
"path": {
"items": {
"type": "string"
},
"type": "array"
},
"root_id": {
"pattern": "^rt_[0-9a-f]{32}$",
"type": "string"
},
"space_id": {
"pattern": "^spc_[0-9a-f]{32}$",
"type": "string"
}
},
"required": [
"root_id",
"space_id",
"path"
],
"title": "Space",
"type": "object"
},
"SpaceRef": {
"additionalProperties": false,
"description": "SpaceRef is the exact identity of one continuing space and its journal.",
"properties": {
"root_id": {
"pattern": "^rt_[0-9a-f]{32}$",
"type": "string"
},
"space_id": {
"pattern": "^spc_[0-9a-f]{32}$",
"type": "string"
}
},
"required": [
"root_id",
"space_id"
],
"title": "SpaceRef",
"type": "object"
}
}
},
"info": {
"description": "Generated from journal.Operations and the journal types (ulab-standard/API.md). SURFACE.md and HTTP.md define semantics beyond these checked shapes.",
"title": "ulab-journal",
"version": "2026-09-12"
},
"openapi": "3.1.0",
"paths": {
"/describe": {
"get": {
"operationId": "describe",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Describe"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "service identity, root, contract, build, binding, operations, refusals, limits, profiles and files",
"tags": [
"operational"
]
}
},
"/describe/{file}": {
"get": {
"operationId": "describe_file",
"parameters": [
{
"description": "an exact file name listed by describe",
"in": "path",
"name": "file",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"content": {
"application/json": {
"schema": {}
},
"text/markdown": {
"schema": {
"type": "string"
}
}
},
"description": "the file, verbatim",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "one embedded contract file, verbatim",
"tags": [
"operational"
]
}
},
"/healthz": {
"get": {
"operationId": "health",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Health"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Health"
}
}
},
"description": "a check is failing; the same envelope",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "whether the engine can serve the contract",
"tags": [
"operational"
]
}
},
"/livez": {
"get": {
"operationId": "livez",
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Health"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "the process is up and can answer; empty checks and never 503",
"tags": [
"operational"
]
}
},
"/v1/append": {
"post": {
"operationId": "append",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppendRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppendResult"
}
}
},
"description": "replayed: the original result of this operation ID",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/AppendResult"
}
}
},
"description": "accepted",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "conflict, idempotency_mismatch",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"413": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: the JSON request envelope exceeds 8 MiB",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "internal",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "unavailable",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "append an atomic batch of facts, optionally requiring the current cutoff",
"tags": [
"mutation"
]
}
},
"/v1/children": {
"post": {
"operationId": "children",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChildrenRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ChildrenResult"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"413": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: the JSON request envelope exceeds 8 MiB",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "internal",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "unavailable",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "enumerate a space's immediate children at a fixed cutoff, in creation order",
"tags": [
"read"
]
}
},
"/v1/create": {
"post": {
"operationId": "create",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateResult"
}
}
},
"description": "replayed: the original result of this operation ID",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"201": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateResult"
}
}
},
"description": "accepted",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"409": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "conflict, exists, idempotency_mismatch",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"413": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: the JSON request envelope exceeds 8 MiB",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "internal",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "unavailable",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "create a child space and its empty journal under an existing parent, recording the creation in the parent's journal",
"tags": [
"mutation"
]
}
},
"/v1/head": {
"post": {
"operationId": "head",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HeadRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/HeadResult"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"413": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: the JSON request envelope exceeds 8 MiB",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "internal",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "unavailable",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "read a space's committed cutoff",
"tags": [
"read"
]
}
},
"/v1/query": {
"post": {
"operationId": "query",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QueryRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/QueryResult"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"413": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: the JSON request envelope exceeds 8 MiB",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "internal",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "unavailable",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "read a space and its descendants over an explicit snapshot manifest",
"tags": [
"read"
]
}
},
"/v1/read": {
"post": {
"operationId": "read",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReadRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ReadResult"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"413": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: the JSON request envelope exceeds 8 MiB",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "internal",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "unavailable",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "read a fixed prefix of one journal, optionally filtered, one page at a time",
"tags": [
"read"
]
}
},
"/v1/resolve": {
"post": {
"operationId": "resolve",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResolveRequest"
}
}
},
"required": true
},
"responses": {
"200": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ResolveResult"
}
}
},
"description": "the result",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"400": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"404": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "not_found",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"405": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: unsupported method; Allow names the supported method",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"413": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "invalid: the JSON request envelope exceeds 8 MiB",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"500": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "internal",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
},
"503": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
},
"description": "unavailable",
"headers": {
"Ulab-Contract": {
"required": true,
"schema": {
"const": "2026-09-12",
"type": "string"
}
},
"Ulab-Service": {
"required": true,
"schema": {
"const": "journal",
"type": "string"
}
}
}
}
},
"summary": "resolve a path to its current occupant, or an exact space identity to its path",
"tags": [
"read"
]
}
}
},
"servers": [
{
"description": "the standalone default listener",
"url": "http://127.0.0.1:8092"
}
]
}