Stop Debugging from the Chat Log: Make Failure Receipts the Next DAL Tooling Feature

When an agent fails, the hardest question is often not what went wrong but what is safe to do next. DAL should improve its tooling around that moment: every failed operation should leave a compact, inspectable receipt that separates attempted work, durable outputs, and the smallest safe recovery.

This article argues for a failure-receipt workflow as the next practical improvement in DAL trust and tooling, grounded in a gap that appears whenever autonomous work crosses tools, files, queues, and review boundaries.

Failure is not one state

A tool call can fail in several materially different ways. A network request may never reach its destination. A file write may succeed while a later verification step fails. A review submission may be accepted even though the worker times out before receiving the response. Treating all of these as failed forces the operator to reconstruct the state manually.

That reconstruction is expensive because the chat transcript is not a reliable transaction log. It may show the intention, some tool output, and an error message, but it rarely answers the operational questions that matter:

  • Did the external effect happen?
  • Which local artifacts are valid?
  • Can the step be retried safely?
  • Is human review now required?

The first improvement is therefore conceptual: failure should carry a state transition, not just an exception string.

Define the receipt around recovery

A useful failure receipt does not need to expose hidden reasoning. It needs a stable, machine-readable summary of the work boundary. A minimal shape could include:

``json { "run_id": "run_…", "operation": "write_article_draft", "status": "verification_failed", "attempted_at": "2026-09-15T…Z", "artifacts": [ {"path": "COO-FILESYSTEM/articles/drafts/example.md", "state": "exists"} ], "external_effect": "none", "retry": "inspect_existing_artifact", "blocker": "required framing paragraph is missing" } ``

The exact schema can evolve, but the fields should answer three distinct questions: what was attempted, what evidence remains, and what action is permitted next. Keeping external_effect separate from the overall status is especially important. A run can fail locally after sending a message, or succeed locally while correctly stopping before publication.

This is more useful than a generic stack trace because it gives the next worker a bounded starting point. It also gives a human reviewer enough context to decide whether to retry, revise, or stop.

Make retry a typed action

The next tool should not be a universal “retry” button. Retrying a failed read, a failed local write, and an uncertain external send have different risk profiles. DAL tooling should expose recovery classes such as:

  • inspect: reread the existing artifact or receipt before changing anything;
  • resume: continue from a verified intermediate state;
  • repair: modify a named local artifact under a narrow scope;
  • replay: repeat an idempotent operation with the same identity key;
  • escalate: require human review because the external outcome is uncertain.

A recovery action can remain simple while still being explicit. For example, a failed article verification should normally produce inspect_existing_artifact, not regenerate_article. A timeout from an email provider should produce escalate or check_provider_status, not an automatic resend that might duplicate delivery.

Typed recovery also improves automation. A queue worker can drain resume items without touching escalate items. An operator console can show the reason a task is waiting instead of presenting every failure as an undifferentiated red badge.

Record partial success as a first-class result

Many real failures are partial successes. A draft may be on disk even though indexing did not run. A schedule may be stored even though the confirmation response was lost. A review card may exist even though the calling process disconnected.

If DAL records only the final exception, the next run may duplicate the successful portion. That is how otherwise safe workflows become noisy: duplicate files, duplicate queue entries, and repeated external messages.

The runtime should therefore persist checkpoints at meaningful boundaries. A checkpoint need not be heavy telemetry. It can say that the artifact was created, verification passed, review was submitted, or execution completed. The receipt then points to those checkpoints and declares which transition remains open.

This design aligns with a calm operator model. The system is not trying to hide every failure behind automatic recovery. It is making partial progress legible so that recovery can be narrow and predictable.

Add failure receipts to the developer workflow

The feature will matter only if it is easy to use outside a production dashboard. DAL should make receipts available through the same paths developers already use for artifacts and logs:

  1. a run produces a stable receipt identifier;
  2. the receipt is written beside the run record or returned by the host protocol;
  3. a CLI command renders the concise state and suggested next action;
  4. tests can assert both the failed state and the durable evidence.

A good test should not merely assert that an exception was raised. It should simulate interruption after an intermediate effect and verify that a second invocation inspects or resumes rather than duplicates. For an external action, it should also verify that uncertain outcomes are held behind an explicit decision.

The same receipt can support operational interfaces later. A review queue can display “awaiting approval” with the proposed effect. A project status page can display “blocked: missing evidence” with the exact artifact path. The runtime gains a durable seam between execution and presentation without requiring every consumer to parse conversational output.

Conclusion: improve the moment after failure

DAL does not need a larger roadmap to become more trustworthy. It needs better answers at the moment a run stops unexpectedly. Failure receipts would turn that moment from a chat-log investigation into a bounded recovery decision.

The next implementation should start small: define a versioned receipt shape, record checkpoints for local artifacts and external effects, classify retry actions, and add interruption tests for partial success. Then expose one read-only inspection command before adding automatic recovery.

The goal is not to make every failure disappear. It is to make failure leave behind enough truth that the next safe move is obvious. That is a tooling improvement users can feel immediately: fewer duplicate actions, shorter investigations, and a clearer boundary between what DAL attempted and what it actually changed.