The problem nobody named

Agents can decide the same thing many times.
Only one should ever be able to do it.

Every system that plans with AI now has a gap between thinking and acting. A model retries. A queue redelivers. Two agents coordinate and both "win." The decision is cheap and reversible. The execution is not.

Qascade closes that gap with a primitive: a single-use executable state — attempted many times, realized exactly once.

manifesto · 3 min read
01

Why this is necessary— the gap between decision and execution

Modern systems are a stack of retries. That was fine when every step was a read. Agentic systems flipped the ratio: most steps are now writes — money moved, orders placed, tickets issued, doses dispensed, contracts signed.

The moment you put an LLM, a planner, or a multi-agent workflow in front of those writes, three old problems get worse at the same time:

  • Duplication. The same decision fires twice because a timeout, a retry, or another agent can't tell "it failed" from "it succeeded silently."
  • Ambiguity. "Who actually executed this?" has no single answer — logs say one thing, the ledger says another, the model says a third.
  • Drift. The state the agent reasoned about is not the state that finally got written — something mutated in between.

Every framework today addresses the decision side (tools, memory, planners, evals). Almost none of them address the irreversibility side.

✗ Without Qascade

agent-a: approve loan L-42 → wire $10,000  ✔
agent-b: approve loan L-42 → wire $10,000  ✔  (retry after 30s timeout)
ledger:  TOTAL SENT = $20,000
ops:     "which one was real?"  ¯\_(ツ)_/¯

✓ With Qascade

state_7f1c… created once, policy locked
agent-a: redeem state_7f1c…  →  consumed
agent-b: redeem state_7f1c…  →  blocked (StateAlreadyConsumed)
ledger:  TOTAL SENT = $10,000   · 1 winner, 1 loser, full audit
02

What's groundbreaking— redemption as a physical event

Idempotency keys exist. Distributed locks exist. Sagas exist. Qascade isn't any of those — it unifies them into a first-class object that the rest of your system can talk about, pass around, and audit.

🧱
State as a capability

A StateEnvelope is the right to execute. Possessing it is meaningful; redeeming it is terminal. Decisions become objects you can hand to another agent without losing control.

🔒
Irreversibility, not advice

Single-use is enforced by the database, not by a convention. select_for_update + a unique (state, idempotency_key) constraint mean exactly one caller wins.

🧬
Lineage that survives transforms

Every refinement mints a new immutable child. You can replay the decision graph; you can never mutate a past state.

🎟️
Scoped, signed authority (TAT)

Transformation Authorization Tokens bind sub·op·executor·purpose·exp. A stolen TAT can't be replayed, widened, or retargeted.

📜
Audit as an API

Every create / authorize / submit / redeem / block is a structured event — a queryable ledger other agents can reason about.

🧩
Portable across stacks

SUQA is a plain service layer plus HTTP — no new runtime, no framework lock-in. Any agent, any language, any orchestrator can participate.

The shift: "don't execute twice" stops being a best practice and becomes a physical property of the state itself.
02b

Why not just build this yourself?— the hidden iceberg under "it's just a unique index"

Every engineer who sees Qascade has the same first reaction: "I could do this in an afternoon. Idempotency key + a unique index + a lock. Done." They're not wrong about the afternoon. They're wrong about what ships.

The naïve version handles ~20% of the problem. The other 80% is what makes this a primitive instead of a helper function — and it's exactly the part that bites you six months in, usually at 3 a.m., during an incident you can't explain.

ConcernRolling your ownQascade (SUQA)
Exactly-once under real contentionWorks in tests. Breaks under threads/processes/regions. Your SELECT then INSERT isn't atomic.select_for_update + UniqueConstraint(state, idempotency_key). Tested under threaded contention.
Immutability of past statesNothing stops UPDATE states SET payload=…. Your "history" quietly rewrites itself.Models enforce IMMUTABLE_FIELDS at save-time; hash-locked payloads; every transform mints a new child.
Lineage across transformsYou'll add a parent_id. Then a root_id. Then a graph table. Then a migration. Then another.Lineage is first-class. GET /v1/states/{id}/lineage walks the chain; children inherit policy by construction.
Delegated authorityPass a bearer token? A row id? A signed blob? Whatever you pick, scope-creep is inevitable.Signed TATs bind sub·op·executor·purpose·exp. Can't be replayed, widened, or retargeted.
Lazy expirationA cron job. That sometimes doesn't run. Leaves "alive but expired" states for hours.Expiration is a pre-flight UPDATE on access — durable, no scheduler, no race with the redeemer.
Audit & post-incident truthlogger.info("ok") scattered across four services. Good luck reconstructing who actually did it.Structured events on one channel with actor identity: state_created, state_redeemed, state_redemption_blocked.
Service identity"We'll add auth later." (You won't.)X-Service-Identity actor allowlist from day one; every write is attributed.
API surface other agents can speakInternal helpers. Different in every repo. No other team can integrate without reading your code.Stable HTTP contract: create · get · lineage · authorize · submit · duplicate · redeem · redemptions.
Correctness proofs"It passed manual QA."43 tests including a threaded race-condition test that asserts the hard exactly-once invariant.
MaintenanceYou own it forever. Every new consumer makes the contract fuzzier.One app, one contract. Upgrading the primitive upgrades every consumer at once.
What "I'll build it myself" actually means
  • Week 1: idempotency key + unique index. Feels done.
  • Week 3: first duplicate in prod. Different bug appears.
  • Month 2: someone needs lineage. Schema migration #1. Backfill weekend.
  • Month 3: a subagent leaks a token. Retrofit scopes. Breaking change.
  • Month 4: cron misses an expiry; a redemption fires 14h late. Post-mortem #1.
  • Month 5: audit doesn't match the ledger. Compliance ticket.
  • Month 6: each team has forked the helper. No single source of truth.
What adopting Qascade means
  • Day 1: pip install, one migration, one X-Service-Identity header.
  • Day 1: create_state → redeem_state. Exactly-once already holds.
  • Day 2: lineage & TATs are already there when you need them.
  • Day 2: audit events flow to your log pipeline unchanged.
  • Forever: the invariant doesn't rot. Tests guard it. New services inherit it for free.

Rough comparison — to reach the same correctness bar:

DIY — eng-weeks to v1
~8–12 wks
DIY — ongoing maintenance
high
Qascade — time to v1
~1 day
Qascade — ongoing maintenance
~zero
The real question isn't "can I build this?" It's "do I want every service that writes to the world to depend on a primitive I re-invented, or on one that's shared, proven, and boring?"

Idempotency keys are a pattern. Qascade is the object that pattern always wanted to be — with lineage, authority, audit, and expiration built in so you stop re-solving them per service, per team, per incident.

03

How this transforms execution— what teams get to stop doing

Once redemption is a real object, a long list of hard problems collapse into one pattern:

  • Multi-agent coordination. Agents no longer need a coordinator. They race against the state itself; the loser is told cleanly, the winner has a receipt.
  • Retry safety. Any retry — human, queue, model — that replays a consumed state is inert by construction. No more "did the webhook land?"
  • Human-in-the-loop. An approver redeems the state; that redemption is the approval. No parallel status table to keep in sync.
  • Delegation without fear. Hand a TAT to a subagent, a third-party service, or a partner — it can only do the one thing you authorized, once.
  • Post-incident clarity. "Who did this?" has a single, provable answer: the RedemptionRecord. Compliance, SRE, and ops read the same truth.
  • Safer autonomy. You can let agents act faster because the cost of being wrong is bounded by what they can redeem, not by what they can retry.
The payoff: you can finally let agents act on the world without writing a new coordination protocol for every write.

Qascade is small on purpose. It doesn't replace your planner, your orchestrator, or your model. It gives all of them the same atom to stand on: a state that can be tried many times and realized exactly once.

See it fail, then fix it (6-act story) Watch three agents race Read the client code All Demos
Source of truth: suqa/services.py · suqa/models.py · invariant enforced by select_for_update + UniqueConstraint(state, idempotency_key).