Skip to content

feat(otel): add go/internal/otel bootstrap package (RIG-2888) - #699

Merged
mattwilkinsonn merged 2 commits into
mainfrom
compass-obs/rig-2888-otel-bootstrap
Aug 28, 2026
Merged

feat(otel): add go/internal/otel bootstrap package (RIG-2888)#699
mattwilkinsonn merged 2 commits into
mainfrom
compass-obs/rig-2888-otel-bootstrap

Conversation

@rigel-mintaka

Copy link
Copy Markdown
Contributor

T1 of the frozen server+runner OTel design record (docs/designs/platform/compass-server-runner-otel/design.md, RIG-2685, #690). Establishes the single Go OTel convention for the Compass backend — there was no Go OTel instrumentation before this; the server and runner emission wiring (T2/T3) and the propagation leg (T5) all build on it.

New package go/internal/otel:

  • Config{ServiceName, ServiceVersion, Endpoint} + SetupTracerProvider/SetupMeterProvider(ctx, cfg) (shutdown, err) — off by default, endpoint-gated on OTEL_EXPORTER_OTLP_ENDPOINT: empty endpoint installs no global provider and returns a non-nil no-op shutdown (zero overhead, no network egress), mirroring the agent's src/transport/otel-layer.ts posture. Non-empty installs global providers whose resource carries service.name/service.version, OTLP-over-HTTP/protobuf exporters that read the endpoint env themselves (standard per-signal /v1/traces vs /v1/metrics suffixing), and the global W3C TraceContext propagator.
  • Traceparent(ctx) / ContextWithTraceparent(ctx, tp) — thin wrappers over the shared W3C propagator; empty/no-span yields "", malformed input returns the context unchanged.
  • NewTraceResponseInterceptor() — a connect unary interceptor that sets a traceresponse response header (00-<traceid>-<spanid>-<flags>) from the active span, the UI/PostHog trace-id correlation source; no-op when no active span.

OTel Go SDK deps added at v1.46.0 (above the ≥v1.23.0 floor the record sets for Span.AddLink, used later by T5).

FOD vendorHash lockstep

The new Go deps move the fetched Go module set, invalidating the pinned vendorHash the two buildGoModule FODs share (flake.nix and guest-image/default.nix, both documented to carry the same value since guestd's proxyVendor fetches the full module graph). Left stale, the compass-guest-image and flake-gate:flake-check builds fail hash mismatch in fixed-output derivation …-go-modules.drv. Per the repo's gomod↔FOD lockstep convention (the same refresh Renovate's refresh-fod-hashes.ts rides in-PR on a dep bump), both pins are refreshed here to the SRI the build reports, so a gomod change and its FOD refresh land in one commit and main never goes red between merges. Verified locally: moon run compass-guest-image:build flake-gate:flake-check both pass.

Built, tested (8/8), vetted, gofmt- and golangci-lint-clean.

Spec-impact: none. Refs RIG-2888, RIG-2685, RIG-2895.

Co-authored-by: Matt Wilkinson matt@rigel.build

@linear-code

linear-code Bot commented Aug 28, 2026

Copy link
Copy Markdown

RIG-2888

RIG-2685

RIG-2895

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown

Compass engineering docs preview: https://compass-obs-rig-2888-otel-bo.compass-eng-docs.pages.dev

Deployed from compass-obs/rig-2888-otel-bootstrap at 09dcb9f.

rigel-mintaka and others added 2 commits August 27, 2026 22:58
T1 of the frozen server+runner OTel design record (`docs/designs/platform/compass-server-runner-otel/design.md`, RIG-2685, #690). Establishes the single Go OTel convention for the Compass backend — there was no Go OTel instrumentation before this; the server and runner emission wiring (T2/T3) and the propagation leg (T5) all build on it.

New package `go/internal/otel`:

- `Config{ServiceName, ServiceVersion, Endpoint}` + `SetupTracerProvider`/`SetupMeterProvider(ctx, cfg) (shutdown, err)` — off by default, endpoint-gated on `OTEL_EXPORTER_OTLP_ENDPOINT`: empty endpoint installs no global provider and returns a non-nil no-op shutdown (zero overhead, no network egress), mirroring the agent's `src/transport/otel-layer.ts` posture. Non-empty installs global providers whose resource carries `service.name`/`service.version`, OTLP-over-HTTP/protobuf exporters that read the endpoint env themselves (standard per-signal `/v1/traces` vs `/v1/metrics` suffixing), and the global W3C `TraceContext` propagator.
- `Traceparent(ctx)` / `ContextWithTraceparent(ctx, tp)` — thin wrappers over the shared W3C propagator; empty/no-span yields `""`, malformed input returns the context unchanged.
- `NewTraceResponseInterceptor()` — a connect unary interceptor that sets a `traceresponse` response header (`00-<traceid>-<spanid>-<flags>`) from the active span, the UI/PostHog trace-id correlation source; no-op when no active span.

OTel Go SDK deps added at v1.46.0 (above the ≥v1.23.0 floor the record sets for `Span.AddLink`, used later by T5).

### FOD vendorHash lockstep

The new Go deps move the fetched Go module set, invalidating the pinned `vendorHash` the two `buildGoModule` FODs share (`flake.nix` and `guest-image/default.nix`, both documented to carry the same value since guestd's `proxyVendor` fetches the full module graph). Left stale, the `compass-guest-image` and `flake-gate:flake-check` builds fail `hash mismatch in fixed-output derivation …-go-modules.drv`. Per the repo's gomod↔FOD lockstep convention (the same refresh Renovate's `refresh-fod-hashes.ts` rides in-PR on a dep bump), both pins are refreshed here to the SRI the build reports, so a gomod change and its FOD refresh land in one commit and main never goes red between merges. Verified locally: `moon run compass-guest-image:build flake-gate:flake-check` both pass.

Built, tested (8/8), vetted, gofmt- and golangci-lint-clean.

Spec-impact: none. Refs RIG-2888, RIG-2685, RIG-2895.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
…erceptor tests (RIG-2888)

Review-fix commit atop the T1 bootstrap PR (#699). Addresses the low-severity findings from the review pass; the single medium (exporter-endpoint knob reconciliation) is a design decision routed separately and does not change T1 code.

- **provider.go:** wrap the three bootstrap errors (resource build, trace exporter, metric exporter) with `fmt.Errorf("otel: ...: %w", err)` so a fatal startup log names the failing stage (house Go idiom).
- **otel_test.go:** strengthen `TestSetupMeterProviderDisabled` with a sentinel assertion that no SDK MeterProvider is installed on the disabled path (mirrors the tracer test); add `TestSetupMeterProviderEnabled`; add `TestFormatTraceResponse` and `TestTraceResponseInterceptor` (valid-span sets header, no-span sets none, handler error passthrough) — the interceptor is a cross-task contract symbol and was previously uncovered in-package.

Refs RIG-2888.

Co-authored-by: Matt Wilkinson <matt@rigel.build>
@rigel-mintaka
rigel-mintaka force-pushed the compass-obs/rig-2888-otel-bootstrap branch from 905567b to 09dcb9f Compare August 28, 2026 03:01
@rigel-mintaka
rigel-mintaka marked this pull request as ready for review August 28, 2026 03:15
@mattwilkinsonn
mattwilkinsonn merged commit 108f174 into main Aug 28, 2026
23 of 25 checks passed
@mattwilkinsonn
mattwilkinsonn deleted the compass-obs/rig-2888-otel-bootstrap branch August 28, 2026 03:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants