Skip to content

Meridian reliability: make concurrent RLM subagents production-safe over Claude Max #22

Description

@rynfar

Umbrella for making Meridian (the Claude Agent SDK proxy at rynfar/meridian) a production-safe provider for Prime Agent, including concurrent RLM subagents. Meridian's README currently rates Prime Agent "single-agent verified" with these failure modes: overload amplification, expensive cache churn after fresh-session replay, loss of child-task context during recovery, undelivered tool envelopes, incomplete parent-to-child cancellation.

Measured evidence (Meridian telemetry, real prime traffic 2026-08-17/18)

  • prime adapter averaged 65.8% cache hit vs 95.1% for OpenCode; 212 successful requests ran below 20% cache hit and wrote ~12M cache-creation tokens.
  • Repeated cache_miss: Cache hit rate 0% on resume (expected >50%) diagnostics on continuations.
  • Resume-failure cascade observed: "You've hit your session limit" on resume, then the same request retried resume=false (full fresh replay) one second later; a dozen requests failed in ~15s.
  • 3× ENVELOPE VIOLATION [undelivered_tool_use] on the ipython tool, two coinciding with upstream 529s.

Root causes on the Prime Agent side (verified in this repo)

  1. Provider identity is unstable and collapses for inline subagents. The Meridian extension stamps metadata.user_id from ctx.sessionManager.getSessionId() in before_provider_request. Inline RLM children reuse the parent's extension runner (packages/coding-agent/src/core/agent-session.ts inline child construction copies onPayload: this.agent.onPayload; the root streamFn/onPayload in packages/coding-agent/src/core/sdk.ts closes over the root extensionRunnerRef), so every inline child request is stamped with the parent's session key. Interleaved parent/child histories on one proxy session key force a fresh-session replay nearly every round. SessionManager.sessionId also mutates on fork/branch/load, and compaction/branch-summarization/refinement completeSimple calls bypass onPayload entirely (unkeyed). → feat(agent): stable child-scoped provider identity for RLM subagents, side questions, and auxiliary requests #23
  2. Retries multiply against an overloaded upstream. Session-level auto-retry (_isRetryableError treats every stopReason === "error" as retryable; fixed 2s/4s/8s backoff, no jitter, no Retry-After) stacks on the Anthropic SDK's own maxRetries, ≈ 4 × (1 + sdkRetries) requests per failed turn per agent, times N concurrent children. maxRetryDelayMs is declared and threaded but never read by any provider (dead code). → fix(agent): kind-aware retry with Retry-After and jitter; implement dead maxRetryDelayMs; stop SDK-times-session retry multiplication #24
  3. User-facing cancel does not reach children. requestAbort() does not call _cancelActiveRlmChildRuns() (only abort() does), and every user-facing cancel path uses requestAbort(). Orphaned children keep consuming the Max subscription. → fix(agent): requestAbort() must cascade to active RLM child runs #25
  4. The cached prompt prefix is volatile. Mutable continual-harness state and Current date: are serialized into the system prompt; cache_control rides the last tool definition so tool-set changes/reordering invalidate the tool cache. → perf(agent): keep the prompt-cache prefix stable across harness updates, date flips, and tool refreshes #26

Meridian-side work (tracked in rynfar/meridian, cross-linked)

Sequencing

Per PYLON.md, each item needs an upstream-overlap check and a .pylon/features.yaml decision before landing.

Activity

  1. rynfar commented on Aug 31, 2026

    @rynfar
    Author

    Status: all three P0 implementation slices are up and reviewed.

    Merge-order note for #30/#31: both touch agent-session.ts, side-question.ts, and the .pylon ledgers; whichever merges second needs a rebase.

    Remaining, deliberately queued to avoid stacking more unmerged branches on agent-session.ts: #25 (requestAbort cascade), #26 (cache-prefix stability), and rynfar/meridian#902 (parent-tree cancellation, blocked on the parent_session_id wire contract deferred from #23).

  2. rynfar commented on Aug 31, 2026

    @rynfar
    Author

    All sequenced work has landed. Merged:

    Extension contract v2 is deployed to the maintainer's ~/.prime/agent/extensions/meridian.ts: appendOnlyHistory: true on the model entry and guarded parent_session_id stamping.

    Remaining deployment note: merged is not yet running — Meridian needs a release published and the global install updated, and the Prime Agent fork has no release pipeline by design (see PYLON.md release boundary), so running builds must come from the fork source until that is designed. Deferred items are recorded on the individual PRs. Closing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions