Dispatch success must be proven.
Text appearing in an input box is not delivery.
dispatch_written
dispatch_inserted
dispatch_submitted
dispatch_completed
dispatch_blocked
dispatch_writtendispatch_inserteddispatch_submitteddispatch_completeddispatch_blockeddispatch_completed for controlling-agent self-workdispatch_completed for that agent only after the expected task-local evidence
exists, and the receipt should state that self-work was tracked through compact
evidence files.If expected evidence is declared, the gate requires:
dispatch_completed
dispatch_submitted is not enough when evidence is expected.
For Full Mode and Remote Mode, dispatch_completed also needs runtime
submission provenance. Each Leader-declared Agent must have a prior
dispatch_submitted receipt with concrete adapter proof, for example a
submission id, queue id, hosted run id, pane/session submit proof, or equivalent
runtime record. A dry-run dispatch, a local sub-agent result, a simulated
review, or a manually appended dispatch_completed receipt is not HERDR/live
runtime proof.
For tasks that claim the owned-session contract, a HERDR
dispatch_submitted proof must also cite agent-sessions.json, the accepted
binding generation, identity token, and ownership record. The same generation
and token must exist in agent-session-receipts.jsonl. A pane id, matching
Agent label, or working-state event without that chain is not Full Mode
provenance.
If an outer Agent stays idle while child work runs, its adapter must export a
structured child-job identity or event bound to the accepted session and
current dispatch. Visible counters, labels, conversation text, and dispatch
content cannot produce dispatch_submitted.
Deterministic Full/Remote suspension accepts only an identity-matching
dispatch_submitted receipt with concrete adapter proof. A missing or empty
proof object and manual_delivery_attested do not satisfy the suspension entry
guard. Proof identity/ref values must be non-empty strings, directly or inside
a typed adapter record; booleans and counters are not delivery identities.
Because the ledger is append-only, legacy validators evaluate the latest
receipt for each Leader-declared Agent. Deterministic wait validators evaluate the
latest accepted receipt for the exact task, work item, role, dispatch id, and
dispatch generation. A different role or retry generation cannot supersede or
satisfy that gate. If late evidence appears after a timeout, the runtime must
append a newer identity-bound dispatch_completed receipt and use an explicit
recovery transition.
The reference CLI exposes that transition as:
valp resume <task-id> --workspace <root> \
--event receipt --ref dispatch-receipts.jsonl#<line>
This path is available only after an accepted timeout wake. It verifies the
timed-out work-item identity, suspension epoch, receipt sequence, expected
evidence, and original concrete submission receipt before returning the current
task to dispatching. The accepted timeout event and wake-result remain
unchanged.
File-backed adapters must allocate the next receipt sequence and durably append the receipt while holding one inter-process task lock. The reference queue adapter uses the same lock as the state/wake reducer so concurrent submitters cannot reuse a sequence.
The reference queue adapter also gives each logical task/dispatch/generation
submission a stable receipt ID. Retrying after a file or directory flush error
reuses an identical queue record and receipt instead of appending a second
sequence. A queue JSON file alone is prepared data, not delivery proof; a worker
must require its matching dispatch_submitted receipt or reconcile the pair.
If a concrete HERDR dispatch_submitted receipt exists but the same work item
has no terminal receipt, the automatic frontier correctly treats it as already
delivered even when expected evidence arrives after the observer window. A
coordinator may explicitly reconcile that one work item through the public
dispatch interface:
valp dispatch <task-id> --workspace <root> \
--agent <agent> --role <role> --runtime herdr \
--recover-incomplete --retry-generation 1 --submit
This is not the transport-failure retry. The command first requires one exact
prior submission, no conflicting terminal receipt, the unchanged routed
identity, and a matching immutable control contract and agent slice. If every
expected ref is already valid, it appends the identity-bound
dispatch_completed receipt for the original submission without HERDR
preflight, worker submission, or a retry receipt. If every ref remains absent
or invalid, it performs the one bounded resubmission; that retry receipt
preserves the original identity, adds retry_generation: 1, and binds both the
originating receipt ID and control-contract digest in proof.recovery. Partial
evidence, a repeat or different identity, retry generation 2, and any attempt
after failed recovery transport fail closed. The original ledger line is never
deleted or rewritten.
See examples/incomplete-submission-recovery/dispatch-receipts.jsonl for the
original and retry receipts.
If an evidence file exists but is marked invalid, superseded, rejected, or
blocked in evidence-status.json, it does not satisfy dispatch_completed or
the expected evidence gate.
Expected evidence refs must be task-relative safe paths. They must be non-empty
POSIX-style relative paths and must not be absolute paths, contain backslash
separators, or include .. path segments. Evidence outside the task folder
cannot satisfy dispatch_completed.
Receipts are appended to:
.herdr-loop/tasks/<task-id>/dispatch-receipts.jsonl
Every non-empty JSONL line must parse as a JSON object. A corrupted receipt ledger is an audit failure, even if earlier valid lines look complete.
Legacy/non-deterministic receipt example (useful for older and Manual Mode task folders, but not deterministic Full/Remote submission proof):
{
"ts": "2026-07-03T00:00:00Z",
"agent": "claude",
"event": "dispatch_completed",
"exit_code": 0,
"dispatch_ref": "agents/claude/dispatch.md",
"expected_refs": ["agents/claude/visible-review.md"],
"proof": {
"runtime_state": "completed",
"evidence_found": true
},
"summary": "Expected dispatch evidence exists"
}
Deterministic Full/Remote receipt v2 starts with concrete adapter-issued submission proof while binding the complete work-item identity:
{
"schema_version": "valp-dispatch-receipt.v2",
"receipt_id": "receipt-submit-41",
"task_id": "TASK-001",
"event_sequence": 41,
"ts": "2026-07-13T10:28:45Z",
"agent": "codex",
"role": "implementer",
"work_item_id": "implementer:codex",
"dispatch_id": "TASK-001:implementer:1",
"dispatch_generation": 1,
"event": "dispatch_submitted",
"dispatch_ref": "agents/codex/dispatch.md",
"expected_refs": ["agents/codex/evidence.md", "evidence/verification.md"],
"proof": {
"adapter_record": {
"adapter": "herdr",
"submission_id": "herdr-submit-7f3a"
}
}
}
The matching terminal completion keeps the same identity and records the suspension epoch:
{
"schema_version": "valp-dispatch-receipt.v2",
"receipt_id": "receipt-complete-42",
"task_id": "TASK-001",
"event_sequence": 42,
"ts": "2026-07-13T10:28:55Z",
"agent": "codex",
"role": "implementer",
"work_item_id": "implementer:codex",
"dispatch_id": "TASK-001:implementer:1",
"dispatch_generation": 1,
"suspension_epoch": 1,
"event": "dispatch_completed",
"dispatch_ref": "agents/codex/dispatch.md",
"expected_refs": ["agents/codex/evidence.md", "evidence/verification.md"]
}
Terminal v2 receipts require suspension_epoch. Full and Remote Mode reject
manual terminal receipts as wake evidence. Timestamps remain descriptive;
accepted core sequence and revision CAS decide races.
Manual Mode may record:
manual_dispatch_written
manual_delivery_attested
manual_result_attested
manual_blocked
These are useful audit records, but they are not equivalent to Full Mode runtime
receipts. A Manual Mode task can be complete as a manual evidence trail, but it
must not label manual attestation as dispatch_submitted.