Skip to content

Slice 1: Contamination fix — derive agent-file filter from tool filediff only #742

Description

@jeonghun-jj-lee

Important

Problem — The Files Changed tab's session.diff() handler builds its agent-touched-file filter from two sources: tool filediff metadata (clean — records exactly what the agent's edit/write/patch/apply_patch tools modified) and patch part file lists (contaminated — captures all worktree changes between step-start and step-finish snapshots, including modifications by other sessions or external processes). The contaminated source causes the tab to show files the current session never edited.

Approach — Remove the patch part file lists from the agentFilesAbsolute set in session.diff(). Derive the filter exclusively from tool filediff metadata. The patch parts retain their snapshot hashes (used for the from/to diff range) but their files arrays no longer feed the filter.

Scope — in: the session.diff() handler's file-filter loop, two new tests. out: the processor's patch-part emission (unchanged), the patch-part schema (unchanged), client-side code.

Acceptance Criteria

  • A session with no edit/write/patch/apply_patch tool calls shows zero files in the Files Changed tab — the session.diff() endpoint returns an empty array
  • A session with edit tool calls shows exactly the files those tools modified (deduplicated by path), with M/A/D status derived from the server's git-state comparison — not from patch-part file lists
  • Concurrent sessions editing different files do not leak files into each other's Files Changed tabs
  • Existing sessions with contaminated patch parts in the DB retroactively show correct (filtered) results

Testing Decisions

  • Zero-edits test (new): construct a session with only read/grep/glob tool parts and patch parts containing file lists — assert session.diff() returns an empty array
  • Contamination test (new): construct a session with patch parts listing files A, B, C alongside tool parts with filediff metadata for file A only — assert session.diff() returns only file A

Key Decisions

  • Filter at the query handler, not the event emitter. The patch/step-end data in the processor is left unchanged — no backward compatibility concerns with existing DB records. The fix is a single loop change in session.diff().
  • Snapshot hashes on patch parts still used. The from/to diff range computation reads step-start and step-finish snapshot hashes from their respective parts — these are independent of the patch.files array and remain the source of truth.

Constraints & Invariants

  • The patch/step-end part schema is unchanged — no migration needed
  • The diff query contract (GET /session/:id/diff) returns only agent-touched files, never workspace-wide changes
  • The fallback chain (summary diffs, tool-part accumulation) continues to work for sessions lacking filediff metadata

Prior Art

Source

Part of #741 · Follow-up to #733

Activity

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

Metadata

Metadata

Labels

afkImplementable without human interaction

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions