Live-capture investigations: id-less source taxonomy, quota retry-after metadata, studio inspection fields

Author: teng-linCreated Jul 16, 2026Updated Aug 12, 2026
Labelsbot-generatedneeds-infoP2

From a Codex MCP stress-test (v0.8.0b2). These findings are real gaps but cannot be implemented from code alone — the wire data may not carry the needed fields, so each needs a live capture of the relevant raw RPC response before we can decide whether/how to surface it. Grouped so we do the captures together.

1. Richer source counters / row taxonomy (from #1919, stress-test F5)

source_list filters to id-bearing rows; the ~118 id-less rows in nb_info[1] (research candidates, generated-report stubs, placeholders, ghosts) are dropped at _source/listing.py:168-173 before their type/status can be read. An active / processing / failed split of the real sources is feasible today from decoded per-row status/type_code, but a research-candidate / generated-report / placeholder taxonomy is not — those rows are discarded pre-inspection. Capture needed: raw GET_NOTEBOOK nb_info[1] from a research-heavy notebook, to learn the shape/discriminator of the id-less rows (cf. the Drive url=null / type_code-14 quirks already documented).

2. Quota error retry-after / structured metadata (stress-test F16)

A cinematic-video quota rejection arrives via the in-band USER_DISPLAYABLE_ERROR path (rpc/decoder.py:594-606), where _user_displayable_error_message keeps only a generic string + gRPC status and drops the rest of item[5]. The HTTP-429 path already parses Retry-After (_rpc_executor.py:435-440), but the in-band path does not. A repo-wide grep finds no handling of RetryInfo/QuotaFailure/ErrorInfo google.rpc.* detail types. Capture needed: the raw resource-exhaustion block for cinematic-video, to confirm whether it carries a machine-readable RetryInfo.retryDelay/quota fields. If yes → surface them like the 429 path; if no → monitor-only.

3. Studio artifact inspection metadata (from #1924, stress-test observation)

Completed studio_list rows don't expose duration / question count / slide count / generation duration / source count / generator version, so QA requires downloading each artifact. The row decode (_row_adapters/artifacts.py:104-197) has no positions mapped for these — no code evidence the wire carries them. (Cheap sliver already decoded: created_at and generation_prompt could be added to the summary projection now — that part is actionable without capture.) Capture needed: raw LIST_ARTIFACTS rows for each artifact type, to locate any duration/count slots before adding fields blind.

Do not implement blind — each item is gated on the capture confirming the field exists on the wire.

Filed by Claude Code from stress-test findings; the client-actionable halves are #1919 and #1924.