fix: correct idempotency cache scope in docs + smoke#18
Merged
chenliuyun merged 1 commit intomainfrom Apr 20, 2026
Merged
Conversation
src/lib/idempotency.ts is an in-memory Map ("Process-local only — not
shared across replicas"), but CHANGELOG and capabilities.idempotencyContract
both claimed "keys are SHA-256-hashed on disk". An agent reading the
capabilities payload would assume cross-invocation replay works and be
mismatched against reality — the second real-device smoke run
(24649650541) surfaced this: the first CLI call wrote into the in-memory
cache, the second CLI call started fresh, and the `replayed:true` flag
never appeared because each `node` process was starting from empty.
Fixes scope only (no behavior change):
- CHANGELOG: replace "SHA-256-hashed on disk" with accurate in-memory
wording + enumerate which long-lived surfaces the cache covers (MCP,
batch, plan run, history replay).
- capabilities.idempotencyContract: keyStorage no longer claims disk
persistence; add `scope` field making the process-local constraint
explicit for agents reading capabilities.
- smoke.yml: drop cross-invocation replay + conflict assertions (they
can never pass given the process-local cache); keep a single flag-
accepted check against the real API. Cross-process behavior is covered
by tests/lib/idempotency.test.ts unit tests, which the smoke workflow
is not the right layer to re-verify.
Follow-up (deferred): if we want replay to survive across shell CLI
invocations, add a disk-backed store to IdempotencyCache (2.4.1 scope).
That is a feature addition, not required for 2.4.0 correctness.
chenliuyun
pushed a commit
that referenced
this pull request
Apr 20, 2026
C1 (#14): update --idempotency-key / --idempotency-key-prefix help text in devices.ts and batch.ts to mention process-local scope, per-process cache semantics, and that independent CLI invocations do not share cache. C2 (#15): mcp --help "eight tools" → "eleven tools"; list all 11 by name including get_device_history, query_device_history, aggregate_device_history. C3 (#17): add `scenes describe <sceneId>` subcommand. Returns sceneId, sceneName, stepCount:null, and a note explaining v1.1 API limitation. Exits 2 with scene_not_found + candidate list on unknown sceneId. Adds 'scenes describe' to COMMAND_META in capabilities.ts. Adds 2 tests (known + unknown scene). C4 (#13): add JSDoc comment on hints field in agent-bootstrap.ts clarifying empty array semantics. Add 'hints' field to cliAddedFields in schema.ts. C5 (#16): create docs/verbose-redaction.md documenting masked headers (authorization, token, sign, nonce, x-api-key, cookie, set-cookie, x-auth-token, t) and the --trace-unsafe opt-out flag. C6 (#18): plan schema output now includes agentNotes.deviceNameStrategy documenting that deviceName uses require-unique resolution and plans should pin deviceId for determinism. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
chenliuyun
pushed a commit
that referenced
this pull request
Apr 20, 2026
Document every fix landed in this branch beyond the history-aggregate feature: bugs #1, #4, #5, #6, #8, #9, #10, #11, #12, #13, #14, #15, #16, #17, #18 from the OpenClaw v2.4.0 smoke-test report. Call out the deferred items (#2, #7) explicitly so readers don't assume they were overlooked. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
4 tasks
chenliuyun
pushed a commit
that referenced
this pull request
Apr 20, 2026
C1 (#14): update --idempotency-key / --idempotency-key-prefix help text in devices.ts and batch.ts to mention process-local scope, per-process cache semantics, and that independent CLI invocations do not share cache. C2 (#15): mcp --help "eight tools" → "eleven tools"; list all 11 by name including get_device_history, query_device_history, aggregate_device_history. C3 (#17): add `scenes describe <sceneId>` subcommand. Returns sceneId, sceneName, stepCount:null, and a note explaining v1.1 API limitation. Exits 2 with scene_not_found + candidate list on unknown sceneId. Adds 'scenes describe' to COMMAND_META in capabilities.ts. Adds 2 tests (known + unknown scene). C4 (#13): add JSDoc comment on hints field in agent-bootstrap.ts clarifying empty array semantics. Add 'hints' field to cliAddedFields in schema.ts. C5 (#16): create docs/verbose-redaction.md documenting masked headers (authorization, token, sign, nonce, x-api-key, cookie, set-cookie, x-auth-token, t) and the --trace-unsafe opt-out flag. C6 (#18): plan schema output now includes agentNotes.deviceNameStrategy documenting that deviceName uses require-unique resolution and plans should pin deviceId for determinism.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The second real-device smoke run (24649650541) surfaced a doc/implementation drift:
src/lib/idempotency.tsis an in-memoryMap— its header comment even says "Process-local only — not shared across replicas" — but CHANGELOG +capabilities.idempotencyContract.keyStorageboth claimed "keys are SHA-256-hashed on disk". Agents reading capabilities would assume cross-CLI-invocation replay works. It does not: each freshnodeprocess starts with an empty cache, so the `replayed:true` flag never lit up on the second smoke invocation.Fix (docs match code; no behavior change)
Follow-up (deferred, not in this PR)
If we want replay semantics to survive across shell CLI invocations, `IdempotencyCache` needs a disk-backed store (atomic write + TTL cleanup + concurrent-read safety). That's a real feature addition — 2.4.1 scope, not required for 2.4.0 correctness.
Test plan