## Lesson — Hook stderr diagnostics use script-identifier prefix, not

**Tags:** review-guidance, hooks, stderr, error-handling, graceful-degradation, adr-090

**Applies-to:** infrastructure

**Hook stderr diagnostics use script-identifier prefix, not `[Totem Error]`.** Session-start hooks (`.claude/hooks/*.js`, `.gemini/hooks/*.js`) and hook helpers (`packages/cli/src/hooks/auto-context.ts`) follow a two-tier convention for stderr output: degradation/diagnostic `process.stderr.write` calls use `[<hook-name>]` (e.g., `[auto-context]`, `[session-context]`) as the prefix; only explicitly-constructed thrown `Error` objects carry the `[Totem Error]` prefix per styleguide §3. The script-identifier pattern is canonical at `packages/cli/src/hooks/auto-context.ts:149, :160, :175, :189` — production-grade hook helper code that has been live since the auto-context feature shipped. **Do not suggest swapping `[<hook-name>]` to `[Totem Error]` on raw stderr writes**; §3's guidance governs thrown errors, not degradation diagnostics.

**Throwing in session-start hook catch blocks defeats the design intent.** Session-start hooks terminate with an outer `process.exit(0)` catch by design — they MUST NOT crash session boot. Inner catch blocks that `process.stderr.write` and continue allow partial context to be built when one read path fails (e.g., proposals fails but vector-context still runs). Suggesting `throw new Error(...)` in inner catches short-circuits subsequent context-building and reduces signal to the user. §9 line 112's "Defense-in-depth guards… use `log.warn()` + counter increments, NOT `throw`. The design intent is resilient continuation, not fail-fast" governs the same principle for raw `process.stderr.write` even though the medium differs from `log.warn()`. Both styleguide §6 carve-out and this lesson exist to prevent re-litigation in future review cycles.

**Reproduction:** `mmnto-ai/totem#1823` R1 (GCA, 2026-05-05) — flagged 3 stderr.write call sites in `.claude/hooks/session-context.mjs` for both prefix-swap and throw-instead-of-write. Empirical decline grounding: `auto-context.ts:149` precedent + the file's own `process.exit(0)` outer catch + §9 line 112 (resilient continuation). Substrate-update path closed via `.gemini/styleguide.md` §6 entry.

**Source:** mcp (added at 2026-05-05T04:01:49.847Z)
