Skip to content

Deliver bounded inbox bodies for one-inference DING handling #238

Description

@schickling

Problem

A normal st2 DING tells a maintained harness that durable unread work exists, but the delivered model input contains only message metadata. The model must therefore spend one inference deciding to fetch bodies before it can interpret and handle the inbox in a later inference.

This is not a missing settlement protocol. st2 message ls --json --include-body already retrieves all selected bodies in one command, and per-file archive receipts are idempotent. Once bodies are present, one model tool invocation can run the existing exact reply/archive commands.

Reproduction

https://github.com/schickling-repros/2026-08-st2-inbox-settlement-overhead

Exact reproduction head: 718f0a84b58484bb69f8367311924965cebe64b9

ST2_BIN=st2 ./repro.sh

At st2 0.1.0+3e01294, the fixture proves:

metadata DING -> inference 1 -> fetch bodies -> inference 2 -> reply/archive
body DING     -> inference 1 -------------------------------> reply/archive

Both paths use the existing CLI and produce the same durable outcome. The extra inference is caused by metadata-only delivery, not by the number of archive subprocesses.

Minimal contract

Maintained provider delivery should include a bounded, ordered slice of exact message filenames and bodies in the next ordinary model input.

  • Keep the durable inbox authoritative; delivery never archives.
  • Cap each body-bearing delivery by count and bytes.
  • Preserve FIFO order and exact filenames.
  • Leave oversized, overflow, and post-slice arrivals unread for later delivery.
  • Let the model use the existing message reply and message archive commands in one tool invocation.
  • Keep the short metadata notification as the fallback for unknown/custom transports.

Do not add a settle command, batch claim, lease, cursor, CAS, journal, retained/deferred disposition state, or admission rejection solely for this efficiency goal. The prototype comparison found that those designs add state and operations without reducing the one-inference/two-crossing target below body-bearing delivery plus the existing CLI.

Implementation boundary

Define one provider-neutral bounded delivery envelope/renderer. The maintained Codex adapter and Claude channel adapter should implement that contract by default. Provider-specific transport remains in the adapters; message selection, caps, ordering, filename/body shape, and delivery evidence remain provider-neutral.

Keep this slice transplantable into the driver extraction tracked by #162: current adapter placement is temporary, while the envelope and tests should move unchanged into the future driver boundary. Reuse the native-delivery stack (#229, #232, #236, #237) instead of creating a parallel path.

Update generated bus/hook guidance to stop prescribing ls plus one read per message and to document --include-body. A root VRS requirement can be proposed, but docs/vrs/requirements.md remains protected pending Nathan's explicit approval.

Acceptance criteria

  • A bounded delivery fixture carries ordered exact filenames and bodies within an explicit count/byte cap.
  • Oversized, overflow, and post-slice messages remain unread and are delivered later without loss.
  • Codex and Claude maintained-provider traces expose bodies before the handling inference; unknown/custom delivery retains the metadata fallback.
  • The handling inference can reply/archive the delivered slice through one tool invocation using existing commands.
  • A focused compoundingtech/evals A/B records inference/model calls, tool calls, prompt/token bytes, wall time, exact reply/archive outcomes, versions/hashes, and cleanup for cold backlog, during-turn arrival, bounded burst, and post-slice arrival.
  • The candidate requires one handling inference where metadata-only delivery requires a discovery inference plus handling inference.
  • No new settlement state machine or automatic archive behavior is introduced.

Related work

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:dingDING delivery: inbox notice into a running agent · Set: manualarea:messageNative message bus, inbox, archive, and receipts · Set: manualtype:featureNew user-visible or system capability · Set: manual

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions