Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

### Documentation and governance

- Added Phase 2.7B repository governance evidence finalization: changed the GitHub default branch to `2.x`, activated repository rulesets for `master` and `2.x`, preserved `master` as the EvolvePHP 1 legacy line, required PR-based change on both branches, blocked deletion and force pushes, enforced strict/up-to-date required status checks on `2.x` for `Policy (PHP 8.4)`, `Workspace quality (PHP 8.4)` and `Workspace quality (PHP 8.5)`, and made no branch rename or deletion.
- Added Phase 2.7A repository-owned branch-governance policy foundation for EvolvePHP 2 development on `2.x`, preserved EvolvePHP 1 maintenance on `master`, explicit separation of modern development and legacy maintenance, and preparation for a later default-branch and ruleset transition.
- Added Phase 2.6 GitHub Actions CI foundation with a PHP 8.4/8.5 workspace quality matrix, separate PHP 8.4 root-policy job, lockfile-based workspace installation, immutable action pinning, and successful initial CI execution for the current workspace, tooling and package foundation.
- Added Phase 2.5.1 README and metadata consistency cleanup, aligning the EvolvePHP 2 README hierarchy, correcting root Composer metadata, deduplicating stale RFC index narration, removing duplicated phase history, and clarifying workspace installation and compatibility guidance.
Expand Down
17 changes: 11 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# EvolvePHP 2

`2.x` is the designated EvolvePHP 2 development branch.
`2.x` is the designated EvolvePHP 2 development branch and the GitHub default branch.

`master` remains the preserved EvolvePHP 1 legacy branch for historical reference and explicitly approved legacy maintenance. EvolvePHP 2 development and proposed changes must not target `master`.

During Phase 2.7A, the current GitHub default branch remains `master` until the Phase 2.7 external transition. The live default-branch and ruleset transition is still pending external GitHub evidence.
Phase 2.7B completed the external governance transition. Repository rulesets actively protect both branch lines: `master` remains preserved, and `2.x` now receives default-branch development changes.

EvolvePHP 2 is not an in-place refactor, replacement or rewrite of the EvolvePHP 1 runtime history.

Expand All @@ -21,9 +21,12 @@ The EvolvePHP 2 line redesigns the framework as a modular package architecture w
## Current Status

- EvolvePHP 2 development branch: `2.x`
- Current GitHub default during Phase 2.7A: `master`
- GitHub default branch: `2.x`
- Legacy line: EvolvePHP 1 on `master`
- Governance transition: live default-branch and ruleset changes pending external verification
- Repository rulesets: active for `master` and `2.x`
- `master` ruleset: pull request requirement, deletion protection, force-push protection, required approvals remain zero, conversation resolution is required, and there are no bypass actors
- `2.x` ruleset: pull request requirement, deletion protection, force-push protection, required CI status checks, strict/up-to-date status-check policy, required approvals remain zero, conversation resolution is required, and there are no bypass actors
- Required `2.x` checks: `Policy (PHP 8.4)`, `Workspace quality (PHP 8.4)`, `Workspace quality (PHP 8.5)`
- Runtime implementation: not yet complete
- Package publication: packages are not yet published
- PHP baseline: PHP 8.4
Expand Down Expand Up @@ -56,11 +59,13 @@ The legacy EvolvePHP 1 runtime files remain in the repository for preservation a
```bash
git clone https://github.com/josiahking/evolvephp.git
cd evolvephp
git switch 2.x
git branch --show-current
composer --working-dir=workspace install
composer --working-dir=workspace quality
```

The normal clone path starts on `2.x` because it is the GitHub default branch. For an older local checkout, verify the branch with `git branch --show-current` and run `git switch 2.x` only when the checkout is not already on `2.x`.

The EvolvePHP 2 workspace owns dependency installation and quality checks. Use [workspace/README.md](workspace/README.md) for detailed Composer, PHPUnit, PHPStan, PHP-CS-Fixer and Deptrac guidance.

## Quality Checks
Expand All @@ -85,7 +90,7 @@ EvolvePHP 1 has been used as the foundation of Africa Global Export Market, a li

That production-use background belongs to the preserved EvolvePHP 1 history. New EvolvePHP 2 work happens separately on `2.x`, and EvolvePHP 2 changes must not target `master`. New production applications should not start from EvolvePHP 1 without a detailed security and compatibility review.

Phase 2.7A establishes repository-owned branch-governance policy only. `master` has not been renamed or deleted, no `main` branch has been created, and no `1.x` branch has been created. Any stable-release branch rename or promotion is deferred, and Phase 2.7 does not replace the legacy history.
Phase 2.7B completed the external governance transition without replacing history. `master` has not been renamed or deleted, no branch was renamed or deleted, no `main` branch has been created, and no `1.x` branch has been created. Any stable-release branch rename or promotion is deferred, and Phase 2.7 does not replace the legacy history.

See the [legacy overview](docs/history/evolvephp-1-overview.md), [known risks and limitations](docs/history/known-risks-and-limitations.md), [support policy](SUPPORT.md) and [security policy](SECURITY.md).

Expand Down
49 changes: 30 additions & 19 deletions tests/Documentation/EvolvePhp2RepositoryGovernanceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@ protected function setUp(): void
$this->root = dirname(__DIR__, 2);
}

public function testReadmeDocumentsStageABranchIdentity()
public function testReadmeDocumentsFinalBranchIdentity()
{
$content = $this->readProjectFile('README.md');

$this->assertMatchesPattern('/2\.x.*designated EvolvePHP 2 development branch|designated EvolvePHP 2 development branch.*2\.x/is', $content);
$this->assertMatchesPattern('/2\.x.*GitHub default branch|GitHub default branch.*2\.x/is', $content);
$this->assertMatchesPattern('/master.*preserved EvolvePHP 1 legacy branch|preserved EvolvePHP 1 legacy branch.*master/is', $content);
$this->assertMatchesPattern('/EvolvePHP 2 changes.*must not target.*master|must not target.*master.*EvolvePHP 2 changes/is', $content);
$this->assertMatchesPattern('/current GitHub default.*master.*Phase 2\.7 external transition|Phase 2\.7 external transition.*current GitHub default.*master/is', $content);
$this->assertDoesNotMatchPattern($this->unsupportedDefaultBranchClaimPattern(), $content);
$this->assertMatchesPattern('/repository rulesets?.*protect.*branch lines|branch lines.*protect.*repository rulesets?/is', $content);
$this->assertDoesNotMatchPattern($this->staleTransitionPattern(), $content);
}

public function testAgentRulesDocumentVerifiedBaseBranchWorkflow()
Expand Down Expand Up @@ -60,35 +61,45 @@ public function testCanonicalDocumentationKeepsStableCutoverDeferred()
$this->assertMatchesPattern('/Phase 2\.7.*does not replace.*legacy history|legacy history.*not.*replaced.*Phase 2\.7/is', $content);
}

public function testStageAEvidenceBoundaryIsDocumented()
public function testFinalGovernanceRulesetsAreDocumented()
{
$content = $this->readProjectFile('README.md') . "\n" . $this->readProjectFile('CHANGELOG.md');

$this->assertMatchesPattern('/Phase 2\.7A.*repository-owned branch-governance policy|repository-owned branch-governance policy.*Phase 2\.7A/is', $content);
$this->assertMatchesPattern('/live default-branch.*ruleset.*pending external GitHub evidence|pending external GitHub evidence.*live default-branch.*ruleset/is', $content);
$this->assertDoesNotMatchPattern($this->unsupportedDefaultBranchClaimPattern(), $content);
$this->assertDoesNotMatchPattern('/branch protection is active|rulesets? (?:is|are) active|required checks (?:are|have been) enforced/i', $content);
$this->assertMatchesPattern('/Phase 2\.7B.*completed.*external governance transition|external governance transition.*completed.*Phase 2\.7B/is', $content);
$this->assertMatchesPattern('/repository rulesets? (?:are )?active|active repository rulesets?/i', $content);
$this->assertMatchesPattern('/master.*pull request.*deletion.*force-push|master.*force-push.*deletion.*pull request/is', $content);
$this->assertMatchesPattern('/2\.x.*pull request.*deletion.*force-push.*required CI status checks.*strict|2\.x.*strict.*required CI status checks.*force-push.*deletion.*pull request/is', $content);
$this->assertMatchesPattern('/required approvals.*zero|zero.*required approvals/i', $content);
$this->assertMatchesPattern('/conversation resolution.*required|required.*conversation resolution/i', $content);
$this->assertMatchesPattern('/no bypass actors|bypass actors.*none/i', $content);
$this->assertMatchesPattern('/Policy \(PHP 8\.4\)/', $content);
$this->assertMatchesPattern('/Workspace quality \(PHP 8\.4\)/', $content);
$this->assertMatchesPattern('/Workspace quality \(PHP 8\.5\)/', $content);
$this->assertDoesNotMatchPattern($this->staleTransitionPattern(), $content);
$this->assertDoesNotMatchPattern('/classic branch protection|branch protection is active/i', $content);
$this->assertDoesNotMatchPattern('/master (?:was|has been) (?:renamed|deleted|replaced)/i', $content);
}

public function testChangelogRecordsPolicyFoundationWithoutExternalSettingChange()
public function testChangelogRecordsFinalGovernanceEvidence()
{
$content = $this->readProjectFile('CHANGELOG.md');

$this->assertMatchesPattern('/Phase 2\.7A/i', $content);
$this->assertMatchesPattern('/branch-governance policy/i', $content);
$this->assertMatchesPattern('/EvolvePHP 2 development on `2\.x`/i', $content);
$this->assertMatchesPattern('/EvolvePHP 1 maintenance on `master`/i', $content);
$this->assertMatchesPattern('/later default-branch and ruleset transition/i', $content);
$this->assertDoesNotMatchPattern($this->unsupportedDefaultBranchClaimPattern(), $content);
$this->assertDoesNotMatchPattern('/branch protection is active|rulesets? (?:is|are) active|required checks (?:are|have been) enforced/i', $content);
$this->assertMatchesPattern('/Phase 2\.7B/i', $content);
$this->assertMatchesPattern('/GitHub default branch.*`2\.x`|`2\.x`.*GitHub default branch/i', $content);
$this->assertMatchesPattern('/repository rulesets?.*`master`.*`2\.x`|`master`.*`2\.x`.*repository rulesets?/is', $content);
$this->assertMatchesPattern('/preserved `master`.*EvolvePHP 1 legacy line|EvolvePHP 1 legacy line.*preserved `master`/i', $content);
$this->assertMatchesPattern('/PR-based change.*both branches|both branches.*PR-based change/i', $content);
$this->assertMatchesPattern('/block(?:s|ed)? deletion.*force pushes|force pushes.*block(?:s|ed)? deletion/i', $content);
$this->assertMatchesPattern('/strict.*up-to-date required status checks|up-to-date.*strict.*required status checks/i', $content);
$this->assertMatchesPattern('/Policy \(PHP 8\.4\).*Workspace quality \(PHP 8\.4\).*Workspace quality \(PHP 8\.5\)/is', $content);
$this->assertMatchesPattern('/no branch rename or deletion|no branch was renamed or deleted/i', $content);
$this->assertDoesNotMatchPattern('/classic branch protection|branch protection is active/i', $content);
}

private function unsupportedDefaultBranchClaimPattern()
private function staleTransitionPattern()
{
$branch = '2' . '\.x';

return '/' . $branch . ' is (?:now |already )?the (?:GitHub )?default branch|default branch (?:is|changed to) `?' . $branch . '/i';
return '/current GitHub default.*master|default branch remains.*master|ruleset.*pending|default-branch.*pending|pending external GitHub evidence|live.*transition.*pending/i';
}

private function readProjectFile($path)
Expand Down