Skip to content

release-train: develop -> staging - #506

Merged
tracebloc-release-train[bot] merged 1 commit into
stagingfrom
release-train/to-staging
Aug 14, 2026
Merged

release-train: develop -> staging#506
tracebloc-release-train[bot] merged 1 commit into
stagingfrom
release-train/to-staging

Conversation

@LukasWodka

@LukasWodka LukasWodka commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Automated promotion by the release train (RFC-0008 D14). Head is the train-managed release-train/to-staging branch (a mirror of develop), so it never collides with a human PR. Merged only when the fr-gate is green.


Note

Low Risk
New library-only package with no production wiring in the diff; validation errors return to callers without changing CLI behavior until integrated.

Overview
Introduces internal/telemetry, the Go side of the backend telemetry contract (RFC-BACKEND-1872), so the CLI can emit validated outcome events instead of relying on pod log collection.

An Emitter is built with fixed resource identity (service.name / tracebloc.component = cli), version normalization (dev/empty → 0.0.0-unknown), and Exports() aligned with api.IsKnownEnv—unknown envs never get deployment.environment and do not export. Emit enforces event naming (cli/auth domains, closed outcomes), attribute keys (OTel allowlist, tracebloc.*, retired names), primitive values, omission of nil/empty strings, and failure records (error.type, full exception set when any exception field is present). Delivery is via an injectable SetSink; nil sink still runs validation.

telemetry_test.go locks identity, env/version behavior, grammar, attributes, failure rules, and sink/resource layering.

Reviewed by Cursor Bugbot for commit 209e4b5. Bugbot is set up for automated code reviews on this repo. Configure here.

…ckend#1897) (#503)

RFC-BACKEND-1872 D2 for the CLI, and D12's host-process path. The Go half of
what backend#1896 does for the Python services. Unblocks #1907.

The CLI emits nothing today — it is not a pod, so the edge Collector's filelog
receiver cannot reach it, and a field failure is only ever a support thread.

    e := telemetry.New(cfg.CurrentEnv, version, hostname)
    err := e.Emit("cli.command.failed", telemetry.Attrs{"error.type": "network"})

ENFORCED, NOT DOCUMENTED. The contract's mechanically-checkable rules run at the
call site and return an error: the <domain>.<object>.<outcome> grammar with its
closed vocabularies, the attribute-key namespace, retired names, value types,
and the error set a failure must carry — stacktrace included. It returns rather
than panics, because a CLI must never die of telemetry; but a malformed event
must not pass silently either, and the caller's tests are where it fails.

THE ENVIRONMENT IS DERIVED, NOT RESTATED. `New` classifies via
`api.IsKnownEnv`, the same function that rejects a `--env staging` typo at the
CLI's front door, and a test asserts the two agree across dev/stg/prod/staging/
prd/PROD/"". One saying yes while the other says no is precisely how records
acquire a guessed environment.

The domain vocabulary is narrower than the full registry — `cli` and `auth`
only. The CLI is not the installer and not the backend, so admitting domains it
cannot legitimately produce would make a typo look plausible. That is the
failure already visible in the browser leg, where 461 of 484 events are named
`not_specified`.

25 tests, 100% statement coverage, `make check` green. Twelve rules
mutation-proved.

ONE SURVIVED THE FIRST PASS, and it was a weak test rather than weak code —
the same one the Python side hit. Every key I had tried was caught by the
retired or namespace rule, so nothing exercised the key-SHAPE check; it needed a
key that passes every other rule and is still badly shaped
(`tracebloc.clientID`). Added, and the mutation now bites.

NOTHING IMPORTS THIS YET, deliberately: #1907 is the consumer ticket. One
consequence worth recording rather than discovering — `make deadcode` scans
reachability from ./cmd/tracebloc, so a package outside that import graph is
invisible to it. The gate is SILENT on this package, not passing it, and will
start covering it the moment #1907 wires the first call site.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@LukasWodka

Copy link
Copy Markdown
Contributor Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 209e4b5. Configure here.

@tracebloc-release-train tracebloc-release-train Bot added gate-nudge Toggled by the release train to (re-)fire the fr-gate and removed gate-nudge Toggled by the release train to (re-)fire the fr-gate labels Aug 14, 2026
@tracebloc-release-train
tracebloc-release-train Bot merged commit e2bf9f6 into staging Aug 14, 2026
45 checks passed
@tracebloc-release-train
tracebloc-release-train Bot deleted the release-train/to-staging branch August 14, 2026 15:22
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.

1 participant