Inspiration

Most legitimate claims do not fail because the person is wrong. They fail because the person gets tired.

Institutions can delay, deny, and request follow-up indefinitely. A person has to keep reconstructing context, interpreting policy, remembering prior responses, and deciding what to do next.

The Attrition Engine was inspired by a simple asymmetry: institutions already have systems that never get tired, while individuals usually do not.

So I built a persistent consumer-advocacy agent that can wait, remember, follow up, and adapt without becoming an unbounded general-purpose bot.

Give it the case. It keeps going.

What it does

The Attrition Engine is a Taskmaster workflow, not a chatbot.

A user delegates one fixed synthetic AetherAir delay case. Gemini 3.7 Flash, orchestrated through Google ADK, extracts structured facts from the bundled evidence and selects a bounded next action. Deterministic tools apply the fictional DEMO-AIR-261 policy, persist the case to Firestore, and submit the first attempt to a separate private AetherAir service.

AetherAir responds asynchronously. Cloud Tasks schedules the delayed institutional response, Pub/Sub wakes the workflow through an authenticated push endpoint, and the Attrition Engine reloads its durable Firestore state instead of relying on a long-lived model session.

After the first denial, the case records DENIAL_ANALYZED, changes strategy from initial_claim to evidence_challenge, adds the denial reason to the evidence set, and submits a materially different second attempt without another human action.

The second delayed response approves the synthetic case, and the workflow closes itself as RESOLVED.

The dashboard makes the lifecycle visible through durable state: human action count, agent action count, attempt count, simulated day, policy, evidence, strategy transition, and an append-only event ledger.

30 simulated days. 2 bounded attempts. 1 human action.

How we built it

The system separates model judgment from deterministic authority.

  • Gemini 3.7 Flash: structured evidence extraction and bounded strategy selection.
  • Google ADK: agent and tool orchestration.
  • Firestore: authoritative case memory, action reservations, processed-event claims, and the append-only event ledger.
  • Cloud Tasks: delayed, OIDC-authenticated AetherAir callbacks outside the originating request.
  • Pub/Sub: asynchronous institution events and authenticated wake-ups, with retry and dead-letter handling.
  • Cloud Run: the public Attrition Engine dashboard/API and the separate private AetherAir simulator.
  • Cloud Build and Artifact Registry: reproducible container builds and image storage.
  • Deterministic domain layer: attempt limits, state transitions, idempotency keys, event IDs, terminal-state enforcement, and fixed external destinations.

The public product surface can only start the bundled synthetic case. It does not accept arbitrary prompts, arbitrary evidence uploads, real institutions, or arbitrary destination URLs.

AetherAir remains private and authenticated.

Challenges we ran into

The hardest challenge was preserving useful model agency while keeping side effects deterministic.

The model should be able to reason about what action makes sense next, but it should not control identifiers, counters, authentication, retry semantics, attempt limits, terminal-state transitions, or where requests are sent. That boundary became one of the core architectural decisions in the project.

Another challenge was proving that the workflow was genuinely asynchronous rather than a synchronous demo disguised with delays. We correlated Cloud Tasks execution, authenticated Pub/Sub pushes, Firestore ledger timestamps, Cloud Run revisions, and one case ID across the full deployed loop.

We also had to make the strategy change visible without exposing hidden chain-of-thought. The solution was to persist product-safe structured rationale, such as the denial reason and the strategy transition, as explicit case state.

Accomplishments that we're proud of

A fresh deployed case completed the full workflow in roughly 45 seconds of wall time while clearly representing 30 simulated days.

The final state showed:

  • 1 human action
  • 2 agent actions
  • 2 bounded attempts
  • 12 durable ledger events
  • a real strategy change from initial_claim to evidence_challenge
  • a terminal RESOLVED state

The second attempt was not a blind retry. DENIAL_ANALYZED(extraordinary_circumstances) caused the agent to select evidence_challenge and include denial_reason in the evidence set.

The same deployed case verified the private AetherAir service, Cloud Tasks, authenticated Pub/Sub wake-ups, Firestore memory reload, and Cloud Run execution.

Repeated or stale actions remain safe. Repeating attempt 2 returns already_accepted, and duplicate events do not mutate terminal state.

Thirty-nine deterministic tests pass.

The ADK session is disposable. The case memory isn't.

What we learned

Long-running agents benefit more from application-owned state machines than from simply extending prompt context.

Durable memory, event identity, idempotent side effects, explicit terminal states, and deterministic authority boundaries make it possible to wake an agent repeatedly without losing control of the workflow.

We also learned that observability matters to agent credibility. If the audience cannot see why a second action differs from the first, autonomy can look like random retry behavior.

Persisting a structured denial reason and strategy delta made the behavior legible without exposing private chain-of-thought.

Finally, asynchronous agents need to be designed around interruption. The model session may disappear. The process may stop. The case still has to continue correctly when the next external event arrives.

What's next for The Attrition Engine

The current project is intentionally narrow and synthetic. The next step would be to generalize the same persistence architecture to additional bounded administrative workflows where people currently lose time to repeated follow-up.

That could include more institution types, richer policy structures, stronger approval boundaries for higher-impact actions, and more configurable escalation strategies.

A production version would also need stronger privacy, consent, retention, audit, and security controls before handling real personal data or interacting with real institutions.

The core idea would remain the same:

Give the agent bounded authority, durable memory, and a goal that may take time. Let the human delegate once. Let the system keep going.

Data sources

The demo uses only bundled synthetic data: a fictional AetherAir delay notice and the fictional DEMO-AIR-261 policy.

It uses no real airline record, passenger record, legal policy, filing, payment, or external real-world dataset.

Synthetic scope and safety

AetherAir and DEMO-AIR-261 are fictional. The passenger, evidence, policy, case, filing, and money are synthetic.

No real airline claim, legal filing, policy enforcement action, or payment is involved.

Attempts are deterministically bounded at two.

The bundled synthetic evidence passes through deterministic direct-identifier tokenization before model processing. Handling real personal data would require additional production privacy, consent, retention, security, and compliance controls.

Built With

Share this project:

Updates

Submission history