Config Seam Contract
This document defines an implementation-ready seam contract for configuration loading and validation, with staged migration and rollback guidance.
Objective
Create a clear configuration boundary between:
- File discovery and provisioning
- Parse and schema validation
- Version policy and compatibility decisions
- Runtime projection into typed policy objects
The goal is to reduce coupling inside configuration bootstrap while preserving strict validation, deterministic startup behavior, and backward-compatible migration paths.
Current State (baseline)
Configuration handling is currently centralized primarily in src/vulnparse_pin/core/apppaths.py and consumed in bootstrap.
Current workflow includes:
- Ensuring user config files exist (
config.yaml,scoring.json,tn_triage.json) - Reading YAML/JSON with PFH policy enforcement
- Schema validation against packaged schemas
- Global config version warning/fail policy
- Returning raw dict payloads for downstream policy construction
Seam Contract
Contract A: Config source boundary
Config source handling should expose one contract for discover/provision/read operations.
class ConfigSource(Protocol):
def ensure_files(self, ctx: RunContext) -> ConfigFileSet:
...
def read_payloads(self, ctx: RunContext, files: ConfigFileSet) -> RawConfigPayloads:
...
ConfigFileSet
Required fields:
global_yaml: Pathscoring_json: Pathtopn_json: Path
RawConfigPayloads
Required fields:
global_config: dictscoring_config: dicttopn_config: dict
Contract B: Validation boundary
Validation should be isolated and deterministic, producing explicit failure/warning structures.
class ConfigValidator(Protocol):
def validate(self, payloads: RawConfigPayloads) -> ConfigValidationResult:
...
ConfigValidationResult
Required fields:
ok: boolwarnings: list[str]errors: list[str]normalized: RawConfigPayloads
Validation responsibilities:
- Schema validation for all runtime configs
- Global version policy checks (
version: v1compatibility behavior) - Type/top-level object guarantees for all config payloads
Contract C: Runtime projection boundary
Raw validated config should be projected into typed runtime policy objects in one explicit stage.
@dataclass(frozen=True)
class RuntimeConfigBundle:
global_config: dict
scoring_policy: ScoringPolicyV1
topn_policy: TriageConfigLoadResult
This projection boundary preserves strict loading while minimizing config-shape leakage across modules.
Non-goals
- No scoring algorithm changes
- No TopN ranking logic changes
- No parser detection behavior changes
- No runtime CLI flag semantics changes
Migration Sketch
Stage 0 (compatibility wrappers)
- Keep existing
load_config(ctx)entrypoint. - Internally split responsibilities into source/validate/project helper modules.
- Preserve current exception and warning behavior.
Stage 1 (source split)
- Move file ensure/read logic into dedicated source module.
- Keep PFH enforcement and current file naming unchanged.
- Return
ConfigFileSetandRawConfigPayloads.
Stage 2 (validation split)
- Move schema/version validation into validator module.
- Keep error wording and fail-fast behavior stable where practical.
- Keep global version compatibility rule unchanged.
Stage 3 (projection split)
- Consolidate conversion from raw config dicts to typed policy objects.
- Keep bootstrap signatures stable via adapter layer.
- Preserve existing policy defaults and threshold semantics.
Stage 4 (cleanup)
- Remove transitional glue once parity is verified.
- Keep
load_configcompatibility shim until consumers are fully migrated.
Blast Radius
Potentially affected areas:
src/vulnparse_pin/core/apppaths.pysrc/vulnparse_pin/app/bootstrap.pysrc/vulnparse_pin/core/passes/Scoring/src/vulnparse_pin/core/passes/TopN/- config schema resources and related tests
Risk is controlled by preserving current entrypoints and staged migration.
Rollback Strategy
- Keep legacy
load_configpath available behind a compatibility branch. - If validation/projection drift is detected, route startup back to legacy logic immediately.
- Preserve current schema files and version policy behavior to avoid startup regressions.
Verification Plan
Minimum validation for implementation phase:
- Existing config schema validation tests pass unchanged.
- Bootstrap and pass-contract tests remain green.
-
Version-policy behavior is verified for:
- missing
version - supported
version: v1 - unsupported versions
- missing
-
Runtime startup parity checks validate identical loaded policy outcomes.
Exit Criteria
- Config seam contracts are documented and accepted.
- Migration plan is staged and reversible.
- Blast radius and rollback plan are explicit.
- Test matrix for parity and version behavior is defined.