# Generic tail — technologies outside the mandated stack

Load when: the touched code exhibits one of these technologies and no dedicated pack covers it. Entries here are deliberately thin — one gotcha and the safe-change essence each; diagnose the rest from the mechanism (see `../mechanisms.md`). When the org adopts one of these seriously, promote its section into a full pack.

## API styles

- **graphql-schema — CRITICAL · serialized-shape.** The SDL is executed by clients you don't redeploy: removing/renaming a field, tightening output nullability, or removing an in-use enum value breaks live queries at execution. Safe: schema-diff check in CI (GraphQL Inspector / `rover graph check`); `@deprecated` + usage metrics before removal; regenerate client types every change. Federation directives (`@key`, `@external`, `@requires`, `@shareable`) add a cross-*team* facet: composition fails or takes down fields other subgraphs own.
- **graphql-persisted-queries — HIGH · generated-artifact.** The server executes only registered hashes; editing an operation without republishing the manifest → `PersistedQueryNotFound` for all traffic on that operation.
- **grpc-protobuf — CRITICAL · serialized-shape.** Field numbers identify fields on the wire and can never be reused — a reused number deserializes garbage with no error, across services on different `.proto` versions. Safe: `reserved` removed numbers; add with new numbers only; `buf breaking` in CI; never change wire type or cardinality in place.
- **trpc — HIGH · generated-artifact.** The exported `AppRouter` type is the contract; it holds only if client and server build from the same version — deploy skew breaks at runtime despite full type safety. Keep tRPC package versions identical on both sides; version procedures via sub-routers.
- **openapi-spec — HIGH · generated-artifact.** Spec↔server drift makes generated SDKs/mocks send wrong shapes, visible only at runtime. Regenerate spec-from-code (or code-from-spec) in one change; run a breaking-change linter (`oasdiff`) in CI.
- **cache-headers/cdn — HIGH · config-elsewhere.** The cache obeys the header you already sent: `immutable`/long `max-age` on non-hashed assets means users never update; caching a personalized response in a shared cache leaks it; any header the response branches on must appear in `Vary` (and never `Vary: Authorization` on a shared cache). Deploys need a purge step.

## Event/stream platforms

- **kafka-consumer-groups — CRITICAL · rendezvous-string + lifecycle-protocol.** The group id owns the committed offset: renaming a group restarts from `auto.offset.reset` — `earliest` reprocesses everything, `latest` skips the backlog, both silently. Rewind via explicit offset reset, never a group rename.
- **schema-registry — CRITICAL · serialized-shape.** The compatibility mode (BACKWARD/FORWARD/FULL/TRANSITIVE) defines which producer/consumer upgrade orders are safe; Avro fields without defaults and Protobuf number reuse break consumers fleet-wide. CI-enforce a mode; every new Avro field gets a default.
- **cdc/debezium — CRITICAL · generated-artifact.** The stream's shape derives from a source schema owned by a team that may not know consumers exist — a column rename silently reshapes the stream; a table rename relocates the topic. Treat CDC-source columns as a published contract; pin topic routing and `REPLICA IDENTITY`.
- **event-sourcing/audit tables — CRITICAL · serialized-shape + lifecycle-protocol.** Events are immutable and replayed: today's projector must read events written years ago. Version event types + upcast; never mutate history; test a full replay.
- **outbox/saga — HIGH · lifecycle-protocol.** The outbox table schema is co-owned by the writing transaction and the relay (columns additive; keep the relay mapping synced). Every forward saga step needs its compensation wired into the failure path — a mid-saga failure otherwise leaves money reserved and never released.
- **workflow-engines (Temporal etc.) — CRITICAL · lifecycle-protocol.** Running workflows replay their history through current code: adding/reordering an `await` on a command-producing call diverges replay and bricks in-flight executions while new-workflow tests pass. Gate logic changes with `patched()`/`getVersion()`; keep I/O in Activities; replay production histories in CI.

## Postgres deep end

- **rls-policies — CRITICAL · trust-invariant.** A new tenant table without a policy, a missing `FORCE`, an owner/`BYPASSRLS` connection, or a forgotten `SET LOCAL` silently returns all rows. Column + policy + `FORCE` land in one migration; app traffic runs under a non-owner role.
- **pooled-session-state — HIGH · lifecycle-protocol.** Under PgBouncer transaction pooling, session state (`SET`, prepared statements, advisory locks, RLS GUCs) is shared across clients: use `SET LOCAL` only and disable server-side prepared statements, or tenant context leaks across pooled connections.
- **collation/extensions — HIGH · config-elsewhere.** A schema object needs its extension installed before the migration that uses it (from-scratch deploys fail); a glibc/ICU collation change silently corrupts B-tree index order → wrong results and "duplicate" unique rows. Reindex after any collation-version change.
- **matviews/read-models — MED · generated-artifact.** Two contracts: the source schema the refresh reads (a source column change breaks it) and the read-model shape consumers query; `REFRESH … CONCURRENTLY` needs a unique index; staleness serves wrong data with no error.

## Frontend long tail

- **ssr-hydration — HIGH · serialized-shape.** Server markup must byte-match the client's first render (React 19: mismatch is a hard error discarding the server tree) and transferred state must survive serialization (`Date`/`Map`/`Set`/`undefined` don't, by default). Move non-determinism into effects; use superjson/devalue or explicit rehydration.
- **module-federation — CRITICAL · config-elsewhere.** Host and remotes deploy independently but must agree at runtime on exposed-module names and `shared` singleton versions — drift loads duplicate React and breaks hooks/context silently. `singleton: true` + `strictVersion` for framework libs; coordinate deploys.
- **i18n-keys — MED · rendezvous-string.** Key renamed in code but not catalogs shows the raw key; missing interpolation vars render literal `{{name}}`. CI-gate with a parser (`i18next-parser --ci`); generate key types.
- **analytics-tracking-plan — MED · rendezvous-string.** Renaming an event or property silently breaks dashboards/funnels and fragments history, with no app error. Centralize names in a typed module; add, deprecate, never rename.
- **feature-flags (hosted) — HIGH · rendezvous-string.** A deleted-but-still-referenced flag returns the SDK default (often `false`), silently hiding a shipped feature; off must always mean previous-safe-behavior so disabling is rollback. Two-step removal in distributed systems: make safe unconditionally → deploy everywhere → delete.
- **deep-links/oauth-callbacks — HIGH · rendezvous-string.** Links already sent in emails/push are irrecoverable, and OAuth providers allowlist exact callback URLs — a path change breaks both. Keep old paths redirecting; update provider allowlists and AASA/assetlinks in lockstep.

## Orchestrated runtime (K8s and friends)

- **health-probes — HIGH · rendezvous-string + lifecycle-protocol.** The orchestrator polls a path the app owns: rename `/healthz` and K8s CrashLoopBackOffs a healthy pod. Liveness = cheap process-only check (a DB blip in liveness kills the pod); readiness = critical deps and must fail immediately on SIGTERM or rolling deploys 502.
- **graceful-shutdown — HIGH · lifecycle-protocol.** Shell-form ENTRYPOINT swallows SIGTERM (signals hit the shell, not the app); a `preStop` sleep covers endpoint-propagation lag. On SIGTERM: fail readiness → stop new connections → drain → exit; grace period ≥ max request time.
- **resource-limits — HIGH · config-elsewhere.** The kernel enforces limits the app never sees: a bigger cache OOMKills (exit 137) with no app error; CPU limits throttle silently. Make heap settings cgroup-aware; re-evaluate limits when adding caches/deps.
- **service-discovery/ingress/tls — HIGH · rendezvous-string.** Service names, ingress path rules (order- and specificity-sensitive; rewrites must match mounted routes), and cert SANs each bind by exact string — a rename 404s/NXDOMAINs/fails handshake while the app stays healthy. Add hostnames to the cert SAN list before routing traffic.
- **mesh-resilience-budgets — HIGH · lifecycle-protocol.** Timeouts must nest (caller > callee × retries) or retries storm a recovering service; these configs live in a different repo/layer than the calling code.
- **iac-outputs — HIGH · rendezvous-string.** A consuming stack reads producer outputs by name (`terraform_remote_state`, `Fn::ImportValue`): rename/remove one and every consumer fails to plan. Outputs are public API — deprecate, don't rename.
- **trace/metrics/logs naming — MED · rendezvous-string.** Dashboards, alerts, and cross-service queries pin exact metric names, label keys, and log field names — a rename makes the alert go quiet, not fire. Deprecate, don't rename; never put unbounded cardinality in labels.

## Misc

- **di-containers — HIGH · rendezvous-string.** String/symbol tokens and registrations match at runtime only; a scope change (singleton↔request) silently shares state across requests/tenants. Typed tokens; treat scope as part of the contract.
- **worker/ipc boundaries — MED · serialized-shape.** Only structured-cloneable values cross `postMessage`/IPC — class instances lose methods, `instanceof` fails; a renamed IPC channel (`ipcMain.handle` vs `ipcRenderer.invoke`) silently no-ops. Version the message envelope; share channel constants.
- **object-storage keys — MED · rendezvous-string.** The key template is a contract among uploader, downloader, lifecycle rules, and DB pointers — changing it orphans existing objects (no FK between DB and bucket). Store the full key in the DB; migrate by copy/re-point.
- **saml — HIGH · config-elsewhere.** IdP signing-cert rotation without the SP re-importing metadata fails every assertion; a `NameID` format change re-keys identity and duplicates accounts. Overlap certs during rotation; pin identity on a stable identifier.
- **lambda-handler-envelopes — HIGH · serialized-shape.** The platform owns the event shape: API Gateway payload v1→v2 moves `event.httpMethod` to `event.requestContext.http.method`, existing parsing reads `undefined`. Pin the payload format version; validate the event at the handler.
