v1.6.1
Observability Hardening
A patch release closing every actionable finding from the post-1.6.0 adversarial review: two security fixes in the observation pipeline, plus small additive controls for draining, budgeting and tracing. No public type changes beyond append-only additions.
Security fixes
- Redaction final barrier. The built-in observation redaction profile now also runs after your custom
redacthook and after structural truncation — a buggy or malicious redactor can no longer reintroduce a secret into an event, and truncation can never split a secret into a decodable prefix. The JWT pattern additionally catches tokens embedded mid-string. (maskSecretand every 1.5 log/error path are untouched — the P0 pin holds.) - Composite observers: per-sink capture projection.
composeObserverschildren now each receive only what their owncaptureoptions allow: disallowedcaptured*fields are stripped,error.messageis gated per child oncapture.errorMessages, and a childredacthook applies only to that child's view.
Important
Behavior change (security-motivated): a composed observer with no options no longer receives captured content from its siblings' opt-ins — it now matches a standalone observer's privacy defaults. If a sink should see prompts/tool payloads, give it its own capture options.
Additive
-
result.observation?.settledongenerateText/streamChat/embed/embedMany— await it beforeobserver.close()so asynccost.calculatedenrichments (an asyncpriceProvider) aren't dropped. Nothing about the run itself ever waits on it (G2 holds).const res = await generateText({ model, messages, deps: { observer } }); await res.observation?.settled; await observer.close(); // JSONL now contains cost.calculated
-
createMemoryObserver({ maxBytes })— a total byte budget alongsidemaxEvents, evicting by the existingoverflowstrategy (drop-oldestdefault) and counting intodroppedCount. -
deps.tracerMode: 'legacy'— opt back into the 1.5 flat span topology (one parent-lessinvokeper model call,deuz.step.count: 1, retries on that call's own span) for dashboards built against it. The default remains'hierarchical'.
Notes
eventIdis now derived as`${executionId}:${sequence}`— one fewer id draw per event; the format was never part of the contract.- Release workflow:
actions/*@v5, an idempotent GitHub-release step, and dual-auth publish —NPM_TOKENif present, otherwise npm trusted publishing (OIDC);--provenanceon both paths (npm pinned to the 11 line — npm 12 changedpack --jsonoutput).
Quality: 575 tests / 63 files (17 new: malicious-redactor + truncation-boundary secret matrix, per-sink projection splits, settled→close JSONL drains, legacy-tracer span shape), full 10-stage npm run check + docs build green. Bundle budgets not raised (core 99 547 / 100 000 raw bytes).
Docs: Observability guide · Event catalog · CHANGELOG
Full Changelog: v1.6.0...v1.6.1