LearnNewsExamplesServices
Frontmatter
title>-
authorneo-opus-ada
stateClosed
createdAtMay 11, 2026, 7:39 AM
updatedAtMay 22, 2026, 8:27 PM
closedAtMay 11, 2026, 7:41 AM
mergedAt
branchesdevagent/11182-wake-subscription-reconciler-v2
urlhttps://github.com/neomjs/neo/pull/11184

Running 42 tests using 1 worker

Closed
neo-opus-ada
neo-opus-ada commented on May 11, 2026, 7:39 AM

Authored by Neo Claude Opus 4.7 (Claude Code). Session c2912891-b459-4a03-b2af-154d5e264df1.

Refs #11182 (Phase 2 Layer 2 reconciler — partial implementation; #11182 remains OPEN after merge; Layer 1 + Layer 3 + Layer 4 deferred to follow-up work)

Supersedes PR #11183 (closed per @neo-gpt's Cycle 2 RA on branch-history cleanliness; v2 has a single clean commit instead of 2 commits with stale Resolves metadata).

Summary

Recovery substrate for cross-session duplicate WAKE_SUBSCRIPTION accumulation. Empirically both @neo-opus-ada and @neo-gpt accumulated 2 active subscriptions per identity with identical route-tuples, ~2 days apart (one created per session-boot). The static idempotency check via _findActiveSubscriptionByRoute() looks correct on paper but empirically misses existing-rows at next-session bootstrap.

This PR makes bootstrap the canonical retire point: scan SQLite for all this-agent's active subscriptions, group by canonical route-key (same key the service uses for idempotency), and retire N-1 PER GROUP. Route-aware grouping preserves legitimate multi-route setups (e.g., distinct SENT_TO_ME + TASK_STATE_CHANGED routes for same agent); only true duplicates within an identical route-tuple are retired.

Evidence: L1 (static contract audit + 5 new Playwright unit tests with empirical-anchored timestamps, all pass alongside 37 existing in spec) → L1 required.

What changed

ai/services/memory-core/WakeSubscriptionService.mjs (route-aware reconciler — single clean commit):

  1. bootstrap() calls _reconcileDuplicateSubscriptions(owner) as FIRST step, BEFORE _findActiveSubscriptionByRoute(...).

  2. New protected _reconcileDuplicateSubscriptions(owner):

    • Fetches all this-agent's active subscriptions via direct SQLite scan
    • Groups by canonical route-key via _buildSubscriptionRouteKey() — same key the service uses elsewhere for idempotency
    • Retires N-1 PER GROUP (not owner-wide) — preserves legitimate distinct routes
    • Returns count of retired subscriptions (0 on canonical state — idempotent)
    • Logs warning per route-group on retire (preserves diagnostic trail)
  3. New protected _retireSubscription(id):

    • Marks the durable node status='retired' + adds retiredAt timestamp
    • Drops from in-memory subscriptionCache
    • Does NOT remove the SUBSCRIBES_TO edge (preserves audit trail)
    • Distinct from unsubscribe() (agent-initiated removal); reconciler is system-initiated stale-duplicate-retire

test/playwright/unit/ai/services/memory-core/WakeSubscriptionService.spec.mjs (5 new tests in bootstrap describe block):

  • reconciles duplicate active subscriptions at bootstrap, keeping newest (#11182) — empirical timestamps from bug report
  • reconciler is idempotent on canonical single-active state (#11182) — single active, no-op
  • reconciler retires N-1 when 3+ duplicates exist, keeping newest (#11182) — 3 subs in same route, only newest survives
  • reconciler preserves distinct route-tuples for same owner (#11183 Cycle 1 GPT-RA1) — SENT_TO_ME + TASK_STATE_CHANGED for same agent BOTH survive
  • reconciler ignores already-retired or inactive subscriptions (#11182) — pre-retired stays retired

Test Evidence

CI=true npm run test-unit -- --retries 0 test/playwright/unit/ai/services/memory-core/WakeSubscriptionService.spec.mjs


<h1 class="neo-h1" data-record-id="5">··········································</h1>

<h1 class="neo-h1" data-record-id="6">42 passed (877ms)</h1>

All 42 tests pass (37 prior + 5 new). No regressions.

Acceptance Criteria Coverage

FULLY addresses (Phase 2 / Layer 2 scope):

  • AC2 (bootstrap idempotent on repeated calls)
  • AC3 (startup-time reconciler retires duplicates)
  • AC5 (test coverage for duplicate-accumulation)

Does NOT address (#11182 stays open after merge):

  • AC1 (read-path silent-strip audit) — Layer 1; reconciler bypasses rather than fixes
  • AC4 (@neo-gpt wake-event delivery) — Layer 3; harness-specific Codex investigation
  • AC6 (Codex-Desktop harness test coverage) — Layer 3
  • AC7 (post-merge 7-day verification) — awaits 7 days post-merge
  • AC8 (cross-substrate canonicalization audit) — Layer 4; connects #11181 + #11182

Substrate-discipline notes

  • Cross-session duplicate-accumulation root cause is unclear without runtime instrumentation; static V-B-A on _findActiveSubscriptionByRoute() shows architecture-correct-on-paper. The recovery substrate (Layer 2) works regardless of WHY duplicates accumulate. Detailed V-B-A findings: #11182 comment
  • This PR supersedes #11183 (which had Cycle 1 + Cycle 2 reviews from @neo-gpt). RAs from both cycles addressed in this single clean commit. Branch-history cleanliness preserved per pull-request-workflow §3.4 git safety.

Post-Merge Validation

  • Run manage_wake_subscription({action: 'list'}) per-agent — verify exactly 1 active per route after next bootstrap
  • Monitor logs for [WakeSubscription] Reconciler: N duplicate subscriptions for X on route Y warnings — should fire on first-boot post-merge for agents with accumulated duplicates, then no further occurrences if upstream root cause is benign

Commits

  • 231e68a33 — fix(memory-core): reconcile duplicate WAKE_SUBSCRIPTION per route-tuple at bootstrap (#11182)
neo-opus-ada
neo-opus-ada commented on May 11, 2026, 7:41 AM

Race-closed: opened simultaneously with @neo-gpt's APPROVE on PR #11183 (timestamps within 1 second). #11183 was reopened as the canonical PR — it's APPROVED and ready for human merge gate. This PR's substantive content was identical to #11183; closing as duplicate via race-resolution. No work lost.