Skip to content

S006: Configuration & Settings

FieldValue
SpecS006
FeatureConfiguration & Settings
Date2026-04-23
StatusDraft
Authorspec-writer-agent

Overview

Configuration is the foundation of Parity. Every behavior -- test naming conventions, which rules to apply, coverage thresholds, namespace resolution, and source-to-test directory mappings -- is driven by a single parity.yaml file. The configuration system has three core responsibilities: (1) discovering and loading the YAML file, (2) parsing it into a typed Settings DTO with sensible defaults, and (3) resolving per-structure rule configurations including backwards-compatible legacy format translation.

The parity.yaml schema defines two conceptual layers. The global layer (settings, coverage_xml, min_coverage, min_coverage_global, min_matched_coverage) establishes project-wide defaults for namespace mapping, file extensions, test naming, and coverage thresholds. The structure layer (structure[]) defines one or more source-to-test directory mappings, each with its own optional rules array and file_map overrides. This two-layer design lets teams enforce different standards for different parts of their codebase (e.g., stricter coverage for services than for controllers).

The system supports a legacy flat format (source_path/test_path, enforce_attribute, enforce_coverage_link) for backwards compatibility. When legacy keys are detected in a structure entry and no rules array is present, they are internally translated to the equivalent modern rules configuration. The Settings DTO is the canonical in-memory representation consumed by all downstream systems: the CLI (S001), rule evaluation (S002), coverage readers (S003), coverage linkers (S004), plugins (S005), and path mapping (S007).

User Scenarios

S006-US-001 [P1] As a developer, I want Parity to read a parity.yaml file from my project root so that all analysis behavior is driven by declarative configuration.

S006-US-002 [P1] As a developer, I want to define namespace roots, test suffixes, and file extensions so that Parity correctly maps source files to test files regardless of my project's naming conventions.

S006-US-003 [P1] As a team lead, I want to set global coverage thresholds (min_coverage, min_coverage_global) so that every source file and the project overall meet minimum standards.

S006-US-004 [P1] As a developer, I want to define multiple structure blocks with per-structure rule overrides so that different parts of my codebase can have different testing and coverage requirements.

S006-US-005 [P2] As a developer with non-standard file naming, I want to use file_map within a structure to explicitly map source files to test files so that Parity does not flag them as missing.

S006-US-006 [P2] As a developer migrating from an older Parity version, I want the legacy config format (source_path/test_path/enforce_attribute) to still work so that I do not have to update my config immediately.

S006-US-007 [P1] As a new user, I want parity init to generate a sensible default parity.yaml so that I can start using Parity without manual configuration.

S006-US-008 [P1] As a CI engineer, I want to point Parity at a config file outside the current directory via --config=path so that I can use Parity in monorepo or non-standard directory layouts.

Requirements Summary

IDTypePriorityTitleStatus
S006-FR-001FunctionalP1Config file discoveryDraft
S006-FR-002FunctionalP1YAML parsingDraft
S006-FR-003FunctionalP1Settings DTO constructionDraft
S006-FR-004FunctionalP1Namespace roots configurationDraft
S006-FR-005FunctionalP1File extension and test naming configurationDraft
S006-FR-006FunctionalP1Coverage path resolutionDraft
S006-FR-007FunctionalP1Global coverage thresholdsDraft
S006-FR-008FunctionalP1Structure block format (modern)Draft
S006-FR-009FunctionalP1Structure rules configurationDraft
S006-FR-010FunctionalP2File map overridesDraft
S006-FR-011FunctionalP2Legacy structure format supportDraft
S006-FR-012FunctionalP2Legacy rule translationDraft
S006-FR-013FunctionalP1Default values for all optional keysDraft
S006-FR-014FunctionalP1Init command default templateDraft
S006-FR-015FunctionalP1Config path override via --config flagDraft
S006-FR-016FunctionalP1Project root derivation from config locationDraft
S006-FR-017FunctionalP1test-exists auto-prependDraft
S006-FR-018FunctionalP2PHPUnit XML rule auto-appendDraft
S006-FR-019FunctionalP1Structure block iteration orderDraft
S006-FR-020FunctionalP2Namespace separator configurationDraft
S006-IF-001InterfaceP1parity.yaml full schemaDraft
S006-IF-002InterfaceP1Settings DTO constructor contractDraft
S006-IF-003InterfaceP1Settings::fromConfig() contractDraft
S006-IF-004InterfaceP1Structure block schema (modern)Draft
S006-IF-005InterfaceP2Structure block schema (legacy)Draft
S006-IF-006InterfaceP1Rule configuration formatsDraft
S006-IF-007InterfaceP1Default template contentDraft
S006-AS-001AcceptanceP1Minimal valid configDraft
S006-AS-002AcceptanceP1Full config with all keysDraft
S006-AS-003AcceptanceP1Settings DTO defaults appliedDraft
S006-AS-004AcceptanceP1Multiple structures with different rulesDraft
S006-AS-005AcceptanceP2File map overrides standard namingDraft
S006-AS-006AcceptanceP2Legacy format parsed correctlyDraft
S006-AS-007AcceptanceP1Coverage path as stringDraft
S006-AS-008AcceptanceP1Coverage path as arrayDraft
S006-AS-009AcceptanceP1Init creates valid parseable configDraft
S006-AS-010AcceptanceP1Custom config path resolves project rootDraft
S006-AS-011AcceptanceP1test-exists auto-prepended to rulesDraft
S006-AS-012AcceptanceP2Legacy enforce_attribute translatedDraft
S006-SC-001SuccessP1All optional keys have defaultsDraft
S006-SC-002SuccessP1Settings DTO is immutableDraft
S006-SC-003SuccessP1Round-trip: init output is parseableDraft
S006-SC-004SuccessP1Legacy configs produce identical SettingsDraft
S006-SC-005SuccessP1Invalid config produces actionable errorsDraft
S006-EC-001Edge CaseP1Missing settings block entirelyDraft
S006-EC-002Edge CaseP1Empty parity.yaml (null parse result)Draft
S006-EC-003Edge CaseP1coverage_xml as string vs arrayDraft
S006-EC-004Edge CaseP2Missing namespace_rootsDraft
S006-EC-005Edge CaseP2Unknown keys in config (forward compatibility)Draft
S006-EC-006Edge CaseP1Structure entry missing required pathsDraft
S006-EC-007Edge CaseP1Empty structure arrayDraft
S006-EC-008Edge CaseP2file_map with empty or non-array valueDraft
S006-EC-009Edge CaseP1min_coverage as string vs numberDraft
S006-EC-010Edge CaseP2Negative or >100 coverage thresholdDraft
S006-EC-011Edge CaseP2Mixed legacy and modern keys in one structureDraft
S006-EC-012Edge CaseP1Config file is valid YAML but not an arrayDraft
S006-EC-013Edge CaseP2test_extension defaults to source_extensionDraft
S006-EC-014Edge CaseP2coverage_xml with non-string array elementsDraft
S006-EC-015Edge CaseP2Structure with rules but no test-existsDraft

Cross-Spec Dependencies

  • Depends on: None (configuration is a foundational module with no upstream spec dependencies)
  • Required by: S001 (CLI Commands -- loads config, passes to Settings), S002 (Rules System -- reads per-structure rules, global min_coverage), S003 (Coverage Readers -- reads coverage_xml paths), S004 (Coverage Linkers -- reads linker selection from structure rules), S005 (Plugin System -- plugin rules referenced by name in structure rules), S007 (Path & Namespace Mapping -- reads namespace_roots, source_extension, test_suffix, test_extension, namespace_separator)