Problem
Non-sensitive configuration is scattered as inline literals and direct process.env reads across several apps in the monorepo, with no single source of truth — changing a value means hunting for every occurrence:
- docs — PostHog host strings are hardcoded in two places that must stay in sync: the client init (
instrumentation-client.ts) and the build-time /ingest rewrites (next.config.mjs).
- shade-agent —
NEXT_PUBLIC_contractId is read directly via process.env in two route files, bypassing the app's existing validated env module.
- examples — the default model name is duplicated as an inline literal across 13 agent files (two distinct defaults).
Proposal
Centralize each app's non-sensitive config into one source-of-truth module, with zero behavior change. Rule: read from process.env only where the env var is a documented per-deploy / user-override value (e.g. LLM_MODEL, contractId, the PostHog key); otherwise hold a plain constant (fixed hosts).
- docs —
apps/docs/config/posthog.mjs (plain ESM so both the client init and next.config.mjs can import it).
- shade-agent — add
NEXT_PUBLIC_contractId to the existing Zod env.ts (optional, to preserve graceful runtime handling).
- examples —
apps/examples/src/config.ts exporting DEFAULT_MODEL / DEFAULT_MODEL_STABLE.
Out of scope
Sensitive keys/tokens stay as direct process.env reads; model names in JSDoc/comments are left as-is.
Problem
Non-sensitive configuration is scattered as inline literals and direct
process.envreads across several apps in the monorepo, with no single source of truth — changing a value means hunting for every occurrence:instrumentation-client.ts) and the build-time/ingestrewrites (next.config.mjs).NEXT_PUBLIC_contractIdis read directly viaprocess.envin two route files, bypassing the app's existing validatedenvmodule.Proposal
Centralize each app's non-sensitive config into one source-of-truth module, with zero behavior change. Rule: read from
process.envonly where the env var is a documented per-deploy / user-override value (e.g.LLM_MODEL,contractId, the PostHog key); otherwise hold a plain constant (fixed hosts).apps/docs/config/posthog.mjs(plain ESM so both the client init andnext.config.mjscan import it).NEXT_PUBLIC_contractIdto the existing Zodenv.ts(optional, to preserve graceful runtime handling).apps/examples/src/config.tsexportingDEFAULT_MODEL/DEFAULT_MODEL_STABLE.Out of scope
Sensitive keys/tokens stay as direct
process.envreads; model names in JSDoc/comments are left as-is.