LearnNewsExamplesServices
Frontmatter
id13524
titleWire add_memory recency into who_is_online projection
stateClosed
labels
enhancementaiarchitecturemodel-experience
assigneesneo-opus-ada
createdAtJun 19, 2026, 8:34 AM
updatedAtJun 19, 2026, 2:49 PM
githubUrlhttps://github.com/neomjs/neo/issues/13524
authorneo-gpt
commentsCount2
parentIssue13498
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[x] 13515 who_is_online liveness projection — Substrate B of #13498, [x] 13499 Add turn-presence writer substrate
blocking[]
closedAtJun 19, 2026, 2:49 PM

Wire add_memory recency into who_is_online projection

Closed v13.1.0/archive-v13-1-0-chunk-4 enhancementaiarchitecturemodel-experience
neo-gpt
neo-gpt commented on Jun 19, 2026, 8:34 AM

Context

This ticket was originally filed as the A-to-B integration leaf for the turn-presence beacon. That premise changed after V-B-A against the deployment model: who_is_online must use add_memory recency as its primary activity signal, not a harness-local beacon.

The reason is portability. add_memory is the universal authenticated activity write every agent produces at turn boundaries. A turn-presence beacon is useful local telemetry, but it is emitted by a specific harness path and is coupled to local process / clone topology. who_is_online is a Memory Core tool and must work in stdio swarm mode and multi-tenant server deployments without relying on repo-local or PID-local presence.

This body supersedes the original beacon-primary Contract Ledger for #13524.

Release classification: boardless agent-runtime hardening; candidate for the Agent Harness board only if the operator wants #13498 fully board-tracked.

The Problem

who_is_online should answer a simple operational question: which participating maintainers have produced caller-visible activity recently?

The beacon-first shape answered a narrower local-harness question. It could mark the local swarm correctly, but it would be inert or misleading in deployments where agents interact through different clients, workspaces, or server topologies. It also risked bypassing the same tenant visibility semantics that govern memory reads.

The Architectural Reality

  • add_memory writes durable AGENT_MEMORY graph nodes with timestamps and tenant visibility metadata.
  • Memory graph reads already have an RLS predicate for caller-visible data: caller user, public/null user, shared entity, or team visibility.
  • who_is_online lives in WakeSubscriptionService and is exposed through the Memory Core MCP surface.
  • participationStatus remains the hard operator gate: benched or unreachable identities must report offline even when recent activity exists.
  • The merged turn-presence writer remains useful telemetry, but it is no longer the primary who_is_online input.

The Fix

Project maintainer liveness from caller-visible add_memory recency:

  • Keep participationStatus as the first hard gate.
  • Read the latest visible AGENT_MEMORY.timestamp for each maintainer identity.
  • Treat fresh activity within the configured window as online.
  • Treat stale or absent activity as offline / dark.
  • Expose the signal as signals.activityRecency and signalStatus, not signals.beacon.
  • Keep the tool advisory. It must not hard-gate review routing.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
who_is_online MCP response Memory Core tool contract + this corrected ticket body Report signalStatus and signals.activityRecency from caller-visible AGENT_MEMORY recency No visible memory activity returns dark/offline, not process-present OpenAPI tool schema / service JSDoc Focused WakeSubscriptionService unit + dispatch tests
WakeSubscriptionService.whoIsOnline() projection WakeSubscriptionService + Memory Core graph visibility rules participationStatus hard gate, then add_memory-recency liveness Benched/unreachable stays offline even with fresh activity service method JSDoc focused unit tests
Tenant visibility GraphService.searchNodes RLS predicate shape Read through tenant isolation, not around it stdio swarm memories with null user remain cross-visible; server-mode user-scoped memories stay tenant-scoped inline reader structure unit coverage with visible and non-visible activity rows
Turn-presence beacon #13499 / #13500 Remains untouched telemetry, no longer feeds who_is_online primary status Future consumers may use it separately existing writer docs out of scope

Decision Record impact

aligned-with Discussion #13495 and parent #13498 after operator-directed correction. No ADR amendment. This ticket body supersedes its original beacon-primary prescription.

Acceptance Criteria

  • who_is_online reads recent caller-visible AGENT_MEMORY activity for each maintainer identity.
  • Fresh visible activity after the participationStatus gate reports the maintainer online.
  • Stale or absent activity reports offline / dark.
  • Benched/unreachable participationStatus remains offline regardless of fresh activity.
  • The response uses signalStatus and signals.activityRecency; stale beaconStatus / signals.beacon response fields are removed from this projection.
  • The read respects tenant visibility; server-mode user-scoped memories do not leak cross-tenant activity.
  • Unit coverage includes fresh activity online, stale activity offline, no activity dark, participationStatus gate, visibility scoping, family filter, and MCP callTool('who_is_online') dispatch.

Out of Scope

  • Writing the turn-presence beacon itself (#13499 / PR #13500).
  • Removing the turn-presence writer.
  • Hard-gating review routing on who_is_online; advisory first remains the rule.
  • Closing #13498 unless epic-resolution confirms the parent ACs after all required leaves are merged.

Avoided Traps

  • Process presence as liveness: rejected. Process presence is not proof of maintainer activity.
  • Harness-local beacon as primary: rejected. It is too coupled to one harness topology.
  • Tenant-blind recency: rejected. The recency read must use the same visibility model as Memory Core graph reads.
  • Chroma/vector dependency: rejected. The recency signal is graph-backed so it survives embed-drain lag.

Related

Parent: #13498

Supersedes beacon-primary PR shape: #13517 / #13515

Turn-presence writer remains adjacent: #13499 / #13500

Origin Session ID

378b8b47-8025-47e0-9de1-15274874480f

Handoff Retrieval Hints

query_raw_memories("who_is_online add_memory recency tenant scoped RLS memory core #13524")

query_raw_memories("who_is_online beacon superseded add_memory recency operator pivot")