Skip to content

feat(module)!: remove telemetry service and use the operations intake - #1027

Merged
antoinetoussaint-byte merged 26 commits into
codefly-dev:mainfrom
crisfiorini-oss:feat/telemetry-service-removal
Oct 23, 2026
Merged

antoinetoussaint-byte merged 26 commits into
codefly-dev:mainfrom
crisfiorini-oss:feat/telemetry-service-removal

Conversation

@crisfiorini-oss

@crisfiorini-oss crisfiorini-oss commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

Refs #1022.

The module removes its in-graph telemetry collector. Accounts and auth-gateway use released SDK v0.4.1 for conditional tracing and bounded shutdown, and push metrics directly to the HTTPS operations intake. No endpoint means no export, including local runs. Exporter configuration failures are logged without stopping the service; the Prometheus exporter and /metrics route are removed. The immutable module package moves to 0.2.0.

Classification: fix at the owner. The SDK owns tracing; Core owns endpoint declaration validation. Current lifecycle Core/workcontext pins and APIs are preserved; released CLI v0.1.197 includes the squash-merged lifecycle implementation and environment telemetry delivery. The retired observability group is removed: the environment's optional telemetry: declaration delivers standard OTEL variables to every service, following the user choice on 2026-10-21. No module-owned telemetry configuration group or scoped in-cell carrier remains.

Code review found no blocking correctness, security or duplication issues. Live development export remains unqualified and is tracked separately from this merge; no deployment is claimed.

Review map and size

Raw diff against main: 3,692 changed lines (+1,568 / -2,124), including generated files and deletions. Generated deployment outputs remain committed; dedicated output directories are marked in .gitattributes:5. Authored configuration, templates, lockfiles and mixed-directory goldens remain visible, following the 2026-10-20 feedback and follow-up.

Build or reuse Verified owner implementation Final choice
Environment delivery Released CLI v0.1.197, merged CLI #1097 and lifecycle #994 Reuse every-service standard OTEL injection and HTTPS operations intake; checksum-pin the released CLI.
Tracing lifecycle SDK v0.4.1 Init/ShutdownTelemetry Remove duplicate tracing bootstrap; retain real span-export, identity and shutdown-flush regression coverage.
Endpoint declarations Core Endpoint/InterfaceEndpoint YAML decoders Reuse Core input types and error sentinel; remove copied validators and the fixture sanitizer.
Metrics/runtime Standard OTLP metrics exporter and runtime v0.71.0; Core/SDK have no metrics bootstrap Retain small per-service wiring and existing GC counters. Runtime defaults omit cycle count/GC pause CPU seconds; deprecated wall-pause metrics are different. No new framework or sibling Go module.
JavaScript security fixes Official Next.js 16.4.1, Sentry 10.75.2, and DOMPurify advisory Consume fixed versions of existing dependencies; no new package, security exception or forced major downgrade.
Go security fix Released go-grpc v0.1.58, shared runtime Go 1.27.3 Consume the owner fix, regenerate agent build recipes and runnables, use the same Go patch in CI.

Validation

  • Repaired inherited npm audit failures using released Next.js 16.4.1 in frontend/marketing, Sentry 10.75.2 in frontend, and DOMPurify 3.4.17 within Swagger's existing dependency range. npm regenerated complete lockfiles; the owning Next build's declaration update is retained. Both production builds and high/critical audit gates pass, plus 70 frontend Sentry/proxy/security tests and 22 marketing tests. Four existing moderate Swagger-chain findings remain below the unchanged gate; marketing reports none. Current head 4ec66a5a passed all 20 CI checks.

  • Merged current main 0ad1b0cb normally and resolved conflicts while preserving its security requirements and contracts. Owning CLI v0.1.197 regenerated all Runnable outputs; complete catalog generation, Runnable drift check, Accounts main/cataloggen suites, naming, boundaries and whitespace checks pass. The resulting head and subsequent security update are covered by the 20 passing CI checks.

  • Accounts main package and cataloggen tests pass; gateway SDK/metrics tests and full gateway suite pass. SDK lifecycle tests run in child processes so SDK configuration snapshots cannot affect other tests. With the CI scoped MFA setting retained at 15m, the exact SDK/MFA regression and both service suites pass; MFA expectations are unchanged. Root endpoint/topology/bootstrap tests pass. SDK integration tests receive real OTLP spans with the delivered service name and flush through public SDK shutdown.

  • Module/target Node gates: 32 passed. Catalog generation and owning Runnable generation/check pass; no generated output is curated by hand. The existing committed contract inventory is retained and the prior head passed all contract/sync CI gates.

  • Tree/record naming, boundaries and whitespace checks pass. The actual module verifier, local-default configuration guard, module/tools suite and CI replay plans for sync-drift/lint/compile/test/build pass. The retired workspace observability symlink is removed with its module default.

  • The released agent/Go security fix is retained; the prior head passed every code/build CI gate. This update passes all five released-CLI replay plans, owning Runnable drift check, 19 installer/release-record tests and both focused service telemetry suites. Local image builds and codefly generate contracts --check require an unavailable Docker socket.

Remaining limits

  • Qualify environment delivery and new-environment trace/metric export to the operations intake. Auth-gateway has no direct public TCP443 egress. The selected ambient waypoint route uses the existing HBONE TCP15008 admission; no new module collector-egress field or broad public-egress rule is needed for that route. Live CNI/HBONE handling, waypoint routing, DNS, TLS and export remain unqualified.
  • Metrics consume standard resource attributes. Current Core tracing forwards service.name/library.name only; arbitrary trace resource attributes remain a shared Core gap.
  • Core/workcontext lifecycle source candidates still require qualified released pins before publishing the module.

crisfiorini-oss and others added 9 commits October 6, 2026 16:43
…servability group (Refs codefly-dev#1022)

accounts and auth-gateway used to reach an in-graph OTLP gateway through
`Service("telemetry")`, with the service name typed as a Go literal and a
constant `WithInsecure()`. They now read where the cell's collector is from the
`observability` configuration group, which the platform delivers as
`TELEMETRY_STATE` (`available` or `absent`, never empty), with
`OTEL_EXPORTER_OTLP_ENDPOINT` when available and `TELEMETRY_ABSENT_REASON` when
absent. The group's three keys resolve to one of three outcomes:

- available with an endpoint: traces and the OTLP metric push go to it, and the
  transport is derived from the endpoint's scheme (`http://` is plaintext because
  the mesh supplies mTLS; `https://` takes the exporter's TLS default).
- absent with a reason: no OTLP exporters, the reason is logged once, boot
  continues. A local run uses wool's own stdout tracer for traces.
- anything else (state missing or unknown, available without an endpoint, absent
  without a reason, both set, a malformed endpoint): refuse to start, naming what
  is wrong. A group that did not arrive is not a cell without a collector, and
  reading it as one would leave a deployment converging green while exporting
  nothing. accounts checks this before it touches the database or Vault.

The group is read only through the SDK's workspace lookup, with no fallback to a
bare process variable: an ambient OTEL_EXPORTER_OTLP_ENDPOINT is conventionally
the OTLP/HTTP address, not the cell's gRPC collector.

Metrics now leave by one path, OTLP push. The Prometheus scrape exporter, its
/metrics mount on both services and the accounts gateway-route exemption that
existed only for it are removed, with their dependencies.

service.name is no longer a literal. OTEL_SERVICE_NAME or OTEL_RESOURCE_ATTRIBUTES
wins, and otherwise the service identity the SDK's provider holds (the one wool
stamps on log lines) is used, read from the provider rather than the runtime's
environment carrier.

wool's tracer cannot dial TLS: wool/otel.Enable always sets an insecure transport
and has no option to turn it off. An https:// endpoint is therefore refused at
startup instead of being dialed in the clear and reported as TLS, until wool can
dial it. This is a stopgap in this repository; the fix belongs in wool.

The resolution is two small mirrored copies, one per service, because they are
independent Go modules with no shared package; a module/tools test holds the
copies byte-identical.

`configurations/local/observability.env` and the local-dogfood example now say
`TELEMETRY_STATE=absent` with a reason, and OBSERVABILITY_EXPORTER is gone. The
dogfood secret example held only the collector's external headers, which nothing
reads any more, so it is removed with its ignore entry.

Tested: unit tests for the three outcomes in both services, including a
loopback OTLP receiver that checks exported spans and metrics carry the resolved
service.name. The real auth-gateway binary refuses with no group or an unknown
state, and passes the telemetry step with `absent` (then stops at the unrelated
missing runtime endpoint, since no Codefly runtime was present). Not exercised
against a real cell collector.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…laces it (Refs codefly-dev#1022)

`module/services/telemetry` was a hand-written in-graph OTLP gateway: a go-grpc
service that registered the three upstream collector services and either logged
each signal or re-marshalled it and POSTed it on. Every other upstream in this
module is a published Codefly agent with a declarative spec; this one existed
only because no collector agent did, and it was a worse collector than the one
the cell already runs. An inline POST in the gRPC handler has no batching, no
queue, no retry and no sampling, and a failed forward reaches the client as an
unretryable `Unknown`, so every forward failure dropped that batch. LogsService
was dead surface. accounts and auth-gateway now resolve the cell's collector from
the `observability` group (previous commit), so the service has no caller.

Removed:
- the service: manifest, code with its own go.mod, proto and its SchemaMarker.
- its dependency blocks in accounts and auth-gateway, its entry in
  module.codefly.yaml and in module.package.codefly.yaml.
- the generated Codefly client stubs under `code/external/.../telemetry` in both
  services. `codefly sync service` does not prune an orphaned stub; with the
  dependency gone and the stubs deleted, a sync is a no-op in both services, which
  is what a from-scratch run produces.

Regenerated, never edited, with `go generate ./pkg/cataloggen`: the topology
loses the service, both dependency edges and the telemetry public-egress row, and
the network-policy golden loses the five rules that named it. auth-gateway still
has no public egress, which is now asserted: it reached a backend only by talking
in-mesh to the gateway, and exporting to the cell's in-mesh collector needs no
443 allowance on the one service whose job is to be the perimeter. The topology
and golden tests move with it, including the strict-spec cases that borrowed this
service's manifest as a fixture.

The module-package version is bumped 0.1.0 -> 0.2.0. Removing a service and making
`TELEMETRY_STATE` mandatory is a breaking change for anyone composing the package
and, at 0.x, that is a minor bump; the manifest records it in `breaking-changes`.
`contracts/api/catalog.codefly.json` carries the package version, so it is
regenerated with `codefly generate contracts saas-starter` (a one-line change) and
the check passes. The reference composition's accepted range and the pin examples
move to the 0.2 line, and a composition test fixture now takes the package
version from the manifest instead of a literal.

Counted prose corrected: seven services, twelve endpoints, six dependency edges,
six interface endpoints, three public-egress grants and eighteen NetworkPolicy
documents (the topology doc's endpoint, interface and policy counts were already
stale against its own test); five Go modules by the enumeration given; the
service graph and dependency tables; the collector-resolution paragraphs in the
module, topology, analytics, SigNoz, features, local-dogfood and dogfooding docs
and the run-locally skill. The metrics decision is recorded: OTLP push only,
2026-10-06.

Left alone on purpose: the job-worker and analytics-outbox telemetry files and the
synthetic `telemetry` fixture in the root module's mesh-policy test, which share
only a word with this service. The point-in-time security review records still
describe the former /metrics route as filed.

Not done here: this does not bump the pinned codefly core, so the log/trace
correlation fix is not yet consumed. Tested: the Go suites in accounts (pure),
auth-gateway, module/tools, the root module and qualification/module-authority,
the cataloggen parity tests, and the repository's node gates. Two module/tools
tests fail identically on an untouched checkout in this environment (a missing
`buf` binary, and a cache rename refused on macOS) and were not run to success.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e metrics exporter from the endpoint URL (Refs codefly-dev#1022)

The `observability` group is layered: a cell's values override the module's
local defaults one key at a time. A deployed producer therefore receives
`TELEMETRY_STATE=available` and `OTEL_EXPORTER_OTLP_ENDPOINT` from the cell and
a leftover `TELEMETRY_ABSENT_REASON` from the local profile, and the previous
resolution refused that as "both set", so the service would not start on the one
configuration a cell is certain to deliver.

The state now decides, in both mirrored copies of telemetry_destination.go:

- `available` requires a non-empty endpoint. A leftover reason is ignored.
- `absent` requires a non-empty reason. A leftover endpoint is ignored, and is
  not parsed, so a stale one cannot stop a cell that says it has no collector.
- A missing or unknown state, and the key the state requires being missing, still
  refuse to start.

What was ignored is carried on the destination and reported once, where the
process acts on the answer (accounts' doWork, auth-gateway's main), not by
requireStartupConfiguration, which reads the group a second time only to refuse.
The notice names the key and never its value: a leftover endpoint may carry
credentials and a leftover reason is free text.

The metrics exporter is now built with `otlpmetricgrpc.WithEndpointURL`, so the
official exporter reads its transport off the URL's scheme instead of being given
host:port and a separately derived insecure flag. The destination carries the
origin as scheme://host:port with the port always explicit, because gRPC would
otherwise dial 443 whatever the scheme. Traces keep wool's Enable path and its
labelled https stopgap; a separate core change teaches wool TLS-from-scheme. An
empty URL is refused rather than handed to WithEndpointURL, which would fall back
to the exporter's own localhost:4317 and report success.

The exporter used to be created before the resource, and a resource that could not
be built returned without shutting it down, leaking its client connection. The
resource is now built first, so there is no exporter to leak; the later failure
paths already shut the provider down, which shuts the exporter down with it.

Tests: both layered cases, a module default of `absent` with a reason under a cell
override of `available` with an endpoint (and the reverse), a leftover endpoint
that is malformed or carries credentials, blank leftovers, the same through the
SDK's lookup, and the requirement that a state still supplies its own key. An
https:// URL is shown to be TLS by failing to export to a plaintext receiver, and
the test fails if the exporter is given a constant insecure transport. The mirror
test still holds the two copies identical. FEATURES, the local profile and the
local-dogfood example describe the rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… default network (Refs codefly-dev#1022)

Both services read their own listener ports through `WithDefaultNetwork()`, which
makes the SDK answer an endpoint that does not resolve with a default network
instance instead of an error. The next SDK release deletes that method, and its
own test holds it deleted ("legacy means delete, not deprecate"): a port the
runtime did not inject is an error, never a default, and a service that serves on
a port nobody gave it is reachable from nowhere and reports healthy. This lands
before the dependency bump so the bump is only a bump.

- auth-gateway: the gRPC port is resolved with ResolveNetworkInstance and the
  process refuses to start without it, exactly as it already does for its REST
  port on the next line.
- accounts: the gRPC port is required, for the same reason: it is what the
  process is. REST and Connect were optional in code but, behind the default
  network, never actually absent; they now resolve through one helper that, when
  an endpoint does not resolve, logs it by name and serves no listener for it,
  which is how this file already treats the module authority endpoint. The comment
  above that endpoint no longer needs to say it is the one query that avoids the
  default network.

Behaviour is unchanged wherever the runtime injects the endpoint (auth-gateway
already refused to start on a missing REST carrier, so that path is exercised).
What changes is only the broken case: a missing gRPC endpoint is a refusal to
start instead of a listener on a default port, and a missing REST or Connect
endpoint is a logged error and no listener instead of a listener on a default
port. Not exercised against a real cell: only a simulated deployed process, with
the carriers set by hand.

Classified as a fix at the place that owns the behaviour: these two call sites
asked the SDK to invent a value, and the SDK stopped doing that. accounts'
main.go still carries the template's "do not edit" banner, but it is authored: it
already holds the module authority endpoint block and `codefly sync service` leaves
it untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…odefly-dev#1022)

Core v0.13.0 carries the log/trace correlation that codefly-dev#1022 waits on, so accounts
and auth-gateway now consume it. Each Go module was moved with the repository's
bump verb, `codefly agent deps --dir <module> --pin v0.13.0` (which pins every
lock the module owns and verifies the standalone build), and `go mod tidy` leaves
every module unchanged afterwards.

Modules that pin core and moved: the root module agent, `module/tools`, accounts,
auth-gateway, and `qualification/module-authority` and the store migrator, which
only carry it indirectly. `libraries/source-read-sdk/go` does not depend on core.

sdk-go moves with it, v0.2.1-0.20260926212413 -> v0.3.1, in accounts,
auth-gateway and the store migrator, because it is not optional: the old sdk-go
uses `resources.VisibilityExternal`, which core removed before v0.13.0, so no
sdk-go older than v0.3.1 builds against any core this change could pin. v0.3.1
itself requires core v0.13.0, which makes v0.13.0 the pair upstream tested. Its one
source-level break for this repository, the deleted `WithDefaultNetwork`, is
handled in the commit before this one.

Why not v0.14.0, which was the target: v0.14.0 builds, but it refuses a module
interface or endpoint that authors `allow-modules`, since an allow-list is derived
from the consumers' declared dependencies and never written by the module it
grants. This module authors `allow-modules: ["*"]` in `module.codefly.yaml` and in
the accounts, auth-gateway and vault manifests, so
`TestGeneratedCodeflyAndNetworkManifestsParseStrictly` fails to load them under
v0.14.0 and passes under v0.13.0. Moving those manifests to derived allow-lists is
its own change, with its own render consequences for composing workspaces, and is
not made here.

`sdk-go/workcontext` stays on its current pseudo-version in accounts and
auth-gateway. The newer workcontext replaces the signing API this repository
imports (`WorkContextSigner`, `WorkContextVerifier`, `WorkContextToken` and the
header constants), a migration of its own that touches most of accounts' Work
Context handling.

Tested with the generated telemetry stubs present: `go vet` and `go test` in
accounts (pure suite), auth-gateway, `module/tools`, the root module and
`qualification/module-authority`, `go vet` in the store migrator and the source-read
SDK; every generator and `codefly sync` rerun leaves the tree unchanged; the
contracts check with the CI-pinned CLI 0.1.171. Not exercised: `codefly run` of the
graph, a deployed cell, or the accounts database suites.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ubs the generator owns (Refs codefly-dev#1022)

The service-removal commit deleted `external/saas-starter/telemetry/` from accounts
and auth-gateway by hand. Both files are generator output (`Code generated by
protoc-gen-go. DO NOT EDIT.`), and this repository does not hand-edit generated
code, deletion included. They are restored byte for byte from main, with no
other change.

They are orphaned: no dependency block declares the telemetry service any more, and
nothing imports the package. `codefly sync service` does not prune bindings for a
dependency that is no longer declared, so a sync leaves them where they are, and the
tree stays clean after every generator and sync rerun with them present. With them
present, `go vet` and `go test` in accounts (pure suite) and auth-gateway, the
contracts check with the CI-pinned CLI 0.1.171, the module-package validation and
archive determinism, and the node gates all pass, so there is no failing check to
justify removing them. The generator owns them and will prune them once it learns
to; a draft issue against the go-grpc agent describes the gap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Remove TELEMETRY_STATE from module defaults that deployed cells inherit.
Infer an absent collector only when the SDK identifies a local runtime,
and retain refusal of explicit invalid or incomplete configuration.

Cover shipped defaults, both runtime modes and startup checks in both
producers; update the operator docs and module breaking-change notice.
crisfiorini-oss and others added 5 commits October 8, 2026 13:57
…iewed state (Refs codefly-dev#1022)

This pull request carries the telemetry cleanup, and that alone. It had been
folded into the audit store pull request; the owner asked for one pull request
per feature, so the cleanup is reopened here with its full current state.

Brought forward from the combined branch, telemetry hunks only:

- the review fix that ships neither `TELEMETRY_STATE` nor its reason in the
  module profile: both services supply the `absent` state and its reason in code,
  and only when the runtime is `local`, and the local-dogfood docs say what
  that environment exports;
- the destination, metrics and startup code, their mirror test and the
  `observability` profile and docs;
- the deletion of `module/services/telemetry` with its topology, golden and
  package-contract entries, and module package 0.2.0 with its breaking-changes
  record.

Brought forward because both features compile against them, and written so the
audit pull request carries the same lines: core v0.15.1 and sdk-go v0.3.1, the
listener ports resolved with `ResolveNetworkInstance`, the Vault endpoint
declared private, the Core 0.14 declaration changes, and the presence-schema
test updates Core 0.15 asks for.

Nothing from the audit store is carried: no relay, queue, quarantine, warehouse
store or audit migration.

Main moved the key service in beneath the startup checks; `doWork` and the
startup requirement now take its context. The root guide and the release-gates
page no longer state a count of Go modules, which nothing enforces and which the
removal changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ervability requirement (Refs codefly-dev#1022)

Main made the key service the first startup requirement outside a local run:
`requireStartupConfiguration` now refuses an unset `KEY_SERVICE_BACKEND` before
it reaches the observability group, so the test that proves a missing
`TELEMETRY_STATE` is refused stopped reaching that refusal. It now names a
backend and a key custody through the helpers the other startup tests use, so
the observability requirement is what is under test again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cope ceilings in the authority fixtures

Core v0.15 requires every authority document to state the subject module's
three declarations, `[]` when it owns none, so that a renderer which dropped one
cannot read as "owns nothing". The two delivery fixtures that build an
`AuthorityDocument` by hand left them nil, and eight database-backed tests in
`pkg/infra` failed validation with "declares no queues" once the module took the
bump.

The fixtures now write all three as empty lists. A withdrawn generation states
them empty too, which is what the document rule asks of it.

This hunk is shared: it rides with the core bump, and the other feature's pull
request carries the same lines, so whichever merges second rebases onto them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…motion (Refs codefly-dev#1022)

The topology page's promotion paragraph named the audit store's deploy-job
driver beside Core's consumer-derived allow-list support. Only the second is
this change's requirement. The shared sentences stand alone and the driver
belongs to the audit store's pull request, which states it in a paragraph of its
own, so the two pull requests no longer edit the same lines.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…codefly-dev#1022)

The topology page said the policy golden holds 18 resources, which was the count
before main added the policy-log service's policies. The golden and the
topology test hold 19, and the page now says so in both places it counts them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
crisfiorini-oss added a commit to crisfiorini-oss/module-saas-starter that referenced this pull request Oct 8, 2026
… (Refs codefly-dev#996, codefly-dev#1022)

This pull request carries the audit store migration, and that alone. The
telemetry cleanup it had absorbed (codefly-dev#1022, formerly the reviewed codefly-dev#1027) is back
on its own branch, so each feature reviews, merges and, if it must, reverts by
itself.

Removed here, because the cleanup owns them:

- the deletion of `module/services/telemetry` and its service-graph, topology,
  golden and package-contract entries;
- the `telemetry_destination.go` copies in accounts and auth-gateway and their
  mirror test, the OTLP-only metrics, and the `observability` profile and docs;
- the module package version 0.2.0 and its `telemetry` breaking-changes record,
  with the generated catalogs and the reference composition that follow it.

Kept, because both features compile against it: core v0.15.1 and sdk-go v0.3.1,
the migration of the listener ports to `ResolveNetworkInstance`, the Vault
endpoint declared private, the declaration changes core v0.14 requires and the
presence-schema test updates v0.15 requires. The same hunks sit unchanged in the
telemetry pull request, so whichever merges second rebases onto identical lines.

The audit review fixes stay as they were: `RefusedForOneReason`, and a store's
details written before its events.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (Refs codefly-dev#1022)

The review of this change found the module reimplementing what core already
does. wool/otel.Enable reads OTEL_EXPORTER_OTLP_ENDPOINT itself, tells a URL from
a host:port, validates the URL, takes the transport from the scheme and refuses a
portless one or one carrying credentials. The 326-line destination resolver in
each service, its roughly 600-line test, the mirror test that held the two copies
identical, and the fail-closed state machine around them (TELEMETRY_STATE,
TELEMETRY_ABSENT_REASON) all collapse into the standard variable and one call.

The whole contract is that one variable. The platform delivers it when the cell
has a collector the workload may reach, and delivers nothing when it does not:

- set: `wooltel.Enable` exports traces to it, and the metrics exporter, which
  reads the same variable, exports metrics to it;
- unset: no OTLP exporter is built at all, and a process given no collector
  starts normally. There is no telemetry startup requirement any more, and the
  `observability` group no longer has a state or a reason to refuse on.

Two behaviours of the dependencies decided the shape, each read from source:

- `Enable` with no endpoint falls back to a stdout tracer, so it is only called
  when the variable is set or the run is local; a deployed process with none
  registers no tracer rather than printing every span to its log.
- `otlpmetricgrpc.New` with nothing configured dials localhost:4317 over TLS,
  and it reads the variable only as an http:// or https:// URL, keeping that
  default on any other value without a word, where `Enable` takes such a value
  for a bare host:port. So the metrics call refuses an unset variable and any
  value that is not such a URL, instead of building an exporter pointed at the
  default.

`IsLocal()` no longer decides whether to export. A pod deployed into an
environment named `local` that is handed a collector exports to it; `IsLocal()`
now only chooses wool's stdout tracer when no collector is named. An https://
endpoint is no longer refused at startup: core's URL path takes the transport
from the scheme, which wool's tracer could not do before.

`service.name` still comes from `OTEL_SERVICE_NAME`, `OTEL_RESOURCE_ATTRIBUTES`
or the service's own identity, and stays in a small `telemetry.go` per service
with its tests.

`configurations/local/observability.env` ships the one empty assignment the
repository's every-declared-group-ships-a-default test needs, which is no
endpoint. Nothing reads that key: a group value arrives as a
`CODEFLY__WORKSPACE_CONFIGURATION__OBSERVABILITY__` carrier, and the standard
variable is what points a run at a collector. The docs, FEATURES.md, the local
dogfood example and the package's breaking-changes record now describe the one
variable.

Classification: fix, at the place that owns the behaviour (core reads the
variable); the module stops duplicating it.

Not done: a NetworkPolicy egress rule for the collector in the generators
(gitops.go and cataloggen). The collector's namespace and port are not part of
the environment declaration they read, and the Vault precedent
(`managed-services.<svc>.egress-namespace`) is authored by hand in the
workspace: the CLI's environment model has no such field and its contract parser
refuses unknown keys. That needs the CLI to carry the field first; no rule is
rendered from a guessed or typed value, and DEPLOYMENT_TOPOLOGY.md says so.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep workload TLS and current Core/SDK dependencies while removing the telemetry service and its build files. Verify retention failures through OTLP, and regenerate Runnable packages for module version 0.2.0.
@crisfiorini-oss crisfiorini-oss changed the title feat(module)!: remove the telemetry service; producers resolve the cell's collector from the observability group feat(module)!: remove telemetry service and export to the cell collector Oct 21, 2026
@crisfiorini-oss crisfiorini-oss changed the title feat(module)!: remove telemetry service and export to the cell collector feat(module)!: remove telemetry service and use the operations intake Oct 22, 2026
@crisfiorini-oss
crisfiorini-oss marked this pull request as ready for review October 22, 2026 17:19
gael-obin pushed a commit to gael-obin/module-saas-starter that referenced this pull request Oct 23, 2026
@antoinetoussaint-byte
antoinetoussaint-byte added this pull request to the merge queue Oct 23, 2026
Merged via the queue into codefly-dev:main with commit 0004aee Oct 23, 2026
25 checks passed
crisfiorini-oss pushed a commit to crisfiorini-oss/module-saas-starter that referenced this pull request Oct 23, 2026
…codefly-dev#1232)

The frontend and marketing services pinned the nextjs agent at 0.0.163. That
agent pins the framework EXACTLY in `base/code` and `templates/factory/code`,
and its `framework_version_test.go` holds the lockfile's resolved version equal
to the declared one, so no service it builds can resolve past the agent's pin.
Through 0.0.166 that pin was next 16.3.6, which carries three criticals:

  - unauthenticated RCE in the Image Optimization API when SVG files are used
    (GHSA-2464-fhr4-w9xw)
  - DoS in App Router using Server Actions (GHSA-p3m5-59mp-jv5r)
  - RCE in `use cache` functions returning typed arrays (GHSA-673q-mjm6-r5xr)

0.0.167 ships next 16.4.1 (service-nextjs#177), and with it Go 1.27.3 for
GO-2026-6809 (codefly-dev#178) and typescript back to ^5 — the only major
typescript-eslint@8 admits, so the scaffold's own lint runs again (codefly-dev#179).

Verified against the release rather than the release notes: v0.0.167 is a
published, non-draft GitHub Release with 9 assets (`agent.version` resolves a
Release, not a tag — a tag-only version 404s and takes every integration suite
with it), and the tag itself carries next 16.4.1, typescript ^5 and go 1.27.3.

This is the durable half of the Next.js remediation. The application-side
lockfiles were already patched on main by codefly-dev#1027; this moves the agent that
builds them, so a future service scaffolded here does not start vulnerable.

Classification: fix, at the place that owns the framework version.

Co-authored-by: Antoine Toussaint <312536060+antoinetoussaint-byte@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
saurabhmaheshwari-obin added a commit to saurabhmaheshwari-obin/module-saas-starter that referenced this pull request Oct 24, 2026
…codefly-dev#1232)

The frontend and marketing services pinned the nextjs agent at 0.0.163. That
agent pins the framework EXACTLY in `base/code` and `templates/factory/code`,
and its `framework_version_test.go` holds the lockfile's resolved version equal
to the declared one, so no service it builds can resolve past the agent's pin.
Through 0.0.166 that pin was next 16.3.6, which carries three criticals:

  - unauthenticated RCE in the Image Optimization API when SVG files are used
    (GHSA-2464-fhr4-w9xw)
  - DoS in App Router using Server Actions (GHSA-p3m5-59mp-jv5r)
  - RCE in `use cache` functions returning typed arrays (GHSA-673q-mjm6-r5xr)

0.0.167 ships next 16.4.1 (service-nextjs#177), and with it Go 1.27.3 for
GO-2026-6809 (codefly-dev#178) and typescript back to ^5 — the only major
typescript-eslint@8 admits, so the scaffold's own lint runs again (codefly-dev#179).

Verified against the release rather than the release notes: v0.0.167 is a
published, non-draft GitHub Release with 9 assets (`agent.version` resolves a
Release, not a tag — a tag-only version 404s and takes every integration suite
with it), and the tag itself carries next 16.4.1, typescript ^5 and go 1.27.3.

This is the durable half of the Next.js remediation. The application-side
lockfiles were already patched on main by codefly-dev#1027; this moves the agent that
builds them, so a future service scaffolded here does not start vulnerable.

Classification: fix, at the place that owns the framework version.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
(cherry picked from commit 7ed5ded)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
saurabhmaheshwari-obin added a commit to saurabhmaheshwari-obin/module-saas-starter that referenced this pull request Oct 24, 2026
…v#1239)

Ported to the v0.0.105 line. Beyond codefly-dev#1239, this also takes main's exact pins
from codefly-dev#1027 that the first-party audit gate needs on this line: next and
eslint-config-next 16.4.1 (frontend and marketing; GHSA-2464-fhr4-w9xw,
GHSA-p3m5-59mp-jv5r, GHSA-673q-mjm6-r5xr) and @sentry/nextjs 10.75.2
(GHSA-mchm-gjx6-7h55), and refreshes dompurify to 3.4.17 within its range
(GHSA-cg2g-xh64-v4q7). Lockfiles regenerated with npm install
--package-lock-only. The kit packages are byte-identical to main's 0.13.0.

(cherry picked from commit f3fee4c)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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