Overview

Qascade exposes one primitive — the State Update Qascade Agent (SUQA) — in two equivalent shapes: a stable HTTP API mounted at /v1/, and a Python SDK in suqa.services that the demos and the HTTP views both call. Anything you can do over HTTP you can do in-process.

Base URL: https://<host>/v1 (use http://localhost:8000/v1 for local dev) · Content-Type: application/json · IDs are prefixed: state_…, tr_…, red_…

Auth & service identity

who's calling, and can they?

Every mutating HTTP call must carry a service identity header. Unknown services receive 401 before the service layer is ever reached.

X-Service-Identity: risk-service

Identities are validated against an allowlist in suqa/identity.py. The same header populates created_by, requested_executor, and redeemer on audit events.

Transformation Auth Tokens (TATs) are separate. They're short-lived signed capabilities minted by authorize_transform that bind sub · op · executor · purpose · exp. A TAT is the only way to submit a transformed state.

Data model

four objects, one lifecycle
ObjectPurposeKey fields
StateEnvelopeAn executable state. Single-use. state_id · state_type · content_hash · status (active/consumed/expired) · parent_state_id
StatePolicyWhat may be done with a state. allowed_transformations · delegated_executors · ttl_days
TransformationRequestServer-side record of an authorized transform. transformation_request_id · parent_state · operation · requested_executor
RedemptionRecordOne attempt to redeem. Exactly one succeeds per (state, idempotency_key). redemption_id · state · idempotency_key · outcome (consumed/blocked) · redeemer
Immutability. After insert, StateEnvelope enforces IMMUTABLE_FIELDS at save() time (payload, hash, ids, lineage). Every transform mints a new child — you never overwrite history.

Errors

machine-readable codes
codeHTTPmeaning
unauthorized401Missing/unknown X-Service-Identity.
not_found404State / transformation request doesn't exist.
state_not_active409State is consumed or expired.
state_consumed409Second redemption attempt — one already won.
state_expired409TTL elapsed. Transitioned lazily on access.
policy_violation403Operation not in allowed_transformations, or executor not delegated.
tat_invalid401TAT signature bad, expired, or op/executor/sub mismatch.
validation_error400Missing/malformed field, or immutable-field mutation attempt.
POST/v1/statesHTTPmutatesmint a new executable state
fieldtypereqmeaning
state_typestringyesDomain type, e.g. fintech.loan.commit.v1.
encrypted_payloadstringyesOpaque blob. Content is hashed; hash is immutable.
policyobjectyesallowed_transformations, delegated_executors, ttl_days.
metadataobjectnoFree-form routing info.
request
POST /v1/states
X-Service-Identity: risk-service
Content-Type: application/json

{
  "state_type": "fintech.loan.commit.v1",
  "encrypted_payload": "enc::{amount:25000}",
  "policy": {
    "allowed_transformations": ["underwrite","price"],
    "delegated_executors": ["underwriting-service"],
    "ttl_days": 7
  },
  "metadata": {"loan_id":"L-42"}
}
201 created
{
  "state_id": "state_7f1c2e8b49a9",
  "status": "active",
  "content_hash": "sha256:4e9b…",
  "parent_state_id": null,
  "created_at": "2025-04-20T22:12:04Z"
}
GET/v1/states/<state_id>HTTPreadfetch a state (triggers lazy expiry)

Returns the envelope. If ttl_days has elapsed, the state is durably transitioned active → expired as a pre-flight UPDATE before the response is built.

request
GET /v1/states/state_7f1c2e8b49a9
X-Service-Identity: underwriting-service
200 ok
{
  "state_id": "state_7f1c2e8b49a9",
  "state_type": "fintech.loan.commit.v1",
  "status": "active",
  "content_hash": "sha256:4e9b…",
  "parent_state_id": null,
  "policy": {"allowed_transformations":["underwrite","price"],"ttl_days":7}
}
GET/v1/states/<state_id>/lineageHTTPreadwalk parents to the root

Returns the chain from this state up to the originating root, in order. Useful for audit ("what decision led to this execution?") and for refining policies along the chain.

200 ok
{
  "lineage": [
    {"state_id":"state_9aa2…","state_type":"fintech.price.v1","parent_state_id":"state_7f1c…"},
    {"state_id":"state_7f1c…","state_type":"fintech.loan.commit.v1","parent_state_id":null}
  ]
}
POST/v1/states/<state_id>/transformHTTPmutatesauthorize a transform & mint a TAT
fieldtypereqmeaning
operationstringyesMust appear in parent's allowed_transformations.
requested_executorstringyesMust appear in parent's delegated_executors.
purposestringnoFree-form audit reason, bound into the TAT.
ttl_secondsintnoTAT lifetime. Default short — minutes, not days.
request
POST /v1/states/state_7f1c…/transform
X-Service-Identity: risk-service

{"operation":"underwrite",
 "requested_executor":"underwriting-service",
 "purpose":"credit-check",
 "ttl_seconds": 300}
201 created
{
  "transformation_request_id": "tr_d3c9…",
  "tat": "eyJhbGciOi…<signed>…",
  "expires_at": "2025-04-20T22:17:04Z"
}
Policy violations (403 policy_violation) are returned here, not later — a rogue caller can't mint a TAT for an operation the parent never permitted.
POST/v1/states/submitHTTPmutatesdeliver a transformed child state under a TAT

The TAT's sub/op/executor claims must match the server-side TransformationRequest. On success, a new child StateEnvelope is created with parent_state_id set and the parent's policy inherited.

request
POST /v1/states/submit
X-Service-Identity: underwriting-service

{
  "tat": "eyJhbGciOi…",
  "state_type": "fintech.underwrite.v1",
  "encrypted_payload": "enc::{score:720}",
  "metadata": {"model":"uw-v3"}
}
201 created
{
  "state_id": "state_9aa2…",
  "parent_state_id": "state_7f1c…",
  "status": "active"
}
POST/v1/states/<state_id>/duplicateHTTPmutatessafe read-like fork (does not consume)

Creates a sibling state with identical content but a new state_id. The original remains active. Useful when multiple consumers need to reason about the same decision without racing for its one redemption.

POST/v1/states/<state_id>/redeemHTTPmutates · irreversiblethe irreversible act — exactly once
fieldtypereqmeaning
idempotency_keystringyesClient-chosen key. Unique together with state_id.
reasonstringnoFree-form audit note.

Guarded server-side by select_for_update and a UniqueConstraint(state, idempotency_key). Under N concurrent callers, exactly one gets consumed; the others get blocked. Retrying with the same idempotency key is safe.

first caller — 200 ok
{
  "redemption_id": "red_5b12…",
  "state_id": "state_7f1c…",
  "outcome": "consumed",
  "redeemer": "execution-service"
}
losing caller — 409 state_consumed
{
  "error": "state_consumed",
  "redemption_id": "red_a4ee…",
  "outcome": "blocked"
}
Invariant. Per state_id: at most one consumed redemption ever exists. Proven by a threaded race test in the suite.
GET/v1/states/<state_id>/redemptionsHTTPreadthe ledger — every attempt, every outcome
200 ok
{
  "redemptions": [
    {"redemption_id":"red_5b12…","outcome":"consumed","redeemer":"agent-b","at":"…"},
    {"redemption_id":"red_a4ee…","outcome":"blocked","redeemer":"agent-a","at":"…"},
    {"redemption_id":"red_91c0…","outcome":"blocked","redeemer":"agent-c","at":"…"}
  ]
}

This is what makes "attempted many times, realized exactly once" provable after the fact. It's what Act 6 of the story demo renders as the final ledger.

suqa.services.create_state(...)

SDKmutatessame code path as POST /v1/states
from suqa import services

state = services.create_state(
    state_type="fintech.loan.commit.v1",
    encrypted_payload="enc::{amount:25000}",
    created_by="risk-service",
    policy={
        "allowed_transformations": ["underwrite", "price"],
        "delegated_executors": ["underwriting-service"],
        "ttl_days": 7,
    },
    metadata={"loan_id": "L-42"},
)
# -> StateEnvelope(state_id='state_7f1c…', status='active')

Returns StateEnvelope. Raises ValidationError on malformed policy/payload. Emits audit event state_created.

suqa.services.duplicate_state(state_id, actor)

SDKmutatesfork content, new identity, parent unchanged
sibling = services.duplicate_state(state.state_id, actor="risk-service")
# sibling.state_id != state.state_id, but content_hash matches.

Emits state_duplicated. Does not consume the original; both remain active until one is redeemed.

suqa.services.authorize_transform(...)

SDKmutatesmint a scoped, signed TAT
req, tat = services.authorize_transform(
    state_id=state.state_id,
    operation="underwrite",
    requested_executor="underwriting-service",
    actor="risk-service",
    purpose="credit-check",
    ttl_seconds=300,
)
# req: TransformationRequest  (persisted, with tr_ id)
# tat: signed capability string — hand this to the executor

Raises PolicyViolation if operation isn't allowed or the executor isn't delegated. Emits transform_authorized.

suqa.services.submit_transformed_state(...)

SDKmutatesverify TAT, mint child, inherit policy
child = services.submit_transformed_state(
    tat=tat,
    state_type="fintech.underwrite.v1",
    encrypted_payload="enc::{score:720}",
    actor="underwriting-service",
    metadata={"model": "uw-v3"},
)
# child.parent_state_id == state.state_id
# child.policy inherited from parent — immediately usable

Raises TATInvalid if signature/expiry is bad or the TAT's sub/op/executor don't match the persisted TransformationRequest. Emits transformed_state_submitted.

suqa.services.get_lineage(state_id)

SDKreadlist ancestors, child → root
for node in services.get_lineage(child.state_id):
    print(node.state_id, node.state_type)

suqa.services.redeem_state(...)

SDKmutates · irreversiblethe one that flips the bit
result = services.redeem_state(
    state_id=child.state_id,
    idempotency_key="exec-L-42-attempt-1",
    redeemer="execution-service",
    reason="loan commit",
)
if result.outcome == "consumed":
    do_the_irreversible_thing()
else:
    # 'blocked' — someone else already won, or this is a retry
    log.info("skipped", original_winner=result.existing_redeemer)
Contract. Exactly one call per state_id returns outcome='consumed'. Retrying with the same idempotency_key is safe and replays the original outcome. Emits state_redeemed or state_redemption_blocked.

suqa.tokens

SDKhelpersTAT mint/verify (low-level)

Most code should never touch this module directly — authorize_transform and submit_transformed_state call it for you. It's exposed for testing and for integrations that need to validate a TAT at the edge.

from suqa import tokens

tat = tokens.mint_tat(
    sub=req.transformation_request_id,
    op="underwrite",
    executor="underwriting-service",
    purpose="credit-check",
    ttl_seconds=300,
)
claims = tokens.verify_tat(tat)
# {'jti','sub','op','executor','purpose','iat','exp'}

Signed with django.core.signing. Tampering, expiry, or mismatched sub/op/executor all raise TATInvalid.

Same code path, two front doors. The HTTP views in suqa/views.py are thin adapters over the SDK in suqa/services.py. The CLI demos and the web demos on this site call the SDK directly — which is why the invariants hold identically in all three.