implements PR-06.5

This commit is contained in:
bQUARKz 2026-03-09 08:04:54 +00:00
parent 3e345ab827
commit 4fb3d686e3
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
4 changed files with 98 additions and 0 deletions

View File

@ -105,6 +105,7 @@ For PBS quality claims at this stage:
- a language may be considered `frontend-ready` only with Gate U passing,
- a language may be considered `integration-ready` only with Gate U and Gate I passing where Gate I applies,
- and a published support claim must map to executable evidence from these gates.
- conformance-relevant FE/BE changes in executable backend paths MUST update `22. Backend Spec-to-Test Conformance Matrix.md` and pass matrix hard-gate policy checks.
The exact publication vocabulary is owned by `17. Compatibility and Evolution Policy.md`.

View File

@ -96,10 +96,18 @@ to concrete positive/negative test evidence and current status.
1. Any backend PR that changes conformance-relevant behavior in FE/BE pipeline MUST update this matrix.
2. If requirement coverage changes, update: mapped tests, status, and `Last Updated` date.
3. New normative MUSTs in specs `19/20/21` or PBS `13` addendum MUST add a new matrix row before merge.
4. Conformance-relevant FE/BE code paths for hard-gate are:
- `prometeu-compiler/prometeu-build-pipeline/`
- `prometeu-compiler/frontends/prometeu-frontend-pbs/`
- `prometeu-compiler/prometeu-frontend-api/`
- `prometeu-compiler/prometeu-compiler-core/`
## 6. Review/Lint Gate
Matrix integrity is enforced by automated document lint:
- `BackendConformanceMatrixSpecTest` validates file presence, required requirement IDs, and row status integrity.
- `BackendConformanceMatrixSpecTest` enforces hard-gate policy:
- if `PROMETEU_MATRIX_HARD_GATE=true` and `PROMETEU_CHANGED_FILES` contains a path under conformance-relevant FE/BE prefixes,
- then this matrix file MUST be present in `PROMETEU_CHANGED_FILES`, otherwise the gate fails.
- CI policy uses strict Gate I mode via `PROMETEU_GATE_I_STRICT=true` (or `CI=true`) and requires `PROMETEU_RUNTIME_CHECK_CMD` for runtime-backed evidence.

View File

@ -136,6 +136,7 @@ Every accepted change MUST update, when relevant:
- diagnostics documentation,
- conformance tests,
- compatibility matrix/changelog.
- For executable FE/BE conformance-relevant code changes, the backend conformance matrix (`docs/general/specs/22. Backend Spec-to-Test Conformance Matrix.md`) MUST be updated and pass hard-gate policy checks.
## 12. Conflict Resolution

View File

@ -5,15 +5,24 @@ import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.regex.Pattern;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
class BackendConformanceMatrixSpecTest {
private static final String MATRIX_RELATIVE_PATH = "docs/general/specs/22. Backend Spec-to-Test Conformance Matrix.md";
private static final String MATRIX_HARD_GATE_ENV = "PROMETEU_MATRIX_HARD_GATE";
private static final String CHANGED_FILES_ENV = "PROMETEU_CHANGED_FILES";
private static final List<String> HARD_GATE_PATH_PREFIXES = List.of(
"prometeu-compiler/prometeu-build-pipeline/",
"prometeu-compiler/frontends/prometeu-frontend-pbs/",
"prometeu-compiler/prometeu-frontend-api/",
"prometeu-compiler/prometeu-compiler-core/");
private static final Pattern LAST_UPDATED_PATTERN = Pattern.compile("Last Updated: \\d{4}-\\d{2}-\\d{2}");
private static final List<String> REQUIRED_IDS = List.of(
"G19-5.1.1",
@ -99,6 +108,46 @@ class BackendConformanceMatrixSpecTest {
}
}
@Test
void hardGatePolicyMustFailWhenConformanceRelevantPathsChangeWithoutMatrixUpdate() {
final var changedFiles = List.of(
"prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/irvm/OptimizeIRVMService.java",
"prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/PbsFrontendCompiler.java");
assertTrue(requiresMatrixUpdate(changedFiles));
}
@Test
void hardGatePolicyMustPassWhenConformanceRelevantPathsChangeAndMatrixIsUpdated() {
final var changedFiles = List.of(
"prometeu-compiler/prometeu-build-pipeline/src/main/java/p/studio/compiler/backend/irvm/OptimizeIRVMService.java",
MATRIX_RELATIVE_PATH);
assertFalse(requiresMatrixUpdate(changedFiles));
}
@Test
void hardGatePolicyMustIgnoreNonConformanceChangesWithoutMatrixUpdate() {
final var changedFiles = List.of(
"README.md",
"docs/pbs/agendas/18.0. Backend VM Pipeline - Orchestration Agenda.md");
assertFalse(requiresMatrixUpdate(changedFiles));
}
@Test
void matrixHardGateEnvironmentCheckMustRejectRelevantChangesWithoutMatrixUpdate() {
if (!isTruthy(System.getenv(MATRIX_HARD_GATE_ENV))) {
return;
}
final var changedFiles = parseChangedFiles(System.getenv(CHANGED_FILES_ENV));
assertTrue(!changedFiles.isEmpty(),
CHANGED_FILES_ENV + " must be provided when " + MATRIX_HARD_GATE_ENV + " is enabled");
assertFalse(
requiresMatrixUpdate(changedFiles),
"conformance-relevant FE/BE changes require matrix update: " + MATRIX_RELATIVE_PATH);
}
private Optional<String> findRequirementRow(
final List<String> lines,
final String requirementId) {
@ -119,4 +168,43 @@ class BackendConformanceMatrixSpecTest {
fail("could not locate repository root from working directory");
throw new IllegalStateException("unreachable");
}
private boolean requiresMatrixUpdate(final List<String> changedFiles) {
final var normalized = changedFiles.stream()
.filter(path -> path != null && !path.isBlank())
.map(path -> path.replace('\\', '/'))
.toList();
final var relevantTouched = normalized.stream().anyMatch(this::isConformanceRelevantPath);
final var matrixTouched = normalized.stream().anyMatch(path -> path.equals(MATRIX_RELATIVE_PATH));
return relevantTouched && !matrixTouched;
}
private boolean isConformanceRelevantPath(final String path) {
for (final var prefix : HARD_GATE_PATH_PREFIXES) {
if (path.startsWith(prefix)) {
return true;
}
}
return false;
}
private List<String> parseChangedFiles(final String raw) {
if (raw == null || raw.isBlank()) {
return List.of();
}
return Arrays.stream(raw.split("[,\\n]"))
.map(String::trim)
.filter(path -> !path.isBlank())
.toList();
}
private boolean isTruthy(final String value) {
if (value == null) {
return false;
}
return switch (value.trim().toLowerCase()) {
case "1", "true", "yes", "on" -> true;
default -> false;
};
}
}