Repository navigation
FEAT: Shared scan result building blocks and ScenarioRunPage split - #4031
Richard Lundeen (richlundeen) wants to merge 6 commits into
Conversation
- GET /api/attacks/{id}/findings lists findings linked to an attack across Operations,
backed by a new FindingEvidenceEntries.attack_result_id index (Alembic b5d7f9a1c3e6).
- Attack read APIs (summary, metadata, conversations, messages) resolve scan attacks that
are still running through a read-only LiveAttackLookup provided by ScenarioRunService.
Saved results always win; summaries/metadata expose in_progress and scenario_result_id.
- ScenarioActiveConversation.conversation_ids lists every objective conversation so far.
- ScenarioProgressScore carries score_category for progress results and hierarchy nodes.
- Frontend types and attacksApi.getAttackFindings for later layers.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Split ScenarioRunPage into section components and hooks, and add the shared blocks the scan results redesign builds on: OperationParentLink, ScanStatusBadge, OutcomeBadge progress labels and score popover, ScoreDetails over a narrow ScoreSummary, DetailFacts, IdentityDisclosure, AttackActivity, formatAttemptTiming, useAttackFindings, and AttachToFindingsButton. Existing pages adopt them only where output is unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
The popover-enabled badge’s accessible name omits its visible outcome, making success, failure, and error indistinguishable to screen-reader users without opening each popover.
1 open issue
What changed in this PR
This adds the frontend foundations for the scan-results redesign, building on #4030’s backend APIs. It splits ScenarioRunPage into focused sections and hooks, following #3526’s approach, while preserving the existing layout and improving attack-dialog focus return.
Changes:
- Extracts run controls, attack selection, navigation, and page sections.
- Centralizes status badges, score details, identity disclosure, and reusable result components.
- Adds findings-loading and attachment helpers for the next redesign layer.
| File | Description |
|---|---|
| tests/unit/memory/test_score_participation_migration.py | Allows a newer single migration head. |
| tests/unit/memory/test_findings.py | Tests cross-operation attack findings. |
| tests/unit/memory/test_finding_evidence_attack_index_migration.py | Tests index migration and backend compatibility. |
| tests/unit/memory/memory_interface/test_interface_scenario_progress.py | Verifies progress score categories. |
| tests/unit/backend/test_scenario_resume.py | Tests live-to-saved attack reads. |
| tests/unit/backend/test_live_attack_reads.py | Covers live reads and attack findings APIs. |
| pyrit/models/scenario_progress.py | Adds categories and objective conversation IDs. |
| pyrit/memory/memory_models.py | Declares the attack-evidence lookup index. |
| pyrit/memory/memory_interface.py | Shares reference paging and exposes findings/categories. |
| pyrit/memory/alembic/versions/b5d7f9a1c3e6_index_finding_evidence_attack_result.py | Adds the attack-evidence lookup index. |
| pyrit/backend/services/scenario_run_service.py | Exposes active attack lookup and conversations. |
| pyrit/backend/services/saved_conversation_read_service.py | Accepts an injectable reference reader. |
| pyrit/backend/services/operation_service.py | Lists findings linked to an attack. |
| pyrit/backend/services/live_attack_reader.py | Defines read-only live attack projections. |
| pyrit/backend/services/attack_service.py | Supports live attacks in read endpoints. |
| pyrit/backend/routes/attacks.py | Adds the attack findings endpoint. |
| pyrit/backend/README.md | Documents live reads and findings contracts. |
| pyrit/backend/models/operations.py | Defines attack findings responses. |
| pyrit/backend/models/attacks.py | Adds live-state and scan provenance fields. |
| pyrit/backend/mappers/attack_mappers.py | Maps live-state and provenance fields. |
| frontend/src/utils/scoreSummary.ts | Normalizes score data for shared presentation. |
| frontend/src/utils/scoreSummary.test.ts | Tests score adapters and fallback values. |
| frontend/src/types/index.ts | Adds shared display and API contracts. |
| frontend/src/services/api.ts | Adds attack findings retrieval. |
| frontend/src/services/api.test.ts | Tests findings requests and failures. |
| frontend/src/hooks/useScenarioRunControls.ts | Extracts rerun, cancel, and resume controls. |
| frontend/src/hooks/useScenarioRunAttackDetails.ts | Extracts attack selection and focus restoration. |
| frontend/src/hooks/useAttackFindings.ts | Loads and refreshes linked findings. |
| frontend/src/hooks/useAttackFindings.test.tsx | Tests findings loading and state transitions. |
| frontend/src/components/ScenarioSuites/ScenarioSuiteExecutionPage.tsx | Adopts shared scan status badges. |
| frontend/src/components/Scenarios/ScenarioTechniqueSection.tsx | Uses shared identity disclosure styles. |
| frontend/src/components/Scenarios/ScenarioRunProgress.tsx | Extracts progress and timing display. |
| frontend/src/components/Scenarios/ScenarioRunPage.tsx | Composes extracted sections and hooks. |
| frontend/src/components/Scenarios/ScenarioRunOverview.tsx | Extracts scan summary facts. |
| frontend/src/components/Scenarios/ScenarioRunObjectivesSection.tsx | Extracts dataset and objective results. |
| frontend/src/components/Scenarios/ScenarioRunNotices.tsx | Extracts errors and progress notices. |
| frontend/src/components/Scenarios/scenarioRunNavigation.ts | Centralizes run back-link rules. |
| frontend/src/components/Scenarios/scenarioRunNavigation.test.ts | Tests back-link destinations and labels. |
| frontend/src/components/Scenarios/ScenarioRunHeader.tsx | Extracts title, status, and controls. |
| frontend/src/components/Scenarios/ScenarioRunDialogs.tsx | Adds the extracted cancellation dialog. |
| frontend/src/components/Scenarios/ScenarioRunConversations.tsx | Extracts executing and saved conversations. |
| frontend/src/components/Scenarios/ScenarioRunConfigurationSection.tsx | Extracts saved configuration disclosure. |
| frontend/src/components/Scenarios/AttackExecutionTable.tsx | Uses shared outcome label styles. |
| frontend/src/components/Scenarios/AttackDetailsDialog.tsx | Extracts attack details presentation. |
| frontend/src/components/Scenarios/AttackActivity.tsx | Adds a reusable activity graphic. |
| frontend/src/components/Scenarios/AttackActivity.test.tsx | Tests activity labels and loading states. |
| frontend/src/components/Scenarios/AttackActivity.styles.ts | Styles activity with reduced-motion support. |
| frontend/src/components/Scenarios/AtomicAttackGroupsSection.tsx | Extracts expandable attack groups. |
| frontend/src/components/ScanStatusBadge.tsx | Centralizes lifecycle labels, colors, and icons. |
| frontend/src/components/ScanStatusBadge.test.tsx | Tests status labels and optional icons. |
| frontend/src/components/Registry/RegistryIdentityRow.tsx | Reuses shared disclosure components. |
| frontend/src/components/Registry/RegistryIdentityRow.styles.ts | Retains row-specific styling. |
| frontend/src/components/Registry/IdentityDisclosure.tsx | Adds reusable identity JSON disclosure. |
| frontend/src/components/Registry/IdentityDisclosure.test.tsx | Tests disclosure behavior and click isolation. |
| frontend/src/components/Registry/IdentityDisclosure.styles.ts | Centralizes disclosure styling. |
| frontend/src/components/OutcomeBadge.tsx | Adds pending states and score popovers. |
| frontend/src/components/OutcomeBadge.test.tsx | Covers new labels and popover behavior. |
| frontend/src/components/OutcomeBadge.styles.ts | Styles pending states and score triggers. |
| frontend/src/components/Operations/OperationParentLink.tsx | Adds reusable parent-operation navigation. |
| frontend/src/components/Operations/OperationParentLink.test.tsx | Tests links and missing-operation behavior. |
| frontend/src/components/Operations/OperationParentLink.styles.ts | Styles parent-operation links. |
| frontend/src/components/Home/Home.tsx | Adopts shared scan status badges. |
| frontend/src/components/DetailFacts.tsx | Adds reusable description-list components. |
| frontend/src/components/DetailFacts.test.tsx | Tests label/value semantics. |
| frontend/src/components/DetailFacts.styles.ts | Adds responsive fact-list layout. |
| frontend/src/components/Chat/ScoreDetails.tsx | Extracts score presentation using ScoreSummary. |
| frontend/src/components/Chat/ScoreDetails.test.tsx | Tests score details and empty sections. |
| frontend/src/components/Chat/ScoreDetails.styles.ts | Extracts shared score-detail styling. |
| frontend/src/components/Chat/MessageList.tsx | Uses shared score details and adapters. |
| frontend/src/components/Chat/MessageList.styles.ts | Removes extracted score-detail styles. |
| frontend/src/components/Chat/FindingEvidenceDialog.tsx | Reports successful attachments via callback. |
| frontend/src/components/Chat/AttachToFindingsButton.tsx | Wraps attachment dialog and focus return. |
| frontend/src/components/Chat/AttachToFindingsButton.test.tsx | Tests attachment, cancellation, and disabled states. |
| frontend/src/components/Chat/AttachToFindingsButton.styles.ts | Applies touch-target sizing. |
| frontend/src/components/AttackResults/attackAttemptFormatting.ts | Adds retry and combined timing formatting. |
| frontend/src/components/AttackResults/attackAttemptFormatting.test.ts | Tests retry and timing output. |
Review effort: Balanced
| return ( | ||
| <Popover withArrow> | ||
| <PopoverTrigger disableButtonEnhancement> | ||
| <Button appearance="transparent" className={styles.scoreTrigger} aria-label={scoreButtonLabel}> |
There was a problem hiding this comment.
Fixed in 343e600. The score button now includes the displayed outcome and the score action in its accessible name. The regression cases cover all saved and pending outcomes, missing outcomes, custom labels, and score/fallback triggers.
Integrate main 25417ff without rewriting the existing stack history. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Limit running-state guarantees to attack summary and metadata reads without expanding conversation/message schemas or removing score details. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Carry forward the verified running-state documentation correction and the predecessor main-integration lockfile state. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve the visible verdict in score-trigger accessible names, cover saved and pending outcomes plus custom labels, and prove populated findings survive refresh before replacement. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
The accessible-name concern in this review is fixed in 343e600. The badge keeps its visible outcome in the score action name; the existing inline thread has the detailed correction. |

Description
Layer 2 of 3 for the scanner results redesign. It adds one shared implementation for each concept the redesigned scan pages use, and splits
ScenarioRunPageinto sections, without visible changes to existing pages. Layer 3 builds the redesign on these pieces.ScenarioRunHeader,ScenarioRunOverview,ScenarioRunNotices,ScenarioRunProgress,ScenarioRunConversations,AtomicAttackGroupsSection,ScenarioRunObjectivesSection,ScenarioRunConfigurationSection,AttackDetailsDialog, andCancelScanDialog. Rerun, cancel, and resume state lives inuseScenarioRunControls. Route-addressed attack selection and focus return live inuseScenarioRunAttackDetails. The back-link rules moved toscenarioRunBackLink.STATE_COLORS(run page),SCAN_STATUS_*(Home), and*_BADGE_COLORS+statusIcon(suite execution page). The suite page keeps its "In progress" wording throughlabel.in_progress/preparing(AttackDisplayOutcome),labelStyle('success'→ True/False,'outcome'→ Success/Failure), and an optional score popover (score,scoreFallback,scoreButtonLabel).AttackExecutionTableuseslabelStyleinstead of hand-built labels.MessageListintoChat/ScoreDetailsand takes a narrowScoreSummarybuilt byscoreSummaryFromBackendScore/scoreSummaryFromProgressScore. Scan results no longer need a fabricatedBackendScore.RegistryIdentityRownow uses itsIdentityDisclosureButton/IdentityJsonparts, so the app has one JSON reveal implementation.dlwith a 9rem label column that stacks on narrow viewports.attacksApi.getAttackFindings.FindingEvidenceDialog, which gains anonAttachedcallback so callers can refresh the findings hook.Behavior note: closing attack details now always returns focus to the control that opened them. Before, opening an attack from an "Executing" row could send focus back to an earlier trigger.