diff --git a/docs/general/specs/22. Backend Spec-to-Test Conformance Matrix.md b/docs/general/specs/22. Backend Spec-to-Test Conformance Matrix.md index f182c538..27cffd0c 100644 --- a/docs/general/specs/22. Backend Spec-to-Test Conformance Matrix.md +++ b/docs/general/specs/22. Backend Spec-to-Test Conformance Matrix.md @@ -38,7 +38,7 @@ to concrete positive/negative test evidence and current status. | G19-5.2.5 | Gate S-I MUST reject host ABI mismatch. | N/A | `BackendGateIIntegrationTest#gateI_rejectHostAbiMismatchAtEmitTime` | pass | | | G19-5.2.6 | Gate S-I MUST reject missing capability at load-time. | N/A | `BackendGateIIntegrationTest#gateI_rejectMissingCapability` | pass | | | G19-5.2.7 | Gate S-I MUST cover valid VM-owned intrinsic path. | `BackendGateIIntegrationTest#gateI_validIntrinsicPath` | N/A | pass | | -| G19-5.2.8 | Gate S-I MUST cover repeatability across runtime line. | `RuntimeBackedCompatibilityAdapterTest#checkMustPassInStrictModeWhenRuntimeCommandIsValid` | `RuntimeBackedCompatibilityAdapterTest#checkMustFailInStrictModeWhenRuntimeCommandIsUnavailable` | partial | Runtime-line repeatability is validated at adapter contract level; multi-line matrix coverage is pending. | +| G19-5.2.8 | Gate S-I MUST cover repeatability across runtime line. | `RuntimeBackedCompatibilityAdapterTest#checkMustPassInStrictModeWhenRuntimeCommandIsValid`; `RuntimeBackedCompatibilityAdapterTest#checkMustBeRepeatableAcrossDeclaredRuntimeLinesInStrictMode` | `RuntimeBackedCompatibilityAdapterTest#checkMustFailInStrictModeWhenRuntimeCommandIsUnavailable` | pass | Multi-line repeatability is asserted with strict runtime-backed checks over distinct declared runtime lines. | | G20-6.2 | `IRVM_EXT` MUST declare structural metadata (`pops/pushes/is_branch/is_terminator`). | `IRVMValidatorTest#validateMustApplyStructuralMetadataForCustomInternalExtension`; `IRVMValidatorTest#validateMustRejectCustomInternalExtensionWhenStructuralMetadataUnderflowsStack`; `IRVMOp` record contract (`pops/pushes/branch/terminator/internal`) | N/A | pass | Dedicated extension fixtures now assert structural metadata is consumed by validation behavior. | | G20-6.3 | `IRVM_EXT` MUST be eliminable before bytecode emission. | `OptimizeIRVMServiceTest#optimizeDefaultPassesMustEliminateUnreachableInternalExtensionBeforeEmission` | `EmitBytecodePipelineStageTest#runMustFailWhenInternalOpcodesRemain`; `EmitBytecodePipelineStageTest#runMustFailWhenInternalOpcodesRemainEvenWithNonEmptyEmissionPlan`; `IRVMValidatorTest#validateMustRejectInternalOpcodeWhenConfigured` | pass | Optimizer elimination path and emit-stage hard rejection path are both covered. | | G20-6.4 | IRVM MUST preserve per-function slot and identity headers. | `IRVMProgramTest#constructorMustRejectModuleAndEmissionPlanMismatch` | `IRVMProgramTest#constructorMustRejectModuleAndEmissionPlanMismatch` | pass | Header mismatch is rejected deterministically. | diff --git a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeBackedCompatibilityAdapterTest.java b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeBackedCompatibilityAdapterTest.java index 989e4031..a0713bb5 100644 --- a/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeBackedCompatibilityAdapterTest.java +++ b/prometeu-compiler/prometeu-build-pipeline/src/test/java/p/studio/compiler/integration/RuntimeBackedCompatibilityAdapterTest.java @@ -1,11 +1,14 @@ package p.studio.compiler.integration; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; import p.studio.compiler.backend.bytecode.BytecodeModule; import p.studio.utilities.structures.ReadOnlyList; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; +import java.nio.file.Files; import java.nio.file.Path; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -67,6 +70,44 @@ class RuntimeBackedCompatibilityAdapterTest { assertTrue(result.reason().contains("accepted artifact")); } + @Test + void checkMustBeRepeatableAcrossDeclaredRuntimeLinesInStrictMode( + @TempDir final Path tempDir) throws IOException { + final var runtimeLineA = tempDir.resolve("runtime-a"); + final var runtimeLineB = tempDir.resolve("runtime-b"); + Files.createDirectories(runtimeLineA); + Files.createDirectories(runtimeLineB); + Files.writeString(runtimeLineA.resolve("VERSION.txt"), "1.0.0-a\n"); + Files.writeString(runtimeLineB.resolve("VERSION.txt"), "1.0.0-b\n"); + + final var adapterA = new RuntimeBackedCompatibilityAdapter( + new LocalRuntimeCompatibilityAdapter(), + runtimeLineA, + "test -f {artifact}", + true); + final var adapterB = new RuntimeBackedCompatibilityAdapter( + new LocalRuntimeCompatibilityAdapter(), + runtimeLineB, + "test -f {artifact}", + true); + + final var firstA = adapterA.check(moduleWithSingleRet()); + final var firstB = adapterB.check(moduleWithSingleRet()); + final var secondA = adapterA.check(moduleWithSingleRet()); + final var secondB = adapterB.check(moduleWithSingleRet()); + + assertEquals(CompatibilityError.NONE, firstA.error()); + assertEquals(CompatibilityError.NONE, firstB.error()); + assertEquals("runtime-backed", firstA.adapterMode()); + assertEquals("runtime-backed", firstB.adapterMode()); + assertEquals("runtime-v1.0.0-a", firstA.runtimeLine()); + assertEquals("runtime-v1.0.0-b", firstB.runtimeLine()); + assertEquals(firstA.runtimeLine(), secondA.runtimeLine()); + assertEquals(firstB.runtimeLine(), secondB.runtimeLine()); + assertEquals(firstA.error(), secondA.error()); + assertEquals(firstB.error(), secondB.error()); + } + private BytecodeModule moduleWithSingleRet() { return new BytecodeModule( 0,