You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Mike body-verify directive 2026-05-11 — Layer 2 SDK auto-verify
across cueapi-python. Sibling to Layer 3 force-file mode shipped in
cueapi-cli #51 + cue-mac-app commit b892613.
Bug class (caller-side shell expansion silently mutating body content
BEFORE the SDK receives it): cueapi-cli #51 closed the CLI side via
force-file mode. cueapi-python callers (notebook / script / hosted
agent runtime) hit the same class via f-strings + os.popen + format()
+ similar Python-level mutation hidden under "literal string".
Auto-verify catches it server-side via echo-back, raising
BodyVerifyMismatchError instead of silent corruption.
Changes:
cueapi/exceptions.py:
- BodyVerifyMismatchError(CueAPIError) — new exception with sent_body,
received_body, first_divergence_byte, message_id attributes.
- first_divergence_byte(a, b) — pure helper returning byte index of
first differing position. -1 when one is a proper prefix of the
other (length mismatch; caller distinguishes via len()). Cross-SDK
re-usable.
cueapi/resources/messages.py:
- send(auto_verify=True) — new kwarg, default ON per CTO concur
(Q-C4). Adds X-CueAPI-Verify-Echo: true header. After 201, checks
response.get("body_received") against sent body; raises
BodyVerifyMismatchError on mismatch.
- Backward-compat: when substrate omits body_received field (pre-
Layer-1 deploy), SDK silently no-ops. Existing callers see no
behavior change until both Layer 1 + Layer 2 are deployed.
- Opt-out: auto_verify=False omits header + skips check.
tests/test_messages_resource.py:
- 11 new tests pin:
- Default auto_verify=True adds header
- Opt-out omits header
- Byte-identical response returns normally
- Mismatched response raises BodyVerifyMismatchError with attributes
- Substrate omits echo field → no raise (backward-compat)
- Opt-out skips verify even if substrate echoes
- first_divergence_byte: equal, prefix, first-char, middle, realistic
metachar-substitution scenario
- 4 existing tests updated to expect default-on header.
- All 22 messages tests pass.
Phase 2 substrate field name `body_received` documented as locked
during joint CMA + cueapi-primary design (design Dock workspace
cue-message-silent-corruption-substrate-design-2026-05-11). If
Layer 1 ships under a different name, update _VERIFY_ECHO_FIELD
constant (single 1-line change).
CHANGELOG entry under [Unreleased].
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,6 +6,7 @@ All notable changes to cueapi-sdk will be documented here.
6
6
7
7
### Added
8
8
9
+
-**`client.messages.send(auto_verify=True)` body-verify defense (Mike directive 2026-05-11).** New `auto_verify` kwarg, default `True`. When set, the SDK sends `X-CueAPI-Verify-Echo: true` request header. Substrate-side (Phase 1; cueapi-core's lane) echoes the body it received back in the response under `body_received`. SDK diffs sent vs received and raises `BodyVerifyMismatchError` on drift (with `sent_body`, `received_body`, `first_divergence_byte`, `message_id` attributes for programmatic recovery / diagnostic output). Catches the caller-side shell-expansion bug class where `body=f"... {dynamic_var} ..."` or worse `body=os.popen(...)` silently mutated body content upstream. Opt-out via `auto_verify=False` for perf-sensitive flows. Backward-compat: SDK no-ops when substrate omits the echo field (pre-Layer-1 behavior unchanged). New helper: `cueapi.exceptions.first_divergence_byte(a, b)` returns the byte index of the first differing position (pure function; re-usable cross-SDK).
9
10
-`client.cues.bulk_delete(ids)` — delete up to 100 cues in a single call. Returns `{"deleted": [...], "skipped": [...]}`. Per-ID atomic, not batch atomic. Sends `X-Confirm-Destructive: true` header automatically. Wraps `POST /v1/cues/bulk-delete` (cueapi #650). Parity port of cueapi-cli #46. Raises `ValueError` client-side on empty list or > 100 IDs.
0 commit comments