Skip to content

Findings: the evidence pane and the assessment parts split by concern - #1799

Merged
nadaverell merged 4 commits into
mainfrom
refactor/findings-structure
Sep 17, 2026
Merged

nadaverell merged 4 commits into
mainfrom
refactor/findings-structure

Conversation

@nadaverell

@nadaverell nadaverell commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The Findings pane and its assessment parts are split by concern. Nothing changes for a reader: the same cards, folds, chips and steps render from the same record. What changes is where the code lives, so a card change is a change to one file rather than to a 4,000-line pane, and the two files that every future evidence feature touches (the card and its bodies) now have one owner each.

What changed

The evidence pane, one module per concern

InvestigationEvidencePane.tsx keeps the component: its state, the reveal logic and the layout. Everything else moved with its comments, and imports run one way: pane → sections → card → bodies → card parts → context and types.

Now in What
investigationEvidence/navigation.tsx EvidenceNavigationContext (same object, so provider identity is preserved) and InvestigationTimelineScope
investigationEvidence/cardParts.tsx SourceButton, EvidenceIcon, EvidenceCaveat, ResourceFact, OpenResourceButton, OpenTimelineButton, EvidenceDataOf, the severity and phase helpers
investigationEvidence/bodies/ the sixteen body renderers in six families: workload (issue, startup, crash, resource with GitOps status and scaled-by), streams (logs, events, changes), network (dns, network, relationships, topology), inventory (with InventoryRow and namedInventoryRows), metrics (metrics, alerts), platform (helm, permissions); index.tsx holds EvidenceBody and evidenceHasDetails
investigationEvidencePartition.ts partitionInvestigationEvidence and the six pure helpers beside it
EvidenceCard.tsx the card and RevisionHistory
InvestigationEvidenceSections.tsx CoverageStrip, CoverageGroupRow, CollapsedEvidenceCollection, EmptyCollection, RuledOutBlock, AssessmentEvidenceQualification

parts.tsx, split behind an explicit barrel

Now in What
AgentControls.tsx agent controls, model and effort options, consent card
ActivityTurn.tsx TurnView, Timeline, ToolRow, ToolResultDialog, the startup and thinking helpers, the label helpers
ApplyDialog.tsx ApplyDialog, ApplyOutcomeCard
AssessmentCard.tsx ResultCard, DiagnosisResult with its next steps, AllClearCard, InconclusiveCard, AssessmentHeadline, AssessmentSources, the remediation helpers
assessmentCopy.ts assessmentCopyText and the labels it shares with the cards (pure)
AIMarkdown.tsx AIMarkdown, CopyButton
toolCallLabel.ts prettyTool, moved down so the label module imports nothing from the UI

parts.tsx re-exports the same public names, so its twelve importers are unchanged; no internal module imports the barrel.

Two small shape changes, each its own commit

  • AnalysisStory takes placements as a prop. The pane already resolves the story once for its own counts; the story no longer resolves it again.
  • The running label is investigationRunningLabel in toolCallLabel.ts, a pure function with tests for the call in flight, the quiet seconds after one finishes, the flip to Thinking, and the counters. The view calls it.

Left for later, deliberately

Splitting InvestigationView (2,400 lines, 29 hooks) needs a state-ownership plan and interaction coverage first. The excerpt slot and the focus contract belong to the next feature PR, where their behaviour is defined.

Testing

  • make tsc; cd web && npm test (113 files, 1338 tests); cd packages/k8s-ui && npm test (3771); npm run lint (0 errors); git diff --check.
  • Every moved declaration compared with its original on main by code (comments stripped, whitespace removed): identical apart from the export keyword and prettier's reflow. One regex quantifier mangled by an import cleanup was caught this way and restored before the commit.
  • The same scripted interaction check run on two saved investigations before and after the change: card count and titles in the story, inline log lines, fold open, close and reopen, the Captured results toggle, and two Activity-to-Findings round trips. Identical results on both runs.
  • Import direction checked by grep: no body or card part imports the pane, the sections or the card; no module imports the parts barrel.

Note

Low Risk
Refactor with preserved exports and broad test coverage; main risk is accidental import/barrel cycles or a missed re-export, not production logic changes.

Overview
Structural refactor of the diagnose Findings surface: large blocks move out of monolithic pane/parts files into focused modules. User-visible behavior is intended unchanged; imports and ownership change so card, body, and assessment work land in smaller files.

The evidence pane keeps InvestigationEvidencePane as the shell; partitioning, navigation context, card chrome, EvidenceCard, section layouts, and six body families (workload, streams, network, inventory, metrics, platform) live in dedicated paths under investigationEvidence/. Tests follow the new import locations (e.g. VISIBLE_LOG_EVIDENCE_LINES, namedInventoryRows, partitionInvestigationEvidence).

Assessment and activity UI split from parts into AgentControls, ActivityTurn (turns, timeline, tool rows, dialogs), ApplyDialog, AssessmentCard, plus AIMarkdown / CopyButton (clipboard UX, fence normalization, softer inline code) and assessmentCopy / toolCallLabel. parts still re-exports the same public names so existing ./parts importers stay stable.

AnalysisStory now accepts pre-resolved placements (StoryPlacements) instead of report + resolveItem, so hosts resolve once for counts and rendering; tests pass resolveStoryPlacements(...) explicitly.

Minor formatting-only diffs in a few test/surface files; DiagnoseSurface import line-wrap only in the shown diff.

Reviewed by Cursor Bugbot for commit 8c8af11. Bugbot is set up for automated code reviews on this repo. Configure here.

The pane keeps its component, state, reveal logic and layout. The
navigation context, the shared card parts, the sixteen body renderers in
six families, the pure partition helpers, the card and the coverage and
collection sections each live in their own module, with imports running
one way: pane, sections, card, bodies, card parts, context and types.
Nothing changes shape; every declaration moved with its comment.
Agent controls and consent, the Activity turn and timeline, the Apply
dialog, the assessment cards with their next steps, the pure copy text and
the shared markdown and copy button each live in their own module.
parts.tsx re-exports the same public names, so its consumers do not
change; no internal module imports the barrel. prettyTool moves down into
the label module it belongs with.
The pane already resolves the story once for its own counts; the story
takes that result as a prop instead of resolving it again.
The label's rule lived in a closure inside the view; it is now a pure
function in the label module, pinned by tests for the call in flight, the
quiet seconds after one finishes, the flip to Thinking, and the counters.
@nadaverell
nadaverell requested a review from hisco as a code owner September 17, 2026 11:25
@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Split findings evidence and assessment UI by concern

âœĻ Enhancement 🧊 Tests 🕐 40+ Minutes

Grey Divider

AI Description

â€Ē Split evidence rendering, cards, navigation, and partitioning into focused modules.
â€Ē Replace monolithic assessment parts with concern modules behind a compatible barrel.
â€Ē Reuse resolved story placements and test pure running-label behavior.
Diagram

graph TD
  IV["Investigation View"] --> EP["Evidence Pane"] --> ES["Evidence Sections"] --> EC["Evidence Card"] --> EB["Body Renderers"] --> CP["Card Parts"]
  IV --> PB["Parts Barrel"] --> AM["Assessment Modules"]
Loading
High-Level Assessment

The concern-based extraction with a compatibility barrel is the appropriate approach for a behavior-preserving refactor. Removing the barrel would create unnecessary consumer churn, while splitting the state-heavy InvestigationView in the same PR would substantially increase behavioral risk without dedicated interaction coverage.

Files changed (34) +7786 / -7450

Refactor (26) +7685 / -7402
AIMarkdown.tsxExtract AI markdown and clipboard controls +87/-0

Extract AI markdown and clipboard controls

â€Ē Moves normalized agent-markdown rendering and copy-state feedback from the former parts monolith into a shared focused module.

web/src/components/diagnose/AIMarkdown.tsx

ActivityTurn.tsxExtract activity turns and tool timeline +1243/-0

Extract activity turns and tool timeline

â€Ē Moves turn models, startup handling, timeline rendering, tool rows, payload dialogs, thinking blocks, and related helpers into the activity concern.

web/src/components/diagnose/ActivityTurn.tsx

AgentControls.tsxExtract agent configuration and consent UI +603/-0

Extract agent configuration and consent UI

â€Ē Moves agent, execution profile, model, effort, and consent controls into a dedicated module without changing their public behavior.

web/src/components/diagnose/AgentControls.tsx

AnalysisStory.tsxAccept resolved story placements from the host +13/-18

Accept resolved story placements from the host

â€Ē Introduces the StoryPlacements interface and changes AnalysisStory to consume precomputed placements, avoiding duplicate resolution inside the component.

web/src/components/diagnose/AnalysisStory.tsx

ApplyDialog.tsxExtract apply confirmation and outcome cards +289/-0

Extract apply confirmation and outcome cards

â€Ē Moves apply confirmation, safety acknowledgements, and mutation outcome presentation into a dedicated apply module.

web/src/components/diagnose/ApplyDialog.tsx

AssessmentCard.tsxExtract assessment cards and remediation UI +1560/-0

Extract assessment cards and remediation UI

â€Ē Moves diagnosis routing, assessment headlines and sources, healthy and inconclusive states, remediation steps, and assessment helpers into one assessment-focused module.

web/src/components/diagnose/AssessmentCard.tsx

DiagnoseSurface.tsxReformat animation imports +5/-1

Reformat animation imports

â€Ē Reflows the animation utility import after the broader module split; runtime behavior is unchanged.

web/src/components/diagnose/DiagnoseSurface.tsx

EvidenceCard.tsxExtract evidence cards and revision history +693/-0

Extract evidence cards and revision history

â€Ē Moves evidence card rendering, story-specific details, expansion behavior, navigation controls, and prior observation history out of the pane.

web/src/components/diagnose/EvidenceCard.tsx

Home.tsxReformat recent investigation kind selection +2/-1

Reformat recent investigation kind selection

â€Ē Reflows the readable-kind conditional in RecentList with no functional change.

web/src/components/diagnose/Home.tsx

InvestigationEvidencePane.tsxReduce the evidence pane to orchestration and layout +31/-3445

Reduce the evidence pane to orchestration and layout

â€Ē Removes embedded cards, sections, bodies, navigation context, and partition helpers in favor of focused modules. The pane retains state, reveal behavior, story composition, and layout, and now passes its already-resolved story placements to AnalysisStory.

web/src/components/diagnose/InvestigationEvidencePane.tsx

InvestigationEvidenceSections.tsxExtract evidence collection and coverage sections +523/-0

Extract evidence collection and coverage sections

â€Ē Moves ruled-out evidence, assessment qualification, empty states, collapsed collections, and coverage detail rendering into a dedicated sections module.

web/src/components/diagnose/InvestigationEvidenceSections.tsx

InvestigationView.tsxUse extracted evidence partitioning and running labels +11/-28

Use extracted evidence partitioning and running labels

â€Ē Imports partitioning from its dedicated module and delegates assessment progress text, counters, and quiet-period transitions to investigationRunningLabel.

web/src/components/diagnose/InvestigationView.tsx

assessmentCopy.tsExtract pure assessment copy generation +169/-0

Extract pure assessment copy generation

â€Ē Moves channel-ready assessment text generation and shared certainty and step labels into a UI-independent module.

web/src/components/diagnose/assessmentCopy.ts

index.tsxAdd centralized evidence body dispatch +115/-0

Add centralized evidence body dispatch

â€Ē Introduces the EvidenceBody dispatcher and detail-detection logic for all supported evidence data variants.

web/src/components/diagnose/investigationEvidence/bodies/index.tsx

inventory.tsxExtract inventory evidence rendering +126/-0

Extract inventory evidence rendering

â€Ē Moves inventory row rendering, scoped citation matching, and absent or ambiguous row handling into the inventory body module.

web/src/components/diagnose/investigationEvidence/bodies/inventory.tsx

metrics.tsxExtract metrics and alert evidence bodies +373/-0

Extract metrics and alert evidence bodies

â€Ē Moves metric charts, sparse and instant value handling, change annotations, and alert rule and instance presentation into the metrics family.

web/src/components/diagnose/investigationEvidence/bodies/metrics.tsx

network.tsxExtract network evidence bodies +274/-0

Extract network evidence bodies

â€Ē Moves DNS findings, route checks, relationship graphs, and topology summaries into the network body family.

web/src/components/diagnose/investigationEvidence/bodies/network.tsx

platform.tsxExtract Helm and permission evidence bodies +318/-0

Extract Helm and permission evidence bodies

â€Ē Moves Helm release health and owned-resource rendering plus RBAC access and binding details into the platform body family.

web/src/components/diagnose/investigationEvidence/bodies/platform.tsx

streams.tsxExtract logs, events, and changes bodies +211/-0

Extract logs, events, and changes bodies

â€Ē Moves bounded log excerpts, event timelines, resource changes, and the shared visible-log limit into the stream body family.

web/src/components/diagnose/investigationEvidence/bodies/streams.tsx

workload.tsxExtract workload evidence bodies +335/-0

Extract workload evidence bodies

â€Ē Moves issue, startup, crash, resource, GitOps, replica, condition, and scaler presentation into the workload body family.

web/src/components/diagnose/investigationEvidence/bodies/workload.tsx

cardParts.tsxExtract shared evidence card parts +306/-0

Extract shared evidence card parts

â€Ē Moves source and navigation controls, icons, caveats, resource facts, severity mapping, phase labels, and border helpers into a shared card-parts module.

web/src/components/diagnose/investigationEvidence/cardParts.tsx

navigation.tsxExtract evidence navigation context +26/-0

Extract evidence navigation context

â€Ē Moves the existing navigation context and timeline scope contract into a low-level module so cards and bodies share the same provider identity.

web/src/components/diagnose/investigationEvidence/navigation.tsx

investigationEvidencePartition.tsExtract pure evidence partitioning helpers +296/-0

Extract pure evidence partitioning helpers

â€Ē Moves collection selection and ordering, full-row layout decisions, case grouping, reveal routing, and revision-history filtering into a pure module.

web/src/components/diagnose/investigationEvidencePartition.ts

parts.tsxReplace the parts monolith with a compatibility barrel +26/-3904

Replace the parts monolith with a compatibility barrel

â€Ē Removes embedded implementations and re-exports the same public assessment, activity, apply, controls, copy, and label APIs from concern-specific modules.

web/src/components/diagnose/parts.tsx

target.tsReformat target identity helpers +9/-3

Reformat target identity helpers

â€Ē Reflows navigation imports and canonical target formatting without changing generated investigation target labels.

web/src/components/diagnose/target.ts

toolCallLabel.tsMove tool formatting and running labels into pure helpers +41/-2

Move tool formatting and running labels into pure helpers

â€Ē Removes the dependency on the UI barrel, defines prettyTool locally, and adds a pure helper for assessment progress labels and counters.

web/src/components/diagnose/toolCallLabel.ts

Tests (8) +101 / -48
AnalysisStory.test.tsxAdapt story tests to pre-resolved placements +31/-25

Adapt story tests to pre-resolved placements

â€Ē Updates AnalysisStory test fixtures to resolve placements before rendering and pass the resulting placement object as a prop.

web/src/components/diagnose/AnalysisStory.test.tsx

DiagnoseSurface.test.tsxReformat diagnose surface assertions +9/-9

Reformat diagnose surface assertions

â€Ē Applies formatter-driven line wrapping to rerun eligibility assertions without changing coverage or expectations.

web/src/components/diagnose/DiagnoseSurface.test.tsx

Home.test.tsxReformat investigation home fixture +1/-3

Reformat investigation home fixture

â€Ē Simplifies formatting of the InvestigationHome render call without changing the test scenario.

web/src/components/diagnose/Home.test.tsx

InvestigationEvidencePane.story.test.tsxImport inventory helpers from their new module +2/-4

Import inventory helpers from their new module

â€Ē Updates story tests to import named inventory row resolution directly from the extracted inventory body module.

web/src/components/diagnose/InvestigationEvidencePane.story.test.tsx

InvestigationEvidencePane.test.tsxRetarget evidence tests to extracted modules +5/-3

Retarget evidence tests to extracted modules

â€Ē Updates test imports for log limits and evidence partition helpers while retaining pane-specific imports.

web/src/components/diagnose/InvestigationEvidencePane.test.tsx

investigationCase.test.tsxRetarget case tests to partition helpers +2/-2

Retarget case tests to partition helpers

â€Ē Updates investigation-case tests to import pane rendering and pure evidence partition helpers from their respective modules.

web/src/components/diagnose/investigationCase.test.tsx

identity.test.tsReformat evidence identity expectation +4/-1

Reformat evidence identity expectation

â€Ē Reflows a root-cause evidence resolution assertion without altering expected identity behavior.

web/src/components/diagnose/investigationEvidence/identity.test.ts

toolCallLabel.test.tsTest pure investigation running labels +47/-1

Test pure investigation running labels

â€Ē Adds coverage for active calls, the post-call quiet period, transition to Thinking, read counters, elapsed time, and the initial state.

web/src/components/diagnose/toolCallLabel.test.ts

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 17, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (2) 📎 Requirement gaps (0) ðŸŽĻ UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Status panels ignore theme backgrounds 📘 Rule violation ⚙ Maintainability
Description
ApplyDialog, ActivityTurn, AgentControls, and related split components use palette utilities
such as bg-amber-500/20, bg-red-500/10, and bg-emerald-500/5 instead of approved theme
background tokens. These colors appear whenever warning, error, or success states render, so theme
changes do not reach those surfaces.
Code

web/src/components/diagnose/ApplyDialog.tsx[64]

+        <div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-full bg-amber-500/20">
Evidence
Rule 3036653 permits only the listed theme background utilities. The cited split components add
hardcoded red, amber, and emerald background classes without a documented design-spec exception.

Rule 3036653: Use theme background tokens instead of hardcoded utility color classes
web/src/components/diagnose/ActivityTurn.tsx[394-394]
web/src/components/diagnose/AgentControls.tsx[294-294]
web/src/components/diagnose/ApplyDialog.tsx[64-64]
web/src/components/diagnose/AssessmentCard.tsx[1319-1319]
web/src/components/diagnose/InvestigationEvidenceSections.tsx[92-92]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Several split diagnosis components use hardcoded Tailwind palette background utilities instead of the approved theme background tokens.
## Fix Focus Areas
- web/src/components/diagnose/ActivityTurn.tsx[394-394]
- web/src/components/diagnose/AgentControls.tsx[294-294]
- web/src/components/diagnose/ApplyDialog.tsx[64-64]
- web/src/components/diagnose/AssessmentCard.tsx[1319-1319]
- web/src/components/diagnose/InvestigationEvidenceSections.tsx[92-92]
## Recommended Fix
Replace the hardcoded red, amber, and emerald background utilities with the appropriate `bg-theme-base`, `bg-theme-surface`, `bg-theme-elevated`, or `bg-theme-hover` token. Preserve state semantics through existing semantic borders, icons, badges, and text colors rather than raw background palette classes.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. A timeline comment duplicates its type 📘 Rule violation ⚙ Maintainability
Description
TimelineItem is immediately preceded by a comment that translates its union into prose as “agent
reasoning, or a tool call.” The adjacent thinking and tool variants already express that
distinction, so a later type change must update duplicate information that supplies no rationale.
Code

web/src/components/diagnose/ActivityTurn.tsx[139]

+// TimelineItem is one ordered transcript entry: agent reasoning, or a tool call.
Evidence
Rule 3036542 disallows comments that only restate immediately adjacent code. The cited comment
describes exactly the thinking and tool alternatives declared on the following lines.

Rule 3036542: Avoid explanatory comments that restate obvious code behavior
web/src/components/diagnose/ActivityTurn.tsx[139-142]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The comment above `TimelineItem` merely restates the two variants visible in the adjacent union and adds no intent, constraint, or rationale.
## Fix Focus Areas
- web/src/components/diagnose/ActivityTurn.tsx[139-140]
## Recommended Fix
Delete the redundant comment and leave the self-describing discriminated union unchanged.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
ðŸ’Ą Did you know, you can enable the Remediation agent and Qodo fixes findings in a dedicated fix PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread web/src/components/diagnose/ApplyDialog.tsx
Comment thread web/src/components/diagnose/ActivityTurn.tsx
@nadaverell
nadaverell merged commit 81abf71 into main Sep 17, 2026
9 checks passed
@nadaverell
nadaverell deleted the refactor/findings-structure branch September 17, 2026 13:38
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