ToMFormer API
A cloze-style API with first-class edit, grow, receipt, abstention, and footprint fields.
contract v1.5.0 · c6ce2ce83719 · generated from contract/tomformer-v1.yaml
Try it now
Get a trial token and make a real call. No signup. Trial tokens expire and every write is scoped to your own session overlay.
curl -s -X POST https://tomformer.com/api/v1/trial-token
curl -s -X POST https://tomformer.com/api/v1/ask \
-H "Authorization: Bearer <token>" -H "Content-Type: application/json" \
-d '{"arm":"tomx","query":"douglas adams wrote ____ in 1979"}'
Raw contract: /openapi.yaml · agent overview: /agents.md
Fields a chat-completions API has no analog for
These fields are derived from the contract flags below; the deployment footer still reports the served contract hash so drift is visible.
Controls
Inference-time control over *whether the system answers at all*. It does not control sampling, so there is no temperature here. What these controls set is how sure the system must be before it speaks.
Controls.gate
The absent-detection serve gate. Added in v1.1. With the gate on (the default) the system detects that it holds no fact for what was asked and declines. Turn it off and it answers anyway, which is what a system without this capability does on every such question, all the time. The toggle exists so the capability can be demonstrated rather than asserted: ask something the corpus has no answer for, watch it decline, turn the gate off, watch it produce a fluent wrong answer instead. It does NOT disable the out-of-corpus badge. A query that cannot be routed at all hits a hard rail that no flag tunes: charter §2 requires free text to never yield a silent wrong answer, so that path abstains regardless of this flag. Note that the regime's internal calibration constants remain caller-invisible by ruling: a regime IS a calibrated operating point, and its internals are not knobs (CONTRACT_RULINGS N1).
Confidence
TOMX only. `margin` is the gap between the top candidate and the runner-up; `tau` is the threshold in force under the current regime. When `margin < tau` the system abstains instead of answering. This is why abstention here is a decision with a number behind it, rather than a refusal string the model was prompted into producing.
TraceStep
One step of the read that produced the answer: which entity was routed to, which relation was selected, the receipt for what was read, and the score. The trace shows WHICH source was read. It does not expose how the system chose it or how the answer was computed.
PublicInferResponse.abstained
True when the system declined to answer because its margin fell below the serving threshold. The abstention is native. It is not produced by prompting.
PublicInferResponse.trace
TOMX only; null for other arms.
InferResponse.abstained
True when the system declined to answer because its margin fell below the serving threshold. The abstention is native. It is not produced by prompting.
InferResponse.trace
TOMX only; null for other arms.
TrustObservation
Capability-level source-trust result with no raw source content or internal scoring path.
TrustInspectResponse
Source trust state and observable capability outcomes; no source content is exposed.
GateDecision
What the write gate decided about one fact extracted from the document, and why. `contradiction` is the interesting case: the new fact disagrees with something already held. The system records both with provenance rather than silently overwriting or silently ignoring, which is what separates integrating knowledge from merely indexing text.
BenchArmResult.families
Per-family breakdown, and **the only figure P5 may headline**. The families are different tasks. They are not difficulty tiers. A relational hop (answer is a different entity from the subject) and an identify-the-described-entity query are won by different architectures for structural reasons: a reader-free retrieval arm cannot reach the answer's document on the former and dominates the latter. So the blended figure above is a function of the probe's family MIX. It does not measure capability. On a family-balanced probe it will report a winner that a naturally-weighted probe reverses. Publishing it as "the score" is the same class of error as reporting bare accuracy without coverage; see the note on `accuracy`. Null only when the slice carries no family labels.
ArmFootprint.resident_params
Resident parameter count for this arm. Added in v1.2. This is the number the demo's central claim rests on, so it is published rather than described: charter §1 defines TX as having the same resident parameter budget as TOMX, and CONTRACT_RULINGS N9 fixes the tolerance at ±10% with both figures visible here. For TOMX this is SERVE-resident and does not scale with entity count: the count is what serving holds resident, and training-only structures are excluded, so served entity content comes from the disk rows rather than from weights. That is precisely why `disk_mb` can grow while this number stays flat, which is the architecture's whole argument. Null when the driver has no model to count, which is the honest answer under the mock rather than a plausible-looking integer.
Footprint
Where each arm keeps what it knows. All three arms run in one process, so per-arm `resident_mb` is an explicit allocation figure and `process_rss_mb` is the real total. RSS is never divided between arms to manufacture a per-arm number; the two are not expected to sum, and `resident_basis` says which kind of figure you are reading (CONTRACT_RULINGS N6).
Authentication
A Sanctum personal access token, issued from the dashboard. Scopes: `ask`, `edit`, `grow`, `bench`. Tokens are rate-limited per minute and capped per day. Edits and grows are always overlay-scoped: a token can never mutate base state.
Authorization: Bearer <token>
Endpoints
POST
/v1/trial-token
Issue yourself a short-lived trial token. No signup.
The only unauthenticated route. It exists so a first-pass reader, human or AI agent, can prove this API is real in one call. The token carries the ask, edit, and grow scopes and expires within a day. Every write it makes lands in its own session overlay, which also expires; the shared base state cannot be changed by any token. The bench scope is not included. Issuance is tightly rate limited per address, and the usual per-token and per-day limits apply on top.
Response
TrialToken
POST
/v1/ask
Ask a question.
scope: ask
Mirrors the sidecar's `/infer`. `arm` defaults to `tomx`. With `?compare=true` the same query is run through all three arms and the trio is returned together, which is the entire point of the thing. Comparing arms costs three forwards and is rate-limited accordingly.
Parameters
-
comparein query – Run all three arms and return the trio.
Request
AskRequest
Response
PublicInferResponse | PublicCompareResponse
POST
/v1/edits
Edit one fact.
scope: edit
Writes a single `(entity, relation) -> value` into **your session overlay**. The base knowledge store is read-only at the filesystem level and no token can reach it. The edit takes effect on the next `ask`. There is no retraining step, no reindex, and no cache to warm, which is the claim this endpoint exists to make checkable.
Request
PublicEditRequest
Response
EditResponse
POST
/v1/grow
Add a document and write its facts into your overlay.
scope: grow
Retrying after a timeout is safe: the gate reads the current belief (including your overlay) per fact, so facts already written on the first attempt come back as `skip` instead of being written twice. The first grow on a fresh deployment loads a large document parser and can take 60 to 90 seconds; later calls do not pay that.
Request
PublicGrowRequest
Response
GrowResponse
POST
/v1/revert
Discard every edit and every grown fact in your overlay.
scope: edit
Response
RevertResponse
POST
/v1/bench
Start a benchmark run over a dev slice.
scope: bench
Request
PublicBenchRequest
Response
BenchJob
GET
/v1/bench/{id}
Poll a benchmark run.
scope: bench
Parameters
-
idin path
Response
BenchProgress
GET
/v1/queries
Curated queries you can ask by id.
scope: ask
The corpus's own questions, with the `query_id` to pass to `/v1/ask`. Asking by id is the in-corpus path: free text is accepted too, but a query the system cannot resolve comes back with `out_of_corpus: true` rather than a guess.
Parameters
-
limitin query
Response
QueryList
GET
/v1/footprint
Resident RAM and disk, per arm.
scope: ask
Per-arm resident figures are allocated parameter and buffer bytes when the driver can attribute them; process RSS and anonymous/required memory are reported separately. Disk is `stat` on the actual files. These values are measurements, not configured constants. This endpoint is where the physical-system claim becomes a number: TOMX serves knowledge from disk, so allocated resident model bytes can stay flat while served disk grows. TX carries its deployed knowledge in weights.
Response
Footprint
GET
/v1/meta
What is actually deployed right now.
scope: ask
The checkpoint hashes and bench tag returned here are the same ones displayed in the demo's footer. If they ever disagree, the UI says so rather than serving results from an unknown build.
Response
Meta
Schemas
Answer
{
"type": "object",
"additionalProperties": false,
"properties": {
"text": {
"type": "string"
},
"p": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "This candidate's share of the top-k mass, renormalized ACROSS THE\nRETURNED TOP-K. It is not an absolute probability. Over the full\ncandidate set the absolute masses round to 0.0000 and would render\nas if the arm returned nothing.\n\nThe arms reach it differently and the panel says so: each arm\nnormalizes its own top-k scores, and those scores are not on a\ncommon scale across arms. Manufacturing a calibrated probability\nfor TOMX would be theater; `score` below carries the real\nquantity, and `confidence.margin` is what the gate actually\ndecides on.\n"
},
"score": {
"type": "number",
"description": "The raw, unnormalized score behind this candidate. Optional;\nomitted by arms that have no meaningful raw score to report.\n"
},
"entity": {
"type": "string",
"pattern": "^Q[0-9]+$",
"description": "The entity this candidate IS, as a Wikidata QID. The QID carries\nidentity; `text` is a display label and labels are not unique, so\nscoring or comparing on `text` is lossy: where two entities share\na label, label-based scoring loses the answer and makes the\npublished figure a property of the label file rather than of the\nmodel. Consumers must score on the QID.\n\nOptional, because some answers have no entity behind them: an\noverlay edit carries the free text a visitor typed, which may name\nnothing in the corpus. Consumers that need identity must handle its\nabsence rather than assume it.\n"
}
},
"required": [
"text",
"p"
]
}
Arm
{
"type": "string",
"enum": [
"tomx",
"tx",
"rag"
],
"description": "`tomx`: the ToMFormer system. It can be edited through a session overlay,\ngrown through bounded document writes, audited with opaque source receipts,\nand served with named abstention thresholds.\n`tx`: matched-size dense transformer.\n`rag`: that same TX plus retrieval over documents from the same public corpus label.\n"
}
ArmFootprint
{
"type": "object",
"additionalProperties": false,
"properties": {
"resident_params": {
"type": [
"integer",
"null"
],
"minimum": 0,
"x-differentiator": true,
"description": "Resident parameter count for this arm. Added in v1.2.\n\nThis is the number the demo's central claim rests on, so it is\npublished rather than described: charter §1 defines TX as having\nthe same resident parameter budget as TOMX, and CONTRACT_RULINGS\nN9 fixes the tolerance at ±10% with both figures visible here.\n\nFor TOMX this is SERVE-resident and does not scale with entity\ncount: the count is what serving holds resident, and\ntraining-only structures are excluded, so served entity content\ncomes from the disk rows rather than from weights. That is\nprecisely why `disk_mb` can grow while this number stays flat,\nwhich is the architecture's whole argument.\n\nNull when the driver has no model to count, which is the honest\nanswer under the mock rather than a plausible-looking integer.\n"
},
"resident_mb": {
"type": "number",
"minimum": 0,
"description": "Measured resident memory attributable to this arm."
},
"disk_mb": {
"type": "number",
"minimum": 0,
"description": "Measured on-disk size of the files this arm actually OPENS to\nanswer a question. Zero for TX, whose knowledge is entirely in\nresident weights; that zero is the comparison. It is not a\nmissing value.\n"
},
"disk_unserved_mb": {
"type": "number",
"minimum": 0,
"description": "Measured on-disk size of artifacts shipped for this arm that no\nquery reads. Reported separately. It is never folded into\n`disk_mb`.\n\nFor TOMX this covers several gigabytes of shipped files the serve\npath never opens. Adding them to `disk_mb` would inflate the\nknowledge-store figure severalfold with bytes nothing reads: the\nsame theater as the previous undercount, pointing the other way.\n"
}
},
"required": [
"resident_params",
"resident_mb",
"disk_mb"
]
}
AskRequest
{
"type": "object",
"additionalProperties": false,
"description": "Public form of InferRequest. `overlay` is derived from the token.\n\nSupply EITHER `query` (free text, blank marked with ____) OR\n`query_id` (a curated id from GET /v1/queries; the row's own text\nbecomes the query). If both are supplied, `query_id` wins and the\nfree text is ignored. An unknown `query_id` is a 422.\n",
"properties": {
"arm": {
"allOf": [
{
"$ref": "#/components/schemas/Arm"
}
],
"default": "tomx"
},
"query": {
"type": "string",
"minLength": 1,
"maxLength": 4000
},
"query_id": {
"type": [
"string",
"null"
]
},
"controls": {
"$ref": "#/components/schemas/Controls"
}
},
"anyOf": [
{
"required": [
"query"
]
},
{
"required": [
"query_id"
]
}
]
}
BenchArmResult
{
"type": "object",
"additionalProperties": false,
"description": "**`accuracy` alone is not a quality comparison, and must never be\ndisplayed as one.**\n\nIt is precision over what an arm actually ANSWERED. An arm that\nabstains on the questions it cannot answer will score higher here than\none that guesses at them, without being any better at the questions\nboth attempted. Two arms are only comparable on quality when their\n`coverage` is comparable, so any surface showing `accuracy` must show\n`coverage` beside it (charter §2: no claim that TOMX beats TX on raw\nquality unless a shipped bench measures it).\n",
"properties": {
"accuracy": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "correct / answered. Precision on attempted questions."
},
"coverage": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "answered / n. The other half of the trade. A deployed arm without\nthe TOMX abstention gate reports 1.0 here for this ungated comparison,\nwhich keeps its lower `accuracy` from being overread.\n"
},
"correct": {
"type": "integer",
"minimum": 0
},
"answered": {
"type": "integer",
"minimum": 0
},
"abstained": {
"type": "integer",
"minimum": 0,
"description": "Counted separately from wrong answers. An arm that abstains is\nnot scored as if it had guessed, and deployed no-gate comparison arms\nreport 0 here; the comparison is only meaningful when both\nnumbers are visible.\n"
},
"n": {
"type": "integer",
"minimum": 0
},
"families": {
"x-differentiator": true,
"description": "Per-family breakdown, and **the only figure P5 may headline**.\n\nThe families are different tasks. They are not difficulty tiers.\nA relational hop (answer is a different entity from the subject)\nand an identify-the-described-entity query are won by different\narchitectures for structural reasons: a reader-free retrieval arm\ncannot reach the answer's document on the former and dominates the\nlatter.\n\nSo the blended figure above is a function of the probe's family\nMIX. It does not measure capability. On a family-balanced probe it\nwill report a winner that a naturally-weighted probe reverses.\nPublishing it as\n\"the score\" is the same class of error as reporting bare accuracy\nwithout coverage; see the note on `accuracy`.\n\nNull only when the slice carries no family labels.\n",
"oneOf": [
{
"type": "null"
},
{
"type": "array",
"maxItems": 0
},
{
"type": "object",
"minProperties": 1,
"additionalProperties": {
"type": "object",
"additionalProperties": false,
"properties": {
"label": {
"type": "string"
},
"accuracy": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "correct / EVERY row asked. Distinct from `precision`,\nwhich divides by the rows the arm chose to answer. The\ntwo differ only for an arm that can abstain, which is why\nreporting one number called \"accuracy\" flattered TOMX:\nits figure was precision-given-answered while TX and RAG,\nwhich expose no TOMX abstention gate here, were scored on every row.\n"
},
"accuracy_at5": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Same, at k=5. Recorded for EVERY arm. RAG was previously\nscored @5 while TOMX and TX were scored @1: a three-way\ncomparison in which one arm got five guesses.\n"
},
"precision": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"coverage": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"correct": {
"type": "integer",
"minimum": 0
},
"correct_at5": {
"type": "integer",
"minimum": 0
},
"answered": {
"type": "integer",
"minimum": 0
},
"n": {
"type": "integer",
"minimum": 0
},
"self_answering": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "Share of this family whose answer IS its own source\ndocument's entity. At 1.0 a retrieval arm is being asked\nto find the document it was handed and cannot lose;\nmeasured 1.0000 for families 1 and 3, 0.0000 for family\n0.\n"
}
},
"required": [
"label",
"accuracy",
"coverage",
"correct",
"answered",
"n"
]
}
}
]
},
"latency_ms": {
"$ref": "#/components/schemas/LatencyStats"
},
"accuracy_at5": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"precision": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"correct_at5": {
"type": "integer",
"minimum": 0
},
"gate_applied": {
"type": "boolean",
"description": "Whether TOMX's abstention gate was in force for these figures. It\nis FALSE for the accuracy comparison: TX and RAG expose no TOMX\nabstention gate here, so scoring TOMX gated against them counts declining\nas being wrong. The gate is reported separately, below.\n"
},
"gate": {
"description": "TOMX only. What declining actually buys, computed post-hoc from the\nper-row margins of the ungated run, so every banked operating\npoint is evaluated on the same rows, and none is selected after\nseeing which flatters.\n",
"oneOf": [
{
"type": "null"
},
{
"type": "object"
}
]
}
},
"required": [
"accuracy",
"coverage",
"correct",
"answered",
"abstained",
"n",
"families",
"latency_ms"
]
}
BenchJob
{
"type": "object",
"additionalProperties": false,
"properties": {
"job": {
"type": "string",
"format": "uuid"
}
},
"required": [
"job"
]
}
BenchProgress
{
"type": "object",
"additionalProperties": false,
"properties": {
"job": {
"type": "string",
"format": "uuid"
},
"status": {
"type": "string",
"enum": [
"queued",
"running",
"done",
"error"
]
},
"slice": {
"type": "string"
},
"done": {
"type": "integer",
"minimum": 0
},
"total": {
"type": "integer",
"minimum": 0
},
"results": {
"description": "Per-arm results. Populated progressively while running.",
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"tomx": {
"$ref": "#/components/schemas/BenchArmResult"
},
"tx": {
"$ref": "#/components/schemas/BenchArmResult"
},
"rag": {
"$ref": "#/components/schemas/BenchArmResult"
}
}
},
{
"type": "null"
}
]
},
"error": {
"type": [
"string",
"null"
]
},
"meta": {
"$ref": "#/components/schemas/ResponseMeta"
}
},
"required": [
"job",
"status",
"slice",
"done",
"total",
"results",
"error",
"meta"
]
}
Confidence ◆
{
"type": "object",
"x-differentiator": true,
"additionalProperties": false,
"description": "TOMX only. `margin` is the gap between the top candidate and the\nrunner-up; `tau` is the threshold in force under the current regime.\nWhen `margin < tau` the system abstains instead of answering.\n\nThis is why abstention here is a decision with a number behind it,\nrather than a refusal string the model was prompted into producing.\n",
"properties": {
"margin": {
"type": "number"
},
"tau": {
"type": "number"
}
},
"required": [
"margin",
"tau"
]
}
Controls ◆
{
"type": "object",
"x-differentiator": true,
"description": "Inference-time control over *whether the system answers at all*. It\ndoes not control sampling, so there is no temperature here. What\nthese controls set is how sure the system must be before it speaks.\n",
"additionalProperties": false,
"properties": {
"regime": {
"$ref": "#/components/schemas/Regime"
},
"t_open": {
"type": [
"number",
"null"
],
"description": "Routing-open threshold. Overrides the regime's banked value."
},
"t_serve": {
"description": "Serve threshold. Overrides the regime's banked value.\n\nA bare number applies to both channels. The object form sets the\ntwo serve channels independently.\n\nThe per-channel form is deliberate: thresholds are banked per\nregime AND per channel, and the object form exposes the shape the\nmodel actually takes (CONTRACT_RULINGS N1).\n",
"oneOf": [
{
"type": "null"
},
{
"type": "number"
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"self": {
"type": "number"
},
"kw": {
"type": "number"
}
},
"required": [
"self",
"kw"
]
}
]
},
"gate": {
"type": "boolean",
"default": true,
"x-differentiator": true,
"description": "The absent-detection serve gate. Added in v1.1.\n\nWith the gate on (the default) the system detects that it\nholds no fact for what was asked and declines. Turn it off and it\nanswers anyway, which is what a system without this capability\ndoes on every such question, all the time.\n\nThe toggle exists so the capability can be demonstrated rather\nthan asserted: ask something the corpus has no answer for, watch\nit decline, turn the gate off, watch it produce a fluent wrong\nanswer instead.\n\nIt does NOT disable the out-of-corpus badge. A query that cannot\nbe routed at all hits a hard rail that no flag tunes: charter §2\nrequires free text to never yield a silent wrong answer, so that\npath abstains regardless of this flag.\n\nNote that the regime's internal calibration constants remain\ncaller-invisible by ruling: a regime IS a calibrated operating\npoint, and its internals are not knobs (CONTRACT_RULINGS N1).\n"
}
}
}
CuratedQuery
{
"type": "object",
"additionalProperties": false,
"properties": {
"query_id": {
"type": "string"
},
"text": {
"type": "string"
},
"family": {
"type": [
"integer",
"null"
],
"description": "Task family. Different families are different TASKS won by\ndifferent architectures, which is why P5 may only headline a\nper-family breakdown.\n"
},
"family_label": {
"type": [
"string",
"null"
]
},
"answerable": {
"type": "boolean",
"description": "False marks a query the system holds no fact for. Included on\npurpose: a deployed no-gate arm may still return a candidate.\n\nUnder the live driver this is MEASURED for the entity the\nquestion is cut from. It was previously the literal `True` for\nevery query, which made the panel's \"try it on a no-row query\" copy\nfalse: there was no such query and no way to produce one.\n"
},
"self_answering": {
"type": "boolean",
"description": "True when this question's answer IS its own source document's\nentity, i.e. retrieval is being asked to find the document it was\nhanded. Measured for each question rather than assumed.\n\nDisclosed on each question rather than only in aggregate:\nfamilies 1 and 3 measure 1.0000 here and family 0 measures\n0.0000, so a\nreader-free retrieval arm cannot lose on two thirds of the probe\nset. Presenting those rows without the flag would let a\nnear-ceiling RAG score read as capability.\n"
}
},
"required": [
"query_id",
"text",
"answerable"
]
}
EditResponse
{
"type": "object",
"additionalProperties": false,
"properties": {
"ok": {
"type": "boolean"
},
"row": {
"type": "string",
"pattern": "^r:[0-9a-f]{12,32}$",
"description": "Opaque receipt for the cell the edit landed on, in the same format\nas `TraceStep.row`; see amendments A6 and A8. Constrained to the\nsame shape, and for the same reason: this one is returned to\npublic API callers.\n"
},
"previous": {
"type": [
"string",
"null"
],
"description": "The value the MODEL answered for this cell before the edit,\nobtained by asking it. It was previously the entity's own label,\nwhich is not the value being replaced.\n"
},
"rel": {
"type": "string",
"description": "The relation the edit was keyed to, echoed back. Edits are scoped\nto the cell (entity, relation); `rel` was previously accepted but\nnot honored, so edits to different relations of one entity\ncollided.\n"
},
"previous_margin": {
"type": "number",
"description": "The shared base's margin for the value being replaced. Reported so\nan edit cannot read as the model having become confident: an edit\npreviously returned a literal margin of 1.0 beside a score of 0.0.\n"
},
"overlay_rows": {
"type": "integer",
"minimum": 0,
"description": "How many edits this overlay now holds. Sparse: a session that has\nedited two facts holds exactly two. It does not hold a copy\nof the shared base.\n"
}
},
"required": [
"ok",
"row",
"previous",
"overlay_rows"
]
}
Footprint ◆
{
"type": "object",
"additionalProperties": false,
"x-differentiator": true,
"description": "Where each arm keeps what it knows.\n\nAll three arms run in one process, so per-arm `resident_mb` is an\nexplicit allocation figure and `process_rss_mb` is the real total.\nRSS is never divided between arms to manufacture a per-arm number;\nthe two are not expected to sum, and `resident_basis` says which kind\nof figure you are reading (CONTRACT_RULINGS N6).\n",
"properties": {
"tomx": {
"$ref": "#/components/schemas/ArmFootprint"
},
"tx": {
"$ref": "#/components/schemas/ArmFootprint"
},
"rag": {
"$ref": "#/components/schemas/ArmFootprint"
},
"process_rss_mb": {
"type": "number",
"minimum": 0,
"description": "Real resident set size of the sidecar process, from the OS. RSS\nincludes disk pages the OS caches on the process's behalf and\nreclaims under memory pressure, so on a machine with spare RAM it\ngrows with use. Read it beside `process_anon_mb`.\n"
},
"process_anon_mb": {
"type": "number",
"minimum": 0,
"description": "The memory the process needs: its anonymous resident set, which\nthe OS cannot reclaim without swapping. The difference between\n`process_rss_mb` and this number is reclaimable cache. This is\nthe figure the budget bounds, because it is the one that decides\nwhat size machine the process runs on.\n"
},
"resident_basis": {
"type": "string",
"enum": [
"allocated",
"unattributed"
],
"description": "How to read every `resident_mb` above. Machine-readable so the UI\ncannot mislabel it.\n\n`allocated`: torch-measured parameter and buffer bytes for that\narm's modules. An honest \"allocated\" figure, and what the live\nsidecar reports.\n\n`unattributed`: this driver cannot attribute resident memory per\narm, and the per-arm figures are NOT a measurement of the arm. The\nmock reports this: a PHP process holding one shared fixture corpus\nhas no per-arm resident memory to measure, and the resident/disk\nsplit P4 exists to show is not demonstrable under it.\n"
},
"budget_mb": {
"type": "number",
"minimum": 0,
"description": "The RAM budget this deployment is specified against: charter §3's\nt3.medium floor, 4096 MB.\n"
},
"within_budget": {
"type": "boolean",
"description": "Whether `process_anon_mb` fits in `budget_mb`. Gated on the\nanonymous figure because cache pages vacate under pressure and\nRSS on a large machine measures the machine, not the process.\nBoth figures are always on screen, and if the anonymous figure\never exceeds the budget this flag goes false and the panel says\nso in red.\n\nThis does not touch the matched-size claim, which is about\nresident PARAMETER counts (6,460,208 vs 6,573,312) and is\nunaffected.\n"
}
},
"required": [
"tomx",
"tx",
"rag",
"process_rss_mb",
"resident_basis"
]
}
GateDecision ◆
{
"type": "object",
"additionalProperties": false,
"x-differentiator": true,
"description": "What the write gate decided about one fact extracted from the\ndocument, and why.\n\n`contradiction` is the interesting case: the new fact disagrees with\nsomething already held. The system records both with provenance rather\nthan silently overwriting or silently ignoring, which is what\nseparates integrating knowledge from merely indexing text.\n",
"properties": {
"fact": {
"type": "string"
},
"decision": {
"type": "string",
"enum": [
"write",
"skip",
"contradiction",
"no_alias",
"out_of_tier"
],
"description": "FIVE outcomes. The two beyond write, skip, and contradiction are\nnot edge cases:\n\n`no_alias`: the document does not state the value in a form the\nsystem can cite, so the write is dropped and reported. On real\ndocuments a large share of attempted writes end this way, and\nreporting only write/skip/contradiction would present those as\nsilent successes.\n\n`out_of_tier`: the value entity lives outside the served tier, so\nthe fact could never be read back. Dropped, counted\nand shown rather than written into a place nothing can reach.\n"
},
"entity": {
"type": [
"string",
"null"
],
"pattern": "^Q[0-9]+$"
},
"rel": {
"type": [
"string",
"null"
],
"pattern": "^P[0-9]+-?$"
},
"value": {
"type": [
"string",
"null"
]
},
"value_id": {
"type": [
"integer",
"null"
]
},
"served_before": {
"type": [
"string",
"null"
],
"description": "What the system answered for this cell BEFORE the write."
},
"margin": {
"type": [
"number",
"null"
],
"description": "The margin behind `served_before`. The contradiction branch fires\nwhen this is at or above a fixed threshold, calibrated offline as\nthe median margin of incorrect serves, which is what that\nconstant was actually fit for.\n"
},
"reason": {
"type": [
"string",
"null"
]
}
},
"required": [
"fact",
"decision"
]
}
GrowResponse
{
"type": "object",
"additionalProperties": false,
"properties": {
"entities_written": {
"type": "array",
"items": {
"type": "string",
"pattern": "^Q[0-9]+$"
}
},
"rows_added": {
"type": "integer",
"minimum": 0
},
"gate": {
"type": "array",
"items": {
"$ref": "#/components/schemas/GateDecision"
}
},
"entity": {
"type": [
"string",
"null"
]
},
"entity_label": {
"type": [
"string",
"null"
]
},
"words": {
"type": [
"integer",
"null"
],
"description": "Corpus words the document tokenized to."
},
"counts": {
"type": [
"object",
"null"
],
"description": "Decision counts by outcome. Published so the panel cannot show only\nthe writes: `no_alias` is the plurality on most real documents.\n"
},
"overlay_rows": {
"type": [
"integer",
"null"
]
},
"documents": {
"type": [
"integer",
"null"
]
},
"note": {
"type": [
"string",
"null"
]
}
},
"required": [
"entities_written",
"rows_added",
"gate"
]
}
LatencyStats
{
"type": "object",
"additionalProperties": false,
"description": "Percentiles over the slice. A mean is never reported. Warmup queries\nare excluded from these numbers and counted separately in\n`warmup_excluded`, so the figure is not flattered by a cold first\nforward or by discarding it quietly (charter §2).\n",
"properties": {
"p50": {
"type": "number",
"minimum": 0
},
"p95": {
"type": "number",
"minimum": 0
},
"n": {
"type": "integer",
"minimum": 0
},
"warmup_excluded": {
"type": "integer",
"minimum": 0
}
},
"required": [
"p50",
"p95",
"n",
"warmup_excluded"
]
}
Meta
{
"type": "object",
"additionalProperties": false,
"properties": {
"ckpt": {
"type": "object",
"additionalProperties": false,
"properties": {
"tomx": {
"type": "string",
"pattern": "^[0-9a-f]{12}$"
},
"tx": {
"type": "string",
"pattern": "^[0-9a-f]{12}$"
}
},
"required": [
"tomx",
"tx"
]
},
"bench": {
"type": "string"
},
"corpus": {
"type": "string"
},
"overlay_ttl_s": {
"type": "integer",
"minimum": 1
},
"driver": {
"type": "string",
"enum": [
"mock",
"live"
]
},
"artifact_namespace": {
"type": [
"string",
"null"
],
"pattern": "^[a-z0-9][a-z0-9_.-]*$",
"description": "Separate artifact namespace. GL-2 reports `gl2`; legacy/mock may omit or return null."
},
"artifacts": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"properties": {
"gl2_trunk": {
"type": "string",
"pattern": "^[0-9a-f]{12}$",
"description": "Pinned GL-2 trunk artifact hash, not a checkpoint-swap alias."
},
"organ_stack": {
"type": "string",
"pattern": "^[0-9a-f]{12}$",
"description": "Pinned stack artifact hash served with the trunk."
}
},
"required": [
"gl2_trunk",
"organ_stack"
]
},
"self_tests": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"properties": {
"anchor": {
"type": "object",
"additionalProperties": false,
"properties": {
"status": {
"type": "string",
"enum": [
"pass",
"fail"
]
},
"hash": {
"type": "string",
"pattern": "^[0-9a-f]{12}$"
}
},
"required": [
"status",
"hash"
]
}
},
"required": [
"anchor"
]
},
"calibration": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"properties": {
"id": {
"type": "string"
},
"hash": {
"type": "string",
"pattern": "^[0-9a-f]{12}$"
},
"measured_at": {
"type": "string"
},
"regimes": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"id",
"hash"
]
},
"comparison_arms": {
"type": [
"object",
"null"
],
"additionalProperties": false,
"properties": {
"manifest": {
"type": "string",
"pattern": "^[0-9a-f]{12}$"
},
"arms": {
"type": "array",
"items": {
"type": "string",
"enum": [
"tomx",
"tx",
"rag"
]
}
},
"matched_on": {
"type": "array",
"items": {
"type": "string"
}
}
},
"required": [
"manifest",
"arms"
]
}
},
"required": [
"ckpt",
"bench",
"corpus",
"overlay_ttl_s",
"driver"
]
}
PublicBenchRequest
{
"type": "object",
"additionalProperties": false,
"properties": {
"arms": {
"type": "array",
"minItems": 1,
"maxItems": 3,
"uniqueItems": true,
"items": {
"$ref": "#/components/schemas/Arm"
},
"default": [
"tomx",
"tx",
"rag"
]
},
"slice": {
"type": "string",
"default": "dev1k"
}
},
"required": []
}
PublicCompareResponse
{
"type": "object",
"additionalProperties": false,
"description": "All three arms on one query, as published to API callers.",
"properties": {
"query": {
"type": "string"
},
"tomx": {
"$ref": "#/components/schemas/PublicInferResponse"
},
"tx": {
"$ref": "#/components/schemas/PublicInferResponse"
},
"rag": {
"$ref": "#/components/schemas/PublicInferResponse"
}
},
"required": [
"query",
"tomx",
"tx",
"rag"
]
}
PublicEditRequest
{
"type": "object",
"additionalProperties": false,
"properties": {
"entity": {
"type": "string",
"pattern": "^Q[0-9]+$"
},
"rel": {
"type": "string",
"pattern": "^P[0-9]+-?$",
"description": "The relation the edit is keyed to. A trailing '-' is the INVERSE\ndirection, and the trace reports inverses that way, so an edit to\na cell the model read via an inverse must be expressible. Without\nthe suffix such edits failed validation silently.\n"
},
"value": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"required": [
"entity",
"rel",
"value"
]
}
PublicGrowRequest
{
"type": "object",
"additionalProperties": false,
"properties": {
"entity": {
"type": "string",
"pattern": "^Q[0-9]+$",
"description": "Which entity the document is ABOUT. The gate writes the facts it\nfinds onto this entity's row.\n"
},
"text": {
"type": "string",
"minLength": 1,
"maxLength": 8000
}
},
"required": [
"entity",
"text"
]
}
PublicInferResponse
{
"type": "object",
"additionalProperties": false,
"description": "`/v1/ask`'s answer. Identical to InferResponse except that `trace`\ncarries PublicTraceStep; see that schema for why.\n",
"properties": {
"answers": {
"type": "array",
"maxItems": 5,
"description": "Top-k candidates, k <= 5. Empty when the system abstains.",
"items": {
"$ref": "#/components/schemas/Answer"
}
},
"abstained": {
"type": "boolean",
"x-differentiator": true,
"description": "True when the system declined to answer because its margin fell\nbelow the serving threshold. The abstention is native. It is not\nproduced by prompting.\n"
},
"confidence": {
"oneOf": [
{
"$ref": "#/components/schemas/Confidence"
},
{
"type": "null"
}
],
"description": "TOMX only; null for other arms."
},
"trace": {
"x-differentiator": true,
"description": "TOMX only; null for other arms.",
"oneOf": [
{
"type": "array",
"items": {
"$ref": "#/components/schemas/PublicTraceStep"
}
},
{
"type": "null"
}
]
},
"retrieved": {
"description": "RAG only; null for other arms.",
"oneOf": [
{
"type": "array",
"items": {
"$ref": "#/components/schemas/Retrieved"
}
},
{
"type": "null"
}
]
},
"latency_ms": {
"type": "number",
"description": "Server-side, monotonic, around the forward only. Network time is\nnot included.\n"
},
"out_of_corpus": {
"type": "boolean",
"description": "True when the query names entities the corpus does not hold. The\nanswer is then unreliable by construction and the UI badges it.\n"
},
"meta": {
"$ref": "#/components/schemas/ResponseMeta"
}
},
"required": [
"answers",
"abstained",
"confidence",
"trace",
"retrieved",
"latency_ms",
"out_of_corpus",
"meta"
]
}
PublicTraceStep
{
"type": "object",
"additionalProperties": false,
"description": "One step of the read that produced the answer, as published to API\ncallers: the receipt for what was read, and the score behind it.\n\nDELIBERATELY NARROWER THAN TraceStep (charter §7 / amendment A8).\nThe sidecar-facing `TraceStep` carries `entity` and `rel` because the\npanels that render this site need them; that contract is spoken over\nlocalhost between Laravel and the sidecar, and it is not published.\n\nThis one is. Trial tokens are self-serve, so any agent can sample\n`/v1/ask` at will, and `entity` + `rel` per hop is a map of which\nrelation the model SELECTS for which question, including, via the\ninverse marker, when it traverses one backwards. Individually that is\nan auditable read; in bulk it is the routing policy, which is \"how\",\nand §7 publishes \"which\" only.\n\nWhat survives is the property a caller actually audits with: receipts\nare deterministic and 1:1 with sources, so two answers carrying the\nsame receipt read the same source, and a receipt that changes after an\nedit proves the read moved. That works without naming anything.\n",
"properties": {
"receipt": {
"type": "string",
"pattern": "^r:[0-9a-f]{12,32}$",
"description": "Opaque receipt for the source actually read. Same value, same\nguarantees and same constrained shape as `TraceStep.row`.\n"
},
"score": {
"type": "number",
"description": "The measured score behind the source that was read."
}
},
"required": [
"receipt",
"score"
]
}
QueryList
{
"type": "object",
"additionalProperties": false,
"properties": {
"queries": {
"type": "array",
"items": {
"$ref": "#/components/schemas/CuratedQuery"
}
},
"total": {
"type": "integer",
"minimum": 0
}
},
"required": [
"queries",
"total"
]
}
Regime
{
"type": "string",
"enum": [
"cautious",
"balanced",
"chatty"
],
"description": "A named operating point on the abstention curve, calibrated offline.\nThe contract reports each point as precision paired with coverage; tighter\nthresholds serve fewer rows, so neither metric should be read alone.\n"
}
ResponseMeta
{
"type": "object",
"additionalProperties": false,
"description": "Which build produced this response.",
"properties": {
"ckpt": {
"type": "string",
"description": "Content hash of the deployed checkpoint, first 12 hex of sha256.",
"pattern": "^[0-9a-f]{12}$"
},
"bench": {
"type": "string",
"description": "Bench version tag this build is pinned to."
},
"driver": {
"type": "string",
"enum": [
"mock",
"live"
],
"description": "`live`: a model produced this answer.\n`mock`: the in-repo reference implementation of this contract\nproduced it from a fixture corpus. No model is running.\n\nAdditive to charter §5; see CONTRACT_NOTES.md N2. The UI keys a\npermanent banner off this field, and refuses to present a\nresponse as a model answer when the field is absent.\n"
},
"artifact_namespace": {
"type": [
"string",
"null"
],
"pattern": "^[a-z0-9][a-z0-9_.-]*$",
"description": "Separate artifact namespace, e.g. `gl2`; null for legacy/mock responses."
},
"calibration_id": {
"type": [
"string",
"null"
],
"description": "Fresh calibration bundle that set this answer's operating point."
},
"comparison_manifest": {
"type": [
"string",
"null"
],
"description": "Matched-arm manifest used for this response's comparison context."
}
},
"required": [
"ckpt",
"bench",
"driver"
]
}
Retrieved
{
"type": "object",
"additionalProperties": false,
"description": "RAG only. The documents retrieved, and what was read from them.",
"properties": {
"doc_id": {
"type": "string",
"pattern": "^[a-z0-9]+:[A-Za-z0-9_.-]+$"
},
"snippet": {
"type": "string"
}
},
"required": [
"doc_id",
"snippet"
]
}
RevertResponse
{
"type": "object",
"additionalProperties": false,
"properties": {
"ok": {
"type": "boolean"
},
"overlay_rows": {
"type": "integer",
"minimum": 0
}
},
"required": [
"ok",
"overlay_rows"
]
}
TrialToken
{
"type": "object",
"additionalProperties": false,
"description": "A self-issued trial credential. Shown once; store it. It expires\nwithin a day and its writes live in an overlay that expires with it.\n",
"properties": {
"token": {
"type": "string",
"description": "The bearer token. Send it in the Authorization header as a Bearer credential."
},
"expires_at": {
"type": "string",
"format": "date-time"
},
"scopes": {
"type": "array",
"items": {
"type": "string",
"enum": [
"ask",
"edit",
"grow"
]
}
},
"note": {
"type": "string"
},
"docs": {
"type": "string",
"format": "uri",
"description": "Where the full agent-readable overview lives."
}
},
"required": [
"token",
"expires_at",
"scopes"
]
}