TenantAtlas/apps/platform/tests/Feature/Guards/ConstitutionBranchTopologyContractTest.php
Ahmed Darrazi 8144a3be78
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 7m2s
feat: implement spec 439 branch and evidence truth
2026-07-11 21:13:42 +02:00

109 lines
4.4 KiB
PHP

<?php
declare(strict_types=1);
function spec439ConstitutionContents(): string
{
$path = repo_path('.specify/memory/constitution.md');
expect(is_file($path))->toBeTrue();
return (string) file_get_contents($path);
}
function spec439ConstitutionUnrelatedBody(string $contents): string
{
$withoutSyncImpact = preg_replace(
'/\A<!--\RSync Impact Report.*?-->\R\R/s',
'',
$contents,
);
$withoutBranchAmendment = preg_replace(
'/### Spec-First Workflow\R.*?(?=\R## Quality Gates)/s',
"### Spec-First Workflow\n[BRANCH-TOPOLOGY-AMENDMENT]\n",
$withoutSyncImpact,
);
$withoutAmendmentMetadata = preg_replace(
'/^\*\*Version\*\*:.*$/m',
'**Version**: [AMENDMENT-METADATA]',
$withoutBranchAmendment,
);
if (! is_string($withoutAmendmentMetadata)) {
throw new RuntimeException('Unable to normalize Constitution amendment boundaries.');
}
return $withoutAmendmentMetadata;
}
it('defines the three canonical branch roles and fail-closed scope routing', function (): void {
$contents = spec439ConstitutionContents();
expect($contents)
->toContain(
'`dev` is the repository-wide integration and promotion branch',
'`platform-dev` is the integration branch for TenantPilot platform work',
'`website-dev` is the integration branch for website work',
'Ordinary platform work MUST branch from, target, and diff against `platform-dev`',
'ordinary website work MUST branch from, target, and diff against `website-dev`',
'Cross-stream integration, promotion, and repository-governance work MUST be explicitly classified',
'Such work MAY target `dev`; the existence of `dev` alone MUST NOT imply that target.',
'Ambiguous or missing branch-family/ref resolution MUST fail closed.',
'`origin/dev`, the wrong branch family, `HEAD~1`, or an arbitrary prior commit',
)
->not->toContain('- New work branches from `dev` using `feat/<NNN>-<slug>`');
expect(substr_count($contents, '### Spec-First Workflow'))->toBe(1);
});
it('keeps the major amendment metadata and Sync Impact report coherent', function (): void {
$contents = spec439ConstitutionContents();
expect($contents)
->toContain(
'- Version change: 2.16.0 -> 3.0.0',
'MAJOR because a normative universal branch rule is redefined',
'- Added sections: None',
'- Removed sections: None',
'✅ `Agents.md`: directly conflicting universal `dev` instructions were',
'✅ Specs 437 and 438: historical/completed or deferred context remains',
'**Version**: 3.0.0 | **Ratified**: 2026-01-03 | **Last Amended**: 2026-07-11',
)
->not->toContain('⏳ `Agents.md`');
expect(substr_count($contents, 'Sync Impact Report'))->toBe(1)
->and(substr_count($contents, '**Version**:'))->toBe(1);
});
it('locks all Constitution content outside the authorized amendment boundaries', function (): void {
$normalized = spec439ConstitutionUnrelatedBody(spec439ConstitutionContents());
expect(hash('sha256', $normalized))
->toBe('9ea4019798f1854e7b513a8fe0bce2529a19207d0b16e81a08582e6b661b8e74');
});
it('keeps authoritative repository branch instructions synchronized', function (): void {
$instructions = (string) file_get_contents(repo_path('Agents.md'));
expect($instructions)
->toContain(
'`dev`: repository-weite Integration und Promotion',
'`platform-dev`: Integration für TenantPilot-Plattformarbeit',
'`website-dev`: Integration für Website-Arbeit',
'Normale Plattformarbeit startet von und zielt auf `platform-dev`',
'Website-Arbeit startet von und zielt auf `website-dev`',
'Cross-Stream-, Promotion- und Repository-Governance-Arbeit muss ausdrücklich',
'`dev` darf dabei ein',
'bewusstes Integrations-/Promotion-Ziel sein, aber kein stiller Fallback.',
'Für normale Plattformarbeit ist das `origin/platform-dev`',
'Website-Arbeit `origin/website-dev`',
'`origin/dev` ist nur für ausdrücklich als',
)
->not->toContain(
'- Default / Integrations-Branch: `dev`',
'Neue Arbeit läuft über Feature-Branches von `dev`',
'PR/MR: `feat/...` → `dev`',
"git merge origin/dev\n",
);
});