Portal
Documentation: all sections

Intelligence Engine

An engine build is a configuration, compiled into an immutable artifact and given a stable callable id: engine/<slug>. Point a request at that id and the gateway expands it — base model, system prompt, temperature, token ceiling, guardrail rule set, key policy, privacy tier — then signs a receipt that names the build, its version, and the digest of the exact configuration that served.

The Intelligence Engine is built and tested. It is not on the production deployment yet, so the calls on this page describe a surface you cannot reach at api.buildsable.com today.

It is not fine-tuning

Stated first because it is the thing most easily assumed. No weights are trained, adapted, merged, quantised or hosted. A build cannot change what a base model is or knows, cannot teach it anything, and cannot make it better at your task than the base model already is. Everything it changes is a gateway-side setting that a receipt could already attest.

What the Intelligence Engine sells is therefore not capability. It is identity: one stable name for a configuration, a version number that is never reused, and a digest a reader can compare between two receipts to prove they were served by the same setup — or to see precisely when it changed.

Honesty box

Proven: that this call was served by this named configuration at this version, whose canonical spec hashes to spec_sha256. Two receipts carrying the same digest ran under the same settings; a digest that moved is a configuration that changed.

Not proven: that the output was correct, safe, or reproducible. The same configuration called twice can still return different text, because the model is not deterministic and Sable does not claim it is. A build is settings, not a guarantee about answers.

What a build holds

FieldMeaning
base_modelA sable id from /v1/models, checked against the catalogue when the version is cut.
system_promptPrepended to every call this build serves. Stored sealed; ≤ 32 KiB.
temperatureFixed for every call, 0.0–2.0, quantised to thousandths.
max_tokensA ceiling, not a quota.
guardrail_ruleset_idA guardrail rule set applied in path.
policy_idA key policy applied in path.
privacy_tierstandard, confidential or sovereign.

name is deliberately not part of the configuration and is not hashed. Renaming a build for the portal must not change what the configuration is, and a digest that moved when you fixed a typo in a label would teach callers to ignore it.

Limits: slug [a-z0-9-], 1–40 characters; 50 live slugs per account; 50 live versions per slug.

The spec digest

spec_sha256 = sha256(canonical_spec_json), where the canonical form is the one the rest of the gateway already uses for hashing: keys sorted by code point, no whitespace, integers only, absent fields omitted rather than nulled. Three details in that sentence are decisions rather than accidents.

The recipe is the existing one. A second canonicalisation with its own rules would be a second thing to get wrong and a second thing for every SDK to reimplement.

Temperature is an integer of thousandths. 0.7 enters the spec as "temperature_milli": 700. Canonical JSON admits integers only, because two languages will not agree on the shortest round-trip decimal form of a float, and a commitment that depends on that is not a commitment. A fixed-decimal string would smuggle the same float back in as text; an integer cannot be gotten wrong.

The system prompt enters as its sha256, never as text. That binds the prompt into the digest — change one character and spec_sha256 moves — while leaving the canonical form publishable. It is also why the ciphertext could not have been hashed instead: AES-GCM draws a fresh nonce per seal, so sealing the same prompt twice would produce two digests for one configuration. The hash is taken in-frame from the plaintext, before the seal.

Because the canonical string is content-free, it is stored in the clear and returned on every response as spec_canonical. A verifier does not have to reconstruct it from the JSON we happened to render — they can hash the bytes we showed them.

{
  "v": 1,
  "base_model": "sable-llama-3.3-70b",
  "max_tokens": 512,
  "privacy_tier": "standard",
  "system_prompt_sha256": "3b1e…",
  "temperature_milli": 200
}

Versions never move, and never repeat

A published version is immutable, and the immutability is structural rather than a rule somebody has to remember: no statement in the Intelligence Engine ever updates a spec column. Publish, unpublish and delete move flags. There is no PATCH, and that absence is the feature.

“Editing” is POST /v1/engine/builds with a slug you already own. It inserts the next version as a draft and leaves every earlier row byte-for-byte as it was.

Version numbers are never reused, even after deletion. A receipt saying “slug triage, v2, spec 9f3a…” can therefore never later describe a different configuration. Deleting a version destroys its sealed prompt and keeps the content-free row, because a digest already stamped on a receipt has to stay explainable.

At most one version of a slug is published at a time, enforced by a database constraint rather than by this code, so two racing publishes fail loudly instead of leaving engine/<slug> ambiguous. Publishing an older version again is the rollback, and it is free and lossless: the row was never mutated.

Pinning, honestly

engine/triage resolves to whichever version is published now.

engine/triage@2 resolves only while v2 is the published one, and fails otherwise. That is a fail-closed pin, not a promise that v2 lives forever: the owner can unpublish it, and a pin that silently resolved to a retired version would be a worse lie than no pin at all.

Pin when you want to notice a configuration change rather than follow it. Leave the pin off when you want to follow it.

How a call is expanded

Four precedence rules, and the asymmetry between them is the point.

FieldRule
System promptPrepended, never substituted. Your own system message is kept and follows the build's, so a build's instructions cannot be deleted by supplying your own.
TemperatureFixed, not a default. A caller cannot override a declared temperature — if they could, spec_sha256 on the receipt would overstate what was actually held constant, and the digest is the entire product.
max_tokensA ceiling. The effective limit is min(requested, declared), which never exceeds what the spec says.
Privacy tierRaised, never lowered. The effective tier is the stronger of the build's and the request's. Silently weakening a caller's explicit privacy request is the bug class this gateway fails closed against everywhere else.

A declared confidential tier does not make a call confidential. It asks for it, and the gateway's existing confidential routing either delivers an attested backend or refuses. A build cannot manufacture a guarantee the hardware did not give.

A policy_id or guardrail_ruleset_id that has since been revoked simply stops applying, and the receipt stamp disappears with it — the behaviour key policies already document. To lock a build down, revoke the key.

On the receipt

A call served by a build carries an additive engine_build block. See Verifiable receipts.

"engine_build": {
  "model": "engine/triage",
  "slug": "triage",
  "version": 2,
  "base_model": "sable-llama-3.3-70b",
  "spec_sha256": "9f3a…"
}

base_model is in the block because without it a reader of the receipt could not tell what actually ran.

Quickstart

curl -s https://api.buildsable.com/v1/engine/builds \
-H "Authorization: Bearer $SESSION" \
-H "Content-Type: application/json" \
-d '{
  "slug": "triage",
  "name": "Support triage",
  "base_model": "sable-llama-3.3-70b",
  "system_prompt": "Classify the ticket. Reply with one of: billing, bug, other.",
  "temperature": 0.2,
  "max_tokens": 512,
  "privacy_tier": "standard"
}'

# {
#   "id": "…", "slug": "triage", "version": 1, "status": "draft",
#   "model": "engine/triage", "pinned_model": "engine/triage@1",
#   "system_prompt_sha256": "3b1e…", "system_prompt_bytes": 62,
#   "spec_canonical": "{\"v\":1,\"base_model\":\"sable-llama-3.3-70b\",…}",
#   "spec_sha256": "9f3a…",
#   "trust_model": "An engine build is a CONFIGURATION, not a fine-tune…"
# }

Endpoints

MethodPathRoleNotes
POST/v1/engine/buildsMemberDraft the next version of a slug. Never edits an existing one.
GET/v1/engine/buildsViewerEvery version the account holds, newest first, with the slug and version caps.
GET/v1/engine/builds/{id}ViewerOne version. A Member or above also gets system_prompt back in plaintext; a Viewer gets system_prompt_sha256 and the byte count.
DELETE/v1/engine/builds/{id}AdminDestroys the sealed prompt. The content-free row and the version number remain.
POST/v1/engine/builds/{id}/publishAdminPoint engine/<slug> here. Retires any other published version of the slug in the same transaction.
POST/v1/engine/builds/{id}/unpublishAdminLeaves engine/<slug> unserved until something else is published.
GET/v1/engine/resolve/{slug}ViewerWhat the callable id resolves to now, plus whether its base model is still in the catalogue.

All of it is session-authed (sess_…). The ladder splits on what a call changes for other people: reading metadata is Viewer, reading the prompt back and drafting are Member, and publish, unpublish and delete are Admin, because each of them changes what engine/<slug> does for every caller in the account, live, with no other confirmation step.

Privacy posture

The system prompt is stored — a named model id that cannot reproduce its own instructions is not a configuration — AES-GCM-sealed with the master key, the same envelope hosted agents, Relay and Sealed Calls use. It is opened in-frame only to answer its own owner or to expand a call that names the build, never logged, and destroyed in the same statement that deletes the build.

This is sealing at rest under Sable's key, not end-to-end encryption.

No other form of the prompt exists anywhere except its sha256, and that fingerprint — never the text — is what appears in the canonical spec, in spec_sha256, on the API, and on receipts. The canonical spec is therefore content-free by construction rather than by filtering: there is no field in it that could hold prompt text. See the privacy contract.