fix: make Copilot capture attribution consistent#16
Conversation
The VS Code extension was using Date.now() as a session ID (so every
capture looked like a different session) and the heuristic threshold
fired on any large edit — including edits from Claude Code, Cursor, and
human copy-paste — producing silent false positives in session.jsonl.
Changes:
- extension.js: stable WINDOW_SESSION_ID per activation; confidence and
capture_mode fields on every event ("high"/manual vs "low"/heuristic);
doc comment explaining which capture modes are reliable vs. unsupported
- capture-copilot.py: passes confidence + capture_mode through to
session.jsonl; documents mode reliability in module docstring
- prepare-ledger.py: reads copilot events (kept excluded from
attribution) and builds a copilot_context summary (event count,
low_confidence flag, files, lines) for the pending payload
- finalize-ledger.py: propagates copilot_context into trace metadata
- data.rs: adds copilot_context field to AgentdiffMetadata
- list.rs: shows "~cpl" in TRUST column when low-confidence events exist
- report.rs: emits a warning note in Review Context markdown section
when low-confidence heuristic capture is detected
- test_capture_copilot.py (new): 10 tests covering all capture modes,
tool mappings, path resolution, and silent-exit behaviour
- test_extension.js: 3 new tests for confidence fields and session ID
stability
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Greptile SummaryThis PR fixes three bugs that made Copilot capture attribution unreliable: a per-call
Confidence Score: 4/5Safe to merge; one test has a logic gap that could cause a false failure in environments where AGENTDIFF_SESSION_LOG is set. The new scripts/tests/test_capture_copilot.py — unused Important Files Changed
Reviews (2): Last reviewed commit: "fix: scope Copilot warning to current in..." | Re-trigger Greptile |
| // These limitations exist because VS Code does not expose a stable public API | ||
| // that identifies the source of a document edit as Copilot vs. human vs. other | ||
| // agent. The VS Code team is tracking this at: | ||
| // https://github.com/microsoft/vscode/issues/XXXXX (placeholder) |
has_cpl_warning was iterating over the full traces slice, causing the warning to appear in every intent group when any single trace had low-confidence Copilot events. Filter to only traces belonging to the current group via group.trace_ids. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
AgentDiff ReportSummary
Review Context
Files To Review First
Trace details
|
| "event": event_name, | ||
| "cwd": str(repo), | ||
| "file_path": str(edited), | ||
| "model": "copilot", | ||
| "session_id": "s", | ||
| "lines": [1], | ||
| "confidence": "high" if event_name == "manual" else "low", | ||
| "capture_mode": event_name if event_name == "manual" else "inline_heuristic", | ||
| } | ||
|
|
There was a problem hiding this comment.
Unused
env dict — test is not actually isolated from environment
The env dict built on line 229 is never used; self.mod.get_session_log(str(repo)) reads os.environ directly. If AGENTDIFF_SESSION_LOG is set to a non-empty value in the process environment (e.g. by a CI runner), get_session_log follows the override path and returns a non-None path, causing the assertIsNone assertion to fail. Compare test_get_session_log_returns_path_when_initialized, which explicitly pops the variable before calling the function. The same guard is needed here.
Summary
Fixes #12. Copilot capture attribution was inconsistent due to three separate bugs:
vscode-${Date.now()}was evaluated on everycaptureFile()call, so each event appeared to come from a different session, breaking per-session grouping.MIN_COPILOT_CHANGE_LEN = 50fires on any large document change — including edits from Claude Code, Cursor, Codex, or human copy-paste. These false positives silently polluted session.jsonl with non-Copilot events.agentdiff.captureNowcommand) from heuristic guesses.Changes
extension.jsWINDOW_SESSION_IDper activation;confidence("high"/"low") andcapture_modefields on every event; doc comment listing reliable vs. unsupported modescapture-copilot.pyconfidence+capture_modethrough to session.jsonl; module docstring documents mode reliabilityprepare-ledger.pycopilot_contextsummary in the pending payloadfinalize-ledger.pycopilot_contextinto trace metadatasrc/data.rscopilot_context: Option<serde_json::Value>toAgentdiffMetadatasrc/commands/list.rs~cplin the TRUST column when low-confidence events existsrc/commands/report.rsscripts/tests/test_capture_copilot.py(new)scripts/tests/test_extension.jsTest plan
python3 -m pytest scripts/tests/ -v— 30/30 passnode --test scripts/tests/test_extension.js— 14/14 passcargo test— 35/35 pass🤖 Generated with Claude Code