{ "testIds": [ "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback does not retry on non-OOM errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback does not retry when already using u2net", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback fires progress callback on fallback retry", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback propagates error if fallback also fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback retries with fallback when no model is specified (default)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback retries with u2net when OOM is detected", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback throws when OOM fallback succeeds at bridge level but Python returns success: false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback uses 300000ms timeout for the u2net fallback attempt", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground OOM fallback uses fallback error message when OOM fallback returns success: false without error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground edge cases handles missing width and height from metadata", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground edge cases passes backgroundColor option in args JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground edge cases propagates readFile error after successful Python run", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground edge cases propagates segfault from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground error handling propagates bridge timeout errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground error handling propagates sharp conversion errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground error handling throws fallback error when success: false and no error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground error handling throws when Python returns success: false with custom error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground image downscaling calls resize when longest edge exceeds 2048px", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground image downscaling constrains by height when portrait orientation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground image downscaling does not call resize when image is within limit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground image downscaling does not upscale mask when image was not downscaled", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground image downscaling upscales mask back to original dimensions after processing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground onProgress forwarding passes onProgress callback through to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground onProgress forwarding passes undefined onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization calls remove_bg.py with input path, output path, and options JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization converts input to PNG via sharp before writing to disk", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization serializes all post-processing options together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization serializes backgroundColor option into the args JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization serializes both model and backgroundColor together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization serializes decontaminate option into the args JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization serializes edgeRefine option into the args JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization serializes model option into the args JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization uses unique UUID in temp file names to prevent collisions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground request serialization writes input to system tmpdir, output to outputDir", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground response parsing passes stdout through parseStdoutJson", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground response parsing reads the output file and returns its buffer on success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground temp file cleanup cleans up both input and output temp files on success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground temp file cleanup cleans up temp files when Python returns failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground temp file cleanup cleans up temp files when bridge rejects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground temp file cleanup does not throw if unlink fails (swallows cleanup errors)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground timeout calculation scales timeout with megapixels for large images", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground timeout calculation uses 300000ms base timeout for non-birefnet models", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground timeout calculation uses 600000ms base timeout for birefnet models", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground timeout calculation uses 600000ms base timeout for birefnet-massive model", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/background-removal.test.ts > removeBackground timeout calculation uses default 300000ms base when model is not specified", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - PROCESSING_TIMEOUT_S env for dispatcher path ignores negative PROCESSING_TIMEOUT_S and uses default 600s", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - PROCESSING_TIMEOUT_S env for dispatcher path ignores zero PROCESSING_TIMEOUT_S and uses default 600s", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - PROCESSING_TIMEOUT_S env for dispatcher path uses PROCESSING_TIMEOUT_S for dispatcher requests when no explicit timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - PYTHON_VENV_PATH env handling passes PYTHON_VENV_PATH through to env when set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - PYTHON_VENV_PATH env handling uses custom PYTHON_VENV_PATH when set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - buildMinimalEnv LANG fallback defaults LANG to C.UTF-8 when LANG is not set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - buildMinimalEnv LANG fallback passes through LANG when set in parent env", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - concurrent dispatcher requests with timeouts one request timing out does not prevent other requests from resolving", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher crash retry annotation appends retry annotation to stderr when dispatcher crashes and per-request succeeds", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher crash retry annotation does not retry per-request for non-crash errors (e.g. timeout)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher error event extracts error for pending requests dispatcher error with non-ENOENT code rejects pending requests with extracted error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher malformed stdout responses handles response where exitCode is missing (treated as undefined !== 0)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher malformed stdout responses ignores response with valid JSON but missing id field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher malformed stdout responses ignores truncated JSON on stdout and processes next valid response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stderr interleaving with stdout responses handles empty lines in stderr between valid progress events", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stderr interleaving with stdout responses handles multiple progress events interleaved between two responses", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stderr interleaving with stdout responses handles stderr arriving between split stdout response chunks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stderr non-progress JSON does not invoke onProgress for JSON with progress as string type", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stderr non-progress JSON does not invoke onProgress for JSON with stage as number type", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stderr non-progress JSON handles ready=true signal after dispatcher was already ready (idempotent)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stdin error suppression does not crash when stdin emits an error event", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stdin write failure falls back to per-request after dispatcher stdin write failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher stdin write failure retries per-request when dispatcher stdin.write throws", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - dispatcher timeout recovery timeout kills the dispatcher so subsequent requests can restart it", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - env passthrough for sidecar-specific vars does not include unset vars in subprocess env", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - env passthrough for sidecar-specific vars passes DATA_DIR to subprocess", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - env passthrough for sidecar-specific vars passes DISPATCHER_MAX_REQUESTS to subprocess", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - env passthrough for sidecar-specific vars passes U2NET_HOME to subprocess", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - extractPythonError uncovered branches extracts error from stderr JSON with error field on non-zero exit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - extractPythonError uncovered branches extracts error from stdout JSON when stderr is empty on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - extractPythonError uncovered branches extracts non-traceback stderr as plain text error on non-zero exit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - extractPythonError uncovered branches uses message field when error object has only message property", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - graceful shutdown during active requests shutdown during active request triggers SIGTERM and the request retries per-request", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - graceful shutdown during active requests shutdown with multiple active requests causes all to retry", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - initDispatcher additional edge cases handles concurrent initDispatcher calls -- both resolve with same result", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - initDispatcher additional edge cases resolves with ready=false when getDispatcher returns null during backoff", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases handles JSON with backslash in path values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases handles JSON with boolean false and empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases handles JSON with curly braces inside string values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases handles JSON with newline characters in string values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases handles JSON with tab characters in string values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases handles JSON with zero/negative number values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases throws on stdout containing brace pair with invalid content", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - parseStdoutJson additional boundary cases throws on stdout containing only opening brace", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - per-request ENOENT retry with non-ENOENT fallback error venv ENOENT triggers python3 fallback, non-ENOENT on fallback rejects directly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge-extended.test.ts > bridge - per-request stderr buffer flush on error exit includes partial stderr buffer in error when process exits non-zero", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - backoff prevents restart during cooldown second crash has 2x the backoff delay of the first crash", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - concurrent dispatcher requests dispatcher crash rejects all pending concurrent requests with retry", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - concurrent dispatcher requests one failing request does not affect other concurrent requests", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - concurrent dispatcher requests progress events on stderr are forwarded to all pending requests", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - concurrent dispatcher requests sends multiple concurrent requests to the same dispatcher process", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - crash recovery resets on successful readiness resets consecutiveCrashes to 0 when dispatcher becomes ready", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher error event handling ENOENT error permanently disables the dispatcher", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher error event handling non-ENOENT dispatcher error increments crash counter and clears dispatcher state", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher error event handling non-ENOENT error records a crash but does not permanently disable", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress concurrent requests to per-request fallback both resolve", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress dispatcher close event rejects all pending requests", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress dispatcher progress events are forwarded to pending request callbacks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress dispatcher ready signal sets dispatcherReady and processes requests via dispatcher", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress dispatcher ready signal with GPU=false sets gpu to false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress dispatcher stderr collects non-JSON non-bracket lines as error output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress dispatcher stderr routes diagnostic messages with bracket prefix to logger", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress does not count exit code 0 as a crash (normal MAX_REQUESTS restart)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress falls back to per-request spawn when dispatcher ENOENT marks it failed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress getDispatcherStatus reflects consecutiveCrashes after dispatcher crashes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress graceful shutdown does not throw when dispatcher already exited", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress handles dispatcher crash followed by successful per-request retry", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress per-request fallback retries with python3 when venv python fails with ENOENT", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress reports failed status when dispatcher ENOENT occurs", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress shutdown is idempotent when called multiple times", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress still counts non-zero exit codes as crashes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher lifecycle via runPythonWithProgress timeout rejects the promise without affecting other requests", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher request timeout kills the dispatcher on timeout so subsequent requests can proceed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher request timeout rejects with timeout when dispatcher does not respond within timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher shutdown behavior calls kill(SIGTERM) on the dispatcher process", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher shutdown behavior calls stdin.end() before killing the process", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher shutdown behavior does not change GPU status after shutdown (isGpuAvailable returns module-level state)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher shutdown behavior sets status to not running and not ready after shutdown", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stderr partial buffering buffers partial JSON progress lines across stderr chunks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stderr partial buffering does not fire progress for partial JSON that is not yet complete", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stderr partial buffering handles multiple complete lines in a single stderr chunk", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stderr partial buffering handles readiness signal split across stderr chunks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol collects stderr lines and returns them with the response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol generates a unique UUID id for each request", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol handles chunked stdout responses split across data events", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol ignores stdout lines that are not valid JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol ignores stdout responses with unknown request IDs", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol rejects the correct request when dispatcher returns non-zero exitCode", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol rejects with OOM message when dispatcher response has exitCode 137", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol rejects with segfault message when dispatcher response has exitCode 139", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol returns empty stdout when dispatcher response omits stdout field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol routes responses by ID to the correct pending request", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol strips .py extension from script name in dispatcher request", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdin JSON-RPC protocol writes a JSON-line with id, script (without .py), and args to dispatcher stdin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdout partial line buffering handles dispatcher response split across 3 or more stdout chunks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - dispatcher stdout partial line buffering handles two complete responses in a single stdout data event", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - extractPythonError coverage via per-request path extracts error from JSON on stdout when non-zero exit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - extractPythonError coverage via per-request path extracts last meaningful line from traceback when error is only in stderr", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - extractPythonError coverage via per-request path returns generic exit code message when stderr has only the traceback header", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - extractPythonError via dispatcher responses extracts error from JSON stdout in dispatcher response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - extractPythonError via dispatcher responses extracts error from traceback in dispatcher stderr", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - extractPythonError via dispatcher responses uses generic exit code message when dispatcher stderr and stdout are both empty", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - getDispatcherStatus returns initial state with no dispatcher running", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher edge cases resolves with ready=false when dispatcher fails during init timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher edge cases returns ready=false immediately when dispatcher already permanently failed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher edge cases returns ready=false when spawn throws synchronously", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher is idempotent -- second call returns same result without respawning", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher resolves with gpu=false when dispatcher reports no GPU", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher resolves with ready=false after timeout when dispatcher never signals ready", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher resolves with ready=false when dispatcher fails with ENOENT", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - initDispatcher resolves with ready=true and gpu status after dispatcher emits readiness", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - isGpuAvailable returns false by default (no dispatcher started)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - max consecutive crash threshold after reaching crash threshold, subsequent requests go directly to per-request path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - max consecutive crash threshold does not reach threshold when fewer than 5 crashes occur", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - max consecutive crash threshold resets crash counter outside the 60s crash window", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - max consecutive crash threshold sets dispatcherFailed after 5 consecutive crashes within the crash window", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - max consecutive crash threshold uses exponential backoff delay between crash restarts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions handles JSON preceded by ANSI escape codes in stdout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions handles JSON with empty arrays and nested empty objects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions handles JSON with empty object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions handles JSON with escaped quotes in string values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions handles JSON with negative numbers", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions handles JSON with only whitespace before the object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions handles JSON with very long string values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson boundary conditions throws on truncated JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson edge cases extracts JSON that follows multiple non-JSON log lines", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson edge cases handles JSON with array values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson edge cases handles JSON with boolean and null values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson edge cases handles JSON with numeric values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson edge cases handles JSON with unicode characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson edge cases handles deeply nested JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson edge cases throws on stdout that is only whitespace", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson extracts JSON from stdout with leading progress lines", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson extracts JSON object from clean stdout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson extracts JSON with special characters in string values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson handles multiline JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson matches greedily from first brace to last brace", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson throws on empty stdout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson throws when JSON is malformed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson throws when multiple JSON objects produce invalid merged JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - parseStdoutJson throws when stdout contains no JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - per-request fallback edge cases does not invoke onProgress for JSON stderr that lacks progress field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - per-request fallback edge cases does not invoke onProgress for JSON stderr that lacks stage field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - per-request fallback edge cases handles empty stdout with successful exit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - per-request fallback edge cases handles large stdout that arrives in many small chunks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - per-request fallback edge cases handles stderr that mixes progress JSON and regular text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - per-request fallback edge cases per-request stderr JSON with only progress is not collected as error output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) accumulates multiple stderr chunks into a single string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) does not invoke onProgress for JSON without progress field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) does not invoke onProgress for non-JSON stderr lines", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) extracts error from JSON stderr when Python writes structured errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) extracts last line from Python traceback on non-zero exit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) flushes partial stderr buffer on process close", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) handles chunked stdout data arriving in multiple events", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) handles stderr output that is not JSON (regular log lines)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) ignores empty stderr lines during progress parsing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) ignores invalid PROCESSING_TIMEOUT_S values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) includes exit code in error when no signal and no stderr", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) invokes onProgress callback for JSON progress lines on stderr", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) passes script path and args to spawn correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) rejects when spawn emits ENOENT error and fallback also fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) rejects with OOM message on exit code 137 (SIGKILL)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) rejects with error message on non-zero exit code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) rejects with segfault message on exit code 139 (SIGSEGV)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) rejects with timeout error when process exceeds timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) resolves with stdout/stderr on successful exit (code 0)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) treats SIGKILL signal as OOM error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) treats SIGSEGV signal as segfault error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - runPythonWithProgress (per-request fallback) uses PROCESSING_TIMEOUT_S env var when set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/bridge.test.ts > bridge - shutdownDispatcher does not throw when no dispatcher is running", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize edge cases handles zero width and height in response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize edge cases passes empty options as empty JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize error handling propagates bridge rejection", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize error handling throws fallback error when success: false and no error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize error handling throws when Python returns success: false with custom error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize onProgress forwarding passes onProgress callback to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize request serialization calls colorize.py with input path, output path, and options JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize request serialization converts input to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize request serialization serializes both intensity and model together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize request serialization serializes intensity option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize request serialization serializes model option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize response parsing defaults method to 'unknown' when not provided by Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize response parsing preserves width and height from Python response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize response parsing reads from alternate output_path when provided by Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize response parsing reads from default output path when output_path not in response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize response parsing returns ColorizeResult with buffer, width, height, and method", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/colorization.test.ts > colorize sharp conversion errors propagates sharp toBuffer error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces error handling propagates OOM errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces request serialization calls detect_faces.py with correct file paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces request serialization converts input to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces request serialization serializes blurRadius option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces request serialization serializes both blurRadius and sensitivity", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces request serialization serializes sensitivity option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces response parsing defaults faces to empty array when field absent from response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces response parsing reads the output file for the blurred image", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces response parsing returns BlurFacesResult with multiple face regions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > blurFaces response parsing returns empty faces array when none detected", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces edge cases converts input to PNG before writing to tmpdir", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces edge cases propagates sharp conversion errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces edge cases propagates writeFile errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces error handling propagates OOM errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces error handling propagates segfault error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces error handling throws fallback error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces request serialization calls detect_faces.py with detectOnly: true", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces request serialization merges user sensitivity with detectOnly flag", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces request serialization passes 'unused' as the output path argument", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces request serialization writes input to tmpdir", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces response parsing defaults faces to empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces response parsing returns DetectFacesResult without a buffer property", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces temp file cleanup cleans up temp file when bridge rejects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces temp file cleanup cleans up temp input file after failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-detection.test.ts > detectFaces temp file cleanup cleans up temp input file after success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces edge cases handles response with zero facesDetected and non-empty faces array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces edge cases propagates segfault errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces error handling propagates OOM errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces request serialization calls enhance_faces.py with correct file paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces request serialization converts input to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces request serialization serializes all options together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces request serialization serializes model option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces request serialization serializes onlyCenterFace option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces request serialization serializes sensitivity option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces request serialization serializes strength option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces response parsing defaults faces to empty array when absent from response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces response parsing defaults model to 'unknown' when absent from response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces response parsing reads the enhanced output file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces response parsing returns EnhanceFacesResult with all fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces response parsing returns multiple face regions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-enhancement.test.ts > enhanceFaces sharp conversion errors propagates sharp toBuffer error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks edge cases handles faceDetected true with missing landmarks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks edge cases propagates segfault from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks edge cases uses timestamps in temp file names", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks error handling propagates OOM errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks request serialization calls face_landmarks.py with input path, 'unused', and '{}'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks request serialization converts input buffer to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks request serialization writes to system tmpdir", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing defaults imageHeight to 0 when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing defaults imageWidth to 0 when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing defaults landmarks to null when field is absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing returns all landmark points when face is detected", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing returns both dimensions as 0 when both absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing returns imageWidth and imageHeight from response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing returns individual landmark points correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks response parsing returns null landmarks when no face detected", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks temp file cleanup cleans up temp input file after success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks temp file cleanup cleans up temp input file when Python returns failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks temp file cleanup cleans up temp input file when bridge rejects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/face-landmarks.test.ts > detectFaceLandmarks temp file cleanup does not throw if unlink fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough always includes PYTHONUNBUFFERED=1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough does not include SNAPOTTER_GPU when not set in parent env", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough does not leak unrelated env vars to Python subprocess", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough does not pass MODELS_DIR (removed dead entry)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough passes CUDA_VISIBLE_DEVICES when set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough passes LD_LIBRARY_PATH when set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough passes MODELS_PATH to Python subprocess", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/gpu-detection.test.ts > buildMinimalEnv - env passthrough passes SNAPOTTER_GPU to Python subprocess", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint edge cases propagates readFile error after successful Python run", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint edge cases propagates segfault from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint edge cases propagates writeFile error when writing input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint error handling propagates bridge OOM", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint error handling propagates sharp conversion errors on input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint request serialization calls inpaint.py with input, mask, and output paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint request serialization converts both input and mask to PNG via sharp", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint request serialization does not pass any options argument (only 3 args)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint request serialization writes both input and mask files to disk", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint response parsing reads from the correct output path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint response parsing returns output buffer on success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/inpainting.test.ts > inpaint sharp conversion errors propagates sharp error on mask conversion", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval edge cases handles zero dimensions from metadata", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval edge cases propagates readFile error after successful Python run", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval edge cases propagates segfault from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval error handling propagates OOM errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval parseStdoutJson error propagation propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization calls noise_removal.py with correct file paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization converts input to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization serializes all options together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization serializes colorNoise option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization serializes detailPreservation option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization serializes format and quality options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization serializes strength option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval request serialization serializes tier option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval response parsing defaults format to 'png' when absent from response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval response parsing defaults tier from Python response when present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval response parsing falls back to 'balanced' when both Python and options omit tier", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval response parsing falls back to options tier when Python omits it", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval response parsing reads from alternate output_path when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval response parsing reads from default output path when output_path not in response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval response parsing returns NoiseRemovalResult with all fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval sharp conversion converts input to PNG and writes to outputDir", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval sharp conversion propagates sharp toBuffer error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval timeout calculation scales timeout for large images using megapixels * 120000", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval timeout calculation uses metadata from the PNG-converted buffer for timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/noise-removal.test.ts > noiseRemoval timeout calculation uses minimum 300000ms timeout for small images", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText edge cases handles zero dimensions from metadata for timeout calculation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText edge cases passes empty options as empty JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText edge cases propagates segfault from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText error handling propagates OOM errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText image downscaling caps input to 2048px using resize with inside fit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText multiline and unicode text handles multiline OCR text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText multiline and unicode text handles unicode text from CJK languages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization calls ocr.py with input path and options JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization resizes input to max 2048px before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization serializes all options together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization serializes deprecated engine option for backward compatibility", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization serializes enhance option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization serializes language option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization serializes quality option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText request serialization writes resized PNG to outputDir", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText response parsing returns OcrResult with text and engine", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText response parsing returns empty text string when no text detected", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText response parsing returns engine information", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText response parsing returns text with special characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText response parsing returns undefined engine when not provided by Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText sharp conversion errors propagates sharp conversion errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText timeout calculation scales timeout for large images", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ocr.test.ts > extractText timeout calculation uses minimum 600000ms timeout for small images", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint edge cases handles zero extension on all sides", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint edge cases propagates readFile error after successful Python run", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint error handling propagates bridge OOM", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint error handling propagates sharp conversion error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint module exports accepts a valid OutpaintOptions object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint module exports exports outpaint as a function", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint request serialization calls outpaint.py with input, output, and extension args", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint request serialization converts input to PNG via sharp", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint request serialization passes 'fast' tier value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint request serialization passes custom tier value instead of default 'balanced'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint request serialization writes input file to disk", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint response parsing reads from the correct output path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/outpaint.test.ts > outpaint response parsing returns output buffer on success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye edge cases passes empty options as empty JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye edge cases propagates readFile error after successful Python run", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye error handling propagates OOM errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye error handling propagates bridge segfault", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye request serialization calls red_eye_removal.py with correct file paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye request serialization converts input to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye request serialization serializes all options together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye request serialization serializes format and quality options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye request serialization serializes sensitivity option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye request serialization serializes strength option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing defaults eyesCorrected to 0 when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing defaults facesDetected to 0 when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing defaults format to 'png' when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing handles multiple faces with multiple corrections", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing reads from alternate output_path when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing reads from default output path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing reports zero corrections when no red eyes found", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye response parsing returns RedEyeRemovalResult with all fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/red-eye-removal.test.ts > removeRedEye sharp conversion errors propagates sharp toBuffer error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto edge cases handles single-step restoration pipeline", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto edge cases passes empty options as empty JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto edge cases propagates readFile error after successful Python run", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto edge cases propagates segfault from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto error handling propagates OOM errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization calls restore.py with correct file paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization converts input to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization serializes all options together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization serializes colorize option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization serializes colorizeStrength option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization serializes denoise and denoiseStrength options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization serializes faceEnhancement option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization serializes fidelity option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto request serialization serializes scratchRemoval option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing defaults colorized to false when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing defaults facesEnhanced to 0 when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing defaults isGrayscale to false when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing defaults scratchCoverage to 0 when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing defaults steps to empty array when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing preserves multi-step restoration pipeline info", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing reads from alternate output_path when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing reads from default output path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto response parsing returns RestorePhotoResult with all fields populated", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/restoration.test.ts > restorePhoto sharp conversion errors propagates sharp toBuffer error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve accepts 75% reduction exactly (ratio = 0.25)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve always passes -preview=false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve caches the caire binary path after first discovery", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve cleans up temp files even when image is too large", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve cleans up temp files on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve cleans up temp files on success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve does not pass -blur and -sobel when not specified", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve does not pass -face when protectFaces is false or absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve does not pass width/height args when not specified", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve falls back to default caire when CAIRE_PATH is not set and caire is in PATH", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve handles zero dimensions from metadata gracefully", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve includes megapixels in the too-large error message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve passes blurRadius and sobelThreshold options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve passes only height when width is not specified", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve passes only width when height is not specified", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve passes protectFaces option as -face flag", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve passes width and height args to caire", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve pre-resizes large image for square mode with small target", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve pre-resizes when height reduction exceeds 75%", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve pre-resizes when width reduction exceeds 75%", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve propagates readFile error when reading caire output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve propagates sharp jpeg conversion error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve propagates sharp metadata error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve propagates writeFile error when writing input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve returns SeamCarveResult with output dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve scales timeout based on megapixels", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve square mode uses shortest dimension for both width and height", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve throws when caire binary is not found", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve throws when image exceeds 25 MP", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve timeout is always an integer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve uses CAIRE_PATH env var when set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve uses default width and height when no options are specified", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve uses square mode with shortest side", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve uses unique UUID in temp file names to prevent collisions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/seam-carving.test.ts > seamCarve writes JPEG input and reads PNG output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_CSS_URL_RE does NOT match data: CSS url()", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_CSS_URL_RE matches @import with bare URL", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_CSS_URL_RE matches @import with double-quoted URL", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_CSS_URL_RE matches @import with single-quoted URL", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_CSS_URL_RE matches double-slash CSS url()", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_CSS_URL_RE matches single-slash CSS url()", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE does NOT match data: URIs", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE does NOT match relative paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE matches double-slash http img", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE matches double-slash https img", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE matches formaction attribute", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE matches poster attribute", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE matches single-slash http img (pandoc rewrite)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE matches single-slash https img", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/ssrf-prescan-regex.test.ts > SSRF pre-scan regexes (doc_html_pdf.py) _REMOTE_REF_RE matches srcset attribute", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OCR dynamic timeout uses megapixel-based timeout for large images", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through blurFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through colorize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through detectFaceLandmarks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through detectFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through enhanceFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through inpaint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through noiseRemoval", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through removeRedEye", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > OOM propagation through all tools propagates OOM through restorePhoto", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > alternate output_path from Python noiseRemoval reads from alternate output_path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > alternate output_path from Python removeRedEye reads from alternate output_path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > alternate output_path from Python restorePhoto reads from alternate output_path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > alternate output_path from Python upscale reads from alternate output_path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > blurFaces calls runPythonWithProgress with detect_faces.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > blurFaces passes blur options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > blurFaces returns BlurFacesResult with face regions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > blurFaces returns empty faces array when none detected", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > blurFaces throws when detection fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > colorize calls runPythonWithProgress with colorize.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > colorize passes intensity option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > colorize reads from alternate output_path when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > colorize returns ColorizeResult with buffer and metadata", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > colorize throws when colorization fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > custom error messages from Python result blurFaces surfaces Python error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > custom error messages from Python result detectFaceLandmarks surfaces Python error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > custom error messages from Python result noiseRemoval surfaces Python error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > custom error messages from Python result removeBackground surfaces Python error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > custom error messages from Python result removeRedEye surfaces Python error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > custom error messages from Python result restorePhoto surfaces Python error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > custom error messages from Python result upscale surfaces Python error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > default values for optional response fields blurFaces defaults faces to empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > default values for optional response fields colorize defaults method to unknown", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > default values for optional response fields detectFaceLandmarks defaults imageWidth and imageHeight to 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > default values for optional response fields enhanceFaces defaults faces to empty array and model to unknown", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > default values for optional response fields noiseRemoval defaults format and tier from options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > default values for optional response fields removeRedEye defaults format to png", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaceLandmarks calls runPythonWithProgress with face_landmarks.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaceLandmarks cleans up temp file even on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaceLandmarks cleans up temp file in finally block", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaceLandmarks converts input buffer to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaceLandmarks returns FaceLandmarksResult with all landmark points", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaceLandmarks returns null landmarks when no face detected", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaces calls runPythonWithProgress with detectOnly option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaces cleans up temp input file after failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaces cleans up temp input file after success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > detectFaces returns DetectFacesResult without buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > enhanceFaces calls runPythonWithProgress with enhance_faces.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > enhanceFaces defaults model to unknown when not provided by Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > enhanceFaces passes enhancement options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > enhanceFaces returns EnhanceFacesResult with model info", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > enhanceFaces throws when enhancement fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates OOM errors through tool functions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates bridge rejection through tool functions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates segfault through detectFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through blurFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through detectFaceLandmarks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through enhanceFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through inpaint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through noiseRemoval", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through removeBackground", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through removeRedEye", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through restorePhoto", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > error propagation from bridge propagates timeout through upscale", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > extractText (OCR) calls runPythonWithProgress with ocr.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > extractText (OCR) passes quality and language options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > extractText (OCR) returns OcrResult with text and engine", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > extractText (OCR) throws when OCR fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > extractText (OCR) uses fallback error message when no error string provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent blurFaces uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent colorize uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent detectFaceLandmarks uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent detectFaces uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent enhanceFaces uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent noiseRemoval uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent removeBackground uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent removeRedEye uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent restorePhoto uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > fallback error messages when error string is absent upscale uses fallback message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > inpaint calls runPythonWithProgress with inpaint.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > inpaint returns the output buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > inpaint throws when inpainting fails", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > inpaint uses fallback error message when no error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > inpaint writes both input and mask files", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > noiseRemoval calls runPythonWithProgress with noise_removal.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > noiseRemoval defaults tier from options when Python omits it", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > noiseRemoval passes strength and tier options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > noiseRemoval returns NoiseRemovalResult with all fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > noiseRemoval throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding blurFaces forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding colorize forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding detectFaceLandmarks forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding detectFaces forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding enhanceFaces forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding inpaint forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding noiseRemoval forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding removeRedEye forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding restorePhoto forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > onProgress forwarding upscale forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization blurFaces passes empty options as empty JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization detectFaceLandmarks passes fixed unused and empty options args", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization detectFaces merges user options with detectOnly flag", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization noiseRemoval passes all option fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization removeBackground passes empty options as empty JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization removeRedEye passes format and quality options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization restorePhoto passes all option fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization upscale passes all option fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > option serialization upscale passes empty options as empty JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through blurFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through colorize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through detectFaceLandmarks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through detectFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through enhanceFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through extractText", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through inpaint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through noiseRemoval", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through removeBackground", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through removeRedEye", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through restorePhoto", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > parseStdoutJson throws in tool pipeline propagates parse error through upscale", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run blurFaces propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run colorize propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run enhanceFaces propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run inpaint propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run noiseRemoval propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run removeRedEye propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run restorePhoto propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > readFile errors after successful Python run upscale propagates readFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground calls runPythonWithProgress with remove_bg.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground cleans up temp files on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground cleans up temp files on success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground dynamic timeout uses megapixel-based timeout for large images", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground passes onProgress callback to runPythonWithProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground passes options as JSON string argument", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground returns the output buffer on success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground throws when Python returns success: false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeBackground uses higher timeout for birefnet models", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeRedEye calls runPythonWithProgress with red_eye_removal.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeRedEye defaults facesDetected and eyesCorrected to 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeRedEye passes sensitivity and strength options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeRedEye returns RedEyeRemovalResult with correction counts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > removeRedEye throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > restorePhoto calls runPythonWithProgress with restore.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > restorePhoto defaults optional fields when Python omits them", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > restorePhoto passes restoration options including scratch and colorize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > restorePhoto returns RestorePhotoResult with all metadata", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > restorePhoto throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through blurFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through colorize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through detectFaceLandmarks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through enhanceFaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through inpaint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through noiseRemoval", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through removeBackground", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through removeRedEye", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through restorePhoto", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > segfault propagation through all tools propagates segfault through upscale", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > temp file cleanup on bridge rejection detectFaceLandmarks cleans up temp file when bridge rejects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > temp file cleanup on bridge rejection detectFaces cleans up temp file when bridge rejects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > temp file cleanup on bridge rejection removeBackground cleans up when bridge rejects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > upscale calls runPythonWithProgress with upscale.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > upscale defaults method and format when not provided by Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > upscale passes scale and model options as JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > upscale reads from output_path when Python provides alternate path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > upscale returns UpscaleResult with dimensions and method", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > upscale throws when Python returns success: false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run blurFaces propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run colorize propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run detectFaceLandmarks propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run detectFaces propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run enhanceFaces propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run inpaint propagates writeFile error on input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run noiseRemoval propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run removeRedEye propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run restorePhoto propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/tools.test.ts > writeFile errors before Python run upscale propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio defensive parsing defaults language to en when missing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio defensive parsing defaults text to empty string when missing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio defensive parsing returns empty segments when segments field is missing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio defensive parsing returns empty segments when segments is not an array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio defensive parsing returns empty segments when segments is null", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio error handling propagates OOM errors from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio error handling throws when Python returns an error field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio request serialization always includes task: transcribe", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio request serialization calls transcribe.py with input path and options JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio request serialization serializes a specific language", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio request serialization uses 30 minute timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio response parsing returns detected language", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio response parsing returns language, text, and segments", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio segment key mapping defaults missing start/end to 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio segment key mapping defaults missing text to empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio segment key mapping maps python start/end to startS/endS", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/transcription.test.ts > transcribeAudio segment key mapping trims segment text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale edge cases passes empty options as empty JSON object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale edge cases propagates readFile error after successful Python run", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale edge cases propagates segfault from bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale edge cases propagates writeFile error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale error handling propagates OOM errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale error handling propagates bridge timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale error handling propagates parseStdoutJson errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale error handling throws fallback error when success: false without error string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale error handling throws with custom error from Python", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale onProgress forwarding omits onProgress when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale onProgress forwarding passes onProgress to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization calls upscale.py with correct file paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization converts input to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization serializes all options together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization serializes denoise option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization serializes faceEnhance option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization serializes format and quality options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization serializes model option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale request serialization serializes scale option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale response parsing defaults format to 'png' when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale response parsing defaults method to 'unknown' when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale response parsing reads from alternate output_path when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale response parsing reads from default output path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale response parsing returns UpscaleResult with all fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale response parsing returns correct dimensions for 4x upscale", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale sharp conversion errors propagates sharp toBuffer error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation defaults scale to 2 when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation handles zero dimensions from metadata gracefully", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation passes a timeout to runPythonWithProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation provides generous timeout for CPU upscale at high scale", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation scales timeout with image megapixels", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation scales timeout with scale factor squared", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation uses minimum timeout of 600s for small images", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/ai/upscaling.test.ts > upscale timeout calculation uses shorter timeout when GPU is available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > consent lifecycle simulations fresh -> accept immediately -> never show again", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > consent lifecycle simulations fresh -> decline immediately -> never show again", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > consent lifecycle simulations fresh -> maybe later -> remind time NOT yet passed -> stay hidden", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > consent lifecycle simulations fresh -> maybe later -> remind time passes -> show again -> accept", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > isConsentEnabled edge cases returns false when analyticsEnabled is false (explicitly declined)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > isConsentEnabled edge cases returns false when analyticsEnabled is null (never decided)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > isConsentEnabled edge cases returns false when server disabled even if user opted in", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > shouldShowConsent edge cases returns false when remindAt is 1ms in the future", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > shouldShowConsent edge cases returns false when server is disabled regardless of remindAt", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > shouldShowConsent edge cases returns true after 'Maybe later' and 7 days have passed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > shouldShowConsent edge cases returns true when remindAt is exactly equal to Date.now()", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent-extended.test.ts > shouldShowConsent edge cases returns true when remindAt is set but consentShownAt is null (defensive)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > isConsentEnabled returns false when server disabled", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > isConsentEnabled returns false when user has not consented", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > isConsentEnabled returns true when user opted in and server enabled", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > shouldShowConsent returns false when remind-at is in the future", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > shouldShowConsent returns false when server has analytics disabled", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > shouldShowConsent returns false when user already opted in", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > shouldShowConsent returns false when user explicitly declined", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > shouldShowConsent returns true for a fresh user who has never been asked", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-consent.test.ts > shouldShowConsent returns true when remind-at has passed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS AI_BUNDLE_ACTION has the correct snake_case value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS PIPELINE_EXECUTED has the correct snake_case value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS SEARCH has the correct snake_case value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS TOOL_USED has the correct snake_case value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS all event values are strings", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS all values are unique (no duplicate event names)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS all values follow snake_case convention", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS contains the expected keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS has exactly 4 event keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-events.test.ts > ANALYTICS_EVENTS is frozen (as const prevents mutation)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > AnalyticsConfig type accepts a config with analytics disabled", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > AnalyticsConfig type accepts a fully populated config object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > AnalyticsConfig type accepts fractional sample rates", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > AnalyticsConfig type has exactly the expected keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > ConsentState type accepts all-null state (fresh user)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > ConsentState type accepts declined state (analyticsEnabled = false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > ConsentState type accepts deferred state (maybe later with remindAt set)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > ConsentState type accepts mixed state with analyticsEnabled true and remindAt set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > ConsentState type accepts opted-in state (analyticsEnabled = true)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/analytics-types.test.ts > ConsentState type has exactly the expected keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - crash recovery ENOENT error permanently disables dispatcher", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - crash recovery applies exponential backoff between crash restarts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - crash recovery increments crash count on non-zero close", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - crash recovery marks dispatcher as permanently failed after max consecutive crashes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - crash recovery rejects all pending requests on dispatcher error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - crash recovery rejects pending requests when dispatcher closes unexpectedly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - crash recovery retries with per-request mode after dispatcher crash during request", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - getDispatcherStatus reports not running initially", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - getDispatcherStatus reports running after init", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - initDispatcher is idempotent when already ready", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - initDispatcher returns ready:false on timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - initDispatcher returns ready:false when dispatcher failed permanently", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - initDispatcher spawns python process with dispatcher.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - isGpuAvailable returns false when dispatcher has not started", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - isGpuAvailable returns false when dispatcher reports no GPU", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - isGpuAvailable returns true when dispatcher reports GPU", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - parseStdoutJson extracts JSON object from the end of stdout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - parseStdoutJson handles nested JSON objects", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - parseStdoutJson handles stdout that is only JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - parseStdoutJson throws on empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - parseStdoutJson throws when no JSON object is present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - progress event parsing collects non-JSON stderr as error context for failed requests", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - progress event parsing ignores non-JSON stderr lines (logs them, does not crash)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - progress event parsing readiness signal sets GPU status", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - progress event parsing routes JSON progress events from stderr to onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) clears timeout on successful response", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) extracts error from JSON stdout on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) handles concurrent requests matched by id", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) rejects on non-zero exit code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) rejects with timeout error and kills dispatcher", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) resolves with stdout and stderr", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) returns OOM message for exit code 137", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) returns segfault message for exit code 139", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) routes progress events to the onProgress callback", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) sends JSON-lines request to dispatcher stdin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) strips .py from script name in dispatcher request", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (dispatcher path) uses PROCESSING_TIMEOUT_S env var when set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (per-request fallback) falls back to per-request mode when dispatcher is not available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (per-request fallback) per-request SIGKILL maps to OOM message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (per-request fallback) per-request SIGSEGV maps to segfault message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (per-request fallback) per-request fallback tries system python3 on ENOENT", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (per-request fallback) per-request mode parses progress events on stderr", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (per-request fallback) per-request mode rejects on non-zero exit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - runPythonWithProgress (per-request fallback) per-request mode rejects on timeout", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - shutdownDispatcher is safe to call when no dispatcher is running", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - shutdownDispatcher kills the dispatcher process", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - shutdownDispatcher marks status as not running after shutdown", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-bridge.test.ts > AI Bridge - stdout buffering (partial JSON lines) handles response split across multiple chunks", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > blurFaces calls runPythonWithProgress with detect_faces.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > blurFaces defaults faces to empty array when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > blurFaces passes blur options in args", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > blurFaces returns buffer, facesDetected, and faces array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > blurFaces throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > colorize calls runPythonWithProgress with colorize.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > colorize defaults method to 'unknown' when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > colorize forwards onProgress callback", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > colorize passes options as JSON in args", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > colorize returns structured result with buffer, dimensions, and method", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > colorize throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > colorize uses output_path from result when available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > cross-cutting tool patterns all Python tools accept default empty options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > cross-cutting tool patterns all Python tools call parseStdoutJson on the result", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > cross-cutting tool patterns all Python tools convert input to PNG via sharp", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > cross-cutting tool patterns all Python tools propagate runPythonWithProgress errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks calls face_landmarks.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks cleans up temp file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks converts input buffer to PNG before writing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks defaults dimensions to 0 when absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks passes 'unused' as output path and empty JSON options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks returns landmarks result", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks returns null landmarks when no face found", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaceLandmarks throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaces cleans up temp file even on error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaces cleans up temp input file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaces merges sensitivity option", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaces passes 'unused' as outputPath arg", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaces passes detectOnly: true in options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > detectFaces returns facesDetected and faces without a buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > enhanceFaces calls enhance_faces.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > enhanceFaces defaults model to 'unknown'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > enhanceFaces passes all options through", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > enhanceFaces provides fallback error message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > enhanceFaces returns result with buffer, facesDetected, faces, and model", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > enhanceFaces throws on failure with specific error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > extractText (OCR) calculates timeout based on megapixels", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > extractText (OCR) calls ocr.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > extractText (OCR) passes options as JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > extractText (OCR) provides fallback error message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > extractText (OCR) resizes image to max 2048px", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > extractText (OCR) returns text and engine", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > extractText (OCR) throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > inpaint calls inpaint.py with input, mask, and output paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > inpaint converts both input and mask to PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > inpaint forwards onProgress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > inpaint provides fallback error message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > inpaint returns the output buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > inpaint throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > inpaint writes both input and mask files", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval calculates timeout based on megapixels", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval calls noise_removal.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval defaults format and tier", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval passes options as JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval prefers tier from result over options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval returns structured result", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > noiseRemoval uses output_path from result when available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground calculates timeout based on megapixels", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground calls runPythonWithProgress with remove_bg.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground cleans up temp files even on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground cleans up temp files in finally block", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground does not retry OOM if already using u2net", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground downscales large images and upscales mask back", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground passes onProgress callback through to bridge", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground passes options as JSON in args", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground provides fallback error message when error field is empty", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground retries with u2net fallback on OOM error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground returns the output file buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground throws when Python reports failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground uses longer base timeout for birefnet model", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeBackground writes input as PNG before processing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeRedEye calls red_eye_removal.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeRedEye defaults optional fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeRedEye passes options as JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeRedEye provides fallback error message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeRedEye returns structured result", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeRedEye throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > removeRedEye uses output_path from result when available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > restorePhoto calls restore.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > restorePhoto defaults optional result fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > restorePhoto passes options as JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > restorePhoto provides fallback error message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > restorePhoto returns full restoration result", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > restorePhoto throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > restorePhoto uses output_path from result when available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve calculates timeout based on megapixels", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve cleans up temp files even on error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve cleans up temp files in finally block", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve passes -face flag when protectFaces is true", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve passes -preview=false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve passes -square flag with shortest dimension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve passes -width and -height flags", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve passes blur and sobel options", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve pre-resizes when reduction exceeds 75% instead of rejecting", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve rejects images larger than 25 MP", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve returns buffer with dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve uses original dimensions when width/height not specified", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > seamCarve writes input as JPEG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale calculates higher timeout for CPU mode", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale calculates timeout with GPU rate when GPU available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale calls upscale.py", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale defaults method and format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale defaults scale to 2 for timeout calculation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale passes options as JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale provides fallback error message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale returns structured result", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale throws on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ai-tools.test.ts > upscale uses output_path from result when available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator conditions checks auth_anomaly condition", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator conditions checks backup_never_run condition", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator conditions checks backup_stale condition", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator conditions checks disk_space_low condition", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator conditions checks license_expiring condition", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator conditions only delivers to enabled webhooks of type alerts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator module exports evaluateAlerts is the only named export", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator module exports exports evaluateAlerts as a function", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds auth anomaly alert reports windowMinutes of 5", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds auth anomaly threshold is 20 failures", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds auth anomaly window is 5 minutes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds backup staleness alert reports threshold of 48", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds backup staleness threshold is 48 hours", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds disk space alert reports threshold of 1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds disk space threshold is 1 GB", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/alert-evaluator.test.ts > alert-evaluator thresholds license expiry warning threshold is 30 days", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_ENABLED defaults to false (no-phone-home)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_ENABLED rejects non-enum values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_ENABLED='false' transforms to boolean false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_ENABLED='true' transforms to boolean true", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_SAMPLE_RATE < 0 fails validation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_SAMPLE_RATE > 1 fails validation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_SAMPLE_RATE defaults to 1.0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_SAMPLE_RATE=0 is valid (no sampling)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_SAMPLE_RATE=0.5 parses correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_SAMPLE_RATE=1 is valid (full sampling)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation ANALYTICS_SAMPLE_RATE=2 fails validation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation POSTHOG_API_KEY can be overridden with a custom value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation POSTHOG_API_KEY can be set to empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation POSTHOG_API_KEY defaults to empty string (no baked key)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation POSTHOG_HOST can be overridden", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation POSTHOG_HOST defaults to the PostHog US endpoint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation SENTRY_DSN can be overridden with a custom value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation SENTRY_DSN can be set to empty string to disable", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-env.test.ts > analytics env var validation SENTRY_DSN defaults to empty string (no baked DSN)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant PII scrubbing regex - FILE_EXT_PATTERN does NOT match non-image extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant PII scrubbing regex - FILE_EXT_PATTERN matches all common image extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant PII scrubbing regex - FILE_EXT_PATTERN matches extensions in the middle of paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant PII scrubbing regex - FILE_EXT_PATTERN replaces extensions with [REDACTED]", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant PII scrubbing regex - FILE_PATH_PATTERN does NOT match safe paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant PII scrubbing regex - FILE_PATH_PATTERN matches workspace and data paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant PII scrubbing regex - FILE_PATH_PATTERN replaces paths with [REDACTED]", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant captureException consent gating (code review) captureException checks isRequestOptedIn before sending to Sentry", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant captureException consent gating (code review) error handler passes request to captureException", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant initAnalytics gating (code review) initAnalytics bails when ANALYTICS_ENABLED is false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant initAnalytics gating (code review) shutdownAnalytics nulls both clients", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant isUserOptedIn logic (code review) checks ANALYTICS_ENABLED before user DB lookup", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant isUserOptedIn logic (code review) returns false for anonymous user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant shouldSample logic rate 0.0 always rejects (Math.random() < 0.0 is always false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant shouldSample logic rate 1.0 always accepts (checked before Math.random call)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant shouldSample logic rate between 0 and 1 produces a mix", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant trackEvent gating (code review) trackEvent checks posthogClient, consent, and sampling", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-no-leak.test.ts > Server-side Analytics No-Leak Invariant trackEvent gating (code review) trackEvent wraps capture in try-catch (never throws)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent logic enabled=false sets analyticsEnabled to false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent logic enabled=true sets analyticsEnabled to true", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent logic missing enabled defaults to false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent logic remindLater branch sets analyticsEnabled to null", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent logic remindLater sets remind-at 7 days in the future", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema accepts both enabled and remindLater together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema accepts empty object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema accepts enabled: false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema accepts enabled: true", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema accepts remindLater: true", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema rejects enabled as number", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema rejects enabled as string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema rejects remindLater as string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics-route.test.ts > analytics consent schema strips unknown properties", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > captureException captures when sentry is initialized and no request provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > captureException captures when sentry is initialized and request user is opted in", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > captureException does nothing when request user is not opted in", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > captureException does nothing when sentryModule is null", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > initAnalytics does nothing when ANALYTICS_ENABLED is false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > initAnalytics does nothing when ANALYTICS_ENABLED is true but POSTHOG_API_KEY is empty", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > initAnalytics initializes posthog when enabled with API key", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > initAnalytics initializes sentry when SENTRY_DSN is provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > shutdownAnalytics closes sentry when initialized", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > shutdownAnalytics resolves without error when no clients initialized", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > shutdownAnalytics shuts down posthog when initialized", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent allows anonymous users with x-analytics-consent header", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent captures event when all conditions are met", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent does not throw when capture throws internally", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent does nothing when ANALYTICS_ENABLED is false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent does nothing when ANALYTICS_SAMPLE_RATE is 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent does nothing when posthogClient is null", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent does nothing when request user is not opted in", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent rejects anonymous users without consent header", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/analytics.test.ts > trackEvent uses instance ID from DB when available", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/anonymous-admin.test.ts > anonymous user when AUTH_ENABLED=false anonymous admin can pass requirePermission('settings:write')", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/anonymous-admin.test.ts > anonymous user when AUTH_ENABLED=false anonymous admin has all admin permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/anonymous-admin.test.ts > anonymous user when AUTH_ENABLED=false anonymous admin has settings:write permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/anonymous-admin.test.ts > anonymous user when AUTH_ENABLED=false assigns admin role to anonymous user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/anonymous-admin.test.ts > session endpoint when AUTH_ENABLED=false GET /api/auth/session returns admin role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/anonymous-admin.test.ts > session endpoint when AUTH_ENABLED=false GET /api/auth/session returns null expiresAt", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic API key format raw key has correct length (si_ + 96 hex chars = 99)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic API key format raw key starts with si_ prefix", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation accepts all fields together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation accepts empty object (all fields optional)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation accepts empty permissions array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation accepts name exactly 100 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation accepts permissions array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation accepts valid expiresAt date string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation accepts valid name", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic create API key validation rejects name longer than 100 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic default name behavior uses default name when name is empty", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic default name behavior uses default name when name is whitespace", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic default name behavior uses provided name when not empty", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic expiresAt validation accepts date in the future", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic expiresAt validation rejects date in the past", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic expiresAt validation rejects empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic expiresAt validation rejects invalid date string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic key prefix computation always starts with si_ prefix", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic key prefix computation handles short keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic key prefix computation returns first 10 characters of the key", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic permission scoping fails when requesting permissions user does not have", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic permission scoping fails when user has no permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic permission scoping passes when all requested permissions are in user permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic permission scoping passes with empty requested permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic permission scoping returns all invalid permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic response serialization formats key list entry correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/api-keys-route.test.ts > API keys route logic response serialization handles null permissions and dates", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/aspect-tools.test.ts > canvasFor already matching ratio returns same-ish dims (both even)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/aspect-tools.test.ts > canvasFor odd-dim source gets even output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/aspect-tools.test.ts > canvasFor small source into 4:3", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/aspect-tools.test.ts > canvasFor tall source into wide ratio (portrait into 16:9)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/aspect-tools.test.ts > canvasFor wide source into tall ratio (landscape into 9:16)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audio-output.test.ts > audioOutputFor falls back to mp3 for decode-only formats", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audio-output.test.ts > audioOutputFor maps .aac input to .m4a output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audio-output.test.ts > audioOutputFor normalises uppercase extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine COMPLETE is terminal (no outgoing transition)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine covers all non-terminal states", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine defines exactly 5 states", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine follows the exact sequence PENDING->EXPORTING->EXPORTED->PURGING->COMPLETE", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine has exactly 4 transitions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine has no cycles in the transition graph", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine state transitions are valid", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-archival.test.ts > audit archival state machine visits each state exactly once in the transition chain", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType API_KEY_CREATED -> api_key", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType API_KEY_DELETED -> api_key", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType FILE_DELETED -> file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType FILE_UPLOADED -> file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType LOGIN_FAILED -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType LOGIN_SUCCESS -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType LOGOUT -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType PASSWORD_CHANGED -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType PASSWORD_RESET -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType ROLE_CREATED -> role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType ROLE_DELETED -> role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType ROLE_UPDATED -> role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType SETTINGS_UPDATED -> setting", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType USER_CREATED -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType USER_DELETED -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers deriveTargetType USER_UPDATED -> user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorId falls back to adminId when userId is absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorId prefers userId over adminId when both are present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorId returns null for an empty details object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorId returns null when neither userId nor adminId is present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorId returns userId when present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorUsername falls back to newUsername when username is absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorUsername prefers username over newUsername when both are present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorUsername returns \"system\" for an empty details object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorUsername returns \"system\" when neither username nor newUsername is present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-helpers.test.ts > audit helpers extractActorUsername returns username when present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity canonicalizes arrays", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity canonicalizes deeply nested objects (3+ levels)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity canonicalizes empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity canonicalizes empty object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity canonicalizes mixed types", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity canonicalizes with null values included", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity canonicalizes with sorted keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity computes and verifies HMAC", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity computes deterministic HMAC", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity detects tampering", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity key order does not matter with 5+ keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity key ordering does not affect HMAC", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity produces different HMACs for different keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity serializes undefined values as null in canonicalization", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity verifyHmac returns false for completely wrong HMAC", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity verifyHmac returns false for empty HMAC string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-integrity.test.ts > audit integrity verifyHmac returns false for malformed HMAC string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog extracts actorId from userId field first", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog extracts username from details", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog falls back to adminId when userId is absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog handles empty details object", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog includes all detail fields in the log output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog inserts a record into the database", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog logs different event types correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog logs to the structured logger with audit flag", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog serializes details as JSON for DB storage", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-lib.test.ts > auditLog survives DB insert failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic entry serialization handles null details", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic entry serialization parses JSON details string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic entry serialization serializes a complete entry", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing adds action filter", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing adds from date filter", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing adds to date filter", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing handles all filters together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing ignores invalid from date", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing ignores invalid to date", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing keeps valid filters even when one is invalid", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic filter parsing returns empty conditions for no filters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing calculates correct offset for page 2 with limit 25", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing calculates correct offset for page 5 with limit 10", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing clamps limit to maximum 100", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing clamps limit to minimum 1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing clamps negative page to 1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing clamps page to minimum 1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing defaults to page 1, limit 50", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing handles non-numeric limit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing handles non-numeric page", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-log-route.test.ts > audit log route logic pagination parsing parses valid page and limit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput does not truncate a string at exactly 200 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput preserves safe characters unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput returns (empty) for empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput returns (empty) when only special characters remain", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput strips all dangerous characters in one pass", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput strips ampersand", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput strips angle brackets", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput strips double quotes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput strips single quotes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput truncates a 201-character string to 200", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/audit-system.test.ts > sanitizeAuditInput truncates long strings after stripping characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > computeKeyPrefix is deterministic (same input gives same output)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > computeKeyPrefix produces different prefixes for different inputs", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > computeKeyPrefix returns a 16-character hex string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > computeKeyPrefix works with various key formats", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > hashPassword generates different salts on each call", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > hashPassword produces a 128-character hex hash (64 bytes)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > hashPassword produces a 64-character hex salt (32 bytes)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > hashPassword produces a hash that can be verified back", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > hashPassword returns a string in salt:hash format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > verifyPassword handles unicode passwords", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > verifyPassword returns false for a malformed stored string (no colon)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > verifyPassword returns false for a truncated hash", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > verifyPassword returns false for a wrong password", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > verifyPassword returns false for an empty stored string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-functions.test.ts > verifyPassword returns true for the correct password", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > computeKeyPrefix (additional coverage) prefix for binary-like input still works", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > computeKeyPrefix (additional coverage) returns consistent 16-char prefix for empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > getAuthUser returns null when request has no user property", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > getAuthUser returns null when user is undefined", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > getAuthUser returns the user when request has user property", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > hashPassword (additional coverage) different passwords produce different hashes even with same salt length", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > hashPassword (additional coverage) handles empty string password", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > hashPassword (additional coverage) handles very long passwords", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats admin routes as private", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats auth routes as public", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats docs as public", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats download routes as public", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats health endpoint as public", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats job progress as public", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats meme templates as public", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats non-API routes as public", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > isPublicRoute treats tool endpoints as private", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > requireAdmin returns null and sends 401 when not authenticated at all", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > requireAdmin returns null and sends 403 when role is not admin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > requireAdmin returns null for editor role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > requireAdmin returns the user when role is admin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > requireAuth returns null and sends 401 when not authenticated", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > requireAuth returns the user when authenticated", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validatePasswordStrength accepts password with special characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validatePasswordStrength accepts valid password", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validatePasswordStrength rejects empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validatePasswordStrength rejects password shorter than 8 chars", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validatePasswordStrength rejects password without lowercase", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validatePasswordStrength rejects password without number", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validatePasswordStrength rejects password without uppercase", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validateUsername accepts exactly 3 chars", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validateUsername accepts exactly 50 chars", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validateUsername accepts valid usernames", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validateUsername rejects username longer than 50 chars", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validateUsername rejects username shorter than 3 chars", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validateUsername rejects username with spaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > validateUsername rejects username with special characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > verifyPassword (additional coverage) handles special characters in password", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > verifyPassword (additional coverage) returns false for completely empty input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auth-routes.test.ts > verifyPassword (additional coverage) returns false when stored has colon but empty salt", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient handles orientation 2 (horizontal flip)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient returns original buffer for corrupted/invalid input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient returns original buffer for empty buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient returns original buffer unchanged when no EXIF orientation is present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient returns original buffer unchanged when orientation is 1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient rotates image when orientation is 3 (180)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient rotates image when orientation is 6 (90 CW)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient rotates image when orientation is 8 (270 CW)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/auto-orient.test.ts > autoOrient strips orientation tag after rotation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/background-composite.test.ts > blurBackground modifies the background corner relative to pure blue", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/background-composite.test.ts > blurBackground preserves the subject center pixel", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/background-composite.test.ts > blurBackground produces an image of the same dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/background-composite.test.ts > compositeOnColor fills transparent corners with the background color", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/background-composite.test.ts > compositeOnColor preserves the subject pixel in the center", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/background-composite.test.ts > compositeOnColor produces a fully opaque image (no alpha)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch output filename suffix adds tool suffix when filename unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch output filename suffix handles filenames with multiple dots", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch output filename suffix handles filenames without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch output filename suffix preserves filename when tool changed it", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch progress status determination status is 'completed' when no files fail", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch progress status determination status is 'completed' when some files succeed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch progress status determination status is 'failed' when all files fail", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch size enforcement allows any count when limit is 0 (unlimited)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch size enforcement allows files within the limit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch size enforcement allows when count equals limit exactly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch size enforcement rejects files exceeding the limit", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > batch size enforcement rejects when count equals limit + 1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > file results map (X-File-Results header) builds correct map for unique filenames", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > file results map (X-File-Results header) deduplicates conflicting filenames", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > file results map (X-File-Results header) returns empty map when all files failed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > file results map (X-File-Results header) skips null entries (failed files)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > skip-preprocess logic for metadata tools does not skip preprocess for compress", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > skip-preprocess logic for metadata tools does not skip preprocess for resize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > skip-preprocess logic for metadata tools skips preprocess for edit-metadata", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/batch.test.ts > skip-preprocess logic for metadata tools skips preprocess for strip-metadata", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > addDropShadow higher opacity produces more shadow alpha than lower opacity", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > addDropShadow opacity 0 produces no visible shadow (alpha bytes near zero in shadow area)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > addDropShadow opacity 100 produces visible shadow", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > addDropShadow output dimensions match input dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > addDropShadow returns a valid PNG buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > addDropShadow throws when buffer has no readable dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects blurEnabled with blur bgType blurs the original background", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects blurEnabled with transparent bgType blurs the original background", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects color backgroundType composites on solid color", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects combined shadow + color background works", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects defaults backgroundType to transparent when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects defaults blurIntensity to 50 when not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects gradient backgroundType composites on gradient", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects image backgroundType composites on provided image", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects image backgroundType with blurEnabled blurs the background image", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects shadowEnabled with opacity adds shadow", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects shadowOpacity 0 does not add shadow", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > applyEffects transparent backgroundType with no effects returns subject approximately unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > blurBackground clamps intensity above 100 to 100", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > blurBackground clamps intensity below 0 to 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > blurBackground different intensity values produce different output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > blurBackground intensity 0 produces minimal blur (sigma ~1)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > blurBackground intensity 100 produces heavy blur (sigma 50)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > blurBackground output dimensions match subject dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > blurBackground returns a valid PNG buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnColor accepts hex color without hash prefix", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnColor composites subject onto solid color background", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnColor output dimensions match subject dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnColor output is a valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnColor throws on invalid buffer with no dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnImage background is resized to cover subject dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnImage composites subject onto background image", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnImage output dimensions match subject dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnImage output is a valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > compositeOnImage throws on invalid subject buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > createGradientBackground creates correct size output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > createGradientBackground default angle is 180 (top to bottom)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > createGradientBackground different angles produce different pixel data", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > createGradientBackground different colors produce different output", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bg-effects.test.ts > createGradientBackground output is a valid PNG buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bullmq-context-propagation.test.ts > BullMQ trace context extraction creates root span when _otel is absent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bullmq-context-propagation.test.ts > BullMQ trace context extraction extracts parent context from _otel carrier", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bullmq-context-propagation.test.ts > BullMQ trace context injection injects _otel with traceparent when a span is active", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/bullmq-context-propagation.test.ts > BullMQ trace context injection injects nothing when no SDK is registered", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) computes deleteAfter as retentionHours converted to milliseconds from now", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) falls back to FILE_MAX_AGE_HOURS when team has no retentionHours", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) function is defined as async", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) gates on team_retention_overrides enterprise feature", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) is called fire-and-forget from enqueueToolJob", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) looks up the user's team from the users table", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) reads retentionHours from the teams table", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) returns early when feature is not enabled", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) returns early when user has no team", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > computeDeleteAfter logic (source verification) updates the job row with the computed deleteAfter", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > enqueue module exports does not export computeDeleteAfter (private function)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > enqueue module exports exports closeFlowProducer as a function", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > enqueue module exports exports closeQueueEvents as a function", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > enqueue module exports exports enqueueToolJob as a function", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > enqueue module exports exports getFlowProducer as a function", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/compute-delete-after.test.ts > enqueue module exports exports waitForJob as a function", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp allows OpenStreetMap tiles in img-src for app pages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains includes PostHog assets (isDocs=false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains includes PostHog assets (isDocs=true)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains includes PostHog ingest (isDocs=false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains includes PostHog ingest (isDocs=true)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains includes Sentry ingest (isDocs=false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains includes Sentry ingest (isDocs=true)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains keeps self (isDocs=false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows analytics domains keeps self (isDocs=true)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows data: URIs for client-side blob operations (isDocs=false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp connect-src allows data: URIs for client-side blob operations (isDocs=true)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp font-src allows Scalar docs fonts app pages do not include Scalar fonts origin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp font-src allows Scalar docs fonts docs pages include Scalar fonts origin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp includes frame-ancestors none for app pages but not docs", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp script-src allows PostHog config loader app pages do not allow unsafe-inline", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp script-src allows PostHog config loader docs pages allow unsafe-inline for Scalar", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp script-src allows PostHog config loader includes PostHog assets origin (isDocs=false)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/csp.test.ts > buildCsp script-src allows PostHog config loader includes PostHog assets origin (isDocs=true)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt groups endpoints by tag", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt handles spec with no description", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt includes parameters section", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt includes request body section", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt includes responses section", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt includes the description", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt includes title with version", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt marks auth-required endpoints", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt marks public endpoints", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsFullTxt puts untagged endpoints under 'Other'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsTxt handles spec with empty paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsTxt handles spec with no tags", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsTxt includes authentication section", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsTxt includes the Docs section", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsTxt lists API sections with endpoint counts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic generateLlmsTxt starts with the API title", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic isPublic returns false for non-empty security array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic isPublic returns false for null-like security", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic isPublic returns false for undefined security", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/docs-route.test.ts > docs route logic isPublic returns true for empty security array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions exact counts for built-in roles admin has exactly 17 permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions exact counts for built-in roles editor has exactly 7 permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions exact counts for built-in roles user has exactly 5 permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions invalid and edge-case role names case-sensitive: ADMIN (uppercase) returns empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions invalid and edge-case role names case-sensitive: Admin (capitalized) returns empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions invalid and edge-case role names case-sensitive: User (capitalized) returns empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions invalid and edge-case role names empty string returns empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions invalid and edge-case role names null coerced to string returns empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions invalid and edge-case role names undefined coerced to string returns empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions invalid and edge-case role names whitespace-padded role name returns empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions role permission subsets editor permissions are a subset of admin permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions role permission subsets user permissions are a subset of admin permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > getPermissions role permission subsets user permissions are a subset of editor permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission API key cannot grant permissions the role lacks editor with apiKeyPermissions including settings:write still denied", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission API key cannot grant permissions the role lacks unknown role gains nothing even with full apiKeyPermissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission API key cannot grant permissions the role lacks user with apiKeyPermissions including users:manage still denied", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission API key scoping restricts permissions admin scoped to tools:use can only use tools:use", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission API key scoping restricts permissions editor scoped to files:own and tools:use only has those", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission API key scoping restricts permissions user scoped to settings:read only has that", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission empty apiKeyPermissions blocks everything admin with empty array has no effective permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission empty apiKeyPermissions blocks everything user with empty array has no effective permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission undefined apiKeyPermissions inherits all role permissions admin without apiKeyPermissions gets full admin access", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission undefined apiKeyPermissions inherits all role permissions user without apiKeyPermissions gets full user access", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission without API key scoping (apiKeyPermissions undefined) admin can use any permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission without API key scoping (apiKeyPermissions undefined) editor can use all editor permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission without API key scoping (apiKeyPermissions undefined) editor cannot use admin-only permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission without API key scoping (apiKeyPermissions undefined) unknown role has no effective permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission without API key scoping (apiKeyPermissions undefined) user can use all user permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasEffectivePermission without API key scoping (apiKeyPermissions undefined) user cannot use editor or admin permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasPermission edge cases returns false for a non-existent permission string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasPermission edge cases returns false for an empty string permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasPermission edge cases returns false for both unknown role and unknown permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/effective-permissions.test.ts > hasPermission edge cases returns false for unknown role even with valid permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption decrypt passes through non-encrypted values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption decrypt returns null for $ENC$ with corrupted ciphertext", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption decrypt returns null for $ENC$ with truncated data", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption decrypt returns null for wrong key", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption decrypt tries previous key on failure", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption deriveAuditHmacKey is deterministic", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption deriveAuditHmacKey produces a 32-byte buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption deriveAuditHmacKey produces different keys for different master keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption encrypts and decrypts a value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption encrypts and decrypts a very long input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption encrypts and decrypts an empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption encrypts and decrypts special characters (newlines, tabs, null bytes)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption encrypts and decrypts unicode and emoji characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption isEncrypted returns false for plaintext", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption isEncrypted returns true for $ENC$ prefix with invalid base64", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption produces different ciphertext for same plaintext (random IV)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/encryption.test.ts > encryption two encryptions of the same plaintext decrypt to the same value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-flags.test.ts > enterprise feature flags enterprise plan includes everything", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-flags.test.ts > enterprise feature flags has exactly 19 features total", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-flags.test.ts > enterprise feature flags includes all Phase 1 flags", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-flags.test.ts > enterprise feature flags includes all Phase 2-4 flags", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-flags.test.ts > enterprise feature flags includes distributed_tracing in enterprise plan only", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-flags.test.ts > enterprise feature flags team plan does NOT include compliance features", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-flags.test.ts > enterprise feature flags team plan includes operational features", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-mock.test.ts > enterprise mock mocks feature enabled", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-mock.test.ts > enterprise mock mocks no enterprise", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-mock.test.ts > enterprise mock returns license payload with correct shape", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/enterprise-mock.test.ts > enterprise mock returns null license when no enterprise", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > formatZodErrors formats single issue with path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > formatZodErrors formats single issue without path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > formatZodErrors joins multiple issues with semicolons", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > formatZodErrors joins nested paths with dots", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > formatZodErrors returns empty string for empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths handles pipeline step error wrapping", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths leaves safe messages untouched", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths leaves timeout messages untouched", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths strips /app container paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths strips /data/ai/venv Python traceback paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths strips /home paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths strips /opt paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths strips /tmp scratch paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths strips /workspace paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/errors.test.ts > stripInternalPaths strips multiple paths in one message", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs adds keywords in add mode", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs allows field names with colons and hyphens", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs allows field names with underscores", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs applies dateShift without explicit sign as positive", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs applies negative dateShift", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs applies positive dateShift", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs artist takes precedence over author", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs clearGps takes priority over GPS coordinates", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs clears GPS data with clearGps flag", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs clears existing keywords before setting in set mode", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs does not add keywords args when keywords array is empty", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs does not set GPS when only latitude is provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs does not set GPS when only longitude is provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs does nothing for empty fieldsToRemove array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs filters out blank and whitespace-only keywords", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs handles complex settings with multiple fields combined", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs handles negative GPS altitude (below sea level)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs handles zero GPS altitude", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs handles zero GPS coordinates", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs imageDescription takes precedence over title for ImageDescription tag", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs includes GPS altitude when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs rejects unsafe field names from removal", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs removes safe field names", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs returns empty array for empty settings", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets IPTC city", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets IPTC country", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets IPTC headline", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets IPTC state", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets IPTC title (ObjectName)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets all dates to a specific value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets copyright field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets dateTime as ModifyDate", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets dateTimeOriginal", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets negative GPS latitude", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets positive GPS coordinates", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs sets software field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs trims keyword whitespace", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs uses artist field when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs uses author as fallback when artist is not provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs uses imageDescription when provided", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > buildTagArgs uses title as fallback for imageDescription", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > inspectMetadata returns correct filename and fileSize for JPEG with EXIF", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > inspectMetadata returns keywords array (may be empty)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > inspectMetadata returns non-null exif object for JPEG with EXIF data", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > inspectMetadata returns null for GPS when no GPS data present", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > inspectMetadata works with PNG which has no EXIF -- returns null for exif, iptc, xmp, gps", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > writeMetadata empty tags array returns buffer unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > writeMetadata returns a valid image buffer that Sharp can read", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > writeMetadata writing -Artist=TestArtist then inspecting shows the artist", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/exiftool.test.ts > writeMetadata writing multiple tags works", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > external auth resolver module exports findUniqueUsername", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > external auth resolver module exports resolveExternalUser", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > external auth resolver module exports sanitizeUsername", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > findUniqueUsername appends _2 when the base username is taken", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > findUniqueUsername appends _3 when both base and _2 are taken", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > findUniqueUsername resolves collisions through the loop until a free slot is found", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > findUniqueUsername returns the base username when it is not taken", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername allows input that starts with numbers", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername collapses multiple underscores", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername does not truncate input that is exactly 46 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername handles email addresses as input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername handles empty-after-strip edge case", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername handles numeric-only input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername handles pure whitespace input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername handles single character input by padding to 3", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername lowercases input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername pads short usernames to 3 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername passes through admin as a valid username", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername preserves consecutive dots and hyphens", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername preserves dots and hyphens", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername replaces non-alphanumeric characters with underscores", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername replaces unicode characters with underscores", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername strips leading @ from input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername strips leading and trailing separators", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername truncates input that is exactly 47 characters to 46", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/external-auth-resolver.test.ts > sanitizeUsername truncates to 46 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > getDirSize handles deeply nested directories", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > getDirSize recurses into subdirectories", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > getDirSize returns 0 for empty directory", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > getDirSize returns 0 for non-existent directory", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > getDirSize returns correct size for a single file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > getDirSize sums sizes of multiple files", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > readManifest handles manifest with empty bundles", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > readManifest handles manifest with models without paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > readManifest handles manifest with multiple bundles", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > readManifest parses valid manifest JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > readManifest returns null for invalid JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > readManifest returns null for non-existent file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > shared model path deduplication handles bundle with no models property", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/features-route.test.ts > shared model path deduplication identifies models shared between bundles", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl decodes percent-encoded characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl extracts filename from URL with query string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl extracts filename from simple URL", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl handles deeply nested path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl handles filename at exactly 255 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl handles filename with multiple dots", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl returns fallback for URL without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl returns fallback for empty path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl returns fallback for filename over 255 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl returns fallback for invalid URL", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > filenameFromUrl returns fallback for root URL", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType handles uppercase extensions via toLowerCase", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType maps .jpeg to image/jpeg", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType maps .jpg to image/jpeg", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType maps .png to image/png", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType maps .ttf to font/ttf", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType maps .webp to image/webp", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType returns undefined for filename without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType returns undefined for unknown extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getContentType uses the last dot for extension detection", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getUniqueName adds each unique name to the used set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getUniqueName appends _1 for first collision", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getUniqueName appends _2 when _1 is also taken", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getUniqueName handles filename with multiple dots", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getUniqueName handles filename without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getUniqueName handles multiple collisions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > getUniqueName returns name unchanged if not in used set", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > hasPathTraversal returns false for filename with dots that are not traversal", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > hasPathTraversal returns false for safe filenames", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > hasPathTraversal returns true for ..", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > hasPathTraversal returns true for backslash", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > hasPathTraversal returns true for embedded ..", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > hasPathTraversal returns true for forward slash", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/fetch-urls-helpers.test.ts > hasPathTraversal returns true for null byte", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > deleteStoredFile deletes existing file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > deleteStoredFile does not throw for non-existent file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > ensureStorageDir creates directory if not exists", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > ensureStorageDir is idempotent (second call does not throw)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > getStoredFilePath returns correct joined path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > saveFile accepts known image extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > saveFile creates storage directory on first call", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > saveFile lowercases extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > saveFile returns different filenames for same input (UUID-based)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > saveFile sanitizes dangerous extensions to .bin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > saveFile saves buffer and returns UUID-based filename with correct extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > saveFile uses .bin for files with no extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > thumbnail functions deleteThumbnail does not throw for non-existent", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > thumbnail functions deleteThumbnail removes the file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > thumbnail functions getCachedThumbnail reads back saved thumbnail", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > thumbnail functions getCachedThumbnail returns null for non-existent thumbnail", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > thumbnail functions saveThumbnail creates .thumbs subdirectory", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/file-storage.test.ts > thumbnail functions saveThumbnail writes to correct path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename falls back to upload for double dot", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename falls back to upload for empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename falls back to upload for four dots (.. removal leaves empty)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename falls back to upload for single dot", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename falls back to upload for triple dots (.. removal leaves .)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles emoji filenames", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles filename with only unknown extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles filenames with dashes and underscores", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles filenames with spaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles no extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles only null bytes falling back to upload", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles trailing slash in path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles unicode filenames", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename handles unknown extensions without truncation", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename passes through a simple filename", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename preserves dotfiles", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename recognizes all safe image extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename recognizes safe extensions across all modalities", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename removes .. sequences", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename removes embedded .. sequences in filename", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename removes null bytes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename strips directory path and returns basename only", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename strips relative directory path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename truncates after first safe image extension (photo.png.php)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename truncates after first safe image extension (report.jpg.exe)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename truncates after first safe image extension with multiple unsafe parts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename truncates long filename without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename truncates long unicode filenames correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/filename.test.ts > sanitizeFilename truncates very long filenames over 200 bytes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic extension extraction from filename extracts extension from simple filename", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic extension extraction from filename handles filename with multiple dots", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic extension extraction from filename handles filename without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic filename encoding for Content-Disposition encodes special characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic filename encoding for Content-Disposition encodes unicode characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic filename encoding for Content-Disposition preserves simple filenames", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps HEIC/HEIF formats correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps RAW formats correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps avif to image/avif", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps bmp to image/bmp", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps gif to image/gif", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps ico to image/x-icon", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps jpeg to image/jpeg", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps jpg to image/jpeg", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps json to application/json", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps jxl to image/jxl", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps pdf to application/pdf", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps png to image/png", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps specialty formats correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps svg to image/svg+xml", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps tif to image/tiff", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps tiff to image/tiff", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps webp to image/webp", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType maps zip to application/zip", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType returns application/octet-stream for empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic getContentType returns application/octet-stream for unknown extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal allows alphanumeric-only segment", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal allows clean UUID-like segment", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal allows clean filename", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal allows hyphens and underscores", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal allows single dot in filename (extension)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal detects Windows-style path traversal (..\\)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal detects backslash", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal detects double dot traversal", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal detects double dot with prefix", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal detects forward slash", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal detects null byte", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/files-route.test.ts > files route logic isPathTraversal detects relative path traversal (../)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - EPS size limit rejects EPS files over 50MB", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - QOI decoder decoded QOI produces a buffer sharp can process further", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - QOI decoder decodes QOI fixture to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - QOI decoder round-trips PNG -> QOI -> PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification bmp: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification dds: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification dpx: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification exr: output has non-zero dimensions (requires delegate)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification fits: output has non-zero dimensions (requires delegate)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification hdr: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification ico: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification jp2: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification jxl: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification psd: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat - individual decoder verification tga: output has non-zero dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes BMP to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes CUR using ICO decoder to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes DDS to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes DPX to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes EXR to valid PNG (requires EXR delegate)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes FITS to valid PNG (requires FITS delegate)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes HDR to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes ICO to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes JP2 to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes JXL to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes PBM to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes PGM to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes PPM to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes PSD to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat decodes TGA to valid PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat returns buffer unchanged for avif format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat returns buffer unchanged for empty format string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat returns buffer unchanged for gif format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat returns buffer unchanged for png format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat returns buffer unchanged for tiff format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat returns buffer unchanged for unknown/native formats", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > decodeToSharpCompat returns buffer unchanged for webp format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for avif format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for gif format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for jpeg format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for png format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for svg format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for unknown format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns false for webp format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for bmp format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for cur format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for dds format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for dpx format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for eps format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for exr format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for fits format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for hdr format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for ico format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for jp2 format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for jxl format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for pbm format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for pgm format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for ppm format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for psd format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for qoi format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for raw format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-decoders.test.ts > needsCliDecode returns true for tga format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeBmp encodes JPEG input to BMP", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeBmp encodes a PNG buffer to BMP format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeBmp produces a BMP with correct dimensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeIco encodes a PNG buffer to ICO format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeIco preserves small images without enlargement", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeIco resizes large images to fit within 256x256", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeJp2 accepts optional quality parameter", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeJp2 encodes a PNG buffer to JP2 format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeJp2 produces valid output at different quality levels", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeQoi encodes JPEG input to QOI", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeQoi encodes a PNG buffer to QOI format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/format-encoders.test.ts > encodeQoi encodes fixture image to QOI", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > decodeHeic cleans up temp files after success", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > decodeHeic decodes sample.heic to a valid PNG buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > decodeHeic decodes sample.heif to a valid PNG buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > decodeHeic preserves image dimensions after decoding", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > decodeHeic rejects an empty buffer", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > decodeHeic rejects invalid/corrupt data", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > ensureSharpCompat decodes a HEIC buffer to PNG", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > ensureSharpCompat detects heic brand in ftyp box", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > ensureSharpCompat detects mif1 brand in ftyp box", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > ensureSharpCompat does not treat a short buffer as HEIF", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > ensureSharpCompat passes through a JPEG buffer unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > ensureSharpCompat passes through a PNG buffer unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/heic-converter.test.ts > ensureSharpCompat passes through a WebP buffer unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist EXEMPT_PATHS includes IdP callback paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist EXEMPT_PATHS includes all expected infrastructure paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist buildBlockList builds a list from IPv4 CIDRs", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist buildBlockList builds a list from IPv6 CIDRs", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist buildBlockList builds a list from bare IPv4 addresses", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist buildBlockList returns null for an empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist buildBlockList skips invalid entries without throwing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath does NOT exempt regular API paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath does NOT exempt the root path", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath exempts OIDC callback", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath exempts SAML callback", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath exempts SCIM paths", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath exempts health endpoint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath exempts metrics endpoint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isExemptPath exempts readyz endpoint", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed allows /0 to match everything", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed allows /32 single-host CIDR", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed allows 127.0.0.1 when loopback is listed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed allows an IP inside a CIDR range", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed allows an IPv6 address inside a subnet", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed allows an exact single-address match", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed denies an IP outside all ranges", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed handles IPv4-mapped IPv6 addresses (::ffff:x.x.x.x)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isIpAllowed handles multiple CIDR ranges", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr accepts valid IPv4 CIDR", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr accepts valid IPv6 CIDR", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr accepts valid bare IPv4 address", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr accepts valid bare IPv6 address", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr rejects IPv4 prefix > 32", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr rejects IPv6 prefix > 128", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr rejects invalid strings", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/ip-allowlist.test.ts > IP allowlist isValidCidr rejects negative prefix", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > ENTERPRISE_FEATURES contains all expected feature strings", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > ENTERPRISE_FEATURES contains exactly 19 features", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > ENTERPRISE_FEATURES every entry is a non-empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > ENTERPRISE_FEATURES has no duplicate entries", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > PLAN_FEATURES enterprise plan has all 19 features", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > PLAN_FEATURES enterprise plan is a superset of team plan", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > PLAN_FEATURES enterprise plan references the same array as ENTERPRISE_FEATURES", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > PLAN_FEATURES team plan contains the expected features", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > PLAN_FEATURES team plan does not include compliance-only features", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > PLAN_FEATURES team plan has exactly 8 features", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > initEnterprise returns valid:false and license:null when called with an invalid key", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > initEnterprise returns valid:false and license:null when called with empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > initEnterprise returns valid:false and license:null when called with undefined", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > initEnterprise returns valid:false for a key with wrong signature", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > initEnterprise sets activeLicense to null for invalid keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > isFeatureEnabled (direct, no mock) returns false for all features after initEnterprise with invalid key", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > isFeatureEnabled (direct, no mock) returns false for all features after initEnterprise with undefined", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > isFeatureEnabled (direct, no mock) returns false for all features when initEnterprise was not called", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > isFeatureEnabled (via mock) returns correct results when switching from active to no license", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > isFeatureEnabled (via mock) returns false for features NOT in the active license", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > isFeatureEnabled (via mock) returns false when no license is active", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > isFeatureEnabled (via mock) returns true for features in the active license", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null for empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null for input without a dot separator", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null for invalid base64url payload", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null for payload with multiple dots", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null for undefined input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null for valid JSON payload with wrong signature", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null for valid base64url that is not JSON", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/license-validation.test.ts > validateLicense returns null when dot is at position 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/log-trace-mixin.test.ts > traceMixin returns empty object when no span is active", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/log-trace-mixin.test.ts > traceMixin returns traceId, spanId, traceFlags when span is active", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > autoSizeFontToFit respects maxFontSize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > autoSizeFontToFit returns min size for tiny box", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > autoSizeFontToFit returns size within bounds", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > autoSizeFontToFit returns smaller size for longer text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > loadFont caches across calls", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > loadFont falls back to anton for unknown fonts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > loadFont loads anton font", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > measureText returns 0 for empty text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > measureText returns positive width for non-empty text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > measureText scales with font size", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > renderMemeTextSvg applies allCaps", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > renderMemeTextSvg has correct fill/stroke attributes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > renderMemeTextSvg has paint-order=\"stroke fill\"", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > renderMemeTextSvg renders differently with different fonts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > renderMemeTextSvg returns valid SVG with elements", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > renderMemeTextSvg skips empty text boxes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > renderMemeTextSvg uses custom fontSize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > wrapText handles multiple spaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > wrapText handles single word exceeding width", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > wrapText returns [\"\"] for empty text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > wrapText returns single line when text fits", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/meme-text-renderer.test.ts > wrapText wraps into multiple lines", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA createTotp generates a TOTP with a valid secret", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA createTotp generates a valid TOTP URI", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA createTotp generates unique secrets across calls", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA createTotp uses a provided secret when given", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA hashRecoveryCodes handles a single code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA hashRecoveryCodes hashes recovery codes into comma-separated SHA-256 hashes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA hashRecoveryCodes produces deterministic hashes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA isMfaRequiredForUser returns false for admins_only policy when role is not admin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA isMfaRequiredForUser returns false for optional policy", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA isMfaRequiredForUser returns true for admins_only policy when role is admin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA isMfaRequiredForUser returns true for required policy regardless of role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyRecoveryCode consumes a recovery code on use", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyRecoveryCode preserves other codes when one is consumed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyRecoveryCode rejects an invalid recovery code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyRecoveryCode returns empty remaining when last code is used", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyRecoveryCode verifies a valid recovery code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyTotpCode accepts codes within the 1-step window", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyTotpCode rejects a code from a different secret", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyTotpCode rejects an empty code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyTotpCode rejects an incorrect TOTP code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/mfa.test.ts > MFA verifyTotpCode verifies a correct TOTP code", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/object-storage.test.ts > object-storage (local backend) rejects path traversal in keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/object-storage.test.ts > object-storage (local backend) round-trips buffers and streams with size and listing", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/output-format.test.ts > resolveOutputFormat accepts quality override for PNG without error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/output-format.test.ts > resolveOutputFormat detects JPEG input and returns jpeg config", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/output-format.test.ts > resolveOutputFormat detects PNG input and returns png config", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/output-format.test.ts > resolveOutputFormat detects WebP input and returns webp config", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/output-format.test.ts > resolveOutputFormat falls back to PNG for unknown format", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/output-format.test.ts > resolveOutputFormat respects quality override for lossy formats", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange deduplicates overlapping ranges", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange deduplicates repeated pages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange handles a range of one page (start equals end)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange handles range ending at totalPages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange handles ranges with spaces", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange handles single page equal to totalPages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange parses a simple range", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange parses a single page number", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange parses mixed single pages and ranges", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange parses multiple ranges", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange parses multiple single pages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange returns all pages for ' all ' (trimmed)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange returns all pages for 'ALL' (case-insensitive)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange returns all pages for 'all'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange returns all pages for empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange sorts pages in ascending order", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for empty segment (leading comma)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for empty segment (trailing comma)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for negative page number", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for non-integer page number", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for non-numeric input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for page 0 (pages start at 1)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for page exceeding totalPages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for range exceeding totalPages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-range.test.ts > parsePageRange throws for reversed range (start > end)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > compressPageRuns collapses a full consecutive run: [2..80] -> '2-80'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > compressPageRuns handles a single page: [3] -> '3'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > compressPageRuns leaves non-consecutive pages as singles: [1,3,5,7] -> '1,3,5,7'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > compressPageRuns mixes runs and singles: [1,2,4,5,6,9] -> '1-2,4-6,9'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > compressPageRuns pathological alternation (odd pages 1..399) produces ~800 chars", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > compressPageRuns returns empty string for empty input", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec '1,1' deduplicates to {1}", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec '1-r1' of 5 resolves to all pages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec 'r2-r1' of 5 resolves to {4,5}", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec 'z-1' of 3 resolves to all pages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec handles 1-z as all pages", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec handles comma-separated values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec remove-pages: '1-2' of 3 yields keep '3'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec remove-pages: '1-z' of 3 leaves nothing to keep", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec remove-pages: '2' of 3 yields keep '1,3'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec remove-pages: 'z' of 3 yields keep '1,2'", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec resolves a range", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec resolves a single page", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec resolves r1 as the last page", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec resolves r2 as second-to-last", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec resolves r3 as the first page of 3", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec resolves z as the last page", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec reversed range '3-1' normalizes to {1,2,3}", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec throws on out-of-range page", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec throws on page 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/page-spec.test.ts > parsePageSpec throws on r-index that resolves below 1", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasEffectivePermission extended admin without apiKeyPermissions has all permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasEffectivePermission extended apiKeyPermissions that do NOT include the permission returns false", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasEffectivePermission extended apiKeyPermissions that include the permission returns true", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasEffectivePermission extended role lacking the permission returns false even if apiKeyPermissions include it", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasEffectivePermission extended user with apiKeyPermissions only gets intersecting permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasPermission extended admin has all 14 permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasPermission extended editor does NOT have admin-only permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasPermission extended editor has the expected permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasPermission extended unknown role returns false for any permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasPermission extended user does NOT have elevated permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > hasPermission extended user has the expected permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requireOwnershipOrPermission returns null and sends 401 when no user", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requireOwnershipOrPermission returns null when not owner and lacks allPermission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requireOwnershipOrPermission returns user when resourceUserId matches user.id (own resource)", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requireOwnershipOrPermission returns user when user has the allPermission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requirePermission returns null and sends 401 when getAuthUser returns null", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requirePermission returns null and sends 403 when user lacks permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requirePermission returns user when editor has an editor-level permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions-extended.test.ts > requirePermission returns user when user has the permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions getPermissions does NOT contain admin-only permissions for user role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions getPermissions returns all 17 permissions for admin", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions getPermissions returns empty array for unknown role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions getPermissions returns only basic permissions for user role", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions hasPermission returns false for user with settings:write", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions hasPermission returns false for user with users:manage", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions hasPermission returns true for admin with users:manage", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/permissions.test.ts > permissions hasPermission returns true for user with tools:use", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > content-aware resize routing keeps non-resize tools unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > content-aware resize routing keeps resize as-is without contentAware", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > content-aware resize routing resolves resize with contentAware to content-aware-resize", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > filename deduplication (getUniqueName logic) adds _1 suffix on first conflict", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > filename deduplication (getUniqueName logic) handles filenames without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > filename deduplication (getUniqueName logic) handles multiple dots in filename", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > filename deduplication (getUniqueName logic) increments counter on repeated conflicts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > filename deduplication (getUniqueName logic) returns the original name when no conflicts", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > filename deduplication (getUniqueName logic) tracks all used names across multiple calls", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline step error message formatting falls back to generic message for non-Error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline step error message formatting wraps step errors with step number and tool ID", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline step schema validation defaults settings to empty object when omitted", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline step schema validation requires at least one step", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline step schema validation validates step has toolId field", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline tool registry lookup getToolConfig returns undefined for unregistered tool", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline tool registry lookup registered tool appears in getRegisteredToolIds", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline tool registry lookup registered tool is found via getToolConfig", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/pipeline.test.ts > pipeline tool registry lookup registered tool process function executes correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/postprocess.test.ts > CONTENT_TYPE_TO_EXT maps common image MIME types to extensions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/postprocess.test.ts > buildOutputName appends toolId suffix when filename is unchanged", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/postprocess.test.ts > buildOutputName applies both suffix and extension fixup when needed", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/postprocess.test.ts > buildOutputName does not add suffix when tool renames the file", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/postprocess.test.ts > buildOutputName fixes extension mismatch between content-type and filename", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/postprocess.test.ts > buildOutputName handles filenames without extension", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/postprocess.test.ts > buildOutputName preserves extension when content-type matches", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > JobProgress type shape supports all required fields", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > JobProgress type shape supports optional currentFile and type", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateJobProgress handles completed status", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateJobProgress handles failed status with errors", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateJobProgress handles progress with currentFile", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateJobProgress stores progress that can be sent to SSE listeners", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateSingleFileProgress handles complete phase", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateSingleFileProgress handles failed phase with error", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateSingleFileProgress handles processing phase", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/progress.test.ts > updateSingleFileProgress handles progress with result data", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/rbac-enforcement.test.ts > role permissions admin has all 17 permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/rbac-enforcement.test.ts > role permissions editor has collaborative but not admin permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/rbac-enforcement.test.ts > role permissions hasPermission checks correctly", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/rbac-enforcement.test.ts > role permissions unknown role returns empty permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/rbac-enforcement.test.ts > role permissions user has basic permissions only", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic ALL_PERMISSIONS constant contains all expected permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic ALL_PERMISSIONS constant contains exactly 14 permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic builtin role protection allows modification of custom roles", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic builtin role protection blocks deletion of builtin roles", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic builtin role protection blocks modification of builtin roles", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic create role validation accepts valid create payload", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic create role validation description is optional", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic create role validation rejects description longer than 500 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic create role validation rejects missing permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic create role validation requires at least one permission", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic permission validation handles empty array", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic permission validation returns all permissions if all are invalid", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic permission validation returns empty array for valid permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic permission validation returns invalid permission strings", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name rename cascading updates all users when role name changes", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation accepts name exactly 2 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation accepts name exactly 30 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation accepts valid lowercase name", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation allows hyphens", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation allows numbers", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation allows underscores", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation converts to lowercase", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation rejects dots in name", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation rejects names longer than 30 characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation rejects single character", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation rejects spaces in name", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation rejects special characters", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic role name validation trims whitespace and lowercases", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic update role validation accepts all fields together", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic update role validation accepts empty update body", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic update role validation accepts partial update with just description", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic update role validation accepts partial update with just name", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic update role validation accepts partial update with just permissions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/roles-route.test.ts > roles route logic user reassignment on role deletion reassigns users to 'user' role when custom role is deleted", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > getSettingNumber defaults defaultValue to 0", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > getSettingNumber returns defaultValue when setting does not exist", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > getSettingNumber returns defaultValue when setting value is NaN", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > getSettingNumber returns the number when setting exists", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > getSettingString defaults defaultValue to empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > getSettingString returns defaultValue when setting does not exist", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > getSettingString returns the string when setting exists", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > upsertSetting handles empty string value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > upsertSetting inserts a new setting", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-helpers.test.ts > upsertSetting updates an existing setting", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation accepts clean keys and values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation accepts values with angle brackets that are not HTML tags", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation allows multiple settings entries", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation rejects HTML tag in the middle of a value", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation rejects HTML tags in keys", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation rejects HTML tags in values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation stringifies boolean values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation stringifies non-string values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML tag validation stringifies object values", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex does not match empty string", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex does not match numeric comparisons", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex does not match plain text", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex matches ", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex matches closing tags", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex matches processing instructions", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex matches tags", "/Users/sidd/Desktop/Personal/Projects/SnapOtter/.claude/worktrees/test+suite-overhaul-and-real-fixtures/tests/unit/api/settings-route.test.ts > settings route logic HTML_TAG_PATTERN regex matches