S010 Functional Requirements
Test Suite Organization
S010-FR-001 [P1] The test suite MUST be organized into two test suites per phpunit.xml.dist: Unit and Feature. S010-FR-001.a Unit tests MUST reside in parity/tests/Unit/ and MUST test individual classes and services in isolation. S010-FR-001.b Feature tests MUST reside in parity/tests/Feature/ and MUST test end-to-end CLI or release workflows. S010-FR-001.c Unit test files MUST be suffixed with Test.php (e.g., RuleRegistryTest.php). S010-FR-001.d Feature test files MUST be suffixed with Test.php (e.g., InitCommandTest.php).
S010-FR-002 [P1] Test naming conventions MUST be consistent within each suite: S010-FR-002.a Feature tests SHOULD use Pest closure-style test() or it() functions because they exercise CLI behavior through Laravel Zero. S010-FR-002.b Unit tests MAY use PHPUnit TestCase classes when class setup/teardown or isolated service fixtures are clearer. S010-FR-002.c Test names SHOULD be descriptive English phrases or PHPUnit method names that clearly state the behavior under test.
Pest Configuration
S010-FR-003 [P1] Pest configuration MUST be defined in parity/tests/Pest.php. S010-FR-003.a The uses() call MUST bind Tests\TestCase::class to the Feature directory. S010-FR-003.b Custom expectations MAY be added via expect()->extend(). S010-FR-003.c Helper functions MAY be defined globally in Pest.php.
S010-FR-004 [P1] Coverage report generation MUST be configured in phpunit.xml.dist. S010-FR-004.a The <coverage> element MUST include PHPUnit XML and Clover report targets. S010-FR-004.b CI and release-gate test runs MUST generate both coverage-xml/ and clover.xml.
Spec ID Traceability
S010-FR-005 [P1] All behavior-focused test files MUST reference the spec IDs they verify. S010-FR-005.a Pest feature tests MUST include a // Specs: comment near the top of the file or equivalent Pest group() metadata. S010-FR-005.b PHPUnit unit test classes MUST include a // Specs: comment near the class declaration when they verify public behavior. S010-FR-005.c Tests covering multiple spec IDs MUST list all relevant IDs in the traceability comment or group metadata.
CI Pipeline Triggers
S010-FR-006 [P1] The CI pipeline MUST trigger on the following events: S010-FR-006.a On every branch push. S010-FR-006.b On every pull request opened against main. S010-FR-006.c On manual workflow dispatch (workflow_dispatch).
CI Lint Job
S010-FR-007 [P1] The CI lint job MUST run Laravel Pint to verify code style compliance. S010-FR-007.a The job MUST run ./vendor/bin/pint --test to check without modifying files. S010-FR-007.b If Pint detects any style violations, the job MUST fail with a non-zero exit code. S010-FR-007.c The lint job MUST NOT modify files in the CI environment; it MUST only report violations.
CI Test Job
S010-FR-008 [P1] The CI test job MUST execute the full Pest test suite. S010-FR-008.a The job MUST run ./vendor/bin/pest. S010-FR-008.b The job MUST generate coverage-xml/ and clover.xml. S010-FR-008.c The job MUST use PHP 8.4 with Xdebug coverage driver configured. S010-FR-008.d If any test fails, the job MUST fail with a non-zero exit code.
CI Coverage Job
S010-FR-009 [P1] The CI job MUST run Parity against itself using the generated coverage report. S010-FR-009.a The job MUST run php parity check --format=json to validate structural parity. S010-FR-009.b The self-check MUST prefer the attribution-capable PHPUnit XML directory generated by the test step. S010-FR-009.c If Parity detects any structural violations, the job MUST fail with a non-zero exit code.
CI Artifact Publication
S010-FR-010 [P1] The CI pipeline MUST upload Parity JSON results as a build artifact. S010-FR-010.a Every completed self-check MUST save parity check --format=json output to parity-results.json while preserving the command's exit code. S010-FR-010.b The artifact MUST be uploaded using actions/upload-artifact@v4, including after a failed self-check, and MUST NOT mask an earlier gate that failed before producing the file. S010-FR-010.c The artifact MUST be named parity-results and retained for 30 days.
Box PHAR Compilation
S010-FR-011 [P1] The system MUST use Box to compile a standalone PHAR binary from the Parity application. S010-FR-011.a The box.json configuration MUST include app, bootstrap, config, and vendor directories. S010-FR-011.b The box.json MUST set chmod to 0755 for the PHAR binary. S010-FR-011.c The box.json MUST use KevinGH\Box\Compactor\Php and KevinGH\Box\Compactor\Json compactors. S010-FR-011.d The box.json MUST set compression to GZ (gzip). S010-FR-011.e The PHAR MUST be built via ./vendor/bin/box compile.
PHAR Distribution Mechanism
S010-FR-012 [P1] The PHAR binary MUST be distributed via a GitHub Release asset. S010-FR-012.a Every git tag MUST trigger a GitHub Actions workflow that builds and uploads the PHAR as a Release asset. S010-FR-012.b The PHAR asset MUST be named parity.phar. S010-FR-012.c The Release MUST include a SHA-256 checksum file (parity.phar.sha256) as a separate asset.
PHAR Version Injection
S010-FR-013 [P1] The PHAR binary MUST report the correct version when run with parity --version. S010-FR-013.a The Box configuration MUST package the tracked VERSION file as the build-time version source. S010-FR-013.b The version string MUST match the git tag associated with the build (e.g., v1.0.0). S010-FR-013.c The tagged release workflow MUST fail before building when the tag, tracked VERSION, and changelog section do not identify the same release.
Laravel Pint Integration
S010-FR-014 [P1] Laravel Pint MUST be used for code style enforcement. S010-FR-014.a Pint MUST be listed in require-dev in composer.json with a version constraint ^1.25.1. S010-FR-014.b A .php_cs or pint.json configuration MAY be included to customize rule sets. S010-FR-014.c Pint SHOULD be run as a pre-commit hook (via Composer scripts or husky) when installed locally.
Release Version Bumping
S010-FR-015 [P1] The release process MUST update the tracked VERSION file and CHANGELOG.md. S010-FR-015.a The VERSION value MUST match the release tag format v{MAJOR}.{MINOR}.{PATCH}. S010-FR-015.b Version bumping MUST be automated via a release script (e.g., dev/release-version.sh). S010-FR-015.c The script MUST accept patch, minor, or major as an argument to indicate bump type. S010-FR-015.d The script MUST support a non-mutating --dry-run preview and an explicit --push mode. S010-FR-015.e Release metadata verification MUST be shared by the local release script and tagged CI workflow.
Changelog Generation
S010-FR-016 [P1] A changelog MUST be maintained in CHANGELOG.md. S010-FR-016.a The changelog MUST follow the Keep a Changelog format. S010-FR-016.b Maintainers MUST curate at least one change bullet beneath ## [Unreleased] before releasing. S010-FR-016.c The release script MUST promote the Unreleased notes into a new version entry with the current date. S010-FR-016.d The changelog entry MUST include Added, Changed, Fixed, Removed, or Security sections where applicable and MUST NOT contain placeholder notes.
Git Tagging
S010-FR-017 [P1] Every release MUST create a corresponding git tag. S010-FR-017.a The tag format MUST be v{MAJOR}.{MINOR}.{PATCH} (e.g., v1.0.0). S010-FR-017.b When --push is supplied, the release commit and tag MUST be pushed atomically to the remote. S010-FR-017.c The tag MUST be annotated (git tag -a) with a message referencing the version and changelog entry.
GitHub Release Creation
S010-FR-018 [P1] Every git tag push MUST trigger GitHub Release creation via GitHub Actions. S010-FR-018.a The Release MUST be titled with the version string (e.g., v1.0.0). S010-FR-018.b The Release body MUST contain generated release notes, while CHANGELOG.md remains the curated project changelog. S010-FR-018.c The PHAR binary MUST be attached as a Release asset. S010-FR-018.d The Release MUST remain a draft until the public Packagist smoke test passes, then be published. S010-FR-018.e The public smoke MUST install the exact tag from Packagist, assert parity --version, and successfully run both parity check and parity test.
Sample Project Matrix
S010-FR-019 [P1] The repository MUST include runnable sample projects under samples/ that exercise Parity across multiple language and framework conventions. S010-FR-019.a The sample matrix MUST include plain PHP, Laravel-style PHP, Vite/TypeScript, AdonisJS-style TypeScript, and Rust-style layouts. S010-FR-019.b Each sample MUST include a parity.yaml, at least one source file, at least one matching test file, and a supported coverage fixture. S010-FR-019.c The test suite MUST execute parity check --format=json --config=samples/{name}/parity.yaml against every sample. S010-FR-019.d All sample checks MUST pass with exit code 0 before release. S010-FR-019.e The sample matrix SHOULD include runnable tool samples for PHPUnit, Pest, Jest, Mocha, Vitest, and Cargo/Rust, each with a code/ directory and a result.md capturing native test and Parity outcomes.

