diff --git a/.changeset/15295-serve-observability-mirror-comment.md b/.changeset/15295-serve-observability-mirror-comment.md new file mode 100644 index 0000000000..7a55384552 --- /dev/null +++ b/.changeset/15295-serve-observability-mirror-comment.md @@ -0,0 +1,56 @@ +--- +'@objectstack/cli': patch +--- + +`serve.ts`'s observability knob block points at the cloud mirror in the house style, keeps the sync duty, and names the package that owns the list (#15295) + +The block above `buildServeObservability()` instructed the reader to *"keep the +two in sync"* with `apps/cloud/server/observability.ts` — a path that has not +existed in this repository since `apps/cloud` moved to `objectstack-ai/cloud` +(`git ls-tree origin/main -- apps/` returns exactly `apps/docs`, the positive +control that makes that a reading rather than a broken query). A reader was +being sent to a file they cannot open, with no hint that it lives in another +repository. + +**The duty is live, so it stays.** The cloud file still exists and still reads +these names as `process.env` lookups (measured on `objectstack-ai/cloud` and +recorded on #15295, with that file's own `process.env` hit count as the firing +control) — for every knob in the block except `OS_OTLP_FLUSH_MS`, which was +added on this side after that measurement and is therefore unverified rather +than mirrored. The comment states that boundary rather than a bare count, so a +reader counting six entries under a claim about five cannot be misled about +which of them the reading covers. Deleting the clause would have dropped a real +obligation whose failure mode is quiet: the two exporters drift and the cloud +host stops reading the variables an operator set. + +Three things change, all inside one comment block: + +- the path is re-spelled in this repo's settled style for a cloud-repo + reference — ``(`apps/cloud/server/observability.ts`, cloud repo)``, the form + at `packages/services/service-cluster/src/multi-node-gate-mount.ts:9`; +- the duty is narrowed to what its own words say — **names, not defaults**. + `OS_OBS_SERVICE_NAME` defaults to `objectstack` here and to + `objectstack-cloud` there *deliberately*, because two deployments are two + services; a future reader "tidying" that into one value would merge both + deployments into a single telemetry series. The comment now says so, which is + the point of writing it down rather than leaving it to be rediscovered; +- the canonical home for the variable list is named as + `@objectstack/observability` — the package **both** consumers already import + — instead of two consumers pointing at each other. That mutual pointing is + the decay mechanism itself, and it is still one-sided today: the cloud file + carries no reciprocal sentence, so nobody renaming a name over there is + prompted to come back here. + +⛔ No behaviour changes, and no observability code path was touched. No env var +is added, removed or renamed; no default moves. + +**This ships, which is why it carries a changeset rather than +`skip-changeset`.** `@objectstack/cli`'s published `files[]` is +`["dist","README.md","CHANGELOG.md"]`, and this package builds with plain `tsc` +(no `removeComments`), so the block is emitted verbatim into the tarball — +measured on the rebuilt artifact: the new clause is present in +`dist/commands/serve.js` (1 occurrence, and the knob-list line as control +resolves to that one file), the old spelling is absent from all of `dist`, and +`dist/commands/serve.d.ts` carries 0 of it because the block sits above a +non-exported helper. So the published JS bytes move while the declaration +surface does not. diff --git a/packages/cli/src/commands/serve.ts b/packages/cli/src/commands/serve.ts index f48928e204..e73424b4ac 100644 --- a/packages/cli/src/commands/serve.ts +++ b/packages/cli/src/commands/serve.ts @@ -146,8 +146,35 @@ import { SEMCONV, OBSERVABILITY_METRICS_SERVICE, type MetricsRegistry } from '@o // to hand off to `createDispatcherPlugin`. Default is fully noop so the // CLI imposes no runtime cost when observability isn't configured. // -// Env knobs (also documented in apps/cloud/server/observability.ts — keep -// the two in sync if you tweak names): +// Env knobs — the SAME names are also read by the cloud host +// (`apps/cloud/server/observability.ts`, cloud repo), so keep the two in sync +// if you tweak NAMES. That duty is live, not stale prose: the cloud file reads +// these as `process.env` lookups — measured on #15295 for every knob listed +// below EXCEPT `OS_OTLP_FLUSH_MS`, which was added on this side afterwards and +// has never been measured against that repository: treat that one as +// unverified rather than mirrored. +// +// ⛔ NAMES only — the DEFAULTS differ on purpose, and unifying them is a +// telemetry regression rather than a tidy-up: `OS_OBS_SERVICE_NAME` defaults +// to `objectstack` here and to `objectstack-cloud` there because two +// deployments are two services; collapsing them merges both into one series. +// +// The canonical home for this list is `@objectstack/observability` — the +// package BOTH sides already import (statically, a few lines above; the cloud +// file imports it too) — not these comments pointing at each other, which +// is how the duty decayed to begin with: it is one-sided today, the cloud file +// carries no reciprocal sentence, so nobody renaming a name over there is +// prompted to come back here. Until the list lives in that package, this block +// is it, and moving the cloud half is a change in the cloud repo (#17693). +// +// ⚠️ And the carriers are not two but three: +// `content/docs/deployment/environment-variables.mdx` (`## Observability`) +// publishes this same list with types and defaults, and it is the one most +// readers reach first. Its `OS_OBS_SERVICE_NAME` row states the framework +// default with no note that the cloud host differs on purpose, so the +// NAMES-only rule above has to be honoured there too. Fixing that page is out +// of this block's scope; the caveat rides with the canonical-home decision +// (#17693). // OS_OBS_EXPORTER noop (default) | console | json | otlp // OS_OTLP_ENDPOINT OTLP/HTTP root, e.g. https://otlp.grafana.net/otlp // OS_OTLP_HEADERS comma-separated Key=Value; values may be URL-encoded