« Track Overview · Warmup · Lab 01
Phase 10 — The Action Gateway: Contracts, Idempotency, Sagas & Audit-Grade Logging
Answers this JD line: "Design the action gateway as the bank's enforcement boundary for agentic action, including API mediation, contract enforcement, circuit breakers, idempotency guarantees, transactional safety, and audit-grade action logging."
Why this phase exists
Everything before this phase is about an agent deciding. This phase is about the moment a decision becomes an effect on the bank, and it is the layer the whole track has been building toward.
The one-line statement of the architecture — the model proposes, the platform disposes — is implemented here. No agent talks to core banking. It talks to the action gateway, which:
- validates the proposed call against the tool's declared contract and the business invariants a schema cannot express;
- looks up the tool's side-effect class and derives the retry and approval policy from it;
- enforces idempotency so a retry cannot double-execute;
- attaches a just-in-time, action-scoped credential (Phase 08);
- requires dual control above a threshold, with the approver authenticated at the moment of approval;
- protects the downstream with a circuit breaker;
- runs multi-step work as a saga with compensations, because two-phase commit across a bank's estate is not available;
- and writes an audit-grade, hash-chained record that answers "who authorized this?"
The reason this is a separate layer from the agent kernel is not tidiness. The kernel executes model-proposed plans; the gateway exists precisely because the kernel's input is untrusted. Putting them in one process means one bug removes both, and the entire architecture rests on their independence.
Concept map
- Contract enforcement: schema validation, then business invariants — currency matches the account, amount within the agent's limit, value date is a business day, the beneficiary is registered.
- Side-effect classes:
read·write_idempotent·write_non_idempotent·irreversible, and the retry/approval/audit policy each implies. A required field with no default. - Idempotency: caller-supplied keys; the store as
key → (state, request_hash, response); the three cases (replay-with-same-hash returns the stored response; different hash is a 409 and never executes; in-flight is a 409/retry-after). - Exactly-once effects: at-least-once delivery plus idempotent handling. Why exactly-once delivery is not available and does not need to be.
- Sagas: forward steps with compensations; compensation as a semantic inverse, not a rollback; compensations must themselves be idempotent and retryable, because they run in exactly the conditions that broke.
- Finality: which actions are past the point of reversal, and why
irreversibleis a distinct class rather than "non-idempotent but worse". - Circuit breakers and bulkheads: percentage thresholds over a rolling window, minimum throughput, open duration, half-open probes, and the requirement that "open" has a defined behaviour rather than just a faster failure.
- Dual control: two distinct authenticated humans; the agent may never be one of them; threshold boundaries are inclusive.
- Human-in-the-loop: the pause lives in the kernel so the approval lands in the execution chain (Phase 01).
- Audit-grade logging: actor chain, action, redacted parameters, decision, policy version, model version, idempotency key, approvals, result — hash-chained so modification is detectable, with join keys to the trace and the cost record.
The lab
| Lab | You build | Proves you understand |
|---|---|---|
| 01 — The Action Gateway | contract enforcement with schema plus business invariants; a side-effect-class-driven policy table; an idempotency store implementing all three replay cases; a saga engine with idempotent compensations and a partial-failure path; a circuit breaker with rolling-window thresholds, half-open probes and a defined open-behaviour; dual-control approval with distinct authenticated approvers; parameter redaction; and a hash-chained audit log with a verifier that detects any modification | that transactional safety in a bank is a composition of small, boring guarantees — and that the audit chain is the artifact everything else exists to produce |
120 tests, all green. Test contract: the same key with the same request returns the stored response and executes once; the same key with a different request is a conflict and executes never; a saga failing at step 3 runs compensations 2 and 1 in reverse and is idempotent under replay; the breaker opens at the threshold exactly, half-opens after the interval, and re-closes on successful probes; an agent cannot be its own second approver; a modified audit record fails chain verification; and no secret or full account number appears in any log line.
Documents
| Document | For |
|---|---|
| WARMUP.md | zero to principal on the enforcement boundary — first principles, then the interview answers |
| HITCHHIKERS-GUIDE.md | the fast orientation: what the pieces are and how they fit |
| DEEP-DIVE.md | the mechanisms, in detail, with the failure modes |
| PRINCIPAL-DEEP-DIVE.md | the trade-offs you own at principal level |
| CORE-CONTRIBUTOR.md | what it takes to work on Temporal, resilience4j or an in-house gateway |
| STAFF-NOTES.md | judgment, review signal, war stories |
Deliverables checklist
- You can state the three idempotency cases and what each returns.
- You can explain why exactly-once delivery is unavailable and unnecessary.
- You can design a saga for a payment investigation, with compensations.
- You can explain why compensation is not rollback.
- You can configure a circuit breaker and say what "open" does.
- You can list every field an audit record needs and name who asks for each.
- You can explain why the gateway must be a separate process from the kernel.
Key takeaways
- The model proposes, the platform disposes. This is where that sentence is implemented.
- Retry policy is derived from the side-effect class, by the platform, not chosen per call site.
- An idempotency key is the cheapest control in the track and prevents the most expensive incident.
- Compensation is a semantic inverse, and the intermediate state was visible.
- A breaker without a defined open-behaviour just converts a slow failure into a fast one.
- Dual control counts distinct authenticated humans, and the agent is never one of them.
- Hash-chain the audit log, or "tamper-evident" is a claim rather than a property.