Completes the wait capability per review guidance ("add corresponding
execution hooks and fallback tests for the modes"):
- contract.WaitSpec restores event/auto modes with event_key,
match_field, and a new resource_query (dotted path into the accepted
result data yielding the identifier events correlate against);
per-mode validation of required fields
- internal/wait adds EventStream (leaf-owned transport) and RunEvent:
correlated-event filtering, the same terminal/pending/unknown mapping
as polling, timed-out pending on deadline during consumption, and an
ErrEventStreamEnded sentinel distinguishing stream termination from
fail-closed status errors
- Spec.WaitEvents hook; validateWaitDecl pairs mode with hooks
(poll<->WaitPoll, event<->WaitEvents, auto<->both; surplus hooks
rejected too)
- the wait phase runs event-first in auto mode and falls back to polling
when the stream ends or the subscription fails, under one deadline
spanning both phases; strict event mode surfaces stream errors
- output.CommandResult gains Data() (deep copy) so the framework can
resolve the resource identifier without exposing mutable state
Changed-code coverage re-verified at 100% (CI cross-package recipe).
1.5 KiB
1.5 KiB
category
| category |
|---|
| Added |
- Wait framework capability — adds the reviewed
Contract.Waitdeclaration (contract.WaitSpec) with three execution modes:poll(cadence-poll the leaf'sWaitPollhook),event(consume the leaf'sWaitEventspush stream, correlate events to the accepted resource viamatch_field/resource_query, apply the same terminal map), andauto(event first, fall back to polling when the stream ends or the subscription fails — one deadline spans both phases). Declared commands must use theResultInvokedispatcher; mode and hooks are paired at construction (poll↔WaitPoll, event↔WaitEvents, auto↔both; surplus hooks are rejected too). Declared commands register--wait/--wait-timeout(framework-owned flags that never enter MCP toolArgs); undeclared commands reject the flags as unknown. The wait phase closes the unified envelope exactly once: terminal success →success, terminal failure →failurewith new wire-stableerror.type: "wait"(exit code 8), timeout →pendingwithmeta.operation.timed_out: trueand the last observed state (exit 0). Deadline exhaustion during a poll, during event consumption, or between polls always closes as timed-out pending, never as a poll/stream failure; a correlated event with an unknown status fails closed exactly like a poll. The capability is projected into the Schema catalog (waitkey) alongsidedry_run. No business command declares it yet; approval/export/batch adoption lands separately.