refactor(telemetry): replay feedback sessions without buffering

This commit is contained in:
Turtle
2026-08-06 14:57:30 +08:00
parent 9d9b547d55
commit 4e8067e8d5
24 changed files with 270 additions and 200 deletions

View File

@@ -4,9 +4,9 @@
* The seam owns the CAPTURE side of session-event reporting — which records
* exist (the chunk projection), what they carry (the logical record), when
* they are captured (adoption, the per-append firehose, lifecycle
* forwarding), immediate versus explicitly released handoff, and the HMR
* forwarding), live versus on-demand canonical-log capture, and the HMR
* cursor. Everything downstream of
* {@link Telemetry.emit} — batching, retry, queueing, loss policy — is the
* {@link Telemetry.emit} — batching, retry, queueing, and loss policy — is the
* reporting SDK's territory and is deliberately not modelled here. The
* design and its trade-offs are pinned in
* .agents/notes/implemented/feature/2026-07-23-session-telemetry-otel-revival.md.
@@ -33,8 +33,9 @@ declare module 'cordis' {
* `next()` replaces everything beneath. Dispatched synchronously on the
* capture hot path inside the coordinator's containment: a throwing
* listener withholds that one record (fail-closed) and never reaches the
* agent loop. Redaction applies to the exported copy only; the canonical
* session log is never rewritten.
* agent loop. Live capture dispatches at append time; on-demand capture
* dispatches while reading the canonical log. Redaction applies to the
* exported copy only; the canonical session log is never rewritten.
* @param record - the candidate record, already the coordinator's own deep
* copy; listeners return a (possibly new) record and must not mutate it.
* @mode waterfall
@@ -95,8 +96,8 @@ export interface TelemetryBackend {
/**
* Hand one record to the backend's pipeline. MUST be a non-blocking
* enqueue — the coordinator calls this synchronously from the
* `session/event` hot path, either at capture or while releasing a held
* prefix, so anything slower than a queue push would tax the agent loop.
* `session/event` hot path or an explicit canonical-log capture, so anything
* slower than a queue push would tax the agent loop or feedback handling.
* Errors thrown here are contained by the coordinator and logged; they
* never reach the loop.
* @param record - the logical record to report; owned by the backend after the call.
@@ -123,9 +124,8 @@ export interface TelemetryBackend {
* coordinator emits its dispose-time `shutdown` markers immediately before
* calling this). Awaited by the coordinator's dispose; a rejection is
* logged as a warning and never fails application teardown.
* The coordinator captures dispose-time shutdown markers immediately
* before this call; immediate delivery enqueues them, while held delivery
* leaves an unreleased suffix local.
* The coordinator captures dispose-time shutdown markers immediately before
* this call for live capture; on-demand capture creates no ops records.
* @returns resolves when the backend's pipeline has quiesced.
*/
shutdown(): Promise<void>
@@ -158,4 +158,4 @@ export abstract class Telemetry extends Service implements TelemetryBackend {
abstract shutdown(): Promise<void>
}
export { TelemetryCoordinator, type TelemetryDelivery } from './coordinator.ts'
export { TelemetryCoordinator, type TelemetryCapture } from './coordinator.ts'