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:
@@ -1,8 +1,13 @@
|
||||
# Test-only composition: session-telemetry-otel through the real Loader/app
|
||||
# path, exporting to the mock OTLP collector the driver starts (url via env).
|
||||
# The redact-rule entry models a deployment mounting its own scrub rule on the
|
||||
# telemetry/redact waterfall — the seam itself ships no rules.
|
||||
- id: cli-mock-llm
|
||||
name: './cli-mock-llm.ts'
|
||||
|
||||
- id: telemetry-redact-rule
|
||||
name: './telemetry-redact-rule.ts'
|
||||
|
||||
- id: bash
|
||||
name: '@deepseek-ai/dsh-bash-local'
|
||||
|
||||
|
||||
29
examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts
vendored
Normal file
29
examples/headless-agent/tests/fixtures/telemetry-redact-rule.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
import type { Context } from 'cordis'
|
||||
|
||||
/**
|
||||
* Deployment-style redaction rule for the telemetry e2e: scrubs the fixture
|
||||
* credential from body strings, exactly as a real deployment would mount its
|
||||
* own rules on the `telemetry/redact` waterfall.
|
||||
*/
|
||||
|
||||
const SECRET = /sk-e2efixture[0-9]+/g
|
||||
const PLACEHOLDER = '[E2E-REDACTED]'
|
||||
|
||||
function scrub(value: unknown): unknown {
|
||||
if (typeof value === 'string') return value.replace(SECRET, PLACEHOLDER)
|
||||
if (Array.isArray(value)) return value.map(scrub)
|
||||
if (value !== null && typeof value === 'object') {
|
||||
return Object.fromEntries(Object.entries(value).map(([key, entry]) => [key, scrub(entry)]))
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
export const name = 'telemetry-redact-rule'
|
||||
|
||||
/** Mount the fixture scrub rule onto the redact waterfall. */
|
||||
export function apply(ctx: Context): void {
|
||||
ctx.on('telemetry/redact', (_record, next) => {
|
||||
const record = next()
|
||||
return { ...record, body: scrub(record.body) }
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user