Skip to content

session-flow/running-retro: detached observer's distilled observations never preserve enough structure to compute sequencing/batching/delegation/dependency claims #1485

Description

@kyle-sexton

Context

Filed from PR #1482 (fix for #1473 recommendation 1, the running-retro compute-don't-assert prompt
rule). Both claude[bot]'s PR review and Codex's automated review independently flagged the same
consistency gap: the detached observer's headless analysis prompt (observer.py's
_analysis_prompt) instructs the analyzer to derive tool-call sequencing/batching/delegation claims
by "grouping tool-use events by API message id" — but summarize_record() (the function that
produces the distilled observations the headless run actually receives) never preserves a
message-id field. It extracts only type, timestamp, tools, a truncated text snippet, and
stop_reason.

PR #1482 closed the immediate correctness gap defensively: the prompt now states explicitly that an
absent message-id field makes the claim uncomputable, so the analyzer drops it rather than asserting
it from impression (the compute-don't-assert rule's fallback already covered this). That is safe,
but it means the headless observer path can never actually compute a sequencing/batching/delegation
finding — it can only ever drop that finding class. The in-session checkpoint path (which reads the
full transcript directly) is unaffected.

Codex's suggested remediation is a genuine capability restoration, not just a prompt clarification:
preserve enough structure in the distilled observations (either the real API message id, or an
explicit per-assistant-turn grouping boundary) so the headless path can compute these findings
instead of always dropping them. That is a change to summarize_record()'s output schema and the
observations' on-disk shape — a larger, separately-scoped piece of work, not a text-only fix, so it
was deferred out of #1482 rather than expanding that PR's scope.

Addendum (from claude[bot]'s review of PR #1482 commit 8f29a28): the same gap extends to the
dependency check PR #1482 later added (a computed sequencing fact isn't proof of a missed batching
opportunity when the calls are dependent). That check tells the headless agent to inspect the calls'
tool inputs and result content — but summarize_record() strips both: it preserves only tool
names (out["tools"] = [c.get("name") ...]) and result counts (out["tool_results"] = results),
never the actual input arguments or result values. So the dependency check is equally uncomputable
on the headless path today — same interim fallback applies (drop the Efficiency finding rather than
infer dependency from tool names alone), same underlying schema gap this item tracks.

Proposed work

  • Add a stable grouping key to each distilled observation summarize_record() emits — either the
    transcript record's own message id (if present in the raw JSONL) or an explicit per-assistant-turn
    boundary marker the headless prompt can group on.
  • Preserve enough of each tool call's input arguments and result content (or a bounded/truncated
    summary of them) for the headless path to check for a data/control/resource/side-effect dependency
    between calls, not just their names and result counts.
  • Update observer.py's _analysis_prompt to reference the new fields instead of (or in addition
    to) "API message id" / "tool inputs/results," and drop the corresponding "may not carry..." caveats
    once those fields are reliably present.
  • Verify token-cost impact is acceptable — summarize_record()'s whole design goal is a token-cheap
    distillation; any added field should stay minimal (an integer/short id, a truncated argument/result
    summary, not full message objects).

Acceptance criteria

  • summarize_record()'s output carries a grouping key sufficient to reconstruct tool-call
    batching/sequencing without the raw transcript.
  • summarize_record()'s output carries enough of each tool call's inputs/results (or a bounded
    summary) to support a dependency check between calls without the raw transcript.
  • The headless analysis prompt in observer.py can compute a sequencing/batching/delegation
    finding, and a data/control/resource/side-effect dependency check backing an Efficiency
    finding, from the distilled observations alone — verified by a test that builds observations
    from real transcript-shaped records and checks both round-trip correctly.
  • No meaningful token-cost regression to the distilled observations file.

References

Metadata

Field Value
Category session-flow / running-retro
Area session-flow
Ecosystem python

This was generated by AI during work-loop execution.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions