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 readWhy 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
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.
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.
| Concern | Rolling your own | Qascade (SUQA) |
|---|---|---|
| Exactly-once under real contention | Works 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 states | Nothing 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 transforms | You'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 authority | Pass 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 expiration | A 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 truth | logger.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 speak | Internal 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. |
| Maintenance | You 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, oneX-Service-Identityheader. - 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:
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.
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.
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.