refactor(telemetry): ship the redact waterfall without built-in rules
The seam keeps the telemetry/redact scrubbing interface but ships no rules of its own: the innermost next() passes records through unchanged, and deployments mount their rules as waterfall listeners. As an SDK we cannot know which patterns are secrets in a given deployment; a shipped list invites false confidence while catching only known shapes, and false positives would corrupt exported bodies. Mechanism stays with the seam, policy moves to the deployment; both READMEs and the Agent Note state the raw-export default plainly. The loader-composition e2e now mounts a deployment-style rule fixture and pins the same wire behavior: secret absent, placeholder present, canonical log untouched.
This commit is contained in:
@@ -2,10 +2,11 @@
|
||||
* Capture coordinator: the seam's upstream half. Subscribes to the session
|
||||
* firehose plus the one live-bus relay (`agent/error`), applies the fixed
|
||||
* chunk projection, builds logical records, runs each through the
|
||||
* `telemetry/redact` waterfall, and hands the redacted copy to the backend —
|
||||
* synchronously, with every handler self-contained so a failing backend can
|
||||
* never starve other subscribers (cordis `emit` is stop-on-throw) or touch
|
||||
* the agent loop. Composed by a backend in its constructor.
|
||||
* `telemetry/redact` waterfall (deployment-mounted rules; pass-through when
|
||||
* none), and hands the result to the backend — synchronously, with every
|
||||
* handler self-contained so a failing backend can never starve other
|
||||
* subscribers (cordis `emit` is stop-on-throw) or touch the agent loop.
|
||||
* Composed by a backend in its constructor.
|
||||
*
|
||||
* @module @deepseek-ai/dsh-session-telemetry/coordinator
|
||||
*/
|
||||
@@ -14,7 +15,6 @@ import type { Context } from 'cordis'
|
||||
import type { Session, SessionEvent } from '@deepseek-ai/dsh-session'
|
||||
import type { Agent } from '@deepseek-ai/dsh-agent'
|
||||
import type { TelemetryBackend, TelemetryRecord, TelemetrySeverity } from './index.ts'
|
||||
import { applyDefaultRedaction } from './redact.ts'
|
||||
|
||||
/**
|
||||
* The handoff cursor: per session, the highest `seq` handed to a backend.
|
||||
@@ -145,13 +145,13 @@ export class TelemetryCoordinator {
|
||||
|
||||
/**
|
||||
* Run the `telemetry/redact` waterfall over one record and hand the result
|
||||
* to the backend. The innermost `next` applies the seam's conservative
|
||||
* default rules, so an unconfigured deployment still never exports raw
|
||||
* credential shapes; callers run inside {@link contain}, so a throwing
|
||||
* to the backend. The innermost `next` passes the record through unchanged
|
||||
* — the seam ships no rules; exported data is as clean as the listeners a
|
||||
* deployment mounts. Callers run inside {@link contain}, so a throwing
|
||||
* rule withholds the record instead of reaching the loop (fail-closed).
|
||||
*/
|
||||
private handOff(record: TelemetryRecord): void {
|
||||
this.backend.emit(this.ctx.waterfall('telemetry/redact', record, () => applyDefaultRedaction(record)))
|
||||
this.backend.emit(this.ctx.waterfall('telemetry/redact', record, () => record))
|
||||
}
|
||||
|
||||
/** Forward the turn-end boundary to the backend's optional flush hint. */
|
||||
|
||||
Reference in New Issue
Block a user