From 70ddf201eb06dc128bcce99a0f912d2685aa8d78 Mon Sep 17 00:00:00 2001 From: mikemolinet Date: Mon, 11 May 2026 18:01:54 -0700 Subject: [PATCH] feat(action): forward --verify opt-in flag for fire (cueapi-cli #55 parity) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cueapi-cli #55 added a --verify opt-in flag to the `fire` command for Phase 2 body-verify (Mike directive 2026-05-11). The Action's fire step should forward it so GitHub Actions callers can opt into body-verify on cues fire from their workflows. ## Why opt-in for fire (vs default-on for messages) Substrate /v1/cues/{id}/fire echoes a pydantic-after-parse body that may include server-side default-population, causing spurious diff vs the CLI's canonical-JSON serialization. So fire's verify is opt-in; messages' verify is default-on (different endpoint, different echo semantics post-#798 spec-lock). ## Change - Adds a new `verify` action input (default empty/false). - Sets `VERIFY: ${{ inputs.verify }}` env in runs.steps. - Wires `[ "$VERIFY" = "true" ] && cmd+=(--verify)` into the fire case. ## Naming clarity The `verify` input is intentionally NOT the same as `no-verify`: - `no-verify`: messages-send / message-to (default-on opt-out — verify-on by default) - `verify`: fire (default-off opt-in — verify-off by default) Both inputs are documented with the divergence noted explicitly. ## Out of scope - No test framework in cueapi-action (action.yml + shell). YAML validates; the runtime path was inherited from the cli #55 changes which have 219/219 tests passing including `test_fire_verify_*`. Companion PRs: - cueapi-cli #55 (--verify flag) - cueapi-python #41 (auto_verify kwarg) - cueapi-mcp #36 (auto_verify schema field on cueapi_fire_cue) --- action.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/action.yml b/action.yml index a60ba7b..b196aaa 100644 --- a/action.yml +++ b/action.yml @@ -115,6 +115,20 @@ inputs: verification_failed. Pass an empty string to opt out of cue-level required_assertions for this fire. Max 20 keys. required: false + verify: + description: | + Set "true" to OPT IN to Phase 2 body-verify on `fire` (parity with + cueapi-cli #55 + cueapi-python #41, Mike body-verify directive + 2026-05-11). When set, cueapi-cli sends X-CueAPI-Verify-Echo header + + checks substrate-echoed body matches sent body, failing the Action + step (exit 7) on drift. Default OFF for fire because substrate + /v1/cues/{id}/fire echoes a pydantic-after-parse body that may + include server-side default-population, causing spurious diff vs + the CLI's canonical-JSON serialization. Opt in when you know your + payload-override serialization matches substrate echo semantics. + NOTE: distinct from `no-verify` (which is for messages — default-on + opt-out); fire is default-off opt-in. + required: false # Executions lifecycle inputs (cueapi 0.2.0+). execution-id: @@ -364,6 +378,7 @@ runs: # Per-fire/per-message scheduling + work-verification (PR #618 / #623 / #632). SEND_AT: ${{ inputs.send-at }} EXIT_CRITERIA: ${{ inputs.exit-criteria }} + VERIFY: ${{ inputs.verify }} EXECUTION_ID: ${{ inputs.execution-id }} WORKER_ID: ${{ inputs.worker-id }} TASK: ${{ inputs.task }} @@ -459,6 +474,11 @@ runs: [ -n "$MERGE_STRATEGY" ] && cmd+=(--merge-strategy "$MERGE_STRATEGY") [ -n "$SEND_AT" ] && cmd+=(--send-at "$SEND_AT") [ -n "$IDEMPOTENCY_KEY" ] && cmd+=(--idempotency-key "$IDEMPOTENCY_KEY") + # Phase 2 body-verify opt-in for fire (cueapi-cli #55, Mike directive + # 2026-05-11). Default OFF — substrate echoes parsed-after-default body + # that would cause spurious mismatches for the typical caller. Opt in + # when the caller knows substrate echo matches their serialization. + [ "$VERIFY" = "true" ] && cmd+=(--verify) # Whitespace-separated list of assertion keys → repeated --exit-criteria # flags (the CLI uses click's `multiple=True`, so each key needs its own # flag invocation). Empty string === field not passed, in which case