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).
27 lines
1.5 KiB
Markdown
27 lines
1.5 KiB
Markdown
---
|
|
category: Added
|
|
---
|
|
|
|
- **Wait framework capability** — adds the reviewed `Contract.Wait`
|
|
declaration (`contract.WaitSpec`) with three execution modes: `poll`
|
|
(cadence-poll the leaf's `WaitPoll` hook), `event` (consume the leaf's
|
|
`WaitEvents` push stream, correlate events to the accepted resource via
|
|
`match_field`/`resource_query`, apply the same terminal map), and `auto`
|
|
(event first, fall back to polling when the stream ends or the
|
|
subscription fails — one deadline spans both phases). Declared commands
|
|
must use the `ResultInvoke` dispatcher; 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 → `failure` with new wire-stable `error.type: "wait"`
|
|
(exit code 8), timeout → `pending` with `meta.operation.timed_out: true`
|
|
and 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 (`wait` key) alongside `dry_run`. No
|
|
business command declares it yet; approval/export/batch adoption lands
|
|
separately.
|