Description
Adds a raw http_status_code filter to the tool execution logs endpoint (Linear PLEN-2502), backed by the existing mercury_last_http_status_code column on tool_execution_logs. No migration, no backfill — the column was already populated at insert time, just never read back.
Filter contract (multi-select via comma-separated codes):
{ "field": "http_status_code", "operation": "in", "value": "401,403,429" }
Supported operations: ==, !=, in, not_in. Codes are validated as positive integers and inlined as static SQL literals (no user string reaches the query).
Bucket taxonomy stays out of the backend. The dashboard owns the bucket → codes map (auth → 401,403, rate_limit → 429, etc.) and emits raw codes here. Public SDK contract stays minimal: just the httpStatusCode field on each row + the new filter, no enums. Future bucket evolution doesn't require an API change.
Response shape — both list and detail responses gain httpStatusCode: number | null (and mercury_last_http_status_code is now selected in both getLogs and getSingleLog, where it wasn't before). The v3.1 SDK transformer also populates the existing public data.response.status_code field from the same column instead of hardcoding null. ClickHouse + self-hosted Postgres backends kept in lockstep.
Drive-by fix: clickhouse-tool-logs_test.ts used an underscore instead of a dot, so vitest's *.test.ts include pattern silently skipped it. Renaming surfaces 11 applyClickhouseOperation tests that were never running.
How did I test this PR
- Unit tests: 56/56 across
error_type.test.ts (16 covering isErrorLog + parseHttpStatusCodeFilterValue + buildHttpStatusCodeClickhouseClause), clickhouse-tool-logs.test.ts (11 newly running), and unified-log-transformer.unit.test.ts (29).
- Live ClickHouse: seeded rows with 401/429/500/404/200, hit the endpoint with each operation, then validated the WHERE clauses directly against CH:
in 401,429 → log_b_401, log_b_429
in 500 → log_b_500
not_in 401,429 → log_b_404, log_b_500, log_b_ok
== 404 → log_b_404
pnpm format:check, pnpm lint, pnpm check-types clean on touched files (no net new errors).
🤖 Generated with Claude Code