What Happened
@everme/agent-sdk@0.3.4 documents one retry for safe transport failures, but the retry branch is unreachable for native fetch failures:
execOnce() catches the native failure and wraps it in EvermeError.
execWithRetry() immediately rethrows every EvermeError.
- A synthetic local socket-reset probe therefore observes one request, not two.
There is a second semantic gap: /mem/search and /mem/context are safe reads implemented as POST, so method-only retry gating cannot cover them. When the error reaches @everme/memory-mcp, the adapter returns only error: <message> and drops correlation/classification data that an MCP host could use for health decisions.
This is separate from EverMind-AI/EverOS#338, which tracks ingestion task metadata and exact visibility verification.
Steps To Reproduce
- Use
@everme/agent-sdk@0.3.4 or current main at 0e6fd0ec90a2cf8a90946f434504b6813826eb1a.
- Point
createClient() at a local HTTP server that resets the first GET connection and succeeds on the second.
- Call
client.request("GET", "/healthz").
- Observe that the server receives one request and the caller receives
EvermeError immediately.
The same dead path applies to DNS/connection errors. POST /mem/search and POST /mem/context are never eligible under the current method-only check.
Expected Behavior
- Explicit semantic reads (
GET/HEAD, plus POST /mem/search and /mem/context) should make at most one bounded retry for transient transport failures, HTTP 429, and HTTP 5xx.
- All attempts and
Retry-After delay should share the original timeout budget.
- Non-idempotent memory writes must remain single-attempt, even if a caller mislabels one as a read.
- Exhausted errors should expose redacted fields such as classification, cause code, HTTP status, request id, attempts, retryability, and elapsed time.
- MCP tool failures should preserve those fields in
structuredContent.error while retaining the existing isError text response.
- Diagnostics must not include queries, request bodies, URLs, tokens, or native fetch cause text.
Environment
- Package:
@everme/agent-sdk@0.3.4, @everme/memory-mcp@0.3.4
- Runtime: Node.js 18+
- Reproduction: synthetic localhost transport failure; no production data involved
Proposed Fix
- Add explicit
safe_read / non_idempotent_write request semantics.
- Allow POST safe-read opt-in only for a hard allowlist of
/mem/search and /mem/context.
- Retry safe reads once within a shared deadline; do not start a second full timeout.
- Preserve structured, sanitized
EvermeError metadata through the MCP adapter.
- Add regression coverage for socket reset, DNS failure, timeout budget, 429, 5xx, 401/auth classification, and write single-attempt behavior.
Logs
No production logs are attached. The reproduction uses placeholder credentials and a local synthetic endpoint only.
What Happened
@everme/agent-sdk@0.3.4documents one retry for safe transport failures, but the retry branch is unreachable for nativefetchfailures:execOnce()catches the native failure and wraps it inEvermeError.execWithRetry()immediately rethrows everyEvermeError.There is a second semantic gap:
/mem/searchand/mem/contextare safe reads implemented as POST, so method-only retry gating cannot cover them. When the error reaches@everme/memory-mcp, the adapter returns onlyerror: <message>and drops correlation/classification data that an MCP host could use for health decisions.This is separate from EverMind-AI/EverOS#338, which tracks ingestion task metadata and exact visibility verification.
Steps To Reproduce
@everme/agent-sdk@0.3.4or currentmainat0e6fd0ec90a2cf8a90946f434504b6813826eb1a.createClient()at a local HTTP server that resets the first GET connection and succeeds on the second.client.request("GET", "/healthz").EvermeErrorimmediately.The same dead path applies to DNS/connection errors. POST
/mem/searchand POST/mem/contextare never eligible under the current method-only check.Expected Behavior
GET/HEAD, plus POST/mem/searchand/mem/context) should make at most one bounded retry for transient transport failures, HTTP 429, and HTTP 5xx.Retry-Afterdelay should share the original timeout budget.structuredContent.errorwhile retaining the existingisErrortext response.Environment
@everme/agent-sdk@0.3.4,@everme/memory-mcp@0.3.4Proposed Fix
safe_read/non_idempotent_writerequest semantics./mem/searchand/mem/context.EvermeErrormetadata through the MCP adapter.Logs
No production logs are attached. The reproduction uses placeholder credentials and a local synthetic endpoint only.