You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
# ADR-53719: Warn Callers When `logs` MCP Tool Returns Stale Data Without a Date Range
2
+
3
+
**Date**: 2026-08-18
4
+
**Status**: Draft
5
+
**Deciders**: pelikhan, copilot-swe-agent
6
+
7
+
---
8
+
9
+
### Context
10
+
11
+
The `logs` MCP tool paginates workflow runs backwards by creation date until it has collected the requested count. In high-activity repositories, this walk can silently land on a window that is days or weeks old when recent non-agentic runs dominate the page. Callers that omit `start_date`/`end_date` receive stale data with no signal that more recent runs exist, causing deep-report and audit workflows to draw incorrect conclusions about current fleet health (see issue #53683).
12
+
13
+
### Decision
14
+
15
+
We will add a post-query staleness check (`staleLogsWarning`) that fires only when no date range was requested and the newest run in the result set is older than 48 hours. The warning is folded into the output's `message` field by `renderLogsOutput`, then extracted and surfaced verbatim in the MCP tool's top-level response text by `buildLogsFileResponse` so callers see it immediately without opening the cached file.
16
+
17
+
### Alternatives Considered
18
+
19
+
#### Alternative 1: Require explicit date bounds (hard rejection)
20
+
21
+
Reject any `logs` call that omits both `start_date` and `end_date`, returning an error that forces the caller to specify a range.
22
+
23
+
This eliminates the ambiguity entirely but is a breaking change: all existing callers that rely on the count-only invocation pattern would need to be updated simultaneously, and some legitimate use-cases (e.g., "give me the last N runs regardless of when they ran") become impossible to express.
24
+
25
+
#### Alternative 2: Transparent auto-retry with a default date window
26
+
27
+
Detect staleness and automatically re-issue the query with a sensible default `start_date` (e.g., `-1d`) without telling the caller.
28
+
29
+
This silently fixes the common case but hides the ambiguity rather than exposing it. Callers lose visibility into the scope of their query; if the auto-selected window is wrong for a given repo's cadence, results are still wrong—and now there is no warning to prompt investigation.
30
+
31
+
### Consequences
32
+
33
+
#### Positive
34
+
- Callers receive an actionable warning in the MCP response's top-level `message` field immediately, without reading the cached file.
35
+
- No breaking change: callers that already supply explicit date bounds see no difference in behavior.
36
+
- The 48-hour threshold is documented as a named constant (`staleLogsWarningThreshold`), making it easy to tune.
37
+
38
+
#### Negative
39
+
- The staleness heuristic (48 hours) is repo-cadence-agnostic; low-activity repositories may never trigger the warning even when results are genuinely stale, while repos with infrequent runs could trigger false positives.
40
+
- The warning travels through two encoding layers (render → JSON `message` field → guardrail JSON extraction), creating coupling between `renderLogsOutput` and `buildLogsFileResponse` that can silently break if the output schema changes.
41
+
42
+
#### Neutral
43
+
- Unit tests cover all four guard conditions: explicit start date, explicit end date, empty result set, and recent-data threshold, providing a regression baseline for future threshold changes.
44
+
- The `renderLogsOutputOptions` struct gains two new fields (`startDate`, `endDate`) that are threaded from `DownloadWorkflowLogs`, a minor expansion of the internal API surface.
45
+
46
+
---
47
+
48
+
*ADR created by [adr-writer agent]. Review and finalize before changing status from Draft to Accepted.*
response.Message=fmt.Sprintf("PARTIAL RESULTS: the download stopped before all matching runs were collected. %s Partial logs data has been written to '%s'. Use the file_path to read the collected data and the continuation parameters to fetch the remaining logs.", continuation.Message, filePath)
163
+
msgs=append(msgs, fmt.Sprintf("PARTIAL RESULTS: the download stopped before all matching runs were collected. %s Partial logs data has been written to '%s'. Use the file_path to read the collected data and the continuation parameters to fetch the remaining logs.", continuation.Message, filePath))
164
+
} else {
165
+
msgs=append(msgs, fmt.Sprintf("Logs data has been written to '%s'. Use the file_path to read the full data.", filePath))
166
+
}
167
+
// Surface the stale-data warning (when no date range was requested and the
168
+
// newest run returned is unexpectedly old) directly in the tool response so
169
+
// callers see it without having to open the file.
output:=`{"summary":{"total_runs":1},"runs":[],"stale_warning":"No start_date/end_date was specified, and the most recent run in this result is 11 days old."}`
0 commit comments