Skip to content

prune-transcript hook_run reads and re-parses the whole transcript file twice per invocation #188

Description

@SUaDtL

prune-transcript hook_run reads and re-parses the whole transcript file twice per invocation

Severity: medium | Confidence: 0.8 | Effort: S
Where:
plugins/ca/hooks/_prunelib.py:1251-1259
plugins/ca/hooks/_prunelib.py:1316-1329
Evidence: hook_run() does with open(path,'rb') as f: data = f.read() then load_lines(data) (lines 1252-1256) purely to evaluate tail_is_settled(...). It then calls run(path, cfg, session=session), whose body (lines 1324-1328) reopens the same path, reads the full bytes again (orig_bytes = f.read()), and calls load_lines(orig_bytes) a second time to rebuild lines. Both reads/parses operate on the identical on-disk content within one hook_run() call.
Impact: hook_run is the UserPromptSubmit/PreCompact entry point (CODEARBITER_PRUNE=dry|on); it fires on every qualifying user prompt. The transcript file can be large (the routine explicitly tolerates up to 50MB via the st.st_size > (50 << 20) guard, and pruning is specifically targeted at transcripts that have grown large). Reading and JSONL-parsing that file twice roughly doubles the I/O and CPU cost of this hot-path hook on every prune-eligible turn, adding latency the user directly feels before their prompt is processed.
Recommendation: Thread the already-read bytes (or the already-parsed lines) from hook_run's settledness check into run(), e.g. add an optional data=/lines= parameter to run() that hook_run supplies so the file is read and parsed exactly once per invocation.
Acceptance criteria:

  • hook_run's tail_is_settled check and run()'s pruning pass operate on a single read+parse of the transcript file per hook_run invocation (verifiable via a call-count/spy on open()/load_lines in a unit test)
  • Existing prune/hook test suites (test_prune_nudge.py, _prunelib tests) continue to pass unchanged in behavior

Metadata

Metadata

Assignees

No one assigned

    Labels

    sev:medTribunal/triage: medium severity

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions