Skip to content

MCP budget: finish get_analysis_findings default limit and text previews (#4198) - #4266

Merged
erikdarlingdata merged 11 commits into
devfrom
fix/4198-analysis-findings-default
Sep 25, 2026
Merged

erikdarlingdata merged 11 commits into
devfrom
fix/4198-analysis-findings-default

Conversation

@erikdarlingdata

@erikdarlingdata erikdarlingdata commented Sep 25, 2026 •

Copy link
Copy Markdown
Owner

Part of #4198.

Finishes lane TG's work on get_analysis_findings (both products), picked up from checkpoint e159afd5 after TG stopped at its 200-turn limit.

Why

get_analysis_findings had no default response-size budget. A busy production store's default call (24h, no limit) measured 66,838 bytes, well over the shared 32 KB McpResponseBudget.DefaultBytes. TG sized the fix. A default limit of 18 diagnostic chains caps the page, and findings_truncated flags a cut. Each finding's confidence_basis and its advice (investigation/remediation) preview to 160 characters by default, with *_truncated flags and a full_text opt-in. remediation_command is never previewed, because a half risk-disclosure header on a destructive change is worse than none.

What changes

  • Built both test projects and fixed what did not compile against the checkpoint's own targets.
  • The limit parameter's description was 225 characters, over the D2 200-char cap for a converted tool's parameter. Cut it to 122 characters and moved the detail into the tool's guide tail, on both products.
  • Fixed a missing space the checkpoint's head-sentence insertion left ("whole.confidence_basis").
  • Caught a second, stricter budget. Lite's full suite (McpToolGuideTests, McpToolGuideHeadsSqlCoreTests) enforces a hard 620-character served-head cap that McpToolsListBudgetTests' looser check (1000 hard, 600 target) does not. The checkpoint's head-sentence addition pushed the served head to 740 characters. That fact is not in either guide's required guardrail roster. It is now covered in the tail, so the sentence is dropped from the head entirely. The head is back to its exact original text: 610 served bytes on both products.
  • Fixed the /api/read row for get_analysis_findings in DarlingWebEndpoints.cs. It had inherited the new limit: 18 / full_text: false defaults. That limited the web viewer's two "Analysis Findings" tables to 18 of a window's chains. The tables render no field the text preview cuts, so only the row-count cut was visible. It now passes Rows(c, "limit", MaxRowLimit) and QueryBool(c, "full_text", true), matching what dev always returned: every chain, full text. Added a no-rig source-scan pin in DarlingWebEndpointsTests (GetAnalysisFindingsRow_PassesTheOldViewerDefaults_EveryChainFullText) that fails if the row regresses. GetAnalysisFindings needs a live Postgres connection, so the row cannot be pinned by invoking it directly.
  • Census: classified the four new payload keys in McpPayloadContractCensusTests. findings_truncated and findings_truncated_note join SecondBoundCutKeys and CutNoteKeys as a second, independent page cut beside the tool's pre-existing truncated/truncation_note. confidence_basis_truncated and advice_truncated start a new FieldPreviewCutKeys roster. It uses the same name and tuple shape #4254 uses for get_deadlock_detail, so a later merge only needs to combine array entries.
  • Updated both products' McpToolsListBudgetTests pins: the two new parameter lines (limit 122, full_text 146), and each product's TotalCeilingBytes. The ceiling raised by the measured growth (+364 Darling, +353 Lite), with a change-log comment.
  • Merged origin/dev. Resolved one conflict: both branches had raised TotalCeilingBytes from different base points, so the resolution kept both change-log comments and combined the growth.

Test plan

  • Darling.Tests and Lite.Tests both build, 0 warnings, 0 errors.
  • New live test DarlingMcpAnalysisFindingsBudgetLiveTests (30 planted chains, realistic prose, mixed remediation shapes). Default call is 28,711 bytes (budget 32,768), 18 of 30 chains returned. full_text: true, limit: 30 returns all 30 untruncated. The production "before" measurement (66,838 bytes) is documented in the test's own doc comment.
  • Proved the pin is meaningful. Temporarily flipped the Darling tool's defaults back to old behavior (limit = 1000, full_text = true, parameters kept), rebuilt, and ran the live test. It failed (finding_count came back 30, not the pinned 18), then was reverted.
  • Lite's twin live-shaped test in McpAnalysisFindingsCommandTests (same 30-chain seed) passes under budget.
  • McpPayloadContractCensusTests: all pass (77 test cases in the combined Darling run touching this area).
  • McpToolsListBudgetTests: both products, 5/5 pass, totals match pins exactly (Darling 172,083/172,083, Lite 90,234/90,234).
  • DarlingWebEndpointsTests: 68/68 pass, including the new no-rig pin.
  • Full Darling.Tests suite (rig-tg, port 55982, UTC): 13,882 total, 3 failed, 47 skipped, 1 not run. The 3 failures (TrendPayloadBudgetLiveTests, CaptureDownChunkOrderTests, ServerListAndSummaryPlanShapeTests) are TimescaleDB chunk-count/plan-shape tests unrelated to any file this PR touches (collection_log chunk append plans). They reproduce in isolation on this rig, but dev's own latest Build run (2026-09-19) is green. This reads as accumulated chunk state on the long-lived, reused rig-tg (shared across TG's session and mine), not a code regression. Flagging for the coordinator rather than filing an issue. I cannot rule out rig state without restarting a rig my brief told me to reuse as-is.
  • Full Lite.Tests suite: 5343 total, 0 failed, 0 skipped. One run earlier in the session showed a one-off fail in AnalysisPassTokenThreadingTests.TheReadLockWaitIsAbandonableWhileAWriterHoldsIt, a timing-sensitive threading test in a file this PR does not touch. It passed both alone and in this final clean run.

CHANGELOG entry

None. This PR is test, description and wiring fixes on top of TG's still-unmerged #4198 work. The user-visible entry belongs with the parent #4198 PR once every lane's work lands.

Generated with Claude Code

https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3

erikdarlingdata and others added 6 commits September 25, 2026 03:31
Checkpoint of lane TG's uncommitted work at its 200-turn stop. Not yet
built or tested as a whole; a finishing lane completes it.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
…er row

Both build now. The limit parameter description was 225 characters, over
the D2 200-char cap for a converted tool's parameter; cut it to the
essentials and moved the longer explanation into the tool's guide tail
(after <<GUIDE>>), on both products. Also fixed a missing space the
checkpoint's head-sentence insertion left ("whole.confidence_basis").

The /api/read row for get_analysis_findings inherited the new limit:18/
full_text:false defaults, which would have shown the web viewer's two
"Analysis Findings" tables only 18 of a window's chains. Pass
Rows(c, "limit", MaxRowLimit) and QueryBool(c, "full_text", true) so the
row keeps returning what dev always did: every chain, full text. Added a
no-rig source-scan pin (DarlingWebEndpointsTests) that fails if the row
regresses, since GetAnalysisFindings needs a live Postgres connection and
can't be pinned by invoking it directly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
Classified the four new payload keys (findings_truncated,
findings_truncated_note, confidence_basis_truncated, advice_truncated)
in McpPayloadContractCensusTests: findings_truncated/_note join
SecondBoundCutKeys/CutNoteKeys as a second, independent page cut beside
the tool's pre-existing truncated/truncation_note; confidence_basis_
truncated/advice_truncated start a new FieldPreviewCutKeys roster (added
with the same name and tuple shape #4254 uses for get_deadlock_detail, so
a later merge only needs to combine array entries).

Updated both products' McpToolsListBudgetTests pins for the grown tool:
the served head (610 -> 740 bytes, from the new head sentence), the two
new parameter lines (limit 122, full_text 146), and each product's
TotalCeilingBytes raised by the measured +495 bytes, with a change-log
comment. Both products' McpToolsListBudgetTests classes pass (5/5 each).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
…ings-default

# Conflicts:
#	Darling/Darling.Tests/McpToolsListBudgetTests.cs
Lite's full suite caught a hard 620-char served-head cap
(McpToolGuideTests.EveryConvertedHead_StaysAtOrUnder620Characters and
its SqlCore sibling) that McpToolsListBudgetTests' looser 1000-char/
600-target check didn't. TG's head-sentence addition ("Default limit 18
chains...") pushed the served head to 740; that fact isn't in either
guide's required guardrail roster (McpToolGuideHeads.SqlCore.cs), and
it's now covered in the tail I added in the prior commit, so the
sentence is dropped from the head entirely rather than trimmed. The head
is back to its exact original text (610 served bytes on both products).

Banked the resulting savings in both products' pins: the per-tool line
back to 610, and TotalCeilingBytes lowered to the newly measured total
(the two new parameters still cost real bytes: +364 Darling, +353 Lite).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
Merged duplicate FieldPreviewCutKeys arrays (branch's confidence_basis+advice
from analysis_findings, dev's deadlock+query_text) into one. Removed duplicate
description item. Budget: analysis_findings+audit+plan_corrections+deadlock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
@erikdarlingdata erikdarlingdata changed the title DO NOT MERGE (MCP budget): finish get_analysis_findings default limit and text previews (#4198) MCP budget: finish get_analysis_findings default limit and text previews (#4198) Sep 25, 2026
@erikdarlingdata
erikdarlingdata marked this pull request as ready for review September 25, 2026 08:58
@erikdarlingdata
erikdarlingdata enabled auto-merge (squash) September 25, 2026 08:58
erikdarlingdata and others added 4 commits September 25, 2026 06:17
Darling: HEAD=172,584 (analysis_findings +364) + dev=172,367 -> 172,731
Lite: HEAD=90,624 (analysis_findings +353) + dev=90,418 -> 90,771
Census: take FieldPreviewCutKeys block from dev (HEAD had empty region)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
…truncated

Conflict resolution for McpPayloadContractCensusTests.cs added a second
FieldPreviewCutKeys array after SourceSideCutKeys. The branch already
defined FieldPreviewCutKeys before SourceSideCutKeys, so the result was
a CS0102 duplicate-field error. Remove the second block and add the
missing top_query_text_truncated entry to the first array instead.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
…ings-default

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
A blank line introduced during merge resolution broke the doc comment
XML run between the FieldPreviewCutKeys item and the WithheldSummaryKeys
item, causing DocCommentHygieneTests.EveryDocRunClosesTheSummariesItOpens
to fail.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3
@erikdarlingdata
erikdarlingdata merged commit 07496c9 into dev Sep 25, 2026
15 of 16 checks passed
@erikdarlingdata
erikdarlingdata deleted the fix/4198-analysis-findings-default branch September 25, 2026 12:41
erikdarlingdata added a commit that referenced this pull request Sep 25, 2026
Measured with McpToolsListBudgetTests after merging origin/dev (#4261,
#4258, #4265, #4267, #4264, #4266 and #4268) plus this PR's catalog
changes. Budget, census and tool-guide classes: 219/219.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ
erikdarlingdata added a commit that referenced this pull request Sep 25, 2026
…nder the response budget (#4198) (#4272)

* MCP budget: describe_custom_view_catalog default groups measures by source (#4198)

Default default-argument call was 98,173 bytes (#4198's own measurement), three
times the tool's 32 KB budget. It is pure static reference data (no server/store
read), so the cut groups the 179 measures by source and keeps only
key/displayName/kind/unitFamily/validAggregates per measure; source=<name>
drills into one source's full detail, full_detail=true returns the original
shape unfiltered. /api/catalog (the web Custom Views editor) calls the
underlying builder directly, never this MCP method, so it is unaffected -
pinned in DarlingComposeTests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3

* Trigger CI (draft PR skipped the Build workflow)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ

* Add comment to DarlingMcpCustomViewCatalogSizeTests.cs to trigger Build CI

GitHub did not fire pull_request events for this draft-opened PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ

* fix(#4272): reword validAggregates description - compact drops allowedDimensions, source=<name> returns it

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TszxYhJJbTEh4LrZ56NYo3

* #4272: set TotalCeilingBytes to the measured 174,236 after merging dev

Measured with McpToolsListBudgetTests after merging origin/dev (#4261,
#4258, #4265, #4267, #4264, #4266 and #4268) plus this PR's catalog
changes. Budget, census and tool-guide classes: 219/219.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FVjn4PBJN71NQXdFo6ZxNQ

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant