implements PR-06.5
This commit is contained in:
parent
3e345ab827
commit
4fb3d686e3
@ -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`.
|
||||
|
||||
|
||||
@ -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.
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user