Files
orca/src/shared/orchestration-mutation-request.ts
Brennan Benson cc6b600e21 Fix orchestration CLI recovery, settled-Dispatch mail, and guide defects (#16919)
* Fix orchestration CLI recovery, settled-Dispatch mail, and guide defects

Five reported orchestration CLI defects, verified individually before fixing.
Two were real code defects, one was a docs error, one was correct as-is, and
one was correct on both ends except for its recovery wording.

- Mail addressed to a settled `dispatch:<id>` was accepted and silently dropped.
  Local sends bypassed the settlement check the federated branch already had, so
  the caller was told success for a delivery no worker would ever read. Reject
  with `dispatch_inactive` and name the Run mailbox to use instead.

- A lost mutation response offered no read-only way to ask whether it took
  effect. `--retry-request` does dedupe correctly, but the recovery guidance
  emitted a query command only when the payload carried a dispatch id, which is
  exactly what a lost response lacks. Add read-only
  `orca orchestration request-show --request <id>` over the durable receipt
  ledger, and always emit a read-only step before the keyed retry.

- The bundled `orca-cli` guide documented `check --unread --inject`, a flag the
  parser rejects. Correct it to `--format` and add a ratchet that runs every
  orchestration invocation in the bundled guides through the real CLI parser.

- `check --json` is one stdout document and its keepalives are stderr-only; the
  reported `Extra data: line 2` came from merging the streams. Document the
  contract rather than changing the wire.

- A rejected lifecycle message is loud on both ends already, but the rejection
  never named the flag that supplies the missing capability. Name it.

* Harden orchestration mutation recovery guidance
2026-08-30 18:12:58 -07:00

34 lines
1.7 KiB
TypeScript

// Shared shape for `orchestration request-show`, the read-only answer to
// "did my mutation take effect?" when the response was lost in transit.
export const MUTATION_REQUEST_STATES = ['completed', 'pending', 'absent'] as const
export type OrchestrationMutationRequestState = (typeof MUTATION_REQUEST_STATES)[number]
export type OrchestrationMutationRequestShowResult = {
requestId: string
state: OrchestrationMutationRequestState
method?: string
createdAt?: string
updatedAt?: string
receipt?: unknown
// Why: `absent` is genuinely ambiguous, so the honest reading ships with the row
// instead of being re-derived (and softened) by every caller.
interpretation: string
}
export function describeMutationRequestState(params: {
requestId: string
state: OrchestrationMutationRequestState
method?: string
}): string {
const { requestId, state, method } = params
if (state === 'completed') {
return `Request ${requestId} already took effect${method ? ` (${method})` : ''}. Replaying it with --retry-request ${requestId} returns the recorded outcome and starts nothing new.`
}
if (state === 'pending') {
return `Request ${requestId} was accepted${method ? ` by ${method}` : ''} but its outcome is not recorded yet. The original mutation may still be running, or Orca may have restarted before recording its outcome. Wait for the original command when it is still running; otherwise replay it with --retry-request ${requestId}. Do not issue a fresh mutation.`
}
return `No receipt for request ${requestId} under this caller identity. It never reached this Orca runtime, failed before recording anything, or its receipt was pruned. Absent is not proof that nothing happened.`
}