Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
dcf012f
FEAT: Add expandable sidebar navigation
richlundeen Oct 29, 2026
4a72b94
FIX: Preserve sidebar tooltips and share responsive queries
richlundeen Oct 29, 2026
ca81736
FEAT: Consolidate attack and scanner history
richlundeen Oct 29, 2026
22faf6b
FIX: Keep editor drafts until new-attack navigation commits
richlundeen Oct 29, 2026
c8c3a56
FIX: Show unknown routes without losing view state
richlundeen Oct 29, 2026
9bd986a
FIX: Return to retained chat work after inspection
richlundeen Oct 29, 2026
2b4b45d
FEAT: Normalize registry identities
richlundeen Oct 29, 2026
9fc4c51
FIX: Align registry browser checks and identity docs
richlundeen Oct 29, 2026
65fe249
FEAT: Reuse last-used chat and scan selections
richlundeen Oct 29, 2026
c548838
FIX: Preserve scorer preferences and repair target setup coverage
richlundeen Oct 29, 2026
0ea5a7a
FIX: Preserve explicit unavailable scorer overrides
richlundeen Oct 29, 2026
4428222
DOC: Clarify the current adversarial fallback order
richlundeen Oct 29, 2026
287e94a
MAINT: Remove obsolete effect lint suppression
richlundeen Oct 29, 2026
10c7fe8
FEAT: Latest-response Scoring
richlundeen Oct 29, 2026
95bbe2b
FIX: Harden latest-response scoring ownership
richlundeen Oct 29, 2026
dbf8cf4
FIX: Scope Apply status to its scorer and objective
richlundeen Oct 29, 2026
3ecc1bf
FIX: Apply layer-4 scorer preference guards to Apply
richlundeen Oct 29, 2026
7c56674
6 - FEAT: Scan Results and Live Chats
richlundeen Oct 29, 2026
c7d304e
Fix scan observation and result workflow regressions
richlundeen Oct 29, 2026
0818b89
Propose durable cancelled-attempt evidence for user review
richlundeen Oct 29, 2026
1180149
Keep cancellation metric policy unchanged while preparing provenance
richlundeen Oct 29, 2026
de1c016
Preserve interrupted scan conversations without adding outcomes
richlundeen Oct 29, 2026
d7dc88c
Keep interrupted conversations reachable from scan results
richlundeen Oct 29, 2026
c5af4c0
TEST: Stabilize scan launch and queue browser coverage
richlundeen Oct 29, 2026
ce32f01
FIX: Include saved scan conversations in history lookup
richlundeen Oct 29, 2026
3dde572
FEAT: Focus Home on attacks, scans, and recent work
richlundeen Oct 29, 2026
b101117
FIX: Reuse shared Home outcome labels and restore coverage
richlundeen Oct 29, 2026
48fef3a
TEST: Supply Home scan summaries in the shared-label fixture
richlundeen Oct 29, 2026
dbe36b7
FIX: Prioritize saved Home links and secondary target setup
richlundeen Oct 29, 2026
e08649b
TEST: Preserve composer sequence ownership in the App fixture
richlundeen Oct 29, 2026
a3faf99
TEST: Match picker HTTP fixtures to Home list contracts
richlundeen Oct 29, 2026
c9ffd77
TEST: Align Home tour cases with workflow-focused entry points
richlundeen Oct 29, 2026
7f925d7
Merge origin/main and stabilize chat scoring concurrency regression
richlundeen Oct 29, 2026
708654e
8 - FEAT: Contextual Help
richlundeen Oct 29, 2026
1731119
Fix empty attack history target guidance
richlundeen Oct 29, 2026
dfba632
Fix contextual help accessibility and guidance
richlundeen Oct 29, 2026
2bda4a0
Align integrated chat target selectors with visible label
richlundeen Oct 29, 2026
cc89f14
Disambiguate outcome actions from information controls in tests
richlundeen Oct 29, 2026
91857f1
Use native input roles in Registry browser checks
richlundeen Oct 29, 2026
abf2b71
Align target and scenario tests with native help semantics
richlundeen Oct 29, 2026
c18d316
Fix narrow chat controls and update browser acceptance
richlundeen Oct 29, 2026
a21c1a6
Fix tour target selector after contextual-help labeling
richlundeen Oct 29, 2026
7279872
Merge origin/main into PR 3650
richlundeen Oct 31, 2026
050678a
Merge PyRIT 3642 dependency into PR 3650
richlundeen Oct 31, 2026
6aa0feb
Merge latest main before PR repair
richlundeen Oct 31, 2026
aa611d7
fix(frontend): repair consolidated history feedback
richlundeen Nov 1, 2026
3b01664
Merge main into PR 3642 repair baseline
richlundeen Nov 1, 2026
1ac07c1
Restore focused chat scoring test waits
richlundeen Nov 1, 2026
a9f4e93
Merge exact origin/main into PR 3650 preserving consolidated navigation
richlundeen Nov 1, 2026
9f85042
Merge prepared PyRIT PR 3642 dependency into PR 3650
richlundeen Nov 1, 2026
b1b7db5
fix: restore consolidated history validation contracts
richlundeen Nov 1, 2026
3221d05
Fix seeded flow setup for feature-owned New attack control
richlundeen Nov 1, 2026
9f5caca
Merge origin/main into PR #3651
richlundeen Nov 1, 2026
1e4014f
Merge prepared PR #3650 dependency into PR #3651
richlundeen Nov 1, 2026
176ffd4
Fix registry filters and target identity inspection
richlundeen Nov 1, 2026
53d7e77
Merge origin main into last-used defaults
richlundeen Nov 1, 2026
1951754
Merge reviewed PR 3651 dependency into last-used defaults
richlundeen Nov 1, 2026
4d399a1
Fix confirmed-use preferences and delayed target defaults
richlundeen Nov 1, 2026
dadec69
Fix successful chat mock send receipts and reset regression
richlundeen Nov 1, 2026
2ac7374
Merge exact origin main into PR 3644
richlundeen Nov 1, 2026
7edb0b3
Merge exact prepared PR 3647 dependency into PR 3644
richlundeen Nov 1, 2026
e37b611
Match chat scores to captured evidence and current projection
richlundeen Nov 1, 2026
d829fe8
Merge exact refreshed main into repaired PR 3644
richlundeen Nov 1, 2026
63b8749
Correct conversation-scoring mock and Rolldown target option
richlundeen Nov 1, 2026
9304421
Include authoritative scoring projection in chat E2E mock
richlundeen Nov 1, 2026
76ddd7c
Merge upstream main into scan results
richlundeen Nov 1, 2026
e51a235
Merge prepared PR 3644 dependency into scan results
richlundeen Nov 1, 2026
312fa48
Fix scenario run repair regressions
richlundeen Nov 1, 2026
8f70a3b
Fix CI typing and historical rerun validation
richlundeen Nov 2, 2026
0fb96c9
Fix frontend conversation handoff and CI interaction contracts
richlundeen Nov 2, 2026
6634a42
Merge pinned PR 3643 dependency into Home workflows
richlundeen Nov 2, 2026
e9388cd
Order Home scans by activity before paging
richlundeen Nov 2, 2026
0f93f81
Merge upstream main preserving reviewed frontend integrations
richlundeen Nov 2, 2026
74d9c6b
Merge reviewed PR 3645 dependency preserving contextual help
richlundeen Nov 2, 2026
dc19b47
Fix contextual help editor interactions and selection-limit wording
richlundeen Nov 2, 2026
9a0d77b
Merge upstream main refresh f6440161 into PR 3646
richlundeen Nov 2, 2026
7d45541
Keep scenario queue run navigation inside the router
richlundeen Nov 2, 2026
11753e6
Merge upstream main 5365a18b into repaired PR 3646
richlundeen Nov 2, 2026
97e4a47
test: mock hierarchy in FIFO handoff scenario
richlundeen Nov 2, 2026
3d22619
Merge upstream main 5e333e78 into PR 3646
richlundeen Nov 2, 2026
7be955a
Fix wrapped conversation score freshness
richlundeen Nov 2, 2026
52b895e
Merge upstream main f4185465 into repaired PR 3646
richlundeen Nov 2, 2026
dc14bdf
Track scorer wrapper participation for freshness
richlundeen Nov 2, 2026
71614ae
Test persisted scorer participation upgrades
richlundeen Nov 2, 2026
7c9ba7f
Keep scorer participation metadata private
richlundeen Nov 2, 2026
0f79d85
Document private scorer participation persistence
richlundeen Nov 2, 2026
b70e6b7
Preserve caller score participation metadata
richlundeen Nov 2, 2026
4a824be
Validate persisted scorer provenance and migration head
richlundeen Nov 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions .github/workflows/frontend_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,6 @@ jobs:
config: playwright.analytics.config.ts
shard: 1
total: 1
- project: paired-outcomes
config: playwright.paired-outcomes.config.ts
shard: 1
total: 1
- project: scenario-hierarchy
config: playwright.scenario-hierarchy.config.ts
shard: 1
Expand Down Expand Up @@ -135,7 +131,7 @@ jobs:
run: npx playwright install --with-deps chromium

- name: Build the isolated fixture frontend
if: matrix.project == 'analytics' || matrix.project == 'paired-outcomes' || matrix.project == 'scenario-hierarchy'
if: matrix.project == 'analytics' || matrix.project == 'scenario-hierarchy'
run: npm run build

- name: Run E2E shard (no credentials needed)
Expand Down
3 changes: 3 additions & 0 deletions doc/code/framework.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ If you are contributing to PyRIT, that work will most likely land in one of the
conditions before scoring. Wrappers expose their children; `get_condition_types()` derives their
combined coverage. Use separate leaves and a composite for independent checks.
- `score_observation_async` coordinates replay of stored evidence without calling the target. Scorer target response replay owns the checks for the exact original expectation, scorer configuration, and response-handler contract; evidence resolution checks that scored evidence and response content are unchanged.
- `find_matching_scores` selects the stored results that the same scorer configuration produced for the same evidence and the input `score_async` prepares. The scorer owns this match rule; callers decide whether a match replaces a new evaluation and how it is recorded.
- Same-input wrappers also validate freshness requirements from the child scorers that contributed to a stored result. Wrapper results retain branch participation in private `Score` state, persisted in the nullable `ScoreEntries.snapshot_participation` column rather than public `score_metadata`. Public metadata keys remain caller-owned; older rows without private participation provenance are treated as unknown, so required child freshness is checked conservatively. Nested and composite wrappers therefore check only branches that produced part of the result when private provenance is available. Conversation scorers require a linked complete observation of the current ordered conversation; wrappers preserve their own score identity, and fallback matching checks only branches that contributed a result.
- Tool-event observations can be matched against new tool-name expectations
without querying the trace client again. This does not relax scorer target response replay rules.
- **Does not own**: acting on its own result. A scorer evaluates a response and returns a score; branching on that score is the attack's job, and aggregating scores across runs is analytics'. It may call a target to evaluate, but it doesn't send the attack's objective prompt or manage the conversation.
Expand Down Expand Up @@ -477,6 +479,7 @@ The below describes the user-facing surfaces built on top of the framework.
- Wherever possible it should reuse other components rather than reimplementing them (e.g. the registry to build components, `pyrit.models` for its model layer), while adding presentation-specific information on top as needed.
- Organized into `routes/`, `services/`, `models/`, `mappers/`, and `middleware/`, and launched through the `pyrit_backend` command (configurable via `PYRIT_API_HOST` / `PYRIT_API_PORT` / `PYRIT_API_RELOAD`).
- Saved-result analytics routes consume the cached SDK directly and serialize shared models. The shared runtime owns admission, busy checks, SDK draining and cache invalidation before memory replacement/disposal, including work still cleaning up after an HTTP timeout. It does not calculate statistics or add an SDK authorization scope.
- `ChatScoringService` owns manual chat scoring policy: the scorer and input for the next evaluation, reuse of a complete matching result, publication to the attack, and the latest-response result and outcome that the frontend shows.

## [CLI](../scanner/0_scanner)

Expand Down
110 changes: 93 additions & 17 deletions doc/gui/0_gui.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,35 +23,89 @@ For other setup options, see [Docker](../getting_started/install_docker.md) or t

## Home

Home shows your default objective target and recent attacks grouped by operation.
Open an attack to return to its conversation, or go to Registry to configure a
target. The shared labels bar sets the operator, operation, and custom labels
for new work; it does not change saved results.

![Home page with default target and recent work](images/home.png)
Home puts **Attacks**, **Scans**, **Recent work**, and **Operations** first.
Select **New attack** to start a fresh chat, or **Configure scan** to open scanner
setup. These actions do not send prompts or start a scan. The sidebar's
**Attacks** entry returns to your last conversation or unsent draft.
Each workflow has its own history link. Recent work shows up to five saved
attacks and scans; filter by type or select **Refresh Home** to update the list.
Open a saved operation to review its work and findings. Registry remains
available below these sections for setup. Operation links put the selected saved
operation first, then the newest-created records, not the most recently active
records. When the complete registry confirms that no targets are registered, the
secondary setup action offers **Register a target**.

![Home page with workflows and recent work](images/home.png)

## Chat

Chat (`/chat`) is the manual conversation workspace. Select a target and write
the messages yourself. You can attach media, transform content with converters,
Select **Attacks** in the sidebar to open Chat (`/attack/chat`), the manual conversation
workspace. Select a target and write the messages yourself. You can attach media, transform content with converters,
and branch or edit conversations to try another approach. Add an objective and
select a chat scorer if you want automated assessment of responses.

The same conversation viewer opens saved attacks from History. Automated results
To score a saved response, open the objective outcome, expand **Automated scorer**,
and select a scorer. **Apply scorer** evaluates only the latest saved assistant
response in the open conversation. It keeps an existing complete result for the
same response, scorer configuration, and objective criteria without another
evaluation. **Off** hides the action. Earlier responses, other conversations, and
human scores do not change; future responses keep the selected chat scorer.

New chats and scans start with the last objective target you used. New chats also
reuse the last chat scorer, including **Off**, unless a Registry default is set.
These choices are saved in the current browser profile after use. Opening saved
activity or editing an unsent draft does not change them.
Chat use is recorded only after a request turn is confirmed, not after preparation
fails, and stays with the initiating account even if you navigate away. A chat
with a temperature override remembers its registered source target, without
changing that chat's execution binding. While a remembered scorer is loading,
wait for its catalog. Explicit scorer selections, including **Off**, take
precedence; an unavailable remembered scorer is not saved as **Off**.

The **Chat** tab returns to your retained draft, or your last chat if there is no draft.
Selecting **Chat** while a chat is open keeps that chat open.
Use **New attack** to start a blank draft. The **History** tab
(`/attack/history`) opens saved attacks in the same conversation viewer. Automated results
are read-only; **Continue manually** creates a separate manual attack. Export
a conversation when you need a transcript.

Older `/attacks/{attackId}` and
`/attacks/{attackId}/conversations/{conversationId}` links redirect to the
corresponding Chat route while retaining query parameters and fragments.

![Chat workspace with a prompt and target response](images/chat.png)

## Scanner

Scanner (`/scanner`) is the catalog and launch point for automated scenarios.
Scanner has **Launch** (`/scanner/launch`) and **History** (`/scanner/history`) tabs.
Launch is the catalog and launch point for automated scenarios.
Each scenario defines a test workflow with its techniques, data, and scoring.
Open one to select a target and adjust the settings it supports, such as
techniques, dataset selection, and concurrency.

Use the chevron on the right of a technique to inspect its identity JSON.
This does not change the checkbox selection on the left.

Review the run estimate, then launch the scan. Its run page shows progress,
errors, and results, with links to individual attacks. See the
errors, and results, with links to individual attacks and conversations.
Expand an attack group or objective to inspect its attempts. Technique, scorer,
dataset/seed provenance, and scenario settings use inline identity JSON.
Decided attack outcomes use **True** and **False**; execution errors remain separate.
Groups and objectives show success rates and completion counts separately.
The results page does not include a paired-outcome comparison.

**Watch live conversation** opens saved messages while an attack runs. This view
is read-only and refreshes saved messages; it has no send controls. **Cancel scan**
stops remaining scan work and keeps saved results. Ordinary manual chats do not
have scan cancellation controls.
After cancellation, saved messages remain available in the read-only chat.
Saving these conversation links does not add attack outcomes or change success rates.

**Rerun** opens the scenario launch page with saved settings filled in. It does
not start work or change the original run. Review or edit the settings before
launching. Recorded target/scorer identities and the scenario version are checked.
Settings that cannot be restored, including older records without a required identity,
produce an error instead of silently using current defaults. See the
[scanner guide](../scanner/0_scanner.md) for the scenario model.

![Scanner page with available scenarios](images/scanner.png)
Expand All @@ -61,7 +115,7 @@ errors, and results, with links to individual attacks. See the
Select **technique.execute** in Scanner to run one attack technique against
one free-text objective. This is not Chat: the selected technique controls
the attack, rather than you writing each turn. You can adjust its configuration
for this run and add a baseline comparison.
for this run and include a baseline attack for reference.

For techniques that support conversation history, start with a stored or edited
conversation. **Use in scan** in Chat copies a conversation into this setup
Expand All @@ -77,11 +131,23 @@ Registry prepares reusable components; it does not execute attacks. Create
targets to connect to model endpoints, converters to transform content, and
named techniques that configure existing attacks. Browse configured scorers
and select a default chat scorer; scorer setup uses initializers, not an editor
on this page. Target defaults apply to new chats and scans.
on this page. An explicit scan choice takes precedence. Otherwise, the current
adversarial-target order is a saved Registry default, the registered
`adversarial_chat` target, then last use. Objective targets do not have a Registry
default. Existing chats and runs keep their settings.

Expand a target, scorer, technique, or converter name to inspect its identity
JSON. Target identity inspection is independent of expanding composite target
members; defaults, visibility, and the target's configuration columns remain
available. Converter inputs and outputs stay visible in the table. Use the small
red X to remove a converter from the live registry; confirmation is required.

**Scenario presets** save a scenario configuration for reuse with a target
chosen at launch. **Suites** maintain ordered collections of preset definitions.
They are stored separately from live component instances.
Suite launch dialogs apply arriving target defaults only to untouched selections.
An explicit target choice, including clearing an optional adversarial target to
use the server default, is retained when the registry refreshes.

Targets, converters, and techniques added only to the live registry must be
recreated after a backend restart or reinitialization. Use
Expand All @@ -102,11 +168,17 @@ Load data through PyRIT before refreshing this catalog. See

## History

Find saved attacks and scanner runs. Filter the list, open results, and inspect
the conversations and scores. Supported failed scanner runs can be resumed.
History is next to the feature that produced the results, not a separate sidebar
item. Use the History tab in Attacks or Scanner to filter saved results and inspect
their conversations and scores.

Scanner history opens run-level progress and results, including runs from
`technique.execute`. Its **ID** field accepts a complete conversation, attack,
finding, or scenario result ID and searches all stored runs. Hover over the field
to see the supported ID types. **Back to scan**, beside Markdown in a scan-owned
chat, returns to its run.

The **Attacks** tab opens individual conversations. The **Scanner** tab opens
run-level progress and results, including runs from `technique.execute`.
Supported failed or cancelled scanner runs can be resumed.
Resume retries unfinished objectives or objectives with execution errors when
the original launch configuration is available. It skips completed objectives
with non-error outcomes, including `failure`. Retrying an unsuccessful technique
Expand Down Expand Up @@ -164,5 +236,9 @@ for requirements and limits.

## Preferences

Use the icon at the top of the sidebar to show or hide navigation labels. This
choice is saved for your account in this browser. On narrow screens, the same
icon opens a navigation panel without reducing the workspace width.

Use the sidebar's **Theme** menu to change the appearance. User preferences,
such as default targets, are saved in this browser for the current account.
Binary file modified doc/gui/images/home.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 9 additions & 1 deletion frontend/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@ Your choice is saved in this browser. System follows the operating system's
light/dark preference. High-contrast mode overrides every palette and hides
decorations without forgetting the selected preset.

## Contextual help

Hover over a term or field label to read its explanation. Its information
button also opens the help with a click, tap, or Enter/Space. Press Escape
to dismiss it. Label clicks still focus the field. Field descriptions remain
available to assistive technology while the help is closed. Required markers,
validation errors, input-format guidance, and unavailable-estimate reasons
stay visible.

## Conversation selection

Opening a saved attack with related conversations automatically opens the
Expand Down Expand Up @@ -268,7 +277,6 @@ npm run test:coverage # Run with coverage report (85%+ threshold)
# End-to-End Tests (Playwright)
npm run test:e2e # Run headless (default local setup uses dev.py)
npm run test:e2e:headed # Run with visible browser windows (requires display)
npm run test:e2e:paired-outcomes # Real SQLite/API paired-outcome acceptance tests
npm run test:e2e:ui # Interactive UI mode (requires display)
```

Expand Down
9 changes: 8 additions & 1 deletion frontend/e2e/_fixtures.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { test as base } from "@playwright/test";
import { test as base, expect, type Page } from "@playwright/test";
import { mockVersion } from "./_compatibility";

export * from "@playwright/test";
Expand All @@ -19,3 +19,10 @@ export const test = base.extend<{ mockStartup: void }>({
await use();
}, { auto: true }],
});

export async function selectChatTarget(page: Page, registryName?: string): Promise<void> {
await page.goto("/attack/chat");
const picker = page.getByRole("combobox", { name: "Objective target", exact: true });
await expect(picker).toBeEnabled();
await picker.selectOption(registryName ?? { index: 1 });
}
Loading
Loading