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
{{ message }}
Repository navigation
FEAT: Add a general scorer registry API for dataset-driven scenarios #2970
Is your feature request related to a problem? Please describe.
The dataset explorer in #2744 needs to discover and select configured scorer instances for its custom-scenario flow, rather than hardcoding scorer classes or accepting serialized Python components from the browser. ScorerRegistry already discovers types, exposes constructor metadata, resolves component references, constructs instances, and holds named configured instances. This issue captured the missing general HTTP contract over that registry.
#2834 attempted a specialized objective-presets API for #2755 and closed without merging after Rich's review requested a general registry API first. The subsequent proposal here helped define the backend boundary.
Completed by #2990, merged on October 5, 2026.Rich's final direction on #2755 settled the contract, and #2755 was revised to cover the same general backend scope. This related issue does not represent a second implementation or an additional child in the 17-item dataset roadmap. The earlier contract hold and flat-summary proposal below are superseded by the implemented decision recorded here.
Describe the solution you'd like
Implemented general API
#2990 adds thin typed routes and a service over the existing ScorerRegistry:
Route
Purpose
GET /api/scorers/types
List scorer types with shared constructor-parameter metadata.
GET /api/scorers
List named, configured instances with bounded pagination.
GET /api/scorers/{scorer_registry_name}
Retrieve one configured instance by registry name.
POST /api/scorers
Construct and register a named instance through the shared registry/resolver, returning the same instance model.
The final typed contracts are:
ScorerTypeEntry: scorer_type, shared parameters: list[Parameter], is_llm_based, and description; type discovery uses an items envelope.
ScorerInstance: scorer_registry_name, full typed identifier: ScorerIdentifier, and description; list responses use items and the existing pagination model.
CreateScorerRequest: required name and type, plus params defaulting to an empty object when omitted, using shared registry construction and named component references.
Contract decision: return the full ScorerIdentifier, including child scorers and target identifiers. This deliberately replaces the earlier proposed flat allowlist and blanket prohibition on nested identifiers. Credential values must still be excluded. Identifiers can contain non-secret configuration; they are not a substitute for registry tags, compatible-default selection, or objective-suitability policy.
Keep buildable types distinct from configured instances. A type appearing in the catalog does not prove that its dependencies are initialized or that it is a suitable objective scorer.
Behavior and boundaries
The core registry and shared resolver own constructor metadata, reference resolution, scorer-specific parameter checks, and construction. The backend handles HTTP validation and error translation, not a second registry or a parallel introspection/compatibility implementation.
List/detail/type reads do not construct scorers, score content, call targets, fetch datasets, or generate conversations. Creation configures an instance; it is not a scoring operation.
Failed creation must not register a partial instance. Duplicate-name creation must not silently replace an existing one, including concurrent requests.
The implementation paginates configured instances in sorted registry-name order. An unknown cursor currently restarts at the first page, following the existing target-service convention; the earlier proposal to return 400 for this case was not the behavior shipped in FEAT: expose ScorerRegistry through the backend API #2990.
Registry names identify configured instances in the current runtime. They are not persistent saved configurations and may disappear after registry reset/reinitialization or restart. The service cache is reset when runtime registries are replaced.
Reuse backend-configured dependencies and existing authentication conventions. This work adds no browser credential-entry flow, credential store, memory schema migration, persistent scorer store, or execution engine.
Typed request/response contracts distinguish type discovery from configured-instance discovery.
List, detail, and create use one shared instance model with full nested identifiers.
Named creation uses the shared resolver and the created instance is retrievable by registry name.
Pagination, invalid construction input/references, duplicate names, failed construction, and registry lifecycle changes have focused route/service coverage.
Read endpoints do not construct or invoke scorers, targets, or dataset providers.
Local fake-registry tests cover nested scorer/target identifiers, credential exclusion, and concurrent duplicate creation without paid calls.
Existing /scores operations remain separate; no dataset-specific objective-selection or scenario-default policy is added by these routes.
Remaining dataset-explorer consumers
Basic cards, browsing, media previews, and single-example chat imports do not depend on this API. The dependent flow is selected examples -> Configure scenario -> preview/estimate -> confirmed launch.
The requirements not implemented by #2990 are now explicit in the existing roadmap:
FEAT GUI: Accept exact seed selections in scenario requests #2757: carry scorer_registry_name alongside exact seed selections without serializing components; preserve the effective configuration across preview, estimate, and launch; reject missing/stale/incompatible requested references without silent substitution.
FEAT: Support custom scenarios over selected dataset examples #2760: reuse compatible configured objective defaults, default_objective_scorer, existing composites/inverters, prerequisite validation, and correct objective-result meaning. Raw refusal=true is not attack success. raise_if_scorer_blocks is a blocked-judging policy, not refusal-result inversion.
FEAT GUI: Configure a scenario from selected dataset examples #2759: provide the configured-instance picker, tags/default/compatibility metadata through a shared typed core-backed projection, and setup guidance. The general API's full identifier alone does not supply that metadata or policy.
These are retained follow-ups, not acceptance criteria falsely marked complete here. #2757 still waits for #2756 and maintainer promotion; completing #2755/#2990 does not bypass the main explorer/provider-loading sequence.
Describe alternatives you've considered, if relevant
A flat instance summary was proposed here, but the final maintainer decision chose full typed identifiers, matching the shared catalog approach. The original comment thread remains as decision history.
A hardcoded GUI list would miss initializer-provided instances and custom/composite scorers.
A new general scorer-builder GUI, scorer execution endpoint, arbitrary Python/import support, or update/delete API is outside this completed backend slice.
Additional context
Implementation: #2990, merge commit 5f619c0b87e342ba15b5dd0af29df4858ecce5e9. Related completed roadmap milestone: #2755. The contributor confirmed the general-backend scope and left objective presets and the GUI as follow-ups in this comment.
Rich's broader scorer contract proposal and phase-8 #2899 concern Python evidence/expectation/scorer contracts, not this HTTP endpoint specification. They are related SDK work, not a separate unimplemented copy of the API now shipped in #2990.
Starting points: pyrit\registry\components\scorer_registry.py, pyrit\backend\models\scorers.py, pyrit\backend\services\scorer_service.py, pyrit\models\catalog\scorer.py, ScorerInitializer, ScenarioConfigurationResolver, and Scenario._get_default_objective_scorer().
Follow doc\code\framework.md: registries build and hold components, the backend exposes HTTP contracts, scenarios package selected components, scorers evaluate evidence, and attacks act on scores.
Is your feature request related to a problem? Please describe.
The dataset explorer in #2744 needs to discover and select configured scorer instances for its custom-scenario flow, rather than hardcoding scorer classes or accepting serialized Python components from the browser.
ScorerRegistryalready discovers types, exposes constructor metadata, resolves component references, constructs instances, and holds named configured instances. This issue captured the missing general HTTP contract over that registry.#2834 attempted a specialized objective-presets API for #2755 and closed without merging after Rich's review requested a general registry API first. The subsequent proposal here helped define the backend boundary.
Completed by #2990, merged on October 5, 2026. Rich's final direction on #2755 settled the contract, and #2755 was revised to cover the same general backend scope. This related issue does not represent a second implementation or an additional child in the 17-item dataset roadmap. The earlier contract hold and flat-summary proposal below are superseded by the implemented decision recorded here.
Describe the solution you'd like
Implemented general API
#2990 adds thin typed routes and a service over the existing
ScorerRegistry:GET /api/scorers/typesGET /api/scorersGET /api/scorers/{scorer_registry_name}POST /api/scorersThe final typed contracts are:
ScorerTypeEntry:scorer_type, sharedparameters: list[Parameter],is_llm_based, anddescription; type discovery uses anitemsenvelope.ScorerInstance:scorer_registry_name, full typedidentifier: ScorerIdentifier, anddescription; list responses useitemsand the existingpaginationmodel.CreateScorerRequest: requirednameandtype, plusparamsdefaulting to an empty object when omitted, using shared registry construction and named component references.Contract decision: return the full
ScorerIdentifier, including child scorers and target identifiers. This deliberately replaces the earlier proposed flat allowlist and blanket prohibition on nested identifiers. Credential values must still be excluded. Identifiers can contain non-secret configuration; they are not a substitute for registry tags, compatible-default selection, or objective-suitability policy.Keep buildable types distinct from configured instances. A type appearing in the catalog does not prove that its dependencies are initialized or that it is a suitable objective scorer.
Behavior and boundaries
Acceptance criteria completed in #2990:
/scoresoperations remain separate; no dataset-specific objective-selection or scenario-default policy is added by these routes.Remaining dataset-explorer consumers
Basic cards, browsing, media previews, and single-example chat imports do not depend on this API. The dependent flow is selected examples -> Configure scenario -> preview/estimate -> confirmed launch.
The requirements not implemented by #2990 are now explicit in the existing roadmap:
scorer_registry_namealongside exact seed selections without serializing components; preserve the effective configuration across preview, estimate, and launch; reject missing/stale/incompatible requested references without silent substitution.default_objective_scorer, existing composites/inverters, prerequisite validation, and correct objective-result meaning. Rawrefusal=trueis not attack success.raise_if_scorer_blocksis a blocked-judging policy, not refusal-result inversion.These are retained follow-ups, not acceptance criteria falsely marked complete here. #2757 still waits for #2756 and maintainer promotion; completing #2755/#2990 does not bypass the main explorer/provider-loading sequence.
Describe alternatives you've considered, if relevant
/objective-presetsendpoint first would establish the separate contract that prompted [FEAT] Expose configured objective-scorer presets #2834's closure.Additional context
Implementation: #2990, merge commit
5f619c0b87e342ba15b5dd0af29df4858ecce5e9. Related completed roadmap milestone: #2755. The contributor confirmed the general-backend scope and left objective presets and the GUI as follow-ups in this comment.Rich's broader scorer contract proposal and phase-8 #2899 concern Python evidence/expectation/scorer contracts, not this HTTP endpoint specification. They are related SDK work, not a separate unimplemented copy of the API now shipped in #2990.
Starting points:
pyrit\registry\components\scorer_registry.py,pyrit\backend\models\scorers.py,pyrit\backend\services\scorer_service.py,pyrit\models\catalog\scorer.py,ScorerInitializer,ScenarioConfigurationResolver, andScenario._get_default_objective_scorer().Follow
doc\code\framework.md: registries build and hold components, the backend exposes HTTP contracts, scenarios package selected components, scorers evaluate evidence, and attacks act on scores.