Skip to content

fix(messages send + message-to): body_received is dict not flat string#53

Merged
mikemolinet merged 1 commit into
mainfrom
fix/body-verify-echo-wire-shape
May 11, 2026
Merged

fix(messages send + message-to): body_received is dict not flat string#53
mikemolinet merged 1 commit into
mainfrom
fix/body-verify-echo-wire-shape

Conversation

@mikemolinet
Copy link
Copy Markdown
Collaborator

Summary

Hotfix for PR #52 (Phase 2 auto-verify). Empirically-verified wire shape (~23:17Z probe): substrate's body_received is the PARSED request dict, NOT flat string per the spec text. PM fired primary at 23:20Z to fix substrate to flat-string; this fix handles BOTH shapes via defensive isinstance — no rework needed when primary's substrate fix lands.

Fix shape

  • dict: extract body_received.body for diff
  • str: use as-is
  • neither: no-op (backward-compat)

12 verify-related tests pass including new flat-string defensive test.

🤖 Generated with Claude Code

@mikemolinet mikemolinet merged commit 774ff55 into main May 11, 2026
3 of 4 checks passed
@mikemolinet mikemolinet deleted the fix/body-verify-echo-wire-shape branch May 11, 2026 23:23
mikemolinet added a commit that referenced this pull request May 12, 2026
…y, Mike body-verify directive 2026-05-11) (#55)

Parity port of cueapi-python #41 — body-verify Phase 2 on cues.fire,
but **OPT-IN** (not default-on) because the substrate's
/v1/cues/{id}/fire endpoint echoes a pydantic-after-parse body that
may include server-side default-population, causing spurious diff
vs the CLI's canonical-JSON serialization.

Mirrors primary's #41 design rationale: default OFF; caller opts in
with --verify when they know substrate echo semantics match their
serialization (typical for the sha256 constant-cost path).

Diverges from messages-send body-verify which is default-on
(--no-verify opt-out) because that endpoint echoes the raw STRING
body field per the spec-lock — no parsed-defaulted shape concern.

Implementation:
- New --verify click flag (is_flag, default False). Help text
  documents the OPT-IN rationale + the substrate-echo-shape concern.
- When --verify: send X-CueAPI-Verify-Echo: true header; pre-compute
  sha256(canonical-JSON(body)) hexdigest client-side.
- On 2xx response: compare sha256 first (constant-cost). If sha
  mismatch, fall back to string compare of body_received vs canonical
  body JSON. Spurious sha mismatch (e.g. canonical-JSON serialization
  diff) is rescued by the string compare.
- Defensive isinstance: body_received as string (post-#798 spec-lock)
  OR dict (pre-#798 wire shape). Matches the same pattern in
  cueapi-cli messages-send (#53) and cueapi-python messages.send
  (#40).
- On confirmed mismatch: exit 7 with byte-divergence diagnostic.
  Uses click.echo + raise SystemExit(7) directly (NOT echo_error
  which would raise SystemExit(1) and shadow the verify-specific
  exit code).

Tests (4 new):
- test_fire_verify_off_by_default_omits_header — no --verify ⇒ no
  X-CueAPI-Verify-Echo header (preserves pre-#791 wire format)
- test_fire_verify_on_sends_header — --verify ⇒ header set + sha
  match path passes silently
- test_fire_verify_help_lists_flag — --help mentions --verify + the
  opt-in rationale so users discover the design context
- test_fire_verify_mismatch_exits_7 — substrate echoes corrupted
  body ⇒ exit 7 with "body-verify mismatch" diagnostic

Full file: 219/219 passing (was 215 + 4 new = 219).

Backlog row: cmp1wj0q3.

Out of scope:
- cueapi-mcp parity (Backlog cmp1wj2a6) — separate PR.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant