diff --git a/docs/release-control/v6/internal/CANONICAL_DEVELOPMENT_PROTOCOL.md b/docs/release-control/v6/internal/CANONICAL_DEVELOPMENT_PROTOCOL.md index 97a1e6dc3a..3d05d4e67b 100644 --- a/docs/release-control/v6/internal/CANONICAL_DEVELOPMENT_PROTOCOL.md +++ b/docs/release-control/v6/internal/CANONICAL_DEVELOPMENT_PROTOCOL.md @@ -630,8 +630,10 @@ edits are not sufficient completion proof for runtime changes. Verification artifacts are subsystem-specific. The allowed proof classes are defined in `docs/release-control/v6/internal/subsystems/registry.json` and may include explicit guardrail files, contract tests, benchmark/SLO/query-plan artifacts, -approved test-prefix matches, non-test contract/type files, or same-subsystem -tests only when the registry explicitly allows them. +approved test-prefix matches, or non-test contract/type files. An arbitrary +test elsewhere in the same subsystem is never proof on its own: the registry +audit keeps `allow_same_subsystem_tests` false, because it would accept any +test the subsystem owns rather than the ones a path policy names. Cross-subsystem contract dependencies are not advisory. If a touched runtime path is named in another subsystem contract's `Canonical Files`, @@ -646,7 +648,10 @@ satisfy the first matching proof policy for that file. The v6 registry requires explicit path-policy coverage for every governed subsystem, and default subsystem verification is no longer a supported governed path. New owned runtime files must therefore be added to a concrete proof route instead of -inheriting subsystem-default verification. +inheriting subsystem-default verification. For the same reason the registry +audit requires each subsystem's default `test_prefixes` and `exact_files` to +stay empty: a proof listed there is never consulted, so it belongs on the path +policy whose runtime files it proves. ## Guardrails diff --git a/docs/release-control/v6/internal/subsystems/registry.json b/docs/release-control/v6/internal/subsystems/registry.json index b8ddb8e624..609d75e1e7 100644 --- a/docs/release-control/v6/internal/subsystems/registry.json +++ b/docs/release-control/v6/internal/subsystems/registry.json @@ -2467,11 +2467,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "internal/alerts/migration_characterization_test.go", - "internal/alerts/specs/evaluator_test.go", - "internal/alerts/specs/types_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -2887,12 +2883,8 @@ ], "verification": { "allow_same_subsystem_tests": false, - "test_prefixes": [ - "frontend-modern/src/api/__tests__/" - ], - "exact_files": [ - "internal/api/contract_test.go" - ], + "test_prefixes": [], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -3652,10 +3644,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "internal/api/contract_test.go", - "pkg/licensing/grant_claims_contract_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -4681,10 +4670,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "scripts/installtests/build_release_assets_test.go", - "scripts/installtests/install_docker_sh_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -5334,9 +5320,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "frontend-modern/src/components/shared/TypeColumn.guardrails.test.ts" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -6071,9 +6055,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "internal/unifiedresources/code_standards_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -6752,13 +6734,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "frontend-modern/src/api/__tests__/orgs.test.ts", - "frontend-modern/src/components/Settings/__tests__/OrganizationAccessPanel.test.tsx", - "frontend-modern/src/components/Settings/__tests__/OrganizationOverviewPanel.test.tsx", - "frontend-modern/src/utils/__tests__/organizationSettingsPresentation.test.ts", - "internal/models/organization_additional_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -6949,12 +6925,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "frontend-modern/src/components/AI/__tests__/FindingsPanel.test.ts", - "frontend-modern/src/pages/__tests__/AIIntelligence.test.tsx", - "frontend-modern/src/stores/__tests__/aiIntelligence.test.ts", - "frontend-modern/src/stores/__tests__/aiIntelligenceSummaryModel.test.ts" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -7205,38 +7176,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "frontend-modern/src/components/Workloads/__tests__/DiskList.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/EnhancedCPUBar.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/StackedDiskBar.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/useEnhancedCPUBarState.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/useGroupedTableWindowing.test.ts", - "frontend-modern/src/components/Workloads/__tests__/useMetricBarState.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/useStackedDiskBarState.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/useStackedMemoryBarState.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/useThresholdSliderState.test.ts", - "frontend-modern/src/components/Workloads/__tests__/useWorkloadSelectionState.test.ts", - "frontend-modern/src/components/Workloads/__tests__/useWorkloadViewportSync.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/workloadFilterConfigModel.test.ts", - "frontend-modern/src/components/Workloads/__tests__/workloadInventorySourceIssues.branchcov2.test.ts", - "frontend-modern/src/components/Workloads/__tests__/workloadInventorySourceIssues.test.ts", - "frontend-modern/src/components/Workloads/__tests__/workloadRouteModel.test.ts", - "frontend-modern/src/components/Workloads/__tests__/workloadRouteStateModel.test.ts", - "frontend-modern/src/components/Workloads/__tests__/workloadSelectionModel.test.ts", - "frontend-modern/src/components/Workloads/__tests__/WorkloadsFilter.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/WorkloadsSurface.performance.contract.test.tsx", - "frontend-modern/src/components/Workloads/__tests__/workloadUrlSyncModel.test.ts", - "frontend-modern/src/components/Workloads/MetricBar.test.tsx", - "frontend-modern/src/components/Workloads/StackedMemoryBar.test.tsx", - "frontend-modern/src/components/Workloads/ThresholdSlider.test.tsx", - "frontend-modern/src/hooks/__tests__/useWorkloads.test.ts", - "internal/api/router_bench_test.go", - "internal/api/slo_bench_test.go", - "pkg/metrics/store_bench_test.go", - "pkg/metrics/store_query_plan_test.go", - "pkg/metrics/store_slo_test.go", - "pkg/server/gzip_middleware_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -7479,28 +7419,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "internal/api/relay_mobile_capability_test.go", - "internal/config/persistence_relay_test.go", - "internal/relay/client_test.go", - "internal/relay/encryption_test.go", - "internal/relay/protocol_test.go", - "internal/relay/push_test.go", - "pulse-mobile:src/api/__tests__/coreMobileContract.test.ts", - "pulse-mobile:src/relay/__tests__/channel.test.ts", - "pulse-mobile:src/relay/__tests__/client-hardening.test.ts", - "pulse-mobile:src/relay/__tests__/client.test.ts", - "pulse-mobile:src/relay/__tests__/encryption.test.ts", - "pulse-mobile:src/relay/__tests__/identity.test.ts", - "pulse-mobile:src/relay/__tests__/protocol-contract.test.ts", - "pulse-mobile:src/relay/__tests__/protocol.test.ts", - "pulse-mobile:src/relay/__tests__/proxy.test.ts", - "pulse-pro:relay-server/bridge_test.go", - "pulse-pro:relay-server/device_store_test.go", - "pulse-pro:relay-server/metrics_test.go", - "scripts/release_control/generate_mobile_compatibility_test.py", - "scripts/release_control/mobile_compatibility_test.py" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -7678,28 +7597,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "frontend-modern/src/api/__tests__/security.test.ts", - "frontend-modern/src/components/Settings/__tests__/APITokenManager.test.tsx", - "frontend-modern/src/components/Settings/__tests__/SecurityPostureSummary.test.tsx", - "frontend-modern/src/components/Settings/__tests__/settingsArchitecture.test.ts", - "frontend-modern/src/stores/__tests__/systemSettings.test.ts", - "internal/api/security_regression_test.go", - "internal/api/security_status_additional_test.go", - "internal/api/security_tokens_lifecycle_test.go", - "internal/api/security_tokens_owner_binding_test.go", - "internal/api/security_tokens_test.go", - "internal/api/system_settings_telemetry_test.go", - "internal/cloudcp/auth/magiclink_test.go", - "internal/config/config_load_test.go", - "internal/config/watcher_test.go", - "internal/telemetry/service_health_test.go", - "internal/telemetry/telemetry_test.go", - "pkg/server/service_health_test.go", - "pkg/server/telemetry_pulse_intelligence_test.go", - "pkg/tlsutil/tlsutil_test.go", - "scripts/tests/test_telemetry_adoption_report.py" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -8005,10 +7903,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "frontend-modern/src/components/Storage/code_standards.test.ts", - "internal/recovery/recovery_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { @@ -8295,10 +8190,7 @@ "verification": { "allow_same_subsystem_tests": false, "test_prefixes": [], - "exact_files": [ - "frontend-modern/src/stores/__tests__/websocket-unified.test.ts", - "internal/unifiedresources/code_standards_test.go" - ], + "exact_files": [], "require_explicit_path_policy_coverage": true, "path_policies": [ { diff --git a/scripts/release_control/canonical_completion_guard_test.py b/scripts/release_control/canonical_completion_guard_test.py index 0c6044ecb1..3b2103f2e9 100644 --- a/scripts/release_control/canonical_completion_guard_test.py +++ b/scripts/release_control/canonical_completion_guard_test.py @@ -254,10 +254,7 @@ class CanonicalCompletionGuardTest(unittest.TestCase): self.assertTrue( monitoring["verification"]["require_explicit_path_policy_coverage"] ) - self.assertEqual( - monitoring["verification"]["exact_files"], - ["internal/unifiedresources/code_standards_test.go"], - ) + self.assertEqual(monitoring["verification"]["exact_files"], []) policy_ids = [policy["id"] for policy in monitoring["verification"]["path_policies"]] self.assertEqual( policy_ids, diff --git a/scripts/release_control/registry_audit.py b/scripts/release_control/registry_audit.py index 5d5bc5355e..dedd3b9fc5 100644 --- a/scripts/release_control/registry_audit.py +++ b/scripts/release_control/registry_audit.py @@ -27,16 +27,24 @@ REGISTRY_PATH = DEFAULT_CONTROL_PLANE["registry_path"] REGISTRY_SCHEMA_PATH = DEFAULT_CONTROL_PLANE["registry_schema_path"] LANE_RE = re.compile(r"^L[0-9]+$") # Every subsystem requires explicit path-policy coverage, so the default -# policy is never consulted and a path policy's own proof routes are the whole -# requirement. allow_same_subsystem_tests would widen a policy to every test -# the subsystem owns (any internal/ai test for ai-runtime's mutation-registry -# policy), and its reach would grow with ownership rather than with the -# policy. The commit guards ignored the flag from the v6 import until it was -# retired here, so false is the behaviour every commit has been held to. +# verification policy is never consulted and a path policy's own proof routes +# are the whole requirement. Proofs listed on the default count for nothing, +# though authors kept adding them there as if they did; nearly all were +# already on a path policy. allow_same_subsystem_tests would widen a policy to +# every test the subsystem owns (any internal/ai test for ai-runtime's +# mutation-registry policy), and its reach would grow with ownership rather +# than with the policy. The commit guards ignored the flag from the v6 import +# until it was retired here, so false is the behaviour every commit has been +# held to. SAME_SUBSYSTEM_TESTS_RETIRED = ( "it would accept any test the subsystem owns as proof for this policy; " "list the accepted proofs in test_prefixes or exact_files instead" ) +DEFAULT_PROOFS_RETIRED = ( + "explicit path-policy coverage never consults the subsystem default, so " + "proofs listed here count for nothing; list them on the path policy whose " + "runtime files they prove" +) def load_registry_payload(*, staged: bool = False) -> dict[str, Any]: @@ -363,47 +371,14 @@ def audit_registry_payload( elif verification.get("require_explicit_path_policy_coverage") is not True: errors.append(f"{context}.verification.require_explicit_path_policy_coverage must be true") - test_prefixes = verification.get("test_prefixes") - if not isinstance(test_prefixes, list): - errors.append(f"{context}.verification.test_prefixes must be a list") - test_prefixes = [] - else: - if len(test_prefixes) != len(set(test_prefixes)): - errors.append(f"{context}.verification.test_prefixes must not contain duplicates") - if test_prefixes != sorted_casefold(test_prefixes): - errors.append(f"{context}.verification.test_prefixes must be sorted lexicographically") - for prefix_index, prefix in enumerate(test_prefixes): - if not isinstance(prefix, str) or not prefix.strip(): - errors.append(f"{context}.verification.test_prefixes[{prefix_index}] must be a non-empty string") - continue - validate_prefix( - prefix, - context=f"{context}.verification.test_prefixes[{prefix_index}]", - errors=errors, - tracked_files=tracked_files, - **path_validation_scope, - ) - - exact_files = verification.get("exact_files") - if not isinstance(exact_files, list): - errors.append(f"{context}.verification.exact_files must be a list") - exact_files = [] - else: - if len(exact_files) != len(set(exact_files)): - errors.append(f"{context}.verification.exact_files must not contain duplicates") - if exact_files != sorted_casefold(exact_files): - errors.append(f"{context}.verification.exact_files must be sorted lexicographically") - for file_index, path in enumerate(exact_files): - if not isinstance(path, str) or not path.strip(): - errors.append(f"{context}.verification.exact_files[{file_index}] must be a non-empty string") - continue - validate_path_reference( - path, - context=f"{context}.verification.exact_files[{file_index}]", - errors=errors, - tracked_files=tracked_files, - **path_validation_scope, - ) + for field in ("test_prefixes", "exact_files"): + default_proofs = verification.get(field) + if not isinstance(default_proofs, list): + errors.append(f"{context}.verification.{field} must be a list") + elif default_proofs: + errors.append( + f"{context}.verification.{field} must be empty: " + DEFAULT_PROOFS_RETIRED + ) path_policies = verification.get("path_policies") if not isinstance(path_policies, list): diff --git a/scripts/release_control/registry_audit_test.py b/scripts/release_control/registry_audit_test.py index 619adc5178..ad183202bd 100644 --- a/scripts/release_control/registry_audit_test.py +++ b/scripts/release_control/registry_audit_test.py @@ -573,7 +573,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/monitoring/canonical_guardrails_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -617,9 +617,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": [ - "pulse-mobile:src/relay/__tests__/client.test.ts", - ], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -663,7 +661,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["pulse-mobile:src/relay/__tests__/client.test.ts"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -745,7 +743,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["pkg/licensing/cloud_paid_guardrails_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -788,7 +786,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/api/contract_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": False, "path_policies": [ { @@ -835,7 +833,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": True, "test_prefixes": [], - "exact_files": ["internal/monitoring/canonical_guardrails_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -872,6 +870,57 @@ class RegistryAuditTest(unittest.TestCase): ) self.assertIn("test_prefixes or exact_files", same_subsystem_errors[0]) + def test_audit_registry_payload_rejects_default_verification_proofs(self) -> None: + # The default policy is never consulted under explicit path-policy + # coverage, so a proof listed there would look accepted and count for + # nothing. + payload = { + "version": 13, + "shared_ownerships": [], + "subsystems": [ + { + "id": "monitoring", + "lane": "L6", + "contract": "docs/release-control/v6/internal/subsystems/monitoring.md", + "owned_prefixes": ["internal/monitoring/"], + "owned_files": [], + "verification": { + "allow_same_subsystem_tests": False, + "test_prefixes": ["internal/monitoring/"], + "exact_files": ["internal/monitoring/canonical_guardrails_test.go"], + "require_explicit_path_policy_coverage": True, + "path_policies": [ + { + "id": "monitoring-runtime", + "label": "monitoring runtime proof", + "match_prefixes": ["internal/monitoring/"], + "match_files": [], + "allow_same_subsystem_tests": False, + "test_prefixes": [], + "exact_files": ["internal/monitoring/canonical_guardrails_test.go"], + } + ], + }, + } + ], + } + tracked_files = { + "docs/release-control/v6/internal/subsystems/monitoring.md", + "internal/monitoring/monitor.go", + "internal/monitoring/canonical_guardrails_test.go", + } + + report = audit_registry_payload(payload, tracked_files=tracked_files, status_lane_ids={"L6"}) + + self.assertEqual( + [error.split(":", 1)[0] for error in report["errors"]], + [ + "subsystems[0].verification.test_prefixes must be empty", + "subsystems[0].verification.exact_files must be empty", + ], + ) + self.assertIn("list them on the path policy", report["errors"][0]) + def test_audit_registry_payload_rejects_uncanonical_ordering(self) -> None: payload = { "version": 13, @@ -885,11 +934,8 @@ class RegistryAuditTest(unittest.TestCase): "owned_files": ["internal/monitoring/b.go", "internal/monitoring/a.go"], "verification": { "allow_same_subsystem_tests": False, - "test_prefixes": ["internal/monitoring/tests/", "frontend/tests/"], - "exact_files": [ - "internal/monitoring/z_test.go", - "internal/monitoring/a_test.go", - ], + "test_prefixes": [], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -916,7 +962,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/alerts/guardrails_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -953,8 +999,6 @@ class RegistryAuditTest(unittest.TestCase): self.assertIn("registry.json subsystems must be sorted by subsystem id", joined) self.assertIn("subsystems[0].owned_prefixes must be sorted lexicographically", joined) self.assertIn("subsystems[0].owned_files must be sorted lexicographically", joined) - self.assertIn("subsystems[0].verification.test_prefixes must be sorted lexicographically", joined) - self.assertIn("subsystems[0].verification.exact_files must be sorted lexicographically", joined) self.assertIn( "subsystems[0].verification.path_policies[0].match_prefixes must be sorted lexicographically", joined, @@ -986,7 +1030,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/monitoring/guardrails_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -1039,7 +1083,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/api/contract_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -1063,7 +1107,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/unifiedresources/code_standards_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -1120,7 +1164,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/api/contract_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ { @@ -1144,7 +1188,7 @@ class RegistryAuditTest(unittest.TestCase): "verification": { "allow_same_subsystem_tests": False, "test_prefixes": [], - "exact_files": ["internal/unifiedresources/code_standards_test.go"], + "exact_files": [], "require_explicit_path_policy_coverage": True, "path_policies": [ {