ADR-0080: Observed Memory and Pathway Metrics Telemetry Architecture¶
| Field | Value |
|---|---|
| Status | Accepted (Implemented) |
| Date | 2026-08-28 |
| Authors | Spector Maintainers & Architecture Working Group |
| Deciders | Spector Technical Steering Committee (TSC) |
| Supersedes | None |
| Superseded By | None |
| Last Verified | 2026-09-16 (Verified against main) |
1. Context¶
Spector's cognitive architecture executes multi-stage, high-concurrency workflows across off-heap Panama FFM storage, vector similarity kernels, and external multimodal LLM/embedding endpoints:
- Multi-Stage Cognitive Pathways:
RememberRecipe,RecallRecipe, andReflectRecipechain up to 22 sequential and parallel relays (biological encoding, episodic consolidation, active inference retrieval, sleep synthesis). - Asynchronous Background Processing: Model B
SpectorTaskQueuemanages background consolidation, engram decay, and reflection sweeps on virtual threads. - External Model Inference: Remote LLM and embedding providers introduce variable network latencies, rate limits, and transient failures.
Operating this cognitive engine in production requires end-to-end observability. Operators and AI system architects must be able to inspect real-time throughput, pinpoint latency regressions to specific pathway relays, monitor circuit breaker and bulkhead states, and trace cross-service operations via distributed tracing spans.
2. Problem Statement¶
Instrumenting a cognitive memory engine introduces three major architectural challenges:
- Instrumentation Proliferation & Core Pollution: Injecting telemetry calls directly into domain kernels and math algorithms creates invasive boilerplate, couples engine logic to monitoring vendors, and increases cognitive debt.
- Metrics vs. Tracing Divergence: Maintaining separate metrics collectors (e.g., Prometheus counters) and distributed tracing instrumentations (e.g., OpenTelemetry spans) causes tag drift, duplicate latency measurements, and code duplication.
- Zero Overhead Hot-Path Requirement: Observability hooks must execute with negligible overhead when enabled and zero allocation cost when disabled, without stalling off-heap SIMD vector pipelines.
3. Decision Drivers¶
- Decorator & Interceptor Decoupling: Core interfaces (
SpectorMemory,SynapticRelay,SpectorTaskQueue) must remain pure; observability must be layered externally via decorators, interceptors, and hooks. - Unified Metrics & Tracing: A single instrumentation event must simultaneously produce Prometheus/Micrometer dimensional metrics and OpenTelemetry/W3C distributed trace spans.
- Granular Pathway & Relay Diagnostics: Telemetry must record latency, status, degradation, circuit tripping, timeouts, and retries per individual pathway relay.
- Standardized Observation Conventions: Metric names, tags, and span attributes must follow strict naming conventions adhering to Micrometer Observation standards.
4. Considered Options¶
Option 1: Ad-Hoc Logging and Atomic Counters¶
- Description: Add SLF4J debug logs and
AtomicLongcounters directly within pathway classes. - Advantages: Simple to write initially, no additional library dependencies.
- Disadvantages: Unstructured, difficult to scrape, lacks histogram percentiles, and provides no distributed tracing correlation across services.
Option 2: Direct OpenTelemetry SDK and Prometheus Client Binding¶
- Description: Hard-code OpenTelemetry tracer and Prometheus meter calls throughout all memory classes.
- Advantages: Direct access to vendor-specific APIs.
- Disadvantages: Pollutes core cognitive packages with third-party SDK dependencies, creates divergent metric tag schemas, and duplicates instrumentation across metrics and spans.
Option 3: Micrometer Observation API Decorators and MeterBinders (Selected)¶
- Description: Implement an isolated observability module (
memory/spector-metrics) utilizing the Micrometer Observation API. WrapSpectorMemoryinObservedSpectorMemory, intercept pathway relays viaPathwayMetrics, and bind task queues viaTaskQueueMetricsBinder. - Advantages: Complete architectural decoupling, single-call duality (one observation produces both metrics and OpenTelemetry trace spans), zero dependencies added to core kernel, and full compatibility with Prometheus, Grafana, OpenTelemetry Collector, and Datadog.
5. Decision Outcome¶
Spector standardizes on the Micrometer Observation and Telemetry Architecture in memory/spector-metrics/src/main/java/com/spectrayan/spector/metrics/.
5.1 Architecture Overview¶
flowchart TD
subgraph ClientLayer ["Client / Application Layer"]
App["Application / Agent"]
end
subgraph MetricsModule ["memory/spector-metrics"]
ObsMem["ObservedSpectorMemory<br/><i>(Decorator)</i>"]
ObsCtx["MemoryObservationContext"]
ObsConv["SpectorObservationConvention"]
subgraph PathwayHooks ["Pathway Telemetry"]
PM["PathwayMetrics<br/>(MeterBinder & PathwayObservationHook)"]
Interceptor["PathwayRelayMetricsInterceptor"]
end
subgraph QueueHooks ["Task Queue Telemetry"]
TQMB["TaskQueueMetricsBinder<br/>(MeterBinder)"]
end
end
subgraph CoreEngine ["Cognitive Core & Commons"]
Mem["SpectorMemory (Delegate)"]
Relays["SynapticRelays (1..N)"]
Queue["SpectorTaskQueue"]
end
subgraph ObservabilitySinks ["Observability Infrastructure"]
MRegistry["Micrometer MeterRegistry<br/>(Prometheus / Grafana)"]
OTel["OpenTelemetry Tracer<br/>(W3C Spans / Jaeger)"]
end
App -->|"remember / recall / reflect"| ObsMem
ObsMem -->|"create observation"| ObsCtx
ObsCtx --> ObsConv
ObsMem -->|"delegate"| Mem
Relays -->|"notify hooks"| PM
Queue -->|"poll gauges"| TQMB
ObsMem -->|"export metrics"| MRegistry
ObsMem -->|"export spans"| OTel
PM -->|"export meters"| MRegistry
TQMB -->|"export gauges"| MRegistry 5.2 Core Telemetry Components¶
-
ObservedSpectorMemory(Decorator):- Implements
SpectorMemory, wrapping the underlying memory instance. - Encloses every cognitive operation (
remember,recall,reflect,forget,reinforce,sync) inside a MicrometerObservation. - Uses
DefaultSpectorObservationConventionto attach standardized contextual tags:operation,tier,status,user, andtenant. - Emits both timing histograms to the
MeterRegistryand distributed trace spans with parent-child hierarchy to the OpenTelemetry bridge.
- Implements
-
PathwayMetrics(Relay Telemetry):- Implements
MeterBinderandPathwayObservationHook. - Exports 8 standardized cognitive meters:
spector.pathway.conduct(Timer) — Total latency per pathway execution (tags:pathway,finish).spector.pathway.relay(Timer) — Execution latency per individual synaptic relay (tags:pathway,relay,status).spector.pathway.degraded(Counter) — Count of graceful degradation events (tags:pathway,relay,kind).spector.pathway.circuit(Counter) — Circuit breaker state changes (tags:breaker,event=trip|probe|close|reject).spector.pathway.bulkhead.reject(Counter) — Bulkhead concurrency rejections (tags:bulkhead).spector.pathway.timeout(Counter) — Relay timeouts (tags:pathway,relay).spector.pathway.retry(Counter) — Transient fault retries (tags:pathway,relay).spector.pathway.nested(Timer) — Latency of nested child pathways (tags:from,to).
- Implements
-
TaskQueueMetricsBinder(Concurrency Telemetry):- Implements
MeterBinder, observing an activeSpectorTaskQueue<?>. - Exports real-time queue health gauges and counters:
spector.taskqueue.size: Current backlog depth.spector.taskqueue.capacity: Configured maximum queue capacity.spector.taskqueue.parallelism: Active virtual worker thread count.spector.taskqueue.submitted: Monotonic counter of submitted tasks.spector.taskqueue.processed: Monotonic counter of completed tasks.spector.taskqueue.failed: Monotonic counter of rejected/failed tasks.spector.taskqueue.retried: Retry attempts.spector.taskqueue.latency.avg.ms: Rolling average task execution duration.spector.taskqueue.running: Operational status gauge (1 = running, 0 = closed).
- Implements
-
ObservableRelay&PathwayRelayMetricsInterceptor:- Functional interceptor (
Function<SynapticRelay<S>, SynapticRelay<S>>) decorating relays transparently without modifying their algorithmic code.
- Functional interceptor (
5.3 Distributed Tracing & Span Hierarchy¶
sequenceDiagram
autonumber
participant App as AI Agent Application
participant Obs as ObservedSpectorMemory
participant Hook as PathwayObservationHook
participant LLM as ObservedLlmProvider
participant OTel as OpenTelemetry Trace Sink
App->>Obs: recall(query, options)
activate Obs
Note over Obs,OTel: Root Span: spector.memory.recall [trace_id=t1, span_id=s1]
Obs->>Hook: onConduct("RecallPathway", "START")
activate Hook
Note over Hook,OTel: Child Span: spector.pathway.relay [span_id=s2, parent_id=s1, relay=ActiveInferenceRelay]
Hook->>LLM: generateHypotheses(query)
activate LLM
Note over LLM,OTel: Child Span: spector.provider.llm [span_id=s3, parent_id=s2]
LLM-->>Hook: hypotheses
deactivate LLM
Hook-->>Obs: candidate results
deactivate Hook
Obs-->>App: CognitiveResult
deactivate Obs 6. Pros and Cons of the Options¶
| Option | Pros | Cons |
|---|---|---|
| Option 1: Ad-Hoc Logs & Atomic Counters | Quick to write, zero external libraries | No distributed tracing, high log noise, lacks percentile histograms |
| Option 2: Direct OTel SDK & Prometheus APIs | Direct access to native client features | Violates separation of concerns, pollutes engine code with vendor imports |
| Option 3: Micrometer Observation API Decorators | 100% decoupled decorator pattern, unified metrics + traces, zero engine pollution | Adds spector-metrics module layer; requires binding hooks during startup |
7. Implementation Plan¶
- Phase 1: Architecture & Contracts: Create
memory/spector-metricsand define observation conventions, documentation enums, and observation contexts. - Phase 2: Core Decorator: Implement
ObservedSpectorMemorydecorating all primary cognitive operations with Micrometer Observation scopes. - Phase 3: Pathway Interceptors: Implement
PathwayMetricsandPathwayRelayMetricsInterceptoradhering toPathwayObservationHook. - Phase 4: Concurrency & System Binders: Implement
TaskQueueMetricsBinderandSpectorJvmMetricsfor runtime monitoring. - Phase 5: Provider Observation: Implement
ObservedLlmProviderandObservedEmbeddingProviderfor upstream API latency tracking.
8. Code Reference & Verification¶
- Primary Module:
memory/spector-metrics - Key Packages:
com.spectrayan.spector.metricscom.spectrayan.spector.metrics.observation
- Key Classes:
ObservedSpectorMemory.javaPathwayMetrics.javaTaskQueueMetricsBinder.javaSpectorJvmMetrics.javaDefaultSpectorObservationConvention.javaMemoryObservationContext.javaPathwayRelayMetricsInterceptor.javaObservableRelay.java
- Verification Test Suites:
ObservedSpectorMemoryTest.javaPathwayMetricsTest.javaTaskQueueMetricsBinderTest.javaSpectorMetricsTest.javaObservableRelayTest.java