fix: make agentcore memory actually work end-to-end (Hive Mind)#79
Conversation
…d phase 1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Implements docs/superpowers/specs/2026-07-12-agentcore-onboarding-fix-design.md: - config: delete the vestigial memory-ID env-var gate and both dead Config fields; backend resolution is now env > $BETTER_MEMORY_HOME/settings.json > sqlite via public resolve_storage_backend(); region single-sourced from agentcore.json (BETTER_MEMORY_AGENTCORE_REGION deleted); boto3 ImportError gains a better-memory[agentcore] install hint; AgentCoreConfigError messages gain remediation text - mcp: dispatch wired — memory.observe/semantic_observe/record_use/ retrieve_observations/credit/semantic CRUD route to AgentCoreBackend in agentcore mode via additive keyword-only remote param (sqlite branch verbatim); episode/retention tools hidden via supports_episodes; lazy session-id re-resolution in the backend - hooks: session_close backend gate is settings-aware (env still wins, zero I/O on the sqlite fast path); session_bootstrap routes through build_backend in agentcore mode; boto3 hint mirrored - cli: agentcore init activates by default (atomic merge-write of settings.json, --no-activate opt-out); honest next-steps output; status reports effective backend + source - e2e: pin tests inverted per their FIXME contracts (dispatch-gap -> TestMcpDispatchWired with wire assertions, region split-brain -> TestRegionSingleSource convergence, idvar machinery deleted, anti- resurrection grep-pin added); new write_backend_settings helper - NEW tests/e2e/test_agentcore_journey.py: 8-step full-flow journey on the shipped onboarding config (settings.json, zero env knobs) with per-step wire assertions and no-sqlite-leakage checks; live T3 journey additions - tests/conftest.py: autouse BETTER_MEMORY_HOME isolation (unit tests must never read the developer's real settings.json) - docs: truth-first sweep of README + website (activation flow, deleted env vars, corrected sqlite-traffic claim, init next-steps quoted from source) Full suite: 1388 passed, 22 skipped. Pyright 0 errors. Ruff delta vs main: 0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…rs (Hive repair wave) Live-AWS scout empirically mapped the record-plane dialect against a throwaway memory pair (notes: aws_record_dialect.md); repairs per findings: - storage/agentcore.py + cli smoke: BatchCreateMemoryRecords uses requestIdentifier+timestamp (memoryRecordId rejected by the real model); polarity filtering reworked to what ListMemoryRecords actually supports; semantic read path queries the exact write namespaces; BatchUpdate full-snapshot shape corrected for record_use/credit/ratings - backend majors: session id re-resolved per operation (no process-lifetime freeze on a stale marker); promoted/general reflections fanned into retrieve() + session_bootstrap() (two-namespace merge, deduped) - hooks majors: session marker written BEFORE backend wire calls (contract change — degraded first sessions now still bridge their session id; C2/C3 pins updated, M2 mutation replaced accordingly); session_close closure actorId uses canonical project_name() instead of basename(cwd) - payload parity: apply_session_ratings returns the sqlite shape, retrieve strips internal ranking keys, retrieve_observations key parity, session_bootstrap honors cwd - fake endpoint now REJECTS what real AWS rejects (unknown record keys, unregistered metadata filter keys) so the hermetic tier cannot drift - hygiene: settings read tolerates OSError; unit tests no longer read the developer's real settings.json; live-test Namespace fixes Full suite: 1416 passed, 22 skipped. Pyright 0 errors. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…e updates - storage/agentcore.py: reflections fetch pages with nextToken under the real service's maxResults<=100 constraint (live ValidationException at 120); list_events clamped - fake endpoint enforces the cap so the hermetic tier pins it - live tests: E4 polls retrieves with a bounded retry (record index lags ~60s per the dialect scout — writes are synchronous, the LIST index is not); E5 asserts the sqlite-parity ratings shape; E7 reads back the closure event under the canonical project actor (the actor-consistency fix moved it off basename(cwd)) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔴 Claude BugBot Analysis
Found 1 potential bug in this PR.
low: 1
This PR adds a large AgentCore (AWS-backed) storage backend alongside the existing sqlite backend. Extensive review (3 parallel deep-dive agents plus manual cross-checks of config resolution, backend dispatch, async/sync call signatures, and namespace/metadata handling) found the implementation to be well-guarded and consistent; the only confirmed defect is a diagnostic-accuracy gap in the agentcore status CLI command's backend-resolution helper.
BugBot (PR #79): _effective_backend presented a raw invalid env value as a working backend while the runtime resolver raises on it and the server refuses to start. Status now reports 'env — INVALID value; the MCP server will refuse to start' and keeps going; triggering test added. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🔴 Claude BugBot Analysis
Found 1 potential bug in this PR.
low: 1
This PR adds an AWS AgentCore storage backend across ~14 core source files; after parallelized, cross-verified review of every changed production file (storage/agentcore.py, storage/agentcore_persistence.py, storage/factory.py, cli/agentcore.py, config.py, hooks/session_bootstrap.py, hooks/session_close.py, all five mcp/handlers/*.py, mcp/server.py, mcp/tools.py), only one low-severity issue was confirmed — misleading CLI output text — with no logic errors, race conditions, null dereferences, resource leaks, or incorrect API usage found in the added/modified lines.
BugBot (PR #79): with --no-activate the unconditional next-steps block still said 'restart ... so it picks up the new backend', contradicting the skip message printed one line earlier. Next steps now branch on activate; stdout-contract test extended. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
🟢 Claude BugBot Analysis
Reviewed the AgentCore storage-backend PR (core changes in better_memory/storage/agentcore.py, factory.py, agentcore_persistence.py, config.py, mcp/handlers/*, mcp/server.py, cli/agentcore.py, and the two session hooks) line-by-line against the design doc, verified call-signature and namespace/dedup/pagination logic, and ran the fast unit/mcp/hooks/cli/storage test suites (421 tests) which all pass. No genuine bugs were found in the added/modified lines.
No bugs were detected in this PR.
Summary
Agentcore mode was unusable end-to-end (12 defects documented in PR #78's design doc). This PR fixes every agentcore blocker and proves the result against real AWS: 9/9 live tests green in eu-west-2, zero resource residue.
Product fixes
config.py) — the docs-following setup no longer dies pre-handshakesettings.json—agentcore initpersists{"storage_backend": "agentcore"}(atomic merge-write,--no-activateopt-out); resolution is env > settings.json > sqlite via publicresolve_storage_backend(); hooks no longer need system-wide env exportsmemory.observe/semantic_observe/record_use/retrieve_observations/credit/semantic CRUD now reachAgentCoreBackendin agentcore mode (sqlite branch verbatim); episode/retention tools hidden viasupports_episodesagentcore.json(BETTER_MEMORY_AGENTCORE_REGIONdeleted) — split-brain impossiblerequestIdentifier+timestampbatch-create shape, indexed-key-aware filtering, exact-namespace reads,maxResults<=100with pagination, full-snapshot update shapeproject_name(), promoted/general reflections visible in retrieve/bootstrapbetter-memory[agentcore]install hint, remediation text on corruptagentcore.jsonTest additions
tests/e2e/test_agentcore_journey.py— 8-step full-flow journey on the shipped onboarding config (settings.json, zero env knobs) with per-step wire assertions + zero-sqlite-leakage checksEvidence
Contract changes to note
agentcore initnow activates agentcore mode by default (--no-activatefor provision-only)BETTER_MEMORY_AGENTCORE_REGION+ the twoBETTER_MEMORY_AGENTCORE_*_MEMORY_IDenv vars are gone (values were never consumed)🤖 Generated with Claude Code