Harden runtime: providers, transport, HTTP contract, security, metrics - #1
Merged
Merged
Conversation
Fixes from a multi-agent system review (isolated, non-overlapping scopes): - mem0: drop instance-method lru_cache (leak + stale backend on reconfigure); attribute post-add fallback to the actual write instead of an arbitrary row - metrics: bound error-type/model label cardinality with __other__ overflow - atomic_io: fsync parent directory after os.replace for crash durability - reconcile: partition claims by scope so cross-user matches aren't false conflicts - clients: per-target error isolation; malformed client config no longer aborts the batch or clobbers an unreadable file - scope_registry: enable WAL + busy_timeout; surface status-write failures - api/oauth: reject PLAIN PKCE (S256 only); exact-hostname redirect_uri check; rate-limit the authorize endpoint - http_client/transport: scope the start lock to spawn only; verify owner by pid; map 401/403 to an actionable auth error https://claude.ai/code/session_01BKjtun7hVwxh6Hv3YLdrww
- operation_adapters: HTTP `add` now accepts the documented `text` field and synthesizes `messages` like the MCP/CLI adapters (fixes KeyError on the published contract) - HTTP query/body sources now validate against each operation's input schema (limit/enum/type/unexpected-field checks), matching MCP behavior - extract the shared validator into runtime/schema_validation.py; mcp.py reuses it with no behavior change; lazy OPERATIONS import avoids a cycle https://claude.ai/code/session_01BKjtun7hVwxh6Hv3YLdrww
The test mocks a localjson-like direct provider and expects the dispatcher to reach the mocked memory_search, but it never pinned the transport. should_proxy_ to_api() then read the ambient active provider (mem0 by default), so the call leaked into the owner-process proxy and failed (rc=2) wherever no API is running -- e.g. the provider-certification CI job, which runs with no config. Mock should_proxy_to_api to False so the test exercises the in-process path it intends. https://claude.ai/code/session_01BKjtun7hVwxh6Hv3YLdrww
These surfaced because this is the first PR to run the CI/certification workflows (they trigger on pull_request and push:main, but the default branch is master), not from the hardening changes. - provider-certification: test_localjson_provider (and mempalace, claude_memory) imported the harness only via `from tests.provider_contract_harness`, which fails under the cert runner's discover when `tests` isn't an importable package (PEP 660 editable install exposes only `agentmemory`). Mirror the robust top-level-first fallback already used by test_mem0_provider. - ubuntu/windows test job: test_text_config_status_detects_configured_launcher hardcoded an absolute launcher path that only matches the author's install root, reading as stale everywhere else. Build it from expected_launcher_path() so the assertion is host-portable. https://claude.ai/code/session_01BKjtun7hVwxh6Hv3YLdrww
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
Fixes from a multi-scope code review of the runtime. Each fix was scoped to a disjoint set of files so changes don't overlap. No data migration; existing mem0 stores and access paths are unaffected (qdrant config/read paths unchanged; the scope-registry is a separate, rebuildable index).
Correctness
addcontract — the HTTP surface now accepts the documentedtextfield and synthesizesmessageslike the MCP/CLI adapters (previously{"text": ...}returned aKeyError/400).runtime/schema_validation.py.(user, agent, run), eliminating cross-user false positives and reducing the O(n²) pass to per-group.Reliability / concurrency
@lru_cacheon instance methods with per-instance caches, so a reconfigured provider rebuildsMemoryand re-reads the API key (no stale backend, no instance leak).should_proxy_to_api()now confirms ownership by matchingos.getpid()against the recorded API pid, so a child that inheritsAGENTMEMORY_OWNER_PROCESS=1no longer touches the embedded backend directly.AGENTMEMORY_API_TOKEN" message instead of a misleading validation error.busy_timeout/synchronous=NORMAL; a failedneeds_rebuildstatus write is logged instead of silently swallowed.os.replace(POSIX) for true crash durability; gracefully skipped where unsupported.Security
redirect_uriis validated by exact hostname (127.0.0.1/::1/localhost, rejecting@/suffix spoofing);/oauth/authorizeis rate-limited.Metrics
__other__to prevent unbounded memory/series growth; histogramlelabels render as plain numbers.Test plan
python -m unittest discover -s tests— 422 tests, no new failures (2 pre-existing env-dependent failures confirmed against the base commit).OPENROUTER_API_KEYis configured.Behavioral notes (not breakage)
limit < 1→ 400).-wal/-shmsidecars); no action required.https://claude.ai/code/session_01BKjtun7hVwxh6Hv3YLdrww
Generated by Claude Code