Commit Graph

5 Commits

Author SHA1 Message Date
kingwl
bf76c52d76 fix(telemetry): reject non-positive maxExportBatchSize at plugin load
Review finding, pinned red-first: the SDK accepts
processor.maxExportBatchSize <= 0 (or fractional), but its shutdown
drain then splices empty batches without consuming the queue —
disposing telemetry hangs forever whenever records are queued. The
constructor now rejects a non-positive-integer batch size before
building the SDK processor, per the misconfiguration-fails-loud rule;
everything else in the processor block remains the SDK's verbatim
passthrough.
2026-07-27 20:11:30 +08:00
kingwl
95315386b3 refactor(telemetry): remove the OTel backend's flush forwarding
Three review rounds each found a new silent-loss path in the same
wrapper state (dispose racing an in-flight flush, overlapping hints
displacing the retained promise, the provider's fixed 30s flush timeout
rejecting while the processor still drains). Every path exists only
because forwarding the seam's turn-boundary hint to forceFlush() made
this backend the process's second flusher against undocumented SDK
internals from the upstream experimental tree.

The backend now implements no flush(): the batch processor is the only
flusher, its scheduledDelayMillis (already deployment-tunable through
the processor passthrough) governs export cadence, and shutdown()'s
drain is complete by construction. The two race-pin tests collapse into
one dispose-during-in-flight-batch drain pin; the seam's optional
flush() contract now tells implementers they own the concurrent-flush/
shutdown interaction. Removal rationale and the reinstatement trigger
(a stated turn-boundary latency requirement scheduledDelayMillis cannot
meet — and then via the processor's own forceFlush(), never the
provider's timeout-wrapped one) are recorded in the revival Agent Note,
both languages.
2026-07-26 17:55:54 +08:00
kingwl
d398eda432 fix(telemetry): join overlapping flush hints; contain adoption replay per event
Second review round, both pinned red-first:

- Overlapping turn-boundary flush hints now JOIN the outstanding flush
  promise (Promise.all) instead of displacing it: the SDK's
  concurrent-flush guard resolves an overlapping forceFlush()
  immediately, so retaining only the latest promise let shutdown()
  proceed while the first export was still in flight — the same silent
  drop the single-flush fix closed.
- Adoption replay contains failures per event, matching the firehose:
  one rejected record is withheld fail-closed while the rest of the
  historical log still hands off. Wrapping the whole loop let a single
  failure silently skip the remainder on an already-adopted session.
2026-07-25 03:48:32 +08:00
kingwl
e6a8ff2621 fix(telemetry): review fixes — flush/shutdown ordering, session retirement, whole-exporter passthrough
Three review findings, each pinned by a red test first:

- The OTel backend retains the latest turn-boundary flush promise and
  shutdown() awaits it before provider.shutdown(): the SDK's
  concurrent-flush guard makes the shutdown-internal flush return early
  while one is in flight, silently dropping everything enqueued after
  the flush snapshot (including the coordinator's dispose-time shutdown
  markers).
- The coordinator retires sessions from the adopted set on
  session/disposed (mirroring the persistence coordinator): a long-lived
  backend no longer retains closed sessions and their event logs, and
  final unload no longer stamps shutdown markers for dead sessions.
- The exporter config passes through whole to OTLPLogExporter and its
  type/JSDoc now advertise the full OTLPExporterNodeConfigBase shape:
  rebuilding url/headers only silently dropped documented SDK options
  (timeoutMillis, compression, keepAlive, ...).
2026-07-25 03:20:29 +08:00
kingwl
cf2e184112 feat(telemetry): session-telemetry seam with mandatory redaction + OTel backend
Revive the reviewed session-telemetry packages from the closed
session-telemetry-otlp-rfc branch (PR #222/#231) on current master, renamed
to @deepseek-ai/dsh-session-telemetry{,-otel} (the SDK component-telemetry
package holds the dsh-telemetry name).

Delta over the branch version: every record now passes a telemetry/redact
waterfall between projection and emit() — the innermost next() applies a
non-configurable conservative credential-shape rule set, listeners stack
stricter rules, a throwing rule withholds the record fail-closed, and the
canonical log is never rewritten. This answers the export-side concern that
closed PR #222; the boundary axiom (our aspect ends at emit(); delivery is
the reporting SDK's) is unchanged, and the runtime-telemetry RFC's outbox /
readCommitted lane is recorded as deferred in the Agent Note.

Covered by seam/redact/OTel-wire unit tiers (100% per-file) and a keyless
Loader-composition e2e that boots the examples fixture against a mock OTLP
collector and pins redaction on the wire plus the untouched canonical log.
2026-07-25 01:55:09 +08:00