diff --git a/dag/test/claim/codex_supervised_turn_wet_witness_test.dag b/dag/test/claim/codex_supervised_turn_wet_witness_test.dag index a1cfd0965a9..131d0d56b4b 100644 --- a/dag/test/claim/codex_supervised_turn_wet_witness_test.dag +++ b/dag/test/claim/codex_supervised_turn_wet_witness_test.dag @@ -125,7 +125,7 @@ fn wet_supervised_turn() -> WorkerTurn { } } -fn wet_committed_admitted_source_lock_admits() -> Bool { +test fn wet_committed_admitted_source_lock_admits() -> Bool { match admit_codex_package_lock_text(text: committed_codex_lock_text()) { CodexPackageLockAdmitted { graph: _, nodes, registry_artifacts } => count(nodes) > 0 && count(registry_artifacts) > 0 @@ -133,12 +133,12 @@ fn wet_committed_admitted_source_lock_admits() -> Bool { } } -fn wet_committed_admitted_source_construct_only() -> Bool { +test fn wet_committed_admitted_source_construct_only() -> Bool { let source = committed_admitted_codex_runtime_source() (source.lock_bytes != "") && (source.manifest_bytes != "") } -fn wet_select_codex_exact_target_closure_only() -> Bool { +test fn wet_select_codex_exact_target_closure_only() -> Bool { match admit_codex_package_lock_text(text: committed_codex_lock_text()) { CodexPackageLockAdmitted { graph, nodes: _, registry_artifacts: _ } => match observe_codex_npm_runtime_target() { @@ -161,7 +161,7 @@ fn wet_select_codex_exact_target_closure_only() -> Bool { } } -fn wet_acquire_wrapper_artifact_only() -> Bool { +test fn wet_acquire_wrapper_artifact_only() -> Bool { match prepare_codex_runtime_closure( source: committed_admitted_codex_runtime_source(), ) { @@ -199,7 +199,7 @@ fn wet_acquire_wrapper_artifact_only() -> Bool { } } -fn wet_acquire_platform_artifact_only() -> Bool { +test fn wet_acquire_platform_artifact_only() -> Bool { match prepare_codex_runtime_closure( source: committed_admitted_codex_runtime_source(), ) { @@ -237,7 +237,7 @@ fn wet_acquire_platform_artifact_only() -> Bool { } } -fn wet_codex_runtime_prepare_closure_only() -> Bool { +test fn wet_codex_runtime_prepare_closure_only() -> Bool { match prepare_codex_runtime_closure( source: committed_admitted_codex_runtime_source(), ) { @@ -255,98 +255,98 @@ fn wet_codex_runtime_prepare_closure_only() -> Bool { } } -fn wet_materialize_through_prepare_only() -> Bool { +test fn wet_materialize_through_prepare_only() -> Bool { materialize_codex_runtime_bundle_through_prepare( source: committed_admitted_codex_runtime_source(), ) } -fn wet_acquire_selected_pair_only() -> Bool { +test fn wet_acquire_selected_pair_only() -> Bool { materialize_codex_runtime_bundle_through_pair_acquire( source: committed_admitted_codex_runtime_source(), ) } -fn wet_materialize_npm_ci_offline_only() -> Bool { +test fn wet_materialize_npm_ci_offline_only() -> Bool { materialize_codex_runtime_bundle_through_npm_ci_offline( source: committed_admitted_codex_runtime_source(), ) } -fn wet_materialize_finish_after_install_only() -> Bool { +test fn wet_materialize_finish_after_install_only() -> Bool { materialize_codex_runtime_bundle_finish_after_install( source: committed_admitted_codex_runtime_source(), release_parent: wet_materialize_bisect_release_parent, ) } -fn wet_finish_observe_set_identity_only() -> Bool { +test fn wet_finish_observe_set_identity_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_set_identity_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_manifest_digest_only() -> Bool { +test fn wet_finish_observe_manifest_digest_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_manifest_digest_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_lock_digest_only() -> Bool { +test fn wet_finish_observe_lock_digest_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_lock_digest_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_native_digest_only() -> Bool { +test fn wet_finish_observe_native_digest_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_native_digest_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_toolchain_only() -> Bool { +test fn wet_finish_observe_toolchain_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_toolchain_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_protocol_schema_only() -> Bool { +test fn wet_finish_observe_protocol_schema_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_protocol_schema_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_parse_largest_protocol_schema_only() -> Bool { +test fn wet_finish_parse_largest_protocol_schema_only() -> Bool { materialize_codex_runtime_finish_bisect_parse_largest_protocol_schema_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_parse_canonicalize_largest_protocol_schema_only() -> Bool { +test fn wet_finish_parse_canonicalize_largest_protocol_schema_only() -> Bool { materialize_codex_runtime_finish_bisect_parse_canonicalize_largest_protocol_schema_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_package_tree_only() -> Bool { +test fn wet_finish_observe_package_tree_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_package_tree_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_receipt_identity_only() -> Bool { +test fn wet_finish_observe_receipt_identity_only() -> Bool { materialize_codex_runtime_finish_bisect_observe_receipt_identity_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_observe_package_tree_tiny_fixture() -> Bool { +test fn wet_finish_observe_package_tree_tiny_fixture() -> Bool { finish_bisect_observe_package_materialized_tree_tiny_fixture() } data wet_materialize_bisect_release_parent: FilePath = "/tmp/gunbc-wet-materialize-bisect-release" as FilePath -fn wet_materialize_codex_runtime_bundle_only() -> Bool { +test fn wet_materialize_codex_runtime_bundle_only() -> Bool { match materialize_codex_runtime_bundle( source: committed_admitted_codex_runtime_source(), release_parent: wet_materialize_bisect_release_parent, @@ -357,7 +357,7 @@ fn wet_materialize_codex_runtime_bundle_only() -> Bool { } } -fn supervised_turn_materialized_bundle_writes_terminal_receipt() -> Bool { +test fn supervised_turn_materialized_bundle_writes_terminal_receipt() -> Bool { let release_tmp = shell.Mktemp.Dir() let evidence = shell.Mktemp.Dir() let cwd = shell.Mktemp.Dir() diff --git a/dag/test/claim/emit_summary_map_consumer_partition_test.dag b/dag/test/claim/emit_summary_map_consumer_partition_test.dag index 89807da7d60..b43efa7f9b2 100644 --- a/dag/test/claim/emit_summary_map_consumer_partition_test.dag +++ b/dag/test/claim/emit_summary_map_consumer_partition_test.dag @@ -39,7 +39,7 @@ import gunbc.emit_summary_map_consumer_partition { // THE ASK COLUMN IS A PARTITION, NOT A SET OF TAGS. Every row sits in exactly one of the four ask // arms, so the four counts must sum to the member count. RED case: add a fifth ask arm and file a // row in it without extending the histogram, and this sum breaks. -fn ask_column_partitions_every_member() -> Bool { +test fn ask_column_partitions_every_member() -> Bool { partition_holds_node_count() + partition_spelling_only_count() + partition_composite_count() + partition_scan_count() == partition_member_count() } @@ -49,7 +49,7 @@ fn ask_column_partitions_every_member() -> Bool { // the ask alone would have been sufficient and the second column would be ceremony. RED case: file // the roster with the use column collapsed so that holding a node implies terminal use -- this goes // red, which is exactly the finding it guards. -fn holding_a_node_does_not_imply_a_terminal_use() -> Bool { +test fn holding_a_node_does_not_imply_a_terminal_use() -> Bool { (partition_holds_node_but_rekeys() |> count) > 0 } @@ -58,7 +58,7 @@ fn holding_a_node_does_not_imply_a_terminal_use() -> Bool { // spelling leaving the site. This is the number the sizing rests on, so it is carried by an // executing assertion and not by prose. RED case: any row filed with NodeHeldAtAsk and // TerminalAtSite -- at which point the sizing changed and this witness says so. -fn rekey_alone_repairs_nothing_on_this_roster() -> Bool { +test fn rekey_alone_repairs_nothing_on_this_roster() -> Bool { (partition_repaired_by_rekey_alone() |> count) == 0 } @@ -66,7 +66,7 @@ fn rekey_alone_repairs_nothing_on_this_roster() -> Bool { // ROSTER. Otherwise a row could file "the identity is gone" without saying where it went, which is // the claim a reader most needs to check and the one an author is most tempted to assume. RED case: // file a spelling-only row naming a fold absent from emit_summary_map_severance_points. -fn every_severance_fold_named_is_rostered() -> Bool { +test fn every_severance_fold_named_is_rostered() -> Bool { emit_summary_map_consumers |> all(c => if consumer_ask_is_spelling_only(c: c) { consumer_severance_is_rostered(c: c) @@ -77,19 +77,19 @@ fn every_severance_fold_named_is_rostered() -> Bool { // EVERY MEMBER READS THE MAP AT LEAST ONCE. lookup_expression_count is the only field saying how // much of the map each row actually decides from; a zero would admit a row contributing nothing a // reader could go and look at. RED case: file a row with a count of zero. -fn every_member_reads_the_map() -> Bool { +test fn every_member_reads_the_map() -> Bool { emit_summary_map_consumers |> all(c => c.lookup_expression_count > 0) } // THE LOOKUP TOTAL IS AT LEAST THE MEMBER COUNT, given the assertion above. This is the arithmetic // tie between the two derived numbers a reader compares; it goes red if either fold is rewritten to // count something else. -fn lookup_total_covers_every_member() -> Bool { +test fn lookup_total_covers_every_member() -> Bool { partition_lookup_expression_total() >= partition_member_count() } // EVERY COLUMN COUNT LIES INSIDE THE ROSTER IT IS DERIVED FROM. -fn derived_counts_lie_within_the_roster() -> Bool { +test fn derived_counts_lie_within_the_roster() -> Bool { partition_terminal_use_count() <= partition_member_count() && partition_holds_node_count() <= partition_member_count() && partition_member_count() > 0 @@ -99,14 +99,14 @@ fn derived_counts_lie_within_the_roster() -> Bool { // corpus-wide bound. The two figures came from different walks over different populations, so this // ties them rather than restating one. RED case: file a closure row whose collision count exceeds // the corpus bound, which is what a mis-scoped closure walk would produce. -fn no_pool_collides_more_than_the_whole_tree_bound() -> Bool { +test fn no_pool_collides_more_than_the_whole_tree_bound() -> Bool { largest_measured_pool_collision_count() <= whole_tree_collision_upper_bound() } // THE CORPUS BOUND IS NOT CARRIED ALONE. A collision population reporting only the upper bound is // the shape the sequencing rule forbids -- it cannot size a refusal. RED case: delete the closure // rows and keep the corpus row. -fn the_collision_population_is_measured_at_pool_grain() -> Bool { +test fn the_collision_population_is_measured_at_pool_grain() -> Bool { measured_pool_row_count() > 0 } @@ -114,16 +114,16 @@ fn the_collision_population_is_measured_at_pool_grain() -> Bool { // If this set were empty the two-part test would be carrying no information here and the roster // would collapse back into "is the check well written". RED case: file every guard row as // preserving its trigger. -fn some_guard_is_correct_and_unable_to_fire() -> Bool { +test fn some_guard_is_correct_and_unable_to_fire() -> Bool { (guards_written_correctly_but_unable_to_fire() |> count) > 0 } // AND AT LEAST ONE GUARD MUST PRESERVE ITS TRIGGER, or the roster has no contrast row and the // column cannot be read as discriminating. RED case: drop build_qualified_item_registry. -fn some_guard_preserves_its_trigger() -> Bool { +test fn some_guard_preserves_its_trigger() -> Bool { (guards_preserving_their_trigger() |> count) > 0 } -fn every_guard_row_is_counted() -> Bool { +test fn every_guard_row_is_counted() -> Bool { guard_row_count() == (emit_summary_map_guard_rows |> count) } diff --git a/dag/test/claim/emitter_bare_variant_expected_adoption_witness_test.dag b/dag/test/claim/emitter_bare_variant_expected_adoption_witness_test.dag index 0d79405585d..8cce91a2340 100644 --- a/dag/test/claim/emitter_bare_variant_expected_adoption_witness_test.dag +++ b/dag/test/claim/emitter_bare_variant_expected_adoption_witness_test.dag @@ -10,7 +10,7 @@ data emitter_bare_variant_expected_adoption_witness_note: String = "PERMANENT RE // unwrapped spelling `sign: Sign::Plus` must be absent. The must-contain row alone // would be satisfiable by an emitter that produced both forms; the must-not-contain row // alone passes vacuously if emission fails and yields no text at all. -fn w_optional_field_bare_variant_keeps_its_wrapper() -> Bool { +test fn w_optional_field_bare_variant_keeps_its_wrapper() -> Bool { compile_dag_rust_emit_check( "module optvar\n\nimport std.types { String }\n\ntype Sign\n = Plus\n | Minus\n\ntype Holder {\n sign: Sign?\n label: String\n}\n\nfn make(l: String) -> Holder {\n Holder { sign: Plus, label: l }\n}\n", "src/optvar.rs", @@ -22,7 +22,7 @@ fn w_optional_field_bare_variant_keeps_its_wrapper() -> Bool { // The same shape at a REQUIRED field, which must keep rendering the bare constructor. // This is the feature's positive control: it is what keeps the repair above from being // satisfiable by wrapping every variant, or by refusing every adoption. -fn w_required_field_bare_variant_is_not_wrapped() -> Bool { +test fn w_required_field_bare_variant_is_not_wrapped() -> Bool { compile_dag_rust_emit_check( "module reqvar\n\nimport std.types { String }\n\ntype Sign\n = Plus\n | Minus\n\ntype Holder {\n sign: Sign\n label: String\n}\n\nfn make(l: String) -> Holder {\n Holder { sign: Minus, label: l }\n}\n", "src/reqvar.rs", diff --git a/dag/test/claim/floor_discovery_hand_rust_equivalence_witness_test.dag b/dag/test/claim/floor_discovery_hand_rust_equivalence_witness_test.dag index 54c36d62966..5375a5e8851 100644 --- a/dag/test/claim/floor_discovery_hand_rust_equivalence_witness_test.dag +++ b/dag/test/claim/floor_discovery_hand_rust_equivalence_witness_test.dag @@ -18,6 +18,7 @@ import v2.compiler.discovery_enumeration { } import v2.workflow.floor_discovery { FloorDiscoveryRow, + BarrenTestSidecar, FloorDiscoverySidecarViolation, TestMarkedDecl, WireContractDecl, @@ -27,6 +28,7 @@ import v2.workflow.floor_discovery_producer { FloorDiscoveryAccepted, FloorDiscoveryRefused, discover_floor_corpus_rows_from_host_facts, + floor_discovery_barren_test_sidecar_refusal_for_content, floor_discovery_content_has_wire_contract_decl, floor_discovery_wire_contract_sidecar_refusal_for_content, floor_discovery_entry_live_tree_disposition_refusal_for_content, @@ -79,6 +81,8 @@ data fixture_witness_function: String = "floor_discovery_roster_fixture_witness" data fixture_test_fn_content: String = "test fn floor_discovery_roster_fixture_witness() -> Bool { true }\n" data fixture_test_data_content: String = "test data floor_discovery_data_fixture: Bool = true\n" data fixture_misplaced_entry: String = "src/v2/lens/example.dag" +data fixture_barren_test_entry: String = "dag/test/claim/floor_discovery_barren_fixture_test.dag" +data fixture_barren_test_content: String = "module test.claim.floor_discovery_barren_fixture_test\n\nfn floor_discovery_barren_helper() -> Bool { true }\n" data fixture_misplaced_wire_contract_entry: String = "dag/test/fixture/floor_discovery/misplaced_wire_contract.dag" data fixture_live_tree_entry: String = "dag/test/claim/floor_discovery_roster_fixture_test.dag" @@ -306,6 +310,59 @@ test fn floor_discovery_equivalence_misplaced_wire_contract_refuses_holds() -> B } } +// The `*_test.dag` suffix is one half of a two-sided rule: a `test`-marked decl may live +// ONLY in such a file (the misplaced-decl control above), and such a file must declare at +// least ONE. Without this second half a witness file enrolls nothing and the floor reports +// nothing missing -- discovery cannot distinguish "no witnesses here" from "no witnesses +// authored yet", so the file is silently uncovered. Nine such files stood in tree. +test fn floor_discovery_barren_test_sidecar_refuses_red_control() -> Bool { + match floor_discovery_barren_test_sidecar_refusal_for_content( + repo_path: fixture_barren_test_entry, + content: fixture_barren_test_content + ) { + Present { value: msg } => + string_contains(s: msg, pattern: "test fn") + && string_contains(s: msg, pattern: fixture_barren_test_entry) + Absent => false + } +} + +// The positive control: the SAME path with one authored test decl must be admitted, so the +// row above discriminates on the decl scan rather than on the filename. +test fn floor_discovery_populated_test_sidecar_admitted_holds() -> Bool { + match floor_discovery_barren_test_sidecar_refusal_for_content( + repo_path: fixture_barren_test_entry, + content: fixture_test_fn_content + ) { + Absent => true + Present { value: _ } => false + } +} + +// The other direction: an ordinary module declaring no test decls is not barren -- the rule +// is scoped to entries the sidecar suffix claims, never to the corpus at large. +test fn floor_discovery_non_test_entry_is_never_barren_holds() -> Bool { + match floor_discovery_barren_test_sidecar_refusal_for_content( + repo_path: fixture_misplaced_entry, + content: fixture_barren_test_content + ) { + Absent => true + Present { value: _ } => false + } +} + +test fn floor_discovery_barren_refusal_reason_carries_its_path_holds() -> Bool { + let msg = floor_discovery_sidecar_refusal_reason(violations: [ + FloorDiscoverySidecarViolation { + entry_path: fixture_barren_test_entry, + kind: BarrenTestSidecar, + required_suffix: floor_test_sidecar_suffix + } + ]) + string_contains(s: msg, pattern: fixture_barren_test_entry) + && string_contains(s: msg, pattern: "at least one") +} + test fn floor_discovery_sidecar_combined_refusal_reports_both_holds() -> Bool { let msg = floor_discovery_sidecar_refusal_reason(violations: [ FloorDiscoverySidecarViolation { diff --git a/dag/test/claim/floor_expected_red_coherence_witness_test.dag b/dag/test/claim/floor_expected_red_coherence_witness_test.dag index 535bc53acf9..52474554750 100644 --- a/dag/test/claim/floor_expected_red_coherence_witness_test.dag +++ b/dag/test/claim/floor_expected_red_coherence_witness_test.dag @@ -106,7 +106,7 @@ test fn w_severed_fixture_refusal_message_names_the_derivation_not_an_exclusion( // // This file's fixture witnesses are the complete, permanent proof of the mechanism // (see v2.workflow.floor_expected_red_coherence's floor_expected_red_chunk_coherence_check_note). -// floor_expected_red.dag's own 20 chunks against its own evaluated roster is a +// floor_expected_red.dag's own 21 chunks against its own evaluated roster is a // separate, pre-existing, unowned gap this file does not close -- see that module's // live_floor_expected_red_coherence_join_gap_note for the measured cost and natural // home of that still-open work. diff --git a/dag/test/claim/fn_equality_bound_witness_test.dag b/dag/test/claim/fn_equality_bound_witness_test.dag index f9730a39940..87aba4d1054 100644 --- a/dag/test/claim/fn_equality_bound_witness_test.dag +++ b/dag/test/claim/fn_equality_bound_witness_test.dag @@ -6,7 +6,7 @@ data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly data fn_equality_bound_witness_note: String = "Executing floor witness for the FN-level PartialEq bound trigger (v1.compiler.emit_rust v1_fn_body_equality_bound_param_names, deciding via v1.compiler.trait_bound_witness v1_equality_bound_param_name). The emitter derives Clone bounds on generic fn params ~30-48 references deep but derived NOTHING for equality, so a generic fn comparing two values of its own type param emitted bare and rustc refused with E0369 'binary operation == cannot be applied to type K'. GROUNDING FOR THE EXPECTED SPELLING, so it is not a measurement copied from this tree: quick-lynx-620 measured the requirement against rustc on the real emission -- hand-adding the bound to the emitted mirror and rebuilding the seed gave zero errors, and the required rendering is `K: Clone + PartialEq`, the equality bound COMPOSING with the separately-derived Clone bound on the same parameter rather than replacing it. THE DISCRIMINATOR IS TYPE RESOLUTION, NOT THE == SPELLING, and the two rows below exist to prove the trigger cannot be satisfied by matching on the operator. earning_comparison_bounds_its_generic_param carries BOTH comparisons in one body, exactly the shape of the real specimen: a concrete closed-enum comparison that must earn nothing, and a comparison of two K values that must earn the bound -- rustc emits exactly ONE E0369 on that real shape, at the second comparison, so the first provably compiles unbounded today. concrete_only_comparison_leaves_generic_param_bare is the sharper negative: a fn that HAS a generic param and HAS a comparison, where the comparison involves only concrete types. A predicate keyed on the presence of == bounds K there and breaks every caller instantiating K with a non-PartialEq type; the type-resolving predicate must leave it bare. That row is what makes the pair discriminating rather than two positives, and it is why the refusals below assert the bounded spelling is ABSENT rather than merely asserting some other spelling is present. Over-approximation is not free here: adding a bound TIGHTENS the emitted signature, so a spurious bound is a real break, while a missed bound only leaves the pre-existing E0369 in place." -fn earning_comparison_bounds_its_generic_param() -> Bool { +test fn earning_comparison_bounds_its_generic_param() -> Bool { compile_dag_rust_emit_check( "module fn_equality_witness.earning\n\ntype ShapeTag = ShapeAlpha | ShapeBeta\n\ntype CapRow {\n shape: ShapeTag\n keys: List\n}\n\nfn cap_row_has(row: CapRow, shape: ShapeTag, key: K) -> Bool {\n row.shape == shape && (row.keys |> any(k => k == key))\n}\n", "src/fn_equality_witness_earning.rs", @@ -15,7 +15,7 @@ fn earning_comparison_bounds_its_generic_param() -> Bool { ) } -fn concrete_only_comparison_leaves_generic_param_bare() -> Bool { +test fn concrete_only_comparison_leaves_generic_param_bare() -> Bool { compile_dag_rust_emit_check( "module fn_equality_witness.concrete\n\ntype ShapeTag = ShapeAlpha | ShapeBeta\n\ntype CapRow {\n shape: ShapeTag\n keys: List\n}\n\nfn cap_row_shape_is(row: CapRow, shape: ShapeTag) -> Bool {\n row.shape == shape\n}\n", "src/fn_equality_witness_concrete.rs", @@ -26,7 +26,7 @@ fn concrete_only_comparison_leaves_generic_param_bare() -> Bool { data fn_equality_forwarding_note: String = "Executing floor witness for the CALL-FORWARDING half of the same trigger (v1.compiler.emit_rust v1_call_forwarding_equality_bound_param_names). The seed synthesized the bound only on the fn whose OWN body compares, which is a program that does not typecheck one hop up: a caller instantiating that fn's K with its own generic param is obliged by rustc to prove a bound it never states, and rustc refuses with E0277. MEASURED, not assumed: the real specimen is gunbc#8605's std.trait_derive_shape, where repr_grounding_derive_shape_has_trait compares k == capability_key and earns the bound while repr_grounding_derive_completeness_predicate forwards its own K into that parameter; the reduction below was emitted through the seed before the fix and produced `pub fn cap_table_complete` -- the Clone bound present, the PartialEq bound absent -- which is why the refusal asserts that exact spelling is gone rather than merely asserting the fixed one is present. THE FORWARDED CALL IS NOT AT THE BODY'S ROOT: it sits inside a lambda inside a pipelined all(), the shape the pre-existing Clone forwarding structurally cannot reach, so a row whose caller body IS the call would pass without exercising the recursive walk this row exists to hold. forwarding_into_unbounded_callee_leaves_generic_param_bare is the discriminator: same wrapper shape, same generic param, same pipeline, but the callee compares only concrete types and so earns nothing -- a derivation keyed on 'my callee is generic' rather than on the callee's own resolved-type verdict bounds K there and breaks every caller instantiating K with a non-PartialEq type." -fn forwarding_caller_inherits_callee_equality_bound() -> Bool { +test fn forwarding_caller_inherits_callee_equality_bound() -> Bool { compile_dag_rust_emit_check( "module fn_equality_witness.forwarding\n\ntype ShapeTag = ShapeAlpha | ShapeBeta\n\ntype CapRow {\n shape: ShapeTag\n keys: List\n}\n\nfn cap_row_has(row: CapRow, shape: ShapeTag, key: K) -> Bool {\n row.shape == shape && (row.keys |> any(k => k == key))\n}\n\nfn cap_table_complete(row: CapRow, shape: ShapeTag, required: List) -> Bool {\n required |> all(k => cap_row_has(row: row, shape: shape, key: k))\n}\n", "src/fn_equality_witness_forwarding.rs", @@ -35,7 +35,7 @@ fn forwarding_caller_inherits_callee_equality_bound() -> Bool { ) } -fn forwarding_into_unbounded_callee_leaves_generic_param_bare() -> Bool { +test fn forwarding_into_unbounded_callee_leaves_generic_param_bare() -> Bool { compile_dag_rust_emit_check( "module fn_equality_witness.forwarding_bare\n\ntype ShapeTag = ShapeAlpha | ShapeBeta\n\ntype CapRow {\n shape: ShapeTag\n keys: List\n}\n\nfn cap_row_shape_is(row: CapRow, shape: ShapeTag) -> Bool {\n row.shape == shape\n}\n\nfn cap_table_shape_is(row: CapRow, shapes: List) -> Bool {\n shapes |> all(s => cap_row_shape_is(row: row, shape: s))\n}\n", "src/fn_equality_witness_forwarding_bare.rs", diff --git a/dag/test/claim/json_protocol_schema_memory_split_wet_witness_test.dag b/dag/test/claim/json_protocol_schema_memory_split_wet_witness_test.dag index 1e019a1ba1a..5934d18e706 100644 --- a/dag/test/claim/json_protocol_schema_memory_split_wet_witness_test.dag +++ b/dag/test/claim/json_protocol_schema_memory_split_wet_witness_test.dag @@ -26,13 +26,13 @@ fn committed_admitted_codex_runtime_source() -> AdmittedCodexRuntimeSource { } } -fn wet_finish_parse_largest_protocol_schema_only() -> Bool { +test fn wet_finish_parse_largest_protocol_schema_only() -> Bool { materialize_codex_runtime_finish_bisect_parse_largest_protocol_schema_only( source: committed_admitted_codex_runtime_source(), ) } -fn wet_finish_parse_canonicalize_largest_protocol_schema_only() -> Bool { +test fn wet_finish_parse_canonicalize_largest_protocol_schema_only() -> Bool { materialize_codex_runtime_finish_bisect_parse_canonicalize_largest_protocol_schema_only( source: committed_admitted_codex_runtime_source(), ) diff --git a/dag/test/claim/realization_schedule_witness_test.dag b/dag/test/claim/realization_schedule_witness_test.dag deleted file mode 100644 index 078e3ca5fbe..00000000000 --- a/dag/test/claim/realization_schedule_witness_test.dag +++ /dev/null @@ -1,50 +0,0 @@ -module test.claim.realization_schedule_witness - -import std.content_hash { ContentHash, content_hash_of_value } - -data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree - -data live_tree_disposition_correction_note: String = "Corrected 2026-07-29: the SubstrateInputsOnly stamp was FALSE and lying_substrate_inputs_only_stamp_census caught it — this file's import closure reaches the live-read carrier home v2.compiler.self_host through the v2.workflow.ci_floor_plan import. That import is intentional and stays: the witness compares against cheap_floor_gate_step_labels at its single authority rather than copying the label list (DESIGN §3), so the reach is real even though the rows themselves build synthetic schedules. The census answers reach structurally, which is its precision frontier, not an absorption; the fail-closed reading is ReadsLiveTree (never-skip), since a predict-skipped live-tree row is a selection fail-open." - -data synthetic_target: ContentHash = content_hash_of_value(value: "realization-schedule-witness-v1") -data compile_gate_fn: String = "dag_compile_clean_gate_passes" -data gate_entry: String = "dag/tools/floor_effect_gate_witness.dag" - -fn synthetic_correct_schedule() -> List> { - [ - [ - RunnableSingleClaim { entry: gate_entry, function: "cheap_claim_pool_gate_passes", profile: runnable_resource_profile_negligible() }, - RunnableSingleClaim { entry: gate_entry, function: "extdeps_external_authority_gate_passes", profile: runnable_resource_profile_negligible() }, - RunnableSingleClaim { entry: gate_entry, function: "generated_artifact_drift_gate_passes", profile: runnable_resource_profile_negligible() } - ], - [RunnableSingleClaim { entry: gate_entry, function: compile_gate_fn, profile: runnable_resource_profile_negligible() }], - [ - RunnableDiscoveryBatch { - source_roots: ["dag"] - scan_dirs: [] - explicit_entries: [] - profile: runnable_resource_profile_negligible() - exclude_substrings: [] - discovery_scope_dirs: [] - }, - RunnableSingleClaim { entry: gate_entry, function: "emit_host_gate_passes", profile: runnable_resource_profile_negligible() } - ] - ] -} - -fn synthetic_correct_plan() -> RealizationPlan { - RealizationPlan { - target: synthetic_target - objective: RealizationObjective { goals: [] } - schedule: synthetic_correct_schedule() - total: cost_account_predicted_zero() - } -} - -fn perturbed_schedule_wrong_order(correct: List>) -> List> { - [ - correct.skip(n: 1).first(), - correct.first() - ] -} - diff --git a/src/v2/lens/no_dual_representation_test.dag b/src/v2/lens/no_dual_representation_test.dag index 628fc93f5df..2b5eacbd37a 100644 --- a/src/v2/lens/no_dual_representation_test.dag +++ b/src/v2/lens/no_dual_representation_test.dag @@ -51,14 +51,14 @@ fn no_dual_representation_body_partial_frontier_declared() -> Bool { no_dual_representation_body_partial_frontier_note != "" } -fn no_dual_representation_test_coverage_honesty_holds() -> Bool { +test fn no_dual_representation_test_coverage_honesty_holds() -> Bool { dual_rep_coverage_honesty_holds( eq_site_count: no_dual_representation_test_live_eq_site_count(), frontier_declared: no_dual_representation_body_partial_frontier_declared() ) } -fn no_dual_representation_test_clean_holds() -> Bool { +test fn no_dual_representation_test_clean_holds() -> Bool { dual_rep_clean_holds_for_scans(scans: dual_rep_live_module_scans()) } diff --git a/src/v2/test/claim/generated/language_behavior_equivalence_test.dag b/src/v2/test/claim/generated/language_behavior_equivalence_test.dag index 03967c0ac3a..a8c7899b4e4 100644 --- a/src/v2/test/claim/generated/language_behavior_equivalence_test.dag +++ b/src/v2/test/claim/generated/language_behavior_equivalence_test.dag @@ -293,7 +293,7 @@ fn lbe_run_test_claim_assert_from_mock( ) } -data witness_lbe_conj_snapshot_pass: Bool = match lbe_run_test_claim_assert_from_emit( +test data witness_lbe_conj_snapshot_pass: Bool = match lbe_run_test_claim_assert_from_emit( anchor: ManualLbeConjDagSurface, label: lbe_label_conj_dag_surface, mock: lbe_io_mock_conj_dag_surface() @@ -305,7 +305,7 @@ data witness_lbe_conj_snapshot_pass: Bool = match lbe_run_test_claim_assert_from Deferred { actual: _, diagnostic: _ } => false } -data witness_lbe_disj_snapshot_pass: Bool = match lbe_run_test_claim_assert_from_emit( +test data witness_lbe_disj_snapshot_pass: Bool = match lbe_run_test_claim_assert_from_emit( anchor: ManualLbeDisjDagSurface, label: lbe_label_disj_dag_surface, mock: lbe_io_mock_disj_dag_surface() @@ -317,7 +317,7 @@ data witness_lbe_disj_snapshot_pass: Bool = match lbe_run_test_claim_assert_from Deferred { actual: _, diagnostic: _ } => false } -data witness_lbe_transform_snapshot_pass: Bool = match lbe_run_test_claim_assert_from_emit( +test data witness_lbe_transform_snapshot_pass: Bool = match lbe_run_test_claim_assert_from_emit( anchor: ManualLbeTransformDagSurface, label: lbe_label_transform_dag_surface, mock: lbe_io_mock_transform_dag_surface() @@ -355,6 +355,6 @@ fn lbe_witness_dag_surface_language_identity() -> Bool { lbe_io_mock_conj_dag_surface().snapshot.language == ^dag_language_model_surface_id } -data witness_testgen_schedules_three_lbe_generators: Bool = lbe_witness_testgen_schedules_three_generators() +test data witness_testgen_schedules_three_lbe_generators: Bool = lbe_witness_testgen_schedules_three_generators() -data witness_dag_surface_language_identity: Bool = lbe_witness_dag_surface_language_identity() +test data witness_dag_surface_language_identity: Bool = lbe_witness_dag_surface_language_identity() diff --git a/src/v2/test/claim/manual/bootstrap_footprint_anchor_test.dag b/src/v2/test/claim/manual/bootstrap_footprint_anchor_test.dag index e9e87fff540..f499c26658e 100644 --- a/src/v2/test/claim/manual/bootstrap_footprint_anchor_test.dag +++ b/src/v2/test/claim/manual/bootstrap_footprint_anchor_test.dag @@ -59,7 +59,7 @@ fn bootstrap_footprint_anchor_bad_projection_inputs() -> BootstrapProjectionInpu // refuses at runtime: "atom_identity_hash requires exactly one string argument". // These rows re-promote when either the code-point encoding carries a string identity or // content_hash gains a non-symbol atom arm. -fn bootstrap_footprint_canonical_holds() -> Bool { +test fn bootstrap_footprint_canonical_holds() -> Bool { match bootstrap_footprint(inputs: bootstrap_projection_inputs) { Holds { value: fp } => fp.closure_hash == @@ -68,7 +68,7 @@ fn bootstrap_footprint_canonical_holds() -> Bool { } } -fn bootstrap_footprint_non_canonical_violates() -> Bool { +test fn bootstrap_footprint_non_canonical_violates() -> Bool { let bad_inputs = bootstrap_footprint_anchor_bad_projection_inputs() match bootstrap_footprint(inputs: bad_inputs) { Holds { value: _ } => false @@ -91,7 +91,7 @@ fn bootstrap_footprint_anchor_bad_content_hash_projection_inputs() -> BootstrapP } } -fn bootstrap_footprint_bad_content_hash_violates() -> Bool { +test fn bootstrap_footprint_bad_content_hash_violates() -> Bool { let bad_inputs = bootstrap_footprint_anchor_bad_content_hash_projection_inputs() match bootstrap_footprint(inputs: bad_inputs) { Holds { value: _ } => false @@ -134,7 +134,7 @@ fn bootstrap_footprint_anchor_bad_runtime_projection_inputs() -> BootstrapProjec } } -fn bootstrap_footprint_bad_runtime_same_identity_violates() -> Bool { +test fn bootstrap_footprint_bad_runtime_same_identity_violates() -> Bool { let bad_runtime = bootstrap_footprint_anchor_bad_runtime_model() let canonical_runtime = v2_evaluator_runtime() (bad_runtime.runtime_identity == canonical_runtime.runtime_identity) diff --git a/src/v2/test/claim/manual/nominal_distinctness_cross_call_test.dag b/src/v2/test/claim/manual/nominal_distinctness_cross_call_test.dag index cf65d191626..9dc317b7b06 100644 --- a/src/v2/test/claim/manual/nominal_distinctness_cross_call_test.dag +++ b/src/v2/test/claim/manual/nominal_distinctness_cross_call_test.dag @@ -68,7 +68,7 @@ data nominal_distinct_records_compile_receipt: Outcome> = anchor_ data nominal_distinct_brands_compile_receipt: Outcome> = anchor_nominal_distinct_brands_compile() data nominal_distinct_control_compile_receipt: Outcome> = anchor_nominal_distinct_control_compile() -fn nominal_distinct_control_compiles_ok() -> Bool { +test fn nominal_distinct_control_compiles_ok() -> Bool { match nominal_distinct_control_compile_receipt { Accepted { value: _, diagnostics: _ } => true Rejected { diagnostics: _ } => false diff --git a/src/v2/test/claim/realization_vocabulary_containment/clean_tree_test.dag b/src/v2/test/claim/realization_vocabulary_containment/clean_tree_test.dag deleted file mode 100644 index 7b857e7399b..00000000000 --- a/src/v2/test/claim/realization_vocabulary_containment/clean_tree_test.dag +++ /dev/null @@ -1,6 +0,0 @@ -module v2.test.realization_vocabulary_containment.clean_tree - - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data clean_tree_fast_lane_note: String = "Full-corpus live-tree containment receipt moved to long/realization_vocabulary_containment_witness_test.dag — layer_import_facts_live over realization_vocab_consumer_scan_roots exceeds the per-PR 5s fast-lane eval budget (gunbc_ci_fast_lane_rule_note; explicit enrollment deleted from commit_workflow 2026-07-18). Per-PR fast-lane coverage: lens_unit/discriminators_test.dag (synthetic predicate receipts), scanner/planted_leak_test.dag (fixture scan), roster_soundness_test.dag (stale-roster RED)." diff --git a/src/v2/test/claim/resolve/qualified_module_projection_g1b_witness_test.dag b/src/v2/test/claim/resolve/qualified_module_projection_g1b_witness_test.dag deleted file mode 100644 index c0f6f2ff193..00000000000 --- a/src/v2/test/claim/resolve/qualified_module_projection_g1b_witness_test.dag +++ /dev/null @@ -1,29 +0,0 @@ -module v2.test.resolve.qualified_module_projection_g1b_witness - -import v2.std.node { Atom, Node, SyntheticOccurrence, TypeNode } -import v2.std.verification { - CompilesClaim, - ManualAnchorAbsent, - TestClaim, - TestClassification, - Tier1, - Unit, - manual_claim_anchor -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data qmp_g1b_fixture_subject: Node = Node { - kind: TypeNode { connective: Atom { identity: ^qmp_g1b_fixture_subject } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data claim_qualified_module_projection_g1b_compiles: TestClaim = CompilesClaim { - label: "resolve/qualified_module_projection_g1b: import-less module compiles with qualified projection in fn/data/let annotations and match constructor patterns", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - input: qmp_g1b_fixture_subject, - expected_value: qmp_g1b_fixture_subject, - classification: TestClassification { tier: Tier1, layer: Unit } -} diff --git a/src/v2/test/claim/resolve/qualified_module_projection_stripped_witness_test.dag b/src/v2/test/claim/resolve/qualified_module_projection_stripped_witness_test.dag deleted file mode 100644 index 302420845f9..00000000000 --- a/src/v2/test/claim/resolve/qualified_module_projection_stripped_witness_test.dag +++ /dev/null @@ -1,31 +0,0 @@ -module v2.test.resolve.qualified_module_projection_stripped_witness - -import v2.std.node { Atom, Node, SyntheticOccurrence, TypeNode } -import v2.std.verification { - CompilesClaim, - ManualAnchorAbsent, - TestClaim, - TestClassification, - Tier1, - Unit, - manual_claim_anchor -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data g1_stripped_witness_note: String = "Enrollment witness for qualified_module_projection_stripped_fixture.dag — entry-scoped discovery must not re-resolve the import-less qualified type (provider is outside import closure); batch-1 compile-clean covers the fixture module." - -data qmp_stripped_fixture_subject: Node = Node { - kind: TypeNode { connective: Atom { identity: ^qmp_stripped_fixture_subject } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data claim_qualified_module_projection_stripped_compiles: TestClaim = CompilesClaim { - label: "resolve/qualified_module_projection_stripped: import-less module compiles with qualified type projection", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - input: qmp_stripped_fixture_subject, - expected_value: qmp_stripped_fixture_subject, - classification: TestClassification { tier: Tier1, layer: Unit } -} diff --git a/src/v2/workflow/floor_discovery.dag b/src/v2/workflow/floor_discovery.dag index 51f5f64d23a..c418f9bf9fb 100644 --- a/src/v2/workflow/floor_discovery.dag +++ b/src/v2/workflow/floor_discovery.dag @@ -276,6 +276,7 @@ type FloorDiscoveryRow { type FloorDiscoverySidecarKind = TestMarkedDecl | WireContractDecl + | BarrenTestSidecar type FloorDiscoverySidecarViolation { entry_path: String diff --git a/src/v2/workflow/floor_discovery_producer.dag b/src/v2/workflow/floor_discovery_producer.dag index b8a2866a563..55eda117e84 100644 --- a/src/v2/workflow/floor_discovery_producer.dag +++ b/src/v2/workflow/floor_discovery_producer.dag @@ -17,6 +17,7 @@ import v2.workflow.floor_discovery { FloorDiscoverySidecarViolation } import v2.workflow.floor_naming_hygiene { + floor_entry_is_barren_test_sidecar, floor_test_marked_decl_allowed_in_entry, floor_wire_contract_decl_allowed_in_entry, floor_test_sidecar_suffix, @@ -410,7 +411,14 @@ fn floor_discovery_apply_test_sidecar_rules( floor_discovery_record_disposition_refusal(state: state, reason: reason) EntryLiveTreeResolved { disposition: reads_live } => { let test_names = floor_discovery_scan_test_decl_names(content: content) - if floor_test_marked_decl_allowed_in_entry(entry_path: repo_path) { + if floor_entry_is_barren_test_sidecar(entry_path: repo_path, content: content) { + floor_discovery_collect_sidecar_violation( + state: state, + entry_path: repo_path, + kind: BarrenTestSidecar, + required_suffix: floor_test_sidecar_suffix + ) + } else if floor_test_marked_decl_allowed_in_entry(entry_path: repo_path) { fold( test_names, init: state, @@ -609,9 +617,33 @@ fn floor_discovery_paths_for_sidecar_kind( ) } +data floor_discovery_barren_test_sidecar_reason_prefix: String = "a `*_test.dag` entry must declare at least one `test fn`/`test data` decl; floor discovery enrolls nothing from: " + +fn floor_discovery_barren_test_sidecar_refusal_for_content( + repo_path: String, + content: String +) -> Optional { + if floor_entry_is_barren_test_sidecar(entry_path: repo_path, content: content) { + optional_present( + value: concat(floor_discovery_barren_test_sidecar_reason_prefix, repo_path) + ) + } else { + optional_absent() + } +} + fn floor_discovery_sidecar_refusal_reason( violations: List ) -> String { + let barren_paths = floor_discovery_paths_for_sidecar_kind( + violations: violations, + kind: BarrenTestSidecar + ) + let barren_clause = if barren_paths == "" { + "" + } else { + concat(floor_discovery_barren_test_sidecar_reason_prefix, barren_paths, "; ") + } let test_paths = floor_discovery_paths_for_sidecar_kind( violations: violations, kind: TestMarkedDecl @@ -620,8 +652,11 @@ fn floor_discovery_sidecar_refusal_reason( violations: violations, kind: WireContractDecl ) - if test_paths != "" && wire_paths != "" { + if test_paths == "" && wire_paths == "" { + barren_clause + } else if test_paths != "" && wire_paths != "" { concat( + barren_clause, "`test`-marked decls must live in `*_test.dag` files; found in: ", test_paths, "; wire-contract decls (`CoproductWireContract` and `VariantEncoding` data items) must live in `*_contracts.dag` files; found in: ", @@ -629,11 +664,13 @@ fn floor_discovery_sidecar_refusal_reason( ) } else if test_paths != "" { concat( + barren_clause, "`test`-marked decls must live in `*_test.dag` files; found in: ", test_paths ) } else { concat( + barren_clause, "wire-contract decls (`CoproductWireContract` and `VariantEncoding` data items) must live in `*_contracts.dag` files; found in: ", wire_paths ) diff --git a/src/v2/workflow/floor_expected_red.dag b/src/v2/workflow/floor_expected_red.dag index 02ecedb0d40..cb286ee707c 100644 --- a/src/v2/workflow/floor_expected_red.dag +++ b/src/v2/workflow/floor_expected_red.dag @@ -55,6 +55,11 @@ import v2.std.text { String } // roster is admissible because it is temporary, visible at identity grain, and self-emptying — // remove any of those three and it is the skip list it is carefully not. // +// POPULATION: 311 identities. The five added 2026-08-22 are the previously-INVISIBLE rows +// described at chunk_20 -- they enter this roster from marker-less files rather than from a +// regression, which is a route this roster had not carried before. The 306 below is the count +// before them and the derivation that produced it is unchanged. +// // POPULATION: 306 identities, after the declared rung drop below took 111 out by relocation // and run 32189201111 (PR #8460) observed 52 more PASSING (469 -> 361 -> 358 -> 306). Those 52 // reported STALE-QUARANTINE -- enrolled as expected-red and PASSED -- which is this roster's own @@ -424,8 +429,37 @@ fn floor_expected_red_chunk_19() -> List { Cons { head: "test.claim.direct_call_argument_type_witness_test.direct_call_arg_type_v2_module_red_refuses_blocking_type_mismatch", tail: Empty {} } } +// FIVE IDENTITIES ENROLLED 2026-08-22, and they arrive by a route this roster has not carried +// before: they were not failing rows that someone broke, they were rows the floor COULD NOT SEE. +// Both files declared their assertions as plain `fn`, so floor discovery -- which keys on the +// literal `test fn ` marker -- enrolled nothing from either. Marking them is what made these +// failures observable at all, and unmarking them again would be the same silence wearing a +// different justification, so they are enrolled here instead. +// +// The four bootstrap_footprint rows fail identically: `atom_identity_hash requires exactly one +// string argument`. The cause is stated by the file itself, which DEMOTED them on 2026-08-19 by +// removing their markers -- every bootstrap_footprint path hashes a closure embedding +// rust_target_model().bundle, whose semantic-decl bundles store char CODE POINTS in +// Atom.identity, and content_hash's atom fold routes that into an intrinsic that requires a +// string. That is a substrate gap, not a defect in these rows, and the file names its own +// repair trigger: the code-point encoding carries a string identity, or content_hash gains a +// non-symbol atom arm. +// +// nominal_distinct_control_compiles_ok returns false: the CONTROL fixture -- the one whose call +// site is type-correct -- does not compile through compile_ingest_staging today. gunbc#8505 held +// this class back from promotion for exactly this reason ("35 parse-reaching claims declared as +// residue"), so the red is a known frontier fact rather than news. +// +// WHAT IS HONEST TO SAY ABOUT THEM, since this roster's header asks: nobody is actively fixing +// these five. What the enrolment buys over the demotion it replaces is the stale-quarantine arm +// -- when the substrate arm lands, these rows PASS, and a passing enrolled row reds the build +// naming itself. The file's prose trigger could not do that; this roster does it mechanically. +fn floor_expected_red_chunk_20() -> List { + Cons { head: "v2.test.manual.bootstrap_footprint_anchor.bootstrap_footprint_bad_content_hash_violates", tail: Cons { head: "v2.test.manual.bootstrap_footprint_anchor.bootstrap_footprint_bad_runtime_same_identity_violates", tail: Cons { head: "v2.test.manual.bootstrap_footprint_anchor.bootstrap_footprint_canonical_holds", tail: Cons { head: "v2.test.manual.bootstrap_footprint_anchor.bootstrap_footprint_non_canonical_violates", tail: Cons { head: "v2.test.manual.nominal_distinctness_cross_call.nominal_distinct_control_compiles_ok", tail: Empty {} } } } } } +} + fn floor_expected_red_chunks() -> List> { - Cons { head: floor_expected_red_chunk_00(), tail: Cons { head: floor_expected_red_chunk_01(), tail: Cons { head: floor_expected_red_chunk_02(), tail: Cons { head: floor_expected_red_chunk_03(), tail: Cons { head: floor_expected_red_chunk_04(), tail: Cons { head: floor_expected_red_chunk_05(), tail: Cons { head: floor_expected_red_chunk_06(), tail: Cons { head: floor_expected_red_chunk_07(), tail: Cons { head: floor_expected_red_chunk_08(), tail: Cons { head: floor_expected_red_chunk_09(), tail: Cons { head: floor_expected_red_chunk_10(), tail: Cons { head: floor_expected_red_chunk_11(), tail: Cons { head: floor_expected_red_chunk_12(), tail: Cons { head: floor_expected_red_chunk_13(), tail: Cons { head: floor_expected_red_chunk_14(), tail: Cons { head: floor_expected_red_chunk_15(), tail: Cons { head: floor_expected_red_chunk_16(), tail: Cons { head: floor_expected_red_chunk_17(), tail: Cons { head: floor_expected_red_chunk_18(), tail: Cons { head: floor_expected_red_chunk_19(), tail: Empty {}}}}}}}}}}}}}}}}}}}}} + Cons { head: floor_expected_red_chunk_00(), tail: Cons { head: floor_expected_red_chunk_01(), tail: Cons { head: floor_expected_red_chunk_02(), tail: Cons { head: floor_expected_red_chunk_03(), tail: Cons { head: floor_expected_red_chunk_04(), tail: Cons { head: floor_expected_red_chunk_05(), tail: Cons { head: floor_expected_red_chunk_06(), tail: Cons { head: floor_expected_red_chunk_07(), tail: Cons { head: floor_expected_red_chunk_08(), tail: Cons { head: floor_expected_red_chunk_09(), tail: Cons { head: floor_expected_red_chunk_10(), tail: Cons { head: floor_expected_red_chunk_11(), tail: Cons { head: floor_expected_red_chunk_12(), tail: Cons { head: floor_expected_red_chunk_13(), tail: Cons { head: floor_expected_red_chunk_14(), tail: Cons { head: floor_expected_red_chunk_15(), tail: Cons { head: floor_expected_red_chunk_16(), tail: Cons { head: floor_expected_red_chunk_17(), tail: Cons { head: floor_expected_red_chunk_18(), tail: Cons { head: floor_expected_red_chunk_19(), tail: Cons { head: floor_expected_red_chunk_20(), tail: Empty {}}}}}}}}}}}}}}}}}}}}}} } fn floor_expected_red_roster() -> List { diff --git a/src/v2/workflow/floor_expected_red_coherence.dag b/src/v2/workflow/floor_expected_red_coherence.dag index a88866a87a6..9c61b017003 100644 --- a/src/v2/workflow/floor_expected_red_coherence.dag +++ b/src/v2/workflow/floor_expected_red_coherence.dag @@ -252,7 +252,7 @@ fn floor_expected_red_chunk_coherence_check( data floor_expected_red_chunk_coherence_check_note: String = "MECHANISM ON FIXTURES: floor_expected_red_chunk_coherence_check is proven by execution against planted rosters in dag/test/claim/floor_expected_red_coherence_witness_test.dag -- a severed-aggregator RED, its cause-naming RED siblings, and a linked-chunks-only positive control. That is the complete claim this module makes about the mechanism; it is not partial." // SEPARATE, PRE-EXISTING, UNOWNED OBLIGATION -- not debt this module introduces. -// Folding floor_expected_red.dag's own real 20 chunks through the same check is a +// Folding floor_expected_red.dag's own real 21 chunks through the same check is a // distinct, much larger claim: it requires a fresh // decl_facts(pool_roots: ["src/v2/workflow"]) parse (measured: ~56s process wall, // dominated by the parse itself, ~36x the 1552ms per-PR floor ceiling), so per @@ -269,4 +269,4 @@ data floor_expected_red_chunk_coherence_check_note: String = "MECHANISM ON FIXTU // has already done -- the #8470 shape one level up. Building that preparation-time // consumer is its own future work item with its own owner, not a continuation of // this one. -data live_floor_expected_red_coherence_join_gap_note: String = "PRE-EXISTING, UNOWNED GAP (not this module's debt): the live join of floor_expected_red.dag's own 20 chunks against its own evaluated roster is not a per-PR witness in floor_expected_red_coherence_witness_test.dag, and was not checkable by anything before this module existed either. This single gap has two faces, not two gaps: a checked chunk's identities may drift from the roster (the content face, this note's original subject), and a chunk may be missing from the caller's ChunkDeclRef roster entirely (the omission face, named on floor_expected_red_chunk_coherence_check's own SCOPE comment) -- closing either face requires the identical fresh decl_facts parse over floor_expected_red.dag's module, so one preparation-time consumer closes both. See floor_expected_red_chunk_coherence_check_note and the comment above it for why the mechanism itself is complete, and for the measured cost and natural home (a required-floor preparation-time consumer) of the still-open live-census gap." +data live_floor_expected_red_coherence_join_gap_note: String = "PRE-EXISTING, UNOWNED GAP (not this module's debt): the live join of floor_expected_red.dag's own 21 chunks against its own evaluated roster is not a per-PR witness in floor_expected_red_coherence_witness_test.dag, and was not checkable by anything before this module existed either. This single gap has two faces, not two gaps: a checked chunk's identities may drift from the roster (the content face, this note's original subject), and a chunk may be missing from the caller's ChunkDeclRef roster entirely (the omission face, named on floor_expected_red_chunk_coherence_check's own SCOPE comment) -- closing either face requires the identical fresh decl_facts parse over floor_expected_red.dag's module, so one preparation-time consumer closes both. See floor_expected_red_chunk_coherence_check_note and the comment above it for why the mechanism itself is complete, and for the measured cost and natural home (a required-floor preparation-time consumer) of the still-open live-census gap." diff --git a/src/v2/workflow/floor_naming_hygiene.dag b/src/v2/workflow/floor_naming_hygiene.dag index 8b7ff140e08..d1c908c48a3 100644 --- a/src/v2/workflow/floor_naming_hygiene.dag +++ b/src/v2/workflow/floor_naming_hygiene.dag @@ -135,4 +135,17 @@ fn floor_discovery_scan_test_decl_names(content: String) -> List { ) } +// The sidecar rule read in its second direction. `floor_test_marked_decl_allowed_in_entry` +// answers where a `test`-marked decl MAY live; this answers what a file claiming that place +// OWES. Without it a `*_test.dag` file that declares none enrolls zero rows and no consumer +// can tell that apart from a file whose rows were all excluded -- the floor reports nothing +// missing because nothing asked. +fn floor_entry_is_barren_test_sidecar(entry_path: String, content: String) -> Bool { + if floor_entry_requires_test_sidecar(entry_path: entry_path) { + length(xs: floor_discovery_scan_test_decl_names(content: content)) == 0 + } else { + false + } +} + data floor_naming_hygiene_note: String = "Single authority for floor witness sidecar placement + test-decl name scan predicates. Host discovery walks files and projects rows; these pure fns decide whether an entry placement is admissible and which decls a *_test.dag enrolls.\n\nCORRECTED WITH THE DELETION IT DESCRIBES (gunbc#8155): this note previously claimed two things that stopped being true in the same change that edited this file. It said the module lives here rather than in floor_discovery_producer so that \"orphan/filename hygiene resolve stays free of the Filesystem service closure\" -- there is no longer an orphan census OR a filename-hygiene resolve to keep free of anything, since the `__`-basename rule and the whole-corpus orphan-helper walk are both deleted. It also declared it would dissolve the HAND-Rust mirrors in cli_run.rs check_floor_filename_hygiene and the SIDECAR_PLACEMENT_RULES suffix checks once dual-run equivalence receipts went green -- the filename half of that obligation is discharged by deletion rather than by dissolution, and no receipt was ever needed for a rule with a zero-row population.\n\nWHAT REMAINS TRUE: the sidecar placement predicates and the test-decl line scan are still the single authority for their own questions, and the line scan is still a SECOND PARSER. Its replacement is not a refactor of this module: it needs the canonical parser to retain the authored `test` marker, which v1_compiler_parse.rs drop_leading_test_marker discards, and `test` cannot become a lex keyword because it is a live module-path segment (test.claim.*, extdeps.test.*). The prerequisite is named by v2.workflow.realization_attempt test_marker_capture_note: a GrammarExpr contextual-keyword terminal, which does not exist yet."