Skip to content

ding delivery mode has no spec-level lever, and a permanently-guarded (undeliverable) agent is invisible #7

Description

@schickling-assistant

A hand-authored agent whose command launches a wrapper — a shim script, a Nix/env-wrapped binary, anything whose program basename is not literally claude — silently never receives dings. There is no way to say otherwise in the spec, and nothing anywhere reports it.

Verified at 4e25f56. This is our hard blocker for cutting a live seat over to the native bus, so apologies for the length — but the first half of it is clearly your deliberate design, and we want to be precise about which part we think is a gap.

What is intentional (we are not asking you to change this)

DeliveryMode::for_agent_command selects the legacy text+Return path only for a positively identified claude program name, and guards everything else:

  • src/ding.rs:150-156command_invokes(command, "claude")
  • src/ding.rs:159-170 — basename comparison after stripping a leading exec
  • src/main.rs:1083-1104ding_delivery_mode pulls the agent's pty task command and feeds it in

Your doc comments say exactly this — "Unknown or unrendered agent commands default to the fail-closed Codex guard" (src/ding.rs:137-139), "A missing, wrapped, or unfamiliar command remains guarded" (src/ding.rs:149) — and src/ding.rs:2408-2412 tests sh -c 'claude'CodexGuarded on purpose. Fail-closed is the right default and we are not proposing to weaken it.

The gap: there is no lever, and the closed state is invisible

1. A spec cannot declare its delivery mode. harness is one of the render-only fields the KDL parser explicitly drops (src/kdl_format.rs:6, src/kdl_format.rs:84). So delivery mode is derived only from the emitted command string, and an author whose command is a wrapper, a shim, an absolute path under a package manager's store, or env-prefixed has no way to say "this pane is a Claude TUI". The declaration is correct-looking and undeliverable. That sits awkwardly with hand-authored KDL being the canonical interface.

2. A guarded deferral that can never resolve produces no output. CodexGuarded inspects the pane for an idle Codex composer; against a Claude TUI it never finds one, so every attempt returns Deferred and flush_pending breaks out silently — src/ding.rs:1188 — with no log, no counter, and no state change. Meanwhile the ding process is alive, so its presence refresh keeps writing available, its task passes st2 doctor, and its own log ends at its two startup lines. Through every surface st2 exposes, a permanently undeliverable agent is identical to an idle one.

Observation

Isolated with an agent-free control: two panes running only sleep 900, identical in every respect except the program basename of the emitted command.

  • basename claudeLegacy1 DING line delivered
  • basename anything else (ours is a wrapper that execs claude) → CodexGuarded0 DING lines, indefinitely

Impact for an adopter

Any site that does not invoke the harness binary by its bare name is silently unreachable on the native bus, and the failure is not observable from the spec, the sidecar log, presence, or doctor. We only found it by diffing two otherwise-identical panes.

Offer — your call on shape

Two things, and we would send them as separate PRs so you can take either independently:

  1. A spec-declarable delivery mode, with for_agent_command unchanged as the fallback when it is absent. Additive, does not alter any existing behaviour or test.
  2. Make the guarded path observable — a deferral that never resolves should say so somewhere, rather than looking idle. Whether that belongs in the sidecar log, in doctor, or in presence is a design decision we would rather you made; a log line is the smallest version.

Both would come with regression tests. We may well be duplicating something you already have unpushed — happy for these to be closed in favour of your version, and we would rather you reshaped them than merged ours as-is if the shape is wrong.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:agent-specAgent Spec format, parsing, and the agent-spec crate · Set: manualarea:dingDING delivery: inbox notice into a running agent · Set: manualharness:claudeClaude Code-specific behavior · Set: manualharness:codexCodex-specific behavior · Set: manualorigin:agentFiled or primarily produced by an AI agent · 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