diff --git a/.changeset/trace-correlation.md b/.changeset/trace-correlation.md deleted file mode 100644 index 40522b4..0000000 --- a/.changeset/trace-correlation.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -"@smooai/audit": minor ---- - -Trace correlation: an emitted audit event now carries the W3C trace context of the -request that caused it, so a row in the audit store can be joined to a trace. - -**The ids ride in the ENVELOPE, never inside the event.** The wire body is now -`{"event":,"spanId":"…","traceId":"…"}`. The bytes under -`"event"` are exactly the bytes that were hashed — unchanged, byte-for-byte, with -or without a trace active — because `hashCurrent` covers canonical-JSON(event -minus `hashCurrent`) and any new event field would invalidate every stored chain -and every fixture in `spec/parity-corpus.json`. The corpus is untouched, and each -language asserts it inside an active span as well as outside one. Both ids are -OMITTED when there is no valid span: never `""`, never an all-zero id. - -TypeScript: `AuditClient.emit(event, trace?)` captures the active context at -emit time behind an optional `@opentelemetry/api` peer dependency. Without it -installed (or without a registered SDK) it is a no-op, not a crash. `buildEnvelope` -/ `currentTraceContext` are exported for consumers on their own transport. - -Rust: the same, behind a new optional `otel` cargo feature (off by default — -the crate does not link OpenTelemetry unless you ask for it). `AuditClient::emit` -uses the ambient span; `emit_with_trace` takes an explicit `TraceContext` that -wins per field. `TraceContext::current()` reads both context homes — a `tracing` -span via tracing-opentelemetry and an OTel-native one — because neither falls -back to the other. - -Go: `AuditClient.Emit(ctx, event)` reads the span context already on the `ctx` it -takes (`trace.SpanContextFromContext(ctx).IsValid()` before touching the ids), via -the OpenTelemetry trace API only — no SDK, no exporter. Pinned to otel v1.35.0, -the newest release whose `go` directive (1.22.0) still builds on the Go 1.22 the -CI matrix pins; v1.36+ declare go 1.23. - -Python: the ids come from the ambient span behind a guarded -`from opentelemetry import trace` import, exposed as the optional `otel` extra -(`pip install smooai-audit[otel]`). Without it installed, correlation is a no-op — -`opentelemetry-api` is never a hard dependency. - -.NET: reads `Activity.Current` — the BCL type the OpenTelemetry .NET SDK itself -populates — so no new package reference. Non-W3C or unstarted activities report -nothing. diff --git a/CHANGELOG.md b/CHANGELOG.md index 49dc3e6..40a6b3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,48 @@ # @smooai/audit +## 0.2.0 + +### Minor Changes + +- f05a9ab: Trace correlation: an emitted audit event now carries the W3C trace context of the + request that caused it, so a row in the audit store can be joined to a trace. + + **The ids ride in the ENVELOPE, never inside the event.** The wire body is now + `{"event":,"spanId":"…","traceId":"…"}`. The bytes under + `"event"` are exactly the bytes that were hashed — unchanged, byte-for-byte, with + or without a trace active — because `hashCurrent` covers canonical-JSON(event + minus `hashCurrent`) and any new event field would invalidate every stored chain + and every fixture in `spec/parity-corpus.json`. The corpus is untouched, and each + language asserts it inside an active span as well as outside one. Both ids are + OMITTED when there is no valid span: never `""`, never an all-zero id. + + TypeScript: `AuditClient.emit(event, trace?)` captures the active context at + emit time behind an optional `@opentelemetry/api` peer dependency. Without it + installed (or without a registered SDK) it is a no-op, not a crash. `buildEnvelope` + / `currentTraceContext` are exported for consumers on their own transport. + + Rust: the same, behind a new optional `otel` cargo feature (off by default — + the crate does not link OpenTelemetry unless you ask for it). `AuditClient::emit` + uses the ambient span; `emit_with_trace` takes an explicit `TraceContext` that + wins per field. `TraceContext::current()` reads both context homes — a `tracing` + span via tracing-opentelemetry and an OTel-native one — because neither falls + back to the other. + + Go: `AuditClient.Emit(ctx, event)` reads the span context already on the `ctx` it + takes (`trace.SpanContextFromContext(ctx).IsValid()` before touching the ids), via + the OpenTelemetry trace API only — no SDK, no exporter. Pinned to otel v1.35.0, + the newest release whose `go` directive (1.22.0) still builds on the Go 1.22 the + CI matrix pins; v1.36+ declare go 1.23. + + Python: the ids come from the ambient span behind a guarded + `from opentelemetry import trace` import, exposed as the optional `otel` extra + (`pip install smooai-audit[otel]`). Without it installed, correlation is a no-op — + `opentelemetry-api` is never a hard dependency. + + .NET: reads `Activity.Current` — the BCL type the OpenTelemetry .NET SDK itself + populates — so no new package reference. Non-W3C or unstarted activities report + nothing. + ## 0.1.1 ### Patch Changes diff --git a/package.json b/package.json index 903d2f1..5cb93fb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@smooai/audit", - "version": "0.1.1", + "version": "0.2.0", "description": "A polyglot client SDK for tamper-evident, SQL-queryable audit logging: a canonical event schema, a per-org-per-day SHA-256 hash chain, and an emit client — with byte-for-byte parity across TypeScript, Python, Rust, Go, and .NET.", "homepage": "https://github.com/SmooAI/audit#readme", "bugs": {