docs(agents): rewrite package map and conventions for Veect

AGENTS.md now describes the Veect control plane (ADR-027/028/029,
docs/product/ authority table, glossary Veect-domain vocabulary), with
the package map, boundary tags, and per-package conventions verified
against the filesystem (auth + 11 core + 3 tooling packages;
web-next/cms/storybook apps) and code examples drawn from the real auth
feature. Adds warning notes for known generator staleness — the
release-please per-feature registration that would collide with the
root-only v* tag policy, the pre-shipped trace overwrite hazard (zod
incident, restored in e4a3b65), the trpc template's removed
@trpc/react-query dep — and records the accepted warn-severity lint
backlog (~93 findings).

Per story amendments, the same slice prunes the dead "web-tanstack"
member from core-shared's app-tag unions (bind-otel-instrumentation.ts,
sentry/init-client.ts; tests retargeted to "web-next") and fixes the
stale app/feature tag lists in docs/architecture/overview.md. A warning
comment mirrors the release-please note at the generator call site; no
functional generator changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016j8z4VHjedXDTjEDNg7qHK
This commit is contained in:
2026-07-12 21:06:38 +02:00
parent d7534b9926
commit 46250c819f
8 changed files with 220 additions and 139 deletions

View File

@@ -76,7 +76,7 @@ const wrapped = withSpan(
**`sentry/init-server.ts` + `sentry/init-client.ts`:** centralized init helpers (Next.js flavor). `init-server.ts` calls `Sentry.init` with `sendDefaultPii: false` (R31) — no `beforeSend` hook (PII scrubbed at OTel layer). `init-client.ts` retains `beforeSend`/`beforeSendTransaction` because browser does not use the OTel pipeline.
**`sentry/init-server-node.ts` + `sentry/init-client-react.ts`:** Vite/non-Next variants used by `apps/web-tanstack`. Same posture as their Next.js counterparts.
**`sentry/init-server-node.ts` + `sentry/init-client-react.ts`:** Vite/non-Next variants — no app consumes them since `apps/web-tanstack` was deleted (ADR-027 retrofit); kept for a future Vite/React runtime. Same posture as their Next.js counterparts.
**`di/bind-noop-instrumentation.ts` + `bind-otel-instrumentation.ts`:** bind ITracer + ILogger + IMetrics symbols to a Container. Returns the resolved instances so callers can use them without container lookup. `bindSentryInstrumentation` kept as a deprecated alias for one release.
@@ -87,8 +87,8 @@ const wrapped = withSpan(
- `./instrumentation/otel/init-server-node``initOtelServerNode` (app bootstrap, server-side OTel SDK)
- `./instrumentation/sentry/init-server` — Next.js server Sentry.init helper
- `./instrumentation/sentry/init-client` — Next.js browser Sentry.init helper
- `./instrumentation/sentry/init-server-node``@sentry/node` server init (TanStack Start)
- `./instrumentation/sentry/init-client-react``@sentry/react` browser init (TanStack Start)
- `./instrumentation/sentry/init-server-node``@sentry/node` server init (Vite/non-Next runtimes; currently unconsumed)
- `./instrumentation/sentry/init-client-react``@sentry/react` browser init (Vite/non-Next runtimes; currently unconsumed)
**Boundaries:**

View File

@@ -8,7 +8,7 @@ import type { ITracer, ILogger, IMetrics } from "../index";
export type BindOtelOpts = {
dsn: string;
app: "web-next" | "cms" | "web-tanstack";
app: "web-next" | "cms";
release?: string;
};
@@ -16,8 +16,8 @@ export type BindOtelOpts = {
* Binds OtelTracer, OtelLogger, and OtelMetrics to the DI container.
*
* NOTE: The OTel NodeSDK is NOT initialized here. It is initialized by each
* app's instrumentation.ts `register()` hook (Next.js convention / server-entry
* hook for TanStack) so that PII scrub processors are active before the very
* app's instrumentation.ts `register()` hook (Next.js convention) so that
* PII scrub processors are active before the very
* first request handler runs — before bindAll() fires. Calling initOtelServerNode
* here as well would create a second SDK init path and reintroduce the startup
* window vulnerability (C1 fix).
@@ -41,8 +41,14 @@ export function bindOtelInstrumentation(
if (container.isBound(INSTRUMENTATION_SYMBOLS.METRICS)) {
container.unbind(INSTRUMENTATION_SYMBOLS.METRICS);
}
container.bind<ITracer>(INSTRUMENTATION_SYMBOLS.TRACER).toConstantValue(tracer);
container.bind<ILogger>(INSTRUMENTATION_SYMBOLS.LOGGER).toConstantValue(logger);
container.bind<IMetrics>(INSTRUMENTATION_SYMBOLS.METRICS).toConstantValue(metrics);
container
.bind<ITracer>(INSTRUMENTATION_SYMBOLS.TRACER)
.toConstantValue(tracer);
container
.bind<ILogger>(INSTRUMENTATION_SYMBOLS.LOGGER)
.toConstantValue(logger);
container
.bind<IMetrics>(INSTRUMENTATION_SYMBOLS.METRICS)
.toConstantValue(metrics);
return { tracer, logger, metrics };
}

View File

@@ -28,14 +28,14 @@ describe("initSentryClientReact", () => {
});
it("calls SentryReact.init with sendDefaultPii: false", () => {
initSentryClientReact({ dsn: "https://x@y/1", app: "web-tanstack" });
initSentryClientReact({ dsn: "https://x@y/1", app: "web-next" });
const call = (SentryReact.init as ReturnType<typeof vi.fn>).mock
.calls[0]![0] as Record<string, unknown>;
expect(call["sendDefaultPii"]).toBe(false);
});
it("attaches replay integration with mask flags", () => {
initSentryClientReact({ dsn: "https://x@y/1", app: "web-tanstack" });
initSentryClientReact({ dsn: "https://x@y/1", app: "web-next" });
expect(replayIntegration).toHaveBeenCalledTimes(1);
const replayOpts = (replayIntegration as ReturnType<typeof vi.fn>).mock
.calls[0]![0] as Record<string, unknown>;
@@ -45,7 +45,7 @@ describe("initSentryClientReact", () => {
});
it("defaults replay sample rates", () => {
initSentryClientReact({ dsn: "https://x@y/1", app: "web-tanstack" });
initSentryClientReact({ dsn: "https://x@y/1", app: "web-next" });
const call = (SentryReact.init as ReturnType<typeof vi.fn>).mock
.calls[0]![0] as Record<string, unknown>;
expect(call["replaysSessionSampleRate"]).toBe(0.0);
@@ -53,7 +53,7 @@ describe("initSentryClientReact", () => {
});
it("attaches beforeSend + beforeSendTransaction scrubbers", () => {
initSentryClientReact({ dsn: "https://x@y/1", app: "web-tanstack" });
initSentryClientReact({ dsn: "https://x@y/1", app: "web-next" });
const call = (SentryReact.init as ReturnType<typeof vi.fn>).mock
.calls[0]![0] as Record<string, unknown>;
expect(typeof call["beforeSend"]).toBe("function");
@@ -61,19 +61,19 @@ describe("initSentryClientReact", () => {
});
it("is a no-op when dsn is missing", () => {
initSentryClientReact({ dsn: "", app: "web-tanstack" });
initSentryClientReact({ dsn: "", app: "web-next" });
expect(SentryReact.init).not.toHaveBeenCalled();
});
it("attaches feedbackIntegration when SentryReact.feedbackIntegration is available", () => {
initSentryClientReact({ dsn: "https://x@y/1", app: "web-tanstack" });
initSentryClientReact({ dsn: "https://x@y/1", app: "web-next" });
expect(feedbackIntegration).toHaveBeenCalledTimes(1);
});
it("passes styleNonce and scriptNonce to feedbackIntegration when nonce provided", () => {
initSentryClientReact({
dsn: "https://x@y/1",
app: "web-tanstack",
app: "web-next",
nonce: "abc123",
});
const feedbackOpts = (feedbackIntegration as ReturnType<typeof vi.fn>).mock
@@ -83,7 +83,7 @@ describe("initSentryClientReact", () => {
});
it("omits nonce props from feedbackIntegration when nonce not provided", () => {
initSentryClientReact({ dsn: "https://x@y/1", app: "web-tanstack" });
initSentryClientReact({ dsn: "https://x@y/1", app: "web-next" });
const feedbackOpts = (feedbackIntegration as ReturnType<typeof vi.fn>).mock
.calls[0]![0] as Record<string, unknown>;
expect(feedbackOpts["styleNonce"]).toBeUndefined();

View File

@@ -1,5 +1,6 @@
// packages/core-shared/src/instrumentation/sentry/init-client-react.ts
// Browser-side Sentry init for Vite/React runtimes (TanStack Start). PII scrubbing is
// Browser-side Sentry init for Vite/React runtimes (currently unconsumed —
// kept for a future non-Next runtime). PII scrubbing is
// applied via beforeSend/beforeSendTransaction because browser does NOT use the OTel pipeline.
// PII field lists imported from otel/pii-fields.ts (vendor-neutral).
import * as SentryReact from "@sentry/react";
@@ -64,7 +65,7 @@ function scrubUrl(url: string): string {
}
/**
* Client-side init for non-Next.js (Vite/React) runtimes (TanStack Start).
* Client-side init for non-Next.js (Vite/React) runtimes.
* Mirrors init-client.ts but uses @sentry/react directly. Same PII,
* replay, and scrubbing requirements apply.
*/

View File

@@ -14,7 +14,7 @@ import {
export type InitClientOpts = {
dsn: string | undefined;
app: "web-next" | "cms" | "web-tanstack";
app: "web-next" | "cms";
release?: string;
nonce?: string;
};