diff --git a/.gitattributes b/.gitattributes index 3f631047dbe..c556d8882bc 100644 --- a/.gitattributes +++ b/.gitattributes @@ -11,8 +11,6 @@ .githooks/generated-artifact-merge merge=generated-artifact .githooks/pre-commit merge=generated-artifact .githooks/pre-push merge=generated-artifact -.github/workflows/ci.yml merge=generated-artifact -.github/workflows/falsifier.yml merge=generated-artifact .github/workflows/fleet-converge.yml merge=generated-artifact .gitignore merge=generated-artifact DESIGN.md merge=generated-artifact @@ -31,7 +29,6 @@ docs/plans/ci-merge-freshness.md merge=generated-artifact docs/plans/ci-oom-reclassification.md merge=generated-artifact docs/plans/ci-performance-tanking-evidence.md merge=generated-artifact docs/plans/ci-process-end-to-end.md merge=generated-artifact -docs/plans/ci-selection-vs-scheduling.md merge=generated-artifact docs/plans/cli-run-hollowing-plan.md merge=generated-artifact docs/plans/compile-clean-forcecheck.md merge=generated-artifact docs/plans/compute-envelope-model.md merge=generated-artifact diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index dc351595584..00000000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,758 +0,0 @@ -name: ci -on: - workflow_dispatch: - inputs: - expected_healed_sha: - description: Immutable healed commit required by an auto-heal revalidation run - required: false - type: string - push: - branches: [main] - pull_request: - branches: [main] - types: [opened, synchronize, reopened, ready_for_review] - merge_group: -permissions: - contents: read - pull-requests: read -concurrency: - group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref == 'refs/heads/main' && github.sha || github.ref }} - cancel-in-progress: ${{ github.event_name != 'merge_group' }} -env: - CARGO_TERM_COLOR: always - RUSTFLAGS: -D warnings -jobs: - build: - runs-on: [self-hosted, linux, arm64] - timeout-minutes: 110 - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - ref: ${{ inputs.expected_healed_sha || github.sha }} - - name: Refuse a heal revalidation whose run subject or checkout does not name the expected healed SHA - run: | - EXPECTED_HEALED_SHA="${{ inputs.expected_healed_sha }}" - RUN_SUBJECT_HEAD="${{ github.sha }}" - if [ -n "$EXPECTED_HEALED_SHA" ]; then - ACTUAL_HEAD="$(git rev-parse HEAD)" - if ! [ "$RUN_SUBJECT_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: workflow run subject $RUN_SUBJECT_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - if ! [ "$ACTUAL_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: checkout head $ACTUAL_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - echo "heal revalidation preflight: checkout names expected healed head $EXPECTED_HEALED_SHA" - fi - - name: Isolate toolchain dirs - run: | - rm -rf "$RUNNER_TEMP/rustup" "$RUNNER_TEMP/cargo" - echo "HOME=$RUNNER_TEMP" >> "$GITHUB_ENV" - echo "CARGO_HOME=$RUNNER_TEMP/cargo" >> "$GITHUB_ENV" - echo "RUSTUP_HOME=$RUNNER_TEMP/rustup" >> "$GITHUB_ENV" - echo "MAKEFLAGS=" >> "$GITHUB_ENV" - echo "CARGO_BUILD_JOBS=3" >> "$GITHUB_ENV" - if sccache --show-stats >/dev/null 2>&1; then - echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" - echo "CARGO_INCREMENTAL=0" >> "$GITHUB_ENV" - printf '%s\n' "CiSccacheProviderReceipt: provider=bound catalog=sccache_local" - else - printf '%s\n' "CiSccacheProviderReceipt: provider=SKIPPED catalog=sccache_local host=$(hostname) cause=daemon-unavailable; the release build runs UNCACHED — a counted degradation, not a supported mode (host_build_cache_provision P1b should have converged this host)" - fi - - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.16.0 - with: - components: rustfmt - cache: false - rustflags: '' - env: - HOME: ${{ runner.temp }} - - name: Derive native-cache root (rustc-version segment; after setup-rust-toolchain) - run: | - # 🟡 dissolve-on: ci_native_cache_root_script — orch-emitted foreign-executor prelude step deriving GUNBC_NATIVE_CACHE_ROOT from rustc -V after setup-rust-toolchain; leaf rustc/tr/mkdir/echo strings remain until typed toolchain probe lands on host_effect_apply (#5828 / shell→intent Phase 2) - if ! GUNBC_TOOLCHAIN_SEG_RAW=$(rustc -V 2>/dev/null); then echo "::error::rustc -V failed after setup-rust-toolchain: cannot derive native-cache toolchain segment"; exit 1; fi - GUNBC_TOOLCHAIN_SEG=$(echo "$GUNBC_TOOLCHAIN_SEG_RAW" | tr ' ' '-') - if [ -z "$GUNBC_TOOLCHAIN_SEG" ]; then echo "::error::rustc -V produced an empty native-cache toolchain segment after setup-rust-toolchain"; exit 1; fi - mkdir -p "$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" - echo "GUNBC_NATIVE_CACHE_ROOT=$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" >> "$GITHUB_ENV" - - name: Pin rustup default (isolated RUSTUP_HOME has no default toolchain) - run: | - rustup default "$(rustup show active-toolchain | awk '{print $1; exit}')" - if [ -x "$CARGO_HOME/bin/cargo" ]; then CARGO_BIN="$CARGO_HOME/bin/cargo"; else CARGO_BIN="$(command -v cargo || true)"; fi - if [ -z "$CARGO_BIN" ]; then echo "::error::no cargo binary: neither the isolated $CARGO_HOME/bin/cargo shim nor PATH carries one"; exit 1; fi - echo "CARGO_BIN=$CARGO_BIN" >> "$GITHUB_ENV" - - name: Cache Cargo - uses: actions/cache@v5 - with: - path: | - ${{ runner.temp }}/cargo/registry/index/ - ${{ runner.temp }}/cargo/registry/cache/ - ${{ runner.temp }}/cargo/git/db/ - target/ - key: cargo-ci-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} - restore-keys: | - cargo-ci-${{ runner.os }}-${{ runner.arch }}- - - name: cargo fmt --all --check (fast gate; fails in seconds, before the release build) - run: "\"$CARGO_BIN\" fmt --all --check" - timeout-minutes: 5 - - name: Build release bins (claim_executor + gunbc) - id: release_build - run: | - # 🟡 dissolve-on: ci_release_build_script — concat-built foreign-executor (GitHub Actions run:) release-build runner (ROOT stamp + verify-artifacts + sccache stats wrapping the orch-emitted EAGAIN retry core); membership of --bin / verify paths is derived from gunbc.ci_release_bins, but the runner transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the release-build runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - set -o pipefail - BUILD_LOG=$(mktemp) - if ! ("$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin floor_skip_discovery_witness --bin selection_control_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness) 2>&1 | tee "$BUILD_LOG"; then - if grep -qiE 'Resource temporarily unavailable|failed to spawn|sccache: encountered fatal error|(exit status: 254)|sccache: error: failed to execute compile' "$BUILD_LOG"; then - echo "::warning::cargo/sccache EAGAIN under fleet pressure; cold retry CARGO_BUILD_JOBS=1 (keep sccache)" - CARGO_BUILD_JOBS=1 "$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin floor_skip_discovery_witness --bin selection_control_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness - else - exit 1 - fi - fi - rm -f "$BUILD_LOG" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - sccache --show-stats 2>/dev/null || true - timeout-minutes: 45 - - name: cargo test -p v1-compiler-tests --release (retained-kernel execution gate; reuses release v1-compiler) - run: | - set -e - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - # 🟡 dissolve-on: ci_v1_compiler_tests_compile_gate_script — foreign-executor (GitHub Actions run:) shell transport for extdeps.cargo_build cargo.Build.Test(extra_args: ci_v1_compiler_tests_compile_gate_extra_args); the EAGAIN retry wrapper lives in gunbc.ci_workflow ci_v1_compiler_tests_compile_gate_run_script (same seam as ci_release_build_script); DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the build-job step to orchestration emit over the typed cargo operation — the same de-fork ci_fmt_gate_line and ci_release_build_script await - set -o pipefail - BUILD_LOG=$(mktemp) - if ! ("$CARGO_BIN" 'test' '-p' 'v1-compiler-tests' '--release') 2>&1 | tee "$BUILD_LOG"; then - if grep -qiE 'Resource temporarily unavailable|failed to spawn|sccache: encountered fatal error|(exit status: 254)|sccache: error: failed to execute compile' "$BUILD_LOG"; then - echo "::warning::cargo/sccache EAGAIN under fleet pressure; cold retry CARGO_BUILD_JOBS=1 (keep sccache)" - CARGO_BUILD_JOBS=1 "$CARGO_BIN" 'test' '-p' 'v1-compiler-tests' '--release' - else - exit 1 - fi - fi - rm -f "$BUILD_LOG" - timeout-minutes: 15 - - name: cargo check all seven stage0 partition crates (compile gate; roster drift backstop) - run: | - # 🟡 dissolve-on: ci_stage0_partition_compile_gate_script — foreign-executor (GitHub Actions run:) shell transport for seven partition-crate cargo.Build.Check invocations; DISSOLVES WHEN bash-emit (#5828 / shell→intent Phase 2) binds the build-job step to orchestration emit over the typed cargo operations — same de-fork as ci_v1_compiler_tests_compile_gate_script and ci_fmt_gate_line - "$CARGO_BIN" 'check' '-p' 'v1-stage0-runtime' && "$CARGO_BIN" 'check' '-p' 'v1-stage0-std-core' && "$CARGO_BIN" 'check' '-p' 'v1-stage0-std-surface' && "$CARGO_BIN" 'check' '-p' 'v1-stage0-extdeps-languages' && "$CARGO_BIN" 'check' '-p' 'v1-stage0-v1-infer' && "$CARGO_BIN" 'check' '-p' 'v1-stage0-v1-artifact' && "$CARGO_BIN" 'check' '-p' 'v1-stage0-emit-core' - timeout-minutes: 15 - - name: cargo check -p v1-compiler --all-targets (compile gate; test targets nothing else compiles) - run: | - # 🟡 dissolve-on: ci_v1_compiler_test_targets_compile_gate_script — foreign-executor (GitHub Actions run:) shell transport for one extdeps.cargo_build cargo.Build.Check invocation; DISSOLVES WHEN bash-emit (#5828 / shell→intent Phase 2) binds the build-job step to orchestration emit over the typed cargo operation — the same de-fork ci_stage0_partition_compile_gate_script, ci_v1_compiler_tests_compile_gate_script and ci_fmt_gate_line await - "$CARGO_BIN" 'check' '-p' 'v1-compiler' '--all-targets' - timeout-minutes: 10 - - name: Pack release bins for cross-job handoff (tar keeps exec bits) - run: | - # 🟡 dissolve-on: ci_release_bins_pack_script — concat-built foreign-executor (GitHub Actions run:) release-bins tar pack runner; membership of archived bin names is derived from gunbc.ci_release_bins, but the pack transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the pack runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - tar -czf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" "claim_executor" "gunbc" "regen_floor_skip_witness" "floor_skip_discovery_witness" "selection_control_skip_witness" "discover_source_root_ingest" "claim_batch" "regen_stage0" "interp_recorded_fixture_witness" "v1_src_dag_parse" "auth_declared_but_unwired_witness" "bootstrap_witness" "dag_collect_fingerprint_witness" "diagnostics_witness" "effects_rest_transport_witness" "infer_semantics_witness" "parse_witness" "resolution_divergence_census" "cssl_assemble" "frontier_probe_survey" "namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: Upload release-bins artifact - uses: actions/upload-artifact@v4 - with: - name: release-bins - path: release-bins.tgz - if-no-files-found: error - retention-days: 3 - compression-level: 0 - timeout-minutes: 10 - regen: - runs-on: [self-hosted, linux, arm64] - needs: [build] - timeout-minutes: 35 - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - ref: ${{ inputs.expected_healed_sha || github.sha }} - - name: Refuse a heal revalidation whose run subject or checkout does not name the expected healed SHA - run: | - EXPECTED_HEALED_SHA="${{ inputs.expected_healed_sha }}" - RUN_SUBJECT_HEAD="${{ github.sha }}" - if [ -n "$EXPECTED_HEALED_SHA" ]; then - ACTUAL_HEAD="$(git rev-parse HEAD)" - if ! [ "$RUN_SUBJECT_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: workflow run subject $RUN_SUBJECT_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - if ! [ "$ACTUAL_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: checkout head $ACTUAL_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - echo "heal revalidation preflight: checkout names expected healed head $EXPECTED_HEALED_SHA" - fi - - name: Setup Rust (floor gate toolchain — batch-4 emit_host/self_host gates need cargo/rustfmt; no isolated rustup) - uses: actions-rust-lang/setup-rust-toolchain@v1.16.0 - with: - components: rustfmt - cache: false - rustflags: '' - - name: Derive native-cache root (rustc-version segment; after setup-rust-toolchain) - run: | - # 🟡 dissolve-on: ci_native_cache_root_script — orch-emitted foreign-executor prelude step deriving GUNBC_NATIVE_CACHE_ROOT from rustc -V after setup-rust-toolchain; leaf rustc/tr/mkdir/echo strings remain until typed toolchain probe lands on host_effect_apply (#5828 / shell→intent Phase 2) - if ! GUNBC_TOOLCHAIN_SEG_RAW=$(rustc -V 2>/dev/null); then echo "::error::rustc -V failed after setup-rust-toolchain: cannot derive native-cache toolchain segment"; exit 1; fi - GUNBC_TOOLCHAIN_SEG=$(echo "$GUNBC_TOOLCHAIN_SEG_RAW" | tr ' ' '-') - if [ -z "$GUNBC_TOOLCHAIN_SEG" ]; then echo "::error::rustc -V produced an empty native-cache toolchain segment after setup-rust-toolchain"; exit 1; fi - mkdir -p "$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" - echo "GUNBC_NATIVE_CACHE_ROOT=$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" >> "$GITHUB_ENV" - - name: Download release-bins artifact - uses: actions/download-artifact@v4 - with: - name: release-bins - timeout-minutes: 10 - - name: Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed) - id: release_bins - run: | - # 🟡 dissolve-on: ci_release_bins_unpack_verify_script — concat-built foreign-executor (GitHub Actions run:) release-bins unpack + claim_executor --verify-build-artifacts runner; membership of verified paths is derived from gunbc.ci_release_bins, but the unpack/verify transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the unpack/verify runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - mkdir -p "$ROOT/target/release" - tar -xzf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" - rm -f "$ROOT/release-bins.tgz" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: gunbc ci regen (self-host fixed-point — required) - run: | - # 🟡 dissolve-on: ci_regen_ensure_rustfmt_path_script — foreign-executor PATH ensure for regen_stage0 on hosts with a cargo shim and no CARGO_HOME/bin (receipt CI #7290 srv3-03); control flow is If/Predicate/Exit/Let via orch bash-emit; leaf test -x / command -v / export PATH / dirname strings remain until FileExists + session-EnvExport (PR2b) or the regen job shares isolate+pin by construction; DISSOLVES WHEN rustfmt resolution is a typed toolchain probe on host_effect_apply rather than emitted bash (#5828 / ROADMAP 6-shell-slice0) - # Prepend a locatable rustfmt dir onto PATH before regen_stage0's standalone rustfmt spawn (hosts that expose a cargo shim without CARGO_HOME/bin — receipt CI #7290 srv3-03). Probe order: CARGO_HOME/bin, /opt/cargo/bin, HOME/.cargo/bin, rustup which; refuse if still absent. - if [ -n "$CARGO_HOME" ] && [ -x "$CARGO_HOME/bin/rustfmt" ]; then export PATH="$CARGO_HOME/bin:$PATH"; fi - if ! command -v rustfmt >/dev/null 2>&1 && [ -x /opt/cargo/bin/rustfmt ]; then export PATH="/opt/cargo/bin:$PATH"; fi - if ! command -v rustfmt >/dev/null 2>&1 && [ -x "$HOME/.cargo/bin/rustfmt" ]; then export PATH="$HOME/.cargo/bin:$PATH"; fi - if ! command -v rustfmt >/dev/null 2>&1; then - RF=$(/opt/cargo/bin/rustup which rustfmt) 2>/dev/null || true - if [ -n "$RF" ] && [ -x "$RF" ]; then - RF_DIR="$(dirname "$RF")" - export PATH="$RF_DIR:$PATH" - fi - fi - if ! command -v rustfmt >/dev/null 2>&1; then - echo "::error::rustfmt not on PATH for regen_stage0 standalone spawn (hosts with a cargo shim and no CARGO_HOME/bin — receipt CI #7290 srv3-03)" - exit 1 - fi - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - git fetch --no-tags origin main 2>/dev/null || true - # Affected-set-scoped regen admission (pull_request only): on a pull_request event, regen_floor_skip_witness intersects the merge-base diff with the [src/v1, dag] regen input closure (shared authority cli_run::regen_input_sources — the exact set regen_stage0 compiles; both the RegenVerifyGate and the SelfHostStalenessGate invoke regen_stage0, so the closure covers both). A PR diff touching none of src/v1/** (emitter source + committed stage0 outputs), v1's transitive dag import-closure, or the Cargo/toolchain build config cannot change the self-host fixed-point, so the regen step exits 0 immediately (a required step that passes because the self-host fixed-point is provably unchanged — regen runs before the floor so emitter drift fails fast, with no floor or merge-admission dependency). Empty diff / diff failure / closure failure runs regen (fail-closed). COLD CONTROL: the skip is gated to pull_request events via GITHUB_EVENT_NAME, so push-to-main and workflow_dispatch run regen UNCONDITIONALLY (no witness). A wrong closure that lets a PR wrongly skip therefore surfaces as a counted divergence on the very next merge to main — the squash-merge main-push run has an empty diff and runs regen cold, reding main if the seed is stale (a one-merge acceptance window, the discovery-flip shape). The 4-hourly falsifier does NOT run regen_stage0; the unconditional main-push regen is the cold control. - if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then - _ci_regen_skip=$("$ROOT/target/release/regen_floor_skip_witness" 2>/dev/null || echo run_regen) - if [ "$_ci_regen_skip" = "regen_not_affected_skip" ]; then - echo "gunbc ci regen: pull_request diff does not intersect the [src/v1, dag] regen input closure — self-host fixed-point provably unchanged; skipping (push-to-main runs regen unconditionally as the cold control)" - exit 0 - fi - fi - "$ROOT/target/release/claim_executor" --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --plan-entry src/v2/workflow/ci_floor_plan.dag --plan-function gunbc_ci_regen_floor_plan --notice-title "self-host fixed-point (regen + staleness) — required; own regen job upstream of ci" - timeout-minutes: 15 - ci: - runs-on: [self-hosted, linux, arm64] - needs: [build, regen, heal_generated_artifacts] - timeout-minutes: 140 - if: "!cancelled()" - steps: - - name: "Refuse when an upstream job already established this branch is red (fails fast instead of skipping: a skipped job reports success to the required check)" - run: | - set -e - BUILD='${{ needs.build.result }}' - REGEN='${{ needs.regen.result }}' - HEAL='${{ needs.heal_generated_artifacts.result }}' - if [ "$BUILD" != "success" ] || [ "$REGEN" != "success" ] || [ "$HEAL" = "failure" ]; then - echo "::error::FloorUpstreamAlreadyRed build=$BUILD regen=$REGEN heal=$HEAL — an upstream job already established this branch is red, so the floor refuses before spending its budget. The located cause is that job's own diagnostic; this step adds no verdict of its own." - exit 1 - fi - echo "[floor-preflight] upstream clean: build=$BUILD regen=$REGEN heal=$HEAL" - timeout-minutes: 5 - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - ref: ${{ inputs.expected_healed_sha || github.sha }} - - name: Refuse a heal revalidation whose run subject or checkout does not name the expected healed SHA - run: | - EXPECTED_HEALED_SHA="${{ inputs.expected_healed_sha }}" - RUN_SUBJECT_HEAD="${{ github.sha }}" - if [ -n "$EXPECTED_HEALED_SHA" ]; then - ACTUAL_HEAD="$(git rev-parse HEAD)" - if ! [ "$RUN_SUBJECT_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: workflow run subject $RUN_SUBJECT_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - if ! [ "$ACTUAL_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: checkout head $ACTUAL_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - echo "heal revalidation preflight: checkout names expected healed head $EXPECTED_HEALED_SHA" - fi - - name: Setup Rust (floor gate toolchain — batch-4 emit_host/self_host gates need cargo/rustfmt; no isolated rustup) - uses: actions-rust-lang/setup-rust-toolchain@v1.16.0 - with: - components: rustfmt - cache: false - rustflags: '' - - name: Derive native-cache root (rustc-version segment; after setup-rust-toolchain) - run: | - # 🟡 dissolve-on: ci_native_cache_root_script — orch-emitted foreign-executor prelude step deriving GUNBC_NATIVE_CACHE_ROOT from rustc -V after setup-rust-toolchain; leaf rustc/tr/mkdir/echo strings remain until typed toolchain probe lands on host_effect_apply (#5828 / shell→intent Phase 2) - if ! GUNBC_TOOLCHAIN_SEG_RAW=$(rustc -V 2>/dev/null); then echo "::error::rustc -V failed after setup-rust-toolchain: cannot derive native-cache toolchain segment"; exit 1; fi - GUNBC_TOOLCHAIN_SEG=$(echo "$GUNBC_TOOLCHAIN_SEG_RAW" | tr ' ' '-') - if [ -z "$GUNBC_TOOLCHAIN_SEG" ]; then echo "::error::rustc -V produced an empty native-cache toolchain segment after setup-rust-toolchain"; exit 1; fi - mkdir -p "$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" - echo "GUNBC_NATIVE_CACHE_ROOT=$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" >> "$GITHUB_ENV" - - name: Download release-bins artifact - uses: actions/download-artifact@v4 - with: - name: release-bins - timeout-minutes: 10 - - name: Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed) - id: release_bins - run: | - # 🟡 dissolve-on: ci_release_bins_unpack_verify_script — concat-built foreign-executor (GitHub Actions run:) release-bins unpack + claim_executor --verify-build-artifacts runner; membership of verified paths is derived from gunbc.ci_release_bins, but the unpack/verify transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the unpack/verify runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - mkdir -p "$ROOT/target/release" - tar -xzf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" - rm -f "$ROOT/release-bins.tgz" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: Floor cgroup peak pre-read (calibration; reset if permitted) - run: | - # 🟡 dissolve-on: ci_cgroup_peak_locate_shell — foreign-executor (GitHub Actions run:) shell transport composing extdeps.linux.proc_self_cgroup unified-hierarchy membership (v2.extdeps.languages.bash_proc_self_cgroup) with std.path_intent NearestAncestorContaining dirname ascent (bash_orch_if). Procfs path is extdeps.linux.procfs ProcSelfCgroup. DISSOLVES WHEN shell→intent Phase 2 realizes cgroup membership plus path ascent on host_effect_apply / orchestration path arms without medium-as-string Run.command concat. - { _cg_bad=0; _cg_n=0; _cg_rel=""; while IFS= read -r _cg_line || [ -n "$_cg_line" ]; do _cg_trim=$(echo "$_cg_line" | sed -e 's/^ //' -e 's/ $//'); [ -z "$_cg_trim" ] && continue; case "$_cg_trim" in *:*:*) ;; *) _cg_bad=1; continue ;; esac; _cg_h=$(echo "$_cg_trim" | cut -d: -f1); _cg_ctl=$(echo "$_cg_trim" | cut -d: -f2); _cg_path=$(echo "$_cg_trim" | cut -d: -f3-); [ -z "$_cg_h" ] && _cg_bad=1; [ -z "$_cg_path" ] && _cg_bad=1; if [ "$_cg_h" = "0" ] && [ -z "$_cg_ctl" ]; then _cg_n=$((_cg_n + 1)); _cg_rel="$_cg_path"; fi; done < /proc/self/cgroup; [ "$_cg_bad" -eq 1 ] && { echo "[calibration] cgroup_membership=malformed" >&2; exit 1; }; [ "$_cg_n" -eq 0 ] && { echo "[calibration] cgroup_membership=missing" >&2; exit 1; }; [ "$_cg_n" -gt 1 ] && { echo "[calibration] cgroup_membership=ambiguous" >&2; exit 1; }; d="/sys/fs/cgroup$_cg_rel"; } || exit 1 - while [ -n "$d" ] && [ "$d" != "/sys/fs/cgroup" ] && ! [ -f "$d/memory.peak" ]; do d=$(dirname "$d"); done - if [ -f "$d/memory.peak" ]; then if echo reset > "$d/memory.peak" 2>/dev/null; then echo "[calibration] floor_peak_pre reset=ok scope=floor cgroup=$d"; else echo "[calibration] floor_peak_pre reset=unsupported pre_peak=$(cat "$d/memory.peak") scope=span cgroup=$d (post>pre attributes the peak to the floor exactly; post==pre means floor peak <= pre, a job-scoped upper bound)"; fi; else echo "[calibration] floor_peak_pre scope=unavailable (no memory.peak ancestor)"; fi - timeout-minutes: 5 - - name: gunbc ci (.dag witnesses + gates) - id: floor - run: | - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - # REMOVED 2026-07-21 (gunbc#7023 / proud-cat-517): the documentation_only_skip shell shortcut exited before claim_executor, bypassing the witness corpus entirely on docs-only PRs. That bypassed the existing ReadsLiveTree never-predict-skip lane — doc_reachability_witness_test.dag already declared ReadsLiveTree since #6654, but the shell never reached selection. Docs-only PRs now run the normal floor (SelectionApplied): import-closure skips non-live-tree witnesses cheaply; ReadsLiveTree rows (doc-graph wall, corpus-read host-fed lenses) always run. The isolated pre-executor skip-label binary and its unreachable persistent disposition transport retired afterward; compile-clean docs-universe scoping remains independently exercised on the live floor path. - git fetch --no-tags origin main 2>/dev/null || true - "$ROOT/target/release/claim_executor" --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --plan-entry src/v2/workflow/ci_floor_plan.dag --plan-function gunbc_ci_floor_plan --notice-title "v2 claim corpus" - env: - GUNBC_FLOOR_PHASE_JOURNAL: target/floor-phase-journal.tsv - timeout-minutes: 100 - - name: Floor cgroup peak post-read (calibration; survives a killed floor) - run: | - # 🟡 dissolve-on: ci_floor_phase_journal_if — bounded foreign-executor (GitHub Actions run:) shell transport for exactly four journal leaves: FileExists, column-name log, row-count summary log, and absent log. If/else control flow is already v2.std.orchestration intent; only those leaves remain medium-as-string Run.command values. DISSOLVES WHEN bash-emit (#5828 / ROADMAP shell-effectplan-to-bash / shell→intent Phase 2) binds typed filesystem observation plus diagnostic-log operations through host_effect_apply, so ci_floor_phase_journal_if contains no opaque shell command text. - if [ -f "$GUNBC_FLOOR_PHASE_JOURNAL" ]; then - echo "[floor-phase-journal] columns: unix_millis pid phase state detail" - echo "[floor-phase-journal] $(wc -l < $GUNBC_FLOOR_PHASE_JOURNAL) rows retained; full journal in the floor-phase-journal artifact" - else - echo "[floor-phase-journal] absent" - fi - # 🟡 dissolve-on: ci_floor_wet_witness_row_outcome_receipt_if — bounded foreign-executor (GitHub Actions run:) shell transport for exactly four receipt leaves: FileExists, column-name log, row-count summary log, and absent log. DISSOLVES WHEN bash-emit (#5828 / ROADMAP shell-effectplan-to-bash / shell→intent Phase 2) binds typed filesystem observation plus diagnostic-log operations through host_effect_apply, so ci_floor_wet_witness_row_outcome_receipt_if contains no opaque shell command text. - if [ -f "target/floor-wet-witness-row-outcome-receipt.tsv" ]; then - echo "[wet-witness-row-outcome-receipt] columns: batch entry function outcome detail" - echo "[wet-witness-row-outcome-receipt] $(wc -l < target/floor-wet-witness-row-outcome-receipt.tsv) rows; full receipt in the floor-component-receipt artifact" - else - echo "[wet-witness-row-outcome-receipt] absent" - fi - # 🟡 dissolve-on: ci_cgroup_peak_locate_shell — foreign-executor (GitHub Actions run:) shell transport composing extdeps.linux.proc_self_cgroup unified-hierarchy membership (v2.extdeps.languages.bash_proc_self_cgroup) with std.path_intent NearestAncestorContaining dirname ascent (bash_orch_if). Procfs path is extdeps.linux.procfs ProcSelfCgroup. DISSOLVES WHEN shell→intent Phase 2 realizes cgroup membership plus path ascent on host_effect_apply / orchestration path arms without medium-as-string Run.command concat. - { _cg_bad=0; _cg_n=0; _cg_rel=""; while IFS= read -r _cg_line || [ -n "$_cg_line" ]; do _cg_trim=$(echo "$_cg_line" | sed -e 's/^ //' -e 's/ $//'); [ -z "$_cg_trim" ] && continue; case "$_cg_trim" in *:*:*) ;; *) _cg_bad=1; continue ;; esac; _cg_h=$(echo "$_cg_trim" | cut -d: -f1); _cg_ctl=$(echo "$_cg_trim" | cut -d: -f2); _cg_path=$(echo "$_cg_trim" | cut -d: -f3-); [ -z "$_cg_h" ] && _cg_bad=1; [ -z "$_cg_path" ] && _cg_bad=1; if [ "$_cg_h" = "0" ] && [ -z "$_cg_ctl" ]; then _cg_n=$((_cg_n + 1)); _cg_rel="$_cg_path"; fi; done < /proc/self/cgroup; [ "$_cg_bad" -eq 1 ] && { echo "[calibration] cgroup_membership=malformed" >&2; exit 1; }; [ "$_cg_n" -eq 0 ] && { echo "[calibration] cgroup_membership=missing" >&2; exit 1; }; [ "$_cg_n" -gt 1 ] && { echo "[calibration] cgroup_membership=ambiguous" >&2; exit 1; }; d="/sys/fs/cgroup$_cg_rel"; } || exit 1 - while [ -n "$d" ] && [ "$d" != "/sys/fs/cgroup" ] && ! [ -f "$d/memory.peak" ]; do d=$(dirname "$d"); done - if [ -f "$d/memory.peak" ]; then echo "[calibration] floor_peak_post=$(cat "$d/memory.peak") floor_outcome=${{ steps.floor.outcome }} cgroup=$d (observation label: floor_outcome=success is an EXACT point; any other outcome is a CENSORED lower bound - the process was killed while exceeding the read, so true demand is strictly greater. scope per the floor_peak_pre line: reset=ok means this IS the floor peak; scope=span compares against pre_peak)"; else echo "[calibration] floor_peak_post floor_outcome=${{ steps.floor.outcome }} scope=unavailable (no memory.peak ancestor)"; fi - env: - GUNBC_FLOOR_PHASE_JOURNAL: target/floor-phase-journal.tsv - if: always() - timeout-minutes: 5 - - name: Upload floor receipts (TSV authority for cost/drift rows) - uses: actions/upload-artifact@v4 - with: - name: floor-receipts - path: target/floor-* - if-no-files-found: warn - retention-days: 14 - if: always() - timeout-minutes: 5 - heal_generated_artifacts: - runs-on: [self-hosted, linux, arm64] - needs: [build] - timeout-minutes: 40 - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' - permissions: - contents: write - actions: write - steps: - - name: Checkout triggering branch head (heal pushes the regeneration back to this branch) - uses: actions/checkout@v5 - with: - fetch-depth: 0 - ref: ${{ github.head_ref || github.ref_name }} - - name: Download release-bins artifact - uses: actions/download-artifact@v4 - with: - name: release-bins - timeout-minutes: 10 - - name: Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed) - id: release_bins - run: | - # 🟡 dissolve-on: ci_release_bins_unpack_verify_script — concat-built foreign-executor (GitHub Actions run:) release-bins unpack + claim_executor --verify-build-artifacts runner; membership of verified paths is derived from gunbc.ci_release_bins, but the unpack/verify transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the unpack/verify runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - mkdir -p "$ROOT/target/release" - tar -xzf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" - rm -f "$ROOT/release-bins.tgz" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: Converge repository-local Git integration bindings (repo_local_git_config converge) - run: | - # 🟡 dissolve-on: gunbc_ci_heal_repo_local_git_config_invoke — foreign-executor (GitHub Actions run:) shell transport invoking gunbc run on dag/gunbc/repo_local_git_config converge; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the heal step to orchestration emit over the typed gunbc.WitnessBin.Run route without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/repo_local_git_config.dag --function converge - timeout-minutes: 5 - - name: Refuse a binary/source revision skew (the release binary is built from the PR merge ref; this job checked out the branch head) - run: | - BUILT_FROM="${{ github.sha }}" - if git fetch --quiet origin "$BUILT_FROM" 2>/dev/null || git fetch --quiet origin "${{ github.ref }}" 2>/dev/null; then :; else :; fi - if ! git rev-parse --verify --quiet "$BUILT_FROM" >/dev/null; then - echo "heal refused: cannot resolve the revision the release binary was built from" >&2 - echo " wanted: $BUILT_FROM (github.sha — the ref the build job compiled)" >&2 - echo " without it this job cannot establish that its binary and its tree agree." >&2 - exit 1 - fi - SEED_AHEAD="$(git rev-list HEAD.."$BUILT_FROM" -- src/v1)" - if [ -n "$SEED_AHEAD" ]; then - echo "heal: binary/source revision skew — the branch head lacks these seed (src/v1) commits:" >&2 - echo "$SEED_AHEAD" | head -20 | sed 's/^/ /' >&2 - echo "heal: applying the remedy automatically (merging $BUILT_FROM — the revision the binary was built from — into this branch)" >&2 - git config user.name gunbc-ci-auto-heal - git config user.email gunbc-ci-auto-heal@users.noreply.github.com - if ! git merge --no-edit "$BUILT_FROM"; then - CONFLICTS="$(git diff --name-only --diff-filter=U)" - AUTHORED_CONFLICTS="$(git diff --name-only --diff-filter=U -- . ':(exclude).github/workflows/ci.yml' ':(exclude).github/workflows/falsifier.yml' ':(exclude).github/workflows/fleet-converge.yml' ':(exclude).gitignore' ':(exclude).gitattributes' ':(exclude)ROADMAP.md' ':(exclude)DESIGN.md' ':(exclude).githooks/pre-push' ':(exclude).githooks/pre-commit' ':(exclude).githooks/generated-artifact-merge' ':(exclude)dag/gunbc/stage0_crate_layout_generated.dag' ':(exclude)src/v1/stage0/src/bootstrap_stage0_crate_layout_generated.rs' ':(exclude)dag/gunbc/stage0_crate_partition_generated.dag' ':(exclude)dag/gunbc/stage0_emit_plan_generated.dag' ':(exclude)src/v1/stage0/src/v1_interpreter_dispatch_generated.rs' ':(exclude)docs/plans/idea-machine.md' ':(exclude)docs/plans/algebraic-rewrite-optimization.md' ':(exclude)docs/plans/dag-v2-defork-audit.md' ':(exclude)docs/plans/v2-self-hosting.md' ':(exclude)docs/plans/m5-fixture-store-consolidation.md' ':(exclude)docs/plans/model-realization-fork.md' ':(exclude)docs/plans/value-null-split.md' ':(exclude)docs/plans/ci-merge-freshness.md' ':(exclude)docs/plans/seed-debt-bundle-item-2.md' ':(exclude)docs/plans/axiom-syllogism-lens.md' ':(exclude)docs/plans/invert-hand-maintained.md' ':(exclude)docs/plans/fail-closed-lockdown.md' ':(exclude)docs/plans/format-model-reconciliation.md' ':(exclude)docs/plans/regime2-shared-emission-fold.md' ':(exclude)docs/plans/shell-emission-model.md' ':(exclude)docs/plans/construction-justification-rule.md' ':(exclude)docs/plans/emission-ingestion-inverse.md' ':(exclude)docs/plans/testgen-oracle.md' ':(exclude)docs/plans/disposition-carrier.md' ':(exclude)docs/plans/fold-ergonomics.md' ':(exclude)docs/plans/m4-universal-hermetic-corpus.md' ':(exclude)docs/plans/wiring-liveness-preflight.md' ':(exclude)docs/plans/interpreter-kernel-d.md' ':(exclude)docs/plans/inert-layer-lens.md' ':(exclude)docs/plans/compile-clean-forcecheck.md' ':(exclude)docs/plans/expressibility-frontier.md' ':(exclude)docs/plans/p1-where-clause-lowering.md' ':(exclude)docs/plans/intent-linearity-design-draft.md' ':(exclude)docs/plans/solve-higher-order-design.md' ':(exclude)docs/plans/language-target-self-host-frontier.md' ':(exclude)docs/plans/self-applying-lenses.md' ':(exclude)docs/plans/budget-tree.md' ':(exclude)docs/plans/cardinality-refinement.md' ':(exclude)docs/plans/compute-envelope-model.md' ':(exclude)docs/plans/input-envelope-roadmap.md' ':(exclude)docs/plans/ci-selection-vs-scheduling.md' ':(exclude)docs/plans/ci-process-end-to-end.md' ':(exclude)docs/plans/ci-oom-reclassification.md' ':(exclude)docs/plans/bounded-input-cost-envelope-scheduling.md' ':(exclude)docs/plans/ci-humming.md' ':(exclude)docs/plans/edge-b-rust-dag-provenance-brief.md' ':(exclude)docs/plans/resolver-type-name-collision-wall.md' ':(exclude)docs/plans/realization-measurement-loop.md' ':(exclude)docs/plans/host-effect-orchestration.md' ':(exclude)docs/plans/ci-floor-fractal-gantt.md' ':(exclude)docs/plans/resolver-pathology-profile-receipt.md' ':(exclude)docs/plans/representation-minimization.md' ':(exclude)docs/plans/reference-grounding-migration.md' ':(exclude)docs/plans/typescript-gap-census.md' ':(exclude)docs/plans/cli-run-hollowing-plan.md' ':(exclude)docs/plans/fleet-acceptance-criteria.md' ':(exclude)docs/plans/structural-quadratic-wall-coverage-audit.md' ':(exclude)docs/plans/ci-performance-tanking-evidence.md' ':(exclude)docs/plans/extdeps-modeling-preflight.md' ':(exclude)docs/plans/discrete-cost-derivation.md' ':(exclude)docs/plans/v2-complexity-capability-parity.md' ':(exclude)src/v1/stage0/src/compiler_tests.rs' ':(exclude)src/v1/stage0/src/extdeps_cargo.rs' ':(exclude)src/v1/stage0/src/extdeps_cargo_version.rs' ':(exclude)src/v1/stage0/src/extdeps_container_oci_digest.rs' ':(exclude)src/v1/stage0/src/extdeps_external_authority.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_dag_emit.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_dag_syntax.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_dag_types.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_go_emit.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_go_syntax.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_go_types.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_python_emit.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_python_syntax.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_python_types.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_rust_emit.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_rust_syntax.rs' ':(exclude)src/v1/stage0/src/extdeps_languages_rust_types.rs' ':(exclude)src/v1/stage0/src/extdeps_units_dimensionless.rs' ':(exclude)src/v1/stage0/src/extdeps_units_iec_80000_13.rs' ':(exclude)src/v1/stage0/src/extdeps_units_iso8601.rs' ':(exclude)src/v1/stage0/src/extdeps_units_iso_80000_3.rs' ':(exclude)src/v1/stage0/src/extdeps_uri.rs' ':(exclude)src/v1/stage0/src/extdeps_uri_path.rs' ':(exclude)src/v1/stage0/src/extdeps_version.rs' ':(exclude)src/v1/stage0/src/extdeps_version_semver.rs' ':(exclude)src/v1/stage0/src/gunbc_namespace_reference_derived_closure_admission.rs' ':(exclude)src/v1/stage0/src/gunbc_namespace_reference_derived_closure_contract.rs' ':(exclude)src/v1/stage0/src/gunbc_rust_decl_type_overlay.rs' ':(exclude)src/v1/stage0/src/gunbc_stage0_crate_layout_generated.rs' ':(exclude)src/v1/stage0/src/gunbc_stage0_crate_partition_generated.rs' ':(exclude)src/v1/stage0/src/lib.rs' ':(exclude)src/v1/stage0/src/std_algebra.rs' ':(exclude)src/v1/stage0/src/std_checked_arithmetic.rs' ':(exclude)src/v1/stage0/src/std_coercion.rs' ':(exclude)src/v1/stage0/src/std_computation.rs' ':(exclude)src/v1/stage0/src/std_constructors.rs' ':(exclude)src/v1/stage0/src/std_content_hash.rs' ':(exclude)src/v1/stage0/src/std_currency.rs' ':(exclude)src/v1/stage0/src/std_decl_ref.rs' ':(exclude)src/v1/stage0/src/std_disposition.rs' ':(exclude)src/v1/stage0/src/std_dissolution.rs' ':(exclude)src/v1/stage0/src/std_effects.rs' ':(exclude)src/v1/stage0/src/std_emit_model.rs' ':(exclude)src/v1/stage0/src/std_error_primitives.rs' ':(exclude)src/v1/stage0/src/std_execution_mode.rs' ':(exclude)src/v1/stage0/src/std_graph.rs' ':(exclude)src/v1/stage0/src/std_http_path.rs' ':(exclude)src/v1/stage0/src/std_induction.rs' ':(exclude)src/v1/stage0/src/std_integer.rs' ':(exclude)src/v1/stage0/src/std_interface_summary.rs' ':(exclude)src/v1/stage0/src/std_iteration.rs' ':(exclude)src/v1/stage0/src/std_keyed_roster.rs' ':(exclude)src/v1/stage0/src/std_keyed_row.rs' ':(exclude)src/v1/stage0/src/std_logic.rs' ':(exclude)src/v1/stage0/src/std_machine_constraints.rs' ':(exclude)src/v1/stage0/src/std_magnitude.rs' ':(exclude)src/v1/stage0/src/std_measure.rs' ':(exclude)src/v1/stage0/src/std_nat.rs' ':(exclude)src/v1/stage0/src/std_node.rs' ':(exclude)src/v1/stage0/src/std_occurrence_binding.rs' ':(exclude)src/v1/stage0/src/std_occurrence_binding_candidates.rs' ':(exclude)src/v1/stage0/src/std_occurrence_binding_resolve.rs' ':(exclude)src/v1/stage0/src/std_occurrence_identity.rs' ':(exclude)src/v1/stage0/src/std_pareto.rs' ':(exclude)src/v1/stage0/src/std_process_termination.rs' ':(exclude)src/v1/stage0/src/std_realization_schedule.rs' ':(exclude)src/v1/stage0/src/std_reference_binding_observation.rs' ':(exclude)src/v1/stage0/src/std_roster_frontier.rs' ':(exclude)src/v1/stage0/src/std_serialization.rs' ':(exclude)src/v1/stage0/src/std_source_annotation.rs' ':(exclude)src/v1/stage0/src/std_syntax.rs' ':(exclude)src/v1/stage0/src/std_termination.rs' ':(exclude)src/v1/stage0/src/std_trait_derive_shape.rs' ':(exclude)src/v1/stage0/src/std_types.rs' ':(exclude)src/v1/stage0/src/std_unicode_types.rs' ':(exclude)src/v1/stage0/src/std_witness_admission.rs' ':(exclude)src/v1/stage0/src/v1_compiler_annotation_bind.rs' ':(exclude)src/v1/stage0/src/v1_compiler_artifact.rs' ':(exclude)src/v1/stage0/src/v1_compiler_closure_stub_v2_std_integer_rust.rs' ':(exclude)src/v1/stage0/src/v1_compiler_closure_stub_v2_std_text_rust.rs' ':(exclude)src/v1/stage0/src/v1_compiler_coercion.rs' ':(exclude)src/v1/stage0/src/v1_compiler_compile.rs' ':(exclude)src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs' ':(exclude)src/v1/stage0/src/v1_compiler_complexity.rs' ':(exclude)src/v1/stage0/src/v1_compiler_dag_collect.rs' ':(exclude)src/v1/stage0/src/v1_compiler_dag_collect_support.rs' ':(exclude)src/v1/stage0/src/v1_compiler_effect_derivation.rs' ':(exclude)src/v1/stage0/src/v1_compiler_emit.rs' ':(exclude)src/v1/stage0/src/v1_compiler_emit_core_support.rs' ':(exclude)src/v1/stage0/src/v1_compiler_emit_go.rs' ':(exclude)src/v1/stage0/src/v1_compiler_emit_python.rs' ':(exclude)src/v1/stage0/src/v1_compiler_emit_rust.rs' ':(exclude)src/v1/stage0/src/v1_compiler_frontend_observation.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_access.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_cycle.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_emit_info.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_env.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_items.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_lookup.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_method.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_occurrence_binding.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_patterns.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_resolve.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_service.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_sigs.rs' ':(exclude)src/v1/stage0/src/v1_compiler_infer_types.rs' ':(exclude)src/v1/stage0/src/v1_compiler_languages.rs' ':(exclude)src/v1/stage0/src/v1_compiler_normalize.rs' ':(exclude)src/v1/stage0/src/v1_compiler_ownership.rs' ':(exclude)src/v1/stage0/src/v1_compiler_parse.rs' ':(exclude)src/v1/stage0/src/v1_compiler_resolve.rs' ':(exclude)src/v1/stage0/src/v1_compiler_runtime_go.rs' ':(exclude)src/v1/stage0/src/v1_compiler_runtime_rust.rs' ':(exclude)src/v1/stage0/src/v1_compiler_stage0_crates.rs' ':(exclude)src/v1/stage0/src/v1_compiler_tokenize.rs' ':(exclude)src/v1/stage0/src/v1_compiler_trace.rs' ':(exclude)src/v1/stage0/src/v1_compiler_trait_derive_emit.rs' ':(exclude)src/v1/stage0/src/v1_compiler_workspace_members.rs' ':(exclude)src/v1/stage0/src/v1_gunbc_namespace_reference_derived_closure_production_observations.rs' ':(exclude)src/v1/stage0/src/v1_gunbc_occurrence_binding_parser_walk.rs' ':(exclude)src/v1/stage0/src/v1_probe_emit_interp.rs' ':(exclude)src/v1/stage0/src/v1_rt.rs' ':(exclude)src/v1/stage0/src/v1_std_core.rs' ':(exclude)src/v1/stage0/src/v1_test_non_ascii_perf_fixture.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_caret_parse_smoke_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_dag_parse_continuation_operator_witness_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_namespace_reference_derived_closure_production_admissions_witness_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_occurrence_binding_parser_walk_witness_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_occurrence_identity_debt_receipt_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_ordinary_frontend_observation_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_pattern_binder_declaration_node_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_required_expr_newline_continuation_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_v1_annotation_binding_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_v1_annotation_capture_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_v1_annotation_erasure_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_v1_annotation_round_trip_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_v1_annotation_target_emission_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_v1_complexity_eviction_hazard_test.rs' ':(exclude)src/v1/stage0/src/v1_tests_claim_v1_match_pattern_identity_test.rs' ':(exclude)src/v1/stage0/src/wt_a.rs' ':(exclude)src/v1/stage0/src/wt_b.rs' ':(exclude)src/v1/stage0/src/wt_common.rs')" - if [ -n "$AUTHORED_CONFLICTS" ]; then - echo "heal refused: binary/source revision skew, and the remedy CONFLICTS in authored files" >&2 - echo " conflicting paths:" >&2 - echo "$CONFLICTS" | head -20 | sed 's/^/ /' >&2 - echo " authored (not a registered generated artifact, so not auto-resolvable):" >&2 - echo "$AUTHORED_CONFLICTS" | head -20 | sed 's/^/ /' >&2 - echo " a semantic conflict is the author's to resolve; this job will not guess." >&2 - git merge --abort - exit 1 - fi - echo "heal: conflicts are confined to registered generated artifacts; regeneration is authoritative" >&2 - echo "$CONFLICTS" | head -20 | sed 's/^/ /' >&2 - git diff --name-only --diff-filter=U -z | xargs -0 git checkout --ours -- - git diff --name-only --diff-filter=U -z | xargs -0 git add - STILL_UNMERGED="$(git diff --name-only --diff-filter=U)" - if [ -n "$STILL_UNMERGED" ]; then - echo "heal refused: the index still carries unmerged stages after resolution; refusing to commit" >&2 - echo " still-unmerged paths:" >&2 - echo "$STILL_UNMERGED" | head -20 | sed 's/^/ /' >&2 - echo " a commit over an unmerged index is never fabricated; this job will not guess." >&2 - git merge --abort - exit 1 - fi - echo "heal: admitting the staged commit writer via gunbc.commit_workflow admit_commit_writer before writing" >&2 - "$(git rev-parse --show-toplevel 2>/dev/null || pwd)/target/release/gunbc" run --source-root dag --source-root src/v2 --entry dag/gunbc/commit_workflow.dag --function heal_admit - git commit --no-verify --no-edit >/dev/null - fi - SEED_AHEAD_AFTER="$(git rev-list HEAD.."$BUILT_FROM" -- src/v1)" - if [ -n "$SEED_AHEAD_AFTER" ]; then - echo "heal refused: still skewed after merging $BUILT_FROM" >&2 - echo " this arm should be unreachable — merging BUILT_FROM makes it an ancestor of HEAD, so the seed-ahead set is empty by construction. Reaching it means that invariant broke; do not re-run, investigate." >&2 - exit 1 - fi - echo "heal: remedy applied — tree now carries the binary's seed revision" >&2 - fi - echo "heal preflight: binary revision $BUILT_FROM carries no seed commits missing from this tree" - timeout-minutes: 5 - - name: Regenerate drifted generated artifacts (main_wet — writes each authority projection to the worktree) - run: | - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/tools/generated_artifact_gate.dag --function main_wet - timeout-minutes: 5 - - name: Commit + push auto-push-eligible regenerated artifacts (workflow paths are author-commit-required) - id: heal_commit_push - run: | - git config user.name "gunbc-ci-auto-heal" - git config user.email "gunbc-ci-auto-heal@users.noreply.github.com" - AUTHOR_COMMIT_DRIFT="" - if [ -e ".github/workflows/ci.yml" ] && ! git diff --quiet -- ".github/workflows/ci.yml"; then AUTHOR_COMMIT_DRIFT="$AUTHOR_COMMIT_DRIFT .github/workflows/ci.yml"; fi - if [ -e ".github/workflows/falsifier.yml" ] && ! git diff --quiet -- ".github/workflows/falsifier.yml"; then AUTHOR_COMMIT_DRIFT="$AUTHOR_COMMIT_DRIFT .github/workflows/falsifier.yml"; fi - if [ -e ".github/workflows/fleet-converge.yml" ] && ! git diff --quiet -- ".github/workflows/fleet-converge.yml"; then AUTHOR_COMMIT_DRIFT="$AUTHOR_COMMIT_DRIFT .github/workflows/fleet-converge.yml"; fi - echo "heal_author_commit_required=0" >> "$GITHUB_OUTPUT" - if [ -n "$AUTHOR_COMMIT_DRIFT" ]; then - rm -rf "heal-author-commit-required" - for p in $AUTHOR_COMMIT_DRIFT; do - if ! mkdir -p "heal-author-commit-required/$(dirname "$p")"; then echo "::error::HealRepairBundleIncomplete path=$p" >&2; exit 1; fi - if ! cp "$p" "heal-author-commit-required/$p"; then echo "::error::HealRepairBundleIncomplete path=$p" >&2; exit 1; fi - done - echo "heal_author_commit_required=1" >> "$GITHUB_OUTPUT" - fi - if [ -e ".gitignore" ]; then git add ".gitignore"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: .gitignore"; fi - if [ -e ".gitattributes" ]; then git add ".gitattributes"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: .gitattributes"; fi - if [ -e "ROADMAP.md" ]; then git add "ROADMAP.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: ROADMAP.md"; fi - if [ -e "DESIGN.md" ]; then git add "DESIGN.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: DESIGN.md"; fi - if [ -e ".githooks/pre-push" ]; then git add ".githooks/pre-push"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: .githooks/pre-push"; fi - if [ -e ".githooks/pre-commit" ]; then git add ".githooks/pre-commit"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: .githooks/pre-commit"; fi - if [ -e ".githooks/generated-artifact-merge" ]; then git add ".githooks/generated-artifact-merge"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: .githooks/generated-artifact-merge"; fi - if [ -e "dag/gunbc/stage0_crate_layout_generated.dag" ]; then git add "dag/gunbc/stage0_crate_layout_generated.dag"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: dag/gunbc/stage0_crate_layout_generated.dag"; fi - if [ -e "src/v1/stage0/src/bootstrap_stage0_crate_layout_generated.rs" ]; then git add "src/v1/stage0/src/bootstrap_stage0_crate_layout_generated.rs"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: src/v1/stage0/src/bootstrap_stage0_crate_layout_generated.rs"; fi - if [ -e "dag/gunbc/stage0_crate_partition_generated.dag" ]; then git add "dag/gunbc/stage0_crate_partition_generated.dag"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: dag/gunbc/stage0_crate_partition_generated.dag"; fi - if [ -e "dag/gunbc/stage0_emit_plan_generated.dag" ]; then git add "dag/gunbc/stage0_emit_plan_generated.dag"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: dag/gunbc/stage0_emit_plan_generated.dag"; fi - if [ -e "src/v1/stage0/src/v1_interpreter_dispatch_generated.rs" ]; then git add "src/v1/stage0/src/v1_interpreter_dispatch_generated.rs"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: src/v1/stage0/src/v1_interpreter_dispatch_generated.rs"; fi - if [ -e "docs/plans/idea-machine.md" ]; then git add "docs/plans/idea-machine.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/idea-machine.md"; fi - if [ -e "docs/plans/algebraic-rewrite-optimization.md" ]; then git add "docs/plans/algebraic-rewrite-optimization.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/algebraic-rewrite-optimization.md"; fi - if [ -e "docs/plans/dag-v2-defork-audit.md" ]; then git add "docs/plans/dag-v2-defork-audit.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/dag-v2-defork-audit.md"; fi - if [ -e "docs/plans/v2-self-hosting.md" ]; then git add "docs/plans/v2-self-hosting.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/v2-self-hosting.md"; fi - if [ -e "docs/plans/m5-fixture-store-consolidation.md" ]; then git add "docs/plans/m5-fixture-store-consolidation.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/m5-fixture-store-consolidation.md"; fi - if [ -e "docs/plans/model-realization-fork.md" ]; then git add "docs/plans/model-realization-fork.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/model-realization-fork.md"; fi - if [ -e "docs/plans/value-null-split.md" ]; then git add "docs/plans/value-null-split.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/value-null-split.md"; fi - if [ -e "docs/plans/ci-merge-freshness.md" ]; then git add "docs/plans/ci-merge-freshness.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/ci-merge-freshness.md"; fi - if [ -e "docs/plans/seed-debt-bundle-item-2.md" ]; then git add "docs/plans/seed-debt-bundle-item-2.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/seed-debt-bundle-item-2.md"; fi - if [ -e "docs/plans/axiom-syllogism-lens.md" ]; then git add "docs/plans/axiom-syllogism-lens.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/axiom-syllogism-lens.md"; fi - if [ -e "docs/plans/invert-hand-maintained.md" ]; then git add "docs/plans/invert-hand-maintained.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/invert-hand-maintained.md"; fi - if [ -e "docs/plans/fail-closed-lockdown.md" ]; then git add "docs/plans/fail-closed-lockdown.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/fail-closed-lockdown.md"; fi - if [ -e "docs/plans/format-model-reconciliation.md" ]; then git add "docs/plans/format-model-reconciliation.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/format-model-reconciliation.md"; fi - if [ -e "docs/plans/regime2-shared-emission-fold.md" ]; then git add "docs/plans/regime2-shared-emission-fold.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/regime2-shared-emission-fold.md"; fi - if [ -e "docs/plans/shell-emission-model.md" ]; then git add "docs/plans/shell-emission-model.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/shell-emission-model.md"; fi - if [ -e "docs/plans/construction-justification-rule.md" ]; then git add "docs/plans/construction-justification-rule.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/construction-justification-rule.md"; fi - if [ -e "docs/plans/emission-ingestion-inverse.md" ]; then git add "docs/plans/emission-ingestion-inverse.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/emission-ingestion-inverse.md"; fi - if [ -e "docs/plans/testgen-oracle.md" ]; then git add "docs/plans/testgen-oracle.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/testgen-oracle.md"; fi - if [ -e "docs/plans/disposition-carrier.md" ]; then git add "docs/plans/disposition-carrier.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/disposition-carrier.md"; fi - if [ -e "docs/plans/fold-ergonomics.md" ]; then git add "docs/plans/fold-ergonomics.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/fold-ergonomics.md"; fi - if [ -e "docs/plans/m4-universal-hermetic-corpus.md" ]; then git add "docs/plans/m4-universal-hermetic-corpus.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/m4-universal-hermetic-corpus.md"; fi - if [ -e "docs/plans/wiring-liveness-preflight.md" ]; then git add "docs/plans/wiring-liveness-preflight.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/wiring-liveness-preflight.md"; fi - if [ -e "docs/plans/interpreter-kernel-d.md" ]; then git add "docs/plans/interpreter-kernel-d.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/interpreter-kernel-d.md"; fi - if [ -e "docs/plans/inert-layer-lens.md" ]; then git add "docs/plans/inert-layer-lens.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/inert-layer-lens.md"; fi - if [ -e "docs/plans/compile-clean-forcecheck.md" ]; then git add "docs/plans/compile-clean-forcecheck.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/compile-clean-forcecheck.md"; fi - if [ -e "docs/plans/expressibility-frontier.md" ]; then git add "docs/plans/expressibility-frontier.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/expressibility-frontier.md"; fi - if [ -e "docs/plans/p1-where-clause-lowering.md" ]; then git add "docs/plans/p1-where-clause-lowering.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/p1-where-clause-lowering.md"; fi - if [ -e "docs/plans/intent-linearity-design-draft.md" ]; then git add "docs/plans/intent-linearity-design-draft.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/intent-linearity-design-draft.md"; fi - if [ -e "docs/plans/solve-higher-order-design.md" ]; then git add "docs/plans/solve-higher-order-design.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/solve-higher-order-design.md"; fi - if [ -e "docs/plans/language-target-self-host-frontier.md" ]; then git add "docs/plans/language-target-self-host-frontier.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/language-target-self-host-frontier.md"; fi - if [ -e "docs/plans/self-applying-lenses.md" ]; then git add "docs/plans/self-applying-lenses.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/self-applying-lenses.md"; fi - if [ -e "docs/plans/budget-tree.md" ]; then git add "docs/plans/budget-tree.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/budget-tree.md"; fi - if [ -e "docs/plans/cardinality-refinement.md" ]; then git add "docs/plans/cardinality-refinement.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/cardinality-refinement.md"; fi - if [ -e "docs/plans/compute-envelope-model.md" ]; then git add "docs/plans/compute-envelope-model.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/compute-envelope-model.md"; fi - if [ -e "docs/plans/input-envelope-roadmap.md" ]; then git add "docs/plans/input-envelope-roadmap.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/input-envelope-roadmap.md"; fi - if [ -e "docs/plans/ci-selection-vs-scheduling.md" ]; then git add "docs/plans/ci-selection-vs-scheduling.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/ci-selection-vs-scheduling.md"; fi - if [ -e "docs/plans/ci-process-end-to-end.md" ]; then git add "docs/plans/ci-process-end-to-end.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/ci-process-end-to-end.md"; fi - if [ -e "docs/plans/ci-oom-reclassification.md" ]; then git add "docs/plans/ci-oom-reclassification.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/ci-oom-reclassification.md"; fi - if [ -e "docs/plans/bounded-input-cost-envelope-scheduling.md" ]; then git add "docs/plans/bounded-input-cost-envelope-scheduling.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/bounded-input-cost-envelope-scheduling.md"; fi - if [ -e "docs/plans/ci-humming.md" ]; then git add "docs/plans/ci-humming.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/ci-humming.md"; fi - if [ -e "docs/plans/edge-b-rust-dag-provenance-brief.md" ]; then git add "docs/plans/edge-b-rust-dag-provenance-brief.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/edge-b-rust-dag-provenance-brief.md"; fi - if [ -e "docs/plans/resolver-type-name-collision-wall.md" ]; then git add "docs/plans/resolver-type-name-collision-wall.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/resolver-type-name-collision-wall.md"; fi - if [ -e "docs/plans/realization-measurement-loop.md" ]; then git add "docs/plans/realization-measurement-loop.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/realization-measurement-loop.md"; fi - if [ -e "docs/plans/host-effect-orchestration.md" ]; then git add "docs/plans/host-effect-orchestration.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/host-effect-orchestration.md"; fi - if [ -e "docs/plans/ci-floor-fractal-gantt.md" ]; then git add "docs/plans/ci-floor-fractal-gantt.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/ci-floor-fractal-gantt.md"; fi - if [ -e "docs/plans/resolver-pathology-profile-receipt.md" ]; then git add "docs/plans/resolver-pathology-profile-receipt.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/resolver-pathology-profile-receipt.md"; fi - if [ -e "docs/plans/representation-minimization.md" ]; then git add "docs/plans/representation-minimization.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/representation-minimization.md"; fi - if [ -e "docs/plans/reference-grounding-migration.md" ]; then git add "docs/plans/reference-grounding-migration.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/reference-grounding-migration.md"; fi - if [ -e "docs/plans/typescript-gap-census.md" ]; then git add "docs/plans/typescript-gap-census.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/typescript-gap-census.md"; fi - if [ -e "docs/plans/cli-run-hollowing-plan.md" ]; then git add "docs/plans/cli-run-hollowing-plan.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/cli-run-hollowing-plan.md"; fi - if [ -e "docs/plans/fleet-acceptance-criteria.md" ]; then git add "docs/plans/fleet-acceptance-criteria.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/fleet-acceptance-criteria.md"; fi - if [ -e "docs/plans/structural-quadratic-wall-coverage-audit.md" ]; then git add "docs/plans/structural-quadratic-wall-coverage-audit.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/structural-quadratic-wall-coverage-audit.md"; fi - if [ -e "docs/plans/ci-performance-tanking-evidence.md" ]; then git add "docs/plans/ci-performance-tanking-evidence.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/ci-performance-tanking-evidence.md"; fi - if [ -e "docs/plans/extdeps-modeling-preflight.md" ]; then git add "docs/plans/extdeps-modeling-preflight.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/extdeps-modeling-preflight.md"; fi - if [ -e "docs/plans/discrete-cost-derivation.md" ]; then git add "docs/plans/discrete-cost-derivation.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/discrete-cost-derivation.md"; fi - if [ -e "docs/plans/v2-complexity-capability-parity.md" ]; then git add "docs/plans/v2-complexity-capability-parity.md"; else echo "chore-heal: registered generated artifact absent on this tree, not staging: docs/plans/v2-complexity-capability-parity.md"; fi - PRIOR_HEAD=$(git rev-parse HEAD) - if git diff --cached --quiet; then - if [ -n "$AUTHOR_COMMIT_DRIFT" ]; then - echo "::error::HealAuthorCommitRequired head=$PRIOR_HEAD author_commit_paths=$AUTHOR_COMMIT_DRIFT cause=ActionsJobCredentialScopeUnavailable regen_command='gunbc run --source-root dag --source-root src/v2 --entry dag/tools/generated_artifact_gate.dag --function main_wet'" >&2 - exit 1 - fi - echo "HealNoChange head=$PRIOR_HEAD" - exit 0 - else - CHANGED_ARTIFACTS=$(git diff --cached --name-only) - git commit --no-verify -m "chore: regenerate drifted generated artifacts (ci auto-heal)" - HEALED_HEAD=$(git rev-parse HEAD) - git -c core.hooksPath= push origin HEAD:${{ github.head_ref || github.ref_name }} - echo "HealProduced prior_head=$PRIOR_HEAD healed_head=$HEALED_HEAD changed_artifacts=$CHANGED_ARTIFACTS" - ROOT=$(git rev-parse --show-toplevel) - if ! GUNBC_HEALED_HEAD="$HEALED_HEAD" GUNBC_HEAL_BRANCH_REF="${{ github.head_ref || github.ref_name }}" "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/tools/ci_heal_dispatch.dag --function main - then - echo "::error::HealDispatchRefused healed_head=$HEALED_HEAD cause=CreateWorkflowDispatchFailed" >&2 - exit 1 - fi - echo "SupersededByHealedHead prior_head=$PRIOR_HEAD healed_head=$HEALED_HEAD; revalidation-required" - if [ -n "$AUTHOR_COMMIT_DRIFT" ]; then - echo "::error::HealAuthorCommitRequired head=$HEALED_HEAD author_commit_paths=$AUTHOR_COMMIT_DRIFT cause=ActionsJobCredentialScopeUnavailable regen_command='gunbc run --source-root dag --source-root src/v2 --entry dag/tools/generated_artifact_gate.dag --function main_wet'" >&2 - fi - exit 1 - fi - env: - GITHUB_TOKEN: ${{ github.token }} - timeout-minutes: 5 - - name: Upload author-commit-required workflow repairs (the selected push credential cannot update .github/workflows/**) - uses: actions/upload-artifact@v4 - with: - name: heal-author-commit-required - path: heal-author-commit-required - if-no-files-found: error - include-hidden-files: true - retention-days: 7 - compression-level: 0 - if: always() && steps.heal_commit_push.outputs.heal_author_commit_required == '1' - timeout-minutes: 10 - fleet: - runs-on: [self-hosted, linux, arm64, srv1] - needs: [ci] - timeout-minutes: 70 - if: "!cancelled() && ((github.ref == 'refs/heads/main' && github.event_name == 'push' && needs.ci.result == 'success') || github.event_name == 'workflow_dispatch')" - permissions: - contents: write - id-token: write - concurrency: - group: srv1-dashboard-deploy - cancel-in-progress: false - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - ref: ${{ inputs.expected_healed_sha || github.sha }} - - name: Refuse a heal revalidation whose run subject or checkout does not name the expected healed SHA - run: | - EXPECTED_HEALED_SHA="${{ inputs.expected_healed_sha }}" - RUN_SUBJECT_HEAD="${{ github.sha }}" - if [ -n "$EXPECTED_HEALED_SHA" ]; then - ACTUAL_HEAD="$(git rev-parse HEAD)" - if ! [ "$RUN_SUBJECT_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: workflow run subject $RUN_SUBJECT_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - if ! [ "$ACTUAL_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: checkout head $ACTUAL_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - echo "heal revalidation preflight: checkout names expected healed head $EXPECTED_HEALED_SHA" - fi - - name: Download release-bins artifact - uses: actions/download-artifact@v4 - with: - name: release-bins - timeout-minutes: 10 - - name: Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed) - id: release_bins - run: | - # 🟡 dissolve-on: ci_release_bins_unpack_verify_script — concat-built foreign-executor (GitHub Actions run:) release-bins unpack + claim_executor --verify-build-artifacts runner; membership of verified paths is derived from gunbc.ci_release_bins, but the unpack/verify transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the unpack/verify runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - mkdir -p "$ROOT/target/release" - tar -xzf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" - rm -f "$ROOT/release-bins.tgz" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: WIF auth (OIDC -> fleet-cloud-convergence SA, access token only) - id: wif_auth - uses: google-github-actions/auth@v2 - with: - workload_identity_provider: projects/582015116396/locations/global/workloadIdentityPools/github-actions/providers/github-oidc - service_account: fleet-cloud-convergence@gunbai-secrets.iam.gserviceaccount.com - token_format: access_token - create_credentials_file: false - timeout-minutes: 5 - - name: Materialize fleet key in-run (SM versions/1 pinned -> RUNNER_TEMP 0600 -> ssh-agent -> wipe file) - run: | - # 🟡 dissolve-on: gunbc_ci_fleet_key_agent_script — concat-built foreign-executor (GitHub Actions run:) shell materializing the fleet automation key from Secret Manager versions/1 into an in-run ssh-agent; DISSOLVES WHEN the typed secret-materialization effect (SecretRef -> in-run agent, SECRET-VERSION-LIFECYCLE-0 machinery) lands on host_effect_apply and the step becomes an emitted typed effect - set -euo pipefail - umask 077 - KEY_FILE="$RUNNER_TEMP/fleet-automation-key" - AGENT_STARTED=0 - cleanup() { rm -f "$KEY_FILE"; if [ "$AGENT_STARTED" = 1 ] && [ -n "${SSH_AGENT_PID:-}" ]; then ssh-agent -k >/dev/null 2>&1 || true; fi; } - trap cleanup EXIT - curl -sSf -H "Authorization: Bearer $WIF_ACCESS_TOKEN" "https://secretmanager.googleapis.com/v1/projects/gunbai-secrets/secrets/fleet-automation-ssh-key/versions/1:access" | python3 -c 'import sys,json,base64; sys.stdout.buffer.write(base64.b64decode(json.load(sys.stdin)["payload"]["data"]))' > "$KEY_FILE" - chmod 600 "$KEY_FILE" - EXPECTED_FP="SHA256:mGT7qJsh36VsVb8OPh3m8br3oHedQHxRukRkW5P0CoQ" - OBSERVED_FP="$(ssh-keygen -y -f "$KEY_FILE" | ssh-keygen -lf - | awk '{print $2}')" - if [ "$OBSERVED_FP" != "$EXPECTED_FP" ]; then echo "ProbeCredentialIdentityMismatch: fetched secret versions/1 fingerprint $OBSERVED_FP != modeled $EXPECTED_FP; contacting NO host" >&2; exit 1; fi - eval "$(ssh-agent -s)" >/dev/null - AGENT_STARTED=1 - ssh-add "$KEY_FILE" 2>/dev/null - rm -f "$KEY_FILE" - trap - EXIT - echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> "$GITHUB_ENV" - echo "SSH_AGENT_PID=$SSH_AGENT_PID" >> "$GITHUB_ENV" - echo "fleet-key: agent loaded (identity fleet-automation@gunbc; secret versions/1 pinned; fingerprint verified against modeled authority; key file wiped)" - env: - WIF_ACCESS_TOKEN: ${{ steps.wif_auth.outputs.access_token }} - timeout-minutes: 5 - - name: Deploy dashboard to srv1 (live_deploy_apply_srv1_wet) - run: | - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/live_deploy/apply.dag --function live_deploy_apply_srv1_wet - if: github.event_name == 'push' - - name: Collect fleet converge receipts and fold the fleet verdict (collect_fleet_convergence_wet) - run: | - # 🟡 dissolve-on: gunbc_ci_collect_fleet_convergence_invoke — concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.fleet_receipt_collector collect_fleet_convergence_wet plus a cat of the typed collect receipt; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the step to orchestration emit over the typed gunbc.WitnessBin.Run route - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/fleet_receipt_collector.dag --function collect_fleet_convergence_wet - cat "$ROOT/target/fleet-converge-collect-receipt.txt" - if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: Advance refs/fleet/desired to the merged revision (CAS, floor-green only) - run: | - # 🟡 dissolve-on: gunbc_ci_advance_fleet_desired_script — concat-built foreign-executor (GitHub Actions run:) CAS ref advance (git ls-remote + push --force-with-lease onto gunbc.fleet_main_revision fleet_desired_ref_name); DISSOLVES WHEN the SCM ref-update realization lands as the typed git.Core CAS service op (membership-diff spine classify_change SCM-ref arm) invoked via host_effect_apply - set -eu - DESIRED_REF=refs/fleet/desired - CURRENT=$(git ls-remote origin "$DESIRED_REF" | cut -f1) - if [ -z "$CURRENT" ]; then - git push origin "$GITHUB_SHA:$DESIRED_REF" - echo "[fleet-desired] created $DESIRED_REF -> $GITHUB_SHA" - else - git push --force-with-lease="$DESIRED_REF:$CURRENT" origin "$GITHUB_SHA:$DESIRED_REF" - echo "[fleet-desired] advanced $DESIRED_REF: $CURRENT -> $GITHUB_SHA (CAS expected-prior held)" - fi - if: github.event_name == 'push' - timeout-minutes: 5 - - name: Fleet host-key scan (fleet_host_key_scan_wet; observation only, repairs nothing) - run: | - # 🟡 dissolve-on: gunbc_ci_fleet_host_key_scan_invoke — concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.fleet_host_key_enrollment fleet_host_key_scan_wet plus a cat of the typed scan receipt; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the step to orchestration emit over the typed gunbc.WitnessBin.Run route - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/fleet_host_key_enrollment.dag --function fleet_host_key_scan_wet - cat "$ROOT/target/fleet-host-key-scan-receipt.txt" - if: github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: Fleet host-key enrollment apply (fleet_host_key_enroll_wet; ssh-keygen -F readback) - run: | - # 🟡 dissolve-on: gunbc_ci_fleet_host_key_enroll_invoke — concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.fleet_host_key_enrollment fleet_host_key_enroll_wet plus a cat of the typed enroll receipt; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the step to orchestration emit over the typed gunbc.WitnessBin.Run route - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/fleet_host_key_enrollment.dag --function fleet_host_key_enroll_wet - cat "$ROOT/target/fleet-host-key-enroll-receipt.txt" - if: github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: Live fleet reach probe (probe_fleet_reach_wet; outcomes are data) - run: | - # 🟡 dissolve-on: gunbc_ci_fleet_reach_probe_invoke — concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.host_reach_identity_probe probe_fleet_reach_wet plus a cat of the typed receipt file; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the probe step to orchestration emit over the typed gunbc.WitnessBin.Run route - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/host_reach_identity_probe.dag --function probe_fleet_reach_wet - cat "$ROOT/target/fleet-reach-probe-receipt.txt" - if: github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: Read-only multi-principal fleet-key probe on srv3/srv4 (fleet_multi_principal_probe_wet; hostname + sudo -n -l; no writes) - run: | - # 🟡 dissolve-on: gunbc_ci_multi_principal_probe_invoke — concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.fleet_multi_principal_probe fleet_multi_principal_probe_wet plus a cat of the typed receipt; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the step to orchestration emit over the typed gunbc.WitnessBin.Run route - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/fleet_multi_principal_probe.dag --function fleet_multi_principal_probe_wet - cat "$ROOT/target/fleet-multi-principal-probe-receipt.txt" - if: github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: "Probe-identity observe (read-only: authorized_keys presence + runner GCP credential path)" - run: | - # 🟡 dissolve-on: gunbc_ci_probe_identity_observe_invoke — concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.fleet_probe_identity_observe fleet_probe_identity_observe_wet plus a cat of the typed receipt (READ-ONLY observation; no secret payloads); DISSOLVES WHEN bash-emit (#5828) binds the step to orchestration emit over the typed gunbc.WitnessBin.Run route - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/fleet_probe_identity_observe.dag --function fleet_probe_identity_observe_wet - cat "$ROOT/target/fleet-probe-identity-observe-receipt.txt" - if: github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: Fleet authorized-key self-enroll (public key, idempotent, runs as the runner account on THIS host) - run: | - # 🟡 dissolve-on: gunbc_ci_authorized_key_enroll_invoke — concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.fleet_host_key_enrollment fleet_authorized_key_self_enroll_wet plus a cat of the typed receipt (PUBLIC key only; idempotent exact-line enrollment); DISSOLVES WHEN bash-emit (#5828) binds the step to orchestration emit over the typed gunbc.WitnessBin.Run route - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/fleet_host_key_enrollment.dag --function fleet_authorized_key_self_enroll_wet - cat "$ROOT/target/fleet-authorized-key-enroll-receipt.txt" - if: github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: Read-only srv1 tasks pre-apply observation (observe_srv1_tasks_preapply_wet) - run: | - # 🟡 dissolve-on: gunbc_ci_srv1_tasks_observation_invoke — feature:task-count-measure-carrier sibling transport; concat-built foreign-executor (GitHub Actions run:) shell invoking gunbc run on gunbc.srv1_tasks_preapply_observation observe_srv1_tasks_preapply_wet plus a cat of the typed receipt file; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) binds the observation step to orchestration emit over the typed gunbc.WitnessBin.Run route without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/gunbc" run --source-root "$ROOT/dag" --source-root "$ROOT/src/v2" --entry dag/gunbc/srv1_tasks_preapply_observation.dag --function observe_srv1_tasks_preapply_wet - cat "$ROOT/target/srv1-tasks-preapply-receipt.txt" - if: github.event_name == 'workflow_dispatch' - timeout-minutes: 5 - - name: Kill the in-run ssh-agent (key never outlives the job) - run: | - if [ -n "${SSH_AGENT_PID:-}" ]; then ssh-agent -k || true; fi - if: always() - timeout-minutes: 5 diff --git a/.github/workflows/falsifier-alert.yml b/.github/workflows/falsifier-alert.yml deleted file mode 100644 index c776f1f4739..00000000000 --- a/.github/workflows/falsifier-alert.yml +++ /dev/null @@ -1,500 +0,0 @@ -# HAND-MAINTAINED INTERIM (unlike ci.yml/falsifier.yml, which are generated and -# drift-gated — gunbc.generated_artifact enumerates exactly those two artifacts). -# Purpose: the falsifier is the whole-corpus cold control — the only executor of -# the Gate-1 emit receipts and the verifier of per-PR affected-set selection — -# and it ran RED for 29 consecutive scheduled runs (2026-07-16..07-21) without -# any human noticing, because nothing consumed its conclusion (operator: "totally -# ambient/gets ignored unless a human literally goes to look at it"). This -# workflow makes falsifier state non-ambient: transition-to-red opens a labeled -# issue (notifying watchers), sustained red heartbeats at most daily, and -# transition-to-green closes it with a receipt. -# -# Every one of those is a COMMENT carrying the owner mention, because a mention -# notifies only when it is created and only an issue's first body write is a -# creation — see ALERT_MENTION below for the receipt on why the body alone was -# not enough. -# -# THAT PROPERTY HAS NO EXECUTING CONSUMER, and the gap is named rather than left -# implied. "Every notifying artifact carries the mention" is invisible to yaml -# linting and to this workflow's own green conclusion — the alert ran successfully -# for two days while notifying nobody — so it is exactly the class that wants a -# check. A hand-authored JS harness beside this file was written and then REMOVED -# (operator, 2026-08-06): every foreign-language artifact in this tree is emitted -# from .dag (.github/live-deploy-srv1-apply.sh is the pattern), so hand-authoring -# a second one here would add a hand-maintained realization rather than a scaffold -# — and the substrate route is not merely inconvenient, it is blocked at the same -# seam this file's own dissolve-on names: there is no workflow_run TRIGGER model -# (extdeps.github.workflow_runs models runs as an API resource, not a trigger) and -# gunbc.falsifier_workflow declares issues: none, so the alert's notifying -# artifacts are not substrate objects and no lens has a Node tree to read. -# The evidence the current shape is correct is therefore an unenrolled execution -# receipt, not a live control: run at authoring against 70b422f3c, the heartbeat, -# failing-set-changed, green-close and throttle-pagination scenarios all went RED -# and the open-issue-body scenario stayed green. Next-rung trigger: the dissolve-on -# below. When the alert becomes a typed effect row, these scenarios become ordinary -# .dag witnesses under dag/test/claim and the property stops being unenforced. -# -# The open issue describes the CURRENT failure, not the first one. Earlier this -# workflow wrote the body once at first red and thereafter only appended a -# throttled heartbeat comment, so the body — the thing a human actually reads — -# froze while the failure changed underneath it. Receipt: #7737 sat open for ~30h -# with a body describing a BudgetExceeded kill on witness_committed_is_fixed_point -# that had stopped occurring at 2026-08-03T17:53, while the live failure was -# WitnessRed on entirely different witnesses. Precisely: the alerting MECHANISM was -# working — the 2026-08-04T12:31 heartbeat comment does name the current failing set -# — so this is not missed alerting. What failed is that the two things a reader -# meets first, the title and the body, described a resolved failure, while the -# current one was only in a comment that may be up to 20h old and sits below the -# fold. Worse, the class transition itself never announced anything: BudgetExceeded -# -> WitnessRed is a different incident with a different remedy, and it was absorbed -# into an unchanged "Still red". An open issue reads as an accurate live description -# of the current state, so a stale one is worse than -# none. The body is therefore rewritten every red window (body edits do not -# notify, so this costs no noise), and the failing component/class set plus its -# failure class is carried as a signature: a red that CHANGES CLASS is a different incident from a -# red that persists, and it bypasses the comment throttle rather than being -# suppressed by it. -# -# It reports PER-COMPONENT state read from the floor's own receipt -# (gunbc.floor_component_receipt, uploaded by the falsifier job as -# floor-component-receipt), never inferred from the overall workflow conclusion. -# The earlier version read only run.conclusion and hardcoded one causal story for -# every failure — "affected-set cold control is dark, per-PR selection UNVERIFIED, -# Gate-1 receipts do not execute". On run 30509024051 all three clauses were false: -# the predict-only control concluded Done over 5217 witnesses and only the -# silent-pick gate failed. An overall-red composite that erases the green state of -# its completed children is a state-space conflation, and it misdirected triage -# every time it fired. A missing or unparseable receipt is reported as an explicit -# unknown; it never re-widens into the old claim. -# 🟡 dissolve-on: fold into gunbc.falsifier_workflow (dag/gunbc/falsifier_workflow.dag) -# when the workflow emit seam models workflow_run triggers + issue effects; the -# alert then becomes a typed effect row beside the batches it observes. -# -# THE ALERT DESCRIBES MAIN, AND ONLY MAIN. The issue is a live description of the -# corpus's state at the tip of main, so the run it reads must be a run OF main. -# The trigger carried no branch or event restriction and the job carried no guard, -# so any session branch could dispatch affected-set-falsifier by hand and its -# completion would rewrite the body, flip the signature, comment, or CLOSE the -# issue as green — reporting a branch's state as main's. That is not a noisy -# alert, it is a false one, and the failure is silent: nothing in the rendered -# body said which ref produced it, so a reader could not tell an overwritten -# window from a real transition. Receipt: three branch dispatches appeared among -# the last twelve runs of the observed window. -# -# The restriction is stated TWICE on purpose, and the two are not redundant. -# `branches:` filters delivery — the alert job never starts for a non-main run. -# The `if:` is the fail-closed backstop at the consuming end: if the trigger -# filter is ever widened, or a future trigger type is added beside workflow_run, -# the guard still refuses rather than letting a foreign ref reach the issue. The -# event allowlist is part of it — a schedule or a MAIN manual dispatch is the -# cadence this alert reports; a pull_request-driven run is a different subject. -# -# Both conditions are on the TRIGGERING run's own fields, never on the alert -# run's context: github.ref here is the default branch on every workflow_run -# delivery regardless of what ran, so guarding on it would pass unconditionally -# and read as a check while being none. -name: falsifier-alert -on: - workflow_run: - workflows: ["affected-set-falsifier"] - types: [completed] - branches: [main] -permissions: - issues: write - actions: read - contents: read -jobs: - alert: - runs-on: [self-hosted, linux, arm64] - timeout-minutes: 5 - if: >- - github.event.workflow_run.head_branch == 'main' && - (github.event.workflow_run.event == 'schedule' || - github.event.workflow_run.event == 'workflow_dispatch') - steps: - - name: Download floor component receipt (from the triggering run) - id: receipt - continue-on-error: true - uses: actions/download-artifact@v4 - with: - name: floor-component-receipt - run-id: ${{ github.event.workflow_run.id }} - github-token: ${{ secrets.GITHUB_TOKEN }} - path: receipt - - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const run = context.payload.workflow_run; - const conclusion = run.conclusion; // success | failure | cancelled | ... - if (conclusion !== 'success' && conclusion !== 'failure') { - core.info(`conclusion=${conclusion} — no alert action`); - return; - } - const label = 'falsifier-alert'; - // The single interim owner handle. It is deliberately ONE constant used - // by every notifying artifact rather than a literal repeated per call - // site: gunbc.falsifier_lane falsifier_lane_owner_roster_note records - // this mention as the only owner fact in the tree, and a second copy of - // it would be a second authority for that one fact. - // - // WHY IT IS ON THE COMMENTS AND NOT ONLY THE BODY: an @mention notifies - // when it is CREATED, and only the issue body's first write is a - // creation. Body edits send nothing (that is exactly why the rewrite - // above is safe to run every window), so an alert whose only mention - // lives in the body pings its recipient exactly once — at issue open — - // and then goes silent for the entire incident however long it runs and - // however many times the failing component/class set changes underneath - // it. Receipt: issue #7737 opened 2026-08-03 and carried four github-actions comments - // across the next two days (one heartbeat, three failing-set-changed); - // none of them contained a mention, so the sustained-red heartbeat this - // workflow's header describes as its whole purpose delivered no - // notification after the first one. The mention therefore belongs on - // every artifact that notifies, which is every comment. - const ALERT_MENTION = '@briansrls'; - // The provenance of the run is rendered, not assumed. The trigger - // filter and the job guard above already make a non-main run - // undeliverable, so these fields are not the check — they are what - // lets a READER verify the check held, and what makes the ref and - // head of any given window recoverable from the issue itself rather - // than by opening the run. head_sha is the one that carries triage - // weight: a red window is only comparable to another red window at a - // known head, and the issue previously recorded none. - const runLine = `[run ${run.id}](${run.html_url}) · \`${run.head_branch}\` @ \`${(run.head_sha || '').slice(0, 10)}\` · event \`${run.event}\` · started ${run.run_started_at} · conclusion **${conclusion}**`; - - // ---- read the floor's own per-component receipt ------------------- - // Absence is a NAMED state carrying its cause. It never becomes a - // claim about any component's state. - const EXPECTED_SCHEMA = 'floor-component-receipt/v1'; - function readReceipt() { - const path = 'receipt/floor-component-receipt.json'; - let raw; - try { - raw = fs.readFileSync(path, 'utf8'); - } catch (e) { - return { ok: false, cause: `receipt artifact not present (${e.code || e.message})` }; - } - let doc; - try { - doc = JSON.parse(raw); - } catch (e) { - return { ok: false, cause: `receipt present but unparseable (${e.message})` }; - } - if (doc.schema !== EXPECTED_SCHEMA) { - return { ok: false, cause: `receipt schema ${JSON.stringify(doc.schema)} != ${EXPECTED_SCHEMA}` }; - } - return { ok: true, doc }; - } - - function describeOutcome(c) { - if (c.outcome === 'timed_out') { - return `TimedOut (budget ${c.budget_ms}ms, elapsed ${c.elapsed_ms}ms)`; - } - if (c.outcome === 'refused') return `Refused — ${c.diagnostic}`; - if (c.outcome === 'failed') return `Failed — ${c.error}`; - if (c.outcome === 'skipped') return `Skipped — ${c.reason}`; - if (c.outcome === 'done') return 'Done'; - // The receipt's own arm for a component that reached no conclusion. - if (c.outcome === 'not_concluded') return 'reached no conclusion'; - return String(c.outcome); - } - - function componentReport(r) { - if (!r.ok) { - return [ - '**Per-component state: UNKNOWN.**', - '', - `Cause: ${r.cause}.`, - '', - 'No claim is made here about the affected-set cold control, the', - 'Gate-1 emit receipts, or the known-red accounting: without the', - 'receipt this alert cannot tell which component failed. Read the', - 'run log directly, and treat a persistently missing receipt as its', - 'own defect (the floor is meant to write one on every exit path).', - ].join('\n'); - } - const doc = r.doc; - const ctl = doc.affected_set_cold_control || {}; - // "unsuccessful" is not "failed": a Skipped batch never ran and a Refused - // one stopped deliberately. The receipt keeps those distinct, so the - // rendering must too. - const bad = Array.isArray(doc.unsuccessful_components) ? doc.unsuccessful_components : []; - const lines = []; - - if (ctl.state === 'present' && ctl.verified === true) { - const c = ctl.component || {}; - const n = typeof c.witnesses === 'number' ? c.witnesses.toLocaleString() : 'an unreported number of'; - lines.push(`**Affected-set cold control: GREEN** — concluded Done over ${n} witnesses.`); - lines.push('Per-PR affected-set selection IS verified by this run.'); - } else if (ctl.state === 'present') { - // A control that DID NOT RUN is not a control that FAILED. Both leave - // selection unverified — that stays fail-closed either way — but they - // have different remedies (restore the enrollment vs. fix the control), - // so labelling a Skipped control "RED" is a state-space conflation of - // exactly the kind this receipt exists to prevent. This arm sees Skipped - // once unreached components keep their planned identity (#7818): they - // resolve to present/unverified rather than collapsing to absent. - const c = ctl.component || {}; - const didNotRun = c.outcome === 'skipped' || c.outcome === 'not_concluded'; - lines.push(didNotRun - ? `**Affected-set cold control: DID NOT RUN** — ${describeOutcome(c)}.` - : `**Affected-set cold control: RED** — ${describeOutcome(c)}.`); - lines.push('Per-PR affected-set selection runs UNVERIFIED while this stands.'); - } else { - lines.push(`**Affected-set cold control: ${String(ctl.state || 'unknown').toUpperCase()}** — ${ctl.cause || 'no cause recorded'}.`); - lines.push('Per-PR affected-set selection is NOT verified by this run.'); - } - - lines.push(''); - if (bad.length === 0) { - lines.push('Every component concluded Done.'); - } else { - lines.push(`Component(s) that did not conclude Done — ${bad.length} of ${doc.component_count}:`); - for (const c of bad) { - lines.push(`- batch ${c.index} \`${c.label}\` — ${describeOutcome(c)}`); - } - } - const passed = (doc.component_count || 0) - bad.length; - lines.push(''); - lines.push(`Components that concluded Done: ${passed} of ${doc.component_count}.`); - return lines.join('\n'); - } - - // ---- failing component/class signature ------------------------------ - // The signature is what makes a red that CHANGED CLASS distinguishable - // from a red that merely persists. They are different incidents with - // different remedies (re-basis a dated ceiling vs. fix a witness vs. - // repair a runner), and the 20h heartbeat throttle below is keyed on it - // so a transition is never suppressed as "still red". - // - // IT IS NOT A FAILING *SET* AND NO LONGER CLAIMS TO BE. Its members are - // COMPONENTS — batch-grain rows — so two different witnesses failing - // inside one component are one member, and the prose says "failing - // component/class set" everywhere for that reason. Exact failing-witness - // identities are deliberately absent rather than approximated: the - // receipt does not carry them, and recovering them by parsing a - // component's diagnostic prose is the string-classification the receipt - // module already refuses at its seed boundary. That waits for typed - // witness identities on the receipt, not for a regex here. - // - // FAILURE_MODE IS PART OF THE KEY, and its absence was a real hole. The - // outcome tag alone is many-to-one over the floor's failure vocabulary: - // floor_component_outcome_of_failure_mode maps BOTH Infra and WitnessRed - // to `failed` (gunbc.floor_component_receipt records why — one is the - // fleet's fault, one is the witness owner's, and they route to different - // people). So an Infra -> WitnessRed transition — a change of owner, not - // just of symptom — produced a byte-identical signature and was absorbed - // into "still red, unchanged". The mode already rides on every emitted - // row, so keying on it costs nothing and closes that arm. - // - // Every part is derived from the receipt's own identities — never from - // rendered prose. An unreadable receipt gets its own signature carrying - // the cause: it is an unknown, never folded into any known failing - // component/class set. - function signatureOf(r) { - if (!r.ok) return `receipt-unavailable:${r.cause}`; - const bad = Array.isArray(r.doc.unsuccessful_components) - ? r.doc.unsuccessful_components : []; - if (bad.length === 0) return 'no-unsuccessful-components'; - return bad - .map((c) => { - // A row written before failure_mode was emitted, or one built - // through the tag constructor that genuinely never saw a mode, - // reads as an explicit unknown rather than being silently dropped - // from the key — dropping it would recreate the collapse above. - const mode = typeof c.failure_mode === 'string' && c.failure_mode !== '' - ? c.failure_mode - : 'mode-unrecorded'; - return `${c.index}:${c.label}:${mode}:${c.outcome}`; - }) - .sort() - .join('|'); - } - - // Prior state rides in the issue body as a marker, so no external store - // is needed and the issue stays the single authority for its own state. - // A body with no marker (an issue opened by the previous version of this - // workflow) yields null — an explicit unknown, which compares unequal to - // every real signature, so the first run after this lands rewrites the - // stale body instead of silently keeping it. - const STATE_RE = //; - // Legacy recovery: issues opened before the marker existed still carry a - // rendered "First red: ..." line, and that line is the ONLY record of when - // the incident started. Recovering it is not cosmetic — without it the - // rewrite below would stamp the CURRENT run as "First red", asserting - // something false in the body, which is the same class of defect this - // change exists to remove. If neither the marker nor the legacy line is - // present, the first red is reported as not recorded; it is never guessed. - const LEGACY_FIRST_RED_RE = /^First red: (.+)$/m; - function readState(body) { - const text = body || ''; - const m = STATE_RE.exec(text); - if (!m) { - const legacy = LEGACY_FIRST_RED_RE.exec(text); - return { first_red: legacy ? legacy[1].trim() : null, signature: null }; - } - try { - const s = JSON.parse(m[1]); - return { - first_red: typeof s.first_red === 'string' ? s.first_red : null, - signature: typeof s.signature === 'string' ? s.signature : null, - }; - } catch (e) { - const legacy = LEGACY_FIRST_RED_RE.exec(text); - return { first_red: legacy ? legacy[1].trim() : null, signature: null }; - } - } - - // Owner routing is REFUSED, not guessed. gunbc.falsifier_lane derives a - // lane for a failing component but its owner roster is honestly empty, - // and minting a @mention from a string in this file would fabricate a - // routing fact that no carrier grounds — a second authority for - // ownership living in workflow YAML. - // 🟡 dissolve-on: the owner grounding carrier lands; this block then - // renders the routed owner (or that carrier's own typed refusal). - const ROUTING = [ - '**Owner routing: REFUSED — no grounding carrier.**', - '', - 'The failing component(s) above are named, but no declared roster maps a', - 'falsifier lane to an owner, so this alert routes to nobody rather than', - 'guessing. Treat the missing roster as its own obligation.', - ].join('\n'); - - const receipt = readReceipt(); - const report = componentReport(receipt); - const signature = signatureOf(receipt); - - let titleSuffix; - if (!receipt.ok) { - titleSuffix = 'component receipt unavailable'; - } else { - const bad = receipt.doc.unsuccessful_components || []; - titleSuffix = bad.length === 1 - ? `${bad[0].label} (batch ${bad[0].index})` - : `${bad.length} of ${receipt.doc.component_count} components not Done`; - } - const title = `falsifier is RED — ${titleSuffix}`; - - const { data: open } = await github.rest.issues.listForRepo({ - owner: context.repo.owner, repo: context.repo.repo, - state: 'open', labels: label, per_page: 1, - }); - const existing = open[0]; - - if (conclusion === 'failure') { - const prior = readState(existing ? existing.body : null); - // The first-red line is a SNAPSHOT and is preserved verbatim across - // rewrites; "Current" is re-derived every window. Losing the former - // would discard when the incident started, keeping only the latter - // would leave the body describing a failure that no longer occurs — - // which is exactly the defect this fixes (#7737 sat for ~30h showing a - // BudgetExceeded story while the actual failure was five red witnesses). - // For a NEW issue this run genuinely is the first red. For an existing - // one it is not, so an unrecoverable first red is reported as unknown - // rather than back-filled with the current run. - const firstRed = existing - ? (prior.first_red || 'not recorded (issue predates state tracking)') - : runLine; - const state = JSON.stringify({ first_red: firstRed, signature }); - const body = [ - `${ALERT_MENTION} — the scheduled affected-set falsifier is RED.`, - '', - `First red: ${firstRed}`, - `Current: ${runLine}`, - '', - '## Current failing component/class set', - '', - report, - '', - '## Routing', - '', - ROUTING, - '', - 'This issue auto-closes when a scheduled run goes green. The body above', - 'is REWRITTEN every red window, so it always describes the current', - 'failure rather than the first one. Comments are throttled to at most', - 'every 20h while the failing component/class set and its failure class are', - 'unchanged; a', - 'change in either is a different incident and comments immediately.', - '', - ``, - ].join('\n'); - if (!existing) { - await github.rest.issues.create({ - owner: context.repo.owner, repo: context.repo.repo, - title, labels: [label], body, - }); - core.notice(`falsifier alert issue opened — signature ${signature}`); - } else { - // The body and title are rewritten on EVERY red window. Editing an - // issue body sends no notification, so this costs no noise and is - // deliberately not rate-limited: a stale-but-open issue reads as an - // accurate live description of the current failure, which is worse - // than no description at all. - await github.rest.issues.update({ - owner: context.repo.owner, repo: context.repo.repo, - issue_number: existing.number, title, body, - }); - - // Comments DO notify, so they stay throttled — except across a - // transition, which the throttle must not swallow. - const changed = prior.signature !== signature; - // Paginated deliberately. This endpoint returns comments oldest-first - // and accepts no sort/direction, so a single per_page=100 request - // returns the FIRST hundred: past that boundary `comments.length - 1` - // is the 100th comment, not the newest, and its age only grows — so - // the 20h throttle would silently invert into "heartbeat every run", - // turning the fix for a silent alert into an alert that spams. The - // throttle must read the actual newest comment or it is not a - // throttle. - const comments = await github.paginate(github.rest.issues.listComments, { - owner: context.repo.owner, repo: context.repo.repo, - issue_number: existing.number, per_page: 100, - }); - const last = comments[comments.length - 1]; - const lastTs = new Date(last ? last.created_at : existing.created_at).getTime(); - const heartbeatDue = Date.now() - lastTs > 20 * 3600 * 1000; - if (changed) { - const priorLine = prior.signature === null - ? 'not recorded (issue predates signature tracking)' - : `\`${prior.signature}\``; - await github.rest.issues.createComment({ - owner: context.repo.owner, repo: context.repo.repo, - issue_number: existing.number, - body: [ - `${ALERT_MENTION} — **the failing component/class set changed**; this is a different incident from the one first reported.`, - '', - `Previous: ${priorLine}`, - `Now: \`${signature}\``, - '', - `Latest: ${runLine}`, - '', - report, - ].join('\n'), - }); - core.notice(`falsifier failing component/class set changed: ${prior.signature} -> ${signature}`); - } else if (heartbeatDue) { - await github.rest.issues.createComment({ - owner: context.repo.owner, repo: context.repo.repo, - issue_number: existing.number, - body: `${ALERT_MENTION} — still red, unchanged failing component/class set. Latest: ${runLine}\n\n${report}`, - }); - } else { - core.info(`red, signature unchanged (${signature}) — body refreshed, comment throttled`); - } - } - } else if (existing) { - await github.rest.issues.createComment({ - owner: context.repo.owner, repo: context.repo.repo, - issue_number: existing.number, - // The clear is mentioned too. An incident that stops paging without - // saying it cleared leaves the recipient unable to tell "fixed" from - // "the alerting broke again" — the same ambiguity, one level up. - body: `${ALERT_MENTION} — GREEN again: ${runLine} — cold control restored; closing.\n\n${report}`, - }); - await github.rest.issues.update({ - owner: context.repo.owner, repo: context.repo.repo, - issue_number: existing.number, state: 'closed', - }); - core.notice('falsifier alert issue closed (green)'); - } diff --git a/.github/workflows/falsifier.yml b/.github/workflows/falsifier.yml deleted file mode 100644 index e7e039a576a..00000000000 --- a/.github/workflows/falsifier.yml +++ /dev/null @@ -1,381 +0,0 @@ -name: affected-set-falsifier -on: - workflow_dispatch: - schedule: - - cron: 0 0,4,8,12,16,20 * * * -permissions: - contents: read -concurrency: - group: affected-set-falsifier - cancel-in-progress: false -env: - CARGO_TERM_COLOR: always -jobs: - falsifier-build: - runs-on: [self-hosted, linux, arm64] - timeout-minutes: 65 - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - - name: Isolate toolchain dirs - run: | - rm -rf "$RUNNER_TEMP/rustup" "$RUNNER_TEMP/cargo" - echo "HOME=$RUNNER_TEMP" >> "$GITHUB_ENV" - echo "CARGO_HOME=$RUNNER_TEMP/cargo" >> "$GITHUB_ENV" - echo "RUSTUP_HOME=$RUNNER_TEMP/rustup" >> "$GITHUB_ENV" - echo "MAKEFLAGS=" >> "$GITHUB_ENV" - echo "CARGO_BUILD_JOBS=3" >> "$GITHUB_ENV" - if sccache --show-stats >/dev/null 2>&1; then - echo "RUSTC_WRAPPER=sccache" >> "$GITHUB_ENV" - echo "CARGO_INCREMENTAL=0" >> "$GITHUB_ENV" - printf '%s\n' "CiSccacheProviderReceipt: provider=bound catalog=sccache_local" - else - printf '%s\n' "CiSccacheProviderReceipt: provider=SKIPPED catalog=sccache_local host=$(hostname) cause=daemon-unavailable; the release build runs UNCACHED — a counted degradation, not a supported mode (host_build_cache_provision P1b should have converged this host)" - fi - - name: Setup Rust - uses: actions-rust-lang/setup-rust-toolchain@v1.16.0 - with: - components: rustfmt - cache: false - rustflags: '' - env: - HOME: ${{ runner.temp }} - - name: Derive native-cache root (rustc-version segment; after setup-rust-toolchain) - run: | - # 🟡 dissolve-on: ci_native_cache_root_script — orch-emitted foreign-executor prelude step deriving GUNBC_NATIVE_CACHE_ROOT from rustc -V after setup-rust-toolchain; leaf rustc/tr/mkdir/echo strings remain until typed toolchain probe lands on host_effect_apply (#5828 / shell→intent Phase 2) - if ! GUNBC_TOOLCHAIN_SEG_RAW=$(rustc -V 2>/dev/null); then echo "::error::rustc -V failed after setup-rust-toolchain: cannot derive native-cache toolchain segment"; exit 1; fi - GUNBC_TOOLCHAIN_SEG=$(echo "$GUNBC_TOOLCHAIN_SEG_RAW" | tr ' ' '-') - if [ -z "$GUNBC_TOOLCHAIN_SEG" ]; then echo "::error::rustc -V produced an empty native-cache toolchain segment after setup-rust-toolchain"; exit 1; fi - mkdir -p "$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" - echo "GUNBC_NATIVE_CACHE_ROOT=$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" >> "$GITHUB_ENV" - - name: Pin rustup default (isolated RUSTUP_HOME has no default toolchain) - run: | - rustup default "$(rustup show active-toolchain | awk '{print $1; exit}')" - if [ -x "$CARGO_HOME/bin/cargo" ]; then CARGO_BIN="$CARGO_HOME/bin/cargo"; else CARGO_BIN="$(command -v cargo || true)"; fi - if [ -z "$CARGO_BIN" ]; then echo "::error::no cargo binary: neither the isolated $CARGO_HOME/bin/cargo shim nor PATH carries one"; exit 1; fi - echo "CARGO_BIN=$CARGO_BIN" >> "$GITHUB_ENV" - - name: Cache Cargo - uses: actions/cache@v5 - with: - path: | - ${{ runner.temp }}/cargo/registry/index/ - ${{ runner.temp }}/cargo/registry/cache/ - ${{ runner.temp }}/cargo/git/db/ - target/ - key: cargo-ci-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/Cargo.lock', 'rust-toolchain.toml') }} - restore-keys: | - cargo-ci-${{ runner.os }}-${{ runner.arch }}- - - name: Build release bins (claim_executor + gunbc) - id: release_build - run: | - # 🟡 dissolve-on: ci_release_build_script — concat-built foreign-executor (GitHub Actions run:) release-build runner (ROOT stamp + verify-artifacts + sccache stats wrapping the orch-emitted EAGAIN retry core); membership of --bin / verify paths is derived from gunbc.ci_release_bins, but the runner transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the release-build runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - set -o pipefail - BUILD_LOG=$(mktemp) - if ! ("$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin floor_skip_discovery_witness --bin selection_control_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness) 2>&1 | tee "$BUILD_LOG"; then - if grep -qiE 'Resource temporarily unavailable|failed to spawn|sccache: encountered fatal error|(exit status: 254)|sccache: error: failed to execute compile' "$BUILD_LOG"; then - echo "::warning::cargo/sccache EAGAIN under fleet pressure; cold retry CARGO_BUILD_JOBS=1 (keep sccache)" - CARGO_BUILD_JOBS=1 "$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin floor_skip_discovery_witness --bin selection_control_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness - else - exit 1 - fi - fi - rm -f "$BUILD_LOG" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - sccache --show-stats 2>/dev/null || true - timeout-minutes: 45 - - name: Pack release bins for cross-job handoff (tar keeps exec bits) - run: | - # 🟡 dissolve-on: ci_release_bins_pack_script — concat-built foreign-executor (GitHub Actions run:) release-bins tar pack runner; membership of archived bin names is derived from gunbc.ci_release_bins, but the pack transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the pack runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - tar -czf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" "claim_executor" "gunbc" "regen_floor_skip_witness" "floor_skip_discovery_witness" "selection_control_skip_witness" "discover_source_root_ingest" "claim_batch" "regen_stage0" "interp_recorded_fixture_witness" "v1_src_dag_parse" "auth_declared_but_unwired_witness" "bootstrap_witness" "dag_collect_fingerprint_witness" "diagnostics_witness" "effects_rest_transport_witness" "infer_semantics_witness" "parse_witness" "resolution_divergence_census" "cssl_assemble" "frontier_probe_survey" "namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: Upload release-bins artifact - uses: actions/upload-artifact@v4 - with: - name: release-bins - path: release-bins.tgz - if-no-files-found: error - retention-days: 3 - compression-level: 0 - timeout-minutes: 10 - selection-control: - runs-on: [self-hosted, linux, arm64] - needs: [falsifier-build] - timeout-minutes: 35 - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - ref: ${{ inputs.expected_healed_sha || github.sha }} - - name: Refuse a heal revalidation whose run subject or checkout does not name the expected healed SHA - run: | - EXPECTED_HEALED_SHA="${{ inputs.expected_healed_sha }}" - RUN_SUBJECT_HEAD="${{ github.sha }}" - if [ -n "$EXPECTED_HEALED_SHA" ]; then - ACTUAL_HEAD="$(git rev-parse HEAD)" - if ! [ "$RUN_SUBJECT_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: workflow run subject $RUN_SUBJECT_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - if ! [ "$ACTUAL_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: checkout head $ACTUAL_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - echo "heal revalidation preflight: checkout names expected healed head $EXPECTED_HEALED_SHA" - fi - - name: Setup Rust (floor gate toolchain — batch-4 emit_host/self_host gates need cargo/rustfmt; no isolated rustup) - uses: actions-rust-lang/setup-rust-toolchain@v1.16.0 - with: - components: rustfmt - cache: false - rustflags: '' - - name: Derive native-cache root (rustc-version segment; after setup-rust-toolchain) - run: | - # 🟡 dissolve-on: ci_native_cache_root_script — orch-emitted foreign-executor prelude step deriving GUNBC_NATIVE_CACHE_ROOT from rustc -V after setup-rust-toolchain; leaf rustc/tr/mkdir/echo strings remain until typed toolchain probe lands on host_effect_apply (#5828 / shell→intent Phase 2) - if ! GUNBC_TOOLCHAIN_SEG_RAW=$(rustc -V 2>/dev/null); then echo "::error::rustc -V failed after setup-rust-toolchain: cannot derive native-cache toolchain segment"; exit 1; fi - GUNBC_TOOLCHAIN_SEG=$(echo "$GUNBC_TOOLCHAIN_SEG_RAW" | tr ' ' '-') - if [ -z "$GUNBC_TOOLCHAIN_SEG" ]; then echo "::error::rustc -V produced an empty native-cache toolchain segment after setup-rust-toolchain"; exit 1; fi - mkdir -p "$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" - echo "GUNBC_NATIVE_CACHE_ROOT=$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" >> "$GITHUB_ENV" - - name: Download release-bins artifact - uses: actions/download-artifact@v4 - with: - name: release-bins - timeout-minutes: 10 - - name: Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed) - id: release_bins - run: | - # 🟡 dissolve-on: ci_release_bins_unpack_verify_script — concat-built foreign-executor (GitHub Actions run:) release-bins unpack + claim_executor --verify-build-artifacts runner; membership of verified paths is derived from gunbc.ci_release_bins, but the unpack/verify transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the unpack/verify runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - mkdir -p "$ROOT/target/release" - tar -xzf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" - rm -f "$ROOT/release-bins.tgz" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: Affected-set selection control (floor_skip_discovery_witness) - run: | - # Affected-set-scoped selection-control admission (pull_request only) — the selection mechanism applied to itself. selection_control_skip_witness intersects the merge-base diff with the control suite's input closure (cli_run::selection_control_input_sources: the suite's declared .dag entries plus their import closure through [src/v2, dag], the src/v1/** prefix covering the selection implementation and the witness bin, the Cargo/toolchain build config, and EVERY markdown path). The markdown arm is not incidental: the suite's declared entry dag/test/claim/doc_reachability_witness_test.dag declares LiveTreeDisposition = ReadsLiveTree and folds the live doc graph (gunbc.doc_graph_roots.doc_graph_roots_all) to decide doc_graph_has_no_orphan_docs, asserting the orphan wall green against the REAL tree — so a .md add/edit/delete genuinely changes this suite's verdict, and a live-tree read is not an import edge, so no closure walk can discover that reach. It is a structural over-approximation computed AS the answer (DESIGN §5: a closure superset is the precision frontier), not a widening failure arm. Found by review 44682 on this PR, whose first draft skipped docs-only diffs while its green control asserted that skip. A PR diff touching none of those provably cannot change the suite's verdict, so the step exits 0 immediately. NOT circular: the skip decision is a coarse path/import-closure intersection, never the node-frontier selector the suite verifies, so a broken selector cannot suppress its own control. TWO KINDS OF ARM, and the difference is the whole fail-closed story. STRUCTURAL arms — empty diff, ANY departed path (no docs carve-out — deleting a doc is the direction the orphan/dangling wall is most sensitive to, and regen's/compile-clean's docs exemption is correct only because markdown is outside THEIR closures), any markdown path, and any closure intersection — are label-valued: the diff WAS observed, so the answer is computed, and the witness exits 0 printing run_selection_control. REFUSAL arms — diff-observation failure and input-closure failure — do NOT run the suite and do NOT print a label: they STOP THE LINE. The witness prints a typed, located, countable diagnostic (SELECTION_CONTROL_REFUSED cause=DiffObservationFailed or cause=InputClosureFailed) to stderr and exits NON-ZERO, so the step goes RED. That is DESIGN §5's rule that a failure arm must refuse, never widen: 'can't compute the affected set → rerun everything' is the named absorbing fallback, conflating ⊤-as-ignorance with ⊤-as-answer, and it fails open twice — the deficit's frequency is zeroed by construction so it never ranks for fixing, and the cost is denominated in the corpus rather than the change. It is also the ruling already recorded in floor_diff_baseline_law (src/v2/workflow/floor_diff_observe.dag): a BaselineRefused → NameStatusDiffFail HALTS with a typed AFFECTED-SET REFUSAL, refusing every enrolled row rather than widening to a full-corpus run (operator ruling 2026-07-05). Corrected here after review 44768 caught this note still claiming the failure arms ran the suite — a §3 single-authority violation, since the note is emitted into ci.yml and would have been the authoritative description of the opposite behaviour. TWO DISTINCT fail-closed mechanisms sit outside that, and they are not the same arm: (a) the witness exits 0 but prints anything other than the skip label — the string comparison fails and the suite runs; (b) the witness exits NON-zero — either a deliberate typed REFUSAL (the two computation-failure arms above) or a panic (e.g. the workspace chdir failing) — GitHub runs this step under bash -e, so the command substitution's failure aborts the step RED rather than falling through. (b) is deliberately unlike the regen precedent, which suppresses stderr and defaults with a shell fallback; here a crashing skip witness stops the line loudly instead of being papered over, and stderr is left unredirected so the witness's own typed explanation of WHICH arm fired lands in the job log. COLD CONTROL: the skip is gated to pull_request events via GITHUB_EVENT_NAME, so push-to-main and workflow_dispatch run the suite UNCONDITIONALLY. A wrong closure that lets a PR wrongly skip therefore surfaces on the very next merge to main (the one-merge acceptance window, the regen-skip shape). MEASURED BASIS, including the part that makes this a trade rather than a free win. The step costs 9m02s per PR (run 30482171871, job 90679506428) against the 80s local basis gunbc.ci_workflow's step note declares. The skip witness itself costs ~100s per invocation (three local runs: 100.0s, 100.3s, 103.1s), because selection_control_skip_label_for_ci observes the diff through cli_run::floor_git_diff_name_status_range, which resolves floor_diff_observe.dag with a COLD whole-pool index — that observation, not the closure walk, is essentially the whole 100s. So: a skipping PR pays ~100s instead of 542s (saves ~7m22s); a NON-skipping PR pays 542s + ~100s (a ~100s REGRESSION, stated because it is real). SKIP RATE, MEASURED AGAINST THE REAL CLOSURE (corrected 2026-07-29, third revision — read the correction history, it is the point): over the last 100 origin/main commits, 35 touch src/v1/**, 36 touch markdown, 1 touches Cargo/toolchain, and of the 36 that survive those arms, 13 intersect the suite's actual 391-file import closure. TRUE SKIP RATE 23 of 100, so expected value is about -25s/PR (0.23 x -442s + 0.77 x +100s) — roughly 1.2 percent of a 33.6-minute ci job. Two earlier claims in this note were WRONG and are superseded: -7.7 min/PR from an unmeasured 85 percent skip rate, then -4.3 min/PR from a partially-measured <=66 percent ceiling that extrapolated the src/v1/** prefix alone and had not yet counted markdown or the closure. Each is recorded rather than quietly replaced, because the drift this very note documents (an 80s basis left standing against a 542s reality) is the same failure mode. CONSEQUENCE, stated plainly: the cost win alone does NOT justify this scaffold's hand-Rust under DESIGN §6 (denominate the benefit in displaced cost). What ruins the mean is the ~100s cold diff observation — the 🟡 deficit below, paid twice per PR — not the mechanism; dissolve that and the same code is about -102s/PR at near-zero cost. The teardown removal (-11.2s every PR) and this note's own measured corrections stand independently of the skip. 🟡 dissolve-on: the ~100s diff observation is now paid TWICE per PR, once here and once by regen_floor_skip_witness in the regen job, and both pay it as a cold whole-pool index build in a fresh process. It dissolves with the same persistent content-keyed node store gunbc.ci_materialization's resolve-receipt note names as the terminal condition for the per-entry cold resolve class; until then the double payment is counted here rather than hidden, and the non-skipping regression above is its visible cost. - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - if [ "$GITHUB_EVENT_NAME" = pull_request ]; then - _ci_selection_skip="$("$ROOT/target/release/selection_control_skip_witness" )" - if [ "$_ci_selection_skip" = selection_control_not_affected_skip ]; then - echo "gunbc ci selection control: pull_request diff does not intersect the control suite's input closure — its verdict is provably unchanged; skipping (push-to-main runs it unconditionally as the cold control)" - exit 0 - fi - fi - "$ROOT/target/release/floor_skip_discovery_witness" - timeout-minutes: 15 - cold-corpus: - runs-on: [self-hosted, linux, arm64] - needs: [falsifier-build] - timeout-minutes: 285 - steps: - - name: Checkout - uses: actions/checkout@v5 - with: - fetch-depth: 0 - ref: ${{ inputs.expected_healed_sha || github.sha }} - - name: Refuse a heal revalidation whose run subject or checkout does not name the expected healed SHA - run: | - EXPECTED_HEALED_SHA="${{ inputs.expected_healed_sha }}" - RUN_SUBJECT_HEAD="${{ github.sha }}" - if [ -n "$EXPECTED_HEALED_SHA" ]; then - ACTUAL_HEAD="$(git rev-parse HEAD)" - if ! [ "$RUN_SUBJECT_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: workflow run subject $RUN_SUBJECT_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - if ! [ "$ACTUAL_HEAD" = "$EXPECTED_HEALED_SHA" ]; then - echo "::error::heal revalidation refused: checkout head $ACTUAL_HEAD does not equal expected healed head $EXPECTED_HEALED_SHA" - exit 1 - fi - echo "heal revalidation preflight: checkout names expected healed head $EXPECTED_HEALED_SHA" - fi - - name: Setup Rust (floor gate toolchain — batch-4 emit_host/self_host gates need cargo/rustfmt; no isolated rustup) - uses: actions-rust-lang/setup-rust-toolchain@v1.16.0 - with: - components: rustfmt - cache: false - rustflags: '' - - name: Derive native-cache root (rustc-version segment; after setup-rust-toolchain) - run: | - # 🟡 dissolve-on: ci_native_cache_root_script — orch-emitted foreign-executor prelude step deriving GUNBC_NATIVE_CACHE_ROOT from rustc -V after setup-rust-toolchain; leaf rustc/tr/mkdir/echo strings remain until typed toolchain probe lands on host_effect_apply (#5828 / shell→intent Phase 2) - if ! GUNBC_TOOLCHAIN_SEG_RAW=$(rustc -V 2>/dev/null); then echo "::error::rustc -V failed after setup-rust-toolchain: cannot derive native-cache toolchain segment"; exit 1; fi - GUNBC_TOOLCHAIN_SEG=$(echo "$GUNBC_TOOLCHAIN_SEG_RAW" | tr ' ' '-') - if [ -z "$GUNBC_TOOLCHAIN_SEG" ]; then echo "::error::rustc -V produced an empty native-cache toolchain segment after setup-rust-toolchain"; exit 1; fi - mkdir -p "$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" - echo "GUNBC_NATIVE_CACHE_ROOT=$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG" >> "$GITHUB_ENV" - - name: Download release-bins artifact - uses: actions/download-artifact@v4 - with: - name: release-bins - timeout-minutes: 10 - - name: Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed) - id: release_bins - run: | - # 🟡 dissolve-on: ci_release_bins_unpack_verify_script — concat-built foreign-executor (GitHub Actions run:) release-bins unpack + claim_executor --verify-build-artifacts runner; membership of verified paths is derived from gunbc.ci_release_bins, but the unpack/verify transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the unpack/verify runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - mkdir -p "$ROOT/target/release" - tar -xzf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" - rm -f "$ROOT/release-bins.tgz" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" - timeout-minutes: 5 - - name: Floor cgroup peak pre-read (calibration; reset if permitted) - run: | - # 🟡 dissolve-on: ci_cgroup_peak_locate_shell — foreign-executor (GitHub Actions run:) shell transport composing extdeps.linux.proc_self_cgroup unified-hierarchy membership (v2.extdeps.languages.bash_proc_self_cgroup) with std.path_intent NearestAncestorContaining dirname ascent (bash_orch_if). Procfs path is extdeps.linux.procfs ProcSelfCgroup. DISSOLVES WHEN shell→intent Phase 2 realizes cgroup membership plus path ascent on host_effect_apply / orchestration path arms without medium-as-string Run.command concat. - { _cg_bad=0; _cg_n=0; _cg_rel=""; while IFS= read -r _cg_line || [ -n "$_cg_line" ]; do _cg_trim=$(echo "$_cg_line" | sed -e 's/^ //' -e 's/ $//'); [ -z "$_cg_trim" ] && continue; case "$_cg_trim" in *:*:*) ;; *) _cg_bad=1; continue ;; esac; _cg_h=$(echo "$_cg_trim" | cut -d: -f1); _cg_ctl=$(echo "$_cg_trim" | cut -d: -f2); _cg_path=$(echo "$_cg_trim" | cut -d: -f3-); [ -z "$_cg_h" ] && _cg_bad=1; [ -z "$_cg_path" ] && _cg_bad=1; if [ "$_cg_h" = "0" ] && [ -z "$_cg_ctl" ]; then _cg_n=$((_cg_n + 1)); _cg_rel="$_cg_path"; fi; done < /proc/self/cgroup; [ "$_cg_bad" -eq 1 ] && { echo "[calibration] cgroup_membership=malformed" >&2; exit 1; }; [ "$_cg_n" -eq 0 ] && { echo "[calibration] cgroup_membership=missing" >&2; exit 1; }; [ "$_cg_n" -gt 1 ] && { echo "[calibration] cgroup_membership=ambiguous" >&2; exit 1; }; d="/sys/fs/cgroup$_cg_rel"; } || exit 1 - while [ -n "$d" ] && [ "$d" != "/sys/fs/cgroup" ] && ! [ -f "$d/memory.peak" ]; do d=$(dirname "$d"); done - if [ -f "$d/memory.peak" ]; then if echo reset > "$d/memory.peak" 2>/dev/null; then echo "[calibration] floor_peak_pre reset=ok scope=floor cgroup=$d"; else echo "[calibration] floor_peak_pre reset=unsupported pre_peak=$(cat "$d/memory.peak") scope=span cgroup=$d (post>pre attributes the peak to the floor exactly; post==pre means floor peak <= pre, a job-scoped upper bound)"; fi; else echo "[calibration] floor_peak_pre scope=unavailable (no memory.peak ancestor)"; fi - timeout-minutes: 5 - - name: affected-set falsifier (predict-only cold run) - id: floor - run: | - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/claim_executor" --source-root dag --source-root src/v2 --plan-entry src/v2/workflow/ci_floor_plan.dag --plan-function gunbc_falsifier_plan - env: - GUNBC_CI_DIFF_BASE: HEAD~20 - GUNBC_CI_DIFF_HEAD: HEAD - GUNBC_FLOOR_PHASE_JOURNAL: target/floor-phase-journal.tsv - timeout-minutes: 170 - - name: Upload floor component receipt (read by falsifier-alert) - uses: actions/upload-artifact@v4 - with: - name: floor-component-receipt - path: target/floor-component-receipt.json - if-no-files-found: error - retention-days: 30 - compression-level: 0 - if: always() - timeout-minutes: 10 - - name: Upload floor phase journal (survives killed floor) - uses: actions/upload-artifact@v4 - with: - name: floor-phase-journal - path: target/floor-phase-journal.tsv - if-no-files-found: warn - retention-days: 30 - compression-level: 0 - if: always() - timeout-minutes: 10 - - name: Upload floor receipts (TSV authority for cost/drift rows) - uses: actions/upload-artifact@v4 - with: - name: floor-receipts - path: target/floor-* - if-no-files-found: warn - retention-days: 14 - if: always() - timeout-minutes: 5 - - name: compile-clean whole-tree cold control (scoped-PR admission counterpart) - run: | - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/claim_executor" --source-root dag --source-root src/v2 --plan-entry src/v2/workflow/ci_floor_plan.dag --plan-function gunbc_ci_plan_artifact_plan - env: - GUNBC_CI_COMPILE_CLEAN_COLD_CONTROL: 1 - if: always() && !cancelled() && steps.release_bins.outcome == 'success' - timeout-minutes: 30 - - name: native-cache cold control (warm-tier admission counterpart) - run: | - ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - "$ROOT/target/release/claim_executor" --source-root dag --source-root src/v2 --plan-entry src/v2/workflow/ci_floor_plan.dag --plan-function gunbc_falsifier_native_cache_cold_plan - env: - GUNBC_CI_NATIVE_CACHE_COLD_CONTROL: 1 - if: always() && !cancelled() && steps.release_bins.outcome == 'success' - timeout-minutes: 30 - - name: Floor cgroup peak post-read (calibration; survives a killed floor) - run: | - # 🟡 dissolve-on: ci_floor_phase_journal_if — bounded foreign-executor (GitHub Actions run:) shell transport for exactly four journal leaves: FileExists, column-name log, row-count summary log, and absent log. If/else control flow is already v2.std.orchestration intent; only those leaves remain medium-as-string Run.command values. DISSOLVES WHEN bash-emit (#5828 / ROADMAP shell-effectplan-to-bash / shell→intent Phase 2) binds typed filesystem observation plus diagnostic-log operations through host_effect_apply, so ci_floor_phase_journal_if contains no opaque shell command text. - if [ -f "$GUNBC_FLOOR_PHASE_JOURNAL" ]; then - echo "[floor-phase-journal] columns: unix_millis pid phase state detail" - echo "[floor-phase-journal] $(wc -l < $GUNBC_FLOOR_PHASE_JOURNAL) rows retained; full journal in the floor-phase-journal artifact" - else - echo "[floor-phase-journal] absent" - fi - # 🟡 dissolve-on: ci_floor_wet_witness_row_outcome_receipt_if — bounded foreign-executor (GitHub Actions run:) shell transport for exactly four receipt leaves: FileExists, column-name log, row-count summary log, and absent log. DISSOLVES WHEN bash-emit (#5828 / ROADMAP shell-effectplan-to-bash / shell→intent Phase 2) binds typed filesystem observation plus diagnostic-log operations through host_effect_apply, so ci_floor_wet_witness_row_outcome_receipt_if contains no opaque shell command text. - if [ -f "target/floor-wet-witness-row-outcome-receipt.tsv" ]; then - echo "[wet-witness-row-outcome-receipt] columns: batch entry function outcome detail" - echo "[wet-witness-row-outcome-receipt] $(wc -l < target/floor-wet-witness-row-outcome-receipt.tsv) rows; full receipt in the floor-component-receipt artifact" - else - echo "[wet-witness-row-outcome-receipt] absent" - fi - # 🟡 dissolve-on: ci_cgroup_peak_locate_shell — foreign-executor (GitHub Actions run:) shell transport composing extdeps.linux.proc_self_cgroup unified-hierarchy membership (v2.extdeps.languages.bash_proc_self_cgroup) with std.path_intent NearestAncestorContaining dirname ascent (bash_orch_if). Procfs path is extdeps.linux.procfs ProcSelfCgroup. DISSOLVES WHEN shell→intent Phase 2 realizes cgroup membership plus path ascent on host_effect_apply / orchestration path arms without medium-as-string Run.command concat. - { _cg_bad=0; _cg_n=0; _cg_rel=""; while IFS= read -r _cg_line || [ -n "$_cg_line" ]; do _cg_trim=$(echo "$_cg_line" | sed -e 's/^ //' -e 's/ $//'); [ -z "$_cg_trim" ] && continue; case "$_cg_trim" in *:*:*) ;; *) _cg_bad=1; continue ;; esac; _cg_h=$(echo "$_cg_trim" | cut -d: -f1); _cg_ctl=$(echo "$_cg_trim" | cut -d: -f2); _cg_path=$(echo "$_cg_trim" | cut -d: -f3-); [ -z "$_cg_h" ] && _cg_bad=1; [ -z "$_cg_path" ] && _cg_bad=1; if [ "$_cg_h" = "0" ] && [ -z "$_cg_ctl" ]; then _cg_n=$((_cg_n + 1)); _cg_rel="$_cg_path"; fi; done < /proc/self/cgroup; [ "$_cg_bad" -eq 1 ] && { echo "[calibration] cgroup_membership=malformed" >&2; exit 1; }; [ "$_cg_n" -eq 0 ] && { echo "[calibration] cgroup_membership=missing" >&2; exit 1; }; [ "$_cg_n" -gt 1 ] && { echo "[calibration] cgroup_membership=ambiguous" >&2; exit 1; }; d="/sys/fs/cgroup$_cg_rel"; } || exit 1 - while [ -n "$d" ] && [ "$d" != "/sys/fs/cgroup" ] && ! [ -f "$d/memory.peak" ]; do d=$(dirname "$d"); done - if [ -f "$d/memory.peak" ]; then echo "[calibration] floor_peak_post=$(cat "$d/memory.peak") floor_outcome=${{ steps.floor.outcome }} cgroup=$d (observation label: floor_outcome=success is an EXACT point; any other outcome is a CENSORED lower bound - the process was killed while exceeding the read, so true demand is strictly greater. scope per the floor_peak_pre line: reset=ok means this IS the floor peak; scope=span compares against pre_peak)"; else echo "[calibration] floor_peak_post floor_outcome=${{ steps.floor.outcome }} scope=unavailable (no memory.peak ancestor)"; fi - env: - GUNBC_FLOOR_PHASE_JOURNAL: target/floor-phase-journal.tsv - if: always() - timeout-minutes: 5 - aggregate-verdict: - runs-on: [self-hosted, linux, arm64] - needs: [falsifier-build, selection-control, cold-corpus] - timeout-minutes: 20 - if: always() && !cancelled() - steps: - - name: Download floor component receipt (cold-corpus execution witness) - id: floor_component_receipt_download - uses: actions/download-artifact@v4 - with: - name: floor-component-receipt - path: target - continue-on-error: true - timeout-minutes: 10 - - name: Aggregate falsifier cadence verdict (typed cold-corpus execution) - id: aggregate_verdict - run: | - # 🟡 dissolve-on: falsifier_aggregate_verdict_script — concat-built foreign-executor (GitHub Actions run:) aggregate cadence verdict shell; receipt JSON literals are derived from gunbc.falsifier_cold_corpus_execution classify_cold_corpus_execution / cold_corpus_execution_receipt_json, but the transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the aggregate verdict step through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold - set -euo pipefail - mkdir -p target - BUILD_RESULT="${{ needs.falsifier-build.result }}" - SELECTION_RESULT="${{ needs.selection-control.result }}" - COLD_RESULT="${{ needs.cold-corpus.result }}" - if [ "${BUILD_RESULT}" = "cancelled" ]; then - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-not-run\",\"cause\":\"build-job-cancelled\"}" > target/falsifier-cold-corpus-execution.json - printf '%s\n' "::error::Cold corpus did not run — build cancelled; infrastructure, not a falsifier regression finding" - exit 1 - fi - if [ "${BUILD_RESULT}" = "skipped" ]; then - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-not-run\",\"cause\":\"build-job-skipped\"}" > target/falsifier-cold-corpus-execution.json - printf '%s\n' "::error::Cold corpus did not run — build skipped; infrastructure, not a falsifier regression finding" - exit 1 - fi - if [ "${BUILD_RESULT}" != "success" ]; then - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-not-run\",\"cause\":\"build-job-failed\"}" > target/falsifier-cold-corpus-execution.json - printf '%s\n' "::error::Cold corpus did not run — build unavailable (${BUILD_RESULT}); infrastructure, not a falsifier regression finding" - exit 1 - fi - if [ "${COLD_RESULT}" = "skipped" ]; then - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-not-run\",\"cause\":\"cold-corpus-job-skipped\",\"blocking_job\":\"cold-corpus\"}" > target/falsifier-cold-corpus-execution.json - printf '%s\n' "::error::Cold corpus skipped despite successful build — topology violation" - exit 1 - fi - if [ "${COLD_RESULT}" = "cancelled" ]; then - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-not-run\",\"cause\":\"cold-corpus-job-cancelled\"}" > target/falsifier-cold-corpus-execution.json - printf '%s\n' "::error::Cold corpus cancelled — environment unavailability" - exit 1 - fi - FLOOR_RECEIPT_PRESENT=false - if [ -f target/floor-component-receipt.json ] && grep -q floor-component-receipt/v1 target/floor-component-receipt.json; then - FLOOR_RECEIPT_PRESENT=true - fi - if [ "${FLOOR_RECEIPT_PRESENT}" != true ]; then - if [ "${COLD_RESULT}" = "success" ]; then - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-not-run\",\"cause\":\"cold-corpus-receipt-artifact-absent\"}" > target/falsifier-cold-corpus-execution.json - printf '%s\n' "::error::Cold corpus succeeded but floor-component receipt artifact absent — transport or emit failure, not a falsifier regression finding" - exit 1 - fi - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-not-run\",\"cause\":\"cold-corpus-failed-before-receipt\"}" > target/falsifier-cold-corpus-execution.json - printf '%s\n' "::error::Cold corpus did not produce floor-component receipt (cold=${COLD_RESULT}) — infrastructure, not a falsifier regression finding" - exit 1 - fi - printf '%s\n' "{\"schema\":\"falsifier-cold-corpus-execution/v1\",\"execution\":\"corpus-executed\",\"receipt_path\":\"target/floor-component-receipt.json\"}" > target/falsifier-cold-corpus-execution.json - if [ "${SELECTION_RESULT}" != "success" ] || [ "${COLD_RESULT}" != "success" ]; then - printf '%s\n' "::error::Falsifier cadence red — selection=${SELECTION_RESULT} cold=${COLD_RESULT} (corpus executed; see target/falsifier-cold-corpus-execution.json)" - exit 1 - fi - printf '%s\n' "FalsifierCadenceVerdict: cadence-green" - timeout-minutes: 5 diff --git a/.github/workflows/fleet-converge.yml b/.github/workflows/fleet-converge.yml index ea36eba235a..a7f7fd1b094 100644 --- a/.github/workflows/fleet-converge.yml +++ b/.github/workflows/fleet-converge.yml @@ -84,23 +84,23 @@ jobs: ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) set -o pipefail BUILD_LOG=$(mktemp) - if ! ("$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin floor_skip_discovery_witness --bin selection_control_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness) 2>&1 | tee "$BUILD_LOG"; then + if ! ("$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness) 2>&1 | tee "$BUILD_LOG"; then if grep -qiE 'Resource temporarily unavailable|failed to spawn|sccache: encountered fatal error|(exit status: 254)|sccache: error: failed to execute compile' "$BUILD_LOG"; then echo "::warning::cargo/sccache EAGAIN under fleet pressure; cold retry CARGO_BUILD_JOBS=1 (keep sccache)" - CARGO_BUILD_JOBS=1 "$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin floor_skip_discovery_witness --bin selection_control_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness + CARGO_BUILD_JOBS=1 "$CARGO_BIN" build -p v1-compiler --release --features text_lookup_work_counter,interp_test_witness,test_hooks --bin claim_executor --bin gunbc --bin regen_floor_skip_witness --bin discover_source_root_ingest --bin claim_batch --bin regen_stage0 --bin interp_recorded_fixture_witness --bin v1_src_dag_parse --bin auth_declared_but_unwired_witness --bin bootstrap_witness --bin dag_collect_fingerprint_witness --bin diagnostics_witness --bin effects_rest_transport_witness --bin infer_semantics_witness --bin parse_witness --bin resolution_divergence_census --bin cssl_assemble --bin frontier_probe_survey --bin namespace_structural_root_exposure_generated_witness else exit 1 fi fi rm -f "$BUILD_LOG" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" + "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" sccache --show-stats 2>/dev/null || true timeout-minutes: 45 - name: Pack release bins for cross-job handoff (tar keeps exec bits) run: | # 🟡 dissolve-on: ci_release_bins_pack_script — concat-built foreign-executor (GitHub Actions run:) release-bins tar pack runner; membership of archived bin names is derived from gunbc.ci_release_bins, but the pack transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the pack runner through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) - tar -czf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" "claim_executor" "gunbc" "regen_floor_skip_witness" "floor_skip_discovery_witness" "selection_control_skip_witness" "discover_source_root_ingest" "claim_batch" "regen_stage0" "interp_recorded_fixture_witness" "v1_src_dag_parse" "auth_declared_but_unwired_witness" "bootstrap_witness" "dag_collect_fingerprint_witness" "diagnostics_witness" "effects_rest_transport_witness" "infer_semantics_witness" "parse_witness" "resolution_divergence_census" "cssl_assemble" "frontier_probe_survey" "namespace_structural_root_exposure_generated_witness" + tar -czf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" "claim_executor" "gunbc" "regen_floor_skip_witness" "discover_source_root_ingest" "claim_batch" "regen_stage0" "interp_recorded_fixture_witness" "v1_src_dag_parse" "auth_declared_but_unwired_witness" "bootstrap_witness" "dag_collect_fingerprint_witness" "diagnostics_witness" "effects_rest_transport_witness" "infer_semantics_witness" "parse_witness" "resolution_divergence_census" "cssl_assemble" "frontier_probe_survey" "namespace_structural_root_exposure_generated_witness" timeout-minutes: 5 - name: Upload release-bins artifact uses: actions/upload-artifact@v4 @@ -137,7 +137,7 @@ jobs: mkdir -p "$ROOT/target/release" tar -xzf "$ROOT/release-bins.tgz" -C "$ROOT/target/release" rm -f "$ROOT/release-bins.tgz" - "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/floor_skip_discovery_witness" "$ROOT/target/release/selection_control_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" + "$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc" "$ROOT/target/release/regen_floor_skip_witness" "$ROOT/target/release/discover_source_root_ingest" "$ROOT/target/release/claim_batch" "$ROOT/target/release/regen_stage0" "$ROOT/target/release/interp_recorded_fixture_witness" "$ROOT/target/release/v1_src_dag_parse" "$ROOT/target/release/auth_declared_but_unwired_witness" "$ROOT/target/release/bootstrap_witness" "$ROOT/target/release/dag_collect_fingerprint_witness" "$ROOT/target/release/diagnostics_witness" "$ROOT/target/release/effects_rest_transport_witness" "$ROOT/target/release/infer_semantics_witness" "$ROOT/target/release/parse_witness" "$ROOT/target/release/resolution_divergence_census" "$ROOT/target/release/cssl_assemble" "$ROOT/target/release/frontier_probe_survey" "$ROOT/target/release/namespace_structural_root_exposure_generated_witness" timeout-minutes: 5 - name: WIF auth (OIDC -> fleet-cloud-convergence SA, access token only) id: wif_auth diff --git a/dag/gunbc/accelerator_demo_plan.dag b/dag/gunbc/accelerator_demo_plan.dag index 4ceb9fb156c..bf6a08fdc64 100644 --- a/dag/gunbc/accelerator_demo_plan.dag +++ b/dag/gunbc/accelerator_demo_plan.dag @@ -137,8 +137,7 @@ fn demo_plan_fused_op_count(plan: RealizationPlan) -> Int { Present { value: runnable } => match runnable { RunnableKernelWorkload { fused_op_count: count } => count RunnableSingleClaim { entry: _, function: _, profile: _ } => 0 - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => 0 - RunnableScopedWitnessBatch { batch: _ } => 0 + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => 0 } } } diff --git a/dag/gunbc/ci_layer_roots.dag b/dag/gunbc/ci_layer_roots.dag index 0a32f2cdfa1..81d80d2c26d 100644 --- a/dag/gunbc/ci_layer_roots.dag +++ b/dag/gunbc/ci_layer_roots.dag @@ -3,13 +3,8 @@ module gunbc.ci_layer_roots import std.realization_schedule { ScheduleWitnessEntry, ExecutionWitnessKind, CorpusWitnessKind, schedule_witness_entry_eq, schedule_witness_entry_roster_contains, - ScopedWitnessBatch, ScopedWitnessBatchId, ScopedWitnessBatchResourceProfile, - RunnableBatchClamp, SequentialChildProcess, SelectionApplied, - scoped_witness_batch, runnable_resource_profile, runnable_memory_substantial, } import std.execution_mode { Hermetic } -import std.measure { second, millisecond } -import std.decl_ref { decl_ref } import gunbc.cli_invoke { source_roots_shell_flags, SourceRootBare, @@ -425,11 +420,6 @@ data witness_exclusion_frontier: List = [ classification: BinWitnessWet, reason: excl_bin_wet_reason, dissolution: excl_bin_wet_dissolve}, - WitnessExclusionRow { - pattern: "floor_skip_discovery_witness_test.dag", - classification: FalsifierRehomedBinWet, - reason: excl_rehomed_bin_wet_reason, - dissolution: excl_rehomed_bin_wet_dissolve}, WitnessExclusionRow { pattern: "atom_body_discriminator_witness_test.dag", classification: FalsifierSubstrateLongLane, @@ -527,12 +517,6 @@ data witness_exclusion_frontier: List = [ classification: BinWitnessWet, reason: excl_bin_wet_reason, dissolution: excl_bin_wet_dissolve}, - WitnessExclusionRow { - pattern: "test/fixture/floor_skip/", - classification: FixtureExplicitRoster, - reason: "floor_skip control fixtures at dir grain: driven by floor_skip_discovery_witness explicit rosters, never corpus witnesses (floor_skip_control_fixture_exclusion_note, witness_admission_fixture_note)", - dissolution: unbound_dissolution(description: "fixture-home policy changes (witness_admission_fixture_note); row deletes") - }, WitnessExclusionRow { pattern: "test/fixture/walk_plan_stage/", classification: FixtureExplicitRoster, @@ -895,7 +879,7 @@ Local recipe: gunbc run --source-root src/v2 --source-root dag --entry src/v2/wo Dissolve-on: the crate-layout artifact moves to host-driven generation with the index supplied at the boundary — then the hand rows, the parity witness, and this exclusion delete together." -data witness_admission_fixture_note: String = "Phase 0(b): floor_skip control fixtures excluded at dir grain — consumers are explicit rosters in floor_skip_discovery_witness, not the discovery corpus. Dissolves when fixture-home policy changes." +data witness_admission_fixture_note: String = "Phase 0(b) admitted control fixtures excluded from tree-wide discovery at dir grain: their consumers are explicit rosters, never the discovery corpus. The floor_skip fixture home was deleted with affected-set selection itself (the rows it controlled no longer exist); walk_plan_stage remains. Dissolves when fixture-home policy changes." data known_red_probe_note: String = "Phase 0(b) quarantine probe cadence (module-identity-storage-binding): known-red frontier witnesses that EXPECT RED on main — the falsifier probe batch runs them SelectionApplied; greening is a counted un-quarantine event (per-row dissolve_on on the authority). Distinct from falsifier_self_host_wet (green-only SelfEmitted receipts). SINGLE AUTHORITY (2026-08-03): the rows live at function grain in gunbc.explicit_witness_admission explicit_witness_admissions and BOTH consumers derive from them — this roster is the falsifier batch's projection, and v2.workflow.floor_discovery_producer drops exactly the same (entry, function) pairs from per-PR discovery. The former shape was a dual representation: a QuarantineProbeExpectRed WitnessExclusionRow removing the whole FILE plus a probe_red(entry, f) row enrolling one FUNCTION, reconciled by a check instead of by construction. Those pattern rows are deleted; a pattern row that re-states a quarantine is now refused by witness_exclusion_row_well_formed." @@ -939,76 +923,8 @@ fn bin_wet(entry: String, f: String) -> ScheduleWitnessEntry { ScheduleWitnessEntry { entry: entry, function: f, kind: ExecutionWitnessKind } } -type V1ClaimScopedWitnessDissolutionTrigger - = V2ParserOwnsV1Claims {} - -data v1_claim_scoped_witness_dissolve_on: List = [ - V2ParserOwnsV1Claims {}, -] - -data v1_claim_scoped_witness_dissolve_on_note: String = "When V2ParserOwnsV1Claims removes this scoped tail, the floor coordinator's scoped-receipt arming and std.realization_schedule scoped_witness_execution_receipt_decode surface must dissolve or change in the same motion: a gunbc_ci_floor_plan with no scoped tail otherwise leaves a header-only ledger that the decoder deliberately refuses, so the coupling reds visibly instead of normalizing an unmodeled zero-row run." - -data v1_claim_scoped_witness_entries: List = [ - ScheduleWitnessEntry { - entry: "src/v1/tests/claim/pattern_binder_declaration_node_test.dag", - function: "", - kind: CorpusWitnessKind, - }, - ScheduleWitnessEntry { - entry: "src/v1/tests/claim/caret_parse_smoke_test.dag", - function: "", - kind: CorpusWitnessKind, - }, - ScheduleWitnessEntry { - entry: "src/v1/tests/claim/namespace_reference_derived_closure_production_admissions_witness_test.dag", - function: "", - kind: CorpusWitnessKind, - }, - ScheduleWitnessEntry { - entry: "src/v1/tests/claim/v1_complexity_eviction_hazard_test.dag", - function: "", - kind: CorpusWitnessKind, - }, - ScheduleWitnessEntry { - entry: "src/v1/tests/claim/ordinary_frontend_observation_test.dag", - function: "", - kind: CorpusWitnessKind, - }, - ScheduleWitnessEntry { - entry: "src/v1/tests/claim/v1_match_pattern_identity_test.dag", - function: "", - kind: CorpusWitnessKind, - }, -] +data v1_claim_scoped_witness_batch_deleted_note: String = "THE SCOPED WITNESS BATCH IS DELETED (2026-08-15), and with it the only ScopedWitnessBatch instance that ever existed. It ran five file-grain v1 claim entries under a dag plus src/v1 source-root envelope, in a sequential child worker, so the v1 compiler closure could be resolved without widening witness_layer_roots for everything else.\n\nWHY IT COULD NOT SURVIVE AFFECTED-SET SELECTION. It was the last SelectionApplied consumer on the required path, and its 720-second clamp was derived (PR #8259) from a measured 565-second wall on the assumption that unrelated PRs skip it. With selection deleted the two available readings were both wrong: run it every PR and the required floor grows by roughly nine minutes under a clamp basis that no longer describes it, or keep a selection mechanism alive for one batch. Its cost was also never really the witnesses — the same receipt measured about 390 seconds of closure materialization before the first witness line and about 30 seconds of witness evaluation, so it was paying a whole second subject preparation to check thirty rows.\n\nWHAT THIS NARROWS, stated rather than implied: the five entries under src/v1/tests/claim have NO executing consumer. They are not covered by ordinary discovery, whose roots are dag plus src/v2. Their generated stage0 emissions still compile into the seed crate, which is not execution. This is a real loss of coverage over v1 parser and namespace-binding behavior, taken deliberately as part of deleting the floor rather than discovered later, and it is NOT backstopped by any cadence — the cadence lane those rows might have moved to was refused for the same reason the per-PR slot was: a second subject envelope is the defect, not the schedule it runs on.\n\nRESTORATION: one prepared subject spanning dag, src/v1 and src/v2, at which point a separate envelope, a separate worker, a separate clamp and a separate receipt family all stop existing and these rows are ordinary discovery." -data v1_claim_scoped_witness_batch_note: String = "This is one INSTANCE of std.realization_schedule ScopedWitnessBatch, not a parser branch in the floor mechanism. The four file-grain rows expand through ScheduleWitnessEntry's empty-function authority, so adding or renaming a test fn changes no roster. Their dag plus src/v1 source-root envelope admits the v1 compiler closure without widening witness_layer_roots for unrelated witnesses. SelectionApplied is deliberate: normal affected-set selection avoids paying the measured closure materialization on unrelated PRs; every unselected roster row still emits an exact-head ScopedWitnessSelectionSkipped receipt with provenance, while a provenance failure refuses loudly and never widens. The executor's own module universe is a distinct fact carried by ScopedWitnessBatch.execution_authority as InheritedWalkSourceRoots: the worker resolves affected_set_floor_runner, witness_entry_eligibility_census, and post-discovery cost/attribution projectors from the enclosing walk's roots while the witness subject index remains exactly dag plus src/v1. Adding src/v2 to this batch's witness roots was considered and refused because it widens the subject envelope, moves the receipt digest, and invalidates the measured clamp basis; executor-authority dependencies never enter the witness roots as an absorbing fallback. The profile declares a substantial whole-tree resolve, Hermetic effects, a batch-owned 720-second clamp, and SequentialChildProcess isolation. RECEIPTED RAISE (2026-08-14, PR #8259 — clamp derivation, three questions): (Q1 WHY SLOWER?) Scoped roster unchanged — still five file-grain rows expanding to ~30 witnesses. Continuation-operator witnesses and source-audit rows run in ordinary discovery, not this batch. Run 31775746910 @ 81c90babc journal: ~390s closure materialization before first witness line, ~30s witness eval, ~152s post-batch receipts; every expanded witness completed before walk-terminal failed. Growth is closure-materialization wall, not scoped enrollment. Correlates with editing src/v1/02_parse.dag (parser is in the dag+src/v1 scoped closure) but magnitude is not decomposed here — tracked by module-grain-materialization lane; this raise does not discharge that open cost. (Q2 WHY 720?) Policy chain from gunbc.ci_spec gunbc_ci_floor_batch_clamp_note: measured scoped-worker total wall × 1.2 fleet margin, rounded up to whole-minute grain — the same derivation family #7924 used for 360→480. This batch carries per_unit_ms=0, so the clamp bounds fixed-roster closure materialization, not witness-count creep (discovery batch uses overhead+rate for that). 565s measured wall × 1.2 = 678s → 720s. (Q3 WAS 480 DERIVED?) Yes — #7924 run 31223532865 @ 93b1373751 FLOOR-BATCH-OVER-BUDGET wall_ms=375553 clamp_ms=360000, locally reproduced; 375.553s × 1.2 = 451s → 480s whole-minute grain under the same policy. THE ENROLLMENT THAT GREW THE BATCH: none. Failure was over_budget mislabeled WitnessRed because failure_details stayed empty. RECEIPTED RAISE (2026-08-08, PR #7924 CI run 31223532865 @ 93b1373751): scoped child FLOOR-BATCH-OVER-BUDGET wall_ms=375553 clamp_ms=360000 units=27 — reproduced locally on the same commit after merge with main. Prior 360s basis (199.393s arm64 x 1.8 = 358.9s) is stale: post-merge scoped-worker stage wall is ~376s on x86_local with the full executor-authority projector path. Sizing follows gunbc.ci_spec gunbc_ci_floor_batch_clamp_note fleet-margin policy (measured worst wall x 1.2, not host roulette): 375.553s x 1.2 = 451s, rounded up to 480s whole-minute grain (+33% over the retired 360s row). THE ENROLLMENT THAT GREW THE BATCH: none — wall is closure-materialization dominated, not a roster edit. The earlier 180-second basis measured only 96 seconds before the cost projector and renderers were reachable from the narrow scoped envelope, so it no longer described the executing batch. COST DISPOSITION: the approximately 103-second increase correlated with making the cost projector, histogram, and slowest-attribution renderer reachable while witness row evaluations themselves remain negligible per-row; that reporting/closure cost has not been decomposed in this scoped-scheduling change and is tracked by the real ROADMAP module-grain-materialization lane. Its trigger is a per-projector resolve/materialization attribution showing whether the three projections recompute identical semantic facts, followed by cached-vs-cold receipts before any optimization claim. The larger clamp must not normalize that open cost question into proportionality. per_unit_ms remains zero because row evaluation is negligible; this catches closure growth and deliberately does not price row-count growth until a file brings a distinct closure. Exact-head run 30713632253 proves SharedWalkProcess cannot satisfy this instance: ordinary discovery completed at 7.113GB RSS, then the floor vanished while materializing this second root closure before a batch-start line. The kernel cause is unclassified, but additive same-process residency is established. SequentialChildProcess makes the ordinary worker exit before this worker starts, releasing the first live set without claiming the stronger fresh-cgroup semantics of FreshJobProcess. v1_claim_scoped_witness_dissolve_on fires when the v2 parser owns these claims." - -data v1_claim_scoped_witness_batch: ScopedWitnessBatch = scoped_witness_batch( - batch_id: "v1-claim-scoped-witnesses" as ScopedWitnessBatchId, - source_roots: ["dag", "src/v1"], - entries: v1_claim_scoped_witness_entries, - scan_dirs: [], - node_frontier_selection: SelectionApplied, - resource_profile: ScopedWitnessBatchResourceProfile { - runnable: runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: false, - memory: runnable_memory_substantial(), - execution_mode: Hermetic, - ), - clamp: RunnableBatchClamp { - overhead: second(count: 720), - per_unit: millisecond(count: 0), - authority: decl_ref( - module_path: "gunbc.ci_layer_roots", - decl_name: "v1_claim_scoped_witness_batch", - ), - }, - process_isolation: SequentialChildProcess, - }, -) - -data scoped_witness_batches: List = [v1_claim_scoped_witness_batch] data excl_no_fake_anomalies_reason: String = "The expectation-backfill WALL spawns claim_batch as a child process to read a passing corpus's own stderr, so it is Wet BY CONSTRUCTION — its whole subject is what the observation layer prints, which only exists when the effects really run. The Hermetic discovery corpus refuses it exactly as install_media_real_execution_wet_note describes ('no mock_response for operation Run — refusing to fabricate Unit'), and that refusal is correct: a mocked child emits no real observation stream, so a hermetic version of this witness could only ever pass vacuously. Landed into hermetic discovery by filename convention on first authoring (run 30178544618 @ b2411f0, batch 3) and re-homed to BinWitnessWet; then D6-rehomed to FalsifierRehomedBinWet (run 30220304152: ~85–90s/row vs bin_witness_wet_per_row_wall_budget_seconds=60, batch-4 FLOOR-BATCH-OVER-BUDGET)." @@ -1124,12 +1040,6 @@ type RehomedBinWetRow { } data falsifier_rehomed_bin_wet_rows: List = [ - RehomedBinWetRow { - entry: "dag/test/claim/floor_skip_discovery_witness_test.dag", - function: "floor_skip_discovery_keystone_holds", - reason: "289s measured on run 30009199696 (4.8x the per-row budget). The rehome stands on that measured wall alone. A second clause once stood here claiming the row was ALSO a per-PR duplicate because the ci job runs the floor_skip_discovery_witness binary on every PR; #7446 (Demote the affected-set selection control to the falsifier cadence) moved that step out of ci.yml into falsifier.yml, so the per-PR coverage it cited stopped existing and the sentence became a justification pointing at a step that no longer runs per-PR. The binary now executes on the falsifier cadence only. The detection window is NOT 'within one cadence window' — gunbc_ci_selection_control_step_note already retracted that phrasing as too strong (review correction 2026-07-30): the falsifier is queue-not-cancel and this step sits after the prelude and release build, so a regression landing just after a run passed the control waits for that run's remainder, plus queued-run startup, plus the next run's prelude and build, a sum that can exceed one cadence period. The honest statement is that it reds when the NEXT COMPLETED control runs. Stated here rather than implied by a stale duplicate claim, and stated in the words the retraction settled on rather than the ones it rejected.", - dissolution: unbound_dissolution(description: "the selection-control suite's shared-index rework lands the binary under bin_witness_wet_per_row_wall_budget_seconds on a measured run — then either re-enroll per-PR consciously or delete this row as a duplicate of the step (whichever the measured wall admits)") - }, RehomedBinWetRow { entry: "dag/test/claim/dag_compile_clean_seam_witness_test.dag", function: "cross_shard_seam_preservation_holds_on_live_tree", @@ -1746,9 +1656,7 @@ fn falsifier_silent_pick_gate_roster() -> List { falsifier_silent_pick_gate_entries } -data floor_skip_control_fixture_exclusion_note: String = "test/fixture/floor_skip/ is excluded from tree-wide discovery at DIR grain (parent ruling 2026-07-11: a fixture that WANTS witness enrollment is mis-homed by definition, and file-grain exclusion invites the next control fixture to repeat the landmine). These fixtures exist to be driven by floor_skip_discovery_witness's explicit rosters, not as corpus witnesses: falsifier_divergence_control_test.dag carries a BY-DESIGN red row (falsifier_red_control_holds returns false to prove the divergence attribution channel), so any completed full-corpus run - the nightly falsifier, or a PR whose diff touches its import closure - would red on a row whose red is the control's specification, and a permanent by-design divergence would also make the falsifier's 8-clean-window retirement criterion unsatisfiable; live_tree_declared_test.dag declares ReadsLiveTree as a control, so as a corpus row it would be a permanent never-skip cost with no enforcement value. Genuine corpus witnesses that were mis-homed here have been re-homed under test/claim/ (provenance_fail_closed_contract_test, live_tree_collision_test). Explicit-roster runs (the floor_skip bin) are unaffected: witness exclusions apply to discovery only." - -data walk_plan_stage_control_fixture_exclusion_note: String = "test/fixture/walk_plan_stage/ is excluded from tree-wide discovery at DIR grain (same fixture-home ruling as floor_skip_control_fixture_exclusion_note): these are production-path stage-executor controls with Wet typed-service bodies (shell.Mkdir/Remove/Test, Filesystem.Read/Write, sleep.Delay) driven only through claim_executor --plan-entry/--plan-function recipes in plan.dag. As hermetic discovery witnesses they refuse at the effect boundary (no mock_response for Parents/Write/Read/RecursiveForce) or carry BY-DESIGN reds (failure_red_member_holds); inclusion turned every PR touching the import closure into 8 WitnessRed failures in discovery batch 3. Explicit plan-driven runs and walk_plan_stage_fixture.rs (#[ignore] integration) are unaffected." +data walk_plan_stage_control_fixture_exclusion_note: String = "test/fixture/walk_plan_stage/ is excluded from tree-wide discovery at DIR grain (the fixture-home ruling of 2026-07-11: a fixture that WANTS witness enrollment is mis-homed by definition, and file-grain exclusion invites the next control fixture to repeat the mistake): these are production-path stage-executor controls with Wet typed-service bodies (shell.Mkdir/Remove/Test, Filesystem.Read/Write, sleep.Delay) driven only through claim_executor --plan-entry/--plan-function recipes in plan.dag. As hermetic discovery witnesses they refuse at the effect boundary (no mock_response for Parents/Write/Read/RecursiveForce) or carry BY-DESIGN reds (failure_red_member_holds); inclusion turned every PR touching the import closure into 8 WitnessRed failures in discovery batch 3. Explicit plan-driven runs and walk_plan_stage_fixture.rs (#[ignore] integration) are unaffected." data enforcement_coverage_exclusion_note: String = "The four enforcement inventory/coverage witnesses (enforcement/cost_coverage_witness_test.dag, enforcement/grammar_coverage_witness_test.dag, enforcement_live_witness_test.dag, enforcement_inventory_witness_test.dag) are operator-ruled OFFLINE (2026-07-11; enforcement_inventory_witness_test.dag added 2026-08-02 review 47569). Receipt: their *_live fns read the corpus as data (live-tree rosters), so the PR-A never-predict-skip rule for live-tree rows made them run on EVERY wide PR regardless of diff; the block cost 22.0 min (main run 29137081535, busy fleet) and 21.0 min (PR run 29142398465, quiet fleet) of the 60-minute floor budget - about 35 percent - and their allocation ramp feeds the ~15GiB slot memory.high throttle that turns the floor tail into swap-speed work. Their input is corpus-denominated (the InputEnvelope axis, not layer span): per-PR admission wants a declared bounded envelope, which these rows cannot declare today. Offlining required TWO edits (cursor review catch, same PR): the discovery exclusion rows here AND removing the explicit CommitCheckEnrollment for enforcement_live_witness_test.dag in gunbc.commit_workflow - explicit roster rows merge after discovery with no exclusion filter (cli_run.rs explicit_entries dedup), and that is correct: an explicitly declared row should run, so offlining one means deleting its declaration, never teaching exclusions to veto the roster (a second authority). Run them via the local recipe: claim_batch --source-root dag --source-root src/v2 --entry per fn (all pure reads, no --wet needed). Dissolve-on: witness rows declare InputEnvelope/CostEnvelope and the scheduled (nightly) lane admits corpus-input rows under its own budget - then re-enroll consciously through the floor owner's lane; the affected-set-falsifier cadence covers interim drift." diff --git a/dag/gunbc/ci_materialization_gate.dag b/dag/gunbc/ci_materialization_gate.dag deleted file mode 100644 index 7602e62ce37..00000000000 --- a/dag/gunbc/ci_materialization_gate.dag +++ /dev/null @@ -1,183 +0,0 @@ -module gunbc.ci_materialization_gate - -data ci_materialization_gate_note: String = "The live binding: the ladder run over the ACTUAL emitted workflow (gunbc.ci_workflow data row), never a fixture copy of it. Demands, exemption identities, and fresh-effect scripts are all resolved against the same authority the ci.yml is emitted from, so a workflow edit that introduces cross-job duplication without a covering provider reds the enrolled witness in the same CI run that would have paid the duplication. Post-fold reality (ci_regen job folded into the ci job 2026-07-11): the workflow now has a SINGLE building job, so the release build is one demand -> AcceptedSingleRecompute (state 5: a single undeclared demand needs no provider, a cache there is dead weight), and the ladder holds WITH AND WITHOUT the sccache provider. The cross-job duplication the ladder refutes is now carried as the discriminating RED control by the synthetic placement_grain witness (two independently-building jobs -> AuthoredDuplication/RefusedNoProvider), which the live witness's demand==1 / discharged==0 pins guard against reintroducing. Fresh effects: the floor cgroup-peak measurement scripts (a memory.peak read is a new fact each run, never memoizable — the rust_tests cgroup-peak measurement was the prior subject; it retired with the rust_tests job 2026-07-11, and the ci-job floor peak pre/post reads are the same measurement category), every deploy stage script (a deploy is the effect being the use), and the heal-revalidation exact-head preflight (git HEAD is a new checkout fact in each isolated job and must be observed there, never memoized or discharged from another job); all resolved by projection, not copied strings." - -// The fleet-key materialization and its teardown are FRESH per-job effects (2026-08-09): -// probe_fleet_reach and collect_fleet_convergence each materialize their OWN in-run -// ssh-agent from the WIF-fetched secret and kill it at job end. The identical script -// appears in both jobs by NECESSITY — an ssh-agent lives in one job's process -// environment and cannot be memoized or discharged from another isolated job (the same -// category as a per-job deploy stage or cgroup-peak read). Declaring them fresh is why -// the ladder reads them as ExemptFreshEffect rather than AuthoredDuplication: the effect -// IS the use, per job. The genuine cross-job-duplication guard is unaffected — a -// cacheable computation duplicated across jobs would still red. -fn ci_fresh_effect_scripts() -> List { - concat( - [ - step_run_script(s: ci_floor_peak_pre_step()), - step_run_script(s: ci_floor_peak_post_step()), - ci_heal_revalidation_preflight_script(), - gunbc_ci_fleet_key_agent_script(), - gunbc_ci_fleet_key_agent_cleanup_script(), - ], - map(gunbc_ci_deploy_stages, s => gunbc_ci_deploy_invoke(stage: s)) - ) -} - -fn ci_materialization_demands() -> List { - workflow_run_demands(w: ci_workflow, fresh_scripts: ci_fresh_effect_scripts()) -} - -fn ci_materialization_exempt_identities() -> List { - workflow_scripts_named(w: ci_workflow, names: ci_cost_floor_exempt_step_names) -} - -fn ci_materialization_verdicts() -> List { - materialization_ladder( - demands: ci_materialization_demands(), - providers: ci_cache_providers(), - cost_floor_exempt: ci_materialization_exempt_identities() - ) -} - -fn ci_materialization_ladder_holds_live() -> Bool { - materialization_ladder_holds( - demands: ci_materialization_demands(), - providers: ci_cache_providers(), - cost_floor_exempt: ci_materialization_exempt_identities() - ) -} - -fn ci_materialization_verdicts_without_sccache() -> List { - materialization_ladder( - demands: ci_materialization_demands(), - providers: no_cache_providers, - cost_floor_exempt: ci_materialization_exempt_identities() - ) -} - -fn ci_materialization_holds_without_sccache() -> Bool { - materialization_ladder_holds( - demands: ci_materialization_demands(), - providers: no_cache_providers, - cost_floor_exempt: ci_materialization_exempt_identities() - ) -} - -fn ci_verdict_is_discharged_arm(v: LadderVerdict) -> Bool { - match v { - RefusedNatureConflict { identity: _ } => false - AuthoredDuplication { identity: _, lca: _, site_count: _ } => false - DeadComputation { identity: _ } => false - AcceptedEffectIsTheUse { identity: _ } => false - Discharged { identity: _, lca: _, provider_id: _ } => true - RefusedNoProvider { identity: _, lca: _ } => false - RefusedScopeTooNarrow { identity: _, lca: _, provider_id: _ } => false - RefusedExistenceKeyed { identity: _, lca: _, provider_id: _ } => false - RefusedRetentionUnbounded { identity: _, lca: _, provider_id: _ } => false - RefusedRetentionUnobserved { identity: _, lca: _, provider_id: _ } => false - RefusedUnmodeledWorldRead { identity: _, lca: _ } => false - ExemptFreshEffect { identity: _ } => false - AcceptedBelowCostFloor { identity: _ } => false - AcceptedSingleRecompute { identity: _ } => false - } -} - -fn ci_verdict_is_below_cost_floor_arm(v: LadderVerdict) -> Bool { - match v { - RefusedNatureConflict { identity: _ } => false - AuthoredDuplication { identity: _, lca: _, site_count: _ } => false - DeadComputation { identity: _ } => false - AcceptedEffectIsTheUse { identity: _ } => false - Discharged { identity: _, lca: _, provider_id: _ } => false - RefusedNoProvider { identity: _, lca: _ } => false - RefusedScopeTooNarrow { identity: _, lca: _, provider_id: _ } => false - RefusedExistenceKeyed { identity: _, lca: _, provider_id: _ } => false - RefusedRetentionUnbounded { identity: _, lca: _, provider_id: _ } => false - RefusedRetentionUnobserved { identity: _, lca: _, provider_id: _ } => false - RefusedUnmodeledWorldRead { identity: _, lca: _ } => false - ExemptFreshEffect { identity: _ } => false - AcceptedBelowCostFloor { identity: _ } => true - AcceptedSingleRecompute { identity: _ } => false - } -} - -fn ci_verdict_is_exempt_fresh_arm(v: LadderVerdict) -> Bool { - match v { - RefusedNatureConflict { identity: _ } => false - AuthoredDuplication { identity: _, lca: _, site_count: _ } => false - DeadComputation { identity: _ } => false - AcceptedEffectIsTheUse { identity: _ } => false - Discharged { identity: _, lca: _, provider_id: _ } => false - RefusedNoProvider { identity: _, lca: _ } => false - RefusedScopeTooNarrow { identity: _, lca: _, provider_id: _ } => false - RefusedExistenceKeyed { identity: _, lca: _, provider_id: _ } => false - RefusedRetentionUnbounded { identity: _, lca: _, provider_id: _ } => false - RefusedRetentionUnobserved { identity: _, lca: _, provider_id: _ } => false - RefusedUnmodeledWorldRead { identity: _, lca: _ } => false - ExemptFreshEffect { identity: _ } => true - AcceptedBelowCostFloor { identity: _ } => false - AcceptedSingleRecompute { identity: _ } => false - } -} - -fn ci_release_build_demand_count() -> Int { - ci_materialization_demands() - |> filter(d => d.identity == ci_release_build_script()) - |> count() -} - -fn ci_discharged_verdict_count() -> Int { - ci_materialization_verdicts() - |> filter(v => ci_verdict_is_discharged_arm(v: v)) - |> count() -} - -fn ci_release_build_discharged_by_sccache_count() -> Int { - ci_materialization_verdicts() - |> filter(v => verdict_is_discharged_by(v: v, identity: ci_release_build_script(), provider_id: ci_sccache_provider_id())) - |> count() -} - -fn ci_below_cost_floor_verdict_count() -> Int { - ci_materialization_verdicts() - |> filter(v => ci_verdict_is_below_cost_floor_arm(v: v)) - |> count() -} - -fn ci_exempt_fresh_verdict_count() -> Int { - ci_materialization_verdicts() - |> filter(v => ci_verdict_is_exempt_fresh_arm(v: v)) - |> count() -} - -fn ci_heal_revalidation_preflight_is_fresh_effect() -> Bool { - let identity = ci_heal_revalidation_preflight_script() - let demand_count = ci_materialization_demands() - |> filter(d => d.identity == identity) - |> count() - let verdict_count = ci_materialization_verdicts() - |> filter(v => verdict_is_exempt_fresh(v: v, identity: identity)) - |> count() - demand_count > 1 && verdict_count == 1 -} - -fn ci_uses_steps_skipped_count() -> Int { - workflow_uses_steps_count(w: ci_workflow) -} - -fn ci_run_step_natures_claimed_not_derived_count() -> Int { - workflow_run_steps_count(w: ci_workflow) -} - -fn ci_release_build_refused_without_provider_count() -> Int { - ci_materialization_verdicts_without_sccache() - |> filter(v => verdict_is_refused_no_provider(v: v, identity: ci_release_build_script())) - |> count() -} - -fn ci_release_build_single_recompute_count() -> Int { - ci_materialization_verdicts() - |> filter(v => verdict_is_accepted_single_recompute(v: v, identity: ci_release_build_script())) - |> count() -} diff --git a/dag/gunbc/ci_release_bins.dag b/dag/gunbc/ci_release_bins.dag index 7e3e80cfd77..e4b656eaee5 100644 --- a/dag/gunbc/ci_release_bins.dag +++ b/dag/gunbc/ci_release_bins.dag @@ -21,9 +21,7 @@ Dissolve-on (hand membership of witness_declared_release_bins): a host census of data ci_floor_invoked_bins: List = [ "claim_executor", "gunbc", - "regen_floor_skip_witness", - "floor_skip_discovery_witness", - "selection_control_skip_witness" + "regen_floor_skip_witness" ] data witness_declared_release_bins: List = [ diff --git a/dag/gunbc/ci_workflow.dag b/dag/gunbc/ci_workflow.dag index 4741fa6930a..6be69ae2f42 100644 --- a/dag/gunbc/ci_workflow.dag +++ b/dag/gunbc/ci_workflow.dag @@ -68,7 +68,6 @@ import v2.workflow.ci_workflow_run_emit { ci_isolate_toolchain_script, ci_native_cache_root_script, ci_pin_rustup_default_script, - ci_selection_control_script } import v2.workflow.ci_release_build_emit { ci_release_build_script } import v2.workflow.ci_stage0_partition_compile_gate_emit { ci_stage0_partition_compile_gate_script } @@ -78,10 +77,6 @@ import std.decl_ref { DeclarationRef, WholeDeclaration } import std.types { Duration } import gunbc.repo_identity { gunbc_default_branch_name } import gunbc.fleet_host_key_enrollment { probe_identity_secret_access_requirement } -import gunbc.falsifier_run_control { - falsifier_release_build_step_id, - ci_release_bins_step_id, -} import extdeps.github.actions { Workflow, Job, Step, RunStep, UsesStep, WorkflowTrigger, Push, PullRequest, WorkflowDispatch, MergeGroup, @@ -389,7 +384,7 @@ fn ci_v1_compiler_test_targets_compile_gate_step() -> Step { fn ci_release_build_step() -> Step { RunStep { name: Present { value: "Build release bins (claim_executor + gunbc)" }, - id: Present { value: falsifier_release_build_step_id }, + id: Present { value: "release_build" }, run: ci_release_build_script(), shell: none, env: none, @@ -495,7 +490,7 @@ fn ci_release_bins_download_step() -> Step { fn ci_release_bins_unpack_verify_step() -> Step { RunStep { name: Present { value: "Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed)" }, - id: Present { value: ci_release_bins_step_id }, + id: Present { value: "release_bins" }, run: ci_release_bins_unpack_verify_script(), shell: none, env: none, @@ -536,20 +531,6 @@ fn ci_floor_peak_post_step() -> Step { } } -fn ci_selection_control_step() -> Step { - RunStep { - name: Present { value: "Affected-set selection control (floor_skip_discovery_witness)" }, - id: none, - run: ci_selection_control_script(), - shell: none, - env: none, - working_directory: none, - if_condition: none, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_ci_selection_control_step_timeout_minutes } - } -} - fn ci_deploy_step(stage: DeployStage) -> Step { RunStep { name: Present { value: stage.step_name }, @@ -599,10 +580,6 @@ data gunbc_ci_artifact_transfer_step_timeout_minutes: Int = 10 data gunbc_ci_artifact_transfer_step_note: String = "Cross-job handoff of the release bins (operator job-split ruling 2026-07-11): the build job packs ci_floor_required_artifact_names into one tgz (tar preserves the executable bits a raw artifact zip would drop) and uploads it; the ci floor job downloads, unpacks into target/release, and re-verifies via claim_executor --verify-build-artifacts before any step consumes a bin (fail-closed: a missing or truncated artifact reds the job at the verify, never as a mid-floor bin fallback). 10m is the transfer envelope for a ~200MB archive under fleet pressure; upload uses if-no-files-found: error so an empty pack is loud." -data gunbc_ci_selection_control_step_timeout_minutes: Int = 15 - -data gunbc_ci_selection_control_step_note: String = "The affected-set selection control suite as a per-PR gate (operator fork (c), 2026-07-10 — the acceptance's 'green AND wired' half): floor_skip_discovery_witness runs the hermetic skip/refuse/divergence controls, including predict_only_red_predicted_unaffected_is_divergence — the discriminating RED for the falsifier's divergence counting — and the empty-diff-skips pin (ruling 2026-07-05: a failure arm refuses, never widens). DEMOTED to the falsifier cadence 2026-07-29 (operator ruling, PR-timing analysis) — it no longer rides the per-PR ci job; the coverage delta and detection window are stated at the end of this note. Hermetic: both diff channels are injected (floor_diff_observe.dag's floor_observe_git_diff_unified/floor_observe_git_diff_name_status GUNBC_CI_DIFF_UNIFIED/GUNBC_CI_DIFF_NAME_STATUS arms), so the suite measures fixtures, never this checkout's real diff. Budget: 80s measured local (2026-07-10, full suite, release build); 15m is the fleet-pressure envelope, a named term in the ci backstop sum. MEASURED CORRECTION 2026-07-29: the 80s local basis above had drifted 6.8x — the step measured 9m02s on the fleet (run 30482171871, job 90679506428, 19:22:04 to 19:31:06), about 27 percent of a 33.6-minute ci job wall, and nothing alarmed because the 15m step cap left it at 60 percent of its ceiling. The step's own in-code note (floor_skip_discovery_witness.rs) had already recorded a 4m51s-vs-80s incident and the D3 fix for it, so this is that same class regressed to ~1.9x the state the fix was written to repair. ACCOUNTING, from the job log: the assertions cost nothing (every witness row reports 0.0-0.3ms); the wall is 18 serial scenario setups — ~4m49s for two whole-corpus index builds (one shared-index build plus budget_roster_resolves_cold, the deliberate Class-B pool-coincidence control), ~34s for the eight scenarios that hit the shared index and report 'unaffected (import-closure, skipped without resolve)', ~3m30s for the ~7 scenarios that land 'in the affected closure (resolving to decide node-frontier)' at ~30s per resolve, and 11.2s of thread-local teardown. RESPONSE, in the order the costs were priced: (a) the step is now affected-set scoped by ci_selection_control_skip_step (v2.workflow.ci_workflow_run_emit ci_selection_control_skip_policy_note) — the mechanism applied to itself, pull_request-gated with push-to-main as the unconditional cold control. That is the lever that matters, but it is a TRADE, not a free win, and the numbers are in that policy note: the skip witness costs ~100s per invocation (the cold whole-pool index its diff observation builds), so a skipping PR saves ~7m22s while a non-skipping PR pays ~100s MORE than before. MEASURED SKIP RATE 23 of the last 100 main commits (35 touch src/v1/**, 36 touch markdown, 1 touches Cargo config, and 13 of the remainder intersect the suite's actual 391-file dag closure), for an expected ~-25s/PR — about 1.2 percent of the job. That supersedes two earlier claims in the policy note, -7.7 min/PR (unmeasured 85 percent) and -4.3 min/PR (a <=66 percent ceiling extrapolated from the src/v1/** prefix before markdown and the closure were counted); both are kept visible there rather than replaced. So the cost win alone does not carry the scaffold under DESIGN §6 — the ~100s cold diff observation is what ruins the mean, and it is an already-named deficit this change did not create. (b) the teardown path is removed BY CONSTRUCTION — the suite now exits via process::exit, which does not run thread-local destructors, so cli_run's whole-pool Rc index is never dropped. HONESTY ON THIS ONE: the 11.2s is the CI-MEASURED cost of the path that was removed (the unlogged gap between the final receipt line and step completion on run 30482171871), and the removal is a property of process::exit rather than an inference; what was NOT done is an end-to-end before/after local re-measure, because the suite exceeds the local measurement window available here. So read (b) as mechanism-plus-prior-measurement, not as a fresh paired timing — the next CI run of the unscoped arm is where the paired number lands. STILL OWED, deliberately not fixed here: the ~30s-per-node-frontier-resolve unit is unexplained — it is 4x the ~7.2s/resolve the floor resolve receipt records, so it is either a genuinely larger closure or a PROCESS_RESOLVE_STORE miss, and it wants a measurement rather than a guess. PLACEMENT CALL MADE (operator ruling 2026-07-29, PR-timing analysis) — this note's own line above held the falsifier-cadence question 'for an operator call because that is the placement decision the D3b gate flip mispriced'. The call is: the WHOLE step rides gunbc.falsifier_workflow, not just budget_roster_resolves_cold. IT SUBSUMES THE (a) TRADE RATHER THAN COMPETING WITH IT, using this note's own measured numbers: (a) left a skipping PR paying ~100s and a NON-skipping PR paying 542s + ~100s, at a measured 23-of-100 skip rate for an expected ~-25s/PR, which is why this note already concluded the cost win alone does not carry the scaffold under DESIGN §6. Demotion moves the step and its in-script skip together, so the per-PR job loses BOTH the 542s suite and the ~100s cold diff observation — about -642s on the 77 percent that do not skip and -100s on the rest, dominating the trade instead of tuning it. The ~100s double payment the yellow dissolve-on below counts is halved in the same motion, since only regen_floor_skip_witness still pays it per PR. THE SKIP STAYS CORRECT UNDER DEMOTION BY CONSTRUCTION: ci_selection_control_skip_step's condition is StrEq on \"$GITHUB_EVENT_NAME\" == pull_request, so on the falsifier's schedule event it cannot fire and the suite runs UNCONDITIONALLY — which is exactly the cold-control posture, the same shape as the two controls it now sits beside. MEASUREMENT BASIS, dated honestly: the demotion was priced at 10m09s median on the per-PR ci job (n=6 green runs, range 8m41s-10m32s), which is a WIDER sample than the single 9m02s run above but was taken BEFORE (a) and (b) landed, so it does not credit the teardown removal or the skip. The post-(a)/(b) per-PR number is therefore OWED and not claimed here; the demotion does not rest on it, because (a)'s own measured expectation is only ~-25s/PR and the non-skipping majority still pays minutes. PLACEMENT on the falsifier is load-bearing twice and pinned structurally (test.claim.falsifier_workflow_witness_test): AFTER the release build, because the step executes the release-built floor_skip_discovery_witness, and BEFORE ci_floor_peak_pre_step, because that pair brackets the floor's cgroup measurement and a step inside it would attribute its own residency to the floor's peak receipt. Exactly-one on the falsifier, zero on ci, asserted in both directions — a yaml substring presence test passes for every permutation and cannot express either invariant. COVERAGE DELTA, and the earlier claim retracted: a PR that reintroduces a widen now reds when the NEXT COMPLETED falsifier control runs, NOT 'within one 4h cadence window' (review correction 2026-07-30 — that claim was too strong). The falsifier is queue-not-cancel with a 230-minute backstop class and this step sits after the prelude and release build, so a change landing just after a run passed the control waits for that run's remainder, plus queued-run startup, plus the next run's prelude and build — a sum that can exceed one cadence period. What bounds the damage is unchanged: a widen is bounded by the status quo (per-PR the witness would not have run at all), and the divergence is COUNTED when detected, never absorbed. RETURN TRIGGER, stated as an OUTCOME rather than a mechanism (review correction 2026-07-30 — the prior text prescribed per-gate pooled children, a fix that had already landed while the suite still measured minutes, so it named a stale mechanism as its own re-entry condition): re-enrol per-PR once a named receipt shows the ENTIRE step, spawn to verdict, on the CI fleet rather than a local host, consistently below a seconds-scale ceiling across a full falsifier window. Whichever mechanism buys that — the persistent content-keyed node store the yellow dissolve-on names, witness realization to native bins, or something else — is the lane's business, not this note's. BUDGET: the 15m envelope is retained as a named term in the FALSIFIER backstop sum; the ci backstop drops the same term and falls 115m -> 100m, which is why the two edits are one change and not two." - data gunbc_ci_prelude_allowance_minutes: Int = 5 data gunbc_ci_release_build_step_timeout_minutes: Int = 45 @@ -1047,139 +1024,3 @@ fn ci_heal_author_commit_upload_step() -> Step { timeout_minutes: Present { value: gunbc_ci_artifact_transfer_step_timeout_minutes } } } - -fn ci_heal_generated_artifacts_job() -> Job { - Job { - id: "heal_generated_artifacts", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: concat( - [ci_heal_branch_head_checkout_step()], - [ci_release_bins_download_step(), ci_release_bins_unpack_verify_step(), ci_heal_repo_local_git_config_step(), ci_heal_binary_source_skew_guard_step(), ci_heal_regen_step(), ci_heal_commit_push_step(), ci_heal_author_commit_upload_step()] - ), - needs: ["build"], - env: none, - outputs: none, - if_condition: Present { value: ci_regen_heal_if }, - timeout_minutes: Present { value: gunbc_ci_heal_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: Present { value: ci_heal_job_permissions } - } -} - -fn ci_build_job() -> Job { - Job { - id: "build", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: concat(ci_heal_revalidation_prelude_steps(), [ci_fmt_gate_step(), ci_release_build_step(), ci_v1_compiler_tests_compile_gate_step(), ci_stage0_partition_compile_gate_step(), ci_v1_compiler_test_targets_compile_gate_step(), ci_release_bins_pack_step(), ci_release_bins_upload_step()]), - needs: [], - env: none, - outputs: none, - if_condition: none, - timeout_minutes: Present { value: gunbc_ci_build_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: none - } -} - -fn ci_job() -> Job { - Job { - id: "ci", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: concat([ci_floor_upstream_red_refusal_step()], concat(ci_floor_job_prelude_steps(), [ci_release_bins_download_step(), ci_release_bins_unpack_verify_step(), ci_floor_peak_pre_step(), ci_floor_step(), ci_floor_peak_post_step(), ci_floor_receipts_upload_step()])), - needs: ["build", "regen", "heal_generated_artifacts"], - env: none, - outputs: none, - if_condition: Present { value: ci_floor_runs_unless_cancelled_if }, - timeout_minutes: Present { value: gunbc_ci_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: none - } -} - -fn ci_regen_floor_step() -> Step { - RunStep { - name: Present { value: "gunbc ci regen (self-host fixed-point — required)" }, - id: none, - run: gunbc_ci_regen_floor_run(spec: gunbc_ci_regen_spec), - shell: none, - env: none, - working_directory: none, - if_condition: none, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_ci_regen_step_timeout_minutes } - } -} - -data ci_regen_job_note: String = "The self-host fixed-point regen as its OWN job upstream of ci (operator-directed 2026-07-23: 'regen should be upstream of ci — doesn't ci depend on regen passing anyway?'). It was a step inside the ci job (folded in #6470, 2026-07-11); extracting it makes the dependency explicit — ci needs [build, regen], so a regen fixed-point failure skips ci and blocks the merge, rather than being an early step buried in the ci log. Pipeline shape: build -> regen -> ci -> deploy. It needs [build] for the release bins (regen runs the built gunbc), carries the floor-gate toolchain prelude (regen_stage0 emits rustfmt-formatted .rs), and is read-only (no push — the generated-artifact heal is a separate job with its own contents:write grant)." - -fn ci_regen_job() -> Job { - Job { - id: "regen", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: concat(ci_floor_job_prelude_steps(), [ci_release_bins_download_step(), ci_release_bins_unpack_verify_step(), ci_regen_floor_step()]), - needs: ["build"], - env: none, - outputs: none, - if_condition: none, - timeout_minutes: Present { value: gunbc_ci_regen_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: none - } -} - -data ci_merge_group_trigger_note: String = "merge_group trigger: the merge queue constructs the tree that will actually land on main and asks for checks on THAT tree — the queue is the operational realization of gunbc.merge_admission KeyedReceipt on the tree axis (the verdict's identity IS the landing tree's identity), and the roster axis rides along because the gate roster is in-tree, so a roster change is a tree change. The theorem that this is the policy admitting zero unverified tips across every bounded interleaving — and that GitHub's strict-up-to-date boolean is NOT sufficient — is test.claim.merge_lifecycle_interleaving_witness. Queue runs see github.ref = gh-readonly-queue/*, so the deploy job's main-push guard skips them, the concurrency group falls through pull_request.number to github.ref (shared per queue ref; cancel-in-progress is false for merge_group), and the merge-admission stamp takes its non-PR arm (absent pr_number). If the floor's merge-base diff observation cannot resolve on a queue ref it falls through to the full floor — fail-closed, never widening; affected-set-scoping queue runs is a later optimization. The trigger is inert until the operator adds the merge_queue rule to the main ruleset (Rulesets API write needs the admin grant this integration lacks — gunbc.plans.branch_merge_admission_model section 5); land the trigger FIRST, flip the rule SECOND, else the queue waits forever on a check the workflow never reports." - -data ci_workflow: Workflow = { - name: "ci", - on: [ - WorkflowDispatch { - inputs: [ - DispatchInput { - name: "expected_healed_sha", - description: Present { value: "Immutable healed commit required by an auto-heal revalidation run" }, - required: false, - default: none, - type: InputString - } - ] - }, - Push { branches: [gunbc_default_branch_name], paths: [] }, - PullRequest { - branches: [gunbc_default_branch_name], - types: [Opened, Synchronize, Reopened, ReadyForReview] - }, - MergeGroup - ], - concurrency: Present { - value: ConcurrencyMappingQueueNotMax { - - group: ci_concurrency_group(), - cancel_in_progress: Present { value: CancelInProgressExpression { expression: ci_concurrency_cancel_in_progress_expression() } }, - explicit_single: none - } - }, - env: Present { - value: [ - kv(key: "CARGO_TERM_COLOR", value: yaml_string(s: "always")), - kv(key: "RUSTFLAGS", value: yaml_string(s: "-D warnings")) - ] - }, - permissions: Present { - value: WorkflowPermissions { - contents: Present { value: PermRead }, - pull_requests: Present { value: PermRead }, - issues: none, - actions: none, - id_token: none - } - }, - jobs: [ci_build_job(), ci_regen_job(), ci_job(), ci_heal_generated_artifacts_job(), ci_fleet_job()] -} diff --git a/dag/gunbc/ci_yaml_emit.dag b/dag/gunbc/ci_yaml_emit.dag deleted file mode 100644 index 52fa8bfd061..00000000000 --- a/dag/gunbc/ci_yaml_emit.dag +++ /dev/null @@ -1,13 +0,0 @@ -module gunbc.ci_yaml_emit - -import extdeps.languages.yaml.emit { serialize_yaml } -import extdeps.languages.yaml.gha_workflow { project_workflow_to_yaml } -import gunbc.ci_workflow { ci_workflow } - -fn expected_ci_yml() -> String { - serialize_yaml(v: project_workflow_to_yaml(workflow: ci_workflow)) -} - -fn ci_yml_drifted(committed: String) -> Bool { - !(committed == expected_ci_yml()) -} diff --git a/dag/gunbc/commit_workflow.dag b/dag/gunbc/commit_workflow.dag index 448b627f391..c2a9350513a 100644 --- a/dag/gunbc/commit_workflow.dag +++ b/dag/gunbc/commit_workflow.dag @@ -9,7 +9,7 @@ import gunbc.ci_gate { SelfHostReadsRealBytesGate, SelfHostStalenessGate } import gunbc.generated_artifact { - GeneratedArtifact, CiYamlArtifact, FalsifierYamlArtifact, GithooksPrePushArtifact, artifact_path + GeneratedArtifact, GithooksPrePushArtifact, artifact_path } import std.disposition { Disposition, Scaffold, SingleAuthority, Terminal } import std.decl_ref { DeclarationRef, DeclField, WholeDeclaration, NamedField, declaration_ref_eq, declaration_ref_in_list } @@ -1839,11 +1839,6 @@ data commit_gate_roster: List = [ ] data commit_workflow_realization_bindings: List = [ - CommitWorkflowRealizationBinding { - surface: GithubActionsCiJob, - handler: CiYamlHandler, - artifact: CiYamlArtifact - }, CommitWorkflowRealizationBinding { surface: GitPrePushHook, handler: GitPrePushScriptHandler, @@ -2606,10 +2601,10 @@ fn ci_floor_commit_witness_claim_schedule() -> List { fn realization_artifact_path(surface: CommitWorkflowSurface) -> String { match surface { - GithubActionsCiJob => artifact_path(a: CiYamlArtifact) - GithubActionsCiRegenJob => artifact_path(a: CiYamlArtifact) + GithubActionsCiJob => ci_surface_artifact_wiped + GithubActionsCiRegenJob => ci_surface_artifact_wiped GitPrePushHook => artifact_path(a: GithooksPrePushArtifact) - FalsifierCadenceJob => artifact_path(a: FalsifierYamlArtifact) + FalsifierCadenceJob => ci_surface_artifact_wiped } } @@ -2622,12 +2617,20 @@ fn realization_handler_for_surface(surface: CommitWorkflowSurface) -> CommitWork } } -fn realization_artifact_for_surface(surface: CommitWorkflowSurface) -> GeneratedArtifact { +// The CI surfaces have NO generated artifact as of the 2026-08-15 wipe: ci.yml, falsifier.yml and +// falsifier-alert.yml are deleted and their registry rows are gone, so there is nothing for these +// three surfaces to name. The enrollment rows below are retained deliberately -- they ARE the +// obligations ledger the re-add queue is drawn from -- but a surface with no artifact answers the +// sentinel rather than a fabricated one, and the total function is gone rather than returning a +// plausible wrong artifact. +data ci_surface_artifact_wiped: String = "" + +fn realization_artifact_for_surface(surface: CommitWorkflowSurface) -> GeneratedArtifact? { match surface { - GithubActionsCiJob => CiYamlArtifact - GithubActionsCiRegenJob => CiYamlArtifact - GitPrePushHook => GithooksPrePushArtifact - FalsifierCadenceJob => FalsifierYamlArtifact + GithubActionsCiJob => none + GithubActionsCiRegenJob => none + GitPrePushHook => Present { value: GithooksPrePushArtifact } + FalsifierCadenceJob => none } } diff --git a/dag/gunbc/doc_graph_roots.dag b/dag/gunbc/doc_graph_roots.dag index 8253dd3e044..e0883b7c65f 100644 --- a/dag/gunbc/doc_graph_roots.dag +++ b/dag/gunbc/doc_graph_roots.dag @@ -126,15 +126,6 @@ data hand_authored_doc_binds: List = [ ], dissolution: PlanRetiresWhen { condition: unbound_dissolution(description: "the work this document plans lands and its subject entry_affected_by_touched_paths describes shipped behavior rather than a planned change; the row deletes with the document. Registered at subject grain: the systems bound here are the ones whose movement would make this document's purpose false, not every system its prose mentions.") }, }, - HandAuthoredDocBind { - home: PlanDoc, - slug: "affected-set-precompute-pruning", - primary_work: DeclarationRef { module_path: "v2.workflow.affected_set_floor_runner", decl_name: "floor_witness_run_disposition", field: WholeDeclaration }, - additional_works: [ - DeclarationRef { module_path: "v2.workflow.affected_set_floor_runner", decl_name: "floor_test_fn_declaration_edited", field: WholeDeclaration }, - ], - dissolution: PlanRetiresWhen { condition: unbound_dissolution(description: "the work this document plans lands and its subject floor_witness_run_disposition describes shipped behavior rather than a planned change; the row deletes with the document. Registered at subject grain: the systems bound here are the ones whose movement would make this document's purpose false, not every system its prose mentions.") }, - }, HandAuthoredDocBind { home: PlanDoc, slug: "algebra-grounding-unification-design", @@ -1025,7 +1016,6 @@ data hand_authored_doc_binds: List = [ additional_works: [ DeclarationRef { module_path: "gunbc.roadmap_authority", decl_name: "five_minute_ci_gate_program_note", field: WholeDeclaration }, DeclarationRef { module_path: "gunbc.roadmap_authority", decl_name: "roadmap_authority_for", field: WholeDeclaration }, - DeclarationRef { module_path: "gunbc.selection_degradation_receipt", decl_name: "selection_degradation_receipt_note", field: WholeDeclaration }, DeclarationRef { module_path: "gunbc.p1_retention_cohort_receipt", decl_name: "p1_retention_cohort_receipt_verdict", field: WholeDeclaration }, DeclarationRef { module_path: "gunbc.ci_cost_arc_closeout_receipt", decl_name: "end_to_end_residual", field: WholeDeclaration }, DeclarationRef { module_path: "gunbc.ci_cost_arc_closeout_receipt", decl_name: "retention_settle", field: WholeDeclaration }, diff --git a/dag/gunbc/falsifier_alert_admission.dag b/dag/gunbc/falsifier_alert_admission.dag deleted file mode 100644 index bbd01837cbc..00000000000 --- a/dag/gunbc/falsifier_alert_admission.dag +++ /dev/null @@ -1,145 +0,0 @@ -module gunbc.falsifier_alert_admission - -import std.types { NonEmptyStr, String } -import extdeps.github.actions { github_event_name_schedule, github_event_name_workflow_dispatch, workflow_run_activity_completed } -import extdeps.github.expressions { - Expression, ContextAccess, StringLiteral, LogicalOr, LogicalAnd, Equals, - Github, serialize_expression -} -import extdeps.github.workflow_run_event { - WorkflowRunEvent, - WorkflowRunEventObservation, - WorkflowRunEventObserved, - WorkflowRunEventMemberAbsent, - WorkflowRunEventMemberMalformed, - WorkflowRunEventMalformed, - WorkflowRunEventPayloadReadRefused -} - -data falsifier_alert_admission_purpose_note: String = "ALERT-1(c). THE PRE-EXECUTION TRUST WALL. This alert holds issues: write, so before it reads or acts on ANY content originating from an observed run it must establish that the run is the one it exists to observe. The threat is not exotic: workflow_run fires for runs of the named workflow on any branch and from any originating event, including one produced by a fork's pull request or an unapproved dispatch, and the alert then downloads an artifact from that run and renders its contents into an issue it has write access to. Without this wall, the content of an attacker-influenced run reaches a privileged writer.\n\nADMISSION IS THE CONJUNCTION OF FIVE FACTS, all of which must hold: the workflow is affected-set-falsifier, the repository is gunb-ai/gunbc, the head branch is main, the originating event is a schedule or an approved workflow_dispatch, and the activity is completed. Each is a separate coordinate and each refusal names which one failed — a single boolean 'not trusted' would tell an operator nothing about whether they are looking at a misconfiguration or an attack.\n\nIT IS TO BE ENFORCED TWICE, AND THAT IS NOT REDUNDANCY IN THE DESIGN §2 SENSE. NEITHER POINT IS WIRED YET: this change is ALERT-0..3 modeling and moves no behavior, so the live workflow still carries no job-level `if` and its embedded program does not call falsifier_alert_admit. Saying otherwise in the present tense is the rung inflation DESIGN §4b names — a carrier described by the guarantee it is designed to reach rather than the one it holds — and review 49460 caught this sentence doing exactly that. At cutover the generated workflow carries a job-level `if` derived from falsifier_alert_job_condition so the job does not start, and this program re-evaluates the same facts from the payload it reads itself. They are different mechanisms against different failure modes: the job-level guard is cheap and stops the runner from ever holding the token, but it is written in a foreign expression language and can be silently weakened by an edit to the workflow; the in-program check reads the payload the alert is actually about to act on, and so cannot be bypassed by a workflow edit. Neither subsumes the other, so neither is a second representation of the other — the shared authority is this module's predicate, which the workflow's condition is derived from." - -data falsifier_alert_observed_workflow_name: NonEmptyStr = "affected-set-falsifier" - -data falsifier_alert_workflow_identity_note: String = "THE TRIGGER MATCHES BY NAME BECAUSE THAT IS THE ONLY SHAPE GITHUB EXPOSES THERE; THE TRUST WALL DOES NOT. A workflow's display `name:` is a mutable string — it is whatever the `name:` key in the yaml says today, it is editable in any PR that touches the file, and two workflows may carry the same one. That is adequate as a coarse activation filter, where the cost of a wrong match is a job that starts and then refuses. It is NOT an identity for an authorization decision made by a program holding issues: write, because it means the answer to `is this the run I exist to observe` is decided by a renameable label.\n\nThe wall therefore also binds the workflow's FILE PATH, which is the stable identifier for `which workflow` — a workflow is the file, and renaming the display name does not move it. The path is checked in addition to, not instead of, the name: the name is what the trigger filtered on, so a mismatch between the two is itself a fact worth refusing on rather than silently preferring one. workflow_id (GitHub's numeric identifier for the workflow, stable across renames AND path moves) is decoded and carried so a future revision can pin it, but it is deliberately not compared yet: pinning it means writing a repository-specific integer into this module, which is a real fact that should be observed and recorded rather than typed from memory. Its dissolve-on is that observation." - -data falsifier_alert_expected_workflow_path: NonEmptyStr = ".github/workflows/falsifier.yml" - -data falsifier_alert_expected_repository: NonEmptyStr = "gunb-ai/gunbc" - -data falsifier_alert_expected_head_branch: NonEmptyStr = "main" - -data falsifier_alert_originating_event_note: String = "The admitted originating events are `schedule` and `workflow_dispatch`, and the workflow_dispatch arm carries a real caveat rather than being waved through. GitHub requires write access to dispatch a workflow, so a dispatch is already an authenticated act by someone with repository write — that is the sense in which it is `approved`, and it is the strongest statement this payload supports, because the event does not carry an approval record for the alert to verify independently. `push` and `pull_request` are deliberately NOT admitted even though the falsifier could in principle be triggered by them: a pull_request-originated run can carry a contributor's head, which is exactly the content this wall exists to keep away from a privileged writer, and a push-originated run is not part of the cadence this alert reports on. The head_branch check is a second, independent barrier on the same concern rather than a duplicate of it — an originating event can be legitimate while the head is not main, and a run on main can arrive from an event this alert should not report." - -type RepositoryField - = EnclosingRepository - | HeadRepository - -type FalsifierAlertAdmission - = AlertAdmitted { event: WorkflowRunEvent } - | AlertRefusedWorkflowNotObserved { observed: String, expected: NonEmptyStr } - | AlertRefusedWorkflowPathNotObserved { observed: String, expected: NonEmptyStr } - | AlertRefusedRepositoryNotOwned { field: RepositoryField, observed: String, expected: NonEmptyStr } - | AlertRefusedHeadBranchNotMain { observed: String, expected: NonEmptyStr } - | AlertRefusedOriginatingEventNotAdmitted { observed: String } - | AlertRefusedActivityNotCompleted { observed: String, expected: String } - | AlertRefusedEventUnreadable { observation: WorkflowRunEventObservation } - -fn falsifier_alert_originating_event_admitted(event_name: String) -> Bool { - event_name == github_event_name_schedule || event_name == github_event_name_workflow_dispatch -} - -fn falsifier_alert_admit_event(event: WorkflowRunEvent) -> FalsifierAlertAdmission { - if event.workflow_name != (falsifier_alert_observed_workflow_name as String) { - AlertRefusedWorkflowNotObserved { - observed: event.workflow_name, - expected: falsifier_alert_observed_workflow_name - } - } else if event.workflow_path != (falsifier_alert_expected_workflow_path as String) { - AlertRefusedWorkflowPathNotObserved { - observed: event.workflow_path, - expected: falsifier_alert_expected_workflow_path - } - } else if event.repository_full_name != (falsifier_alert_expected_repository as String) { - AlertRefusedRepositoryNotOwned { - field: EnclosingRepository, - observed: event.repository_full_name, - expected: falsifier_alert_expected_repository - } - } else if event.head_repository_full_name != (falsifier_alert_expected_repository as String) { - AlertRefusedRepositoryNotOwned { - field: HeadRepository, - observed: event.head_repository_full_name, - expected: falsifier_alert_expected_repository - } - } else if event.head_branch != (falsifier_alert_expected_head_branch as String) { - AlertRefusedHeadBranchNotMain { - observed: event.head_branch, - expected: falsifier_alert_expected_head_branch - } - } else if !falsifier_alert_originating_event_admitted(event_name: event.originating_event) { - AlertRefusedOriginatingEventNotAdmitted { observed: event.originating_event } - } else if event.activity != workflow_run_activity_completed { - AlertRefusedActivityNotCompleted { - observed: event.activity, - expected: workflow_run_activity_completed - } - } else { - AlertAdmitted { event: event } - } -} - -data falsifier_alert_head_repository_note: String = "head_repository is checked against the SAME expected repository as the enclosing repository, and the two checks are not a copy of one another. `repository` is where the workflow run lives; `head_repository` is where the code it ran CAME FROM, and on a fork-originated run those differ — that divergence is precisely the fork case, and it is the one shape where an admitted-looking run carries foreign content. Checking only the enclosing repository would admit exactly that run. They share a refusal variant because the remedy is the same (this is not our code, stop), but the variant names WHICH coordinate failed through a RepositoryField discriminator rather than leaving it to be inferred from the observed value. review 49380 caught that an earlier revision claimed the observed value made them distinguishable, which was not true: a consumer holding only the observed string cannot tell a fork-originated run (head_repository diverged — the attack shape) from a plain wrong-repo delivery, and those are different incidents even though both stop. The field is the fact; the observed value is evidence for it." - -fn falsifier_alert_admit(observation: WorkflowRunEventObservation) -> FalsifierAlertAdmission { - match observation { - WorkflowRunEventObserved { event: e } => falsifier_alert_admit_event(event: e) - WorkflowRunEventMemberAbsent { member: _ } => - AlertRefusedEventUnreadable { observation: observation } - WorkflowRunEventMemberMalformed { member: _, detail: _ } => - AlertRefusedEventUnreadable { observation: observation } - WorkflowRunEventMalformed { detail: _ } => - AlertRefusedEventUnreadable { observation: observation } - WorkflowRunEventPayloadReadRefused { path: _, cause: _ } => - AlertRefusedEventUnreadable { observation: observation } - } -} - -data falsifier_alert_no_bool_projection_note: String = "THERE IS DELIBERATELY NO falsifier_alert_is_admitted PREDICATE. An earlier revision carried one, and review 49400 was right to object: a Bool projection over FalsifierAlertAdmission throws away the located reason at exactly the boundary this module's purpose note argues it must be preserved, and once such a helper exists it is the convenient thing to reach for — a caller writes `if is_admitted` and the coordinate that failed is gone, which is the state this whole coproduct exists to prevent. Callers match on the admission and answer each arm; a caller that genuinely only needs a yes/no writes that match at its own use site, where the reason it is discarding is visible in the code discarding it." - -data falsifier_alert_job_condition_note: String = "The generated workflow's job-level condition is DERIVED from this module's constants rather than hand-typed into the YAML, so the two enforcement points cannot drift apart in what they consider admissible. The condition can only express the subset of the wall that GitHub's expression language can see in the event context — workflow name, head branch and originating event — which is why it is the cheap outer guard and not the wall itself: head_repository and the activity are re-read from the payload by the program. A condition that could express everything would still not remove the in-program check, for the reason the purpose note gives.\n\nIT IS BUILT AS A TYPED extdeps.github.expressions Expression AND SERIALIZED, not concatenated as text (review 49400). The earlier revision assembled the condition by nesting concat over raw expression fragments, which is a foreign-language program in normal form authored outside the module that owns that language — precisely the ExecutableSourceString class gunbc.falsifier_alert_residue declares in this same change as the thing to shrink. Emitting new residue while declaring residue is the failure mode worth catching, and the fix is the ordinary one: the expression grammar already had a model, it was missing two operators, so the operators landed there and this site selects from them." - -fn falsifier_alert_workflow_run_field(field: String) -> Expression { - ContextAccess { context: Github, path: ["event", "workflow_run", field] } -} - -data falsifier_alert_condition_distributed_note: String = "THE CONDITION IS BUILT IN DISTRIBUTED FORM — `A && B && schedule || A && B && dispatch` — rather than factored with a parenthesized alternation, and the repetition is deliberate. GitHub binds && tighter than ||, so the factored shape `A && B && (s || d)` REQUIRES the parentheses to mean what it reads as; without them it parses as `(A && B && s) || d`, whose right arm admits a workflow_dispatch run of ANY workflow on ANY branch. That is the trust wall failing open on its outer half while every in-program check still passes — the worst kind of defect here, because nothing downstream would notice.\n\nThe first attempt answered that by making extdeps.github.expressions parenthesize every Or. review 49430 refused it: that module is read in both directions and the parser has no grouping construct, so emission would have gained syntax ingest could not read (DESIGN §4). The distributed form needs no grouping at all — it is already correct under upstream's own precedence — so the hazard is answered at the authoring site and the shared grammar is untouched. Both arms are derived from the same constants, so they cannot disagree about the workflow or the branch." - -fn falsifier_alert_originating_event_arm(event_name: String) -> Expression { - LogicalAnd { - left: Equals { - left: falsifier_alert_workflow_run_field(field: "name"), - right: StringLiteral { value: falsifier_alert_observed_workflow_name as String } - }, - right: LogicalAnd { - left: Equals { - left: falsifier_alert_workflow_run_field(field: "head_branch"), - right: StringLiteral { value: falsifier_alert_expected_head_branch as String } - }, - right: Equals { - left: falsifier_alert_workflow_run_field(field: "event"), - right: StringLiteral { value: event_name } - } - } - } -} - -fn falsifier_alert_job_condition_expression() -> Expression { - LogicalOr { - left: falsifier_alert_originating_event_arm(event_name: github_event_name_schedule), - right: falsifier_alert_originating_event_arm(event_name: github_event_name_workflow_dispatch) - } -} - -fn falsifier_alert_job_condition() -> String { - serialize_expression(expression: falsifier_alert_job_condition_expression()) -} diff --git a/dag/gunbc/falsifier_alert_decision.dag b/dag/gunbc/falsifier_alert_decision.dag deleted file mode 100644 index 695c37a6a31..00000000000 --- a/dag/gunbc/falsifier_alert_decision.dag +++ /dev/null @@ -1,710 +0,0 @@ -module gunbc.falsifier_alert_decision - -import std.types { NonEmptyStr, String, EpochMs } -import std.measure { Millisecond, millisecond, millisecond_count } -import extdeps.github.workflow_run_event { WorkflowRunEvent } -import extdeps.github.workflow_runs { - WorkflowRunConclusion, - Success, Failure, Cancelled, Neutral, Skipped, TimedOut, ActionRequired, StartupFailure -} -import gunbc.falsifier_alert_admission { - FalsifierAlertAdmission, - AlertAdmitted, - AlertRefusedWorkflowNotObserved, - AlertRefusedWorkflowPathNotObserved, - AlertRefusedRepositoryNotOwned, - AlertRefusedHeadBranchNotMain, - AlertRefusedOriginatingEventNotAdmitted, - AlertRefusedActivityNotCompleted, - AlertRefusedEventUnreadable -} -import gunbc.falsifier_alert_state { - FirstRedStanding, FirstRedObserved, FirstRedUnknownBeforeTracking, - FalsifierAlertState, - FalsifierAlertStateDecoding, - CurrentState, LegacyStateWithoutLastNotification, StateAbsent, StateMalformed, - falsifier_alert_heartbeat_window -} -import gunbc.floor_component_receipt_document { - FloorComponentReceiptDocument, - FloorComponentReceiptDecoding, - ReceiptSubjectMatch, - ComponentAlertSummary, - FloorComponentFailureMode, floor_component_failure_mode_tag, - ComponentOutcomeRead, floor_component_outcome_wire_tag, - strict_natural_of_lexeme -} -import extdeps.github.issues { Issue } -import gunbc.falsifier_lane { - FalsifierRouting, RoutedToOwner, RoutingLaneUndetermined, RoutingOwnerUndeclared -} - -data falsifier_alert_decision_purpose_note: String = "ALERT-4. THE WHOLE DECISION, AS A PURE FUNCTION, PERFORMING NO GITHUB CALLS. alert_decision takes an admission outcome, a receipt outcome, the issue's own decoded state, the current instant, the escalation recipient and the lane routings, and returns one terminal AlertDecision. It opens nothing, comments nothing, closes nothing and reads nothing: the effect plan realizes the decision, and this module only decides.\\n\\nWHY THE PURITY IS THE POINT AND NOT A STYLE PREFERENCE. The moment the core reads the world it stops being testable by fixtures — every property below would need a live issue, a live run and a live clock to exercise, which means the properties that matter most (a heartbeat fires at exactly the window boundary; a malformed marker never opens a new incident; every notifying artifact carries the escalation mention) would be checked by nobody. Every fact this function needs arrives as a parameter, so each property is a fixture and a comparison, and the arms that are hardest to reach in production are the cheapest to prove here." - -data falsifier_alert_decision_arm_separation_note: String = "THE ALERT'S OWN FAILURES ARE DISTINGUISHED BY CAUSE, AND THEY NOTIFY. Two axes, deliberately not fused. WHOSE failure it is decides whether anyone is told: an UNTRUSTED event produces RefuseUntrustedEvent and says nothing, because a refusal to act on an unadmitted run is the wall working and making it notify would hand an attacker a way to page an operator on demand. Every other failure here is OURS — a trusted run we could not finish processing — and completing the workflow in silence is the original incident's exact shape one layer up, so those notify through NotifyAlertControllerUnavailable.\\n\\nWHICH failure it is decides who investigates, and that is AlertControllerCause: ControllerReceiptMalformed means the receipt did not decode and the remedy is in the floor's writer; ControllerReceiptMismatch means it decoded perfectly about a DIFFERENT RUN, so the remedy is in the artifact plumbing that fetched it; ControllerMarkerMalformed means the issue's own marker is corrupt and a human must read the body; ControllerIssueLookupRefused means the search could not be performed, which is not the same as finding nothing; ControllerMultipleOpenIssues means the alert already lost track of its own incident; ControllerRoutingJoinRefused means whoever computed the routings disagrees with the receipt about which components failed.\\n\\nSix different investigations, carried as a typed cause rather than a sentence. A single `Refused` arm holding a string would make the alert's most important output — what an operator reads at 3am when the observer itself has stopped working — something to be parsed rather than dispatched on.\\n\\nTHIS NOTE PREVIOUSLY DESCRIBED FOUR TOP-LEVEL REFUSE ARMS THAT NO LONGER EXIST. The operator verdict moved these cases from silent refusals to notifications, the arms were left declared but uninhabited beside the inhabited notify arms, and this paragraph kept describing the dead ones — two representations of one failure, with the prose pointing at the representation nothing constructs. Caught by review 49947; the dead arms are deleted and the cause coproduct is the single authority." - -type EscalationRecipient - = EscalationDeclared { handle: NonEmptyStr } - | EscalationUndeclared { cause: NonEmptyStr } - -data escalation_handle_is_required_note: String = "AN ALERT NOTIFICATION CARRIES A HANDLE, NOT A DISCUSSION OF WHETHER THERE IS ONE. The first revision typed the field as EscalationRecipient and claimed that made `every notifying artifact contains the mention` structurally true. It did not: EscalationUndeclared inhabits that type, so a notification with no mention at all was constructible and typechecked. The type forced an AUTHOR to think about the recipient; it did not force the ARTIFACT to have one, and only the second is the property the incident demanded.\\n\\nSo AlertNotification carries escalation_handle: NonEmptyStr and the undeclared case is lifted OUT of the notification into a decision arm, RefuseEscalationRecipientUndeclared, which is reached before any notifying arm can be built. The alert with nobody to tell refuses loudly instead of quietly notifying nobody — a comment that mentions no one looks identical to a working alert in every log and dashboard, which is how the original defect survived two days.\\n\\nLane ownership is NOT symmetric with this and stays absent-able. An unowned lane is a real, renderable fact — the issue says so by name — because the question `whose component broke` may honestly have no answer yet, while `who is told the falsifier is broken` may not." - -data falsifier_alert_three_facts_note: String = "THREE FACTS, THREE CARRIERS, NEVER FUSED: the GLOBAL ESCALATION RECIPIENT (who is told that the falsifier is broken at all), the LANE-SPECIFIC OWNER (who owns the particular component that failed), and the ISSUE STATE (what has already been said about this incident). They are easy to fuse and fusing them is a real loss.\\n\\nThe live shape makes the trap concrete: the lane owner roster in gunbc.falsifier_lane is EMPTY, so every lane routes to RoutingOwnerUndeclared, while exactly one global handle exists. It is tempting to read the global handle as the owner of every lane — it is the only handle there is — but that would fabricate ownership facts nobody asserted, and would make the undeclared-owner gap invisible precisely because something plausible got rendered in its place.\\n\\nSo the rule is symmetric and both halves are witnessed. An UNDECLARED LANE OWNER MUST NOT SUPPRESS GLOBAL ESCALATION: the falsifier being red is escalated whether or not anyone owns the failing lane, because the escalation recipient's question is `is the observer working` and the lane owner's question is `whose component broke`. And AN UNDECLARED LANE OWNER MUST STILL BE RENDERABLE: the issue says the lane has no owner, by name, so the gap is counted and located rather than papered over by the global mention standing in for it." - -type AlertNotification { - escalation_handle: NonEmptyStr - routings: List -} - -data no_action_reason_note: String = "NoAction carries a typed REASON rather than being a bare arm, because two genuinely different situations reach it: a run whose conclusion is not actionable at all (cancelled, skipped, timed out — the alert has nothing to say about a run that did not conclude green or red), and a green run with no open incident (nothing to close, nothing to announce). The remedy differs — the first may warrant looking at why runs keep being cancelled, the second is the steady state — so although both produce no effect, fusing them would discard the distinction at the only point anything records it. This is a reason on one arm rather than two arms because the brief's terminal set names one NoAction and the EFFECT is genuinely identical; what must not be lost is why." - -data non_success_conclusion_policy_note: String = "A RUN THAT NEVER REACHED A CORPUS VERDICT IS NOT A GREEN CORPUS, and the first revision mapped six conclusions to NoAction as though it were. That is the empty-observation narrow at the top of the alert: the falsifier did not run, so nothing is known, and `nothing is known` was rendered as `nothing to say`. A falsifier that starts failing at startup every time would have gone unreported indefinitely while every run produced a clean NoAction.\\n\\nThe policy, by what the conclusion actually says. TIMED_OUT and STARTUP_FAILURE mean the OBSERVER is broken — it never got far enough to judge the corpus — so they notify: NotifyObserverUnavailable, which is the escalation recipient's own question. SKIPPED, NEUTRAL and ACTION_REQUIRED mean the run was prevented or is waiting on a human, which is a configuration fact rather than an observer fault, so they surface as their own NoActionReason arm and stay countable rather than being folded in with a green.\\n\\nCANCELLED IS SPLIT, because one tag covers three situations with three remedies. A run superseded by a newer run on the same ref is the normal, healthy case and must not page anyone. An operator cancelling deliberately is also fine. An unexplained cancellation is neither, and it is the one worth seeing. The event payload cannot distinguish them today — GitHub does not say who cancelled a run or why in the workflow_run envelope — so the arm records the distinction as UNRESOLVED rather than guessing: CancellationUnexplained is its own reason, counted, with the dissolve-on named. Choosing `supersession` because it is the common case would be the fabricated-plausible-output DESIGN forbids, and choosing `page someone` would make every ordinary force-push noisy." - -data conclusion_decided_before_receipt_note: String = "TimedOut and StartupFailure cannot reach this fold: conclusion_is_observer_unavailable routes them before a receipt is required, which is the whole point of the reordering. They still need an arm because the match is total over the closed conclusion coproduct, and the arm says what is true — this conclusion was decided upstream — rather than picking one of the neighbouring reasons.\\n\\nNaming it honestly rather than folding it into RunPreventedByConfiguration matters because the two are unreachable for opposite reasons. A configuration-prevented run really did reach here and really produces no action; these two never arrive, and if one ever does it means the routing predicate and this fold have diverged. A shared arm would make that divergence invisible; a distinct one makes it a countable, named observation that should be impossible." - -type NoActionReason - = GreenWithNoOpenIncident - | ConclusionDecidedBeforeReceipt { conclusion_tag: NonEmptyStr } - | RunPreventedByConfiguration { conclusion_tag: NonEmptyStr } - | CancellationUnexplained - -data next_state_on_every_writing_arm_note: String = "EVERY WRITING ARM CARRIES THE COMPLETE NEXT STATE, because the alternative is that ALERT-5 and ALERT-6 each re-derive the marker policy from the arm name — a second implementation of one rule, in the layer furthest from the witnesses. The arm knowing `a heartbeat happened` is not the same as the arm knowing what to write, and the gap between them is exactly where first_red gets reset by accident.\\n\\nThe policy, stated once, here. A FIRST RED sets first_red and last_notification_at both to now: the incident starts and is announced in the same act. A HEARTBEAT preserves first_red — the incident did not restart, only the silence ended — and moves last_notification_at to now. A SILENT REFRESH preserves BOTH, which is the whole point of it: the body is rewritten with current facts and the throttle clock does not move, because nothing was sent. A LEGACY MIGRATION preserves the first_red it recovered and writes the current signature with last_notification_at = now.\\n\\nA CHANGED CLASS PRESERVES first_red, and this is the one that had to be decided rather than inherited. The falsifier has been red continuously; what changed is which component is failing. Restarting first_red would erase how long the observer has been broken — the single most useful number on the issue — and would do it precisely when the incident got worse. So the incident's age is a property of the unbroken red period, not of the current class, and the arm says so instead of leaving it to be guessed downstream." - -data observer_incident_note: String = "THE OBSERVER-UNAVAILABLE ARMS ARE COMPLETE WRITING INSTRUCTIONS, NOT ANNOUNCEMENTS. The first revision's NotifyObserverUnavailable carried a conclusion tag and a notification and nothing else — no create-or-update decision, no issue, no next state — so ALERT-5 and ALERT-6 would each have had to invent that policy from the arm name, which is the second-implementation problem this module was built to avoid.\\n\\nThey are split by what the effect actually is. OpenObserverIncident creates; RefreshObserverIncident updates a named issue. Both carry the next state marker, so the same throttle that governs a red incident governs this one and a permanently broken observer does not comment every four hours.\\n\\nAND THE CONTROLLER'S OWN FAILURES NOW NOTIFY. A TRUSTED run whose receipt is missing, malformed or mismatched, or whose marker is corrupt, previously produced a non-notifying refusal — so the alert workflow completed successfully while the thing it exists to do had not happened, which is the original incident's exact shape one layer up. NotifyAlertControllerUnavailable is that report. It carries a typed cause and an issue disposition, and two constraints ride with it: it never renders receipt content, because a receipt that failed to decode is content we could not read and may not have been written by the floor; and it never overwrites the marker, because a corrupt marker is the only record of the incident it belongs to.\\n\\nUNTRUSTED events stay silent, and that asymmetry is the point. A refusal to act on an unadmitted run is the wall working; making it notify would hand an attacker a way to page an operator on demand." - -type AlertControllerCause - = ControllerReceiptMalformed { decoding: FloorComponentReceiptDecoding } - | ControllerReceiptMismatch { mismatch: ReceiptSubjectMatch } - | ControllerMarkerMalformed { detail: String } - | ControllerIssueLookupRefused { cause: NonEmptyStr } - | ControllerMultipleOpenIssues { count: Int } - | ControllerRoutingJoinRefused { mismatch: RoutingJoinMismatch } - -type ControllerIssueDisposition - = ControllerIssueUntouched - | ControllerIssueObserved { issue: Issue } - -type AlertDecision - = NoAction { reason: NoActionReason } - | OpenIssue { signature: IncidentSignature, next_state: FalsifierAlertState, notification: AlertNotification } - | RefreshIssueWithoutNotification { issue: Issue, signature: IncidentSignature, next_state: FalsifierAlertState, silent_for: Millisecond } - | RefreshAndNotifyChangedClass { issue: Issue, previous: IncidentSignature, current: IncidentSignature, next_state: FalsifierAlertState, notification: AlertNotification } - | RefreshAndNotifyHeartbeat { issue: Issue, signature: IncidentSignature, next_state: FalsifierAlertState, silent_for: Millisecond, notification: AlertNotification } - | NotifyGreenAndClose { issue: Issue, notification: AlertNotification } - | NotifyLegacyStateMigration { issue: Issue, first_red: FirstRedStanding, signature: IncidentSignature, next_state: FalsifierAlertState, notification: AlertNotification } - | OpenObserverIncident { conclusion_tag: NonEmptyStr, next_state: FalsifierAlertState, notification: AlertNotification } - | RefreshObserverIncident { issue: Issue, conclusion_tag: NonEmptyStr, next_state: FalsifierAlertState, silent_for: Millisecond, notification: AlertNotification } - | RefreshObserverIncidentWithoutNotification { issue: Issue, conclusion_tag: NonEmptyStr, next_state: FalsifierAlertState, silent_for: Millisecond } - | NotifyAlertControllerUnavailable { cause: AlertControllerCause, issue_disposition: ControllerIssueDisposition, notification: AlertNotification } - | RefuseUntrustedEvent { admission: FalsifierAlertAdmission } - | RefuseEscalationRecipientUndeclared { cause: NonEmptyStr } - -data receipt_input_note: String = "The receipt arrives as its DECODING plus its SUBJECT MATCH, not as a bare document, because the two failures are different arms of the result and a decoded-but-mismatched receipt is not a decode failure. Passing an already-unwrapped document would force the caller to collapse them before calling, which is exactly where the distinction would be lost." - -type AlertReceiptInput - = ReceiptAdmitted { document: FloorComponentReceiptDocument } - | ReceiptSubjectRejected { mismatch: ReceiptSubjectMatch } - | ReceiptUndecodable { decoding: FloorComponentReceiptDecoding } - -data conclusion_actionability_note: String = "Only Success and Failure drive the alert. GitHub's other conclusions describe a run that did not reach a verdict about its subject — Cancelled, Skipped, TimedOut, Neutral, ActionRequired, StartupFailure — and inventing a red from any of them would be the fabricated-plausible-output DESIGN §5 forbids: a startup failure says nothing whatsoever about whether the corpus is green. The match is total over the closed coproduct, so a conclusion added upstream is a compile error here rather than an arm that silently behaves like one of these." - -fn conclusion_tag(c: WorkflowRunConclusion) -> NonEmptyStr { - match c { - Success => "success" as NonEmptyStr - Failure => "failure" as NonEmptyStr - Cancelled => "cancelled" as NonEmptyStr - Neutral => "neutral" as NonEmptyStr - Skipped => "skipped" as NonEmptyStr - TimedOut => "timed_out" as NonEmptyStr - ActionRequired => "action_required" as NonEmptyStr - StartupFailure => "startup_failure" as NonEmptyStr - } -} - -data signature_derivation_note: String = "THE SIGNATURE IS DERIVED FROM THE TYPED COMPONENT SUMMARIES, not from rendered prose and not from a raw JSON scan. ALERT-3.5 made index, label, outcome and failure_mode strictly decoded fields precisely so this function could key on them; the four together are the grain at which a red that CHANGED CLASS is distinguishable from a red that merely persists. failure_mode is in the key because outcome alone is many-to-one — Infra and WitnessRed both surface as `failed` — so without it a change of owner reads as no change at all.\\n\\nAn empty unsuccessful set under a Failure conclusion still produces a signature rather than being treated as green: the run failed, and a receipt that names no failing component is itself a discrepancy the alert should show unchanged across windows rather than silently reclassify." - -data incident_identity_structure_note: String = "THE INCIDENT IDENTITY IS A SET OF TYPED MEMBERS, NOT A JOINED STRING, and both halves of that sentence were defects in the first revision. It mapped the summaries in receipt order and joined them with a pipe, which made the identity depend on two things it has no business depending on.\\n\\nORDER. The floor emits components in whatever order it walked them, so the same failing set arriving in a different order produced a different string and read as a CHANGED INCIDENT — the alert would announce a new class and re-notify while nothing about the failure had changed. Sorting the members by index fixes it at the identity level rather than by hoping the producer is stable.\\n\\nDELIMITERS. index:label:failure_mode:outcome joined by | is ambiguous the moment a label contains a colon or a pipe, and labels are human-authored component names. Two structurally different populations could serialize to one string, or one population could parse two ways — an identity that collides is not an identity. The label is therefore OUT of the identity entirely: it is display text, while index already identifies the component uniquely (the receipt decoder now refuses a population whose indices are not unique, so that uniqueness is a checked property rather than an assumption). What remains — index, outcome class, failure mode — are the facts that decide whether this is the same incident.\\n\\nComparison is over the STRUCTURED SET. Serialization exists only for writing the marker, and it is canonical because it renders the already-sorted members; nothing compares the rendered forms." - -type ComponentIncidentIdentity { - index: Nat - outcome_tag: NonEmptyStr - failure_mode_tag: NonEmptyStr -} - -type IncidentSignature { - members: List -} - -fn component_incident_identity_of(s: ComponentAlertSummary) -> ComponentIncidentIdentity { - ComponentIncidentIdentity { - index: s.index, - outcome_tag: floor_component_outcome_wire_tag(r: s.outcome) as NonEmptyStr, - failure_mode_tag: floor_component_failure_mode_tag(m: s.failure_mode) as NonEmptyStr - } -} - -fn incident_identity_eq(left: ComponentIncidentIdentity, right: ComponentIncidentIdentity) -> Bool { - left.index == right.index - && (left.outcome_tag as String) == (right.outcome_tag as String) - && (left.failure_mode_tag as String) == (right.failure_mode_tag as String) -} - -fn incident_members_contain(xs: List, needle: ComponentIncidentIdentity) -> Bool { - fold(xs, init: false, f: (acc, x) => acc || incident_identity_eq(left: x, right: needle)) -} - -fn incident_members_sorted_by_index(xs: List) -> List { - fold(xs, init: [], f: (acc, x) => incident_members_insert(sorted: acc, member: x)) -} - -fn incident_members_insert(sorted: List, member: ComponentIncidentIdentity) -> List { - concat( - concat(filter(sorted, y => y.index < member.index), [member]), - filter(sorted, y => !(y.index < member.index)) - ) -} - -fn alert_signature_of(doc: FloorComponentReceiptDocument) -> IncidentSignature { - IncidentSignature { - members: incident_members_sorted_by_index( - xs: map(doc.unsuccessful_summaries, x => component_incident_identity_of(s: x)) - ) - } -} - -fn incident_signature_eq(left: IncidentSignature, right: IncidentSignature) -> Bool { - count(left.members) == count(right.members) - && fold(left.members, init: true, f: (acc, m) => acc && incident_members_contain(xs: right.members, needle: m)) - && fold(right.members, init: true, f: (acc, m) => acc && incident_members_contain(xs: left.members, needle: m)) -} - -fn incident_identity_render(m: ComponentIncidentIdentity) -> String { - concat(concat(m.index as String, ":"), concat(m.outcome_tag as String, concat(":", m.failure_mode_tag as String))) -} - -fn incident_signature_render(sig: IncidentSignature) -> NonEmptyStr { - if count(sig.members) == 0 { - "no-unsuccessful-components" as NonEmptyStr - } else { - join(map(sig.members, m => incident_identity_render(m: m)), "|") as NonEmptyStr - } -} - -data notification_always_carries_escalation_note: String = "EVERY NOTIFYING ARM CARRIES AN AlertNotification, AND EVERY AlertNotification CARRIES THE ESCALATION RECIPIENT. That is a construction property rather than a convention: the four notifying arms cannot be built without one, because the field is required, so an author adding a fifth notifying arm has to supply it to make the program typecheck.\\n\\nThis is the structural form of the defect that started this whole lane. The alert reached its recipient once per incident because the mention lived only in the issue body, and a mention notifies when it is CREATED — body edits send nothing — so the heartbeat and changed-class comments, the artifacts carrying current state, notified nobody for two days while the mechanism reported success. A convention that says `remember to include the mention` is exactly what failed there. The non-notifying arms deliberately do NOT carry one: RefreshIssueWithoutNotification edits a body and sends nothing by design, and giving it a notification field would invite someone to use it." - -fn alert_notification(handle: NonEmptyStr, routings: List) -> AlertNotification { - AlertNotification { escalation_handle: handle, routings: routings } -} - -data decision_predicates_are_witness_surface_note: String = "THE BOOL HELPERS BELOW ARE A WITNESS SURFACE, NOT A DISPATCH SURFACE, AND THE DISTINCTION IS THE ONLY THING MAKING THEM LEGITIMATE. alert_decision_notifies, notification_escalates, routing_lacks_owner and notification_has_unowned_routing exist so a claim can assert a structural property across several arms at once — `every notifying arm carries the escalation mention` is a statement about five arms, and writing it as five separate matches would state the property five times and let a sixth arm be added without it.\\n\\nNo production code calls them, and none may. An effect plan branching on alert_decision_notifies would be exactly the predicate dissolution this lane already refused twice (review 49400, and the state module's own no-notifies-bool argument): the arms do not notify the SAME THING, so a Bool answering only `does this notify` erases the instruction at the one boundary where the caller is about to choose what to say. The realization matches AlertDecision and reads the arm it landed on.\\n\\nThis is stated rather than enforced because nothing in the substrate today distinguishes a witness caller from a production one. It is therefore a convention, and named as one — a reviewer flagged these helpers as the shape that normally trips predicate dissolution, and they were right to look; what makes them safe is a fact about their call sites that no mechanism holds. The trigger for climbing it: if the effect plan ever imports this module, the import list is the place to check." - -fn alert_decision_notifies(d: AlertDecision) -> Bool { - match d { - OpenIssue { signature: _, notification: _ } => true - RefreshAndNotifyChangedClass { previous: _, current: _, notification: _ } => true - RefreshAndNotifyHeartbeat { signature: _, silent_for: _, notification: _ } => true - NotifyGreenAndClose { notification: _ } => true - NotifyLegacyStateMigration { first_red: _, signature: _, notification: _ } => true - RefreshIssueWithoutNotification { signature: _, silent_for: _ } => false - NoAction { reason: _ } => false - RefuseUntrustedEvent { admission: _ } => false - RefuseEscalationRecipientUndeclared { cause: _ } => false - OpenObserverIncident { conclusion_tag: _, next_state: _, notification: _ } => true - RefreshObserverIncident { issue: _, conclusion_tag: _, next_state: _, silent_for: _, notification: _ } => true - RefreshObserverIncidentWithoutNotification { issue: _, conclusion_tag: _, next_state: _, silent_for: _ } => false - NotifyAlertControllerUnavailable { cause: _, issue_disposition: _, notification: _ } => true - } -} - -fn alert_decision_notification(d: AlertDecision) -> AlertNotification? { - match d { - OpenIssue { signature: _, notification: n } => Present { value: n } - RefreshAndNotifyChangedClass { previous: _, current: _, notification: n } => Present { value: n } - RefreshAndNotifyHeartbeat { signature: _, silent_for: _, notification: n } => Present { value: n } - NotifyGreenAndClose { notification: n } => Present { value: n } - NotifyLegacyStateMigration { first_red: _, signature: _, notification: n } => Present { value: n } - RefreshIssueWithoutNotification { signature: _, silent_for: _ } => none - NoAction { reason: _ } => none - RefuseUntrustedEvent { admission: _ } => none - RefuseEscalationRecipientUndeclared { cause: _ } => none - OpenObserverIncident { conclusion_tag: _, next_state: _, notification: n } => Present { value: n } - RefreshObserverIncident { issue: _, conclusion_tag: _, next_state: _, silent_for: _, notification: n } => Present { value: n } - RefreshObserverIncidentWithoutNotification { issue: _, conclusion_tag: _, next_state: _, silent_for: _ } => none - NotifyAlertControllerUnavailable { cause: _, issue_disposition: _, notification: n } => Present { value: n } - } -} - -data escalation_survives_undeclared_owner_note: String = "The predicate that makes the escalation/ownership separation checkable: a notification escalates exactly when the escalation recipient is declared, and that answer does not consult the routings at all. An undeclared lane owner therefore cannot suppress escalation, and — the mirror, which is the half that is easy to lose — a declared lane owner cannot substitute for a missing escalation recipient either. Both directions are witnessed." - -fn notification_escalates(n: AlertNotification) -> Bool { - (n.escalation_handle as String) != "" -} - -fn routing_lacks_owner(r: FalsifierRouting) -> Bool { - match r { - RoutedToOwner { index: _, lane: _, owner: _ } => false - RoutingLaneUndetermined { index: _, cause: _ } => true - RoutingOwnerUndeclared { index: _, lane: _, cause: _ } => true - } -} - -fn notification_has_unowned_routing(n: AlertNotification) -> Bool { - fold(n.routings, init: false, f: (acc, r) => acc || routing_lacks_owner(r: r)) -} - -data issue_observation_note: String = "NO OPEN ISSUE AND NO STATE MARKER ARE DIFFERENT FACTS, AND FUSING THEM PRODUCED TWO LIVE DEFECTS. The first revision took only the state decoding, so StateAbsent — which means `the issue body carried no marker` — was read as `there is no incident`. Against an issue that predates the marker format, or one a human opened by hand, that meant a red run OPENED A SECOND ISSUE for an incident already tracked, and a green run reported GreenWithNoOpenIncident and never closed the first one. Both are silent; both look like the alert working.\\n\\nThe observation therefore comes first and the marker is a property of a body that exists. MultipleOpenAlertIssues is its own arm rather than `take the first`: two open alert issues means the alert already lost track of itself, and picking one would compound that by writing to an arbitrary half of a split incident. AlertIssueLookupRefused is its own arm because a failed lookup is not an absence — answering `no issue` when the search could not be performed is the empty-observation narrow, and it would open a duplicate on every red until the lookup recovered." - -type AlertIssueObservation - = NoOpenAlertIssue - | OneOpenAlertIssue { issue: Issue, state: FalsifierAlertStateDecoding } - | MultipleOpenAlertIssues { issues: List } - | AlertIssueLookupRefused { cause: NonEmptyStr } - -data readable_incident_state_note: String = "THE MALFORMED MARKER IS PEELED OFF ONCE, AND WHAT REMAINS CANNOT BE MALFORMED. AlertIncidentState is the state a verdict fold is allowed to see: absent, current, or legacy. StateMalformed has no image in it, so the green fold and the red fold cannot re-decide the corrupt-marker question — not because they are careful, but because there is no arm to write it in.\\n\\nThis replaces the shape this module first had, where the guard sat in alert_decision AND again in each of the two folds. All three agreed, so nothing was wrong; what was wrong was that three copies of one rule can only stay in agreement by diligence, and a fourth fold added later would have started with no answer at all. A discriminating RED found this: deleting the outer guard left every claim green, which is what a redundant check looks like from the outside. The rule now lives at exactly one seam, and the two folds are total over a coproduct in which the bad state does not exist." - -type AlertIncidentState - = NoIncidentIssue - | IncidentIssueWithoutMarker { issue: Issue } - | IncidentCurrent { issue: Issue, state: FalsifierAlertState } - | IncidentLegacy { issue: Issue, first_red: FirstRedStanding, signature: NonEmptyStr } - -type AlertIncidentStateReading - = IncidentReadable { state: AlertIncidentState } - | IncidentUnreadable { detail: String } - | IncidentIndeterminate { cause: AlertControllerCause } - -fn alert_incident_state_of(observation: AlertIssueObservation) -> AlertIncidentStateReading { - match observation { - NoOpenAlertIssue => IncidentReadable { state: NoIncidentIssue } - MultipleOpenAlertIssues { issues: xs } => - IncidentIndeterminate { cause: ControllerMultipleOpenIssues { count: count(xs) } } - AlertIssueLookupRefused { cause: c } => - IncidentIndeterminate { cause: ControllerIssueLookupRefused { cause: c } } - OneOpenAlertIssue { issue: iss, state: decoding } => - match decoding { - StateAbsent => IncidentReadable { state: IncidentIssueWithoutMarker { issue: iss } } - CurrentState { state: s } => IncidentReadable { state: IncidentCurrent { issue: iss, state: s } } - LegacyStateWithoutLastNotification { first_red: f, signature: sig } => - IncidentReadable { state: IncidentLegacy { issue: iss, first_red: f, signature: sig } } - StateMalformed { detail: d } => IncidentUnreadable { detail: d } - } - } -} - -data marker_signature_readback_note: String = "THE STORED MARKER IS READ BACK INTO THE STRUCTURE, NOT COMPARED AS TEXT. Comparing the rendered strings would work today — the identity is now sorted, and index, outcome tag and failure-mode tag are all delimiter-free closed vocabularies, so the rendering is unambiguous — but it would be correct only by coincidence of what the members happen to contain, and the coincidence is exactly what broke the first version when a label was in the key. Reading it back means the comparison is over the SET in both directions, and a rendering change cannot silently become a behavioural change.\\n\\nThis is the same grammar read backwards: incident_signature_render writes `index:outcome:mode` members joined by |, and this reads them — and the index goes through strict_natural_of_lexeme, the SAME cardinal check the receipt decoder applies to the same semantic, rather than a bare parse. A stored signature is a hand-editable string in an issue body, so `-1` or `6.5` there is at least as reachable as it is on the wire; re-minting a weaker parse for the readback would have left the fail-open exactly where the marker is most exposed. A member that does not parse into three parts refuses by producing no signature, which makes the marker malformed rather than making it compare unequal — an unreadable marker must not read as `the incident changed` and trigger a notification about nothing." - -fn nth_string(xs: List, n: Nat) -> String? { - fold(xs, init: { i: 0, found: none }, f: (acc, x) => - if acc.i == n { { i: acc.i + 1, found: Present { value: x } } } else { { i: acc.i + 1, found: acc.found } } - ).found -} - -fn incident_identity_of_rendered(part: String) -> ComponentIncidentIdentity? { - let fields = split(s: part, delimiter: ":") - if count(fields) != 3 { - none - } else { - match nth_string(xs: fields, n: 0) { - Absent => none - Present { value: idx } => - match nth_string(xs: fields, n: 1) { - Absent => none - Present { value: outcome } => - match nth_string(xs: fields, n: 2) { - Absent => none - Present { value: mode } => - if outcome == "" || mode == "" { - none - } else { - match strict_natural_of_lexeme(text: idx) { - Absent => none - Present { value: n } => - Present { value: ComponentIncidentIdentity { - index: n, - outcome_tag: outcome as NonEmptyStr, - failure_mode_tag: mode as NonEmptyStr - } } - } - } - } - } - } - } -} - -fn alert_signature_of_marker(marker: NonEmptyStr) -> IncidentSignature? { - if (marker as String) == "no-unsuccessful-components" { - Present { value: IncidentSignature { members: [] } } - } else { - fold(split(s: marker as String, delimiter: "|"), init: Present { value: IncidentSignature { members: [] } }, f: (acc, part) => - match acc { - Absent => none - Present { value: sig } => - match incident_identity_of_rendered(part: part) { - Absent => none - Present { value: m } => Present { value: IncidentSignature { members: concat(sig.members, [m]) } } - } - }) - } -} - -data routing_exact_join_note: String = "THE ROUTINGS ARE JOINED TO THE FAILING SET, NOT TRUSTED AS INPUT. They arrive as a parameter, which means nothing in the type stops a caller passing routings for the wrong run, a stale set from the previous incident, a duplicate, or an empty list. Each of those produces an issue that names the wrong owners or no owners while looking entirely normal, and the alert is the thing an operator trusts to tell them who to talk to.\\n\\nSo the join is exact and by index, the same identity the incident signature is keyed on and the same one the receipt decoder now proves unique: every failing component has exactly one routing, no routing names a component that is not failing, and no index is routed twice. Any of the three refuses with the offending indices named rather than being silently dropped or padded — a missing routing is not `route to nobody`, it is a defect in whoever computed the routings.\\n\\nThis is an accept-and-join rather than deriving the routing inside the decision, because the lane roster is a repository fact the decision has no business reading and holding it here would put a second copy of lane ownership inside the alert. The join is what makes the accepted input safe." - -type RoutingJoinMismatch - = RoutingsMissingForComponents { indices: List } - | RoutingsForNonFailingComponents { indices: List } - | RoutingsDuplicated { indices: List } - -fn routing_index(r: FalsifierRouting) -> Nat { - match r { - RoutedToOwner { index: i, lane: _, owner: _ } => i - RoutingLaneUndetermined { index: i, cause: _ } => i - RoutingOwnerUndeclared { index: i, lane: _, cause: _ } => i - } -} - -fn nat_list_contains(xs: List, needle: Nat) -> Bool { - fold(xs, init: false, f: (acc, x) => acc || x == needle) -} - -fn nat_list_occurrences(xs: List, needle: Nat) -> Nat { - fold(xs, init: 0, f: (acc, x) => if x == needle { acc + 1 } else { acc }) -} - -fn routing_join_check( - failing: List, - routings: List -) -> RoutingJoinMismatch? { - let failing_indices = map(failing, m => m.index) - let routed_indices = map(routings, r => routing_index(r: r)) - let missing = filter(failing_indices, i => !nat_list_contains(xs: routed_indices, needle: i)) - let surplus = filter(routed_indices, i => !nat_list_contains(xs: failing_indices, needle: i)) - let duplicated = filter(routed_indices, i => nat_list_occurrences(xs: routed_indices, needle: i) > 1) - if count(missing) > 0 { Present { value: RoutingsMissingForComponents { indices: missing } } } - else if count(surplus) > 0 { Present { value: RoutingsForNonFailingComponents { indices: surplus } } } - else if count(duplicated) > 0 { Present { value: RoutingsDuplicated { indices: duplicated } } } - else { none } -} - -data decision_order_note: String = "THE ORDER OF THE GUARDS IS THE ALGEBRA, and it runs outside-in: trust, then the recipient, then whether the observer ran at all, then the artifact, then our own state, then the verdict. Each stage may only be reached when every stage outside it held.\\n\\nTrust first, because an unadmitted event's receipt must never be decoded, rendered, or acted on — this program holds issue-write capability, so content from an untrusted run is exactly what must not reach it. The recipient next, because an alert with nobody to tell should refuse loudly rather than proceed to produce an artifact that mentions no one. Observer availability before the receipt, because a run that timed out or failed at startup produced no receipt at all and demanding one first reports the wrong failure. Then receipt decodability before subject match, because a document that did not decode has no subject to compare; and subject match before state, because a receipt about another run tells us nothing about this incident.\\n\\nSTATE BEFORE VERDICT, AND A CORRUPT MARKER IS NEVER WRITTEN OVER. A green run with a corrupt marker does NOT close the issue: closing is the friendlier-looking answer and it would destroy the marker in the process, which is the one artifact a human needs to diagnose what wrote it. The harm is overwriting an unreadable incident record, not the direction of the verdict, so the same handling applies whether the run passed or failed.\\n\\nWhat changed since this note first described that behaviour is only WHO HEARS ABOUT IT: the corrupt marker used to produce a silent RefuseMalformedState, and it now produces NotifyAlertControllerUnavailable carrying ControllerMarkerMalformed. The marker is still not touched. Silence was the defect — the alert completing successfully while unable to do its job — and the note kept describing the silent arm after the operator verdict removed it (review 49947)." - -fn alert_decision( - admission: FalsifierAlertAdmission, - receipt: AlertReceiptInput, - observation: AlertIssueObservation, - now: EpochMs, - escalation: EscalationRecipient, - routings: List -) -> AlertDecision { - match admission { - AlertRefusedWorkflowNotObserved { observed: _, expected: _ } => RefuseUntrustedEvent { admission: admission } - AlertRefusedWorkflowPathNotObserved { observed: _, expected: _ } => RefuseUntrustedEvent { admission: admission } - AlertRefusedRepositoryNotOwned { field: _, observed: _, expected: _ } => RefuseUntrustedEvent { admission: admission } - AlertRefusedHeadBranchNotMain { observed: _, expected: _ } => RefuseUntrustedEvent { admission: admission } - AlertRefusedOriginatingEventNotAdmitted { observed: _ } => RefuseUntrustedEvent { admission: admission } - AlertRefusedActivityNotCompleted { observed: _, expected: _ } => RefuseUntrustedEvent { admission: admission } - AlertRefusedEventUnreadable { observation: _ } => RefuseUntrustedEvent { admission: admission } - AlertAdmitted { event: e } => - match escalation { - EscalationUndeclared { cause: c } => RefuseEscalationRecipientUndeclared { cause: c } - EscalationDeclared { handle: h } => - if conclusion_is_observer_unavailable(c: e.conclusion) { - alert_decision_observer_unavailable( - event: e, - observation: observation, - now: now, - handle: h, - routings: routings - ) - } else { - alert_decision_with_receipt( - event: e, - receipt: receipt, - observation: observation, - now: now, - handle: h, - routings: routings - ) - } - } - } -} - -data observer_unavailable_precedes_the_receipt_note: String = "THE OBSERVER-UNAVAILABLE CHECK RUNS BEFORE THE RECEIPT IS REQUIRED, AND THE ORDER IS THE WHOLE POINT. A run that timed out or failed at startup produced NO RECEIPT — that is what those conclusions mean — so a guard order demanding a decoded, subject-matched receipt first sent every one of them to RefuseReceiptMalformed. The alert would report `the floor's writer is broken` for the common case where the floor never ran at all: a true observation about a missing artifact standing in for the true observation about a missing observer, with the wrong remedy attached and no notification.\\n\\nSo the order is trust, then recipient, then observer availability, then receipt. It reads as an escalating set of questions about what can be known: may I act on this run, is there anyone to tell, did the observer produce a verdict at all, and only then, what does its verdict say. Requiring the artifact before asking whether the producer ran is the inversion that hid the case." - -fn conclusion_is_observer_unavailable(c: WorkflowRunConclusion) -> Bool { - match c { - TimedOut => true - StartupFailure => true - Success => false - Failure => false - Cancelled => false - Neutral => false - Skipped => false - ActionRequired => false - } -} - -fn alert_decision_observer_unavailable( - event: WorkflowRunEvent, - observation: AlertIssueObservation, - now: EpochMs, - handle: NonEmptyStr, - routings: List -) -> AlertDecision { - let tag = conclusion_tag(c: event.conclusion) - let signature = observer_unavailable_signature(conclusion_tag: tag) - match alert_incident_state_of(observation: observation) { - IncidentIndeterminate { cause: c } => - NotifyAlertControllerUnavailable { - cause: c, - issue_disposition: ControllerIssueUntouched, - notification: alert_notification(handle: handle, routings: routings) - } - IncidentUnreadable { detail: d } => - NotifyAlertControllerUnavailable { - cause: ControllerMarkerMalformed { detail: d }, - issue_disposition: ControllerIssueUntouched, - notification: alert_notification(handle: handle, routings: routings) - } - IncidentReadable { state: incident } => - match incident { - NoIncidentIssue => - OpenObserverIncident { - conclusion_tag: tag, - next_state: FalsifierAlertState { - first_red: FirstRedObserved { at: now }, - signature: signature, - last_notification_at: now - }, - notification: alert_notification(handle: handle, routings: routings) - } - IncidentIssueWithoutMarker { issue: iss } => - RefreshObserverIncident { - issue: iss, - conclusion_tag: tag, - next_state: FalsifierAlertState { - first_red: FirstRedUnknownBeforeTracking, - signature: signature, - last_notification_at: now - }, - silent_for: millisecond(count: 0), - notification: alert_notification(handle: handle, routings: routings) - } - IncidentLegacy { issue: iss, first_red: f, signature: _ } => - RefreshObserverIncident { - issue: iss, - conclusion_tag: tag, - next_state: FalsifierAlertState { first_red: f, signature: signature, last_notification_at: now }, - silent_for: millisecond(count: 0), - notification: alert_notification(handle: handle, routings: routings) - } - IncidentCurrent { issue: iss, state: st } => - if (st.signature as String) != (signature as String) - || now >= st.last_notification_at + millisecond_count(m: falsifier_alert_heartbeat_window) { - RefreshObserverIncident { - issue: iss, - conclusion_tag: tag, - next_state: FalsifierAlertState { first_red: st.first_red, signature: signature, last_notification_at: now }, - silent_for: millisecond(count: now - st.last_notification_at), - notification: alert_notification(handle: handle, routings: routings) - } - } else { - RefreshObserverIncidentWithoutNotification { - issue: iss, - conclusion_tag: tag, - next_state: FalsifierAlertState { first_red: st.first_red, signature: signature, last_notification_at: st.last_notification_at }, - silent_for: millisecond(count: now - st.last_notification_at) - } - } - } - } -} - -data observer_throttle_symmetry_note: String = "THE OBSERVER PATH IS THROTTLED BY THE SAME WINDOW AS THE RED PATH, and for one revision it was not (review 50351). RefreshObserverIncident was returned unconditionally for IncidentCurrent: it never compared the stored signature, never compared the window, and advanced last_notification_at to now on every run. On the four-hourly falsifier cadence a permanently timed-out observer would therefore have paged every four hours — the exact notification spam this module exists to end — while two notes a few lines apart asserted that it did not. The code was wrong and the prose was right, which is the worse way round: a reader checking the policy would have found it documented and true-looking.\\n\\nTHE SUPPRESSED ARM PRESERVES last_notification_at RATHER THAN ADVANCING IT, and that is the load-bearing half. Writing `now` there looks harmless — the run did just observe the incident — but it restarts the window on every cadence, so the elapsed comparison can never fire and the heartbeat is silenced FOREVER. Advancing turns a spam defect into a silence defect, which is strictly worse because nothing observes it. Only an arm that actually notifies may move the instant, so the field records WHEN WE LAST SPOKE, never when we last looked. The red path's RefreshIssueWithoutNotification carries the same asymmetry for the same reason.\\n\\nThe two notifying cases share one arm because they produce the same effect. A changed observer class and an elapsed window both mean speak now, and RefreshObserverIncident already carries the conclusion_tag that says which conclusion it is; splitting them would be two names for one instruction. The red path splits its two only because their MESSAGES differ — a changed class names the previous signature and the current one — which is a distinction in what gets said, not in whether to say it." - -data observer_signature_note: String = "The observer incident gets its own signature, derived from the conclusion tag, so it is distinguishable from every corpus incident AND from the other observer conclusion. A timeout following a startup failure is a changed class and should say so; a timeout following a timeout is the same incident and is throttled by the ordinary window. Reusing a corpus signature here would make an observer outage look like a component failure with no components." - -fn observer_unavailable_signature(conclusion_tag: NonEmptyStr) -> NonEmptyStr { - concat("observer-unavailable:", conclusion_tag as String) as NonEmptyStr -} - -fn alert_decision_with_receipt( - event: WorkflowRunEvent, - receipt: AlertReceiptInput, - observation: AlertIssueObservation, - now: EpochMs, - handle: NonEmptyStr, - routings: List -) -> AlertDecision { - let notification = alert_notification(handle: handle, routings: routings) - match receipt { - ReceiptUndecodable { decoding: d } => - NotifyAlertControllerUnavailable { - cause: ControllerReceiptMalformed { decoding: d }, - issue_disposition: controller_issue_disposition(observation: observation), - notification: notification - } - ReceiptSubjectRejected { mismatch: m } => - NotifyAlertControllerUnavailable { - cause: ControllerReceiptMismatch { mismatch: m }, - issue_disposition: controller_issue_disposition(observation: observation), - notification: notification - } - ReceiptAdmitted { document: doc } => - match alert_incident_state_of(observation: observation) { - IncidentIndeterminate { cause: c } => - NotifyAlertControllerUnavailable { - cause: c, - issue_disposition: controller_issue_disposition(observation: observation), - notification: notification - } - IncidentUnreadable { detail: d } => - NotifyAlertControllerUnavailable { - cause: ControllerMarkerMalformed { detail: d }, - issue_disposition: controller_issue_disposition(observation: observation), - notification: notification - } - IncidentReadable { state: incident } => - match routing_join_check(failing: alert_signature_of(doc: doc).members, routings: routings) { - Present { value: mismatch } => - NotifyAlertControllerUnavailable { - cause: ControllerRoutingJoinRefused { mismatch: mismatch }, - issue_disposition: controller_issue_disposition(observation: observation), - notification: notification - } - Absent => alert_decision_on_verdict( - event: event, - document: doc, - state: incident, - now: now, - handle: handle, - routings: routings - ) - } - } - } -} - -fn controller_issue_disposition(observation: AlertIssueObservation) -> ControllerIssueDisposition { - match observation { - OneOpenAlertIssue { issue: iss, state: _ } => ControllerIssueObserved { issue: iss } - NoOpenAlertIssue => ControllerIssueUntouched - MultipleOpenAlertIssues { issues: _ } => ControllerIssueUntouched - AlertIssueLookupRefused { cause: _ } => ControllerIssueUntouched - } -} - -fn alert_decision_on_verdict( - event: WorkflowRunEvent, - document: FloorComponentReceiptDocument, - state: AlertIncidentState, - now: EpochMs, - handle: NonEmptyStr, - routings: List -) -> AlertDecision { - match event.conclusion { - Success => alert_decision_green(state: state, handle: handle, routings: routings) - Failure => alert_decision_red( - document: document, - state: state, - now: now, - handle: handle, - routings: routings - ) - TimedOut => NoAction { reason: ConclusionDecidedBeforeReceipt { conclusion_tag: conclusion_tag(c: TimedOut) } } - StartupFailure => NoAction { reason: ConclusionDecidedBeforeReceipt { conclusion_tag: conclusion_tag(c: StartupFailure) } } - Cancelled => NoAction { reason: CancellationUnexplained } - Skipped => NoAction { reason: RunPreventedByConfiguration { conclusion_tag: conclusion_tag(c: Skipped) } } - Neutral => NoAction { reason: RunPreventedByConfiguration { conclusion_tag: conclusion_tag(c: Neutral) } } - ActionRequired => NoAction { reason: RunPreventedByConfiguration { conclusion_tag: conclusion_tag(c: ActionRequired) } } - } -} - -data green_close_note: String = "A GREEN RUN CLOSES ONLY AN INCIDENT THAT EXISTS. With no marker there is nothing open and nothing to announce, so the answer is NoAction with the reason recorded — not a notification that everything is fine, which would page the recipient on every successful run of a four-hourly cadence. A legacy marker DOES close: it is a real open incident that merely predates the typed state, and refusing to close it would leave a stale issue open forever as the cost of a format change." - -fn alert_decision_green( - state: AlertIncidentState, - handle: NonEmptyStr, - routings: List -) -> AlertDecision { - match state { - NoIncidentIssue => NoAction { reason: GreenWithNoOpenIncident } - IncidentIssueWithoutMarker { issue: iss } => - NotifyGreenAndClose { issue: iss, notification: alert_notification(handle: handle, routings: routings) } - IncidentCurrent { issue: iss, state: _ } => - NotifyGreenAndClose { issue: iss, notification: alert_notification(handle: handle, routings: routings) } - IncidentLegacy { issue: iss, first_red: _, signature: _ } => - NotifyGreenAndClose { issue: iss, notification: alert_notification(handle: handle, routings: routings) } - } -} - -data red_window_note: String = "THE WINDOW IS MEASURED FROM last_notification_at, WHICH IS THE FACT THE ALERT ITSELF PRODUCED. Not from first_red, which would make the interval drift with incident age; not from the run start, which would notify every run; and emphatically not from the newest comment's timestamp, which is where this began — a single per_page=100 page read oldest-first, so past 100 comments the throttle inverted from at-most-every-20h into every-run. There is no second source of issue state here and none may be added.\\n\\nA CHANGED SIGNATURE IS NEVER THROTTLED. It is a different incident with a different remedy, so suppressing it as `still red` is the conflation the signature exists to detect; the window applies only to a red whose class has not moved.\\n\\nAN EXISTING ISSUE WITH NO MARKER IS ADOPTED, NOT DUPLICATED. It is a real open incident whose body predates the marker or was written by a human, so the alert writes its state onto that issue and notifies once, exactly as it does for a legacy marker. Opening a second issue beside it — which is what the fused reading did — splits one incident across two places and guarantees at least one of them is never closed." - -fn alert_decision_red( - document: FloorComponentReceiptDocument, - state: AlertIncidentState, - now: EpochMs, - handle: NonEmptyStr, - routings: List -) -> AlertDecision { - let signature = alert_signature_of(doc: document) - let rendered = incident_signature_render(sig: signature) - match state { - NoIncidentIssue => - OpenIssue { - signature: signature, - next_state: FalsifierAlertState { first_red: FirstRedObserved { at: now }, signature: rendered, last_notification_at: now }, - notification: alert_notification(handle: handle, routings: routings) - } - IncidentIssueWithoutMarker { issue: iss } => - NotifyLegacyStateMigration { - issue: iss, - first_red: FirstRedUnknownBeforeTracking, - signature: signature, - next_state: FalsifierAlertState { first_red: FirstRedUnknownBeforeTracking, signature: rendered, last_notification_at: now }, - notification: alert_notification(handle: handle, routings: routings) - } - IncidentLegacy { issue: iss, first_red: f, signature: _ } => - NotifyLegacyStateMigration { - issue: iss, - first_red: f, - signature: signature, - next_state: FalsifierAlertState { first_red: f, signature: rendered, last_notification_at: now }, - notification: alert_notification(handle: handle, routings: routings) - } - IncidentCurrent { issue: iss, state: s } => - match alert_signature_of_marker(marker: s.signature) { - Absent => NotifyAlertControllerUnavailable { - cause: ControllerMarkerMalformed { detail: concat("stored incident signature does not parse: ", s.signature as String) }, - issue_disposition: ControllerIssueObserved { issue: iss }, - notification: alert_notification(handle: handle, routings: routings) - } - Present { value: previous } => - if !incident_signature_eq(left: previous, right: signature) { - RefreshAndNotifyChangedClass { - issue: iss, - previous: previous, - current: signature, - next_state: FalsifierAlertState { first_red: s.first_red, signature: rendered, last_notification_at: now }, - notification: alert_notification(handle: handle, routings: routings) - } - } else if now >= s.last_notification_at + millisecond_count(m: falsifier_alert_heartbeat_window) { - RefreshAndNotifyHeartbeat { - issue: iss, - signature: signature, - next_state: FalsifierAlertState { first_red: s.first_red, signature: rendered, last_notification_at: now }, - silent_for: millisecond(count: now - s.last_notification_at), - notification: alert_notification(handle: handle, routings: routings) - } - } else { - RefreshIssueWithoutNotification { - issue: iss, - signature: signature, - next_state: FalsifierAlertState { first_red: s.first_red, signature: rendered, last_notification_at: s.last_notification_at }, - silent_for: millisecond(count: now - s.last_notification_at) - } - } - } - } -} diff --git a/dag/gunbc/falsifier_alert_residue.dag b/dag/gunbc/falsifier_alert_residue.dag deleted file mode 100644 index d7e3bc54418..00000000000 --- a/dag/gunbc/falsifier_alert_residue.dag +++ /dev/null @@ -1,68 +0,0 @@ -module gunbc.falsifier_alert_residue - -import std.types { NonEmptyStr, String } -import std.content_hash { Sha256Digest } -import std.dissolution { DissolutionCondition, unbound_dissolution } - -data falsifier_alert_residue_purpose_note: String = "ALERT-0. This module DECLARES the falsifier alert's residue and the laws its migration must satisfy. IT MOVES NO BEHAVIOR. The embedded program still runs exactly where it ran before; what changes is that it is now a counted row with a named disposition and a dissolution trigger rather than an undeclared fact of the tree. That ordering is deliberate — a residue that is not declared cannot be shown to have shrunk, and a migration that starts by moving behavior has no baseline to measure against." - -// WHAT LANGUAGE-NORMAL-FORM RESIDUE MEANS, stated at the grain that makes it decidable. A .dag corpus that emits foreign artifacts will always contain foreign-language TEXT; that alone is not residue. Residue is foreign text that is in NORMAL FORM for its target language — already a program in that language, authored as such — as opposed to text DERIVED from a modeled structure by an emitter. `bash_build_*` constructors produce shell text and are not residue, because the authority is the Node tree and the text is its projection. A 232-line ECMAScript program pasted into a YAML scalar is residue, because the ECMAScript IS the authority: nothing upstream of it describes what it does, and the only way to change its behavior is to edit ECMAScript. The distinction is exactly the one DESIGN §5 draws between construction and validation, applied to emission: derived text has a single authority, normal-form text is the authority. -type ResidueTarget - = ECMAScript - | Bash - | Yaml - -type ResidueRuntime - = GithubScriptAction - | GithubActionsRunStep - | HostShell - -// ExecutableSourceString is the kind where the residue is a PROGRAM carried as a string value — parsed and executed by a foreign interpreter at runtime, with no modeled structure behind it. It is distinguished from a configuration literal (a string the foreign runtime reads as data) because the remedies differ: a configuration literal wants a typed carrier projected into the same position, while an executable source string wants its BEHAVIOR remodeled and the string deleted. Naming the kind is what makes the disposition derivable rather than chosen per row. -type ResidueKind - = ExecutableSourceString - | ConfigurationLiteral - -data residue_disposition_note: String = "ReplaceWithLanguageIndependentBehavior is the disposition that says: this residue does NOT become an emitter for its target language. The behavior is remodeled as ordinary typed .dag over typed effects, the foreign program is DELETED, and only a thin foreign-executor wrapper remains — a wrapper that invokes a controller, carrying no business logic of its own. It is deliberately distinct from EmitFromModel, which is the right disposition when the artifact genuinely must BE a program in the target language (a generated shell script, a generated workflow file). Choosing EmitFromModel here would have converted a business-logic migration into a JavaScript-emission project, which is a different and much larger lane, and would have left the same logic maintained in the same language with an extra step in front of it." - -type ResidueDisposition - = ReplaceWithLanguageIndependentBehavior - | EmitFromModel - -type LanguageNormalFormResidue { - site: NonEmptyStr - target: ResidueTarget - runtime: ResidueRuntime - kind: ResidueKind - disposition: ResidueDisposition - dissolution: DissolutionCondition -} - -data falsifier_alert_embedded_program_residue: LanguageNormalFormResidue = LanguageNormalFormResidue { - site: ".github/workflows/falsifier-alert.yml", - target: ECMAScript, - runtime: GithubScriptAction, - kind: ExecutableSourceString, - disposition: ReplaceWithLanguageIndependentBehavior, - dissolution: unbound_dissolution(description: "the generated typed falsifier-alert workflow cutover — the alert's decision algebra runs as .dag over typed receipt, clock, state and issue operations, and the github-script step carries no program") -} - -data falsifier_alert_residue_registry: List = [ - falsifier_alert_embedded_program_residue -] - -data falsifier_alert_runtime_acquisition_note: String = "THE ALERT CONTROLLER MUST REMAIN AVAILABLE WHEN THE WORKFLOW IT OBSERVES CANNOT BUILD. This is the load-bearing constraint and it eliminates all three obvious acquisition routes, each for its own reason.\n\nBUILD IT IN THE ALERT JOB: fails exactly when the incident IS a build failure. The observer would go dark in the case it most needs to report, and — worse — it would go dark SILENTLY, because a failed build in the alert job looks like an infrastructure blip rather than a suppressed alert. An observer whose availability is correlated with the health of its subject is not an observer.\n\nDOWNLOAD IT FROM THE TRIGGERING RUN: fails when that run died before publishing artifacts, which is a normal way for the observed run to fail. It also makes the observer execute an artifact produced by the run it is judging, so a run that fails in a way that corrupts its own outputs gets to choose what is said about it.\n\nUSE A MUTABLE PATH LIKE /opt/gunbc/bin/gunbc: silently runs whatever is installed. There is no revision in the record, so two alert runs a week apart can behave differently with nothing anywhere saying so, and a bad deploy to that path changes the observer's behavior without any change to this repository.\n\nTHE SHAPE THAT SURVIVES ALL THREE is a CONTENT-ADDRESSED LAST-KNOWN-GOOD bundle: the binary, the exact alert-program source closure it interprets, and a manifest binding both to one controller revision, selected and VERIFIED THROUGH THE MANIFEST. Last-known-good here is deliberate observer independence, not accidental staleness — the observer is pinned to a revision that was known to work, precisely so that breaking the tree cannot break the thing that reports the tree is broken. A versioned path may be the storage realization, but the path is never the authority: the manifest is, and a bundle whose contents do not hash to the manifest refuses rather than running. An exact triggering-run bundle may become an optional FAST PATH later, once trust and identity admission exist to say whose artifact it is — never the only path, and never the default." - -type FalsifierAlertRuntime { - controller_revision: NonEmptyStr - binary_digest: Sha256Digest - source_closure_digest: Sha256Digest -} - -// VERIFICATION IS A REFUSAL, NOT A WARNING. The bundle is admitted only when the binary and the source closure both hash to the digests the manifest names for the selected controller revision. A mismatch on either is a typed, located refusal that stops the alert — it does not fall back to a different bundle, to a mutable path, or to running the binary anyway. The reasoning is DESIGN §5's absorbing-fallback rule at its sharpest: this controller holds issues: write, so an unverified binary is a thing with write access to the repository's issue tracker, and 'proceed as if verification had passed' is the escape hatch that makes the verification decorative. A refusal here means the alert does not run, which is a visible outage of the observer — and a visible outage is strictly better than an invisible compromise of it. -type FalsifierAlertRuntimeAdmission - = RuntimeAdmitted { runtime: FalsifierAlertRuntime } - | RuntimeManifestAbsent { detail: NonEmptyStr } - | RuntimeBinaryDigestMismatch { expected: Sha256Digest, observed: Sha256Digest } - | RuntimeSourceClosureDigestMismatch { expected: Sha256Digest, observed: Sha256Digest } - -data falsifier_alert_runtime_scaffold_note: String = "gunbc.cli_invoke gunbc_run_shell assumes $ROOT/target/release/gunbc. That is an EMISSION SCAFFOLD for steps that run inside a checkout which has just built the binary — it is not, and must not become, the acquisition authority for this alert. Reusing it here would silently reintroduce the build-it-in-the-job route rejected above, because it presumes exactly the successful build whose absence is the incident. The acquisition authority is the manifest; that this module says so explicitly is what keeps a later author from reaching for the nearest existing helper." diff --git a/dag/gunbc/falsifier_alert_state.dag b/dag/gunbc/falsifier_alert_state.dag deleted file mode 100644 index 3030c40da9b..00000000000 --- a/dag/gunbc/falsifier_alert_state.dag +++ /dev/null @@ -1,203 +0,0 @@ -module gunbc.falsifier_alert_state - -import std.types { NonEmptyStr, String, EpochMs } -import std.measure { Millisecond, millisecond } -import extdeps.languages.json.emit { - JsonValue, JsonString, JsonNumber, - json_object, json_kv, json_string, json_int, JsonKeyValue, - serialize_json -} -import extdeps.languages.json.parse { - parse_json, - json_object_unique_member, - JsonMemberFound, - JsonMemberAbsent, - JsonMemberDuplicated, - JsonMemberNotAnObject -} - -data falsifier_alert_state_purpose_note: String = "ALERT-2's state half. The alert's own state — when the incident started, what is currently failing, and when it last NOTIFIED — rides in the issue body as a typed marker, so the issue remains the single authority for its own state and no external store exists. This module owns the marker's shape and both directions across it.\n\nlast_notification_at IS THE POINT OF THIS CARRIER. It replaces recovering the throttle's input by listing the issue's comments and reading the newest one's timestamp, which failed three separate ways: it read comments[length-1] from a single per_page=100 page, and since the endpoint returns oldest-first and accepts no sort parameter, past 100 comments that index is the 100th and only gets older — so the throttle inverted from at-most-every-20h into every-run, turning a silent alert into a spamming one. It also broke if anyone else commented on the issue, and it made a fact the alert itself produced depend on an API call that could fail. The alert knows when it last notified because it did the notifying; that fact is now written where it is produced and read back with no API call at all." - -data first_red_standing_note: String = "first_red IS A STANDING, NOT ALWAYS AN INSTANT. Adopting an issue that predates state tracking — one opened by hand, or written before this marker existed — means the alert genuinely does not know when the falsifier first went red. Writing `now` there records a fabricated observation under the name of a measurement, and the issue then says `red since 09:14` about an incident that may have started days earlier.\\n\\nSo the marker can say it does not know. FirstRedObserved carries an instant this alert actually recorded; FirstRedUnknownBeforeTracking says the incident predates what is knowable. Both render honestly and they render differently, which is the whole point — one confident sentence that is sometimes false is worse than two true ones.\\n\\nOn the wire the unknown case is JSON null rather than a sentinel number: 0 would be a valid EpochMs meaning 1970, and every consumer would have to know which impossible instant means `unknown`. A null is the absence, and the decoder reads it as the standing rather than as a malformed number." - -type FirstRedStanding - = FirstRedObserved { at: EpochMs } - | FirstRedUnknownBeforeTracking - -fn first_red_json(f: FirstRedStanding) -> JsonValue { - match f { - FirstRedObserved { at: t } => json_int(n: t) - FirstRedUnknownBeforeTracking => json_null() - } -} - -type FalsifierAlertState { - first_red: FirstRedStanding - signature: NonEmptyStr - last_notification_at: EpochMs -} - -data falsifier_alert_state_marker_prefix: NonEmptyStr = "" - -data falsifier_alert_state_first_red_member: String = "first_red" - -data falsifier_alert_state_signature_member: String = "signature" - -data falsifier_alert_state_last_notification_member: String = "last_notification_at" - -data falsifier_alert_state_decode_note: String = "STATE DECODING IS FOUR NAMED STATES AND NOT AN OPTIONAL. CurrentState is a marker carrying all three fields. LegacyStateWithoutLastNotification is a marker written before last_notification_at existed — it has first_red and signature, and its absence of a notification time is a real fact about a real issue in the wild, not a malformation. StateAbsent is no marker at all. StateMalformed is a marker that is present but does not decode.\n\nCollapsing any pair of these would produce a wrong action. Legacy and Absent differ in whether first_red is known, and first_red is the ONLY record of when the incident started — losing it silently restarts the clock on an incident that has been running for days. Absent and Malformed differ in whether something is broken: an issue that predates markers is expected, an issue whose marker does not parse means either the body was hand-edited or the writer has a defect, and both want to be seen.\n\nTHE LEGACY ARM SENDS EXACTLY ONE MIGRATION NOTIFICATION and rewrites the body with typed state, after which the issue is Current forever. One, because the transition is a real event an operator should see once; exactly one, because a migration that notified on every run would be the spamming failure this module exists to close, arriving by a different road.\n\nTHE `First red:` REGEX RECOVERY IS DROPPED. The previous version recovered first_red from a RENDERED PROSE LINE in the issue body when no marker was present. State is never recovered from prose: the prose is a projection for humans, its wording is free to change, and a parser over it makes every cosmetic edit to the alert's own rendering a potential silent state loss. An issue with no marker now yields StateAbsent honestly rather than a value reconstructed from a sentence." - -type FalsifierAlertStateDecoding - = CurrentState { state: FalsifierAlertState } - | LegacyStateWithoutLastNotification { first_red: FirstRedStanding, signature: NonEmptyStr } - | StateAbsent - | StateMalformed { detail: String } - -fn falsifier_alert_state_json(state: FalsifierAlertState) -> JsonValue { - json_object(members: [ - json_kv(key: falsifier_alert_state_first_red_member, value: first_red_json(f: state.first_red)), - json_kv(key: falsifier_alert_state_signature_member, value: json_string(s: state.signature as String)), - json_kv(key: falsifier_alert_state_last_notification_member, value: json_int(n: state.last_notification_at)) - ]) -} - -fn falsifier_alert_state_marker(state: FalsifierAlertState) -> String { - concat( - concat(falsifier_alert_state_marker_prefix as String, serialize_json(v: falsifier_alert_state_json(state: state))), - falsifier_alert_state_marker_suffix as String - ) -} - -type FalsifierAlertStateNumber - = StateNumberFound { value: EpochMs } - | StateNumberMissing - | StateNumberMalformed { detail: String } - | StateNumberNull - -data falsifier_alert_state_number_note: String = "A state number is read back through the JSON number's LEXEME, and a lexeme that is not a run of decimal digits is a malformation rather than a value. This module writes those numbers itself through json_int, so any other shape means the marker was edited by hand or produced by something that is not this writer — in both cases the honest answer is Malformed. The negative arm is explicit rather than left to the carrier: parse_int admits a leading minus, so without it a negative lexeme would reach an `Int where range(min: 0)` position having passed the only check that looked at it." - -fn falsifier_alert_state_number_at(v: JsonValue, key: String) -> FalsifierAlertStateNumber { - match json_object_unique_member(v: v, key: key) { - JsonMemberAbsent => StateNumberMissing - JsonMemberDuplicated { count: _ } => - StateNumberMalformed { detail: concat(key, " is duplicated in the state marker") } - JsonMemberNotAnObject => - StateNumberMalformed { detail: "state marker payload is not a JSON object" } - JsonMemberFound { value: found } => - match found { - JsonNumber { lexeme: l } => - match parse_int(s: l as String) { - Absent => - StateNumberMalformed { detail: concat(key, " is not an integer") } - Present { value: n } => - if n < 0 { - StateNumberMalformed { detail: concat(key, " is negative") } - } else { - StateNumberFound { value: n } - } - } - JsonString { value: _ } => - StateNumberMalformed { detail: concat(key, " is a string, expected a number") } - JsonNull => - StateNumberNull - JsonBool { value: _ } => - StateNumberMalformed { detail: concat(key, " is a bool, expected a number") } - JsonArray { elements: _ } => - StateNumberMalformed { detail: concat(key, " is an array, expected a number") } - JsonObject { members: _ } => - StateNumberMalformed { detail: concat(key, " is an object, expected a number") } - } - } -} - -type FalsifierAlertStateSignature - = StateSignatureFound { value: NonEmptyStr } - | StateSignatureMissing - | StateSignatureMalformed { detail: String } - -fn falsifier_alert_state_signature_at(v: JsonValue) -> FalsifierAlertStateSignature { - match json_object_unique_member(v: v, key: falsifier_alert_state_signature_member) { - JsonMemberAbsent => StateSignatureMissing - JsonMemberDuplicated { count: _ } => - StateSignatureMalformed { detail: "signature is duplicated in the state marker" } - JsonMemberNotAnObject => - StateSignatureMalformed { detail: "state marker payload is not a JSON object" } - JsonMemberFound { value: found } => - match found { - JsonString { value: s } => - if s == "" { - StateSignatureMalformed { detail: "signature is the empty string" } - } else { - StateSignatureFound { value: s as NonEmptyStr } - } - JsonNumber { lexeme: _ } => - StateSignatureMalformed { detail: "signature is a number, expected a string" } - JsonNull => - StateSignatureMalformed { detail: "signature is null, expected a string" } - JsonBool { value: _ } => - StateSignatureMalformed { detail: "signature is a bool, expected a string" } - JsonArray { elements: _ } => - StateSignatureMalformed { detail: "signature is an array, expected a string" } - JsonObject { members: _ } => - StateSignatureMalformed { detail: "signature is an object, expected a string" } - } - } -} - -data first_red_null_is_the_unknown_standing_note: String = "A NULL first_red IS THE UNKNOWN STANDING, NOT A MALFORMED NUMBER — and null is a TYPED ARM of the number reader rather than a detail string to be matched. The first version of this compared the reader's diagnostic prose against a constant, which would have made the meaning of a marker depend on the wording of an error message: rewording it would silently turn `unknown since before tracking` back into `this marker is corrupt`. Reading state out of prose is the exact practice this module deleted when it dropped the `First red:` regex, and it had crept back in one layer down.\\n\\nSo StateNumberNull is its own arm, every numeric member sees it, and each decides. first_red reads it as the unknown standing; last_notification_at still refuses, because there is no meaningful `we notified at an unknown time` — either we did and we know when, or the marker is legacy and says nothing at all." - -fn falsifier_alert_state_with_first_red( - standing: FirstRedStanding, - signature: NonEmptyStr, - doc: JsonValue -) -> FalsifierAlertStateDecoding { - match falsifier_alert_state_number_at(v: doc, key: falsifier_alert_state_last_notification_member) { - StateNumberMissing => LegacyStateWithoutLastNotification { first_red: standing, signature: signature } - StateNumberNull => StateMalformed { detail: "last_notification_at is null" } - StateNumberMalformed { detail: d } => StateMalformed { detail: d } - StateNumberFound { value: last_notification } => - CurrentState { - state: FalsifierAlertState { - first_red: standing, - signature: signature, - last_notification_at: last_notification - } - } - } -} - -fn falsifier_alert_state_from_payload(payload: String) -> FalsifierAlertStateDecoding { - match parse_json(s: payload) { - Absent => StateMalformed { detail: "state marker payload is not valid JSON" } - Present { value: doc } => - match falsifier_alert_state_signature_at(v: doc) { - StateSignatureMissing => StateMalformed { detail: "state marker has no signature" } - StateSignatureMalformed { detail: d } => StateMalformed { detail: d } - StateSignatureFound { value: signature } => - match falsifier_alert_state_number_at(v: doc, key: falsifier_alert_state_first_red_member) { - StateNumberMissing => StateMalformed { detail: "state marker has no first_red" } - StateNumberNull => - falsifier_alert_state_with_first_red(standing: FirstRedUnknownBeforeTracking, signature: signature, doc: doc) - StateNumberMalformed { detail: d } => StateMalformed { detail: d } - StateNumberFound { value: first_red } => - falsifier_alert_state_with_first_red(standing: FirstRedObserved { at: first_red }, signature: signature, doc: doc) - } - } - } -} - -data falsifier_alert_throttle_window_note: String = "The heartbeat window is 20 hours expressed in milliseconds, and it is deliberately shorter than the 24-hour period a `daily` heartbeat suggests. A run cadence of every 4 hours means a 24-hour window would let a heartbeat slip a full cycle whenever the previous one landed slightly late, so the window is set below the cadence-aligned boundary it must not cross. It is a policy budget, not a measurement, which is what makes a literal legitimate here under DESIGN's oracle rule: it states the maximum silence an operator accepts during a live incident." - -data falsifier_alert_instant_duration_split_note: String = "AN INSTANT AND A DURATION ARE DIFFERENT CARRIERS HERE, and an earlier revision straddled them (review 49400, the load-bearing finding on this PR). EpochMs is `milliseconds since the Unix epoch` — a POINT IN TIME — and it was being used for the heartbeat window and for the `silent_for` elapsed spans as well as for the instants. With one carrier for both, `first_red + last_notification_at` typechecks, and it is nonsense: adding two instants has no meaning. So does `now + window` returning something the type says is an instant when the operands say otherwise.\n\nThe split is the ordinary affine one. Instants — first_red, last_notification_at, now — stay EpochMs, because that is what they are and it is the carrier the rest of this tree already uses for epoch-milliseconds facts. Durations — the window, and every silent_for — are std.measure Millisecond, the ratified Measure magnitude, so a duration cannot be passed where an instant is expected or vice versa. The two arithmetic sites are the only places they meet, and each is a legitimate affine operation: instant MINUS instant yields a duration, and instant PLUS duration yields an instant. They are written through millisecond/millisecond_count at exactly those points rather than by making the carriers interchangeable, so the crossing is visible where it happens instead of being everywhere." - -data falsifier_alert_heartbeat_window: Millisecond = millisecond(count: 72000000) - -data falsifier_alert_malformed_state_refuses_note: String = "A MALFORMED MARKER REFUSES; IT DOES NOT BECOME A NEW INCIDENT. An earlier revision mapped StateAbsent and StateMalformed to the same first-red outcome, which threw away the distinction the decoding coproduct exists to make and did so at the one point where it has a data-loss consequence.\n\nThe two are not alike. ABSENT means no marker exists, so there is no incident state to lose and initiating one is correct. MALFORMED means a marker IS there and did not decode — the body was hand-edited, or something that is not this writer produced it, or the writer has a defect. Treating that as a first red does two harmful things at once: it announces a NEW incident for one that has been running, and the very next write overwrites the corrupt marker with a fresh first_red, destroying the only surviving record of when the real incident started. The corruption is then unrecoverable AND unreported, because the alert's own repair erased the evidence.\n\nSo the arm refuses. the refusal carries the decoder's located detail and drives no write: the incident state stays exactly as it is on the issue, corrupt and inspectable, and a human decides. That is DESIGN §5's failure arm — refuse, never widen — applied to a decoder's own output, and the widening it forbids here is the alert overwriting a fact it could not read." - -data falsifier_alert_throttle_note: String = "THE THROTTLE DECISION IS PURE AND TOTAL over (now, state, current signature). A CHANGED SIGNATURE ALWAYS NOTIFIES AND IS NEVER THROTTLED — it is a different incident with a different remedy, so suppressing it as `still red` is the state-space conflation the whole signature mechanism exists to prevent. An unchanged signature notifies only when the window has elapsed since the LAST NOTIFICATION, not since the run started and not since first_red. Comparing against last_notification_at is what makes the window mean what it says: measuring from first_red would make the interval drift with incident age, and measuring from the run start would notify every run." - -data falsifier_alert_throttle_authority_note: String = "THE THROTTLE DECISION IS NOT DEFINED HERE. This module owns the state MARKER — its shape, its encoding, and the decoding of a payload into FalsifierAlertStateDecoding — and it stops there. Whether a given state plus a given signature plus a given instant means notify, suppress or refuse is decided once, by gunbc.falsifier_alert_decision.\\n\\nIt was briefly defined in both places. FalsifierAlertNotificationDecision and falsifier_alert_notification_decision lived here and computed the same window comparison, the same signature comparison and the same silent_for as alert_decision_red; the copy here had no production consumer, only its own witnesses. Two implementations of one rule stay in agreement only by diligence, and the narrower one would have been the tempting thing to call from an effect plan later — at which point the alert would have had two answers to the same question with nothing forcing them to match. Deleted with ALERT-4, and the payload-driven witnesses it carried moved onto alert_decision rather than being deleted alongside it, so the decoder-to-decision coverage survived the consolidation." - -data falsifier_alert_no_notifies_bool_note: String = "THERE IS DELIBERATELY NO does-this-notify BOOL over the state decoding, for the same reason the admission module has none (review 49400). The arms do not notify the SAME THING — a changed incident, a heartbeat, a one-time migration and a first red produce different messages to different effect — so a Bool erases the distinction at the one boundary where the caller is about to choose what to say. The decision coproduct is the instruction; collapsing it to a flag means re-deriving the instruction somewhere else from something weaker. The coproduct itself now lives in gunbc.falsifier_alert_decision as AlertDecision." diff --git a/dag/gunbc/falsifier_cold_corpus_execution.dag b/dag/gunbc/falsifier_cold_corpus_execution.dag deleted file mode 100644 index f9d2e7460a2..00000000000 --- a/dag/gunbc/falsifier_cold_corpus_execution.dag +++ /dev/null @@ -1,234 +0,0 @@ -module gunbc.falsifier_cold_corpus_execution - -import std.types { String, Bool } -import gunbc.floor_component_receipt { - floor_component_receipt_path, - floor_component_receipt_schema, - floor_component_receipt_artifact_name, -} - -data falsifier_cold_corpus_execution_note: String = "NARROW CARRIER (operator ruling proud-bear-834 msg_4657b662, adhoc-8b992195-d13; receipt-backed correction msg_bc390264): whether the falsifier cold corpus EXECUTED, distinct from whether witnesses inside it produced verdicts. CorpusExecuted is emitted only when the floor-component receipt artifact is present and parses — never inferred from a job status code alone (a cold-corpus failure before upload used to read as corpus-executed, which is fabricated plausible output). A generic workflow failure must NEVER be read as evidence the falsifier found a regression; CorpusNotRun arms name infrastructure, not witness redness. The four-job split is pre-authorized in gunbc.falsifier_run_control falsifier_control_prerequisite_note." - -data falsifier_cold_corpus_execution_receipt_path: String = "target/falsifier-cold-corpus-execution.json" - -data falsifier_cold_corpus_execution_schema: String = "falsifier-cold-corpus-execution/v1" - -data falsifier_cold_corpus_job_id: String = "cold-corpus" - -type GithubJobOutcome - = JobOutcomeSuccess - | JobOutcomeFailure - | JobOutcomeCancelled - | JobOutcomeSkipped - | JobOutcomeUnknown { raw: String } - -fn github_job_outcome_from_result(result: String) -> GithubJobOutcome { - if result == "success" { - JobOutcomeSuccess - } else if result == "failure" { - JobOutcomeFailure - } else if result == "cancelled" { - JobOutcomeCancelled - } else if result == "skipped" { - JobOutcomeSkipped - } else { - JobOutcomeUnknown { raw: result } - } -} - -type CorpusNotRunCause - = BuildJobFailed - | BuildJobCancelled - | BuildJobSkipped - | ColdCorpusJobCancelled - | ColdCorpusJobSkipped { blocking_job: String } - | ColdCorpusReceiptArtifactAbsent - | ColdCorpusFailedBeforeReceipt - | ReleaseArtifactsUnavailable - | EnvironmentUnavailable { detail: String } - -type ColdCorpusExecution - = CorpusExecuted { receipt_path: String } - | CorpusNotRun { cause: CorpusNotRunCause } - -fn classify_cold_corpus_execution( - build: GithubJobOutcome, - cold: GithubJobOutcome, - floor_receipt_present: Bool -) -> ColdCorpusExecution { - match build { - JobOutcomeSuccess => - match cold { - JobOutcomeCancelled => CorpusNotRun { cause: ColdCorpusJobCancelled } - JobOutcomeSkipped => CorpusNotRun { cause: ColdCorpusJobSkipped { blocking_job: falsifier_cold_corpus_job_id } } - JobOutcomeUnknown { raw: detail } => CorpusNotRun { cause: EnvironmentUnavailable { detail: detail } } - JobOutcomeSuccess => - if floor_receipt_present { - CorpusExecuted { receipt_path: floor_component_receipt_path } - } else { - CorpusNotRun { cause: ColdCorpusReceiptArtifactAbsent } - } - JobOutcomeFailure => - if floor_receipt_present { - CorpusExecuted { receipt_path: floor_component_receipt_path } - } else { - CorpusNotRun { cause: ColdCorpusFailedBeforeReceipt } - } - } - JobOutcomeFailure => CorpusNotRun { cause: BuildJobFailed } - JobOutcomeCancelled => CorpusNotRun { cause: BuildJobCancelled } - JobOutcomeSkipped => CorpusNotRun { cause: BuildJobSkipped } - JobOutcomeUnknown { raw: detail } => CorpusNotRun { cause: EnvironmentUnavailable { detail: detail } } - } -} - -fn cold_corpus_execution_is_executed(c: ColdCorpusExecution) -> Bool { - match c { - CorpusExecuted { receipt_path: _ } => true - CorpusNotRun { cause: _ } => false - } -} - -data corpus_executed_tag: String = "corpus-executed" - -data corpus_not_run_tag: String = "corpus-not-run" - -fn cold_corpus_execution_tag(c: ColdCorpusExecution) -> String { - match c { - CorpusExecuted { receipt_path: _ } => corpus_executed_tag - CorpusNotRun { cause: _ } => corpus_not_run_tag - } -} - -data corpus_not_run_build_failed_tag: String = "build-job-failed" - -data corpus_not_run_build_cancelled_tag: String = "build-job-cancelled" - -data corpus_not_run_build_skipped_tag: String = "build-job-skipped" - -data corpus_not_run_cold_cancelled_tag: String = "cold-corpus-job-cancelled" - -data corpus_not_run_cold_skipped_tag: String = "cold-corpus-job-skipped" - -data corpus_not_run_cold_receipt_artifact_absent_tag: String = "cold-corpus-receipt-artifact-absent" - -data corpus_not_run_cold_failed_before_receipt_tag: String = "cold-corpus-failed-before-receipt" - -data corpus_not_run_release_artifacts_tag: String = "release-artifacts-unavailable" - -data corpus_not_run_environment_tag: String = "environment-unavailable" - -fn corpus_not_run_cause_tag(cause: CorpusNotRunCause) -> String { - match cause { - BuildJobFailed => corpus_not_run_build_failed_tag - BuildJobCancelled => corpus_not_run_build_cancelled_tag - BuildJobSkipped => corpus_not_run_build_skipped_tag - ColdCorpusJobCancelled => corpus_not_run_cold_cancelled_tag - ColdCorpusJobSkipped { blocking_job: _ } => corpus_not_run_cold_skipped_tag - ColdCorpusReceiptArtifactAbsent => corpus_not_run_cold_receipt_artifact_absent_tag - ColdCorpusFailedBeforeReceipt => corpus_not_run_cold_failed_before_receipt_tag - ReleaseArtifactsUnavailable => corpus_not_run_release_artifacts_tag - EnvironmentUnavailable { detail: _ } => corpus_not_run_environment_tag - } -} - -fn cold_corpus_execution_receipt_json(c: ColdCorpusExecution) -> String { - match c { - CorpusExecuted { receipt_path: path } => - concat( - concat("{\"schema\":\"", concat(falsifier_cold_corpus_execution_schema, "\",")), - concat( - concat("\"execution\":\"", concat(corpus_executed_tag, "\",")), - concat(concat("\"receipt_path\":\"", concat(path, "\"}")), "") - ) - ) - CorpusNotRun { cause: cause } => - match cause { - EnvironmentUnavailable { detail: detail } => - concat( - concat("{\"schema\":\"", concat(falsifier_cold_corpus_execution_schema, "\",")), - concat( - concat(concat("\"execution\":\"", concat(corpus_not_run_tag, "\",")), concat("\"cause\":\"", concat(corpus_not_run_environment_tag, "\","))), - concat(concat("\"detail\":\"", concat(detail, "\"}")), "") - ) - ) - ColdCorpusJobSkipped { blocking_job: job } => - concat( - concat("{\"schema\":\"", concat(falsifier_cold_corpus_execution_schema, "\",")), - concat( - concat(concat("\"execution\":\"", concat(corpus_not_run_tag, "\",")), concat("\"cause\":\"", concat(corpus_not_run_cold_skipped_tag, "\","))), - concat(concat("\"blocking_job\":\"", concat(job, "\"}")), "") - ) - ) - _ => - concat( - concat("{\"schema\":\"", concat(falsifier_cold_corpus_execution_schema, "\",")), - concat( - concat(concat("\"execution\":\"", concat(corpus_not_run_tag, "\",")), concat("\"cause\":\"", concat(corpus_not_run_cause_tag(cause: cause), "\"}"))), - "" - ) - ) - } - } -} - -fn cadence_verdict_should_fail( - build: GithubJobOutcome, - selection: GithubJobOutcome, - cold: GithubJobOutcome, - floor_receipt_present: Bool -) -> Bool { - match classify_cold_corpus_execution(build: build, cold: cold, floor_receipt_present: floor_receipt_present) { - CorpusNotRun { cause: _ } => true - CorpusExecuted { receipt_path: _ } => - selection != JobOutcomeSuccess || cold != JobOutcomeSuccess - } -} - -fn aggregate_shell_receipt_build_failed() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeFailure, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) -} - -fn aggregate_shell_receipt_build_cancelled() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeCancelled, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) -} - -fn aggregate_shell_receipt_build_skipped() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSkipped, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) -} - -fn aggregate_shell_receipt_cold_skipped() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) -} - -fn aggregate_shell_receipt_cold_cancelled() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeCancelled, floor_receipt_present: false) - ) -} - -fn aggregate_shell_receipt_cold_receipt_artifact_absent() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSuccess, floor_receipt_present: false) - ) -} - -fn aggregate_shell_receipt_cold_failed_before_receipt() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: false) - ) -} - -fn aggregate_shell_receipt_corpus_executed() -> String { - cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: true) - ) -} diff --git a/dag/gunbc/falsifier_lane.dag b/dag/gunbc/falsifier_lane.dag deleted file mode 100644 index d8d2b0cda23..00000000000 --- a/dag/gunbc/falsifier_lane.dag +++ /dev/null @@ -1,694 +0,0 @@ -module gunbc.falsifier_lane - -import std.dissolution { DissolutionCondition, unbound_dissolution } - -import std.types { String, NonEmptyStr, Bool, List, list_length } -import std.nat { Nat } -import gunbc.floor_component_receipt { - FloorComponentRow, - ModeUnrecorded, - floor_component_row_index, - floor_component_row_is_done, - floor_component_row_of, - floor_component_row_of_failure_mode, - floor_component_transition_outcome -} -import std.realization_schedule { SelectionApplied } -import std.observation { Done, Refused, Failed, TimedOut, Skipped, Final } -import std.measure { millisecond } - -data falsifier_lane_note: String = "The falsifier's per-component LANE identity, and the two things derived from it: a totality receipt (did every planned component report?) and a routing verdict (which lane owns a failing component?). WHY IT EXISTS, priced: gunbc.floor_component_receipt made the alert read per-component state instead of inferring one causal story from the overall conclusion, but it left the component ANONYMOUS. The label the seed stamps on a discovery batch is generated from the runnable's shape — claim_executor formats 'discovery-corpus[N root(s)+M explicit, adaptive width]' — so two lanes with the same root/entry arithmetic are indistinguishable in the receipt, and no label names the roster that failed. Triage therefore still ends at 'a batch was red', which is the same blindness one level down. THE FIX IS ATTRIBUTION, NOT A SECOND LABEL: the plan already knows which lane each batch is, because each batch is built by a named function over a named roster; that fact is simply discarded when the schedule flattens to List>. This module carries the lane vocabulary and the enrollment-ordered projection, and ci_floor_plan derives BOTH the batch schedule and the planned-component roster from one enrollment list — so an added lane cannot appear in the schedule without appearing in the attribution (DESIGN section 3: one authority, no fork to drift)." - -data falsifier_lane_index_join_note: String = "The join key is the 1-based batch INDEX, and that is not in tension with floor_component_receipt_role_note's rule against keying on indices. That rule forbids treating an index as a STABLE NAME across runs — 'batch 4 is the silent-pick gate' relocates a hardcoded assumption, because gunbc_falsifier_ordinary_batches composes conditionally on enrollment flags and one flip shifts every later index. Here the index is used only WITHIN ONE RUN, to join a receipt against the very plan that produced it: both sides are projections of the same enrollment state, evaluated for the same run, so the correspondence is exact by construction rather than assumed. What crosses runs is the LANE, which is a name and stays one. The index is the join; the lane is the identity." - -type FalsifierLane - = LanePredictOnly - | LaneSelfHostWet - | LaneSelfHostWetKnownRed - | LaneKnownRedProbe - | LaneSilentPickGate - | LaneRehomedBinWet - | LaneSubstrateLongLane - | LaneCadenceWitness - | LaneGates - -fn falsifier_lane_name(l: FalsifierLane) -> String { - match l { - LanePredictOnly => "predict_only" - LaneSelfHostWet => "self_host_wet" - LaneSelfHostWetKnownRed => "self_host_wet_known_red" - LaneKnownRedProbe => "known_red_probe" - LaneSilentPickGate => "silent_pick_gate" - LaneRehomedBinWet => "rehomed_bin_wet" - LaneSubstrateLongLane => "substrate_long_lane" - LaneCadenceWitness => "cadence_witness" - LaneGates => "gates" - } -} - -fn falsifier_lane_eq(left: FalsifierLane, right: FalsifierLane) -> Bool { - falsifier_lane_name(l: left) == falsifier_lane_name(l: right) -} - -type FalsifierLaneEnrollment { - lane: FalsifierLane - enrolled: Bool -} - -type FalsifierPlannedComponent { - index: Nat - lane: FalsifierLane -} - -fn falsifier_planned_components(enrollments: List) -> List { - fold(enrollments, init: [], f: fn(acc, e) { - if e.enrolled { - concat(acc, [FalsifierPlannedComponent { index: list_length(items: acc) + 1, lane: e.lane }]) - } else { - acc - } - }) -} - -fn falsifier_planned_indices(planned: List) -> List { - planned |> map(p => p.index) -} - -fn falsifier_reported_indices(rows: List) -> List { - rows |> map(r => floor_component_row_index(row: r)) -} - -fn index_occurrence_count(xs: List, target: Nat) -> Nat { - fold(xs, init: 0, f: fn(acc, x) { if x == target { acc + 1 } else { acc } }) -} - -fn list_contains_index(xs: List, target: Nat) -> Bool { - index_occurrence_count(xs: xs, target: target) > 0 -} - -fn duplicated_indices(xs: List) -> List { - fold(xs, init: [], f: fn(acc, x) { - if (index_occurrence_count(xs: xs, target: x) > 1) && !list_contains_index(xs: acc, target: x) { - concat(acc, [x]) - } else { - acc - } - }) -} - -data falsifier_run_standing_scope_note: String = "SCOPE, and the boundary that keeps this from being a second representation. This answers ONE question — did the falsifier job execute the components it planned — at BATCH grain. It does NOT answer whether any witness inside a component produced a verdict; that is the pending/current semantic evidence lifecycle signed on the witness-evidence-lifecycle model (docs/plans/witness-evidence-lifecycle-design.md, PR #7778), which is function-grain and is the single authority for enrollment-versus-execution. Nothing here may be read as evidence. The two are composed, never merged: run standing is a NECESSARY condition for the run having observed anything, and it is emphatically not a sufficient one — a component can report Done while every witness inside it was Interrupted and produced no verdict at all. falsifier_observed_health below is what enforces that composition structurally rather than by this note asking readers to remember it. Citation caveat carried per the coordinating directive: the FalsifierSubstrateLongLane cadence that model cites as its live specimen is currently dark." - -data falsifier_run_standing_axes_note: String = "Three defect axes, each an exact index SET and each required to be explicitly empty — never a count equality between planned and reported (DESIGN section 5: completeness is an identity join, and count(planned) == count(reported) is satisfied by one missing component alongside one surplus one; witness_standing_reds_when_counts_agree_but_identities_do_not is the discriminating red for exactly that). MISSING is the axis the receipt cannot currently express on its own: the seed pads batches the stop policy never reached with an explicit not_reached Skipped row, so a gap in the reported set is not an unreached batch — it is the executor and the plan disagreeing about what the run consisted of, which is precisely the state no existing check can see. SURPLUS is its mirror. DUPLICATE catches two rows claiming one component, which would make attribution ambiguous rather than merely incomplete. StandingPlanEmpty fails closed rather than reporting a vacuous completeness: the falsifier always plans at least the predict-only sweep, so an empty planned roster means the projection did not run, not that there was nothing to run." - -type FalsifierRunStanding - = StandingComplete { component_count: Nat } - | StandingMissingComponents { missing_indices: List } - | StandingSurplusComponents { surplus_indices: List } - | StandingDuplicateComponents { duplicated_indices: List } - | StandingPlanEmpty { cause: NonEmptyStr } - -fn falsifier_run_standing_from( - planned: List, - rows: List -) -> FalsifierRunStanding { - let planned_ix = falsifier_planned_indices(planned: planned) - let reported_ix = falsifier_reported_indices(rows: rows) - if list_length(items: planned_ix) == 0 { - StandingPlanEmpty { - cause: "no planned falsifier components — the lane projection did not run, and a vacuous completeness would report that as success" as NonEmptyStr - } - } else { - let missing = filter(xs: planned_ix, predicate: fn(i) { !list_contains_index(xs: reported_ix, target: i) }) - let surplus = filter(xs: reported_ix, predicate: fn(i) { !list_contains_index(xs: planned_ix, target: i) }) - let duplicated = duplicated_indices(xs: reported_ix) - if list_length(items: missing) > 0 { - StandingMissingComponents { missing_indices: missing } - } else if list_length(items: surplus) > 0 { - StandingSurplusComponents { surplus_indices: surplus } - } else if list_length(items: duplicated) > 0 { - StandingDuplicateComponents { duplicated_indices: duplicated } - } else { - StandingComplete { component_count: list_length(items: planned_ix) } - } - } -} - -data falsifier_run_standing_complete_is_not_health_note: String = "This predicate answers 'did every planned component report', and NOTHING else. It is deliberately not named *_is_healthy, *_is_green, or *_is_observed, because each of those would be the success-shaped value the combined finding names: three honest arms — admission honest about enrollment, standing honest about job completion, evidence honest about verdicts — composing into unobserved health because the first two return success while the third is unknown. StandingComplete is necessary and not sufficient, and the type below is what makes that structural instead of advisory." - -fn falsifier_run_standing_is_complete(v: FalsifierRunStanding) -> Bool { - match v { - StandingComplete { component_count: n } => true - StandingMissingComponents { missing_indices: xs } => false - StandingSurplusComponents { surplus_indices: xs } => false - StandingDuplicateComponents { duplicated_indices: xs } => false - StandingPlanEmpty { cause: c } => false - } -} - -data falsifier_observed_health_note: String = "THE CONSTRUCTION WALL, and the reason this module ships a type with no success arm. The acceptance bar for F1 reaches past the run: if a control ran but a witness inside it produced no verdict, standing must not read as observed. A note saying so would be validation — a reader is asked to remember that StandingComplete is insufficient, and the first consumer that wants a green boolean will derive one anyway, because nothing stops it. So the green is made UNWRITABLE instead (DESIGN section 5, construction over validation): FalsifierObservedHealth has exactly two arms and neither of them is healthy. There is no constructor in this module, or reachable from it, that yields 'the falsifier observed its subject' — a consumer that wants to claim observation cannot get the value from here at all. WHAT IS MISSING IS NAMED, not silent (DESIGN section 4b, no untracked stall): the missing conjunct is the per-witness semantic evidence term, CurrentSemanticEvidence over every witness the completed components contain, owned by the witness-evidence-lifecycle model. Dissolve-on: that lifecycle exposes a per-run projection of its evidence status; a third arm ObservedHealthCurrent is added THERE, taking standing and the evidence term together, and this two-arm type becomes the pending half of it. Until then the honest answer to 'is the falsifier observing anything' is that this repository cannot yet compute it, and the type says so rather than a boolean guessing." - -type FalsifierObservedHealth - = ObservedHealthUndecided { standing: FalsifierRunStanding, missing_term: NonEmptyStr } - | ObservedHealthRefused { standing: FalsifierRunStanding, cause: NonEmptyStr } - -fn falsifier_observed_health(v: FalsifierRunStanding) -> FalsifierObservedHealth { - if falsifier_run_standing_is_complete(v: v) { - ObservedHealthUndecided { - standing: v, - missing_term: "per-witness semantic evidence: every planned component reported, but whether any witness inside them returned a verdict on this attempt is not decidable from batch-grain rows — see the witness-evidence-lifecycle CurrentSemanticEvidence authority" as NonEmptyStr - } - } else { - ObservedHealthRefused { - standing: v, - cause: "run standing is not complete — the job did not execute the components it planned, so the run observed strictly less than it was scheduled to" as NonEmptyStr - } - } -} - -data falsifier_routing_note: String = "Routing REFUSES rather than defaulting. There is no catch-all lane and no 'general' owner, because a default owner is the absorbing fallback DESIGN section 5 forbids in its cheapest disguise: every alert would route somewhere, the misroute frequency would be zero by construction, and the missing attribution would never rank for fixing. A refusal is counted and located, so a lane that stops being attributable surfaces as a diagnostic instead of as someone else's pager." - -data falsifier_routing_two_unknowns_note: String = "TWO UNKNOWNS, TWO ARMS — they may not share one refusal (coordinating review, wise-ram-22 2026-08-04). RoutingLaneUndetermined means the component index is not in the planned roster at all: the run reported a component the plan does not know about, which is a MECHANISM gap, and its remedy is in the projection — the enrollment roster and the schedule have diverged, or the receipt is from a different plan. RoutingOwnerUndeclared means the lane IS determined and simply has no owner row: that is a ROUTING gap, and its remedy is authoring one row. Collapsing them would recreate the state-space conflation at the triage layer, which is the worst place for it — the person reading a triage refusal is by definition trying to find out who to talk to, and the two arms send them to entirely different places. Note the asymmetry that makes this more than bookkeeping: an owner-undeclared refusal still names the lane, so it is actionable without any further investigation, while a lane-undetermined refusal names nothing and is itself the bug." - -data falsifier_lane_owner_roster_note: String = "The owner roster is DECLARED AND CURRENTLY EMPTY, and that is the honest state rather than an omission. The only owner fact in the tree today is the ALERT_MENTION constant in .github/workflows/falsifier-alert.yml — one handle for every failure, which is precisely the anonymous routing this module exists to replace. It became a named constant when the alert was found to be reaching that handle only once per incident: a mention notifies when it is CREATED, and only the issue body's first write is a creation, so the sustained-red heartbeat and the failing-set-changed comments — the artifacts that actually carry current state — notified nobody (issue #7737, four uncited comments across two days). The constant is now read by every notifying artifact, which is why it is one name rather than four literals. Copying it onto nine lane rows would fabricate eight ownership facts nobody has asserted (DESIGN section 5, no fabricated plausible output), and would look like attribution while carrying none. So the roster starts empty, every lane routes to RoutingOwnerUndeclared naming itself, and the gap is counted and located instead of papered over — a lane acquires an owner when someone actually owns it, by adding one row. This is deliberately a data roster and not a per-lane function so that authoring an owner never touches the routing algebra. Dissolve-on: the roster covers every lane in FalsifierLane, at which point RoutingOwnerUndeclared becomes unreachable in production and survives only as the witness's red control." - -type FalsifierLaneOwner = LaneOwnerHandle { handle: NonEmptyStr } - -type FalsifierLaneOwnerRow { - lane: FalsifierLane - owner: FalsifierLaneOwner -} - -data falsifier_lane_owner_rows: List = [] - -fn falsifier_owner_of_lane(rows: List, lane: FalsifierLane) -> FalsifierLaneOwner? { - fold(rows, init: none, f: fn(acc, r) { - match acc { - Present { value: o } => Present { value: o } - Absent => if falsifier_lane_eq(left: r.lane, right: lane) { Present { value: r.owner } } else { none } - } - }) -} - -type FalsifierRouting - = RoutedToOwner { index: Nat, lane: FalsifierLane, owner: FalsifierLaneOwner } - | RoutingLaneUndetermined { index: Nat, cause: NonEmptyStr } - | RoutingOwnerUndeclared { index: Nat, lane: FalsifierLane, cause: NonEmptyStr } - -fn falsifier_lane_of_index(planned: List, index: Nat) -> FalsifierLane? { - fold(planned, init: none, f: fn(acc, p) { - match acc { - Present { value: l } => Present { value: l } - Absent => if p.index == index { Present { value: p.lane } } else { none } - } - }) -} - -fn falsifier_route_row( - planned: List, - owners: List, - row: FloorComponentRow -) -> FalsifierRouting { - let ix = floor_component_row_index(row: row) - match falsifier_lane_of_index(planned: planned, index: ix) { - Absent => RoutingLaneUndetermined { - index: ix, - cause: "component index is not in the planned falsifier lane roster — the run reported a component the plan does not know about, so the enrollment projection and the executed schedule have diverged" as NonEmptyStr - } - Present { value: l } => - match falsifier_owner_of_lane(rows: owners, lane: l) { - Present { value: o } => RoutedToOwner { index: ix, lane: l, owner: o } - Absent => RoutingOwnerUndeclared { - index: ix, - lane: l, - cause: "lane is determined but has no owner row in falsifier_lane_owner_rows — attribution succeeded, ownership is unauthored" as NonEmptyStr - } - } - } -} - -fn falsifier_unsuccessful_routings( - planned: List, - owners: List, - rows: List -) -> List { - rows - |> filter(r => !floor_component_row_is_done(row: r)) - |> map(r => falsifier_route_row(planned: planned, owners: owners, row: r)) -} - -fn falsifier_routing_lane_is_determined(r: FalsifierRouting) -> Bool { - match r { - RoutedToOwner { index: i, lane: l, owner: o } => true - RoutingLaneUndetermined { index: i, cause: c } => false - RoutingOwnerUndeclared { index: i, lane: l, cause: c } => true - } -} - -fn falsifier_routing_reaches_owner(r: FalsifierRouting) -> Bool { - match r { - RoutedToOwner { index: i, lane: l, owner: o } => true - RoutingLaneUndetermined { index: i, cause: c } => false - RoutingOwnerUndeclared { index: i, lane: l, cause: c } => false - } -} - -fn falsifier_all_lanes_determined(rs: List) -> Bool { - fold(rs, init: true, f: fn(acc, r) { acc && falsifier_routing_lane_is_determined(r: r) }) -} - -data falsifier_failing_set_note: String = "THE PER-WINDOW FAILING SET — the projection the alert needs and does not have. Priced by a live incident (still-bat-561, 2026-08-04): issue #7737 is open and correct, and its BODY is thirty hours stale. It describes witness_committed_is_fixed_point at 5004ms against a 5000ms budget from run 30809682025; the falsifier stopped failing that way on 2026-08-03T17:53 and has since failed on five entirely different witnesses. Nothing lies — the alerter's heartbeat suppression is working as designed and the issue is genuinely still red — but an open issue READS as a live description of the current failure, and this one is a description of a failure that no longer occurs. The current failing set is derivable today only by downloading a two-hour run log and grepping falsifier-failure-class. So the defect is not detection and not a missing alert; it is that the failing set is not RE-DERIVED per window. This function is that re-derivation, over evidence that already exists: the component rows the receipt already emits, joined to the lane roster the plan already knows." - -data falsifier_failure_class_note: String = "FAILURE CLASS IS CARRIED, because a red that CHANGES CLASS is a different incident from a red that persists, and rendering both as one unchanging open issue is what froze #7737. The two live classes are structurally different and want different responders: Class A (BudgetExceeded, three windows to 2026-08-03 14:46) is HOST-SENSITIVE — head 19cc776d4 passed on srv3-01 and failed on srv4-05 with identical content — while Class B (WitnessRed, seven windows since) is DETERMINISTIC, head 772d92d18 failing identically on two different hosts. A receipt reporting one undifferentiated 'falsifier red' state would conflate a flaky host with a real regression, which is the state-space conflation DESIGN section 5 forbids, at the layer where it costs the most triage time. - -WHAT THIS CAN AND CANNOT DISTINGUISH, stated exactly rather than implied. ClassBudgetExceeded is exact: the seed's BudgetExceeded mode is the only one mapping to Refused. ClassFailedIndistinct is NOT exact and says so in its name — gunbc.floor_component_receipt floor_component_outcome_of_failure_mode maps BOTH WitnessRed AND Infra onto Failed { error, output }, so at component-row grain a genuine witness regression and a broken runner are the same value. That collapse is upstream of this module and is not repaired here; fabricating a split would be inventing a distinction the data does not carry. It is a real limitation of the current receipt for exactly the Class A/Class B question that priced this work, so it is named as a typed arm rather than left for a reader to discover. Dissolve-on: the failure mode reaches the row as a typed field instead of being collapsed into an outcome variant — the same seam floor_component_receipt_timed_out_frontier_note already names for TimedOut — at which point ClassFailedIndistinct splits into ClassWitnessRed and ClassInfra and this arm deletes. - -THE STRENGTH OF THIS CLASSIFICATION, bounded honestly. Everything in THIS module keys on typed structure: the class is selected by matching ObservationOutcome's coproduct arms, never by reading the diagnostic or error text those arms carry, so the identity join over components is complete in the sense DESIGN section 5's oracle ruling means — a row cannot exist without its identity fields (boundary supplied by wise-ram-22, 2026-08-04: an identity anchor is the stronger one only WHERE IDENTITY IS STRUCTURALLY CARRIED, and a population of prose can restate a conclusion without its evidence and thereby escape such a join). But the chain does not begin here, and one layer up it is prose. claim_executor's falsifier_failure_mode reconstructs BudgetExceeded by testing whether a rendered diagnostic contains the substring 'eval budget exceeded', while the seed already HAS the typed InterpError::EvalBudgetExceeded { elapsed_ms, budget_ms } and destroys it in transit; that function's own comment reads 'THIS LIST IS A FORK, and that is the defect'. So ClassBudgetExceeded is exactly as sound as that substring match, and a reworded interpreter diagnostic would silently reclassify Class A as Class B — which is the class transition this module exists to make visible, arriving as a false one. That is inherited debt, not introduced here, and it is named rather than papered over because a classification presented as typed while resting on a grep is the specification-without-execution trap wearing this module's own clothes. The dissolve-on above is the same repair: carrying the typed mode through retires both the collapse AND the substring reconstruction." - -type FalsifierFailureClass - = ClassBudgetExceeded { diagnostic: NonEmptyStr } - | ClassFailedIndistinct { error: NonEmptyStr } - | ClassTimedOut - | ClassNotReached { reason: NonEmptyStr } - | ClassShownFailures { count: Nat } - -fn falsifier_failure_class_of_row(row: FloorComponentRow) -> FalsifierFailureClass? { - match floor_component_transition_outcome(t: row.event.transition) { - Absent => none - Present { value: o } => - match o { - Done => none - Refused { diagnostic: d } => Present { value: ClassBudgetExceeded { diagnostic: d } } - Failed { error: e, output: out } => Present { value: ClassFailedIndistinct { error: e } } - TimedOut { basis: _, budget: b, elapsed: el } => Present { value: ClassTimedOut } - Skipped { reason: r } => Present { value: ClassNotReached { reason: r } } - Final { shown_failures: n } => - if n == 0 { none } else { Present { value: ClassShownFailures { count: n } } } - } - } -} - -fn falsifier_failure_class_name(c: FalsifierFailureClass) -> String { - match c { - ClassBudgetExceeded { diagnostic: d } => "budget_exceeded" - ClassFailedIndistinct { error: e } => "failed_indistinct" - ClassTimedOut => "timed_out" - ClassNotReached { reason: r } => "not_reached" - ClassShownFailures { count: n } => "shown_failures" - } -} - -type FalsifierFailingComponent { - index: Nat - routing: FalsifierRouting - failure_class: FalsifierFailureClass -} - -fn falsifier_failing_set( - planned: List, - owners: List, - rows: List -) -> List { - fold(rows, init: [], f: fn(acc, row) { - match falsifier_failure_class_of_row(row: row) { - Absent => acc - Present { value: c } => concat(acc, [FalsifierFailingComponent { - index: floor_component_row_index(row: row), - routing: falsifier_route_row(planned: planned, owners: owners, row: row), - failure_class: c - }]) - } - }) -} - -data falsifier_failing_set_signature_note: String = "The class SIGNATURE of a window: the ordered failure-class names of its failing components. This is the minimum needed to answer the question that froze #7737 — did the failure change class, or is this the same red as last window — without carrying run identity, timestamps, or history, none of which belong in a pure projection. A consumer compares two windows' signatures; an inequality is a class transition and therefore a new incident, even when the issue stays open. Kept as a derived list rather than a stored digest so the comparison names WHICH position changed rather than only that something did." - -fn falsifier_failing_class_signature(failing: List) -> List { - failing |> map(f => falsifier_failure_class_name(c: f.failure_class)) -} - -data falsifier_lane_witness_note: String = "Witness functions live in the carrier and are imported by dag/test/claim/falsifier_lane_witness_test.dag, the same shape tools.dag_compile_clean_shard_totality uses. Every red control is SYNTHETIC — hand-built planned rosters and fixture component rows — so each defect axis is exercised by a discriminating input that goes red when the algebra is wrong, never by waiting for a real cadence run to misbehave (DESIGN section 5: green by execution plus a discriminating red). The fixture rows are built through floor_component_row_of, the receipt's own constructor, so a change to the row shape breaks these witnesses rather than letting them drift onto a private copy." - -fn falsifier_witness_row(index: Nat, done: Bool) -> FloorComponentRow { - floor_component_row_of( - run_id: "witness" as NonEmptyStr, - index: index, - label: "discovery-corpus[2 root(s)+0 explicit, adaptive width]" as NonEmptyStr, - selection: SelectionApplied, - witnesses: 0, - outcome: if done { Done } else { Failed { error: "synthetic red" as NonEmptyStr, output: "" } }, - wall: millisecond(count: 0), - failure_mode: ModeUnrecorded - ) -} - -fn falsifier_witness_planned_three() -> List { - falsifier_planned_components(enrollments: [ - FalsifierLaneEnrollment { lane: LanePredictOnly, enrolled: true }, - FalsifierLaneEnrollment { lane: LaneKnownRedProbe, enrolled: true }, - FalsifierLaneEnrollment { lane: LaneSilentPickGate, enrolled: true } - ]) -} - -fn witness_planned_components_skip_unenrolled_and_renumber() -> Bool { - let planned = falsifier_planned_components(enrollments: [ - FalsifierLaneEnrollment { lane: LanePredictOnly, enrolled: true }, - FalsifierLaneEnrollment { lane: LaneSelfHostWet, enrolled: false }, - FalsifierLaneEnrollment { lane: LaneKnownRedProbe, enrolled: true } - ]) - (list_length(items: planned) == 2) - && match falsifier_lane_of_index(planned: planned, index: 1) { - Present { value: l } => falsifier_lane_eq(left: l, right: LanePredictOnly) - Absent => false - } - && match falsifier_lane_of_index(planned: planned, index: 2) { - Present { value: l } => falsifier_lane_eq(left: l, right: LaneKnownRedProbe) - Absent => false - } -} - -fn witness_standing_green_on_matching_plan() -> Bool { - let verdict = falsifier_run_standing_from( - planned: falsifier_witness_planned_three(), - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: true), - falsifier_witness_row(index: 3, done: true) - ] - ) - match verdict { - StandingComplete { component_count: n } => n == 3 - _ => false - } -} - -fn witness_standing_reds_on_missing_component() -> Bool { - let verdict = falsifier_run_standing_from( - planned: falsifier_witness_planned_three(), - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: true) - ] - ) - match verdict { - StandingMissingComponents { missing_indices: xs } => - (list_length(items: xs) == 1) && (xs.first() == 3) - _ => false - } -} - -fn witness_standing_reds_on_surplus_component() -> Bool { - let planned = falsifier_planned_components(enrollments: [ - FalsifierLaneEnrollment { lane: LanePredictOnly, enrolled: true }, - FalsifierLaneEnrollment { lane: LaneKnownRedProbe, enrolled: true } - ]) - let verdict = falsifier_run_standing_from( - planned: planned, - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: true), - falsifier_witness_row(index: 3, done: true) - ] - ) - match verdict { - StandingSurplusComponents { surplus_indices: xs } => - (list_length(items: xs) == 1) && (xs.first() == 3) - _ => false - } -} - -fn witness_standing_reds_on_duplicate_component() -> Bool { - let planned = falsifier_planned_components(enrollments: [ - FalsifierLaneEnrollment { lane: LanePredictOnly, enrolled: true }, - FalsifierLaneEnrollment { lane: LaneKnownRedProbe, enrolled: true } - ]) - let verdict = falsifier_run_standing_from( - planned: planned, - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: true), - falsifier_witness_row(index: 2, done: false) - ] - ) - match verdict { - StandingDuplicateComponents { duplicated_indices: xs } => - (list_length(items: xs) == 1) && (xs.first() == 2) - _ => false - } -} - -fn witness_standing_fails_closed_on_empty_plan() -> Bool { - let verdict = falsifier_run_standing_from( - planned: [], - rows: [falsifier_witness_row(index: 1, done: true)] - ) - match verdict { - StandingPlanEmpty { cause: c } => !falsifier_run_standing_is_complete(v: verdict) - _ => false - } -} - -data falsifier_equal_count_witness_note: String = "The axis that proves this is an identity join and not a count oracle: three planned components against three reported rows whose index set is {1, 2, 4}. Every count agrees — a count equality check reports total — while component 3 never reported and component 4 was never planned. The verdict must name the missing index." - -fn witness_standing_reds_when_counts_agree_but_identities_do_not() -> Bool { - let verdict = falsifier_run_standing_from( - planned: falsifier_witness_planned_three(), - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: true), - falsifier_witness_row(index: 4, done: true) - ] - ) - match verdict { - StandingMissingComponents { missing_indices: xs } => - (list_length(items: xs) == 1) && (xs.first() == 3) - _ => false - } -} - -data falsifier_witness_owner_rows_note: String = "A FIXTURE owner roster, deliberately not the production one. The production falsifier_lane_owner_rows is empty by design, so witnessing RoutedToOwner against it would be impossible and the routed arm would be specification-without-execution — proven only by the type existing. Authoring a synthetic row here exercises the reached-owner path for real while leaving the production roster honest, and the empty-roster path gets its own witness below. The handle is plainly synthetic so it can never be mistaken for an ownership assertion about a person." - -fn falsifier_witness_owner_rows() -> List { - [FalsifierLaneOwnerRow { - lane: LaneSilentPickGate, - owner: LaneOwnerHandle { handle: "synthetic-witness-owner" as NonEmptyStr } - }] -} - -fn witness_routing_attributes_failing_component_to_owner() -> Bool { - match falsifier_route_row( - planned: falsifier_witness_planned_three(), - owners: falsifier_witness_owner_rows(), - row: falsifier_witness_row(index: 3, done: false) - ) { - RoutedToOwner { index: i, lane: l, owner: o } => - (i == 3) - && falsifier_lane_eq(left: l, right: LaneSilentPickGate) - && match o { LaneOwnerHandle { handle: h } => (h as String) == "synthetic-witness-owner" } - _ => false - } -} - -data falsifier_two_unknowns_witness_note: String = "The discriminating pair for the two-unknowns split: the SAME planned roster and the SAME owner roster, differing only in which component is being routed. Index 9 is not planned at all and must yield RoutingLaneUndetermined; index 2 is planned as known_red_probe, which the fixture owner roster does not cover, and must yield RoutingOwnerUndeclared STILL NAMING ITS LANE. If the two arms were ever collapsed, one of these two witnesses goes red — which is what makes the split enforced rather than merely described." - -fn witness_routing_refuses_lane_undetermined() -> Bool { - match falsifier_route_row( - planned: falsifier_witness_planned_three(), - owners: falsifier_witness_owner_rows(), - row: falsifier_witness_row(index: 9, done: false) - ) { - RoutingLaneUndetermined { index: i, cause: c } => i == 9 - _ => false - } -} - -fn witness_routing_refuses_owner_undeclared_but_names_lane() -> Bool { - match falsifier_route_row( - planned: falsifier_witness_planned_three(), - owners: falsifier_witness_owner_rows(), - row: falsifier_witness_row(index: 2, done: false) - ) { - RoutingOwnerUndeclared { index: i, lane: l, cause: c } => - (i == 2) && falsifier_lane_eq(left: l, right: LaneKnownRedProbe) - _ => false - } -} - -fn witness_routing_empty_owner_roster_still_determines_lane() -> Bool { - let r = falsifier_route_row( - planned: falsifier_witness_planned_three(), - owners: falsifier_lane_owner_rows, - row: falsifier_witness_row(index: 3, done: false) - ) - falsifier_routing_lane_is_determined(r: r) && !falsifier_routing_reaches_owner(r: r) -} - -fn witness_unsuccessful_routings_exclude_done_rows() -> Bool { - let routings = falsifier_unsuccessful_routings( - planned: falsifier_witness_planned_three(), - owners: falsifier_witness_owner_rows(), - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: false), - falsifier_witness_row(index: 3, done: true) - ] - ) - (list_length(items: routings) == 1) - && falsifier_all_lanes_determined(rs: routings) - && match routings.first() { - Present { value: r } => - match r { - RoutingOwnerUndeclared { index: i, lane: l, cause: c } => - (i == 2) && falsifier_lane_eq(left: l, right: LaneKnownRedProbe) - _ => false - } - Absent => false - } -} - -fn falsifier_witness_row_with(index: Nat, mode: NonEmptyStr, detail: NonEmptyStr) -> FloorComponentRow? { - floor_component_row_of_failure_mode( - run_id: "witness" as NonEmptyStr, - index: index, - label: "discovery-corpus[2 root(s)+0 explicit, adaptive width]" as NonEmptyStr, - selection_tag: "applied" as NonEmptyStr, - witnesses: 0, - failure_mode: mode, - detail: detail, - wall: millisecond(count: 0) - ) -} - -fn falsifier_witness_class_of_mode(mode: NonEmptyStr) -> String { - match falsifier_witness_row_with(index: 1, mode: mode, detail: "synthetic" as NonEmptyStr) { - Absent => "row_not_built" - Present { value: row } => - match falsifier_failure_class_of_row(row: row) { - Absent => "not_failing" - Present { value: c } => falsifier_failure_class_name(c: c) - } - } -} - -data falsifier_class_split_witness_note: String = "The Class A / Class B control, driven through the seed's OWN failure-mode vocabulary rather than through hand-built outcomes, so it exercises the real mapping gunbc.floor_component_receipt performs. It asserts both what the receipt CAN distinguish and what it CANNOT: BudgetExceeded (Class A, host-sensitive) is separable and lands on budget_exceeded, while WitnessRed (Class B, deterministic) and Infra are BOTH failed_indistinct — the collapse named in falsifier_failure_class_note. Asserting the collapse rather than working around it is the point: if the receipt is later fixed to carry the mode through, this row goes red and is the trigger to split ClassFailedIndistinct, which is exactly the dissolution signal that note declares." - -fn witness_failure_class_separates_budget_from_witness_red() -> Bool { - (falsifier_witness_class_of_mode(mode: "BudgetExceeded" as NonEmptyStr) == "budget_exceeded") - && (falsifier_witness_class_of_mode(mode: "WitnessRed" as NonEmptyStr) == "failed_indistinct") - && (falsifier_witness_class_of_mode(mode: "not_reached" as NonEmptyStr) == "not_reached") - && (falsifier_witness_class_of_mode(mode: "none" as NonEmptyStr) == "not_failing") -} - -fn witness_failure_class_records_the_infra_collapse() -> Bool { - falsifier_witness_class_of_mode(mode: "Infra" as NonEmptyStr) == falsifier_witness_class_of_mode(mode: "WitnessRed" as NonEmptyStr) -} - -fn witness_failing_set_names_lane_and_class_per_component() -> Bool { - let failing = falsifier_failing_set( - planned: falsifier_witness_planned_three(), - owners: falsifier_witness_owner_rows(), - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: false), - falsifier_witness_row(index: 3, done: false) - ] - ) - (list_length(items: failing) == 2) - && match failing.first() { - Present { value: f } => - (f.index == 2) - && match f.routing { - RoutingOwnerUndeclared { index: i, lane: l, cause: c } => - falsifier_lane_eq(left: l, right: LaneKnownRedProbe) - _ => false - } - && (falsifier_failure_class_name(c: f.failure_class) == "failed_indistinct") - Absent => false - } -} - -data falsifier_signature_witness_note: String = "The stale-issue control, expressed as the property that would have caught #7737: two windows failing in the SAME components but for DIFFERENT reasons must not produce the same signature. If they did, a consumer comparing windows would see no transition and leave a thirty-hour-old description standing, which is the live defect this lane was reprioritized onto." - -fn witness_class_signature_distinguishes_a_class_transition() -> Bool { - let planned = falsifier_witness_planned_three() - let owners = falsifier_witness_owner_rows() - match falsifier_witness_row_with(index: 2, mode: "BudgetExceeded" as NonEmptyStr, detail: "class A" as NonEmptyStr) { - Absent => false - Present { value: window_a } => - match falsifier_witness_row_with(index: 2, mode: "WitnessRed" as NonEmptyStr, detail: "class B" as NonEmptyStr) { - Absent => false - Present { value: window_b } => - falsifier_failing_class_signature( - failing: falsifier_failing_set(planned: planned, owners: owners, rows: [window_a]) - ) != falsifier_failing_class_signature( - failing: falsifier_failing_set(planned: planned, owners: owners, rows: [window_b]) - ) - } - } -} - -fn witness_class_signature_stable_when_class_persists() -> Bool { - let planned = falsifier_witness_planned_three() - let owners = falsifier_witness_owner_rows() - match falsifier_witness_row_with(index: 2, mode: "WitnessRed" as NonEmptyStr, detail: "first window" as NonEmptyStr) { - Absent => false - Present { value: window_a } => - match falsifier_witness_row_with(index: 2, mode: "WitnessRed" as NonEmptyStr, detail: "later window, different detail" as NonEmptyStr) { - Absent => false - Present { value: window_b } => - falsifier_failing_class_signature( - failing: falsifier_failing_set(planned: planned, owners: owners, rows: [window_a]) - ) == falsifier_failing_class_signature( - failing: falsifier_failing_set(planned: planned, owners: owners, rows: [window_b]) - ) - } - } -} - -data falsifier_no_green_arm_witness_note: String = "The construction wall's own control. It asserts a NEGATIVE — that a complete run standing still does not project to observed — which is the only shape available when the point is that a value cannot be constructed. It is deliberately weaker than the wall itself: the wall is that FalsifierObservedHealth has no healthy arm, which the typechecker enforces at every call site and no witness could ever establish more strongly. This row exists so that ADDING a green arm without also composing in the semantic evidence term breaks a test rather than passing silently (DESIGN section 4b, meta-obligation 4: the discriminating control stays enrolled after the climb)." - -fn witness_complete_standing_does_not_project_to_observed() -> Bool { - let standing = falsifier_run_standing_from( - planned: falsifier_witness_planned_three(), - rows: [ - falsifier_witness_row(index: 1, done: true), - falsifier_witness_row(index: 2, done: true), - falsifier_witness_row(index: 3, done: true) - ] - ) - falsifier_run_standing_is_complete(v: standing) - && match falsifier_observed_health(v: standing) { - ObservedHealthUndecided { standing: s, missing_term: t } => - falsifier_run_standing_is_complete(v: s) - ObservedHealthRefused { standing: s, cause: c } => false - } -} - -fn witness_incomplete_standing_refuses_observed() -> Bool { - let standing = falsifier_run_standing_from( - planned: falsifier_witness_planned_three(), - rows: [falsifier_witness_row(index: 1, done: true)] - ) - match falsifier_observed_health(v: standing) { - ObservedHealthRefused { standing: s, cause: c } => !falsifier_run_standing_is_complete(v: s) - ObservedHealthUndecided { standing: s, missing_term: t } => false - } -} - -fn witness_lane_names_are_distinct() -> Bool { - let names = [ - falsifier_lane_name(l: LanePredictOnly), - falsifier_lane_name(l: LaneSelfHostWet), - falsifier_lane_name(l: LaneSelfHostWetKnownRed), - falsifier_lane_name(l: LaneKnownRedProbe), - falsifier_lane_name(l: LaneSilentPickGate), - falsifier_lane_name(l: LaneRehomedBinWet), - falsifier_lane_name(l: LaneSubstrateLongLane), - falsifier_lane_name(l: LaneCadenceWitness), - falsifier_lane_name(l: LaneGates) - ] - fold(names, init: true, f: fn(acc, n) { - acc && (fold(names, init: 0, f: fn(c, m) { if m == n { c + 1 } else { c } }) == 1) - }) -} - -data falsifier_lane_receipt_wiring_dissolve_on: DissolutionCondition = unbound_dissolution(description: "dissolve-on: the falsifier receipt document carries these blocks. Today the seed calls gunbc.floor_component_receipt floor_component_receipt_document_with_selection with rows only, and that function is SHARED with the per-PR floor, which has no lane roster — so adding a lane block there unconditionally would fabricate lane identity for components that have none. Wiring is therefore a falsifier-spe") diff --git a/dag/gunbc/falsifier_run_control.dag b/dag/gunbc/falsifier_run_control.dag deleted file mode 100644 index a5d85ad2bf6..00000000000 --- a/dag/gunbc/falsifier_run_control.dag +++ /dev/null @@ -1,110 +0,0 @@ -module gunbc.falsifier_run_control - -import std.types { String, NonEmptyStr, List, Int } -import extdeps.languages.yaml.types { yaml_string, kv } -import extdeps.github.actions { Step, RunStep } -import gunbc.ci_layer_roots { witness_layer_roots } -import gunbc.cli_invoke { - CiPlanArtifactPlan, - FalsifierNativeCacheColdPlan, - claim_executor_run_plan_shell, -} -import gunbc.merge_admission_produce { ci_repo_root_shell } -import v2.std.collection { Absent } - -type FalsifierControlRole - = AffectedSetPredictOnlyCold - | CompileCleanWholeTreeCold - | NativeCacheCold - -data falsifier_run_control_note: String = "Closed population of required falsifier control roles (F0, operator mandate 2026-08-04, corrected 2026-08-04 msg_f71d6501). A control cannot silently vanish because a step was renamed or moved — the roster is the authority the totality receipt (F1) and alert router consume. This module owns the RUN-LEVEL control model for the falsifier cadence: cold controls execute after the affected-set control CONCLUDES (always + release_build success), not only when it succeeds — verified defect on run 30935833427 where steps 13-14 SKIPPED while step 12 receipt upload PASSED. RETRACTED: per-PR compile-clean containment on the ci job — measured receipts proved the falsifier is correctly reporting main is red (witness redness, not infrastructure failure); containing an unreliable control was the wrong frame. floor_component_receipt owns batch-grain rows inside the affected-set control." - -fn falsifier_control_role_label(role: FalsifierControlRole) -> NonEmptyStr { - match role { - AffectedSetPredictOnlyCold => "affected-set predict-only cold" as NonEmptyStr - CompileCleanWholeTreeCold => "compile-clean whole-tree cold" as NonEmptyStr - NativeCacheCold => "native-cache cold" as NonEmptyStr - } -} - -data falsifier_required_control_roles: List = [ - AffectedSetPredictOnlyCold, - CompileCleanWholeTreeCold, - NativeCacheCold -] - -data falsifier_release_build_step_id: String = "release_build" - -data falsifier_control_prerequisite_if: String = concat("always() && !cancelled() && steps.", concat(ci_release_bins_step_id, ".outcome == 'success'")) - -data falsifier_control_prerequisite_note: String = "Cold controls execute after the affected-set control CONCLUDES, not after it succeeds — provided checkout, toolchain, and release binaries succeeded. always() lifts the default success() gate that skipped compile-clean and native-cache whenever the predict-only floor reddened (verified run 30935833427: steps 13-14 SKIPPED while step 12 receipt upload PASSED via its own always()). The prerequisite refuses when binaries were never unpacked/verified into this job; it does NOT require the floor step to succeed. THIS IS THE THIRD REPAIR OF THIS CONTROL, NOT THE SECOND, AND THE DARK WINDOW PREDATES #7812 (corrected 2026-08-06, parent session still-bat-561 msg_7ae919df — the prior form of this note read the defect as starting at commit 491ee01d/#7812, which understates it). BEFORE #7812, the controls were ALREADY dark: the inherited default success() gate skipped both cold controls whenever the predict-only floor reddened, and the floor WAS red on every scheduled run checked in that earlier window. #7812 was itself a repair attempt for that earlier defect (adding always()), but it introduced a NEW bug — citing steps.release_build.outcome, a cross-job step id — that made the controls go from conditionally-skipped to UNCONDITIONALLY skipped regardless of upstream outcome, strictly worse than what it repaired. GITHUB ACTIONS steps. IS JOB-SCOPED (found 2026-08-06): falsifier_build_job() (gunbc.falsifier_workflow) owns ci_release_build_step() with id falsifier_release_build_step_id (\"release_build\"), but the cold-control steps this if_condition gates live in the SEPARATE falsifier_floor_job() alongside ci_release_bins_unpack_verify_step() (id ci_release_bins_step_id, \"release_bins\") — a cross-job steps.release_build reference resolves to null and the comparison is unconditionally false. The immediately-following #7839 fixed the step's own id but not this cross-job reference, so the unconditional-skip bug from #7812 persisted through it. Fixed here (#7894) to cite ci_release_bins_step_id, the correct same-job step. falsifier_release_build_step_id is retained: falsifier_build_job's own steps (ci_selection_control_step et al.) legitimately reference it within that job. THE MEASURED DAMAGE WINDOW IS AT LEAST SIXTEEN DAYS, NOT ONE: a second session (merry-wren-185, PR #7908) independently traced the underlying corpus diagnostics these controls exist to catch to a namespace-resolution change merged 2026-07-20T17:26:51Z — sixteen days before this note's previously-stated window start — and by the time #7894 lands, that corpus damage is measured at 19 hard self-compile diagnostics across nvidia.dag, generated_artifact_drift_test.dag, complexity.dag, enforcement/receipts.dag, rust_test_fixtures.dag, and 06_translate.dag (cleared separately by PR #7908, not by this fix). So: this control has not been reliably executing for at least sixteen days, across at least two repair attempts, and the corpus damage it failed to catch during that window is the 19-diagnostic count above with the oldest cause dating to 2026-07-20 — #7894 is the third fix, and whether it is the one that sticks is proven only by a real scheduled run, not by this argument (see falsifier_control_prerequisite_execution_proof_note). HONEST BOUND (operator ruling 2026-08-05): step-level always() does not survive total runner/job loss — if the runner dies or the job is cancelled before a cold control is reached, that step cannot execute. Follow-up, explicitly not a #7812 blocker: split independent controls into serially dependent jobs that consume the build artifact but not each other's success outcome." - -data falsifier_control_prerequisite_execution_proof_note: String = "EXECUTION-PROVING EVIDENCE, NOT CONDITION SHAPE (operator ruling 2026-08-06, parent session still-bat-561 msg_7ae919df): the two repairs before this one (the pre-#7812 inherited success() gate, and #7812's cross-job steps.release_build reference) both shipped WITH shape-based witnesses — assertions on the literal if_condition string — while the control itself stayed dark on every real run. A witness that checks condition SHAPE cannot distinguish a correct always()-based prerequisite from one that references a step id which will resolve to null at runtime; both produce an identical string. falsifier_run_control_witness_test.dag's five witnesses are exactly this shape class (they assert falsifier_control_prerequisite_if equals/contains expected substrings) and remain useful for catching a regression to the OLD string, but none of them can prove the step actually ran. That proof requires a real scheduled falsifier run: after this fix merges, the acceptance gate is the FIRST scheduled falsifier run afterward — inspect its job's compile-clean and native-cache cold-control steps via gh run view --json jobs and confirm each step's conclusion is 'success' or 'failure', never 'skipped'. This fix is not entitled to be declared done at merge time; it is declared done when that first post-merge run shows both cold controls concluding non-skipped. If a subsequent run shows either step skipped again, the corrected root cause is still wrong and this is a fourth repair, not a completed third one." - -data gunbc_falsifier_compile_clean_cold_control_timeout_minutes: Int = 30 - -data gunbc_falsifier_compile_clean_cold_control_note: String = "Compile-clean whole-tree cold control (2026-07-16, lands with the per-PR import-closure scoping in tools.dag_compile_clean_scope): PR floors now compile only the affected entry closure, and main pushes already skip on an empty diff — so this step is the deterministic whole-tree execution of the compile-clean gate, on the falsifier cadence, mirroring how the predict-only cold run controls witness selection. GUNBC_CI_COMPILE_CLEAN_COLD_CONTROL=1 forces the scope plan to WholeTree before any diff observation (a widen-to-more-checking control arm, not an escape hatch — it can only force the gate to run in full). Plan function gunbc_ci_plan_artifact_batches is batch 1 of the floor schedule: exactly the compile-clean anchor through the same executor path that installs and consumes the in-run compile receipt. F0 (2026-08-04): if_condition uses falsifier_control_prerequisite_if so this control runs even when the predict-only floor reddens." - -fn compile_clean_cold_control_invoke() -> String { - concat( - concat("ROOT=", concat(ci_repo_root_shell(), "\n")), - claim_executor_run_plan_shell( - source_roots: witness_layer_roots, - plan_entry: "src/v2/workflow/ci_floor_plan.dag", - plan_function: CiPlanArtifactPlan, - notice_title: Absent, - rooted: false - ) - ) -} - -fn compile_clean_cold_control_step() -> Step { - RunStep { - name: Present { value: "compile-clean whole-tree cold control (scoped-PR admission counterpart)" }, - id: none, - run: compile_clean_cold_control_invoke(), - shell: none, - env: Present { - value: [kv(key: "GUNBC_CI_COMPILE_CLEAN_COLD_CONTROL", value: yaml_string(s: "1"))] - }, - working_directory: none, - if_condition: Present { value: falsifier_control_prerequisite_if }, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_falsifier_compile_clean_cold_control_timeout_minutes } - } -} - -data gunbc_falsifier_native_cache_cold_control_timeout_minutes: Int = 30 - -data gunbc_falsifier_native_cache_cold_control_note: String = "Native-cache cold control (P6 durable-cache rail, 2026-07-21): the nightly Wet emit-on-demand/self-host receipt batch re-executed with GUNBC_CI_NATIVE_CACHE_COLD_CONTROL=1, which makes emit_host_run_transport_cached ignore every .native_ready marker — the full emit+cargo+run chain runs cold on the falsifier cadence while the main falsifier_step's run of the same batch stays warm (the warm-rate receipt the per-PR enrollment decision reads). Widen-to-more-checking control arm, not an escape hatch: the env can only force the transport to do MORE work, never skip it. Mirrors compile_clean_cold_control_step. F0 (2026-08-04): if_condition uses falsifier_control_prerequisite_if so this control runs even when the predict-only floor reddens. SERIAL after compile-clean — must not compete for memory with the dying floor control." - -fn native_cache_cold_control_invoke() -> String { - concat( - concat("ROOT=", concat(ci_repo_root_shell(), "\n")), - claim_executor_run_plan_shell( - source_roots: witness_layer_roots, - plan_entry: "src/v2/workflow/ci_floor_plan.dag", - plan_function: FalsifierNativeCacheColdPlan, - notice_title: Absent, - rooted: false - ) - ) -} - -fn native_cache_cold_control_step() -> Step { - RunStep { - name: Present { value: "native-cache cold control (warm-tier admission counterpart)" }, - id: none, - run: native_cache_cold_control_invoke(), - shell: none, - env: Present { - value: [kv(key: "GUNBC_CI_NATIVE_CACHE_COLD_CONTROL", value: yaml_string(s: "1"))] - }, - working_directory: none, - if_condition: Present { value: falsifier_control_prerequisite_if }, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_falsifier_native_cache_cold_control_timeout_minutes } - } -} - -data ci_release_bins_step_id: String = "release_bins" diff --git a/dag/gunbc/falsifier_workflow.dag b/dag/gunbc/falsifier_workflow.dag deleted file mode 100644 index f90459f4ed4..00000000000 --- a/dag/gunbc/falsifier_workflow.dag +++ /dev/null @@ -1,590 +0,0 @@ -module gunbc.falsifier_workflow - -import v2.std.collection { Absent } -import extdeps.languages.yaml.types { yaml_string, yaml_int, kv } -import extdeps.cron.schedule_model { CronSchedule, Wildcard, Exact, Listed } -import extdeps.github.actions { - Workflow, Job, Step, RunStep, UsesStep, - WorkflowTrigger, Schedule, WorkflowDispatch, - WorkflowPermissions, PermRead, - ConcurrencyMappingQueueNotMax, CancelInProgressBool, - upload_artifact_action, download_artifact_action -} -import gunbc.ci_workflow { - ci_prelude_steps, ci_release_build_step, - ci_floor_job_prelude_steps, - ci_floor_peak_pre_step, ci_floor_peak_post_step, - ci_selection_control_step, - ci_release_bins_pack_step, ci_release_bins_upload_step, - ci_release_bins_download_step, ci_release_bins_unpack_verify_step, - ci_floor_receipts_upload_step, - gunbc_ci_release_build_step_timeout_minutes, gunbc_ci_aux_step_timeout_minutes, gunbc_ci_prelude_allowance_minutes, - gunbc_ci_selection_control_step_timeout_minutes, - gunbc_ci_artifact_transfer_step_timeout_minutes -} -import v2.workflow.ci_floor_peak_emit { - ci_floor_phase_journal_env_name, - ci_floor_phase_journal_path, - ci_floor_phase_journal_artifact_name -} -import gunbc.floor_component_receipt { - floor_component_receipt_path, - floor_component_receipt_artifact_name, - floor_component_receipt_schema, -} -import gunbc.ci_runner_target { gunbc_ci_selected_runner_spec } -import gunbc.falsifier_run_control { - compile_clean_cold_control_step, - native_cache_cold_control_step, - gunbc_falsifier_compile_clean_cold_control_timeout_minutes, - gunbc_falsifier_native_cache_cold_control_timeout_minutes, -} -import gunbc.falsifier_cold_corpus_execution { - falsifier_cold_corpus_execution_receipt_path, - falsifier_cold_corpus_job_id, - aggregate_shell_receipt_build_failed, - aggregate_shell_receipt_build_cancelled, - aggregate_shell_receipt_build_skipped, - aggregate_shell_receipt_cold_skipped, - aggregate_shell_receipt_cold_cancelled, - aggregate_shell_receipt_cold_failed_before_receipt, - aggregate_shell_receipt_cold_receipt_artifact_absent, - aggregate_shell_receipt_corpus_executed, -} -import gunbc.shell_bash_runner { bash_escape_for_double_quotes } -import std.disposition { Disposition, Scaffold, SingleAuthority } -import std.decl_ref { DeclarationRef, WholeDeclaration } -import gunbc.cli_invoke { - FalsifierPlan, - plan_function_name, - claim_executor_run_plan_shell -} -import gunbc.merge_admission_produce { ci_repo_root_shell } -import gunbc.ci_layer_roots { witness_layer_roots } -import extdeps.languages.yaml.emit { serialize_yaml } -import extdeps.languages.yaml.gha_workflow { project_workflow_to_yaml } -import std.types { NonEmptyStr } -import std.dissolution { DissolutionCondition, unbound_dissolution, dissolution_description } - -type FalsifierStepTimeoutBasis { - single_step_cap_minutes: Int - prior_cap_minutes: Int - current_cap_minutes: Int - measurement_github_actions_run_id: NonEmptyStr - not_algebraically_closed_from: NonEmptyStr - dissolution: DissolutionCondition -} - -data gunbc_falsifier_step_timeout_basis: FalsifierStepTimeoutBasis = FalsifierStepTimeoutBasis { - single_step_cap_minutes: 170, - prior_cap_minutes: 120, - current_cap_minutes: 170, - measurement_github_actions_run_id: "29135185172", - not_algebraically_closed_from: "gunbc.ci_spec floor batch-clamp overheads (per-batch wall at execution time; no composed sum closes to the single-step cap)", - dissolution: unbound_dissolution(description: "gunbc.ci_spec batch-clamp overheads algebraically compose to gunbc_falsifier_step_timeout_minutes, replacing the measured-envelope basis") -} - -data gunbc_falsifier_step_timeout_minutes: Int = 170 - -fn gunbc_falsifier_step_timeout_basis_is_measured_not_composed() -> Bool { - match gunbc_falsifier_step_timeout_basis { - FalsifierStepTimeoutBasis { - single_step_cap_minutes: cap, - prior_cap_minutes: 120, - current_cap_minutes: 170, - measurement_github_actions_run_id: run, - not_algebraically_closed_from: _, - dissolution: _ - } => - cap == gunbc_falsifier_step_timeout_minutes - && run == "29135185172" - && gunbc_falsifier_step_timeout_minutes == 170 - } -} - -data gunbc_falsifier_receipt_flush_allowance_minutes: Int = 3 - -fn gunbc_falsifier_soft_deadline_minutes() -> Int { - gunbc_falsifier_step_timeout_minutes - gunbc_falsifier_receipt_flush_allowance_minutes -} - -fn gunbc_falsifier_soft_deadline_precedes_the_hard_kill() -> Bool { - gunbc_falsifier_soft_deadline_minutes() < gunbc_falsifier_step_timeout_minutes - && gunbc_falsifier_receipt_flush_allowance_minutes > 0 - && gunbc_falsifier_soft_deadline_minutes() > 0 -} - -data gunbc_falsifier_soft_deadline_note: String = "THE INTERNAL DEADLINE, DERIVED FROM THE FOREIGN ONE — never a second independently authored number. gunbc_falsifier_step_timeout_minutes is a GitHub Actions step timeout: a SIGKILL delivered by the runner, which the executor cannot catch, cannot log, and cannot conclude through. Crossing it destroyed the run's evidence (the receipt was written once, after every batch), so the one failure mode most in need of a diagnosis was the one that erased its own. The checkpoint now keeps completed components' state on disk; this row is the other half — stop ADMITTING work early enough that the walk concludes itself, on its own terms, with a typed disposition per component, instead of vanishing mid-flight. The allowance is what the walk needs after its last batch to finish the receipt and let the artifact upload step run: the receipt write is a resolve (memoized, so paid once earlier in the run) plus a document eval over single-digit component rows, which is seconds, and 3 minutes is that with room for a loaded runner rather than a measured envelope. THE SUBTRACTION IS THE POINT: raising the step cap moves the soft deadline with it and the two can never cross, which is what makes this a derivation rather than the tuned second knob a bare 167 would be. IT IS NOT A COST BOUND AND MUST NOT BE READ AS ONE. Reaching it means the corpus did not finish in the time the lane has — a DeadlineReached disposition on every unadmitted component, counted, with the run red. That is a measurement of a cost problem, not a resolution of one, and the remedy stays what DESIGN's five-minute-CI-gate lane says it is: remove redundant computation, never raise the cap first." - -data gunbc_falsifier_step_timeout_note: String = "120 -> 170 (2026-07-11, run 29135185172 receipt): the first corpus-reaching cold run was TIME-killed at the 120-min step ceiling with the corpus incomplete (1970 rows, closure 1396 modules, width 1) and floor peak 16146612224 bytes against a 16GiB slot budget, still growing - so 120 censored the measurement without bounding anything real (the memory cap is the true wall). 170 lets a nightly run reach either completion (exact-labeled receipt) or the cap kill (censored-labeled receipt); both are the falsifier doing its measurement job, and the job backstop DERIVES from this value so it stretches in step. Revisit down when the resolver graph-major module split (S2a move 2) shrinks cold-resolve wall and residency." - -data falsifier_plan_function: String = plan_function_name(p: FalsifierPlan) - -fn falsifier_invoke() -> String { - concat( - concat("ROOT=", concat(ci_repo_root_shell(), "\n")), - claim_executor_run_plan_shell( - source_roots: witness_layer_roots, - plan_entry: "src/v2/workflow/ci_floor_plan.dag", - plan_function: FalsifierPlan, - notice_title: Absent, - rooted: false - ) - ) -} - -fn falsifier_step() -> Step { - RunStep { - name: Present { value: "affected-set falsifier (predict-only cold run)" }, - id: Present { value: "floor" }, - run: falsifier_invoke(), - shell: none, - env: Present { - value: [ - kv(key: "GUNBC_CI_DIFF_BASE", value: yaml_string(s: "HEAD~20")), - kv(key: "GUNBC_CI_DIFF_HEAD", value: yaml_string(s: "HEAD")), - kv(key: ci_floor_phase_journal_env_name, value: yaml_string(s: ci_floor_phase_journal_path)) - ] - }, - working_directory: none, - if_condition: none, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_falsifier_step_timeout_minutes } - } -} - -data falsifier_native_cache_cold_plan_target_note: String = "THE STEP WHOSE PLAN TARGET ESCAPED THE #7470 MIGRATION, kept as the receipt for why the target is now a typed variant instead of an argv token. Every other consumer derived its plan name from a constant, so the 2026-07-30 WalkPlan rename reached all four automatically; this step alone passed the inline literal \"gunbc_falsifier_native_cache_cold_batches\", derived from nothing, and was left behind returning a bare List>. The executor's strict parser then refused it on every one of the 8 falsifier runs that armed this step (0 successes), and it read as intermittent only because the step is skipped whenever the falsifier step fails first.\n\nThe first repair here added a naming constant beside the other four. That was still validation — it made the rename reach this site but left the next author free to type a fresh literal. The constant was therefore DELETED in the same change that introduced gunbc.cli_invoke PlanFunction: an inline literal at this argument is now a type error, so the roster is closed by construction and a String projection with no consumer would be exactly the inert carrier §2 forbids. Dissolution-on-climb (§4b): the wall replaces the lower-rung machinery rather than accumulating beside it." - -data floor_component_receipt_upload_note: String = "Uploads the floor's per-component receipt so the alert workflow can READ which component failed instead of inferring one hardcoded story from the overall run conclusion (gunbc.floor_component_receipt carries the priced defect). if: always() is load-bearing and is the whole point: the receipt matters MOST on a red run, and a red floor step would otherwise skip the upload and leave the alert blind — which is the state that produced the false 'affected-set cold control is dark' claim on run 30509024051. It sits immediately after falsifier_step so it captures that step's receipt. F0 (2026-08-04): compile-clean and native-cache cold controls now use falsifier_control_prerequisite_if (always + release_build success) in gunbc.falsifier_run_control — they execute after the floor concludes, not only when it succeeds. if-no-files-found: error, because a silently absent receipt is the same blindness one layer down; the alert's own missing-artifact arm reports an explicit unknown rather than re-widening. Its transfer term joins gunbc_falsifier_job_backstop_timeout_minutes so the backstop stays the exact step-sum + prelude (the invariant falsifier_workflow_witness_test asserts)." - -fn floor_component_receipt_upload_step() -> Step { - UsesStep { - name: Present { value: "Upload floor component receipt (read by falsifier-alert)" }, - id: none, - uses: upload_artifact_action, - with: Present { - value: [ - kv(key: "name", value: yaml_string(s: floor_component_receipt_artifact_name)), - kv(key: "path", value: yaml_string(s: floor_component_receipt_path)), - kv(key: "if-no-files-found", value: yaml_string(s: "error")), - kv(key: "retention-days", value: yaml_int(n: 30)), - kv(key: "compression-level", value: yaml_int(n: 0)) - ] - }, - env: none, - if_condition: Present { value: "always()" }, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_ci_artifact_transfer_step_timeout_minutes } - } -} - -data floor_phase_journal_upload_note: String = "Uploads the synced floor phase journal so post-mortems do not depend on retained console log truncation. The post-read shell step prints the journal, but gh run view --log can end hours before the job completes (run 31334672366: full API job log shows [floor-phase-journal] at 23:52:41 while gh run view stops at 21:52:34). if: always() captures partial journals when the floor step times out. if-no-files-found: warn — absence is a counted signal (env unset or journal never opened), not a silent skip. Its transfer term joins gunbc_falsifier_cold_corpus_job_backstop_timeout_minutes beside floor_component_receipt_upload_step." - -fn floor_phase_journal_upload_step() -> Step { - UsesStep { - name: Present { value: "Upload floor phase journal (survives killed floor)" }, - id: none, - uses: upload_artifact_action, - with: Present { - value: [ - kv(key: "name", value: yaml_string(s: ci_floor_phase_journal_artifact_name)), - kv(key: "path", value: yaml_string(s: ci_floor_phase_journal_path)), - kv(key: "if-no-files-found", value: yaml_string(s: "warn")), - kv(key: "retention-days", value: yaml_int(n: 30)), - kv(key: "compression-level", value: yaml_int(n: 0)) - ] - }, - env: none, - if_condition: Present { value: "always()" }, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_ci_artifact_transfer_step_timeout_minutes } - } -} - -fn gunbc_falsifier_build_job_backstop_timeout_minutes() -> Int { - gunbc_ci_release_build_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes -} - -fn gunbc_falsifier_selection_control_job_backstop_timeout_minutes() -> Int { - gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_selection_control_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes -} - -fn gunbc_falsifier_cold_corpus_job_backstop_timeout_minutes() -> Int { - gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_falsifier_step_timeout_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_falsifier_compile_clean_cold_control_timeout_minutes + gunbc_falsifier_native_cache_cold_control_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes -} - -fn gunbc_falsifier_aggregate_verdict_job_backstop_timeout_minutes() -> Int { - gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes -} - -fn falsifier_floor_component_receipt_download_step() -> Step { - UsesStep { - name: Present { value: "Download floor component receipt (cold-corpus execution witness)" }, - id: Present { value: "floor_component_receipt_download" }, - uses: download_artifact_action, - with: Present { - value: [ - kv(key: "name", value: yaml_string(s: floor_component_receipt_artifact_name)), - kv(key: "path", value: yaml_string(s: "target")) - ] - }, - env: none, - if_condition: none, - continue_on_error: Present { value: true }, - timeout_minutes: Present { value: gunbc_ci_artifact_transfer_step_timeout_minutes } - } -} - -fn gunbc_falsifier_job_backstop_timeout_minutes() -> Int { - gunbc_falsifier_build_job_backstop_timeout_minutes() + gunbc_falsifier_selection_control_job_backstop_timeout_minutes() + gunbc_falsifier_cold_corpus_job_backstop_timeout_minutes() + gunbc_falsifier_aggregate_verdict_job_backstop_timeout_minutes() -} - -data gunbc_falsifier_job_split_note: String = "Four-job topology (2026-08-07, operator ruling proud-bear-834 adhoc-8b992195-d13; pre-authorized follow-up named in gunbc.falsifier_run_control falsifier_control_prerequisite_note): falsifier-build compiles and uploads release-bins ONLY; selection-control independently validates prediction machinery; cold-corpus runs whenever build artifacts are available — needs: [falsifier-build] alone, NOT selection-control — so a selector RED is a reason to run the broad backstop, not suppress it (specimen run 31181460723: selection failure skipped the entire corpus job). aggregate-verdict fails if either arm is red and emits gunbc.falsifier_cold_corpus_execution ColdCorpusExecution so CorpusNotRun is never read as 'falsifier found a regression'. Prior two-job split (2026-08-04) isolated cgroup peak for the floor path; this change isolates SELECTION from CORPUS scheduling." - -data gunbc_falsifier_selection_control_relocation_note: String = "The affected-set selection control (ci_selection_control_step, authority gunbc.ci_workflow) rides this cadence as of 2026-07-29 — full rationale in gunbc_ci_selection_control_step_note. As of the 2026-08-07 four-job topology it lives in selection-control (needs: [falsifier-build]): AFTER artifact download/unpack, executes the release-built floor_skip_discovery_witness binary, in its own job cgroup separate from cold-corpus. cold-corpus brackets peak pre/post around falsifier_step only. Hermetic ~10m control still reds before the up-to-170m corpus walk." - -data falsifier_aggregate_verdict_if: String = "always() && !cancelled()" - -data falsifier_aggregate_verdict_shell_emit_scaffold: Disposition = Scaffold { - dissolves_to: SingleAuthority, - bind: DeclarationRef { - module_path: "gunbc.falsifier_workflow", - decl_name: "falsifier_aggregate_verdict_script", - field: WholeDeclaration - } -} - -data falsifier_aggregate_verdict_shell_emit_dissolution_trigger: DissolutionCondition = unbound_dissolution(description: "🟡 dissolve-on: falsifier_aggregate_verdict_script — concat-built foreign-executor (GitHub Actions run:) aggregate cadence verdict shell; receipt JSON literals are derived from gunbc.falsifier_cold_corpus_execution classify_cold_corpus_execution / cold_corpus_execution_receipt_json, but the transport itself remains hand-shell; DISSOLVES WHEN bash-emit (#5828 / ROADMAP 6-shell-slice0 / shell→intent Phase 2) realizes the aggregate verdict step through orchestration emit or typed host_effect_apply without a medium-as-string concat scaffold") - -fn falsifier_aggregate_verdict_write_receipt(json: String) -> String { - concat( - concat("printf '%s\\n' \"", concat(bash_escape_for_double_quotes(s: json), "\"")), - concat(" > ", concat(falsifier_cold_corpus_execution_receipt_path, "\n")) - ) -} - -fn falsifier_aggregate_verdict_script() -> String { - concat( - concat("# ", concat(dissolution_description(condition: falsifier_aggregate_verdict_shell_emit_dissolution_trigger), "\n")), - concat( - "set -euo pipefail\n", - concat( - "mkdir -p target\n", - concat( - "BUILD_RESULT=\"${{ needs.falsifier-build.result }}\"\n", - concat( - "SELECTION_RESULT=\"${{ needs.selection-control.result }}\"\n", - concat( - "COLD_RESULT=\"${{ needs.cold-corpus.result }}\"\n", - concat( - concat( - "if [ \"$\{BUILD_RESULT}\" = \"cancelled\" ]; then\n", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_build_cancelled()), - concat( - " printf '%s\\n' \"::error::Cold corpus did not run — build cancelled; infrastructure, not a falsifier regression finding\"\n", - concat( - " exit 1\n", - concat( - "fi\n", - concat( - concat( - "if [ \"$\{BUILD_RESULT}\" = \"skipped\" ]; then\n", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_build_skipped()), - concat( - " printf '%s\\n' \"::error::Cold corpus did not run — build skipped; infrastructure, not a falsifier regression finding\"\n", - concat( - " exit 1\n", - concat( - "fi\n", - concat( - concat( - "if [ \"$\{BUILD_RESULT}\" != \"success\" ]; then\n", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_build_failed()), - concat( - " printf '%s\\n' \"::error::Cold corpus did not run — build unavailable ($\{BUILD_RESULT}); infrastructure, not a falsifier regression finding\"\n", - concat( - " exit 1\n", - concat( - "fi\n", - concat( - concat( - "if [ \"$\{COLD_RESULT}\" = \"skipped\" ]; then\n", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_cold_skipped()), - concat( - " printf '%s\\n' \"::error::Cold corpus skipped despite successful build — topology violation\"\n", - concat( - " exit 1\n", - concat( - "fi\n", - concat( - concat( - "if [ \"$\{COLD_RESULT}\" = \"cancelled\" ]; then\n", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_cold_cancelled()), - concat( - " printf '%s\\n' \"::error::Cold corpus cancelled — environment unavailability\"\n", - concat( - " exit 1\n", - concat( - "fi\n", - concat( - concat( - "FLOOR_RECEIPT_PRESENT=false\n", - concat( - concat( - "if [ -f target/floor-component-receipt.json ] && grep -q ", - concat( - floor_component_receipt_schema, - concat( - " target/floor-component-receipt.json; then\n", - concat( - " FLOOR_RECEIPT_PRESENT=true\n", - concat( - "fi\n", - concat( - concat( - "if [ \"$\{FLOOR_RECEIPT_PRESENT}\" != true ]; then\n", - concat( - concat( - " if [ \"$\{COLD_RESULT}\" = \"success\" ]; then\n", - concat( - concat( - " ", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_cold_receipt_artifact_absent()), - concat( - " printf '%s\\n' \"::error::Cold corpus succeeded but floor-component receipt artifact absent — transport or emit failure, not a falsifier regression finding\"\n", - concat( - " exit 1\n", - concat( - " fi\n", - concat( - concat( - " ", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_cold_failed_before_receipt()), - concat( - " printf '%s\\n' \"::error::Cold corpus did not produce floor-component receipt (cold=$\{COLD_RESULT}) — infrastructure, not a falsifier regression finding\"\n", - concat( - " exit 1\n", - concat( - "fi\n", - concat( - concat( - " ", - concat( - falsifier_aggregate_verdict_write_receipt(json: aggregate_shell_receipt_corpus_executed()), - concat( - "if [ \"$\{SELECTION_RESULT}\" != \"success\" ] || [ \"$\{COLD_RESULT}\" != \"success\" ]; then\n", - concat( - " printf '%s\\n' \"::error::Falsifier cadence red — selection=$\{SELECTION_RESULT} cold=$\{COLD_RESULT} (corpus executed; see target/falsifier-cold-corpus-execution.json)\"\n", - concat( - " exit 1\n", - concat( - "fi\n", - "printf '%s\\n' \"FalsifierCadenceVerdict: cadence-green\"\n" - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) - ) -} - -fn falsifier_aggregate_verdict_shell_body() -> String { - falsifier_aggregate_verdict_script() -} - -fn falsifier_aggregate_verdict_step() -> Step { - RunStep { - name: Present { value: "Aggregate falsifier cadence verdict (typed cold-corpus execution)" }, - id: Present { value: "aggregate_verdict" }, - run: falsifier_aggregate_verdict_shell_body(), - shell: none, - env: none, - working_directory: none, - if_condition: none, - continue_on_error: none, - timeout_minutes: Present { value: gunbc_ci_aux_step_timeout_minutes } - } -} - -fn falsifier_build_job() -> Job { - Job { - id: "falsifier-build", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: concat(ci_prelude_steps(), [ci_release_build_step(), ci_release_bins_pack_step(), ci_release_bins_upload_step()]), - needs: [], - env: none, - outputs: none, - if_condition: none, - timeout_minutes: Present { value: gunbc_falsifier_build_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: none - } -} - -fn falsifier_selection_control_job() -> Job { - Job { - id: "selection-control", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: concat(ci_floor_job_prelude_steps(), [ci_release_bins_download_step(), ci_release_bins_unpack_verify_step(), ci_selection_control_step()]), - needs: ["falsifier-build"], - env: none, - outputs: none, - if_condition: none, - timeout_minutes: Present { value: gunbc_falsifier_selection_control_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: none - } -} - -fn falsifier_cold_corpus_job() -> Job { - Job { - id: "cold-corpus", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: concat(ci_floor_job_prelude_steps(), [ci_release_bins_download_step(), ci_release_bins_unpack_verify_step(), ci_floor_peak_pre_step(), falsifier_step(), floor_component_receipt_upload_step(), floor_phase_journal_upload_step(), ci_floor_receipts_upload_step(), compile_clean_cold_control_step(), native_cache_cold_control_step(), ci_floor_peak_post_step()]), - needs: ["falsifier-build"], - env: none, - outputs: none, - if_condition: none, - timeout_minutes: Present { value: gunbc_falsifier_cold_corpus_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: none - } -} - -fn falsifier_aggregate_verdict_job() -> Job { - Job { - id: "aggregate-verdict", - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: [falsifier_floor_component_receipt_download_step(), falsifier_aggregate_verdict_step()], - needs: ["falsifier-build", "selection-control", "cold-corpus"], - env: none, - outputs: none, - if_condition: Present { value: falsifier_aggregate_verdict_if }, - timeout_minutes: Present { value: gunbc_falsifier_aggregate_verdict_job_backstop_timeout_minutes() }, - continue_on_error: none, - concurrency: none, - permissions: none - } -} - -data falsifier_cadence_note: String = "nightly (0 7 * * *) -> every 4h (operator ruling 2026-07-14): a once-daily divergence receipt goes unread; a 4h cadence makes the cold-run receipt a same-day dial. Overlap is handled structurally, not assumed away: the job backstop (230-min class) can tail past a 240-min period, so the workflow carries a queue-not-cancel concurrency group - a scheduled run firing while one is live QUEUES rather than killing a measuring run mid-corpus." - -data falsifier_cadence_cron: CronSchedule = CronSchedule { - minute: Exact { value: 0 }, - hour: Listed { values: [0, 4, 8, 12, 16, 20] }, - day_of_month: Wildcard, - month: Wildcard, - day_of_week: Wildcard -} - -data falsifier_workflow: Workflow = { - name: "affected-set-falsifier", - on: [ - WorkflowDispatch { inputs: [] }, - Schedule { cron: falsifier_cadence_cron } - ], - concurrency: Present { - value: ConcurrencyMappingQueueNotMax { - group: "affected-set-falsifier", - cancel_in_progress: Present { value: CancelInProgressBool { value: false } }, - explicit_single: none - } - }, - env: Present { - value: [kv(key: "CARGO_TERM_COLOR", value: yaml_string(s: "always"))] - }, - permissions: Present { - value: WorkflowPermissions { - contents: Present { value: PermRead }, - pull_requests: none, - issues: none, - actions: none, - id_token: none - } - }, - jobs: [ - falsifier_build_job(), - falsifier_selection_control_job(), - falsifier_cold_corpus_job(), - falsifier_aggregate_verdict_job() - ] -} - -fn expected_falsifier_yml() -> String { - serialize_yaml(v: project_workflow_to_yaml(workflow: falsifier_workflow)) -} diff --git a/dag/gunbc/floor_component_receipt.dag b/dag/gunbc/floor_component_receipt.dag index 3882170dbd4..51124de6071 100644 --- a/dag/gunbc/floor_component_receipt.dag +++ b/dag/gunbc/floor_component_receipt.dag @@ -40,11 +40,6 @@ import std.measure { nanosecond_count, } import std.realization_schedule { - NodeFrontierSelection, - SelectionOff, - SelectionApplied, - SelectionPredictOnly, - node_frontier_selection_eq, } import extdeps.languages.json.emit { JsonValue, @@ -58,11 +53,10 @@ import extdeps.languages.json.emit { json_object, json_kv, } -import gunbc.selection_degradation_receipt { selection_degradation_receipt_json } import gunbc.floor_component_receipt_document { receipt_member_schema, receipt_member_run_id, receipt_member_component_count, - receipt_member_affected_set_cold_control, receipt_member_unsuccessful_components, - receipt_member_components, receipt_member_selection_degradation, + receipt_member_unsuccessful_components, + receipt_member_components, receipt_member_run_terminal, receipt_member_workflow_name, receipt_member_head_sha , @@ -95,16 +89,10 @@ data floor_component_failure_mode_edge_note: String = "WHY THE MODE RIDES BESIDE type FloorComponentRow { event: ObservationEvent - selection: NodeFrontierSelection witnesses: Nat failure_mode: FloorComponentFailureMode } -type FloorControlState - = ControlConcluded { row: FloorComponentRow } - | ControlAbsent { cause: NonEmptyStr } - | ControlAmbiguous { cause: NonEmptyStr, matched: Nat } - fn floor_component_subject(run_id: NonEmptyStr, index: Nat, label: NonEmptyStr) -> ObservationSubject { ObservationSubject { segments: [ @@ -114,21 +102,6 @@ fn floor_component_subject(run_id: NonEmptyStr, index: Nat, label: NonEmptyStr) } } -fn floor_component_selection_of_tag(tag: NonEmptyStr) -> NodeFrontierSelection? { - if (tag as String) == "predict_only" { Present { value: SelectionPredictOnly } } - else if (tag as String) == "applied" { Present { value: SelectionApplied } } - else if (tag as String) == "off" { Present { value: SelectionOff } } - else { none } -} - -fn floor_component_selection_tag(s: NodeFrontierSelection) -> String { - match s { - SelectionOff => "off" - SelectionApplied => "applied" - SelectionPredictOnly => "predict_only" - } -} - fn floor_component_outcome_of_tag( tag: NonEmptyStr, detail: NonEmptyStr, @@ -186,7 +159,6 @@ fn floor_component_row_of( run_id: NonEmptyStr, index: Nat, label: NonEmptyStr, - selection: NodeFrontierSelection, witnesses: Nat, outcome: ObservationOutcome, wall: Millisecond, @@ -199,7 +171,6 @@ fn floor_component_row_of( durations: observation_durations_wall(elapsed: millisecond_to_nanosecond(m: wall)), rss: MeasuredUnavailable { cause: "per-component RSS not sampled by the floor walk" as NonEmptyStr } }, - selection: selection, witnesses: witnesses, failure_mode: failure_mode } @@ -209,7 +180,6 @@ fn floor_component_row( run_id: NonEmptyStr, index: Nat, label: NonEmptyStr, - selection_tag: NonEmptyStr, witnesses: Nat, outcome_tag: NonEmptyStr, detail: NonEmptyStr, @@ -219,31 +189,26 @@ fn floor_component_row( shown_failures: Nat, wall: Millisecond ) -> FloorComponentRow? { - match floor_component_selection_of_tag(tag: selection_tag) { + match floor_component_outcome_of_tag( + tag: outcome_tag, + detail: detail, + basis: basis, + budget: budget, + elapsed: elapsed, + shown_failures: shown_failures + ) { Absent => none - Present { value: sel } => - match floor_component_outcome_of_tag( - tag: outcome_tag, - detail: detail, - basis: basis, - budget: budget, - elapsed: elapsed, - shown_failures: shown_failures - ) { - Absent => none - Present { value: outcome } => Present { - value: floor_component_row_of( - run_id: run_id, - index: index, - label: label, - selection: sel, - witnesses: witnesses, - outcome: outcome, - wall: wall, - failure_mode: ModeUnrecorded - ) - } - } + Present { value: outcome } => Present { + value: floor_component_row_of( + run_id: run_id, + index: index, + label: label, + witnesses: witnesses, + outcome: outcome, + wall: wall, + failure_mode: ModeUnrecorded + ) + } } } @@ -251,33 +216,27 @@ fn floor_component_row_of_failure_mode( run_id: NonEmptyStr, index: Nat, label: NonEmptyStr, - selection_tag: NonEmptyStr, witnesses: Nat, failure_mode: NonEmptyStr, detail: NonEmptyStr, wall: Millisecond ) -> FloorComponentRow? { - match floor_component_selection_of_tag(tag: selection_tag) { + match floor_component_failure_mode_of(mode: failure_mode) { Absent => none - Present { value: sel } => - match floor_component_failure_mode_of(mode: failure_mode) { + Present { value: mode } => + match floor_component_outcome_of_mode(m: mode, detail: detail) { Absent => none - Present { value: mode } => - match floor_component_outcome_of_mode(m: mode, detail: detail) { - Absent => none - Present { value: outcome } => Present { - value: floor_component_row_of( - run_id: run_id, - index: index, - label: label, - selection: sel, - witnesses: witnesses, - outcome: outcome, - wall: wall, - failure_mode: mode - ) - } - } + Present { value: outcome } => Present { + value: floor_component_row_of( + run_id: run_id, + index: index, + label: label, + witnesses: witnesses, + outcome: outcome, + wall: wall, + failure_mode: mode + ) + } } } } @@ -286,33 +245,27 @@ fn floor_component_row_not_concluded( run_id: NonEmptyStr, index: Nat, label: NonEmptyStr, - selection_tag: NonEmptyStr, failure_mode: NonEmptyStr, detail: NonEmptyStr ) -> FloorComponentRow? { - match floor_component_selection_of_tag(tag: selection_tag) { + match floor_component_failure_mode_of(mode: failure_mode) { Absent => none - Present { value: sel } => - match floor_component_failure_mode_of(mode: failure_mode) { - Absent => none - Present { value: mode } => Present { - value: FloorComponentRow { - event: ObservationEvent { - subject: floor_component_subject(run_id: run_id, index: index, label: label), - transition: Begin, - durations: observation_durations_wall( - elapsed: millisecond_to_nanosecond(m: millisecond(count: 0)) - ), - rss: MeasuredUnavailable { - cause: "per-component RSS not sampled by the floor walk" as NonEmptyStr - } - }, - selection: sel, - witnesses: 0, - failure_mode: mode + Present { value: mode } => Present { + value: FloorComponentRow { + event: ObservationEvent { + subject: floor_component_subject(run_id: run_id, index: index, label: label), + transition: Begin, + durations: observation_durations_wall( + elapsed: millisecond_to_nanosecond(m: millisecond(count: 0)) + ), + rss: MeasuredUnavailable { + cause: "per-component RSS not sampled by the floor walk" as NonEmptyStr } - } + }, + witnesses: 0, + failure_mode: mode } + } } } @@ -374,7 +327,6 @@ fn floor_component_row_json(row: FloorComponentRow) -> JsonValue { Absent => json_object(members: [ json_kv(key: "index", value: json_int(n: floor_component_row_index(row: row))), json_kv(key: "label", value: json_string(s: floor_component_row_label(row: row))), - json_kv(key: "selection", value: json_string(s: floor_component_selection_tag(s: row.selection))), json_kv(key: "outcome", value: json_string(s: floor_component_outcome_wire_tag(r: ComponentNotConcluded))), json_kv(key: "failure_mode", value: json_string(s: floor_component_failure_mode_tag(m: row.failure_mode))) ]) @@ -382,13 +334,9 @@ fn floor_component_row_json(row: FloorComponentRow) -> JsonValue { [ json_kv(key: "index", value: json_int(n: floor_component_row_index(row: row))), json_kv(key: "label", value: json_string(s: floor_component_row_label(row: row))), - json_kv(key: "selection", value: json_string(s: floor_component_selection_tag(s: row.selection))), - json_kv(key: "witnesses", value: json_int(n: row.witnesses)), + json_kv(key: "witnesses", value: json_int(n: row.witnesses)), json_kv(key: "outcome", value: json_string(s: floor_component_outcome_wire_tag(r: ComponentConcluded { outcome: o }))), - json_kv(key: "failure_mode", value: json_string(s: floor_component_failure_mode_tag(m: row.failure_mode))), - json_kv(key: "is_affected_set_cold_control", value: json_bool( - b: node_frontier_selection_eq(left: row.selection, right: SelectionPredictOnly) - )) + json_kv(key: "failure_mode", value: json_string(s: floor_component_failure_mode_tag(m: row.failure_mode))) ], concat( floor_component_outcome_members(o: o), @@ -398,49 +346,6 @@ fn floor_component_row_json(row: FloorComponentRow) -> JsonValue { } } -fn floor_affected_set_control_rows(rows: List) -> List { - rows |> filter(r => node_frontier_selection_eq(left: r.selection, right: SelectionPredictOnly)) -} - -fn floor_affected_set_control_state(rows: List) -> FloorControlState { - let matched = floor_affected_set_control_rows(rows: rows) - let n = count(matched) - if n > 1 { - ControlAmbiguous { - cause: "more than one SelectionPredictOnly component — the cold control is not uniquely identified" as NonEmptyStr, - matched: n - } - } else { - match matched.first() { - Absent => ControlAbsent { - cause: "no SelectionPredictOnly component in this receipt — the affected-set cold control did not run" as NonEmptyStr - } - Present { value: r } => ControlConcluded { row: r } - } - } -} - -fn floor_affected_set_control_json(rows: List) -> JsonValue { - match floor_affected_set_control_state(rows: rows) { - ControlConcluded { row: r } => json_object(members: [ - json_kv(key: "state", value: json_string(s: "present")), - json_kv(key: "verified", value: json_bool(b: floor_component_row_is_done(row: r))), - json_kv(key: "component", value: floor_component_row_json(row: r)) - ]) - ControlAbsent { cause: c } => json_object(members: [ - json_kv(key: "state", value: json_string(s: "absent")), - json_kv(key: "verified", value: json_bool(b: false)), - json_kv(key: "cause", value: json_string(s: c as String)) - ]) - ControlAmbiguous { cause: c, matched: m } => json_object(members: [ - json_kv(key: "state", value: json_string(s: "ambiguous")), - json_kv(key: "verified", value: json_bool(b: false)), - json_kv(key: "cause", value: json_string(s: c as String)), - json_kv(key: "matched", value: json_int(n: m)) - ]) - } -} - fn floor_unsuccessful_component_rows(rows: List) -> List { rows |> filter(r => !floor_component_row_is_done(row: r)) } @@ -464,12 +369,6 @@ fn floor_component_receipt_json_value( run_id: NonEmptyStr, head_sha: CommitSha, rows: List, - selection_present: Bool, - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String, run_terminal_present: Bool, run_terminal_disposition: NonEmptyStr, run_terminal_cause: NonEmptyStr, @@ -482,7 +381,6 @@ fn floor_component_receipt_json_value( json_kv(key: receipt_member_run_id, value: json_string(s: run_id as String)), json_kv(key: receipt_member_head_sha, value: json_string(s: head_sha as String)), json_kv(key: receipt_member_component_count, value: json_int(n: count(rows))), - json_kv(key: receipt_member_affected_set_cold_control, value: floor_affected_set_control_json(rows: rows)), json_kv(key: receipt_member_unsuccessful_components, value: json_array( elements: floor_unsuccessful_component_rows(rows: rows) |> map(r => floor_component_row_json(row: r)) )), @@ -490,8 +388,8 @@ fn floor_component_receipt_json_value( elements: rows |> map(r => floor_component_row_json(row: r)) )) ] - let with_terminal = if run_terminal_present { - concat(base, [ + if run_terminal_present { + json_object(members: concat(base, [ json_kv( key: receipt_member_run_terminal, value: floor_run_terminal_json( @@ -501,33 +399,15 @@ fn floor_component_receipt_json_value( pending_from_index: pending_from_index ) ) - ]) - } else { - concat(base, [ - json_kv(key: receipt_member_run_terminal, value: json_null()) - ]) - } - if selection_present { - json_object(members: concat(with_terminal, [ - json_kv( - key: receipt_member_selection_degradation, - value: selection_degradation_receipt_json( - selection_mode_tag: selection_mode_tag, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason - ) - ) ])) } else { - json_object(members: concat(with_terminal, [ - json_kv(key: receipt_member_selection_degradation, value: json_null()) + json_object(members: concat(base, [ + json_kv(key: receipt_member_run_terminal, value: json_null()) ])) } } -data selection_degradation_always_emitted_note: String = "selection_degradation IS EMITTED ON EVERY PATH, INCLUDING THE ONE WITH NO SELECTION SNAPSHOT, where it is an explicit null. It previously appeared only when a snapshot existed, and the member was simply absent otherwise.\n\nThat was tolerable while nothing decoded the receipt. It stopped being tolerable the moment gunbc.floor_component_receipt_document made the member REQUIRED on the read side: the writer could still emit a document the reader would refuse, so encode-then-decode was broken for exactly the path claim_executor takes when no selection ran (review 49594 caught this, correctly, along with a note on the decoder side that overstated what this writer did).\n\nAn explicit null is the right repair rather than relaxing the decoder, because the two states differ and the receipt should say which one it is: `null` means this run had no selection degradation to report, and an ABSENT member means the writer did not tell you either way. Making absence impossible on the write side is what lets the read side treat absence as the defect it now is." +data selection_degradation_member_deleted_note: String = "The receipt carried two members about affected-set selection — selection_degradation and affected_set_cold_control — and both are deleted with the mechanism they described (2026-08-15). Neither can be reconstructed from a run because the fact they reported no longer exists: nothing selects, so there is no degradation to report and no cold control to identify.\n\nWHAT THE DELETION MUST NOT BE READ AS. selection_degradation was made an explicit null on every path (review 49594) precisely so that ABSENT could mean the writer did not tell you either way. Removing the member returns it to absent — but for every reader, unconditionally, rather than for one path. That is only sound because the corresponding read-side requirement in gunbc.floor_component_receipt_document is removed in the same change: a writer that stops emitting a member a decoder still requires is exactly the broken encode-then-decode that ruling was about." fn floor_component_receipt_document( workflow_name: NonEmptyStr, @@ -540,12 +420,6 @@ fn floor_component_receipt_document( run_id: run_id, head_sha: head_sha, rows: rows, - selection_present: false, - selection_mode_tag: "off" as NonEmptyStr, - selected: 0, - total: 0, - categorization_unavailable: false, - categorization_reason: "", run_terminal_present: false, run_terminal_disposition: "concluded" as NonEmptyStr, run_terminal_cause: "none" as NonEmptyStr, @@ -568,12 +442,6 @@ fn floor_component_receipt_document_incomplete( run_id: run_id, head_sha: head_sha, rows: rows, - selection_present: false, - selection_mode_tag: "off" as NonEmptyStr, - selected: 0, - total: 0, - categorization_unavailable: false, - categorization_reason: "", run_terminal_present: true, run_terminal_disposition: "incomplete" as NonEmptyStr, run_terminal_cause: run_terminal_cause, @@ -582,65 +450,3 @@ fn floor_component_receipt_document_incomplete( )) } -fn floor_component_receipt_document_incomplete_with_selection( - workflow_name: NonEmptyStr, - run_id: NonEmptyStr, - head_sha: CommitSha, - rows: List, - run_terminal_cause: NonEmptyStr, - concluded_count: Nat, - pending_from_index: Nat, - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> String { - serialize_json(v: floor_component_receipt_json_value( - workflow_name: workflow_name, - run_id: run_id, - head_sha: head_sha, - rows: rows, - selection_present: true, - selection_mode_tag: selection_mode_tag, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason, - run_terminal_present: true, - run_terminal_disposition: "incomplete" as NonEmptyStr, - run_terminal_cause: run_terminal_cause, - concluded_count: concluded_count, - pending_from_index: pending_from_index - )) -} - -fn floor_component_receipt_document_with_selection( - workflow_name: NonEmptyStr, - run_id: NonEmptyStr, - head_sha: CommitSha, - rows: List, - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> String { - serialize_json(v: floor_component_receipt_json_value( - workflow_name: workflow_name, - run_id: run_id, - head_sha: head_sha, - rows: rows, - selection_present: true, - selection_mode_tag: selection_mode_tag, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason, - run_terminal_present: false, - run_terminal_disposition: "concluded" as NonEmptyStr, - run_terminal_cause: "none" as NonEmptyStr, - concluded_count: count(rows), - pending_from_index: 0 - )) -} diff --git a/dag/gunbc/floor_component_receipt_document.dag b/dag/gunbc/floor_component_receipt_document.dag index 7f0ef77480d..34ff1a23fd6 100644 --- a/dag/gunbc/floor_component_receipt_document.dag +++ b/dag/gunbc/floor_component_receipt_document.dag @@ -24,10 +24,8 @@ data floor_component_receipt_document_member_authority_note: String = "THE MEMBE data receipt_member_schema: String = "schema" data receipt_member_run_id: String = "run_id" data receipt_member_component_count: String = "component_count" -data receipt_member_affected_set_cold_control: String = "affected_set_cold_control" data receipt_member_unsuccessful_components: String = "unsuccessful_components" data receipt_member_components: String = "components" -data receipt_member_selection_degradation: String = "selection_degradation" data receipt_member_run_terminal: String = "run_terminal" data receipt_member_workflow_name: String = "workflow_name" @@ -49,8 +47,6 @@ type FloorComponentReceiptDocument { unsuccessful_components: List unsuccessful_summaries: List component_summaries: List - affected_set_control: JsonValue - selection_degradation: JsonValue run_terminal: JsonValue } @@ -175,10 +171,8 @@ fn floor_component_receipt_document_json(doc: FloorComponentReceiptDocument) -> floor_component_receipt_subject_json(subject: doc.subject), [ json_kv(key: receipt_member_component_count, value: json_int(n: doc.component_count)), - json_kv(key: receipt_member_affected_set_cold_control, value: doc.affected_set_control), json_kv(key: receipt_member_unsuccessful_components, value: json_array(elements: doc.unsuccessful_components)), json_kv(key: receipt_member_components, value: json_array(elements: doc.components)), - json_kv(key: receipt_member_selection_degradation, value: doc.selection_degradation), json_kv(key: receipt_member_run_terminal, value: doc.run_terminal) ] )) @@ -658,12 +652,6 @@ fn floor_component_receipt_decode_with(text: String, expected_schema: NonEmptySt if declared_count_n != count(components) { ReceiptComponentCountMismatch { declared: declared_count_n as String, decoded: count(components) } } else { - match receipt_required_value_at(v: doc, key: receipt_member_affected_set_cold_control) { - ReceiptValueFailed { decoding: d } => d - ReceiptValueFound { value: control } => - match receipt_required_value_at(v: doc, key: receipt_member_selection_degradation) { - ReceiptValueFailed { decoding: d } => d - ReceiptValueFound { value: degradation } => match receipt_run_terminal_at(v: doc) { ReceiptValueFailed { decoding: d } => d ReceiptValueFound { value: run_terminal } => @@ -696,8 +684,6 @@ fn floor_component_receipt_decode_with(text: String, expected_schema: NonEmptySt unsuccessful_components: unsuccessful, unsuccessful_summaries: summaries, component_summaries: complete_summaries, - affected_set_control: control, - selection_degradation: degradation, run_terminal: run_terminal } } @@ -708,8 +694,6 @@ fn floor_component_receipt_decode_with(text: String, expected_schema: NonEmptySt } } } - } - } } } } diff --git a/dag/gunbc/floor_materialization.dag b/dag/gunbc/floor_materialization.dag index 2247d0b7978..b0b2cf1bd1b 100644 --- a/dag/gunbc/floor_materialization.dag +++ b/dag/gunbc/floor_materialization.dag @@ -42,12 +42,9 @@ fn gate_consumer_site(g: Gate) -> String { } } -data floor_prelude_consumer_sites_note: String = "The two fixed prelude entries every floor process resolves against the shared index (mirrors the Rust FLOOR_RUNNER_ENTRY / ENTRY_SELECTION_ENTRY constants in cli_run.rs). Not a fixture roster copy — a genuinely fixed pair, per merry-moth's 'plus your two prelude entries'. 🟡 dissolve-on: floor_prelude_entries_single_authority — this List is a §3 parallel representation of the host's FLOOR_RUNNER_ENTRY / ENTRY_SELECTION_ENTRY constants (cli_run.rs:5351-5352), consumed here as authoritative by reader_count and the enrolled witness; it already DRIFTED once (entry #2 was v2.workflow.affected_set_selection, not the host's v2.lens.affected_set.entry_selection; corrected in #6432 review, 2026-07-10). DISSOLVES WHEN the floor prelude entries are declared once in .dag and consumed by BOTH the host (via resolve) and this row, making the hand-copy — and its drift — unwritable (§3 single authority)." +data floor_prelude_consumer_sites_note: String = "EMPTY, and that is a measured state rather than an unfilled roster. The floor once resolved two fixed prelude entries against the shared index before any batch ran — the affected-set floor runner and the entry-selection lens — mirroring the host's FLOOR_RUNNER_ENTRY / ENTRY_SELECTION_ENTRY constants. Both existed only to answer the selection question, and both were deleted with affected-set selection (2026-08-15), so the floor now has no prelude entry at all and reader_count over this list is zero by construction rather than by omission.\n\nThe drift this row was written to record still stands as history: entry #2 was once v2.workflow.affected_set_selection rather than the host's v2.lens.affected_set.entry_selection, corrected in #6432 review — a hand-copy of a host constant disagreeing with the constant. 🟡 dissolve-on: the list stays empty through the floor rebuild, at which point this carrier and its witness delete together rather than being repopulated; if a prelude entry is ever needed again it is declared once in .dag and consumed by BOTH the host and this row, never hand-copied." -data floor_prelude_consumer_sites: List = [ - "src/v2/workflow/affected_set_floor_runner.dag", - "src/v2/lens/affected_set/entry_selection.dag" -] +data floor_prelude_consumer_sites: List = [] fn floor_index_build_consumer_sites(gates: List, witnesses: List) -> List { concat( diff --git a/dag/gunbc/generated_artifact.dag b/dag/gunbc/generated_artifact.dag index 0adc5517995..eeef91c13bd 100644 --- a/dag/gunbc/generated_artifact.dag +++ b/dag/gunbc/generated_artifact.dag @@ -7,9 +7,7 @@ import gunbc.plan_registry { all_plans } import gunbc.generated_artifact_merge_driver { generated_artifact_merge_driver_script_path } type GeneratedArtifact - = CiYamlArtifact - | FalsifierYamlArtifact - | FleetConvergeYamlArtifact + = FleetConvergeYamlArtifact | GitignoreArtifact | GitattributesArtifact | RoadmapArtifact @@ -30,7 +28,7 @@ type GeneratedArtifact data generated_artifact_registry: List = concat( concat( concat( - [CiYamlArtifact, FalsifierYamlArtifact, FleetConvergeYamlArtifact, GitignoreArtifact, GitattributesArtifact, RoadmapArtifact, DesignArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, RunnerDeployArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, Stage0CratePartitionGeneratedDagArtifact, Stage0EmitPlanGeneratedDagArtifact, V1InterpreterDispatchGeneratedRsArtifact], + [FleetConvergeYamlArtifact, GitignoreArtifact, GitattributesArtifact, RoadmapArtifact, DesignArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, RunnerDeployArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, Stage0CratePartitionGeneratedDagArtifact, Stage0EmitPlanGeneratedDagArtifact, V1InterpreterDispatchGeneratedRsArtifact], map(fleet_autoinstall_specs, s => AutoinstallUserDataArtifact { spec: s }) ), map(fleet_install_server_specs, s => ProxyDhcpDnsmasqArtifact { spec: s }) @@ -50,8 +48,6 @@ type CommitPolicy fn artifact_path(a: GeneratedArtifact) -> String { match a { - CiYamlArtifact => ".github/workflows/ci.yml" - FalsifierYamlArtifact => ".github/workflows/falsifier.yml" FleetConvergeYamlArtifact => ".github/workflows/fleet-converge.yml" GitignoreArtifact => ".gitignore" GitattributesArtifact => ".gitattributes" @@ -79,8 +75,6 @@ fn artifact_commit_policy(a: GeneratedArtifact) -> CommitPolicy { GithooksPrePushArtifact => CommitRequired { consumer: GitProtocol } GithooksPreCommitArtifact => CommitRequired { consumer: GitProtocol } GeneratedArtifactMergeDriverArtifact => CommitRequired { consumer: GitProtocol } - CiYamlArtifact => CommitRequired { consumer: GithubActionsWorkflow } - FalsifierYamlArtifact => CommitRequired { consumer: GithubActionsWorkflow } FleetConvergeYamlArtifact => CommitRequired { consumer: GithubActionsWorkflow } RoadmapArtifact => CommitRequired { consumer: ProjectDocumentation } DesignArtifact => CommitRequired { consumer: ProjectDocumentation } @@ -115,8 +109,6 @@ data artifact_eq_disposition_reference_note: String = "Disposition authority (re fn artifact_eq(a: GeneratedArtifact, b: GeneratedArtifact) -> Bool { match a { - CiYamlArtifact => match b { CiYamlArtifact => true _ => false } - FalsifierYamlArtifact => match b { FalsifierYamlArtifact => true _ => false } FleetConvergeYamlArtifact => match b { FleetConvergeYamlArtifact => true _ => false } GitignoreArtifact => match b { GitignoreArtifact => true _ => false } GitattributesArtifact => match b { GitattributesArtifact => true _ => false } diff --git a/dag/gunbc/generated_artifact_emit.dag b/dag/gunbc/generated_artifact_emit.dag index bfee4bebb28..cbc4612c3e0 100644 --- a/dag/gunbc/generated_artifact_emit.dag +++ b/dag/gunbc/generated_artifact_emit.dag @@ -3,7 +3,7 @@ module gunbc.generated_artifact_emit import gunbc.generated_artifact { GeneratedArtifact, - CiYamlArtifact, FalsifierYamlArtifact, FleetConvergeYamlArtifact, GitignoreArtifact, GitattributesArtifact, RoadmapArtifact, DesignArtifact, + FleetConvergeYamlArtifact, GitignoreArtifact, GitattributesArtifact, RoadmapArtifact, DesignArtifact, RunnerDeployArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, AutoinstallUserDataArtifact, ProxyDhcpDnsmasqArtifact, PlanArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, @@ -12,8 +12,6 @@ import gunbc.generated_artifact { V1InterpreterDispatchGeneratedRsArtifact, artifact_path } -import gunbc.ci_yaml_emit { expected_ci_yml } -import gunbc.falsifier_workflow { expected_falsifier_yml } import gunbc.fleet_converge_workflow { expected_fleet_converge_yml } import gunbc.ci_yaml_validate { ci_yml_parses } import gunbc.gitignore_emit { expected_gitignore } @@ -56,8 +54,6 @@ fn artifact_generated(content: String) -> ArtifactGenerationOutcome { fn artifact_generate(a: GeneratedArtifact) -> ArtifactGenerationOutcome { match a { - CiYamlArtifact => artifact_generated(content: expected_ci_yml()) - FalsifierYamlArtifact => artifact_generated(content: expected_falsifier_yml()) FleetConvergeYamlArtifact => artifact_generated(content: expected_fleet_converge_yml()) GitignoreArtifact => artifact_generated(content: expected_gitignore()) GitattributesArtifact => match expected_gitattributes() { @@ -92,8 +88,6 @@ data artifact_extra_valid_note: String = "P0 (operator-directed, 2026-08-05; loy fn artifact_extra_valid(a: GeneratedArtifact, generated: ArtifactGenerationOutcome) -> Bool { match a { - CiYamlArtifact => ci_yml_parses(path: artifact_path(a: a)) - FalsifierYamlArtifact => ci_yml_parses(path: artifact_path(a: a)) FleetConvergeYamlArtifact => ci_yml_parses(path: artifact_path(a: a)) GitignoreArtifact => true GitattributesArtifact => true diff --git a/dag/gunbc/observation_emit_census.dag b/dag/gunbc/observation_emit_census.dag index 27e3d552350..f7000aeec38 100644 --- a/dag/gunbc/observation_emit_census.dag +++ b/dag/gunbc/observation_emit_census.dag @@ -136,14 +136,6 @@ data witness_row_cost_migration_disclosure_site: CensusedEmitSite = CensusedEmit } -data selection_degradation_site: CensusedEmitSite = CensusedEmitSite { - marker: "[selection-degradation]" as NonEmptyStr, - source_file: "src/v1/stage0/src/cli_run.rs" as NonEmptyStr, - disposition: CountedFrontierSite { - reason: "floor prep-tax P2 selection honesty receipt — selection_state, selected/total entry groups, ratio, fallback_reason on every discovery completion" as NonEmptyStr, - dissolution: unbound_dissolution(description: "fold into observation receipt projection once selection degradation speaks the observation vocabulary") - } -} data observation_emit_roster: List = [ floor_memory_site, @@ -158,8 +150,7 @@ data observation_emit_roster: List = [ resolve_split_site, assembly_split_site, witness_row_cost_site, - witness_row_cost_migration_disclosure_site, - selection_degradation_site + witness_row_cost_migration_disclosure_site ] data observation_emit_roster_completeness_disposition: Disposition = Scaffold { diff --git a/dag/gunbc/plan_registry_batch_f.dag b/dag/gunbc/plan_registry_batch_f.dag index fd28e0d0846..92afebc4a9b 100644 --- a/dag/gunbc/plan_registry_batch_f.dag +++ b/dag/gunbc/plan_registry_batch_f.dag @@ -6,7 +6,6 @@ import gunbc.plans.budget_tree { budget_tree_plan } import gunbc.plans.cardinality_refinement { cardinality_refinement_plan } import gunbc.plans.compute_envelope_model { compute_envelope_model_plan } import gunbc.plans.input_envelope_roadmap { input_envelope_roadmap_plan } -import gunbc.plans.ci_selection_vs_scheduling { ci_selection_vs_scheduling_plan } import gunbc.plans.ci_process_end_to_end { ci_process_end_to_end_plan } import gunbc.plans.ci_oom_reclassification { ci_oom_reclassification_plan } import gunbc.plans.bounded_input_cost_envelope_scheduling { bounded_input_cost_envelope_scheduling_plan } @@ -17,7 +16,6 @@ data batch_f_plans: List = [ cardinality_refinement_plan, compute_envelope_model_plan, input_envelope_roadmap_plan, - ci_selection_vs_scheduling_plan, ci_process_end_to_end_plan, ci_oom_reclassification_plan, bounded_input_cost_envelope_scheduling_plan diff --git a/dag/gunbc/plans/ci_selection_vs_scheduling.dag b/dag/gunbc/plans/ci_selection_vs_scheduling.dag deleted file mode 100644 index e3d83b07caa..00000000000 --- a/dag/gunbc/plans/ci_selection_vs_scheduling.dag +++ /dev/null @@ -1,79 +0,0 @@ -module gunbc.plans.ci_selection_vs_scheduling - -import std.dissolution { unbound_dissolution } -import gunbc.plan { Plan, PlanRetirement, PlanRetiresWhen } -import std.markdown { MarkdownBlock, MarkdownTableRow, TableBlock, BlockquoteBlock, AlignNone } -import gunbc.plans.md_helpers { h2, p, li, ul, ol, cell } - -fn ci_selection_vs_scheduling_body() -> List { - [ - BlockquoteBlock { blocks: [ - p(text: "The framing behind the §1 \"floor runs the right things\" bullets. DESIGN refs: §1 (safety — a wrong answer caught late is paid \"at interest\"), §2 (parallelization-by-realization, the `std/realization.dag` Schedule/Placement/Width arm), §4 (affected-set selection over the Node dep-graph), §6 (don't build machinery for near-zero residue). Authored from warm-lark-306's analysis (2026-06-21), §1-lead input by quick-ant-298. **Carriers are the authority** — this doc exists only to keep the ROADMAP bullets terse (no dual representation)."), - ] }, - h2(text: "0. The reject: \"expensive → nightly\" routes by the wrong axis"), - p(text: "The stood-down nightly lane (proud-deer's #5447, closed by operator decision 2026-06-21) routed tests to cadences by **cost**. That fuses two facts that must stay separate, and the fusion is **unsound**: it lets an *affected* test be dropped from the per-PR gate merely because it is slow — so a breaking change merges green and is caught hours later on the nightly run, the §1-safety harm paid \"at interest\". Cost is a *scheduling* fact; whether a test must gate *this* PR is a *selection* fact. Routing by the wrong axis is the design the operator said we were side-stepping."), - h2(text: "1. The two axes (they never cross)"), - TableBlock { - header: MarkdownTableRow { cells: [ - cell(text: ""), - cell(text: "**SELECTION** (§4)"), - cell(text: "**SCHEDULING** (§1)"), - ] }, - alignments: [AlignNone, AlignNone, AlignNone], - rows: [ - MarkdownTableRow { cells: [ - cell(text: "Question"), - cell(text: "does this result depend on what I changed?"), - cell(text: "given the must-run set, when / where / how-wide?"), - ] }, - MarkdownTableRow { cells: [ - cell(text: "Authority"), - cell(text: "the **affected set** — transitive closure of changed nodes over the dep graph"), - cell(text: "cost + hermeticity profile of each test"), - ] }, - MarkdownTableRow { cells: [ - cell(text: "Derived from"), - cell(text: "a property of the **change**"), - cell(text: "a property of the **test's resources**, not the change"), - ] }, - MarkdownTableRow { cells: [ - cell(text: "Discipline"), - cell(text: "sound, **fail-closed** — never skip an affected test"), - cell(text: "measured — cadence, placement, width"), - ] }, - ], - }, - p(text: "**The load-bearing rule: cost informs SCHEDULING, never SELECTION.** The answer to \"the affected set is expensive\" is *\"run it faster\"* (parallelize + cache — the §2 realization arm), never *\"run it later\"*."), - h2(text: "2. The three distinctions the bullets must preserve"), - ol(items: [ - li(text: "**Cost may inform scheduling, never selection** — the §1-safety violation, the whole reason #5447 was rejected."), - li(text: "**`#5427` run-all is the SOUND BASELINE** (a superset of the affected set, already fail-closed on selection). Affected-set is an **affordability refinement that *shrinks* it — not a correction**. #5427 is step 1, not superseded; affected-set is step 2 on top of it."), - li(text: "**Nightly = full-corpus selector-backstop + non-hermetic residue, NOT a slow-test dump** — and the backstop (a) is precisely what makes the step-2 shrink *safe*."), - ]), - h2(text: "3. Per-PR membership: sound baseline → minimal sound set"), - ul(items: [ - li(text: "**Step 1 — the sound baseline:** run-all-unless-`#[ignore]`d-with-a-written-reason (#5427, fierce-hawk-540). A superset of the affected set; fail-closed on selection by construction (it never skips an affected test). The completeness lens — \"no affected test unrun; no un-run test without a written reason\" — gates this (the `#[ignore]` residue is the legit §6 unstructurable bit)."), - li(text: "**Step 2 — shrink to the affected set:** the **existing** `v2.lens.affected_set` (compile-time, structural over `Node`/`DependencyView`, git-diff edit locus, fail-closed, CI-enrolled) refines the baseline down to the minimal sound set. This is an **affordability** move *on top of* #5427's soundness, not a replacement for it. Membership stays bounded by **affectedness, not cost**: expensive-but-affected tests run per-PR, their cost absorbed by parallelize + cache."), - ]), - h2(text: "4. Off per-PR cadence: only two things (neither is \"expensive\")"), - ol(items: [ - li(text: "**Non-hermetic residue** — live-network / real-external-service captures that *cannot* gate deterministically regardless of cost. Routed by **determinism**, not expense. Small, irreducible."), - li(text: "**The full-corpus selector-backstop** — run *everything* on a slow cadence as soundness insurance that affected-set selection missed no dep edge. This **fail-closes the selector itself**, and is exactly the insurance that lets step 2 shrink the per-PR set safely. It is an audit of *all* tests, **not** a dumping ground for slow ones."), - ]), - p(text: "The \"expensive\" category drains toward ~this residue as #5456 (opt-level=3, debug-amplification fix — restores Pop-A to per-PR) and #5450 (build-once for Pop-B) land. So lane machinery is **residue-gated, built only after measurement shows a genuine irreducible set** (§6 — no machinery for near-zero residue). The scheduled-workflow CI-gen (`gunbc ci` / `ci_spec`) is load-bearing — escalate before editing it."), - h2(text: "5. Why this unifies the §1 story"), - p(text: "Affected-set and parallelization-by-realization are the **same work from two ends**: selection shrinks **what** runs per-PR (to the affected set); realization shrinks **how long** it takes (width / placement / cache / Share). Together they make *\"run the affected set per-PR, fast\"* the default — which dissolves the need for a cost-based nightly dump entirely. The only residue is (1) non-hermetic and (2) the selector backstop — neither is \"expensive\"; both are about soundness / determinism."), - h2(text: "6. The seam, precisely"), - p(text: "§4 selection produces the must-run set; §1 scheduling runs **that** set affordably (parallelism / cache) and runs the **complement** on a backstop cadence. Selection decides *membership*; scheduling decides *cadence / placement / width*. Cost lives only on the scheduling side."), - h2(text: "7. 2026-07-04 — the run-all baseline stood down IN CI (opt-in inversion)"), - p(text: "Step 1's \"sound baseline\" stopped being a baseline the day the floor stopped *completing*: at ~1,551 discovered witnesses the composed pass hit the 90-minute job timeout on every run — maximum cost, **zero delivered signal**, and every merge effectively fail-open (a gate that always times out gates nothing). A run-all that never finishes is not a superset of the affected set; it is the empty set billed at full price. Operator decision: invert to **declared opt-in enrollment** — `CiSpec.witness_entries`, projected from `CommitWitnessClaim` rows on the `GithubActionsCiJob` surface of `commit_gate_roster`; an empty roster puts zero witness-corpus nodes in the floor plan. This is NOT the §0 cost-routed selection this doc rejects: no affected test is demoted by expense, because *no* witness currently gates by discovery — the inversion replaces an always-red-by-timeout gate with an honest, completing floor (gates + declared witnesses), and the discovery roster remains the local path (`claim_batch --roster-from-discovery`). The §3 ladder is unchanged as the *destination*: land affected-set selection + floor memoization, then re-enroll the corpus through the affected set and dissolve the opt-in roster (dissolve-on marker lives on `ci_witness_optin_inversion` in `gunbc.commit_workflow`). Found during the inversion: `resolve_floor_runner_context` had been failing on a comment block the v1 grammar cannot parse (`affected_set_floor_runner.dag`), so the affected-set skip silently fell back to full-corpus on every run — step 2 was dead in CI while the doc described it as CI-enrolled."), - ] -} - -data ci_selection_vs_scheduling_plan: Plan = Plan { - slug: "ci-selection-vs-scheduling", - title: "CI selection vs scheduling — the two orthogonal axes (§1/§4 seam)", - body: ci_selection_vs_scheduling_body(), - retirement: PlanRetiresWhen { condition: unbound_dissolution(description: "Delete this doc when the per-PR gate is the affected set (step 2 landed on top of #5427's baseline), the nightly cadence is the full-corpus backstop + non-hermetic residue (no cost-based selector), and the completeness lens runs executably — at which point the carriers (the lens + the CI-gen spec) state the policy and this framing is redundant.") - } -} diff --git a/dag/gunbc/prose_row_frontier.dag b/dag/gunbc/prose_row_frontier.dag index 2cd3b203378..017aef1a48d 100644 --- a/dag/gunbc/prose_row_frontier.dag +++ b/dag/gunbc/prose_row_frontier.dag @@ -234,7 +234,6 @@ data prose_row_migration_scope: List = [ "dag/test/claim/scm_issuer_corpus_witness_test.dag", "dag/test/claim/scm_provider_matrix_witness_test.dag", "dag/test/claim/scm_serving_model_witness_test.dag", - "dag/test/claim/selection_degradation_receipt_witness_test.dag", "dag/test/claim/session_residency_witness_test.dag", "dag/test/claim/source_annotation_attachment_witness_test.dag", "dag/test/claim/state_response_totality_witness_test.dag", diff --git a/dag/gunbc/roster_registry.dag b/dag/gunbc/roster_registry.dag index 0ee6664603c..69bb5367105 100644 --- a/dag/gunbc/roster_registry.dag +++ b/dag/gunbc/roster_registry.dag @@ -1,84 +1,3 @@ -module gunbc.roster_registry - -import std.decl_ref { DeclarationRef, WholeDeclaration } -import std.dissolution { DissolutionCondition, unbound_dissolution, dissolution_description } - -data roster_registry_taxonomy_note: String = "Group-of-units standard representation (operator ruling 2026-07-22, roadmap group 5a): a plurality of units must have a standard representation, never a nickname. Membership in a group is known exactly one of four ways — POSITIONAL (containment: being-in IS being-there, e.g. a module's members or a directory-grain lane), DERIVED (a computed relation: closure reachability, inhabitance, measurement), FRONTIER (asserted per-row WITH a reason and a dissolve_on trigger — countable, prioritizable, the typed self-host-frontier pattern), or NICKNAME (asserted, string-keyed, no trigger — the violation this registry exists to make visible). The migration pipeline for any hand-kept list is mint -> frontier -> query: a new group lands as typed frontier rows, and graduates to a derived query when its membership predicate is modelable. Every known unit-naming roster is enrolled below; the lens v2.lens.roster_registry holds each registration to ByContainment, ByDerivation, or DeclaredFrontier-with-nonempty-reason-and-trigger." - -data roster_registry_enforcement_intent_convergence_note: String = "Convergence, not implementation: the enforcement-intent thread (DESIGN open thread 'enforcement intent — ask once, compile forever'; docs/plans/enforcement-intent-design.md) absorbs this registry when StandingIntent / LensContract land — its subject_roster IS this concept (a registered group of units with declared membership provenance). Do not build that machinery here; this carrier stays the minimal data authority and the lens stays a data-shape check until that thread lands and this registry becomes its subject_roster carrier." - -data roster_registry_visibility_note: String = "Honesty bound: the lens sees only ENROLLED registrations. An unregistered bare list elsewhere in the tree is invisible to it — until enforcement-intent lands, unregistered nickname lists are caught at review by the group-5a rule (registry admission is the review bar for any new 'pool'/'class'/'lane'/'family' String key), not by this lens. The one residue this note formerly walled — NON_FOLD_RESIDUE_ROSTER, a host-side Rust const whose per-row reasons and triggers lived as comments — is re-homed: the rows are gunbc.non_fold_residue.non_fold_residue_frontier (typed FrontierRow, host census reads through non_fold_residue_units_from_module_source in cli_run.rs) and the roster is enrolled below. RESIDUE ACCOUNTING (corrected 2026-07-25): this note formerly claimed 'no known unregistered residue remains' and that claim was FALSE — a CI-land census that day found five unenrolled hand lists outside gunbc.ci_layer_roots, whose own enrollment lane was complete and had made the gap look closed: ci_floor_required_artifact_names and gunbc_ci_floor_batch_wall_budget_seconds (gunbc.ci_spec), commit_gate_roster (gunbc.commit_workflow), gunbc_ci_cheap_floor_gate_membership (v2.workflow.ci_floor_plan), and ci_cost_floor_exempt_step_names (gunbc.ci_materialization). All five are enrolled below. The lesson is this note's own visibility bound applied to itself: enrollment completeness in one module is not evidence of completeness in the tree, so a 'no residue remains' claim is only ever as good as its last census and carries the census date. CORRECTION (2026-07-25, same day): the paragraph above previously named GENERATED_STAGE0_FILES as residue that 'cannot carry a RosterRegistration until its rows re-home into .dag'. That was WRONG, and it is a second instance of this note's own lesson — a residue claim asserted from one side of the tree without checking the other. The rows were ALREADY in .dag as gunbc.stage0_emit_model.generated_stage0_files, and the Rust const's own header already names that decl 'Registry authority'. So the defect was never a missing re-home; it was a live FORK of two hand copies, which had silently drifted 98 (.dag) versus 101 (Rust) — the .dag side missing three real generated files. The drift is repaired and the roster is enrolled below; the fork itself closes only when regen_stage0 reads the .dag rows and the const is deleted. The lesson generalizes: 'this cannot be enrolled yet' is a claim about the tree and must be verified against the tree, exactly like the 'no residue remains' claim it sits beside. By contrast regen_input_sources (cli_run.rs) is NOT residue and is deliberately not listed: it derives its set by walking the import closure from the entry roots, so it is already ByDerivation in substance. GROWTH BASIS, and how to re-derive it: the point of enrolling a hand list is that its ACCUMULATION becomes observable, so the question a future reader asks is 'has this roster grown since it was registered, and what grew it'. That is answered from git rather than from a count stored here — a stored count is the hand-count-beside-structure class this registry exists to make visible, and it would rot silently (the GENERATED_STAGE0_FILES figure above sat at 54 in prior notes while the const had reached 101). TWO TRAPS make the re-derivation non-obvious. First, working clones here are SHALLOW (a default worktree carries ~12 commits), so git log over a roster's history returns almost nothing and looks like 'this list has never changed' — run git fetch --depth=400 origin main first, and treat any basis older than that horizon as truncated rather than absent. Second, line numbers move, so trace the DECLARATION not a line range: git log -L then the decl's current start,end line range, and for a true growth series count the roster's elements at each touching commit (git show COMMIT:FILE piped through a count of the row marker) rather than trusting the touch count, since most commits edit a row without adding one. Basis (2026-07-25, post-merge of #7199): ci_floor_required_artifact_names 18 entries; witness_exclusion_frontier 74 rows; bin_witness_wet_entries 53; commit_gate_roster 44; known_red_probe_entries 7; gunbc_ci_floor_batch_wall_budget_seconds 7; gunbc_ci_cheap_floor_gate_membership 3; ci_cost_floor_exempt_step_names 3. These are a DATED SNAPSHOT for comparison, not an authority: re-derive before relying on any of them. THE SNAPSHOT'S OWN STALENESS IS THE RECEIPT for why this note stores a recipe instead of a count column. The basis was first taken at main 4aed680509 and read: bin roster 17, exclusion frontier 73, bin_witness_wet 51, commit_gate_roster 45. Merging main a few hours later (bringing #7199) moved FOUR of those seven rows in ONE merge — 17 -> 18 (the bin roster gaining resolution_divergence_census, i.e. the very row this registry names as the expected first faller grew again while being registered), 73 -> 74, 51 -> 53, and commit_gate_roster 45 -> 44, which SHRANK. So a stored count here would have been wrong before the PR that wrote it even landed, and the shrink shows the drift is not monotone, which is why 'has it grown' must be answered by re-derivation over git rather than by comparing against a number someone typed. The rate visible in that one merge — four of seven rosters, inside a single day — is itself the finding this registry exists to surface." - -data roster_registry_upcoming_targets_note: String = "Walls for in-flight lanes (registry admission is the rule): (a) the bulk-native flip's 744 frontier rows MUST land ByDerivation — the native_routing_frontier registration below is the template (subject-keyed, closure-derived membership, equivalence receipt); (b) chore-remedy classification is already by-construction (subject types) and needs no registration; (c) the deploy lease/generation guard reuses Grant/containment-prefix plus git ancestry — no new group concept, nothing to enroll; (d) machine-shape scheduling and CI-ergonomics lanes: any 'pool'/'class'/'lane' String key at review enrolls here or is rejected as a nickname; (e) the long/ dir lane was BLESSED Form-C on the ground that storage grain came WITH a construction backstop — the five-second eval deadline making an over-budget fast-lane witness unwritable-in-place. THAT BLESSING IS RETRACTED (2026-08-04): the deadline is evaluated only while a witness RUNS, and moving a file under the long/ prefix is exactly the act that stops it running, so the backstop is disarmed by the move it was supposed to govern. Measured cost of the wrong blessing: gunbc#7762 commit 0cfd199f8 relocated a thirteen-function discriminating matrix into test/claim/long/ under the title fix CI fast-lane budget failures, adding a claim_batch command line as a data row and no cadence — zero executed coverage, admission holding, and a later commit on the same branch split eight of the thirteen back only because a reviewer looked. The lane keeps its ByContainment registration below because the containment IS still how the files are organized, but containment no longer decides admission: gunbc.witness_deferral_freeze enumerates the frozen legacy identities and anything outside it refuses (std.witness_admission UnclassifiedPathDeferral). The general lesson for a future Form-C blessing is that a backstop must be checked against the transformation it is claimed to prevent, not against the state it describes." - -type GroupMembership - = ByContainment - | ByDerivation { predicate: DeclarationRef } - | DeclaredFrontier { reason: String, dissolution: DissolutionCondition } - -type RosterRegistration { - roster: DeclarationRef - unit_kind: String - membership: GroupMembership -} - -fn roster_decl(module_path: String, decl_name: String) -> DeclarationRef { - DeclarationRef { - module_path: module_path, - decl_name: decl_name, - field: WholeDeclaration - } -} - -data roster_registry: List = [ - RosterRegistration { - roster: roster_decl(module_path: "v1.compiler.infer", decl_name: "unresolved_method_frontier"), - unit_kind: "method call whose receiver establishes no method surface, keyed (module, method, receiver_shape)", - membership: DeclaredFrontier { - reason: "The method-existence wall refuses an unresolved method rather than inheriting the receiver type, but it can only PROVE absence against a receiver that has a complete declared surface. These rows are the calls whose receiver has none — each an upstream receiver-resolution defect (a lambda parameter whose type never propagates, a coproduct payload typed as its variant name, a bare type variable, an optional whose cardinality is dropped before lookup) rather than a fact about the method. Refusing them would fabricate a refusal over correct working code, including the v2 tokenizer's own LexMatchThunk idiom; admitting them silently would fabricate a success. The rows carry the residue as counted MethodExistenceFrontierAdmitted diagnostics instead. The key includes the receiver SHAPE because that shape IS the evidence, so a new call is refused unless it reproduces the exact unestablished shape the row was measured on.", - dissolution: unbound_dissolution(description: "feature:primitive-realization-single-authority — one PrimitiveDefinition identity joining semantic definition, interpreter dispatch and per-target emit handler, at which point every receiver has a complete declared surface and the wall decides these directly. Each row also dissolves individually when its own named receiver-resolution defect is fixed.") - } - }, - RosterRegistration { - roster: roster_decl(module_path: "gunbc.ci_layer_roots", decl_name: "witness_exclusion_frontier"), - unit_kind: "witness discovery-exclusion path substring", - membership: DeclaredFrontier { - reason: "each excluded witness path pattern is an operator-ruled or structurally-forced exception to per-PR hermetic discovery; every row carries its consumer classification, reason, and trigger in-row", - dissolution: unbound_dissolution(description: "witness rows carry derived consumer classification (per witness_exclusion_single_authority_reconciliation_note) or the enforcement-intent registry absorbs the roster") - } - }, - RosterRegistration { - roster: roster_decl(module_path: "gunbc.ci_layer_roots", decl_name: "whole_tree_strict_resolve_exclusion_substrings"), - unit_kind: "strict-resolve probe path substring", - membership: DeclaredFrontier { - reason: "the strict-resolve-broken set, baked as single authority per operator ruling 2026-07-13; per-row audit receipts in whole_tree_strict_resolve_scaffold_exclusion_note", - dissolution: unbound_dissolution(description: "per row: the file relocates under a /test/ path or the blanket /test/ exclusion policy changes so its resolve repairs; a row that excludes nothing deletes") - } - }, - RosterRegistration { - roster: roster_decl(module_path: "gunbc.ci_layer_roots", decl_name: "bin_witness_wet_entries"), - unit_kind: "schedule witness entry (entry file x function)", - membership: DeclaredFrontier { - reason: "bin-execution witness class: fns run compiled seed witness binaries (host effects on non-commit-deterministic inputs), so the hermetic envelope refuses them by construction; they run as the declared Wet-profiled batch (bin_witness_wet_note)", - dissolution: unbound_dissolution(description: "these files migrate under the execution-corpus scope prefix and enroll as ExecutionWitnessKind rows in gunbc.commit_workflow; then this roster and its exclusion rows delete") - } - }, - RosterRegistration { - roster: roster_decl(module_path: "gunbc.ci_layer_roots", decl_name: "scoped_witness_batches"), - unit_kind: "scoped witness batch instance", - membership: DeclaredFrontier { - reason: "source-root envelopes outside ordinary discovery enroll through the generic std.realization_schedule ScopedWitnessBatch carrier; the current v1 claim instance is the first live member", - dissolution: unbound_dissolution(description: "per instance: its source-root envelope joins ordinary discovery or its typed instance dissolution trigger fires; roster-wide, scoped batches derive from declarations that require a non-ordinary source-root envelope") - } - }, - RosterRegistration { - roster: roster_decl(module_path: "gunbc.ci_layer_roots", decl_name: "v1_claim_scoped_witness_entries"), - unit_kind: "file-grain schedule witness entry", - membership: DeclaredFrontier { - reason: "these two v1 claim files require the dag plus src/v1 envelope declared by v1_claim_scoped_witness_batch and are outside ordinary dag plus src/v2 discovery", - dissolution: unbound_dissolution(description: "gunbc.ci_layer_roots v1_claim_scoped_witness_dissolve_on: V2ParserOwnsV1Claims") - } - }, RosterRegistration { roster: roster_decl(module_path: "gunbc.ci_layer_roots", decl_name: "falsifier_rehomed_bin_wet_rows"), unit_kind: "schedule witness entry (entry file x function)", diff --git a/dag/gunbc/selection_degradation_receipt.dag b/dag/gunbc/selection_degradation_receipt.dag deleted file mode 100644 index 3598a68bd72..00000000000 --- a/dag/gunbc/selection_degradation_receipt.dag +++ /dev/null @@ -1,314 +0,0 @@ -module gunbc.selection_degradation_receipt - -import std.types { String, Bool, NonEmptyStr } -import std.nat { Nat } -import std.measure { BasisPoint, basis_point, basis_point_count } -import std.decimal { zero_pad_left } -import extdeps.languages.json.emit { - JsonValue, - JsonKeyValue, - json_string, - json_int, - json_bool, - json_object, - json_kv, -} - -data selection_degradation_receipt_path: String = "target/floor-selection-degradation-receipt.txt" - -data selection_degradation_receipt_note: String = "P2 of the floor prep-tax program (still-moth-459, 2026-08-03): every floor discovery run publishes selection honesty — state, selected/total entry groups, ratio, and fallback_reason — so an affected run that executes the whole corpus is a COUNTED performance degradation (SelectionSuperset), never quiet success (DESIGN section 5). SelectionDegradationUnavailable is the unknown selection_mode_tag fail-closed arm only; upfront categorization_unavailable augments Applied/Superset fallback_reason, not that state. Authority for classification and receipt shape; the seed transport in cli_run.rs resolves this module and calls selection_degradation_receipt_line with measured counts only." - -data selection_degradation_receipt_marker: NonEmptyStr = "[selection-degradation]" as NonEmptyStr - -type SelectionDegradationState - = SelectionDegradationOff - | SelectionDegradationPredictOnly - | SelectionDegradationApplied - | SelectionDegradationSuperset - | SelectionDegradationUnavailable - -type SelectionDegradationReceipt { - selection_state: SelectionDegradationState - selected_entry_groups: Nat - total_entry_groups: Nat - selection_ratio_bp: BasisPoint - fallback_reason: String -} - -fn selection_degradation_mode_of_tag(tag: NonEmptyStr) -> String { - tag as String -} - -fn selection_degradation_state_tag(state: SelectionDegradationState) -> String { - match state { - SelectionDegradationOff => "SelectionOff" - SelectionDegradationPredictOnly => "SelectionPredictOnly" - SelectionDegradationApplied => "SelectionApplied" - SelectionDegradationSuperset => "SelectionSuperset" - SelectionDegradationUnavailable => "SelectionUnavailable" - } -} - -fn selection_ratio_basis_points(selected: Nat, total: Nat) -> BasisPoint { - if total == 0 { - basis_point(count: 0) - } else { - basis_point(count: (selected * 10000) / total) - } -} - -fn selection_ratio_wire(selected: Nat, total: Nat) -> String { - let bp = basis_point_count(bp: selection_ratio_basis_points(selected: selected, total: total)) - let unit = 10000 - let whole = bp / unit - let frac = bp - (whole * unit) - join( - [to_string(whole), ".", zero_pad_left(digits: to_string(frac), width: 4)], - "" - ) -} - -fn selection_degradation_fallback_reason_off() -> String { - "node_frontier_selection=SelectionOff — full corpus roster executed" -} - -fn selection_degradation_fallback_reason_predict_only() -> String { - "node_frontier_selection=SelectionPredictOnly — all witnesses run cold; divergences counted" -} - -fn selection_degradation_fallback_reason_applied_narrowed(selected: Nat, total: Nat) -> String { - concat( - "SelectionApplied: ", - concat( - concat(to_string(selected), concat(" of ", to_string(total))), - " entry groups executed (import-closure and node-frontier skip reduced the run)" - ) - ) -} - -fn selection_degradation_fallback_reason_superset(total: Nat) -> String { - concat( - "SelectionSuperset: all ", - concat( - to_string(total), - " entry groups executed — affected-set selection did not narrow the floor (counted performance degradation)" - ) - ) -} - -fn selection_degradation_fallback_reason_categorization_unavailable(detail: String) -> String { - concat( - "upfront import-closure categorization failed (", - concat(detail, "); per-shard selection is authoritative at completion") - ) -} - -fn selection_degradation_fallback_reason_unknown_mode_tag(tag: NonEmptyStr) -> String { - concat( - "SelectionUnavailable: unknown selection_mode_tag (", - concat(tag as String, "); expected off|applied|predict_only") - ) -} - -fn selection_degradation_state_of( - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> SelectionDegradationState { - if selection_mode_tag == ("off" as NonEmptyStr) { - SelectionDegradationOff - } else if selection_mode_tag == ("predict_only" as NonEmptyStr) { - SelectionDegradationPredictOnly - } else if selection_mode_tag == ("applied" as NonEmptyStr) { - if selected == total { - SelectionDegradationSuperset - } else { - SelectionDegradationApplied - } - } else { - SelectionDegradationUnavailable - } -} - -fn selection_degradation_fallback_reason_of( - selection_mode_tag: NonEmptyStr, - state: SelectionDegradationState, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> String { - match state { - SelectionDegradationOff => selection_degradation_fallback_reason_off() - SelectionDegradationPredictOnly => selection_degradation_fallback_reason_predict_only() - SelectionDegradationApplied => - if categorization_unavailable { - concat( - selection_degradation_fallback_reason_applied_narrowed(selected: selected, total: total), - concat( - " — ", - selection_degradation_fallback_reason_categorization_unavailable(detail: categorization_reason) - ) - ) - } else { - selection_degradation_fallback_reason_applied_narrowed(selected: selected, total: total) - } - SelectionDegradationSuperset => - if categorization_unavailable { - concat( - selection_degradation_fallback_reason_superset(total: total), - concat( - " — ", - selection_degradation_fallback_reason_categorization_unavailable(detail: categorization_reason) - ) - ) - } else { - selection_degradation_fallback_reason_superset(total: total) - } - SelectionDegradationUnavailable => - selection_degradation_fallback_reason_unknown_mode_tag(tag: selection_mode_tag) - } -} - -fn selection_degradation_receipt_of( - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> SelectionDegradationReceipt { - let state = selection_degradation_state_of( - selection_mode_tag: selection_mode_tag, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason - ) - SelectionDegradationReceipt { - selection_state: state, - selected_entry_groups: selected, - total_entry_groups: total, - selection_ratio_bp: selection_ratio_basis_points(selected: selected, total: total), - fallback_reason: selection_degradation_fallback_reason_of( - selection_mode_tag: selection_mode_tag, - state: state, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason - ) - } -} - -fn selection_degradation_receipt_line( - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> String { - let r = selection_degradation_receipt_of( - selection_mode_tag: selection_mode_tag, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason - ) - concat( - concat( - concat(selection_degradation_receipt_marker as String, " selection_state="), - selection_degradation_state_tag(state: r.selection_state) - ), - concat( - concat( - concat( - concat(" selected_entry_groups=", to_string(r.selected_entry_groups)), - concat(" total_entry_groups=", to_string(r.total_entry_groups)) - ), - concat(" selection_ratio=", selection_ratio_wire(selected: selected, total: total)) - ), - concat(" fallback_reason=", r.fallback_reason) - ) - ) -} - -fn selection_degradation_receipt_body( - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> String { - let r = selection_degradation_receipt_of( - selection_mode_tag: selection_mode_tag, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason - ) - concat( - concat( - concat( - concat("selection_state=", selection_degradation_state_tag(state: r.selection_state)), - concat("\nselected_entry_groups=", to_string(r.selected_entry_groups)) - ), - concat("\ntotal_entry_groups=", to_string(r.total_entry_groups)) - ), - concat( - concat("\nselection_ratio=", selection_ratio_wire(selected: selected, total: total)), - concat("\nfallback_reason=", r.fallback_reason) - ) - ) -} - -fn selection_degradation_receipt_json( - selection_mode_tag: NonEmptyStr, - selected: Nat, - total: Nat, - categorization_unavailable: Bool, - categorization_reason: String -) -> JsonValue { - let r = selection_degradation_receipt_of( - selection_mode_tag: selection_mode_tag, - selected: selected, - total: total, - categorization_unavailable: categorization_unavailable, - categorization_reason: categorization_reason - ) - json_object(members: [ - json_kv( - key: "selection_state", - value: json_string(s: selection_degradation_state_tag(state: r.selection_state)) - ), - json_kv(key: "selected_entry_groups", value: json_int(n: r.selected_entry_groups)), - json_kv(key: "total_entry_groups", value: json_int(n: r.total_entry_groups)), - json_kv( - key: "selection_ratio", - value: json_string(s: selection_ratio_wire(selected: selected, total: total)) - ), - json_kv(key: "fallback_reason", value: json_string(s: r.fallback_reason)), - json_kv(key: "categorization_unavailable", value: json_bool(b: categorization_unavailable)) - ]) -} - -fn selection_degradation_is_superset(receipt: SelectionDegradationReceipt) -> Bool { - match receipt.selection_state { - SelectionDegradationSuperset => true - SelectionDegradationOff => false - SelectionDegradationPredictOnly => false - SelectionDegradationApplied => false - SelectionDegradationUnavailable => false - } -} - -fn selection_degradation_is_applied_narrowed(receipt: SelectionDegradationReceipt) -> Bool { - match receipt.selection_state { - SelectionDegradationApplied => true - SelectionDegradationOff => false - SelectionDegradationPredictOnly => false - SelectionDegradationSuperset => false - SelectionDegradationUnavailable => false - } -} diff --git a/dag/gunbc/witness_row_cost.dag b/dag/gunbc/witness_row_cost.dag index 60e8cb8333a..0f6d8949ca7 100644 --- a/dag/gunbc/witness_row_cost.dag +++ b/dag/gunbc/witness_row_cost.dag @@ -11,6 +11,9 @@ import std.measure { millisecond, millisecond_count, nanosecond_to_millisecond_floor, + Second, + second, + second_count, } import v2.std.algebra { filter, length } import std.decl_ref { DeclarationRef, WholeDeclaration } @@ -59,7 +62,6 @@ import std.observation { } import v2.std.optional { Absent, Optional, Present } import v2.std.text { String } -import v2.workflow.ci_floor_plan { gunbc_ci_fast_lane_eval_budget_ms } data witness_row_cost_spine_note: String = "Per-witness cost receipts (placement workstream #5 spine). THE RECORD is std.observation.ObservationEvent (progress-observation-design §2/§3c) — not a TSV schema and not WitnessTimingRow. Production shape is N+1 per entry: exactly ONE entry resolve-phase Concluded event (entry-level/shared resolve wall) plus one declaration-grain Concluded event per witness (eval wall + actual outcome; Refused distinct from Failed). RSS is MeasuredUnavailable with an explicit cause. The canonical event and joined receipt retain exact Nanosecond eval, resolve, and warm values; histogram, ordering, and attribution consume those exact values. The TSV/drift/placement wires are named Millisecond presentation and policy boundaries and may floor only there. The resolve column repeats the observed full entry resolve for each child — never divided across witnesses and never summed N times into a corpus total. W2 filters the SAME events via AttentionLevel/ObservationDensity (Ambient may suppress a render line while the complete receipt still retains the row). Basis values MUST cite an arm64 srv-fleet run id (never local x86). A row with no dated basis is BasisAbsent. Drift is falsifier-cadence counted, not merge-refusing. Executing consumers: dag/test/claim/witness_row_cost_drift_witness_test.dag and dag/test/claim/witness_row_cost_projection_witness_test.dag." @@ -127,7 +129,7 @@ fn witness_row_cost_migration_threshold_order_of_magnitude() -> Nat { } fn witness_row_cost_migration_threshold_ms() -> Nat { - gunbc_ci_fast_lane_eval_budget_ms() / witness_row_cost_migration_threshold_order_of_magnitude() + witness_row_fast_lane_eval_budget_ms() / witness_row_cost_migration_threshold_order_of_magnitude() } type MigrationDisclosureVerdict @@ -655,3 +657,14 @@ fn witness_cost_seed_timed_out_event( outcome: TimedOut { basis: basis, budget: budget, elapsed: elapsed } ) } + +// Re-homed here from v2.workflow.ci_floor_plan when the CI wipe (2026-08-15) deleted that module. +// The five-second fast-lane budget is a fact about what a witness row may cost, which is this +// module's subject; it sat in the floor plan only because the floor plan was what armed it. No +// consumer arms it today -- the executor that did is deleted -- so this is the threshold's +// declaration, not a claim that anything enforces it. +data witness_row_fast_lane_witness_eval_budget: Second = second(count: 5) + +fn witness_row_fast_lane_eval_budget_ms() -> v2.std.nat.Nat { + second_count(s: witness_row_fast_lane_witness_eval_budget) * 1000 +} diff --git a/dag/std/realization_schedule.dag b/dag/std/realization_schedule.dag index d719892e981..dd68abbd390 100644 --- a/dag/std/realization_schedule.dag +++ b/dag/std/realization_schedule.dag @@ -147,9 +147,10 @@ type RunnableResourceProfile { } // A clamp carries WHO DECLARED IT, and it is a required field rather than a lookup, because the -// numbers alone cannot say. Two independently owned populations feed one aligned clamp list — the -// positional gunbc.ci_spec rows for ordinary batches, and the scoped witness batch's own row in -// gunbc.ci_layer_roots — and the executor reconstructed the origin from the LIST POSITION. That is +// numbers alone cannot say. Two independently owned populations once fed one aligned clamp list — +// the positional gunbc.ci_spec rows for ordinary batches, and a scoped witness batch's own row in +// gunbc.ci_layer_roots (that batch is deleted; the field it forced is not) — and the executor +// reconstructed the origin from the LIST POSITION. That is // how a refusal came to report clamp_ms=360000 while citing gunbc_ci_floor_batch_clamp_params[0], // a row whose overhead is 240 seconds: two facts that cannot both be true, printed in one located // diagnostic, costing two lanes their time reconciling a number against a row that never produced @@ -179,16 +180,12 @@ type RunnableBatchClampSource = RunnableUsesFloorPositionalClamp | RunnableOwnsBatchClamp { clamp: RunnableBatchClamp } -type ScopedWitnessProcessIsolation - = SharedWalkProcess - | SequentialChildProcess - | FreshJobProcess - -type ScopedWitnessBatchId = NonEmptyStr where brand("ScopedWitnessBatchId") - +// A single-variant carrier, and deliberately still a coproduct rather than a collapse to a +// bare product: it once had a ScopedWitnessFloorWorker arm carrying a batch id, deleted with +// the scoped witness batch (2026-08-15). The remaining arm keeps its own name so a second +// worker kind is one row rather than a type change at every reader. type FloorWorkerIdentity - = OrdinaryFloorWorker - | ScopedWitnessFloorWorker { batch_id: ScopedWitnessBatchId } + = OrdinaryFloorWorker {} type FloorWorkerTerminalReceipt = FloorWorkerTerminalReceiptObserved { report: FloorWorkerTerminalReport } @@ -248,272 +245,7 @@ type FloorWorkerObservationReceiptPath = NonEmptyStr where brand("FloorWorkerObs data floor_worker_observation_receipt_path: FloorWorkerObservationReceiptPath = "target/floor-worker-observation-receipt.tsv" -type ScopedExecutionRequestPath = NonEmptyStr where brand("ScopedExecutionRequestPath") - -data scoped_execution_request_path: ScopedExecutionRequestPath = "target/floor-attempts/scoped-execution-requests.json" - -data floor_worker_observation_note: String = "The floor coordinator is structurally closure-free: only worker processes resolve or execute a plan. The ordinary worker projects each SequentialChildProcess/FreshJobProcess ScopedWitnessBatch -- its frozen entries, source-root envelope, execution authority, clamp and the plan-derived budgets a child reads -- into scoped_execution_request_path together with the tested commit/tree/tool it was frozen against, then the coordinator waits for that worker to EXIT before spawning any SequentialChildProcess scoped worker, so their substantial live sets never overlap. Every worker writes a terminal receipt only after its result artifacts are complete; the coordinator crosses that report with the OS exit status and persists a located counted FloorWorkerObservation at floor_worker_observation_receipt_path. Missing terminal receipt is an observed state, never absence-as-success. Outcome is deliberately NOT a field: floor_worker_observation_outcome derives it totally from termination crossed with terminal_receipt, so Completed beside signal death or DiedWithoutTerminalReceipt beside an observed report is unrepresentable rather than lens-caught. The TSV outcome column is a boundary rendering of that derivation. FreshJobProcess is intentionally uninhabited and refuses until a workflow realization supplies its distinct cgroup, timeout, and scheduling semantics. 🟡 feature:floor-worker-observation-typed-tabular-codec dissolve-on: a std tabular-codec carrier derives the request and observation storage projections from List and FloorWorkerObservation, deleting the seed wire labels while preserving both branded paths." - -type ScopedWitnessBatchResourceProfile { - runnable: RunnableResourceProfile - clamp: RunnableBatchClamp - process_isolation: ScopedWitnessProcessIsolation -} - -type ScopedWitnessExecutionAuthority - = InheritedWalkSourceRoots {} - -data scoped_witness_execution_authority_note: String = "ScopedWitnessExecutionAuthority carries PROVENANCE, not an open-ended placeholder: InheritedWalkSourceRoots means every executor-owned .dag decision used while realizing the scoped batch — affected-set selection, witness execution-leg classification, and post-discovery cost/attribution projections — resolves from the enclosing walk's source-root authority. The scoped batch cannot author a second root list, so executor machinery cannot enter or move the witness subject universe, its digest, or its measured clamp basis. The one-variant carrier is therefore a construction wall against re-forking the root fact, not hollow generality." - -data scoped_witness_execution_authority_seed_refusal_note: String = "PRE-EXISTING SEED DIAGNOSTIC DEBT, observed by the scoped carrier rather than created by it: cli_run prime_witness_execution_legs panics when witness_entry_eligibility_census cannot resolve, instead of returning a typed located refusal through DiscoverySummary. The panic is fail-closed in effect but loses the actionable result arm and was one cause of an unexplained nonzero worker exit in run 30746409064. dissolve-on: prime_witness_execution_legs returns Result with the eligibility authority entry and inherited execution-authority roots in its error; run_discovery_corpus_with_options projects that error into the existing located discovery refusal and the panic arm deletes." - -type ScopedWitnessBatch { - batch_id: ScopedWitnessBatchId - source_roots: List - entries: List - scan_dirs: List - node_frontier_selection: NodeFrontierSelection - execution_authority: ScopedWitnessExecutionAuthority - execution_mode: ExecutionMode - resource_profile: ScopedWitnessBatchResourceProfile -} - -fn scoped_witness_source_roots_digest(source_roots: List) -> Fnv1a64Structural { - fold(source_roots, init: content_hash_atom(value: "scoped-witness-source-roots"), f: fn(acc, root) { - content_hash_combine_structural(left: acc, right: content_hash_atom(value: root)) - }) -} - -fn scoped_witness_batch( - batch_id: ScopedWitnessBatchId, - source_roots: List, - entries: List, - scan_dirs: List, - node_frontier_selection: NodeFrontierSelection, - resource_profile: ScopedWitnessBatchResourceProfile, -) -> ScopedWitnessBatch { - ScopedWitnessBatch { - batch_id: batch_id, - source_roots: source_roots, - entries: entries, - scan_dirs: scan_dirs, - node_frontier_selection: node_frontier_selection, - execution_authority: InheritedWalkSourceRoots {}, - execution_mode: resource_profile.runnable.execution_mode, - resource_profile: resource_profile, - } -} - -type ScopedWitnessExecutionOutcome - = ScopedWitnessExecuted { ok: Bool } - | ScopedWitnessSelectionSkipped { provenance: String } - | ScopedWitnessSchedulingRefused { detail: String } - | ScopedWitnessBudgetKilled { detail: String } - -type ScopedWitnessExecutionResult { - head_sha: CommitSha - batch_id: String - source_roots_digest: Fnv1a64Structural - entry: String - function: String - witness_kind: WitnessKind - outcome: ScopedWitnessExecutionOutcome -} - -type ScopedWitnessExecutionReceiptDecode - = ScopedWitnessExecutionReceiptDecoded { rows: List } - | ScopedWitnessExecutionReceiptRefused { detail: String } - -type ScopedWitnessExecutionReceiptPath = NonEmptyStr where brand("ScopedWitnessExecutionReceiptPath") - -data scoped_witness_execution_receipt_path: ScopedWitnessExecutionReceiptPath = "target/scoped-witness-execution-receipt.tsv" - -data scoped_witness_execution_receipt_header: String = "head_sha\tbatch_id\tsource_roots_digest\tentry\tfunction\twitness_kind\toutcome\tdetail" - -data scoped_witness_execution_receipt_wire_note: String = "ScopedWitnessExecutionResult and ScopedWitnessExecutionOutcome are the semantic API; the TSV path, header, and labels are their single storage projection for the declared filesystem_read consumer, never a second result schema. Every scheduled head carries one row per expanded roster entry: ScopedWitnessExecuted is execution evidence, while ScopedWitnessSelectionSkipped is a typed nonfailure retaining the selection provenance — never absence-as-pass and never coverage. The decoder returns the modeled rows directly and refuses malformed columns, unknown kinds, unknown outcomes, missing exact-head identity, and empty receipts. The decoded batch_id is validated nonempty wire identity text rather than an authored ScopedWitnessBatchId: this boundary observes a worker projection and cannot honestly construct that brand from arbitrary TSV text. The source_roots_digest carrier is family-narrow Fnv1a64Structural: wrong-family assignment is structurally impossible, while external text remains honestly guarded at rung two by fnv1a64_structural_hex_digest. The union exists only at the wire seam immediately before serialize_content_hash. The decoder intentionally refuses Sha1 and Sha256 wire identities rather than widening this structural-fingerprint field; RED controls pin both refusals. 🟡 feature:scoped-witness-receipt-typed-tabular-codec dissolve-on: a std tabular-codec carrier derives the header and row parser from the result product and outcome coproduct, deleting these hand-written wire labels while preserving ScopedWitnessExecutionReceiptPath and the decoded model surface." - -data scoped_witness_execution_receipt_refined_identity_scaffold_note: String = "DESIGN section 4b guarantee-ladder scaffold for exactly one field: ScopedWitnessExecutionResult.batch_id. PREVIOUS RUNG: the decoded product named ScopedWitnessBatchId but reached it by an unchecked cast from arbitrary TSV text; that was rung inflation, not validation, and canonical stage0 emission exposed the cast as runtime panic. TEMPORARY RUNG: nonempty String identity text admitted only after the receipt decoder's exact-arity and nonempty check. REASON AND ATTAINABLE CEILING: the bootstrap has no validating constructor for this branded refined carrier at the decode boundary; this is the existing ROADMAP capability row `The capability audit: sole_constructor completeness, then seal the proof-carriers`, whose unverified population explicitly includes generic refinements and casts. BOUNDED POPULATION: only decoded ScopedWitnessExecutionResult.batch_id; ScopedWitnessBatch.batch_id remains branded where its authority constructs it. CROSS-REPRESENTATION JOIN: a consumer compares decoded text only with scoped_witness_batch_id_wire_text projected from the scheduled authority, never through an implicit cast. CLIMB ALREADY CONSUMED: #7480 grounded hash families, so source_roots_digest now reaches rung four against wrong-family assignment as Fnv1a64Structural; the minimum in-scope rung remains two at the external-text path, where fnv1a64_structural_hex_digest is the permanent validating mint and refusal is honest rather than debt. RESTORATION TRIGGER: the sole_constructor completeness audit lands a validating ScopedWitnessBatchId constructor for wire text; the decoder calls it, restores that field, and this scaffold deletes." - -fn scoped_witness_batch_id_wire_text(batch_id: ScopedWitnessBatchId) -> String { - concat("", batch_id) -} - -fn scoped_witness_source_roots_digest_wire_text(source_roots_digest: Fnv1a64Structural) -> String { - concat("", serialize_content_hash(hash: as_content_hash_structural(structural: source_roots_digest))) -} - -fn scoped_witness_source_roots_digest_for_wire(source_roots: List) -> String { - scoped_witness_source_roots_digest_wire_text( - source_roots_digest: scoped_witness_source_roots_digest(source_roots: source_roots), - ) -} - -fn scoped_witness_kind_label(kind: WitnessKind) -> String { - match kind { - CorpusWitnessKind => "corpus" - ExecutionWitnessKind => "execution" - NativeBundleWitnessKind => "native-bundle" - } -} - -fn scoped_witness_kind_from_label(label: String) -> WitnessKind? { - if label == "corpus" { - Present { value: CorpusWitnessKind } - } else if label == "execution" { - Present { value: ExecutionWitnessKind } - } else if label == "native-bundle" { - Present { value: NativeBundleWitnessKind } - } else { - none - } -} - -fn scoped_witness_execution_outcome_label(outcome: ScopedWitnessExecutionOutcome) -> String { - match outcome { - ScopedWitnessExecuted { ok: _ } => "executed" - ScopedWitnessSelectionSkipped { provenance: _ } => "selection-skipped" - ScopedWitnessSchedulingRefused { detail: _ } => "scheduling-refused" - ScopedWitnessBudgetKilled { detail: _ } => "budget-killed" - } -} - -fn scoped_witness_execution_outcome_detail(outcome: ScopedWitnessExecutionOutcome) -> String { - match outcome { - ScopedWitnessExecuted { ok: ok } => if ok { "true" } else { "false" } - ScopedWitnessSelectionSkipped { provenance: provenance } => provenance - ScopedWitnessSchedulingRefused { detail: detail } => detail - ScopedWitnessBudgetKilled { detail: detail } => detail - } -} - -fn scoped_witness_execution_result_tsv_row(row: ScopedWitnessExecutionResult) -> String { - join([ - row.head_sha, - row.batch_id, - scoped_witness_source_roots_digest_wire_text(source_roots_digest: row.source_roots_digest), - row.entry, - row.function, - scoped_witness_kind_label(kind: row.witness_kind), - scoped_witness_execution_outcome_label(outcome: row.outcome), - scoped_witness_execution_outcome_detail(outcome: row.outcome), - ], "\t") -} - -fn scoped_witness_execution_outcome_from_wire(label: String, detail: String) -> ScopedWitnessExecutionOutcome? { - if label == "executed" && detail == "true" { - Present { value: ScopedWitnessExecuted { ok: true } } - } else if label == "executed" && detail == "false" { - Present { value: ScopedWitnessExecuted { ok: false } } - } else if label == "selection-skipped" && detail != "" { - Present { value: ScopedWitnessSelectionSkipped { provenance: detail } } - } else if label == "scheduling-refused" && detail != "" { - Present { value: ScopedWitnessSchedulingRefused { detail: detail } } - } else if label == "budget-killed" && detail != "" { - Present { value: ScopedWitnessBudgetKilled { detail: detail } } - } else { - none - } -} - -fn scoped_witness_exact_head_text_holds(head: String) -> Bool { - head.length() == 40 && all(chars(s: head), cp => - (cp >= 48 && cp <= 57) || (cp >= 97 && cp <= 102) - ) -} - -data scoped_witness_exact_head_grounding_note: String = "Scoped witness execution results bind every row to the explicit lowercase 40-hex head supplied by the runner. std.types CommitSha is presently an unvalidated String alias, so scoped_witness_exact_head_text_holds is the located construction wall for this receipt family. Dissolve-on: CommitSha gains one validating constructor shared by every Git-head consumer; this decoder then calls that authority and deletes its local syntax check." - -fn scoped_witness_execution_result_from_columns(columns: List) -> ScopedWitnessExecutionResult? { - match columns { - Empty => none - Cons { head: head_sha, tail: after_head } => match after_head { - Empty => none - Cons { head: batch_id, tail: after_batch } => match after_batch { - Empty => none - Cons { head: source_roots_digest, tail: after_digest } => match after_digest { - Empty => none - Cons { head: entry, tail: after_entry } => match after_entry { - Empty => none - Cons { head: function, tail: after_function } => match after_function { - Empty => none - Cons { head: witness_kind_label, tail: after_kind } => match after_kind { - Empty => none - Cons { head: outcome_label, tail: after_outcome } => match after_outcome { - Empty => none - Cons { head: outcome_detail, tail: after_detail } => match after_detail { - Cons { head: _, tail: _ } => none - Empty => - if !scoped_witness_exact_head_text_holds(head: head_sha) - || batch_id == "" - || source_roots_digest == "" - || entry == "" - || function == "" { - none - } else { - match fnv1a64_structural_hex_digest(hex: source_roots_digest) { - Absent => none - Present { value: decoded_source_roots_digest } => - match scoped_witness_kind_from_label(label: witness_kind_label) { - Absent => none - Present { value: kind } => - match scoped_witness_execution_outcome_from_wire( - label: outcome_label, - detail: outcome_detail, - ) { - Absent => none - Present { value: outcome } => Present { - value: ScopedWitnessExecutionResult { - head_sha: head_sha, - batch_id: batch_id, - source_roots_digest: decoded_source_roots_digest, - entry: entry, - function: function, - witness_kind: kind, - outcome: outcome, - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } -} - -fn scoped_witness_execution_receipt_decode(text: String) -> ScopedWitnessExecutionReceiptDecode { - let lines = split(s: text, delimiter: "\n") - if length(lines) < 2 || lines.first() != scoped_witness_execution_receipt_header { - ScopedWitnessExecutionReceiptRefused { detail: "schema header absent or receipt has no rows" } - } else { - let body = lines.skip(n: 1) - let rows = if body.skip(n: length(body) - 1).first() == "" { - body.take(n: length(body) - 1) - } else { - body - } - if length(rows) == 0 { - ScopedWitnessExecutionReceiptRefused { detail: "receipt has no scoped witness execution result rows" } - } else { - fold(rows, init: ScopedWitnessExecutionReceiptDecoded { rows: [] }, f: fn(state, line) { - match state { - ScopedWitnessExecutionReceiptRefused { detail: detail } => ScopedWitnessExecutionReceiptRefused { detail: detail } - ScopedWitnessExecutionReceiptDecoded { rows: rows } => - match scoped_witness_execution_result_from_columns(columns: split(s: line, delimiter: "\t")) { - Absent => ScopedWitnessExecutionReceiptRefused { detail: "malformed scoped witness execution result row" } - Present { value: row } => ScopedWitnessExecutionReceiptDecoded { rows: concat(rows, [row]) } - } - } - }) - } - } -} +data floor_worker_observation_note: String = "The floor coordinator is structurally closure-free: only worker processes resolve or execute a plan. Every worker writes a terminal receipt only after its result artifacts are complete; the coordinator crosses that report with the OS exit status and persists a located counted FloorWorkerObservation at floor_worker_observation_receipt_path. Missing terminal receipt is an observed state, never absence-as-success. Outcome is deliberately NOT a field: floor_worker_observation_outcome derives it totally from termination crossed with terminal_receipt, so Completed beside signal death or DiedWithoutTerminalReceipt beside an observed report is unrepresentable rather than lens-caught. The TSV outcome column is a boundary rendering of that derivation. 🟡 feature:floor-worker-observation-typed-tabular-codec dissolve-on: a std tabular-codec carrier derives the observation storage projection from FloorWorkerObservation, deleting the seed wire labels while preserving the branded path." fn runnable_memory_negligible() -> RunnableMemoryClass { RunnableMemoryNegligible @@ -580,67 +312,37 @@ fn runnable_heavy_whole_tree_resolve(profile: RunnableResourceProfile) -> Bool { fn runnable_profile(r: Runnable) -> RunnableResourceProfile { match r { RunnableSingleClaim { entry: _, function: _, profile: p } => p - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => p - RunnableScopedWitnessBatch { batch: batch } => batch.resource_profile.runnable + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => p RunnableKernelWorkload { fused_op_count: _ } => runnable_resource_profile_negligible() } } fn runnable_batch_clamp_source(r: Runnable) -> RunnableBatchClampSource { match r { - RunnableScopedWitnessBatch { batch: batch } => RunnableOwnsBatchClamp { clamp: batch.resource_profile.clamp } RunnableSingleClaim { entry: _, function: _, profile: _ } => RunnableUsesFloorPositionalClamp - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => RunnableUsesFloorPositionalClamp + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => RunnableUsesFloorPositionalClamp RunnableKernelWorkload { fused_op_count: _ } => RunnableUsesFloorPositionalClamp } } fn runnable_forbids_corpus_co_residence(r: Runnable) -> Bool { match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => false - RunnableScopedWitnessBatch { batch: batch } => runnable_excludes_corpus_co_residence(profile: batch.resource_profile.runnable) + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => false RunnableSingleClaim { entry: _, function: _, profile: p } => runnable_excludes_corpus_co_residence(profile: p) RunnableKernelWorkload { fused_op_count: _ } => false } } -type NodeFrontierSelection - = SelectionOff - | SelectionApplied - | SelectionPredictOnly - -fn node_frontier_selection_eq(left: NodeFrontierSelection, right: NodeFrontierSelection) -> Bool { - match left { - SelectionOff => match right { - SelectionOff => true - SelectionApplied => false - SelectionPredictOnly => false - } - SelectionApplied => match right { - SelectionOff => false - SelectionApplied => true - SelectionPredictOnly => false - } - SelectionPredictOnly => match right { - SelectionOff => false - SelectionApplied => false - SelectionPredictOnly => true - } - } -} - type Runnable = RunnableSingleClaim { entry: String, function: String, profile: RunnableResourceProfile } | RunnableDiscoveryBatch { source_roots: List scan_dirs: List explicit_entries: List - node_frontier_selection: NodeFrontierSelection exclude_substrings: List discovery_scope_dirs: List profile: RunnableResourceProfile } - | RunnableScopedWitnessBatch { batch: ScopedWitnessBatch } | RunnableKernelWorkload { fused_op_count: Int } type OnSuccessRunnableDisposition @@ -655,9 +357,7 @@ data on_success_runnable_disposition_note: String = "The single modeled admissio fn on_success_runnable_disposition(runnable: Runnable) -> OnSuccessRunnableDisposition { match runnable { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => - OnSuccessDiscoveryRefused - RunnableScopedWitnessBatch { batch: _ } => + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => OnSuccessDiscoveryRefused RunnableKernelWorkload { fused_op_count: _ } => OnSuccessKernelRefused @@ -694,13 +394,13 @@ All four profile restrictions are conditional on mechanisms stages do not yet ha Every plan function returns WalkPlan — a plan with no postconditions returns on_success_stages: [] — and the executor has ONE strict parser: a malformed or missing field is a hard error, never a fallback to a bare-list reading." -data walk_plan_run_stage_claim_executor_seed_deferral: String = "§7 SEED-RETAINED, declared here because this is where the obligation is INCURRED (review 2026-07-31; scoped-worker extension 2026-08-01). `run_stage`, `spawn_units`, `join_units`, `batch_unit_lane`, the stage receipt writers, the walk-attempt observation, `maybe_run_floor_coordinator`, `spawn_floor_worker`, `observe_floor_worker`, `append_floor_phase_journal`, `journal_floor_worker_observation`, `scoped_execution_authority_source_roots`, and the manifest/execution/terminal/observation receipt projections are HAND-RUST in `claim_executor.rs`; retaining typed selection-skipped discovery rows and resolving executor-owned decisions against inherited walk roots are HAND-RUST in `cli_run.rs`. The executor is the seed that runs before any `.dag` walk exists, so the code that decides how a walk executes cannot itself be a walk. The scoped extension does not mint a second deferral: it is another realization of this one executor seed. The merge-admission pre-walk extension (2026-08-02, review 47517) is likewise this SAME deferral grown, not a new one: the PreWalkExecution value parser, `run_pre_walk_execution` (including its capture-refusal-wire read), the two WalkPopulationBudget watchdogs and the WalkPopulationBudgetRefusal durable writer, and the per-stage memory snapshots are HAND-RUST in `claim_executor.rs`, all dissolving on the same trigger as the rest of this row — the executor walk and its receipt projections becoming emitted `.dag` realizations. That is a real deferral, not an exemption — the seed grew here, and a growth in the seed is a §7 debt whether or not anyone writes it down. +data walk_plan_run_stage_claim_executor_seed_deferral: String = "§7 SEED-RETAINED, declared here because this is where the obligation is INCURRED (review 2026-07-31). `run_stage`, `spawn_units`, `join_units`, `batch_unit_lane`, the stage receipt writers, the walk-attempt observation, `maybe_run_floor_coordinator`, `spawn_floor_worker`, `observe_floor_worker`, `append_floor_phase_journal`, `journal_floor_worker_observation`, and the manifest/terminal/observation receipt projections are HAND-RUST in `claim_executor.rs`; resolving executor-owned decisions against inherited walk roots is HAND-RUST in `cli_run.rs`. The executor is the seed that runs before any `.dag` walk exists, so the code that decides how a walk executes cannot itself be a walk. The scoped extension does not mint a second deferral: it is another realization of this one executor seed. The merge-admission pre-walk extension (2026-08-02, review 47517) is likewise this SAME deferral grown, not a new one: the PreWalkExecution value parser, `run_pre_walk_execution` (including its capture-refusal-wire read), the two WalkPopulationBudget watchdogs and the WalkPopulationBudgetRefusal durable writer, and the per-stage memory snapshots are HAND-RUST in `claim_executor.rs`, all dissolving on the same trigger as the rest of this row — the executor walk and its receipt projections becoming emitted `.dag` realizations. That is a real deferral, not an exemption — the seed grew here, and a growth in the seed is a §7 debt whether or not anyone writes it down. WHY THIS ROW LIVES WITH THE CARRIER RATHER THAN WITH A CONSUMER. A first draft of this row was authored in the FIXTURE branch that later exercised this code, on the reasoning that the fixture is where the seed expansion became visible. That reverses ownership: the debt belongs to the change that added the Rust, and a downstream consumer documenting its parent's deferral means the parent could land without one. A consumer may cite this row; it may not be the row's home. -WHAT MAKES THE SCOPED EXTENSION CHECKABLE. `witness_v1_claim_scoped_batch_is_file_grain_and_batch_owned` and `witness_scoped_batch_is_singleton_and_outside_positional_clamps` pin the modeled batch, owned clamp, inherited execution authority, and SequentialChildProcess isolation. `scoped_witness_execution_receipt_decoder_accepts_writer_projection`, `scoped_witness_execution_receipt_decoder_preserves_selection_skip_provenance`, and `scoped_witness_execution_receipt_decoder_refuses_empty_ledger` pin the public modeled decoder across execution, honest nonexecution, and refusal. The Rust controls `scoped_selection_skip_is_a_provenanced_nonfailure_receipt_outcome` and `scoped_execution_authority_inherits_walk_roots_without_widening_subject_roots` pin the seed projections so an unaffected row remains present without failing the worker and executor-owned decisions consume the enclosing walk roots without entering the witness subject envelope. `floor_worker_observation_outcome_is_derived_from_evidence` proves in the model that the same completed terminal report derives Completed beside exit 0 and Failed beside signal death; there is no outcome field to transcribe. The Rust controls `floor_worker_missing_terminal_receipt_is_an_observed_death`, `floor_worker_terminal_crosses_receipt_with_exit_status`, `floor_worker_refusal_remains_distinct_from_failure`, `floor_worker_signal_death_is_not_flattened_to_an_exit_code`, `floor_worker_signal_overrules_a_completed_terminal_report`, and `floor_worker_verdict_reaches_the_durable_journal` pin the coordinator's typed observation boundary, the derived-verdict law, and the surviving out-of-band projection used when the Actions stream drops worker stderr. Deleting or flattening the modeled arms, widening the subject roots with executor dependencies, dropping a selection-skipped roster row, accepting receipt absence, normalizing a signal into success, storing an authored outcome, losing the durable verdict, or restoring the old isolation spelling makes one of those controls red. +WHAT THE SCOPED EXTENSION WAS, and why this row shrank. A scoped-witness worker once ran a second source-root envelope in a sequential child process, with its own clamp, execution authority, request projection and TSV receipt family, all hand-Rust here. Its single instance and every carrier behind it were deleted 2026-08-15 with affected-set selection, because the batch existed to make a second subject envelope affordable and selection was what made it affordable. The seed shrank by that whole path rather than migrating it. -MIGRATION TRIGGER: the executor's own scheduling decisions become a `.dag` walk over `WalkPlan` — lane selection, admission, worker sequencing, and receipt emission expressed as modeled effects rather than as `std::thread`, `std::process`, plus `std::fs` — at which point this Rust becomes an emitted realization and the row deletes. Gated behind the witness-realization lane, concretely ROADMAP `v1-materialization-kernel` (`docs/plans/witness-realization-plan.md`), since a `.dag`-expressed executor needs native witness execution to run at all. The two codec dissolve markers are subordinate parts of this same row: they delete when typed tabular projection is available, before the whole executor can delete. Until then the honest statement is that these are seed-retained by necessity with a named trigger and executable receipts, which is exactly what a self-host frontier row is for." +MIGRATION TRIGGER: the executor's own scheduling decisions become a `.dag` walk over `WalkPlan` — lane choice, admission, worker sequencing, and receipt emission expressed as modeled effects rather than as `std::thread`, `std::process`, plus `std::fs` — at which point this Rust becomes an emitted realization and the row deletes. Gated behind the witness-realization lane, concretely ROADMAP `v1-materialization-kernel` (`docs/plans/witness-realization-plan.md`), since a `.dag`-expressed executor needs native witness execution to run at all. The two codec dissolve markers are subordinate parts of this same row: they delete when typed tabular projection is available, before the whole executor can delete. Until then the honest statement is that these are seed-retained by necessity with a named trigger and executable receipts, which is exactly what a self-host frontier row is for." data walk_finalization_note: String = "THE PLAN CARRIES ITS FINALIZATION POLICY IN ITS TYPE, and the executor never infers it — not from a function's spelling, and not from which arm of a coproduct an authored value happened to pick. Two corrections stacked here. FIRST: the original cut selected finalization by plan-function name (if plan_function == gunbc_ci_floor_plan read the law from the closure) — the same hidden seed-roster convention the WalkPlan carrier was built to remove, reintroduced in the same PR (review 2026-07-30), and the RED fixture made the coupling visible by having to impersonate the production name to arm the contract. Moving it to a field fixed that. SECOND: a field of a coproduct type is still only an authored choice (review 2026-07-30, second pass). With `finalization: WalkFinalization`, `WalkPlan \{ batches: floor_batches, finalization: NoWalkFinalization, .. \}` typechecked — NoWalkFinalization and FloorFinalization inhabit the same sum, so nothing connected floor-shaped work to floor finalization; the production constructor merely chose correctly. So the carrier is PARAMETERIZED: WalkPlan, and gunbc_ci_floor_plan returns WalkPlan while regen, plan-artifact, and falsifier return WalkPlan. One runtime parser still reads both, because the parse is over the finalization VALUE and does not care which instantiation produced it. The parameterization also stops this generic std carrier from owning a growing coproduct of gunbc-specific receipt policies: FloorFinalization moved to gunbc.ci_materialization, beside the declared count it is about, and std keeps only the parameter and the declared-empty inhabitant. @@ -743,25 +443,6 @@ type WalkPopulationBudgetRefusal { data walk_population_budget_note: String = "WalkPlan carries an explicit Optional budget for each population — the unit lives in the std.measure carrier, never in a field name (the RunnableBatchClamp precedent). Absent is authored unboundedness, never a parser fallback; Present must be positive. The ordinary watchdog owns the entire ordinary interval through receipt finalization and is disarmed only before green-only stages arm, so ordinary work cannot consume a reserved postcondition allowance. The postcondition watchdog separately bounds stages plus their receipts. A breach constructs WalkPopulationBudgetRefusal and durably writes floor-population-budget-refusal.txt with the population, plan site, one-based active stage/batch index, active unit, measured elapsed wall, and the budget that fired BEFORE claim_executor flushes stderr and exits nonzero. Index zero means the population had not entered its first unit. The outer workflow timeout remains only a larger wrapper backstop." -fn node_frontier_selection_applied(sel: NodeFrontierSelection) -> Bool { - match sel { - SelectionApplied => true - SelectionOff => false - SelectionPredictOnly => false - } -} - -fn runnable_selection_applied(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: sel, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => - node_frontier_selection_applied(sel: sel) - RunnableScopedWitnessBatch { batch: batch } => - node_frontier_selection_applied(sel: batch.node_frontier_selection) - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - type Schedule = List> type RealizationPlan { @@ -775,8 +456,7 @@ type RealizationPlan { fn runnable_step_label(r: Runnable) -> String { match r { RunnableSingleClaim { entry: _, function: f, profile: _ } => f - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => "__discovery_corpus__" - RunnableScopedWitnessBatch { batch: _ } => "__scoped_witness_batch__" + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => "__discovery_corpus__" RunnableKernelWorkload { fused_op_count: _ } => "__kernel_workload__" } } @@ -833,33 +513,23 @@ fn runnable_eq(left: Runnable, right: Runnable) -> Bool { RunnableSingleClaim { entry: le, function: lf, profile: lp } => match right { RunnableSingleClaim { entry: re, function: rf, profile: rp } => (le == re) && (lf == rf) && runnable_resource_profile_eq(left: lp, right: rp) - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => false - RunnableScopedWitnessBatch { batch: _ } => false + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => false RunnableKernelWorkload { fused_op_count: _ } => false } - RunnableDiscoveryBatch { source_roots: lsr, scan_dirs: lsd, explicit_entries: lex, node_frontier_selection: lskip, exclude_substrings: lex2, discovery_scope_dirs: lsc, profile: lp } => match right { + RunnableDiscoveryBatch { source_roots: lsr, scan_dirs: lsd, explicit_entries: lex, exclude_substrings: lex2, discovery_scope_dirs: lsc, profile: lp } => match right { RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableDiscoveryBatch { source_roots: rsr, scan_dirs: rsd, explicit_entries: rex, node_frontier_selection: rskip, exclude_substrings: rex2, discovery_scope_dirs: rsc, profile: rp } => + RunnableDiscoveryBatch { source_roots: rsr, scan_dirs: rsd, explicit_entries: rex, exclude_substrings: rex2, discovery_scope_dirs: rsc, profile: rp } => string_list_eq(left: lsr, right: rsr) && string_list_eq(left: lsd, right: rsd) && schedule_witness_entry_list_eq(left: lex, right: rex) - && node_frontier_selection_eq(left: lskip, right: rskip) && string_list_eq(left: lex2, right: rex2) && string_list_eq(left: lsc, right: rsc) && runnable_resource_profile_eq(left: lp, right: rp) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } - RunnableScopedWitnessBatch { batch: lb } => match right { - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => false - RunnableScopedWitnessBatch { batch: rb } => lb == rb RunnableKernelWorkload { fused_op_count: _ } => false } RunnableKernelWorkload { fused_op_count: lleft } => match right { RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => false - RunnableScopedWitnessBatch { batch: _ } => false + RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => false RunnableKernelWorkload { fused_op_count: rcount } => lleft == rcount } } diff --git a/dag/std/types.dag b/dag/std/types.dag index 952ef6049eb..eee6aee0183 100644 --- a/dag/std/types.dag +++ b/dag/std/types.dag @@ -113,6 +113,14 @@ fn list_length(items: List) -> Int { type CommitSha = String +data commit_sha_text_holds_note: String = "The located syntax wall for an EXTERNALLY SUPPLIED Git head: lowercase 40-hex. It lives here, beside CommitSha, because that is the one authority every Git-head consumer already names — it was previously homed in std.realization_schedule as scoped_witness_exact_head_text_holds, where a receipt family that has since been deleted happened to be its first caller, and a second consumer (v2.compiler.self_host.frontier_probe_survey) was already importing it across that seam. CommitSha is presently an unvalidated String alias, so this predicate is a validating CHECK a caller must remember to run, not a construction wall. Dissolve-on: CommitSha gains one validating constructor; callers reach the constructor, the invalid state stops being writable, and this predicate deletes." + +fn commit_sha_text_holds(head: String) -> Bool { + head.length() == 40 && all(chars(s: head), cp => + (cp >= 48 && cp <= 57) || (cp >= 97 && cp <= 102) + ) +} + type Sha256 = String type RetryCount = Int where range(min: 1, max: 5) type HttpStatus = Int where range(min: 100, max: 599) diff --git a/dag/test/claim/bmc_wif_delegation_chain_witness_test.dag b/dag/test/claim/bmc_wif_delegation_chain_witness_test.dag index f3200806b4b..10b243d45d4 100644 --- a/dag/test/claim/bmc_wif_delegation_chain_witness_test.dag +++ b/dag/test/claim/bmc_wif_delegation_chain_witness_test.dag @@ -105,13 +105,6 @@ test fn threat_model_names_both_read_capabilities() -> Bool { acc || match c { CodeExecOnRunnerHostDuringJobWindow => true, _ => false }) } -test fn main_ci_workflow_grants_no_id_token() -> Bool { - match ci_workflow.permissions { - Present { value: perms } => match perms.id_token { Absent => true, _ => false } - Absent => true - } -} - test fn secret_ref_login_handler_added_beside_factory_login_not_over_it() -> Bool { secret_ref_credential_authority.module_path == "gunbc.auth.secret_ref_credential" && secret_ref_credential_authority.decl_name == "fetch_secret_ref_credential" diff --git a/dag/test/claim/ci_concurrency_policy_witness_test.dag b/dag/test/claim/ci_concurrency_policy_witness_test.dag deleted file mode 100644 index d29634e7e07..00000000000 --- a/dag/test/claim/ci_concurrency_policy_witness_test.dag +++ /dev/null @@ -1,63 +0,0 @@ -module test.claim.ci_concurrency_policy_witness_test - -import gunbc.ci_workflow { ci_workflow } -import gunbc.ci_workflow_expressions { - ci_concurrency_cancel_in_progress_if, - ci_concurrency_cancel_in_progress_expression, - ci_concurrency_group, -} -import extdeps.github.actions { - ConcurrencyMappingQueueNotMax, - CancelInProgressExpression, -} -import v2.std.collection { Present } -import v2.std.text { String } - -test fn ci_concurrency_cancel_expression_holds() -> Bool { - ci_concurrency_cancel_in_progress_expression() == ci_concurrency_cancel_in_progress_if -} - -test fn ci_concurrency_event_scoped_stop_policy_holds() -> Bool { - match ci_workflow.concurrency { - Present { value: spec } => - match spec { - ConcurrencyMappingQueueNotMax { group: _, cancel_in_progress: cip, explicit_single: _ } => - match cip { - Present { value: c } => - match c { - CancelInProgressExpression { expression: e } => - e == "${{ github.event_name != 'merge_group' }}" - _ => false - } - _ => false - } - _ => false - } - _ => false - } -} - -test fn ci_concurrency_stop_policy_discriminates_merge_group() -> Bool { - ci_concurrency_cancel_in_progress_if != "true" - && ci_concurrency_cancel_in_progress_if != "false" - && ci_concurrency_cancel_in_progress_if != "github.event_name != 'merge_group'" -} - -// The group key is the arm that exempts main from supersession, so it carries three -// claims rather than one string comparison: the exact serialized form, that a main push -// keys on the per-commit sha, and that the exemption did NOT widen into the global -// unique-key mistake the stop-policy note warns about (PR events must still key on the -// PR number, or every event gets its own group and cancellation becomes unreachable). -test fn ci_concurrency_group_exempts_main_and_keeps_pr_supersession() -> Bool { - ci_concurrency_group() == "${{ github.workflow }}-${{ github.event.pull_request.number || github.ref == 'refs/heads/main' && github.sha || github.ref }}" -} - -test fn ci_concurrency_group_keys_main_pushes_per_commit() -> Bool { - string_contains(s: ci_concurrency_group(), pattern: "github.ref == 'refs/heads/main' && github.sha") -} - -test fn ci_concurrency_group_still_supersedes_within_a_pull_request() -> Bool { - string_contains(s: ci_concurrency_group(), pattern: "github.event.pull_request.number") - && !string_contains(s: ci_concurrency_group(), pattern: "github.run_id") -} - diff --git a/dag/test/claim/ci_deploy_target_host_witness_test.dag b/dag/test/claim/ci_deploy_target_host_witness_test.dag index b457ed77a02..a124d3bbf7e 100644 --- a/dag/test/claim/ci_deploy_target_host_witness_test.dag +++ b/dag/test/claim/ci_deploy_target_host_witness_test.dag @@ -97,16 +97,6 @@ test fn witness_preflight_script_checks_target_host() -> Bool { && string_contains(s: script, pattern: "printenv RUNNER_NAME") } -// The deploy is now a STEP inside the unified `fleet` job (operator consolidation -// 2026-08-10), so runner pinning is asserted on that job: it runs on the srv1 self-hosted -// label set and never on a ubicloud runner. The deploy STEP itself carries no runs-on; -// pinning is a job fact, and the fleet job is where the deploy executes. -test fn witness_ci_yml_deploy_job_pins_srv1_runner() -> Bool { - let yaml = expected_ci_yml() - string_contains(s: yaml, pattern: " fleet:\n runs-on: [self-hosted, linux, arm64, srv1]") - && !string_contains(s: yaml, pattern: " fleet:\n runs-on: ubicloud-standard-16-arm") -} - test fn witness_local_proof_requires_host_identity() -> Bool { match deploy_target_proof_from_access(access: ci_deploy_srv1_access) { RunnerIdentityOnHost { host: id } => id == operator_host_srv1 diff --git a/dag/test/claim/ci_deploy_witness_test.dag b/dag/test/claim/ci_deploy_witness_test.dag deleted file mode 100644 index 975341235d8..00000000000 --- a/dag/test/claim/ci_deploy_witness_test.dag +++ /dev/null @@ -1,197 +0,0 @@ -module test.claim.ci_deploy_witness - -import gunbc.ci_spec { - gunbc_ci_spec, - gunbc_ci_deploy_stages, - gunbc_ci_deploy_srv1_stage, - live_deploy_apply_entry, - live_deploy_apply_srv1_wet_function, - gunbc_ci_deploy_invoke, - ci_release_build_line, -} -import v2.workflow.ci_release_build_emit { ci_release_build_script } -import gunbc.ci_deploy_access { - ci_deploy_srv1_access, - deploy_access_is_local_apply, - deploy_access_check, - deploy_access_sudo_miss_reason, - Permit, - Deny, - DeployAccessActor, - gunbc_deploy_sudoers_dropin, - deploy_access_sudoers_line, - srv1_live_deploy_privileged_commands, -} - -import gunbc.fleet_posix_accounts { - FleetAccountCiRunner, - fleet_posix_principal, - grounded_posix_principal_name, -} -import gunbc.ci_workflow { ci_workflow } -import extdeps.github.actions { Step, RunStep, UsesStep } -import gunbc.ci_yaml_emit { expected_ci_yml } -import gunbc.fleet_intent { srv1_host } -import gunbc.host_effect { LocalShell } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data ci_deploy_witness_hermetic_split_note: String = "The observed half of this file (witness_deploy_access_preflight_is_fail_closed, which shells live whoami + sudo -n via deploy_access_check_observed) lives in test.claim.ci_deploy_observed_wet, OFFLINE per the hermetic-floor posture (operator 2026-07-11). This file keeps the hermetic half: pure pins over the deploy spec/script/workflow and the mock-shaped deploy_access_check(access, actor) dual — the dependency-injection exemplar the posture generalizes." - -fn ci_deploy_runner_principal_name() -> String { - grounded_posix_principal_name(p: ci_deploy_srv1_access.principal) as String -} - -test fn witness_deploy_stage_targets_live_deploy_wet() -> Bool { - gunbc_ci_deploy_srv1_stage.entry == live_deploy_apply_entry - && gunbc_ci_deploy_srv1_stage.function == live_deploy_apply_srv1_wet_function - && gunbc_ci_deploy_srv1_stage.needs == ["ci"] -} - -test fn witness_deploy_access_uses_local_apply_on_srv1() -> Bool { - let access = ci_deploy_srv1_access - access.host == srv1_host - && grounded_posix_principal_name(p: access.principal) == "ghrunner" - && deploy_access_is_local_apply(access: access) - && match access.transport { - LocalShell => true - _ => false - } -} - -test fn witness_deploy_access_sudo_miss_surfaces_sudoers_hint() -> Bool { - let actor = DeployAccessActor { - observed_name: fleet_posix_ci_runner_principal().posix.name, - sudo_granted: false, - } - match deploy_access_check(access: ci_deploy_srv1_access, actor: actor) { - Permit => false - Deny { refusal: _ } => - let why = deploy_access_sudo_miss_reason(access: ci_deploy_srv1_access) - string_contains(s: why, pattern: gunbc_deploy_sudoers_dropin) - && string_contains( - s: why, - pattern: deploy_access_sudoers_line( - access: ci_deploy_srv1_access, - cmd: srv1_live_deploy_privileged_commands().first() - ) - ) - } -} - -test fn witness_deploy_access_sudoers_line_authority() -> Bool { - string_contains( - s: deploy_access_sudoers_line( - access: ci_deploy_srv1_access, - cmd: srv1_live_deploy_privileged_commands().first() - ), - pattern: ci_deploy_runner_principal_name() - ) -} - -test fn witness_ci_spec_carries_deploy_stages() -> Bool { - gunbc_ci_spec.deploy_stages == gunbc_ci_deploy_stages -} - -test fn witness_deploy_invoke_runs_gunbc_wet() -> Bool { - let script = gunbc_ci_deploy_invoke(stage: gunbc_ci_deploy_srv1_stage) - string_contains(s: script, pattern: live_deploy_apply_entry) - && string_contains(s: script, pattern: live_deploy_apply_srv1_wet_function) - && string_contains(s: script, pattern: "\"$ROOT/target/release/gunbc\" run") - && string_contains(s: script, pattern: "--source-root \"$ROOT/dag\"") -} - -test fn witness_deploy_invoke_does_not_rebuild_release_bins() -> Bool { - let script = gunbc_ci_deploy_invoke(stage: gunbc_ci_deploy_srv1_stage) - !string_contains(s: script, pattern: ci_release_build_line()) - && !string_contains(s: script, pattern: ci_release_build_script()) - && !string_contains(s: script, pattern: "CARGO_BIN") - && !string_contains(s: script, pattern: "sccache --show-stats") - && !string_contains(s: script, pattern: "CARGO_BUILD_JOBS=1") -} - -// Deploy now runs as a STEP inside the unified `fleet` job (operator consolidation -// 2026-08-10): the job downloads + verifies the release-bins artifact once and the deploy -// step consumes it. The deploy step does not rebuild (asserted directly against the -// invoke script in witness_deploy_invoke_does_not_rebuild_release_bins above). -test fn witness_ci_yml_deploy_job_consumes_release_bins_artifact() -> Bool { - let yaml = expected_ci_yml() - string_contains(s: yaml, pattern: " fleet:") - && string_contains(s: yaml, pattern: " - name: Download release-bins artifact") - && string_contains(s: yaml, pattern: " - name: Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed)") - && string_contains(s: yaml, pattern: " - name: Deploy dashboard to srv1 (live_deploy_apply_srv1_wet)") -} - -test fn witness_ci_yml_deploy_job_serializes_blue_green_cutovers() -> Bool { - let yaml = expected_ci_yml() - string_contains( - s: yaml, - pattern: " concurrency:\n group: srv1-dashboard-deploy\n cancel-in-progress: false" - ) -} - -// The deploy jobs collapsed into ONE `fleet` job (operator consolidation 2026-08-10); -// exactly one fleet job carries the deploy step(s). -test fn witness_workflow_deploy_job_matches_enrollment() -> Bool { - let fleet_jobs = filter(ci_workflow.jobs, j => j.id == "fleet") - length(fleet_jobs) == 1 -} - -// OBSERVATION-UNFUSED-FROM-ACTUATION discriminating control (operator route 2026-08-10, -// CONVERGE acceptance). Two consecutive main pushes hit the cold whole-corpus floor -// over-budget, so the push-gated fleet job skipped every time and collect_fleet_convergence -// (a READ) never ran. The repair admits the collector on workflow_dispatch while keeping -// deploy + advance (the WRITES) push-only. This test REDS if the collector reverts to -// push-only (re-fusing the read to the write gate) OR if either write leaks onto dispatch -// (letting a censored-floor dispatch deploy or advance the desired ref). -fn ci_fleet_step_if_condition(s: Step) -> String { - match s { - RunStep { name: _, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: ifc, continue_on_error: _, timeout_minutes: _ } => - match ifc { Present { value: c } => c, _ => "" } - UsesStep { name: _, id: _, uses: _, with: _, env: _, if_condition: ifc, continue_on_error: _, timeout_minutes: _ } => - match ifc { Present { value: c } => c, _ => "" } - } -} - -fn ci_fleet_step_name(s: Step) -> String { - match s { - RunStep { name: n, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - match n { Present { value: nm } => nm, _ => "" } - UsesStep { name: n, id: _, uses: _, with: _, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - match n { Present { value: nm } => nm, _ => "" } - } -} - -fn ci_fleet_if_for_step_named(needle: String) -> String { - let fleet_steps = filter(ci_workflow.jobs, j => j.id == "fleet").first().steps - fold(fleet_steps, init: "", f: (acc, s) => - if string_contains(s: ci_fleet_step_name(s: s), pattern: needle) { - ci_fleet_step_if_condition(s: s) - } else { - acc - }) -} - -// The READ step and the WRITE steps are deliberately gated differently: collect admits BOTH -// push and workflow_dispatch, while deploy and advance are push-only and never dispatch. A -// dispatchable write is the fused shape this claim exists to refuse. -test fn witness_collector_read_unfused_from_writes() -> Bool { - let collect_if = ci_fleet_if_for_step_named(needle: "Collect fleet converge") - let deploy_if = ci_fleet_if_for_step_named(needle: "Deploy dashboard to srv1") - let advance_if = ci_fleet_if_for_step_named(needle: "Advance refs/fleet/desired") - string_contains(s: collect_if, pattern: "github.event_name == 'push'") - && string_contains(s: collect_if, pattern: "workflow_dispatch") - && string_contains(s: deploy_if, pattern: "github.event_name == 'push'") - && !string_contains(s: deploy_if, pattern: "workflow_dispatch") - && string_contains(s: advance_if, pattern: "github.event_name == 'push'") - && !string_contains(s: advance_if, pattern: "workflow_dispatch") -} - -test fn witness_ci_yml_deploy_job_matches_enrollment() -> Bool { - let yaml = expected_ci_yml() - let enrolled = length(gunbc_ci_deploy_stages) > 0 - string_contains(s: yaml, pattern: " fleet:") - && string_contains(s: yaml, pattern: "Deploy dashboard to srv1 (live_deploy_apply_srv1_wet)") == enrolled - && string_contains(s: yaml, pattern: live_deploy_apply_srv1_wet_function) == enrolled -} diff --git a/dag/test/claim/ci_heal_job_witness_test.dag b/dag/test/claim/ci_heal_job_witness_test.dag deleted file mode 100644 index fc20d9b19d5..00000000000 --- a/dag/test/claim/ci_heal_job_witness_test.dag +++ /dev/null @@ -1,501 +0,0 @@ -module test.claim.ci_heal_job_witness - -import std.dissolution { dissolution_description } - -import v2.std.algebra { list_head, HeadFound, HeadAbsent } -import gunbc.ci_workflow { - ci_workflow, - ci_floor_job_prelude_steps, - ci_regen_job, - ci_heal_generated_artifacts_job, - ci_heal_author_commit_upload_step, - ci_build_job, - ci_job, -} -import extdeps.languages.yaml.types { - YamlKeyValue, YamlValue, - YamlString, YamlNull, YamlBool, YamlInt, YamlFloat, YamlSequence, YamlMapping -} -import gunbc.ci_spec { - ci_heal_generated_artifact_regen_function, - ci_heal_generated_artifact_gate_entry, - ci_heal_dispatch_entry, - ci_heal_author_commit_artifact_dir, - ci_heal_author_commit_artifact_name, - ci_heal_author_commit_artifact_includes_hidden_files, - path_has_hidden_segment, - ci_heal_author_commit_regen_command, - ci_heal_repo_local_git_config_entry, - ci_heal_repo_local_git_config_function, - ci_heal_repo_local_git_config_shell_emit_scaffold, - ci_heal_repo_local_git_config_shell_emit_dissolution_trigger, - gunbc_ci_heal_commit_push_script, - gunbc_ci_heal_repo_local_git_config_invoke, -} -import std.disposition { Scaffold } -import gunbc.generated_artifact { - CiYamlArtifact, FalsifierYamlArtifact, GitignoreArtifact, artifact_path -} -import gunbc.heal_push_plan { - auto_push_eligible_committed_artifact_paths, - author_commit_required_committed_artifact_paths, - live_heal_push_refusal_cause_token -} -import gunbc.ci_heal_credential { - ci_heal_job_permissions, - ci_heal_effective_grant, - ci_heal_branch_ref_expr, - ci_regen_heal_if -} -import gunbc.ci_workflow_expressions { - ci_floor_runs_unless_cancelled_if, - ci_floor_upstream_red_refusal_script -} - -import extdeps.github.actions { - Job, Workflow, WorkflowPermissions, PermissionLevel, PermWrite, PermRead, - WorkflowDispatch, Push, PullRequest, Schedule, WorkflowCall, MergeGroup, WorkflowRunCompleted, - Step, UsesStep, RunStep -} - -data ci_heal_job_witness_note: String = "Green-by-execution proof that the CI auto-heal job is wired correctly, over the actual Job/Workflow model (not a grep). contents_write_is_scoped_to_heal_only pins least privilege. heal_job_needs_build_not_ci prevents heal from depending on ci. heal_commit_scope_is_auto_push_eligible_only: staging is auto_push_eligible_committed_artifact_paths() only — workflow YAML is AuthorCommitRequired and must never be git add'd. heal_workflow_drift_is_author_commit_required: detects drift, packages repair artifact, emits HealAuthorCommitRequired with regen command, never stages workflow paths. heal_author_commit_upload_step_enrolled: upload-artifact publishes heal-author-commit-required/ when workflow drift exists. heal_author_commit_upload_publishes_its_hidden_payload closes the gap that enrollment alone left open: the step being PRESENT was already witnessed while the artifact it published was empty on every run, because upload-artifact excludes hidden paths by default and this artifact's payload is entirely under .github/. Enrollment is not delivery, and only the second test tells them apart. author_commit_required_paths_all_carry_a_hidden_segment pins the premise the derivation rests on, so the day a non-hidden author-commit path is registered the flag stops being unconditionally true by accident. hidden_segment_predicate_discriminates is the RED control: it fixes both polarities on real corpus paths, so broadening the predicate to match every path, or narrowing it to miss a mid-path dot-directory, reds. THE FOUR FLOOR-PREFLIGHT WITNESSES ARE ONE GROUP AND MUST BE READ TOGETHER. floor_job_waits_on_the_heal_preflight pins the dependency so the expensive floor is ordered after the cheap preflights. floor_job_runs_even_when_an_upstream_job_failed pins the condition as !cancelled() and REFUSES BOTH failure() AND success() BY NAME. floor_refuses_an_already_red_branch_before_its_expensive_steps pins that the refusal lives in the prelude, which ci_job composes ahead of the floor step. floor_refusal_tolerates_a_skipped_heal_but_not_a_failed_one pins the asymmetry between heal and its siblings.\n\nWHY failure() IS REFUSED BY NAME, and it is the opposite of what an earlier revision of this witness asserted: the first cut of this change used `!failure() && !cancelled()`, and a review (review 49309) showed that is a fail-open on the only required merge gate. GitHub's troubleshooting-required-status-checks page states that a job skipped by a conditional REPORTS SUCCESS, and the live default-branch ruleset names exactly one required context, ci. So an upstream failure would have skipped ci, ci would have satisfied its own required check by being skipped, and GeneratedArtifactDriftGate would never have run - drift merging while only the non-required heal job was red. The dangerous edit is therefore no longer 'simplify the condition to success()'; it is 'reintroduce failure() into the condition', which reads as a tightening and is in fact the hole. That is what floor_job_runs_even_when_an_upstream_job_failed exists to red on, and why the refusal moved out of the job condition and into an executing first step that exits 1. heal_commit_scope_is_auto_push_eligible_only: staging is auto_push_eligible_committed_artifact_paths() only — workflow YAML is AuthorCommitRequired and must never be git add'd. heal_workflow_drift_is_author_commit_required: detects drift, packages repair artifact, emits HealAuthorCommitRequired with regen command, never stages workflow paths. heal_author_commit_upload_step_enrolled: upload-artifact publishes heal-author-commit-required/ when workflow drift exists." - -fn perm_is_write(p: PermissionLevel) -> Bool { - match p { PermWrite => true _ => false } -} - -fn perm_is_read(p: PermissionLevel) -> Bool { - match p { PermRead => true _ => false } -} - -fn job_contents_is_write(j: Job) -> Bool { - match j.permissions { - Present { value: wp } => - match wp.contents { Present { value: l } => perm_is_write(p: l) Absent => false } - Absent => false - } -} - -fn job_has_no_write(j: Job) -> Bool { - match j.permissions { - Absent => true - Present { value: wp } => - match wp.contents { Present { value: l } => !perm_is_write(p: l) Absent => true } - } -} - -fn job_actions_is_write(j: Job) -> Bool { - match j.permissions { - Present { value: wp } => - match wp.actions { Present { value: l } => perm_is_write(p: l) Absent => false } - Absent => false - } -} - -fn job_has_no_actions_write(j: Job) -> Bool { - match j.permissions { - Absent => true - Present { value: wp } => - match wp.actions { Present { value: l } => !perm_is_write(p: l) Absent => true } - } -} - -fn workflow_contents_is_read(w: Workflow) -> Bool { - match w.permissions { - Present { value: wp } => - match wp.contents { Present { value: l } => perm_is_read(p: l) Absent => false } - Absent => false - } -} - -test fn heal_job_enrolled_in_ci_workflow() -> Bool { - fold(ci_workflow.jobs, init: false, f: (acc, j) => acc || (j.id == "heal_generated_artifacts")) -} - -test fn heal_job_permissions_are_the_grant_authority() -> Bool { - match ci_heal_generated_artifacts_job().permissions { - Present { value: wp } => - (wp == ci_heal_job_permissions) - && (ci_heal_effective_grant.permissions == ci_heal_job_permissions) - && (ci_heal_effective_grant.job.decl_name == "ci_heal_generated_artifacts_job") - && (ci_heal_effective_grant.workflow.module_path == "gunbc.ci_workflow") - Absent => false - } -} - -test fn heal_job_needs_build_not_ci() -> Bool { - ci_heal_generated_artifacts_job().needs == ["build"] -} - -test fn floor_job_waits_on_the_heal_preflight() -> Bool { - any(ci_job().needs, n => n == "heal_generated_artifacts") - && any(ci_job().needs, n => n == "build") - && any(ci_job().needs, n => n == "regen") -} - -test fn floor_job_runs_even_when_an_upstream_job_failed() -> Bool { - match ci_job().if_condition { - Present { value: s } => - (s == ci_floor_runs_unless_cancelled_if) - && string_contains(s: s, pattern: "!cancelled()") - && !string_contains(s: s, pattern: "failure()") - && !string_contains(s: s, pattern: "success()") - Absent => false - } -} - -fn step_is_the_upstream_red_refusal(s: Step) -> Bool { - match s { - RunStep { name: _, id: _, run: r, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - r == ci_floor_upstream_red_refusal_script - UsesStep { name: _, id: _, uses: _, with: _, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - } -} - -test fn floor_refusal_is_exactly_the_first_step() -> Bool { - match list_head(xs: ci_job().steps) { - HeadFound { value: head } => step_is_the_upstream_red_refusal(s: head) - HeadAbsent => false - } -} - -test fn floor_refuses_an_already_red_branch_before_its_expensive_steps() -> Bool { - fold(ci_job().steps, init: false, f: (found, s) => found || step_is_the_upstream_red_refusal(s: s)) - && string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "needs.build.result") - && string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "needs.regen.result") - && string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "needs.heal_generated_artifacts.result") - && string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "FloorUpstreamAlreadyRed") - && string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "exit 1") -} - -test fn floor_refusal_reaches_only_the_job_whose_needs_it_names() -> Bool { - !fold(ci_regen_job().steps, init: false, f: (found, s) => found || step_is_the_upstream_red_refusal(s: s)) - && !fold(ci_build_job().steps, init: false, f: (found, s) => found || step_is_the_upstream_red_refusal(s: s)) - && !fold(ci_heal_generated_artifacts_job().steps, init: false, f: (found, s) => found || step_is_the_upstream_red_refusal(s: s)) - && !fold(ci_floor_job_prelude_steps(), init: false, f: (found, s) => found || step_is_the_upstream_red_refusal(s: s)) -} - -test fn floor_refusal_tolerates_a_skipped_heal_but_not_a_failed_one() -> Bool { - string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "\"$HEAL\" = \"failure\"") - && !string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "\"$HEAL\" != \"success\"") - && string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "\"$BUILD\" != \"success\"") - && string_contains(s: ci_floor_upstream_red_refusal_script, pattern: "\"$REGEN\" != \"success\"") -} - -test fn heal_job_runs_on_pr_only() -> Bool { - match ci_heal_generated_artifacts_job().if_condition { - Present { value: s } => - (s == ci_regen_heal_if) - && string_contains(s: s, pattern: "pull_request") - && !string_contains(s: s, pattern: "push") - Absent => false - } -} - -test fn heal_job_has_scoped_contents_write() -> Bool { - job_contents_is_write(j: ci_heal_generated_artifacts_job()) -} - -test fn contents_write_is_scoped_to_heal_only() -> Bool { - workflow_contents_is_read(w: ci_workflow) - && job_has_no_write(j: ci_build_job()) - && job_has_no_write(j: ci_job()) - && job_contents_is_write(j: ci_heal_generated_artifacts_job()) -} - -test fn actions_write_is_scoped_to_heal_only() -> Bool { - job_has_no_actions_write(j: ci_build_job()) - && job_has_no_actions_write(j: ci_job()) - && job_actions_is_write(j: ci_heal_generated_artifacts_job()) -} - -test fn workflow_dispatch_carries_optional_exact_healed_sha_input() -> Bool { - fold(ci_workflow.on, init: false, f: fn(acc, trigger) { - acc || match trigger { - WorkflowDispatch { inputs } => - fold(inputs, init: false, f: fn(found, row) { - found || (row.name == "expected_healed_sha" && !row.required) - }) - Push { branches: _, paths: _ } => false - PullRequest { branches: _, types: _ } => false - Schedule { cron: _ } => false - WorkflowCall { inputs: _ } => false - WorkflowRunCompleted { workflows: _ } => false - MergeGroup => false - } - }) -} - -test fn heal_regen_targets_generated_artifact_main_wet() -> Bool { - (ci_heal_generated_artifact_regen_function == "main_wet") - && (ci_heal_generated_artifact_gate_entry == "dag/tools/generated_artifact_gate.dag") -} - -test fn heal_converges_repo_local_git_config() -> Bool { - (ci_heal_repo_local_git_config_function == "converge") - && (ci_heal_repo_local_git_config_entry == "dag/gunbc/repo_local_git_config.dag") - && string_contains( - s: gunbc_ci_heal_repo_local_git_config_invoke(), - pattern: dissolution_description(condition: ci_heal_repo_local_git_config_shell_emit_dissolution_trigger) - ) - && string_contains( - s: gunbc_ci_heal_repo_local_git_config_invoke(), - pattern: "repo_local_git_config.dag" - ) - && string_contains( - s: gunbc_ci_heal_repo_local_git_config_invoke(), - pattern: "--function converge" - ) -} - -test fn heal_repo_local_git_config_shell_emit_is_scaffold() -> Bool { - match ci_heal_repo_local_git_config_shell_emit_scaffold { - Scaffold { dissolves_to: _, bind: _ } => true - _ => false - } -} - -test fn heal_commit_scope_is_auto_push_eligible_only() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - string_contains(s: script, pattern: concat("git add \"", artifact_path(a: GitignoreArtifact))) - && !string_contains(s: script, pattern: concat("git add \"", artifact_path(a: CiYamlArtifact))) - && !string_contains(s: script, pattern: concat("git add \"", artifact_path(a: FalsifierYamlArtifact))) - && string_contains(s: script, pattern: "git diff --cached --quiet") - && !string_contains(s: script, pattern: "git add -A") - && (count(auto_push_eligible_committed_artifact_paths()) > 0) - && (count(author_commit_required_committed_artifact_paths()) == 3) -} - -// The packaging diagnostic must be reachable. GitHub runs `run:` under -// `bash -eo pipefail`, so a post-hoc `[ ! -e ]` check after `cp` is dead in both -// directions: cp failing aborts the script first, cp succeeding leaves the file -// present. The typed diagnostic therefore has to hang off the failing command. -test fn heal_bundle_incompleteness_diagnostic_is_reachable() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - string_contains(s: script, pattern: "if ! cp \"$p\" \"") - && string_contains(s: script, pattern: "if ! mkdir -p \"") - && string_contains(s: script, pattern: "::error::HealRepairBundleIncomplete path=$p") - && !string_contains(s: script, pattern: "if [ ! -e \"") -} - -test fn heal_git_add_is_existence_guarded() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - string_contains(s: script, pattern: concat("if [ -e \"", artifact_path(a: GitignoreArtifact))) - && string_contains(s: script, pattern: "not staging:") -} - -test fn heal_workflow_drift_is_author_commit_required() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - string_contains(s: script, pattern: "HealAuthorCommitRequired") - && string_contains(s: script, pattern: concat("cause=", live_heal_push_refusal_cause_token())) - && !string_contains(s: script, pattern: "GitHubAppLacksWorkflowsWrite") - && string_contains(s: script, pattern: ci_heal_author_commit_regen_command) - && string_contains(s: script, pattern: concat("git diff --quiet -- \"", artifact_path(a: CiYamlArtifact))) - && string_contains(s: script, pattern: concat("git diff --quiet -- \"", artifact_path(a: FalsifierYamlArtifact))) - && string_contains(s: script, pattern: "AUTHOR_COMMIT_DRIFT=") - && string_contains(s: script, pattern: ci_heal_author_commit_artifact_dir) -} - -fn step_uploads_author_commit_artifact(s: Step) -> Bool { - match s { - UsesStep { name: _, id: _, uses: _, with: w, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - match w { - Present { value: kvs } => - fold(kvs, init: false, f: fn(found, row) { - found || (row.key == "name" && match row.value { - YamlString { value: v } => v == ci_heal_author_commit_artifact_name - YamlNull => false - YamlBool { value: _ } => false - YamlInt { lexeme: _ } => false - YamlFloat { lexeme: _ } => false - YamlSequence { elements: _ } => false - YamlMapping { entries: _ } => false - }) - }) - Absent => false - } - RunStep { name: _, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - } -} - -fn step_with_value(s: Step, key: NonEmptyStr) -> YamlValue? { - match s { - RunStep { name: _, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => none - UsesStep { name: _, id: _, uses: _, with: w, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - match w { - Absent => none - Present { value: rows } => fold(rows, init: none, f: fn(found, row) { - match found { - Present { value: v } => Present { value: v } - Absent => if row.key == key { Present { value: row.value } } else { none } - } - }) - } - } -} - -// Complements the sibling hidden-payload witnesses rather than restating them: -// they pin that the flag is TRUE, this pins that the emitted flag equals the -// derivation. A hardcoded `true` passes theirs and reds here the day the roster -// gains a non-hidden path — which is the construction property the derivation -// exists to buy. The predicate's own polarities are hidden_segment_predicate_discriminates. -test fn heal_author_commit_upload_includes_hidden_workflow_files() -> Bool { - let paths = author_commit_required_committed_artifact_paths() - (count(paths) > 0) - && match step_with_value(s: ci_heal_author_commit_upload_step(), key: "include-hidden-files") { - Present { value: v } => match v { - YamlBool { value: b } => b == ci_heal_author_commit_artifact_includes_hidden_files() - _ => false - } - Absent => false - } - && match step_with_value(s: ci_heal_author_commit_upload_step(), key: "path") { - Present { value: v } => match v { - YamlString { value: d } => d == ci_heal_author_commit_artifact_dir - _ => false - } - Absent => false - } -} - -test fn heal_author_commit_upload_step_enrolled() -> Bool { - fold(ci_heal_generated_artifacts_job().steps, init: false, f: fn(found, step) { - found || step_uploads_author_commit_artifact(s: step) - }) -} - -fn step_kv_bool_is_true(s: Step, key: String) -> Bool { - match s { - UsesStep { name: _, id: _, uses: _, with: w, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - match w { - Present { value: kvs } => - fold(kvs, init: false, f: fn(found, row) { - found || (row.key == key && match row.value { - YamlBool { value: v } => v - YamlString { value: _ } => false - YamlNull => false - YamlInt { lexeme: _ } => false - YamlFloat { lexeme: _ } => false - YamlSequence { elements: _ } => false - YamlMapping { entries: _ } => false - }) - }) - Absent => false - } - RunStep { name: _, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - } -} - -test fn heal_author_commit_upload_publishes_its_hidden_payload() -> Bool { - fold(ci_heal_generated_artifacts_job().steps, init: false, f: fn(found, step) { - found || (step_uploads_author_commit_artifact(s: step) - && step_kv_bool_is_true(s: step, key: "include-hidden-files")) - }) -} - -test fn author_commit_required_paths_all_carry_a_hidden_segment() -> Bool { - all(author_commit_required_committed_artifact_paths(), p => path_has_hidden_segment(path: p)) - && ci_heal_author_commit_artifact_includes_hidden_files() -} - -test fn hidden_segment_predicate_discriminates() -> Bool { - path_has_hidden_segment(path: ".github/workflows/ci.yml") - && path_has_hidden_segment(path: ".github/workflows/falsifier.yml") - && path_has_hidden_segment(path: ".github/workflows/fleet-converge.yml") - && path_has_hidden_segment(path: "a/.hidden/b") - && !path_has_hidden_segment(path: "release-bins.tgz") - && !path_has_hidden_segment(path: "target/floor-component-receipt.json") - && !path_has_hidden_segment(path: "docs/plans/idea-machine.md") -} - -test fn heal_push_targets_triggering_branch() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - string_contains(s: script, pattern: "git -c core.hooksPath= push origin HEAD:${{ github.head_ref || github.ref_name }}") - && !string_contains(s: script, pattern: "git push origin HEAD:main") -} - -test fn heal_produced_dispatches_and_supersedes_old_run() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - (ci_heal_dispatch_entry == "dag/tools/ci_heal_dispatch.dag") - && string_contains(s: script, pattern: "PRIOR_HEAD=$(git rev-parse HEAD)") - && string_contains(s: script, pattern: "HEALED_HEAD=$(git rev-parse HEAD)") - && string_contains(s: script, pattern: "GUNBC_HEALED_HEAD=\"$HEALED_HEAD\"") - && string_contains(s: script, pattern: "SupersededByHealedHead") - && string_contains(s: script, pattern: "revalidation-required") - && string_contains(s: script, pattern: "exit 1") -} - -test fn dispatch_failure_is_loud_and_has_no_push_event_fallback() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - string_contains(s: script, pattern: "HealDispatchRefused") - && string_contains(s: script, pattern: "CreateWorkflowDispatchFailed") - && !string_contains(s: script, pattern: "workflow will be triggered by push") -} - -fn yaml_value_is_github_token_context(v: YamlValue) -> Bool { - match v { - YamlString { value: s } => s == "${{ github.token }}" - YamlNull => false - YamlBool { value: _ } => false - YamlInt { lexeme: _ } => false - YamlFloat { lexeme: _ } => false - YamlSequence { elements: _ } => false - YamlMapping { entries: _ } => false - } -} - -fn env_binds_github_token(kvs: List) -> Bool { - fold(kvs, init: false, f: (found, row) => - found || (row.key == "GITHUB_TOKEN" && yaml_value_is_github_token_context(v: row.value))) -} - -fn dispatch_step_binds_github_token(s: Step) -> Bool { - match s { - UsesStep { name: _, id: _, uses: _, with: _, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - RunStep { name: _, id: _, run, shell: _, env, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - run == gunbc_ci_heal_commit_push_script() && match env { - Present { value: kvs } => env_binds_github_token(kvs: kvs) - Absent => false - } - } -} - -test fn heal_dispatch_step_exports_github_token_authority() -> Bool { - fold( - ci_heal_generated_artifacts_job().steps, - init: false, - f: (found, step) => found || dispatch_step_binds_github_token(s: step) - ) -} - -fn yaml_value_is_branch_ref(v: YamlValue) -> Bool { - match v { - YamlString { value: s } => s == ci_heal_branch_ref_expr - YamlNull => false - YamlBool { value: _ } => false - YamlInt { lexeme: _ } => false - YamlFloat { lexeme: _ } => false - YamlSequence { elements: _ } => false - YamlMapping { entries: _ } => false - } -} - -fn kvs_have_branch_ref(kvs: List) -> Bool { - fold(kvs, init: false, f: (acc, kv) => - acc || (kv.key == "ref" && yaml_value_is_branch_ref(v: kv.value))) -} - -fn step_checks_out_branch(s: Step) -> Bool { - match s { - UsesStep { name: _, id: _, uses: _, with: w, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - match w { - Present { value: kvs } => kvs_have_branch_ref(kvs: kvs) - Absent => false - } - RunStep { name: _, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - } -} - -test fn heal_checks_out_triggering_branch() -> Bool { - fold(ci_heal_generated_artifacts_job().steps, init: false, f: (acc, s) => acc || step_checks_out_branch(s: s)) -} diff --git a/dag/test/claim/ci_materialization_witness_test.dag b/dag/test/claim/ci_materialization_witness_test.dag deleted file mode 100644 index b22d5466d80..00000000000 --- a/dag/test/claim/ci_materialization_witness_test.dag +++ /dev/null @@ -1,30 +0,0 @@ -module test.claim.ci_materialization_witness - -import std.types { Bool, String } -import gunbc.ci_materialization { ci_catalog_eligibility_refusals } -import gunbc.ci_materialization_gate { - ci_materialization_ladder_holds_live, - ci_materialization_holds_without_sccache, - ci_heal_revalidation_preflight_is_fresh_effect, -} -import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree } - -data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree - -data ci_materialization_witness_note: String = "Behavioral materialization-ladder witnesses over the LIVE emitted workflow (operator, 2026-07-08: see-it-working in the same pipeline the redundancy is paid in). The tautological step-count / demand-count pins (uses==N, run==N, prelude==3, exempt-fresh>=1, single-recompute demand==1) were DELETED 2026-07-15 per operator directive: they asserted calibrated magic numbers that reddened on any benign workflow edit (e.g. re-enrolling the srv1 deploy job) without testing behavior. The discriminating duplication->refusal RED control lives in src/v2/test/claim/duplicate_computation/placement_grain_witness_test.dag; the ladder property itself is exercised behaviorally below." - -test fn ci_ladder_holds_on_live_workflow() -> Bool { - ci_materialization_ladder_holds_live() -} - -test fn ci_ladder_holds_without_sccache_single_build() -> Bool { - ci_materialization_holds_without_sccache() -} - -test fn ci_sccache_is_eligible_for_the_capacity_bounded_role() -> Bool { - ci_catalog_eligibility_refusals() == 0 -} - -test fn ci_heal_revalidation_preflight_is_a_fresh_checkout_observation() -> Bool { - ci_heal_revalidation_preflight_is_fresh_effect() -} diff --git a/dag/test/claim/ci_native_cache_root_witness_test.dag b/dag/test/claim/ci_native_cache_root_witness_test.dag deleted file mode 100644 index 4e528ccafa8..00000000000 --- a/dag/test/claim/ci_native_cache_root_witness_test.dag +++ /dev/null @@ -1,81 +0,0 @@ -module test.claim.ci_native_cache_root_witness - -import std.dissolution { dissolution_description } - -import gunbc.ci_workflow { - ci_native_cache_prelude_order_bridge, - ci_cargo_build_jobs_count -} -import gunbc.ci_yaml_emit { expected_ci_yml } -import gunbc.falsifier_workflow { expected_falsifier_yml } -import v2.workflow.ci_workflow_run_emit { - ci_isolate_toolchain_script, - ci_native_cache_root_script, - ci_native_cache_fabricated_segment_literal, - ci_native_cache_segment_script_refuses_fabrication, - ci_isolate_toolchain_script_excludes_segment_derivation, - ci_native_cache_root_shell_emit_scaffold, - ci_native_cache_root_shell_emit_dissolution_trigger -} -import std.disposition { Scaffold, Terminal } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data ci_native_cache_root_witness_note: String = "Discriminating witnesses for the toolchain-segment reorder+refuse fix (operator 2026-07-29): the isolate prelude must NOT derive GUNBC_TOOLCHAIN_SEG from ambient rustc (that either fabricates toolchain-unresolved or silently keys on the wrong toolchain); the dedicated native-cache step after setup-rust-toolchain must refuse on rustc -V failure. RED controls perturb the good emission with the retired fabrication literal so a regression re-opens the absorbing fallback. Prelude ordering: witness_prelude_native_cache_root_step_follows_setup_rust uses ci_native_cache_prelude_order_bridge_note — adjacency proxy, safe-direction brittleness only." - -test fn witness_isolate_emission_excludes_segment_derivation() -> Bool { - ci_isolate_toolchain_script_excludes_segment_derivation( - isolate_script: ci_isolate_toolchain_script(build_jobs_count: ci_cargo_build_jobs_count()) - ) -} - -test fn witness_native_cache_root_emission_refuses_fabrication() -> Bool { - ci_native_cache_segment_script_refuses_fabrication( - script: ci_native_cache_root_script() - ) -} - -test fn witness_native_cache_root_fabrication_literal_red_control() -> Bool { - let good = ci_native_cache_root_script() - let bad = concat(good, concat("\n", concat("GUNBC_TOOLCHAIN_SEG=", ci_native_cache_fabricated_segment_literal))) - ci_native_cache_segment_script_refuses_fabrication(script: good) && - !ci_native_cache_segment_script_refuses_fabrication(script: bad) -} - -test fn witness_prelude_native_cache_root_step_follows_setup_rust() -> Bool { - let bridge = ci_native_cache_prelude_order_bridge() - string_contains(s: expected_ci_yml(), pattern: bridge) && - string_contains(s: expected_falsifier_yml(), pattern: bridge) -} - -test fn witness_emitted_workflows_exclude_fabricated_segment_literal() -> Bool { - !string_contains(s: expected_ci_yml(), pattern: ci_native_cache_fabricated_segment_literal) && - !string_contains(s: expected_falsifier_yml(), pattern: ci_native_cache_fabricated_segment_literal) && - string_contains( - s: expected_ci_yml(), - pattern: "Derive native-cache root (rustc-version segment; after setup-rust-toolchain)" - ) && - string_contains( - s: expected_falsifier_yml(), - pattern: "Derive native-cache root (rustc-version segment; after setup-rust-toolchain)" - ) -} - -test fn witness_native_cache_root_emission_carries_dissolve_marker() -> Bool { - string_contains(s: ci_native_cache_root_script(), pattern: dissolution_description(condition: ci_native_cache_root_shell_emit_dissolution_trigger)) -} - -test fn witness_native_cache_root_shell_emit_is_scaffold_holds() -> Bool { - match ci_native_cache_root_shell_emit_scaffold { - Scaffold { dissolves_to: _, bind: _ } => true - Terminal { reason: _ } => false - } -} - -test fn witness_emitted_workflows_refuse_missing_segment_red_control() -> Bool { - let good = expected_ci_yml() - let bad = concat(good, ci_native_cache_fabricated_segment_literal) - !string_contains(s: good, pattern: ci_native_cache_fabricated_segment_literal) && - string_contains(s: bad, pattern: ci_native_cache_fabricated_segment_literal) -} diff --git a/dag/test/claim/ci_release_bins_witness_test.dag b/dag/test/claim/ci_release_bins_witness_test.dag deleted file mode 100644 index 0f0787c3f4c..00000000000 --- a/dag/test/claim/ci_release_bins_witness_test.dag +++ /dev/null @@ -1,80 +0,0 @@ -module test.claim.ci_release_bins_witness - -import gunbc.ci_release_bins { - ci_floor_invoked_bins, - witness_declared_release_bins, - ci_floor_required_artifact_names, - release_bin_is_enrolled, - release_bin_list_contains -} -import gunbc.ci_spec { ci_release_build_line } -import gunbc.ci_yaml_emit { expected_ci_yml } -import gunbc.falsifier_workflow { expected_falsifier_yml } -import tools.host_prelude { - witness_bin, - witness_bin_ensure_built_typed, - WitnessBinReady, - WitnessBinRefused, - WitnessBinNotEnrolled -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data ci_release_bins_witness_note: String = "Authority: gunbc.ci_release_bins. Pack membership is derived (floor ∪ witness-declared). Positives: measured gap bins cssl_assemble / frontier_probe_survey are enrolled and appear on the build line. Retirement negative: compile_clean_floor_skip_witness is absent from the roster, release build line, and both generated workflows. RED: no_such_witness_bin_zzz is NOT enrolled, and ensure_built refuses WitnessBinNotEnrolled without cargo (construction wall). Per-claim test fns (no AND-umbrella; #7287 pattern)." - -test fn witness_pack_includes_every_floor_invoked() -> Bool { - fold( - ci_floor_invoked_bins, - init: true, - f: (ok, name) => ok && release_bin_list_contains(xs: ci_floor_required_artifact_names(), needle: name) - ) -} - -test fn witness_pack_includes_every_witness_declared() -> Bool { - fold( - witness_declared_release_bins, - init: true, - f: (ok, name) => ok && release_bin_list_contains(xs: ci_floor_required_artifact_names(), needle: name) - ) -} - -test fn witness_measured_gap_bins_enrolled() -> Bool { - release_bin_is_enrolled(bin_name: "cssl_assemble") - && release_bin_is_enrolled(bin_name: "frontier_probe_survey") -} - -test fn witness_build_line_carries_gap_bins() -> Bool { - let line = ci_release_build_line() - string_contains(s: line, pattern: "--bin cssl_assemble") - && string_contains(s: line, pattern: "--bin frontier_probe_survey") - && string_contains(s: line, pattern: "--bin claim_executor") -} - -test fn witness_negative_control_not_enrolled() -> Bool { - !release_bin_is_enrolled(bin_name: "no_such_witness_bin_zzz") -} - -test fn witness_retired_floor_skip_bin_absent_from_release_projections() -> Bool { - let retired = "compile_clean_floor_skip_witness" - !release_bin_is_enrolled(bin_name: retired) - && !string_contains(s: ci_release_build_line(), pattern: retired) - && !string_contains(s: expected_ci_yml(), pattern: retired) - && !string_contains(s: expected_falsifier_yml(), pattern: retired) -} - -test fn witness_unenrolled_ensure_built_refuses_not_enrolled() -> Bool { - let readiness = witness_bin_ensure_built_typed( - root: "/tmp", - bin: witness_bin(var_name: "NO_SUCH", bin_name: "no_such_witness_bin_zzz") - ) - match readiness { - WitnessBinReady { path: _ } => false - WitnessBinRefused { bin_name: name, path: _, reason: reason } => - name == "no_such_witness_bin_zzz" && reason == WitnessBinNotEnrolled - } -} - -test fn witness_pack_count_floor() -> Bool { - ci_floor_required_artifact_names().length() >= 19 -} diff --git a/dag/test/claim/ci_runner_seam_witness_test.dag b/dag/test/claim/ci_runner_seam_witness_test.dag deleted file mode 100644 index 1b906253732..00000000000 --- a/dag/test/claim/ci_runner_seam_witness_test.dag +++ /dev/null @@ -1,33 +0,0 @@ -module test.claim.ci_runner_seam_witness - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -test fn witness_ci_runner_spec_derives_from_fleet_offer() -> Bool { - gunbc_ci_runner_spec() == runner_spec_from_offer(offer: gunbc_ci_fleet_offer) -} - -test fn witness_ci_workflow_runner_matches_selected_target() -> Bool { - ci_workflow.jobs.first().runner == gunbc_ci_selected_runner_spec() -} - -test fn witness_ci_yaml_runs_on_projects_selected_labels() -> Bool { - let yaml = expected_ci_yml() - string_contains(s: yaml, pattern: " runs-on: [self-hosted, linux, arm64]") - && !string_contains(s: yaml, pattern: " runs-on: [ubicloud-standard-16-arm]") -} - -test fn witness_ci_runner_spec_is_self_hosted_arm64_linux() -> Bool { - match gunbc_ci_runner_spec() { - SelfHosted { labels: ls } => - ls.length() == 3 - && ls.first() == "self-hosted" - && ls.skip(n: 1).first() == "linux" - && ls.skip(n: 2).first() == "arm64" - _ => false - } -} - -test fn witness_selected_target_is_operator_fleet_routing() -> Bool { - gunbc_ci_selected_runner_spec() == gunbc_ci_runner_spec() -} - diff --git a/dag/test/claim/ci_stage0_partition_compile_gate_witness_test.dag b/dag/test/claim/ci_stage0_partition_compile_gate_witness_test.dag deleted file mode 100644 index ea5a5228563..00000000000 --- a/dag/test/claim/ci_stage0_partition_compile_gate_witness_test.dag +++ /dev/null @@ -1,119 +0,0 @@ -module test.claim.ci_stage0_partition_compile_gate_witness - -import gunbc.ci_workflow { ci_build_job } -import extdeps.github.actions { RunStep, UsesStep } -import v2.std.effect_plan { Do, EffectPlan } -import v2.std.operation_argv { - OperationRef, - operation_argv_bind_text_list -} -import v2.std.orchestration { FailFast } -import v2.workflow.ci_stage0_partition_compile_gate_emit { - ci_stage0_partition_compile_gate_extra_args, - ci_stage0_partition_compile_gate_intent, - ci_stage0_partition_compile_gate_package_count_holds, - ci_stage0_partition_compile_gate_refusal_prefix, - ci_stage0_partition_compile_gate_render, - ci_stage0_partition_compile_gate_script, - ci_stage0_partition_compile_gate_shell_emit_dissolution_trigger, - ci_stage0_partition_compile_gate_shell_emit_scaffold, -} -import v2.workflow.effect_plan_bash_materialize { - BashBoundOperationInvocation, - EffectPlanBashMaterializationRefused, - EffectPlanBashMaterialized, - bash_bind_operation_invocation, - effect_plan_bash_materialize -} -import std.disposition { Scaffold } -import std.dissolution { dissolution_description } - -fn gate_materialized_render(plan: EffectPlan) -> String { - ci_stage0_partition_compile_gate_render(plan: plan) -} - -fn gate_plan_refuses(plan: EffectPlan) -> Bool { - match effect_plan_bash_materialize(plan: plan) { - EffectPlanBashMaterialized { source: _ } => false - EffectPlanBashMaterializationRefused { refusal: _ } => true - } -} - -test fn w_stage0_partition_gate_package_count_holds() -> Bool { - ci_stage0_partition_compile_gate_package_count_holds() -} - -test fn w_stage0_partition_gate_script_names_all_seven_packages() -> Bool { - let script = ci_stage0_partition_compile_gate_script() - string_contains(s: script, pattern: "v1-stage0-runtime") - && string_contains(s: script, pattern: "v1-stage0-std-core") - && string_contains(s: script, pattern: "v1-stage0-std-surface") - && string_contains(s: script, pattern: "v1-stage0-extdeps-languages") - && string_contains(s: script, pattern: "v1-stage0-v1-infer") - && string_contains(s: script, pattern: "v1-stage0-v1-artifact") - && string_contains(s: script, pattern: "v1-stage0-emit-core") -} - -test fn w_stage0_partition_gate_shell_emit_is_scaffold_holds() -> Bool { - match ci_stage0_partition_compile_gate_shell_emit_scaffold { - Scaffold { dissolves_to: _, bind: _ } => true - _ => false - } -} - -test fn w_stage0_partition_gate_emit_carries_dissolve_marker_holds() -> Bool { - string_contains( - s: ci_stage0_partition_compile_gate_script(), - pattern: "🟡 dissolve-on: ci_stage0_partition_compile_gate_script" - ) -} - -test fn w_stage0_partition_gate_script_is_typed_plan_plus_marker() -> Bool { - let expected = concat( - concat( - "# ", - concat(dissolution_description(condition: ci_stage0_partition_compile_gate_shell_emit_dissolution_trigger), "\n") - ), - concat( - gate_materialized_render(plan: ci_stage0_partition_compile_gate_intent()), - "\n" - ) - ) - ci_stage0_partition_compile_gate_script() == expected -} - -test fn w_build_job_enrolls_stage0_partition_compile_gate_holds() -> Bool { - fold(ci_build_job().steps, init: false, f: (acc, step) => { - acc || match step { - RunStep { name: _, id: _, run: cmd, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - string_contains(s: cmd, pattern: "v1-stage0-runtime") - && string_contains(s: cmd, pattern: "v1-stage0-emit-core") - UsesStep { name: _, id: _, uses: _, with: _, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - } - }) -} - -test fn w_stage0_partition_gate_RED_missing_operation_refuses() -> Bool { - let bad_step = bash_bind_operation_invocation( - at: OperationRef { - path: "dag/extdeps/rust/cargo_build.dag", - service: "cargo.Build", - operation: "NoSuchCheck" - }, - bindings: [ - operation_argv_bind_text_list( - name: "extra_args", - items: ci_stage0_partition_compile_gate_extra_args(package_name: "v1-stage0-runtime") - ) - ] - ) - let refused_plan = EffectPlan { - steps: [Do { effect: bad_step }], - on_failure: FailFast - } - gate_plan_refuses(plan: refused_plan) - && string_contains( - s: gate_materialized_render(plan: refused_plan), - pattern: ci_stage0_partition_compile_gate_refusal_prefix - ) -} diff --git a/dag/test/claim/ci_v1_compiler_test_targets_compile_gate_witness_test.dag b/dag/test/claim/ci_v1_compiler_test_targets_compile_gate_witness_test.dag deleted file mode 100644 index ee66c46a448..00000000000 --- a/dag/test/claim/ci_v1_compiler_test_targets_compile_gate_witness_test.dag +++ /dev/null @@ -1,121 +0,0 @@ -module test.claim.ci_v1_compiler_test_targets_compile_gate_witness - -import gunbc.ci_workflow { ci_build_job } -import extdeps.github.actions { RunStep, UsesStep } -import v2.std.effect_plan { Do, EffectPlan } -import v2.std.operation_argv { - OperationRef, - operation_argv_bind_text_list -} -import v2.std.orchestration { FailFast } -import v2.workflow.ci_v1_compiler_test_targets_compile_gate_emit { - ci_v1_compiler_test_targets_compile_gate_extra_args, - ci_v1_compiler_test_targets_compile_gate_intent, - ci_v1_compiler_test_targets_compile_gate_package, - ci_v1_compiler_test_targets_compile_gate_refusal_prefix, - ci_v1_compiler_test_targets_compile_gate_render, - ci_v1_compiler_test_targets_compile_gate_script, - ci_v1_compiler_test_targets_compile_gate_shell_emit_dissolution_trigger, - ci_v1_compiler_test_targets_compile_gate_shell_emit_scaffold, -} -import v2.workflow.effect_plan_bash_materialize { - BashBoundOperationInvocation, - EffectPlanBashMaterializationRefused, - EffectPlanBashMaterialized, - bash_bind_operation_invocation, - effect_plan_bash_materialize -} -import std.disposition { Scaffold } -import std.dissolution { dissolution_description } - -data witness_subject_note: String = "Pins the v1-compiler test-targets compile gate the way its siblings are pinned (test.claim.ci_stage0_partition_compile_gate_witness, test.claim.ci_v1_compiler_tests_compile_gate_witness): the emitted argv, the scaffold disposition, the dissolve marker, the exact plan-plus-marker composition, build-job enrollment, and a RED refusal. Added on review of gunbc#8191, which enrolled the gate while pinning only the backstop sum — a new enrolled gate whose emitted script nothing asserts is DESIGN 5 specification-without-execution, and the reviewer was right that the sum alone does not establish the gate emits what it claims. - -WHY THE ARGV IS PINNED TOKEN-BY-TOKEN AND NOT AS ONE STRING: the three tokens carry three separable facts that can each rot independently. `check` is the compile-only operation, and losing it to `test` would silently convert this gate into the execution gate the standing nextest ruling rejects. `-p v1-compiler` is the scope, and widening it to the workspace would re-check what the partition gate already covers. `--all-targets` is the ONLY reason the gate sees test targets at all — drop it and the step still passes, still looks enrolled, and covers exactly the population that was uncovered before this gate existed. That last case is the one a single-string assertion would miss most quietly, so each token gets its own conjunct." - -fn gate_materialized_render(plan: EffectPlan) -> String { - ci_v1_compiler_test_targets_compile_gate_render(plan: plan) -} - -fn gate_plan_refuses(plan: EffectPlan) -> Bool { - match effect_plan_bash_materialize(plan: plan) { - EffectPlanBashMaterialized { source: _ } => false - EffectPlanBashMaterializationRefused { refusal: _ } => true - } -} - -test fn w_v1_compiler_test_targets_gate_script_carries_check_scope_and_all_targets() -> Bool { - let script = ci_v1_compiler_test_targets_compile_gate_script() - string_contains(s: script, pattern: "check") - && string_contains(s: script, pattern: ci_v1_compiler_test_targets_compile_gate_package) - && string_contains(s: script, pattern: "--all-targets") -} - -test fn w_v1_compiler_test_targets_gate_extra_args_are_exactly_scope_then_all_targets() -> Bool { - let actual = ci_v1_compiler_test_targets_compile_gate_extra_args() - let expected = ["-p", ci_v1_compiler_test_targets_compile_gate_package, "--all-targets"] - actual == expected -} - -test fn w_v1_compiler_test_targets_gate_shell_emit_is_scaffold_holds() -> Bool { - match ci_v1_compiler_test_targets_compile_gate_shell_emit_scaffold { - Scaffold { dissolves_to: _, bind: _ } => true - _ => false - } -} - -test fn w_v1_compiler_test_targets_gate_emit_carries_dissolve_marker_holds() -> Bool { - string_contains( - s: ci_v1_compiler_test_targets_compile_gate_script(), - pattern: "🟡 dissolve-on: ci_v1_compiler_test_targets_compile_gate_script" - ) -} - -test fn w_v1_compiler_test_targets_gate_script_is_typed_plan_plus_marker() -> Bool { - let expected = concat( - concat( - "# ", - concat(dissolution_description(condition: ci_v1_compiler_test_targets_compile_gate_shell_emit_dissolution_trigger), "\n") - ), - concat( - gate_materialized_render(plan: ci_v1_compiler_test_targets_compile_gate_intent()), - "\n" - ) - ) - ci_v1_compiler_test_targets_compile_gate_script() == expected -} - -test fn w_build_job_enrolls_v1_compiler_test_targets_compile_gate_holds() -> Bool { - fold(ci_build_job().steps, init: false, f: (acc, step) => { - acc || match step { - RunStep { name: _, id: _, run: cmd, shell: _, env: _, working_directory: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => - string_contains(s: cmd, pattern: ci_v1_compiler_test_targets_compile_gate_package) - && string_contains(s: cmd, pattern: "--all-targets") - UsesStep { name: _, id: _, uses: _, with: _, env: _, if_condition: _, continue_on_error: _, timeout_minutes: _ } => false - } - }) -} - -test fn w_v1_compiler_test_targets_gate_RED_missing_operation_refuses() -> Bool { - let bad_step = bash_bind_operation_invocation( - at: OperationRef { - path: "dag/extdeps/rust/cargo_build.dag", - service: "cargo.Build", - operation: "NoSuchCheck" - }, - bindings: [ - operation_argv_bind_text_list( - name: "extra_args", - items: ci_v1_compiler_test_targets_compile_gate_extra_args() - ) - ] - ) - let refused_plan = EffectPlan { - steps: [Do { effect: bad_step }], - on_failure: FailFast - } - gate_plan_refuses(plan: refused_plan) - && string_contains( - s: gate_materialized_render(plan: refused_plan), - pattern: ci_v1_compiler_test_targets_compile_gate_refusal_prefix - ) -} diff --git a/dag/test/claim/ci_v1_compiler_tests_compile_gate_witness_test.dag b/dag/test/claim/ci_v1_compiler_tests_compile_gate_witness_test.dag deleted file mode 100644 index 4099ac050ce..00000000000 --- a/dag/test/claim/ci_v1_compiler_tests_compile_gate_witness_test.dag +++ /dev/null @@ -1,112 +0,0 @@ -module test.claim.ci_v1_compiler_tests_compile_gate_witness - -import v2.workflow.ci_v1_compiler_tests_compile_gate_emit { - ci_v1_compiler_tests_compile_gate_script, - ci_v1_compiler_tests_compile_gate_shell_emit_scaffold, -} -import gunbc.ci_workflow { ci_v1_compiler_tests_compile_gate_run_script, ci_build_job } -import gunbc.ci_spec { ci_release_features } -import gunbc.ci_build_job_v1_compiler_unit_receipt { - one_profile_ordering_status, - one_compiler_unit_status, - wall_benefit_status, - fleet_build_job_log_evidence_run, - fleet_build_job_log_evidence_status, -} -import gunbc.ci_materialization { step_display_name } -import extdeps.github.actions { Step, RunStep, UsesStep } -import std.disposition { Scaffold } - -data compile_gate_step_name: String = "cargo test -p v1-compiler-tests --release (retained-kernel execution gate; reuses release v1-compiler)" -data release_build_step_name: String = "Build release bins (claim_executor + gunbc)" - -fn step_index_of(steps: List, name: String) -> Int { - let seen = fold(steps, init: { idx: 0, hit: 0 - 1 }, f: fn(acc, s) { - if step_display_name(s: s) == name { - if acc.hit >= 0 { { idx: acc.idx + 1, hit: acc.hit } } else { { idx: acc.idx + 1, hit: acc.idx } } - } else { - { idx: acc.idx + 1, hit: acc.hit } - } - }) - seen.hit -} - -test fn w_gate_script_names_release_test_execution_command() -> Bool { - let script = ci_v1_compiler_tests_compile_gate_script() - string_contains(s: script, pattern: "'test'") - && string_contains(s: script, pattern: "'v1-compiler-tests'") - && string_contains(s: script, pattern: "'--release'") - && !string_contains(s: script, pattern: "'--no-run'") - && string_contains(s: script, pattern: "\"$CARGO_BIN\"") - && !string_contains(s: script, pattern: "'check'") - && !string_contains(s: script, pattern: "nextest") -} - -test fn w_gate_script_eagain_cold_retry() -> Bool { - let script = ci_v1_compiler_tests_compile_gate_run_script() - string_contains(s: script, pattern: "Resource temporarily unavailable|failed to spawn") - && string_contains(s: script, pattern: "CARGO_BUILD_JOBS=1") - && string_contains(s: script, pattern: "keep sccache") -} - -test fn w_gate_run_script_is_cargo_test_execution_only() -> Bool { - let script = ci_v1_compiler_tests_compile_gate_run_script() - string_contains(s: script, pattern: "'test'") - && string_contains(s: script, pattern: "'v1-compiler-tests'") - && string_contains(s: script, pattern: "'--release'") - && !string_contains(s: script, pattern: "'--no-run'") - && !string_contains(s: script, pattern: "compile_contract_admission_witness") - && !string_contains(s: script, pattern: "CompileContractAdmissionReceipt") -} - -test fn w_gate_carrier_is_scaffold() -> Bool { - match ci_v1_compiler_tests_compile_gate_shell_emit_scaffold { - Scaffold { dissolves_to: _, bind: _ } => true - _ => false - } -} - -test fn w_build_job_enrolls_compile_gate_after_release_build() -> Bool { - let steps = ci_build_job().steps - let build = step_index_of(steps: steps, name: release_build_step_name) - let gate = step_index_of(steps: steps, name: compile_gate_step_name) - (build >= 0) && (gate >= 0) && (build < gate) -} - -test fn w_release_features_align_test_crate_deps() -> Bool { - string_contains(s: ci_release_features, pattern: "text_lookup_work_counter") - && string_contains(s: ci_release_features, pattern: "interp_test_witness") - && string_contains(s: ci_release_features, pattern: "test_hooks") -} - -data ci_build_job_v1_compiler_unit_receipt_witness_note: String = "Executing consumer for gunbc.ci_build_job_v1_compiler_unit_receipt (A2 lane, smart-badger-549). THE PAIR IS THE PROOF: landed ordering + delivered unit identity + open wall benefit must hold together with fleet run 31077456733 job 92538509081 cited; RED controls refuse rung inflation (not-delivered unit, measured wall benefit, delivered fleet status without run id)." - -test fn w_receipt_one_profile_ordering_landed() -> Bool { - one_profile_ordering_status == "landed" -} - -test fn w_receipt_one_compiler_unit_delivered() -> Bool { - one_compiler_unit_status == "delivered" -} - -test fn w_receipt_wall_benefit_open() -> Bool { - wall_benefit_status == "open" -} - -test fn w_receipt_fleet_evidence_delivered_with_run() -> Bool { - fleet_build_job_log_evidence_status == "delivered" - && fleet_build_job_log_evidence_run == "31077456733" -} - -test fn red_one_compiler_unit_status_must_not_revert_undelivered() -> Bool { - one_compiler_unit_status != "not delivered" -} - -test fn red_wall_benefit_must_not_claim_measured() -> Bool { - wall_benefit_status != "measured" -} - -test fn red_fleet_status_must_not_claim_delivered_without_run() -> Bool { - !(fleet_build_job_log_evidence_status == "delivered" - && fleet_build_job_log_evidence_run == "") -} diff --git a/dag/test/claim/ci_workflow_witness_test.dag b/dag/test/claim/ci_workflow_witness_test.dag deleted file mode 100644 index 1fcd4bbfaa3..00000000000 --- a/dag/test/claim/ci_workflow_witness_test.dag +++ /dev/null @@ -1,103 +0,0 @@ -module test.claim.ci_workflow_witness_test - -import std.types { Bool, Int } -import std.measure { minute_count } -import gunbc.ci_workflow { - ci_workflow, - gunbc_ci_job_backstop_timeout_minutes, - gunbc_ci_build_job_backstop_timeout_minutes, - gunbc_ci_v1_compiler_test_targets_compile_gate_timeout_minutes, - gunbc_ci_artifact_transfer_step_timeout_minutes, - gunbc_ci_aux_step_timeout_minutes, - gunbc_ci_workflow_wrapper_timeout_minutes, - gunbc_ci_v1_compiler_tests_compile_gate_timeout_minutes, - gunbc_ci_stage0_partition_compile_gate_timeout_minutes, - gunbc_ci_release_build_step_timeout_minutes, - gunbc_ci_prelude_allowance_minutes, -} -import gunbc.ci_workflow_expressions { ci_fleet_job_if } -import gunbc.ci_spec { - gunbc_ci_ordinary_floor_budget_minutes, - gunbc_ci_admission_postcondition_budget_minutes, - gunbc_ci_walk_overhead_allowance_minutes, - gunbc_ci_workflow_wrapper_budget_minutes, -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -fn ci_job_backstop_is_step_sum_plus_prelude() -> Bool { - gunbc_ci_job_backstop_timeout_minutes() == (gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_workflow_wrapper_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes) -} - -fn ci_build_job_backstop_is_step_sum_plus_prelude() -> Bool { - gunbc_ci_build_job_backstop_timeout_minutes() == (gunbc_ci_aux_step_timeout_minutes + gunbc_ci_v1_compiler_tests_compile_gate_timeout_minutes + gunbc_ci_stage0_partition_compile_gate_timeout_minutes + gunbc_ci_v1_compiler_test_targets_compile_gate_timeout_minutes + gunbc_ci_release_build_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes) -} - -data backstop_magnitude_pin_deleted_note: String = "ci_job_backstop_equals_one_hundred_minutes DELETED (the live-state count-transcription class, operator ruling 2026-07-30 — same class as the roadmap 63-declared pin): it mirrored the derived step-sum as a literal, so any legitimate step roster change redded it and the reviewer's move was editing the number until it matched. It redded here when the two receipt-gate steps moved in-executor (100 -> 90) — a correct change reported as a failure. The invariant that MATTERS is magnitude-independent and stays asserted: the backstop equals the exact step-sum + prelude.\n\nSECOND DELETION, same class, caught by execution rather than by reading (2026-08-11): ci_job_backstop_dropped_the_selection_control_term asserted !(backstop == 115), encoding as a SENTINEL the value that would obtain if the 15-minute selection-control term were still summed. That is a magnitude pin wearing a structural name — it does not read the roster, it reads a number — and it survived the first deletion only because 115 happened to be unreachable by any other route. It stopped being unreachable when the floor-receipts upload step added one 5-minute aux term to a 110-minute base, landing on exactly 115 by a path that has nothing to do with selection control. The witness would have redded on a correct change and the reviewer's move would again have been editing the number, which is the whole failure mode the first deletion was ruled on.\n\nWHY DELETING IT LOSES NOTHING: ci_job_backstop_is_step_sum_plus_prelude asserts EXACT equality against an enumeration that contains no selection-control term, so any sum that included one is unequal to it and reds there. Absence of the term is therefore proven structurally, at a grain a magnitude comparison cannot express — a sentinel can only ever say 'not this one number', while the equality says 'exactly these terms and no others'. The sentinel was strictly weaker than a check already present beside it, which is why the correct repair is deletion rather than picking a fresh number." - -test fn ci_workflow_witness_holds() -> Bool { - ci_job_backstop_is_step_sum_plus_prelude() - && ci_build_job_backstop_is_step_sum_plus_prelude() - && (minute_count(m: gunbc_ci_ordinary_floor_budget_minutes) == 80) - && (minute_count(m: gunbc_ci_admission_postcondition_budget_minutes) == 5) - && (minute_count(m: gunbc_ci_walk_overhead_allowance_minutes) == 15) - && (minute_count(m: gunbc_ci_workflow_wrapper_budget_minutes()) == minute_count(m: gunbc_ci_ordinary_floor_budget_minutes) + minute_count(m: gunbc_ci_admission_postcondition_budget_minutes) + minute_count(m: gunbc_ci_walk_overhead_allowance_minutes)) - && (gunbc_ci_workflow_wrapper_timeout_minutes == minute_count(m: gunbc_ci_workflow_wrapper_budget_minutes())) -} - -// RED control for the push-to-main skip cascade (measured 2026-08-09: >=30 main pushes -// silently skipped deploy_dashboard_srv1 — and later advance/collect — because -// heal_generated_artifacts skips on ordinary pushes and a needs:[ci] job whose if -// carries NO status function gets GitHub's implicit success() ANDed in, which is false -// downstream of any transitively skipped job). The wall: every job gating on the -// main-push event must carry its OWN status guard, so a skipped dependency can never -// silently read as 'condition false'. This test REDS if the guard is removed from the -// authority row, if any push-to-main job's condition drops it, or if the family -// becomes vacuously empty. -// -// CONSOLIDATION (operator request 2026-08-10): the deploy/collect/advance family (and -// the workflow_dispatch toolbox) collapsed into ONE `fleet` job (gunbc.ci_workflow -// ci_fleet_job) whose job-level if is ci_fleet_job_if — carrying the same !cancelled() -// + needs.ci.result guard on its push arm. The guard-bearing count is therefore 1 now, -// not >= 2; the per-job status-guard check still holds on that one job, and >= 1 keeps -// the "not vacuously empty" protection (a fleet job that drops its main-push arm or its -// status guard still REDs). -test fn push_to_main_family_carries_explicit_status_guard() -> Bool { - string_contains(s: ci_fleet_job_if, pattern: "!cancelled()") - && string_contains(s: ci_fleet_job_if, pattern: "needs.ci.result == 'success'") - && fold_list( - xs: ci_workflow.jobs, - empty: true, - cons: fn(ok, j) { - if !ok { - false - } else { - match j.if_condition { - Present { value: c } => - if string_contains(s: c, pattern: "refs/heads/main") && string_contains(s: c, pattern: "github.event_name == 'push'") { - string_contains(s: c, pattern: "!cancelled()") && string_contains(s: c, pattern: "needs.ci.result == 'success'") - } else { - true - } - _ => true - } - } - } - ) - && fold_list( - xs: ci_workflow.jobs, - empty: 0, - cons: fn(n, j) { - match j.if_condition { - Present { value: c } => - if string_contains(s: c, pattern: "refs/heads/main") && string_contains(s: c, pattern: "github.event_name == 'push'") { - n + 1 - } else { - n - } - _ => n - } - } - ) >= 1 -} diff --git a/dag/test/claim/ci_yaml_parse_witness.dag b/dag/test/claim/ci_yaml_parse_witness.dag deleted file mode 100644 index a0c74d79b81..00000000000 --- a/dag/test/claim/ci_yaml_parse_witness.dag +++ /dev/null @@ -1,18 +0,0 @@ -module test.claim.ci_yaml_parse_witness - - -data ci_yml_path: String = ".github/workflows/ci.yml" -data expected_parse_scratch: String = "/tmp/gunbc_ci_yml_expected_parse.yml" - -func ci_yaml_parse_witness() -> ProcessExit { - let committed = Filesystem.Read(path: ci_yml_path) - let drift_ok = committed.success && !ci_yml_drifted(committed: committed.content) - let committed_parse = ci_yml_parses(path: ci_yml_path) - let w = Filesystem.Write(path: expected_parse_scratch, content: expected_ci_yml()) - let expected_parse = w.success && ci_yml_parses(path: expected_parse_scratch) - return if drift_ok && committed_parse && expected_parse { - ExitSuccess - } else { - exit_failure(reason: "ci.yml drift and/or YAML parse check failed") - } -} diff --git a/dag/test/claim/ci_yaml_serializer_witness_test.dag b/dag/test/claim/ci_yaml_serializer_witness_test.dag deleted file mode 100644 index db55ab03458..00000000000 --- a/dag/test/claim/ci_yaml_serializer_witness_test.dag +++ /dev/null @@ -1,209 +0,0 @@ -module test.claim.ci_yaml_serializer_witness - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -test fn witness_fetch_depth_is_int_not_string() -> Bool { - let with_block = yaml_mapping(entries: [kv(key: "fetch-depth", value: yaml_int(n: 0))]) - let out = serialize_yaml(v: with_block) - (out == "fetch-depth: 0\n") && (out != "fetch-depth: \"0\"\n") -} - -test fn witness_rustflags_empty_string_quoted() -> Bool { - let with_block = yaml_mapping(entries: [kv(key: "rustflags", value: yaml_string(s: ""))]) - serialize_yaml(v: with_block) == "rustflags: ''\n" -} - -test fn witness_steps_sequence_elements_are_yaml_values() -> Bool { - let job = ci_workflow.jobs.first() - match steps_yaml(steps: job.steps) { - YamlSequence { elements: els } => (els.length() == job.steps.length()) && (els.length() > 0) - _ => false - } -} - -test fn witness_step_sequence_only_serializes() -> Bool { - let step = step_yaml(step: ci_workflow.jobs.first().steps.first()) - serialize_yaml(v: yaml_sequence(elements: concat(empty_yaml_values, [step]))) != "" -} - -test fn witness_step_mapping_serializes() -> Bool { - serialize_yaml(v: step_yaml(step: ci_workflow.jobs.first().steps.first())) != "" -} - -test fn witness_first_step_is_mapping() -> Bool { - match steps_yaml(steps: ci_workflow.jobs.first().steps) { - YamlSequence { elements: els } => - match els.first() { - YamlMapping { entries: _ } => true - _ => false - } - _ => false - } -} - -test fn witness_one_step_serializes() -> Bool { - let first = ci_workflow.jobs.first().steps.first() - serialize_yaml(v: yaml_mapping(entries: [ - kv(key: "steps", value: yaml_sequence(elements: concat(empty_yaml_values, [step_yaml(step: first)]))) - ])) != "" -} - -test fn witness_steps_wrapped_serializes() -> Bool { - serialize_yaml(v: yaml_mapping(entries: [ - kv(key: "steps", value: steps_yaml(steps: ci_workflow.jobs.first().steps)) - ])) != "" -} - -test fn witness_jobs_yaml_serializes() -> Bool { - serialize_yaml(v: yaml_mapping(entries: [ - kv(key: "jobs", value: jobs_yaml(jobs: ci_workflow.jobs)) - ])) != "" -} - -test fn witness_project_workflow_serializes() -> Bool { - serialize_yaml(v: project_workflow_to_yaml(workflow: ci_workflow)) != "" -} - -test fn witness_ci_yaml_gate_red_on_perturbed_bytes() -> Bool { - let expected = expected_ci_yml() - ci_yml_drifted(committed: concat(expected, "\n# perturb")) && - !ci_yml_drifted(committed: expected) -} - -test fn witness_ci_yaml_gate_red_on_wrong_fetch_depth_type() -> Bool { - let expected = expected_ci_yml() - ci_yml_drifted(committed: concat("fetch-depth: \"0\"\n", expected)) -} - -test fn witness_cache_path_block_scalar() -> Bool { - let yaml = expected_ci_yml() - string_contains( - s: yaml, - pattern: " path: |\n ${{ runner.temp }}/cargo/registry/index/" - ) && - string_contains( - s: yaml, - pattern: concat( - concat( - " ${{ runner.temp }}/cargo/registry/cache/\n", - " ${{ runner.temp }}/cargo/git/db/\n" - ), - " target/" - ) - ) -} - -test fn witness_restore_keys_block_scalar_indent() -> Bool { - let yaml = expected_ci_yml() - string_contains( - s: yaml, - pattern: " restore-keys: |\n cargo-ci-${{ runner.os }}-${{ runner.arch }}-\n" - ) && - !string_contains(s: yaml, pattern: " restore-keys: |\n cargo-ci-") -} - -test fn witness_rustup_run_block_scalar_not_quoted() -> Bool { - let yaml = expected_ci_yml() - let rustup_line = concat( - " rustup default \"$(rustup show active-toolchain | awk '", - concat(concat("{", "print $1; exit"), concat("}", "')\"")) - ) - string_contains(s: yaml, pattern: concat(" run: |\n", rustup_line)) && - !string_contains(s: yaml, pattern: "run: \"rustup default") -} - -test fn witness_cache_key_plain_not_quoted() -> Bool { - let yaml = expected_ci_yml() - string_contains(s: yaml, pattern: " key: cargo-ci-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles") && - !string_contains(s: yaml, pattern: "key: \"cargo-ci") -} - -test fn witness_multiline_without_block_scalar_is_invalid() -> Bool { - let broken = concat( - concat( - " path: ${{ runner.temp }}/cargo/registry/index/\n", - " ${{ runner.temp }}/cargo/registry/cache/\n" - ), - "" - ) - !string_contains(s: expected_ci_yml(), pattern: broken) -} - -test fn witness_cache_path_not_flat_multiline_sibling() -> Bool { - !string_contains( - s: expected_ci_yml(), - pattern: concat( - " path: ${{ runner.temp }}/cargo/registry/index/\n", - " ${{ runner.temp }}/cargo/registry/cache/" - ) - ) -} - -test fn witness_restore_keys_content_deeper_than_key() -> Bool { - !string_contains( - s: expected_ci_yml(), - pattern: " restore-keys: |\n cargo-ci-" - ) -} - -test fn witness_sccache_wired_when_fleet_daemon_up() -> Bool { - let yaml = expected_ci_yml() - string_contains(s: yaml, pattern: "if sccache --show-stats >/dev/null 2>&1; then") && - string_contains(s: yaml, pattern: "RUSTC_WRAPPER=sccache") && - string_contains(s: yaml, pattern: "CARGO_INCREMENTAL=0") && - !string_contains(s: yaml, pattern: "sccache --stop-server") && - !string_contains(s: yaml, pattern: "sccache --start-server") && - !string_contains(s: yaml, pattern: "SCCACHE_DIR=$RUNNER_TEMP/sccache") -} - -test fn witness_cargo_jobs_derived_and_jobserver_decoupled() -> Bool { - let yaml = expected_ci_yml() - let n = ci_cargo_build_jobs_count() - string_contains(s: yaml, pattern: "echo \"MAKEFLAGS=\" >> \"$GITHUB_ENV\"") && - string_contains(s: yaml, pattern: concat("CARGO_BUILD_JOBS=", concat(to_string(n), "\""))) && - !string_contains(s: yaml, pattern: "CARGO_BUILD_JOBS=1\"") && - !string_contains(s: yaml, pattern: "CARGO_BUILD_JOBS=2\"") && - n >= 2 -} - -test fn witness_gunbc_ci_step_projects_run_script_markers() -> Bool { - let yaml = expected_ci_yml() - let floor_script = gunbc_ci_floor_run(spec: gunbc_ci_spec) - let build_script = ci_release_build_script() - string_contains(s: yaml, pattern: "Build release bins (claim_executor + gunbc)") && - !string_contains(s: yaml, pattern: "env -u RUSTC_WRAPPER") && - string_contains(s: yaml, pattern: "$ROOT/target/release/claim_executor") && - !string_contains(s: build_script, pattern: "env -u RUSTC_WRAPPER") && - !string_contains(s: floor_script, pattern: "env -u RUSTC_WRAPPER") && - string_contains(s: floor_script, pattern: "$ROOT/target/release/claim_executor") -} - -test fn witness_cache_uses_runner_context_not_env() -> Bool { - template_uses_context(template: ci_cache_path_template, target: Runner) && - !template_uses_context(template: ci_cache_path_template, target: Env) -} - -test fn witness_cache_runner_env_scope_red_control() -> Bool { - - let bad = ExpressionTemplate { segments: [ - Interpolation { expression: ContextAccess { context: extdeps.github.expressions.Env, path: ["CARGO_HOME"] } }, - LiteralText { text: "/registry/index/" } - ] } - !(template_uses_context(template: bad, target: Runner) && - !template_uses_context(template: bad, target: Env)) -} - -test fn witness_no_runner_vars_accessed_via_env_context() -> Bool { - !any_template_accesses_runner_var_via_env(templates: ci_workflow_expression_templates) -} - -test fn witness_no_runner_env_context_red_control() -> Bool { - - let bad = concat(ci_workflow_expression_templates, [ - ExpressionTemplate { segments: [ - Interpolation { expression: ContextAccess { context: extdeps.github.expressions.Env, path: ["RUNNER_TEMP"] } } - ] } - ]) - any_template_accesses_runner_var_via_env(templates: bad) -} - diff --git a/dag/test/claim/commit_workflow_witness_test.dag b/dag/test/claim/commit_workflow_witness_test.dag deleted file mode 100644 index c613824e19f..00000000000 --- a/dag/test/claim/commit_workflow_witness_test.dag +++ /dev/null @@ -1,154 +0,0 @@ -module test.claim.commit_workflow_witness - -import gunbc.commit_workflow { - commit_gate_roster, - commit_workflow_realization_bindings, - commit_workflow_ci_floor_gates, - commit_workflow_local_tidy_checks, - CommitWorkflowSurface, GithubActionsCiJob, GitPrePushHook, - CiYamlHandler, GitPrePushScriptHandler, - gate_lists_eq, local_tidy_lists_eq, - realization_artifact_path, - realization_handler_for_surface, - realization_artifact_for_surface, - project_ci_floor_witness_entries, - roster_witness_spans_wellformed, - witness_span_wellformed -} -import std.measure { millisecond, WallClock } -import std.realization_schedule { - WitnessSeam, SpanSeams, SpanUndeclared, SpanEnrolled, - WitnessCostBasis, MeasuredAtExactSubject, - ScheduledWitnessEnvelope, - CorpusWitnessKind, ExecutionWitnessKind, witness_kind_eq -} -import std.witness_admission { OfflineLocalRecipe, FalsifierRehomedBinWet } -import gunbc.ci_spec { gunbc_ci_floor_gates } -import gunbc.local_tidy_spec { local_tidy_checks } -import gunbc.generated_artifact { - CiYamlArtifact, GithooksPrePushArtifact, artifact_path -} -import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree } - -data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree - -test fn witness_ci_spec_projects_from_roster() -> Bool { - gate_lists_eq(left: gunbc_ci_floor_gates, right: commit_workflow_ci_floor_gates) -} - -test fn witness_local_tidy_spec_projects_from_roster() -> Bool { - local_tidy_lists_eq(left: local_tidy_checks, right: commit_workflow_local_tidy_checks) -} - -test fn witness_ci_jobs_share_yaml_handler() -> Bool { - realization_handler_for_surface(surface: GithubActionsCiJob) == CiYamlHandler - && realization_artifact_for_surface(surface: GithubActionsCiJob) == CiYamlArtifact -} - -test fn witness_pre_push_handler_binding() -> Bool { - realization_handler_for_surface(surface: GitPrePushHook) == GitPrePushScriptHandler - && realization_artifact_for_surface(surface: GitPrePushHook) == GithooksPrePushArtifact -} - -test fn witness_realization_bindings_match_dispatch() -> Bool { - fold(commit_workflow_realization_bindings, init: true, f: fn(acc, b) { - acc - && realization_handler_for_surface(surface: b.surface) == b.handler - && realization_artifact_for_surface(surface: b.surface) == b.artifact - }) -} - -test fn witness_realization_artifact_paths() -> Bool { - realization_artifact_path(surface: GithubActionsCiJob) == artifact_path(a: CiYamlArtifact) - && realization_artifact_path(surface: GitPrePushHook) == artifact_path(a: GithooksPrePushArtifact) -} - -test fn witness_roster_nonempty() -> Bool { - length(commit_gate_roster) > 0 - && length(commit_workflow_realization_bindings) == 2 -} - -test fn witness_roster_spans_wellformed() -> Bool { - roster_witness_spans_wellformed(roster: commit_gate_roster) -} - -test fn witness_span_undeclared_is_wellformed() -> Bool { - witness_span_wellformed(span: SpanUndeclared) -} - -test fn witness_span_accepts_declared_seam() -> Bool { - witness_span_wellformed(span: SpanSeams { - seams: [WitnessSeam { producer: "v2.04_infer", consumer: "v2.06_translate" }] - }) -} - -test fn witness_span_rejects_self_seam() -> Bool { - !witness_span_wellformed(span: SpanSeams { - seams: [WitnessSeam { producer: "v2.04_infer", consumer: "v2.04_infer" }] - }) -} - -test fn witness_span_rejects_duplicate_seams() -> Bool { - !witness_span_wellformed(span: SpanSeams { - seams: [ - WitnessSeam { producer: "v2.04_infer", consumer: "v2.06_translate" }, - WitnessSeam { producer: "v2.04_infer", consumer: "v2.06_translate" } - ] - }) -} - -test fn witness_span_rejects_empty_seam_list() -> Bool { - !witness_span_wellformed(span: SpanSeams { seams: [] }) -} - -test fn witness_span_enrolled_accepts_measured_envelope() -> Bool { - witness_span_wellformed(span: SpanEnrolled { - seams: [ - WitnessSeam { - producer: "GithubActionsCiJob", - consumer: "frontier_probe_read_failure_detail_refused_holds" - } - ], - cost_basis: MeasuredAtExactSubject { - clock: WallClock, - duration: millisecond(count: 3), - receipt: "target/frontier-probe-survey/matrix_readthrough_claim_batch_receipt.log" - }, - envelope: ScheduledWitnessEnvelope { - path_classification: OfflineLocalRecipe, - wall_budget: millisecond(count: 5000), - max_staleness: millisecond(count: 0) - } - }) -} - -test fn witness_span_enrolled_rejects_zero_wall_budget() -> Bool { - !witness_span_wellformed(span: SpanEnrolled { - seams: [ - WitnessSeam { producer: "FalsifierCadenceJob", consumer: "example_witness_holds" } - ], - cost_basis: MeasuredAtExactSubject { - clock: WallClock, - duration: millisecond(count: 100), - receipt: "target/example-receipt.log" - }, - envelope: ScheduledWitnessEnvelope { - path_classification: FalsifierRehomedBinWet, - wall_budget: millisecond(count: 0), - max_staleness: millisecond(count: 14400000) - } - }) -} - -data allowed_long_lane_explicit_entry: String = "src/v2/test/claim/long/parse_table_memo_governed_witness_test.dag" - -test fn witness_floor_roster_has_no_slow_long_lane_entries() -> Bool { - !any( - project_ci_floor_witness_entries(roster: commit_gate_roster), - e => - witness_kind_eq(a: e.kind, b: CorpusWitnessKind) - && string_contains(s: e.entry, pattern: "test/claim/long/") - && e.entry != allowed_long_lane_explicit_entry - ) -} - diff --git a/dag/test/claim/compile_clean_cost_clamp_witness_test.dag b/dag/test/claim/compile_clean_cost_clamp_witness_test.dag deleted file mode 100644 index ddfaf04fa24..00000000000 --- a/dag/test/claim/compile_clean_cost_clamp_witness_test.dag +++ /dev/null @@ -1,43 +0,0 @@ -module test.claim.compile_clean_cost_clamp_witness - -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import v2.workflow.ci_floor_plan { - gunbc_ci_compile_clean_clamp_ms, - gunbc_ci_compile_clean_clamp_overhead_seconds, - gunbc_ci_compile_clean_clamp_rate_per_unit_ms, - gunbc_ci_compile_clean_wall_exceeds_clamp, -} -import std.logic { Bool } -import std.types { Int, String } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data compile_clean_cost_clamp_witness_note: String = "Executing consumer for the compile-clean leg clamp (gunbc.ci_spec gunbc_ci_compile_clean_clamp_note — the prelude-coverage follow-up (a) first slice). THE PAIR IS THE PROOF (the witness_row_cost_drift discipline): a wall one millisecond over the computed clamp MUST exceed and the clamp value itself MUST NOT — either alone is satisfiable by a broken comparator. The formula pins (overhead*1000 + units*rate) keep claim_executor's Rust mirror honest: the executor reads the same two constants through the plan context and computes the same arithmetic, so a drifted mirror shows up here as a wrong pinned value. The 258000ms control is the observed basis run (30602520347, srv1-01, ~1648-unit whole-tree entry closure post-#7490) sitting WITHIN the clamp — the clamp reds runaways, not the healthy wall it was sized from. Runtime enforcement receipt: target/floor-compile-clean-wall-receipt.txt; RED control GUNBC_FLOOR_COMPILE_CLEAN_BUDGET_TIGHTEN_MS (min-only)." - -test fn compile_clean_clamp_formula_whole_tree_pins() -> Bool { - gunbc_ci_compile_clean_clamp_ms(units: 1648) == 587360 -} - -test fn compile_clean_clamp_formula_zero_units_is_overhead() -> Bool { - gunbc_ci_compile_clean_clamp_ms(units: 0) == gunbc_ci_compile_clean_clamp_overhead_seconds() * 1000 -} - -test fn compile_clean_clamp_red_control_over_by_one_exceeds() -> Bool { - gunbc_ci_compile_clean_wall_exceeds_clamp(observed_ms: 587361, units: 1648) -} - -test fn compile_clean_clamp_boundary_at_clamp_does_not_exceed() -> Bool { - !gunbc_ci_compile_clean_wall_exceeds_clamp(observed_ms: 587360, units: 1648) -} - -test fn compile_clean_clamp_observed_basis_run_within() -> Bool { - !gunbc_ci_compile_clean_wall_exceeds_clamp(observed_ms: 258000, units: 1648) -} - -test fn compile_clean_clamp_overhead_positive() -> Bool { - gunbc_ci_compile_clean_clamp_overhead_seconds() > 0 -} - -test fn compile_clean_clamp_rate_nonneg() -> Bool { - gunbc_ci_compile_clean_clamp_rate_per_unit_ms() >= 0 -} diff --git a/dag/test/claim/falsifier_alert_decision_witness_test.dag b/dag/test/claim/falsifier_alert_decision_witness_test.dag deleted file mode 100644 index 75a1c60bf78..00000000000 --- a/dag/test/claim/falsifier_alert_decision_witness_test.dag +++ /dev/null @@ -1,876 +0,0 @@ -module test.claim.falsifier_alert_decision_witness_test - -import std.types { Bool, Int, String, NonEmptyStr, EpochMs } -import std.measure { millisecond_count } -import extdeps.github.workflow_run_event { workflow_run_event_from_json } -import gunbc.falsifier_alert_admission { - FalsifierAlertAdmission, AlertRefusedHeadBranchNotMain, - falsifier_alert_admit -} -import gunbc.falsifier_alert_state { - FirstRedStanding, FirstRedObserved, FirstRedUnknownBeforeTracking, - FalsifierAlertState, - FalsifierAlertStateDecoding, - CurrentState, LegacyStateWithoutLastNotification, StateAbsent, StateMalformed, - falsifier_alert_heartbeat_window, - falsifier_alert_state_from_payload, - falsifier_alert_state_json -} -import gunbc.floor_component_receipt_document { - ReceiptDecoded, ReceiptNotJson, - ReceiptSubjectRunIdMismatch, - floor_component_receipt_decode_with -} -import gunbc.falsifier_lane { - FalsifierRouting, RoutedToOwner, RoutingOwnerUndeclared, - LaneOwnerHandle, LaneSubstrateLongLane -} -import std.types { Timestamp } -import extdeps.languages.json.emit { serialize_json } -import extdeps.github.issues { Issue, IssueState, Open } -import gunbc.falsifier_alert_decision { - AlertDecision, - AlertIssueObservation, NoOpenAlertIssue, OneOpenAlertIssue, MultipleOpenAlertIssues, AlertIssueLookupRefused, - IncidentSignature, ComponentIncidentIdentity, - RefuseEscalationRecipientUndeclared, - OpenObserverIncident, RefreshObserverIncident, RefreshObserverIncidentWithoutNotification, - NotifyAlertControllerUnavailable, - ControllerReceiptMalformed, ControllerReceiptMismatch, ControllerMarkerMalformed, ControllerRoutingJoinRefused, - ControllerIssueLookupRefused, ControllerMultipleOpenIssues, ControllerIssueObserved, ControllerIssueUntouched, - ConclusionDecidedBeforeReceipt, - RunPreventedByConfiguration, CancellationUnexplained, - RoutingsMissingForComponents, RoutingsForNonFailingComponents, RoutingsDuplicated, - incident_signature_eq, incident_signature_render, alert_signature_of_marker, - NoAction, OpenIssue, RefreshIssueWithoutNotification, - RefreshAndNotifyChangedClass, RefreshAndNotifyHeartbeat, - NotifyGreenAndClose, NotifyLegacyStateMigration, - RefuseUntrustedEvent, - GreenWithNoOpenIncident, - AlertReceiptInput, ReceiptAdmitted, ReceiptSubjectRejected, ReceiptUndecodable, - EscalationRecipient, EscalationDeclared, EscalationUndeclared, - AlertNotification, - alert_decision, alert_decision_notifies, alert_decision_notification, - notification_escalates, notification_has_unowned_routing, - alert_signature_of -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data falsifier_alert_decision_witness_note: String = "ALERT-4's evidence. alert_decision performs no GitHub calls, so every property here is a fixture and a comparison — no live issue, no live run, no live clock. That is what makes the arms that are hardest to reach in production the cheapest to prove: the heartbeat boundary, the corrupt-marker refusal and the escalation-survives-undeclared-ownership property are all one call each.\\n\\nEach claim exercises ONE arm and asserts the arm itself, not merely that something happened. A decision procedure with sixteen terminal arms, eight of them refusals, is exactly the shape where `it returned a refusal` passes while the WRONG refusal is returned — and those eight route to eight different investigations, so the wrong one sends a human to the wrong place." - -data falsifier_alert_decision_red_receipts_note: String = "DISCRIMINATING REDS, EXECUTED PER ARM RATHER THAN AS ONE AGGREGATE. Each mutation below was applied to gunbc.falsifier_alert_decision, the named claims run, and the mutation reverted; the third column is the control that stayed GREEN under the same mutation, which is what makes each claim discriminating rather than merely sensitive.\\n\\nDropping failure_mode from component_signature_member reds a_changed_failure_class_notifies_immediately_inside_the_window while an_unchanged_red_inside_the_window_refreshes_without_notifying stays green. Weakening the heartbeat comparison from >= to > reds an_unchanged_red_notifies_at_the_heartbeat_boundary while one_millisecond_before_the_boundary_still_suppresses stays green. Reading a malformed marker as IncidentAbsent — which is precisely the defect of a corrupt marker opening a NEW incident — reds both malformed claims while a_first_red_opens_an_issue_and_notifies stays green. Making notification_escalates consult the routings reds both halves of the escalation/ownership separation while the same control stays green. Testing the receipt before the admission reds an_untrusted_event_refuses_even_when_the_receipt_is_undecodable while an_untrusted_event_refuses_before_anything_else stays green — the ordering claim is therefore proven by the case that distinguishes it, not inferred from the case that would hold under either order.\\n\\nThat last pair is the reason both were written. A trust-first guard and a receipt-first guard agree on every input where the receipt is fine, so the only witness that can tell them apart is the one where the receipt is broken AND the event is untrusted, and it is the one that matters: it is the input on which a receipt-first program decodes an attacker-supplied artifact before deciding it was never allowed to look." - -data mutation_that_reds_nothing_note: String = "A MUTATION THAT REDS NOTHING IS A SIGNAL, NOT A NULL RESULT — and it is ambiguous in a way worth stating, because the two readings have opposite remedies. It means EITHER the witness is vacuous (it would pass however the code behaved, so it is measuring nothing) OR the code is redundant (some other copy of the same rule is still enforcing the property). You cannot tell which without looking at what stayed green and why.\\n\\nBoth diagnoses came out of the same probe on this lane. Deleting the outer malformed-state guard here left every claim green because the rule also sat in both verdict folds — three copies agreeing by diligence, which is what produced AlertIncidentState. Elsewhere the same probe found a control that stayed green because the live population simply did not exhibit the property being checked, which is the vacuous case. Same instrument, opposite findings.\\n\\nThe standing move: after a wall lands, delete the wall and confirm that something reds. A wall whose removal changes nothing is not yet load-bearing, and finding out which of the two reasons applies is the cheapest diagnosis available." - -data alert_expected_schema: NonEmptyStr = "floor-component-receipt/v1" - -fn trusted_event_json_with_conclusion(conclusion: String) -> String { - concat(concat( - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000001,\"workflow_id\":161803,\"path\":\".github/workflows/falsifier.yml\",\"name\":\"affected-set-falsifier\",\"conclusion\":\"", - conclusion), - "\",\"html_url\":\"https://x\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"main\",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":\"schedule\"}}") -} - -fn untrusted_event_json() -> String { - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000001,\"workflow_id\":161803,\"path\":\".github/workflows/falsifier.yml\",\"name\":\"affected-set-falsifier\",\"conclusion\":\"failure\",\"html_url\":\"https://x\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"topic/experiment\",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":\"schedule\"}}" -} - -fn admission_of(json: String) -> FalsifierAlertAdmission { - falsifier_alert_admit(observation: workflow_run_event_from_json(text: json)) -} - -fn red_admission() -> FalsifierAlertAdmission { - admission_of(json: trusted_event_json_with_conclusion(conclusion: "failure")) -} - -fn green_admission() -> FalsifierAlertAdmission { - admission_of(json: trusted_event_json_with_conclusion(conclusion: "success")) -} - -fn cancelled_admission() -> FalsifierAlertAdmission { - admission_of(json: trusted_event_json_with_conclusion(conclusion: "cancelled")) -} - -data one_failing_component: String = "{\"index\":6,\"label\":\"witness discovery\",\"outcome\":\"failed\",\"error\":\"claim is false\",\"output\":\"\",\"failure_mode\":\"WitnessRed\"}" - -data other_failing_component: String = "{\"index\":6,\"label\":\"witness discovery\",\"outcome\":\"failed\",\"error\":\"runner died\",\"output\":\"\",\"failure_mode\":\"Infra\"}" - -fn receipt_text_with(component: String) -> String { - concat(concat(concat( - "{\"schema\":\"floor-component-receipt/v1\",\"workflow_name\":\"affected-set-falsifier\",\"run_id\":\"31000000001\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"component_count\":1,\"affected_set_cold_control\":null,\"selection_degradation\":null,\"run_terminal\":null,\"unsuccessful_components\":[", - component), "],\"components\":["), concat(component, "]}")) -} - -fn receipt_input_with(component: String) -> AlertReceiptInput { - match floor_component_receipt_decode_with(text: receipt_text_with(component: component), expected_schema: alert_expected_schema) { - ReceiptDecoded { document: d } => ReceiptAdmitted { document: d } - _ => ReceiptUndecodable { decoding: ReceiptNotJson { detail: "fixture failed to decode" } } - } -} - -fn red_receipt() -> AlertReceiptInput { - receipt_input_with(component: one_failing_component) -} - -fn signature_struct_of(component: String) -> IncidentSignature { - match floor_component_receipt_decode_with(text: receipt_text_with(component: component), expected_schema: alert_expected_schema) { - ReceiptDecoded { document: d } => alert_signature_of(doc: d) - _ => IncidentSignature { members: [] } - } -} - -fn signature_struct_of_fixture() -> IncidentSignature { - signature_struct_of(component: one_failing_component) -} - -fn signature_of_fixture(component: String) -> NonEmptyStr { - incident_signature_render(sig: signature_struct_of(component: component)) -} - -data escalation_handle: NonEmptyStr = "@briansrls" - -fn declared_escalation() -> EscalationRecipient { - EscalationDeclared { handle: escalation_handle } -} - -fn undeclared_escalation() -> EscalationRecipient { - EscalationUndeclared { cause: "no escalation recipient declared" as NonEmptyStr } -} - -data unowned_routings_note: String = "The routing fixture is deliberately the LIVE shape: the lane owner roster in gunbc.falsifier_lane is empty, so every real routing today is RoutingOwnerUndeclared. Witnessing against the shape production actually produces is what makes the escalation-survives-unowned property mean something." - -fn unowned_routings() -> List { - [RoutingOwnerUndeclared { - index: 6, - lane: LaneSubstrateLongLane, - cause: "no owner row for this lane" as NonEmptyStr - }] -} - -fn owned_routings() -> List { - [RoutedToOwner { - index: 6, - lane: LaneSubstrateLongLane, - owner: LaneOwnerHandle { handle: "@someone" as NonEmptyStr } - }] -} - -fn current_state(signature: NonEmptyStr, last: Int) -> FalsifierAlertStateDecoding { - CurrentState { - state: FalsifierAlertState { - first_red: FirstRedObserved { at: 1000 }, - signature: signature, - last_notification_at: last - } - } -} - -fn fixture_issue() -> Issue { - Issue { - number: 4242, - title: "affected-set falsifier is red" as NonEmptyStr, - body: "", - state: Open, - html_url: "https://github.com/gunb-ai/gunbc/issues/4242" as NonEmptyStr, - created_at: "2026-08-01T00:00:00Z" as Timestamp, - updated_at: "2026-08-06T00:00:00Z" as Timestamp - } -} - -fn observed(state: FalsifierAlertStateDecoding) -> AlertIssueObservation { - OneOpenAlertIssue { issue: fixture_issue(), state: state } -} - -fn decide_observed( - admission: FalsifierAlertAdmission, - receipt: AlertReceiptInput, - observation: AlertIssueObservation, - now: Int -) -> AlertDecision { - alert_decision( - admission: admission, - receipt: receipt, - observation: observation, - now: now, - escalation: declared_escalation(), - routings: unowned_routings() - ) -} - -fn decide( - admission: FalsifierAlertAdmission, - receipt: AlertReceiptInput, - state: FalsifierAlertStateDecoding, - now: Int -) -> AlertDecision { - decide_observed(admission: admission, receipt: receipt, observation: observed(state: state), now: now) -} - -test fn a_first_red_opens_an_issue_and_notifies() -> Bool { - let d = decide_observed(admission: red_admission(), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 5000) - match d { - OpenIssue { signature: sig, next_state: _, notification: _ } => - incident_signature_eq(left: sig, right: signature_struct_of_fixture()) - && alert_decision_notifies(d: d) - _ => false - } -} - -test fn an_unchanged_red_inside_the_window_refreshes_without_notifying() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) - let d = decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: 5001) - match d { - RefreshIssueWithoutNotification { signature: _, silent_for: s } => - millisecond_count(m: s) == 1 && !alert_decision_notifies(d: d) - _ => false - } -} - -test fn an_unchanged_red_notifies_at_the_heartbeat_boundary() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) - let boundary = 5000 + millisecond_count(m: falsifier_alert_heartbeat_window) - let d = decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: boundary) - match d { - RefreshAndNotifyHeartbeat { signature: _, silent_for: s, notification: _ } => - millisecond_count(m: s) == millisecond_count(m: falsifier_alert_heartbeat_window) - && alert_decision_notifies(d: d) - _ => false - } -} - -data heartbeat_boundary_note: String = "The boundary is asserted at exactly last + window and one millisecond BELOW it, because an off-by-one in that comparison is invisible in production — it shifts a twenty-hour heartbeat by a millisecond — and is exactly the kind of thing that only a fixture can pin." - -test fn one_millisecond_before_the_boundary_still_suppresses() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) - let just_under = 5000 + millisecond_count(m: falsifier_alert_heartbeat_window) - 1 - match decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: just_under) { - RefreshIssueWithoutNotification { signature: _, silent_for: _ } => true - _ => false - } -} - -data changed_class_note: String = "The two fixtures differ ONLY in failure_mode — Infra versus WitnessRed on the same index and label — and both map to outcome `failed`. That is the collapse this whole lane started from: a change of owner reading as no change at all. If the signature ever stops keying on failure_mode, this claim reds while every other claim here stays green." - -test fn a_changed_failure_class_notifies_immediately_inside_the_window() -> Bool { - let previous = signature_of_fixture(component: other_failing_component) - let d = decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: previous, last: 5000), now: 5001) - match d { - RefreshAndNotifyChangedClass { issue: _, previous: p, current: c, next_state: _, notification: _ } => - incident_signature_eq(left: p, right: signature_struct_of(component: other_failing_component)) - && incident_signature_eq(left: c, right: signature_struct_of_fixture()) - && alert_decision_notifies(d: d) - _ => false - } -} - -test fn a_green_run_notifies_and_closes_an_open_incident() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) - let d = decide(admission: green_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: 6000) - match d { - NotifyGreenAndClose { notification: _ } => alert_decision_notifies(d: d) - _ => false - } -} - -test fn a_green_run_with_no_open_incident_does_nothing() -> Bool { - match decide_observed(admission: green_admission(), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 6000) { - NoAction { reason: r } => - match r { - GreenWithNoOpenIncident => true - _ => false - } - _ => false - } -} - -test fn an_unexplained_cancellation_is_its_own_reason() -> Bool { - match decide_observed(admission: cancelled_admission(), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 6000) { - NoAction { reason: r } => - match r { - CancellationUnexplained => true - _ => false - } - _ => false - } -} - -test fn a_legacy_marker_sends_one_migration_notification() -> Bool { - let d = decide( - admission: red_admission(), - receipt: red_receipt(), - state: LegacyStateWithoutLastNotification { first_red: FirstRedObserved { at: 1000 }, signature: "old" as NonEmptyStr }, - now: 6000 - ) - match d { - NotifyLegacyStateMigration { first_red: f, signature: _, notification: _ } => - match f { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } && alert_decision_notifies(d: d) - _ => false - } -} - -data malformed_precedes_verdict_note: String = "The corrupt-marker refusal is asserted under BOTH a red and a green run, because the ordering choice is the substantive one: a green run with a corrupt marker refuses rather than closing. Closing would look friendlier and would destroy the corrupt marker in the process — the one artifact a human needs to find out what wrote it." - -test fn a_malformed_marker_reports_a_controller_failure_under_a_red_run() -> Bool { - let d = decide(admission: red_admission(), receipt: red_receipt(), state: StateMalformed { detail: "bad" }, now: 6000) - match d { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: disp, notification: _ } => - alert_decision_notifies(d: d) - && match c { ControllerMarkerMalformed { detail: dd } => dd == "bad", _ => false } - && match disp { ControllerIssueObserved { issue: _ } => true, ControllerIssueUntouched => false } - _ => false - } -} - -test fn a_malformed_marker_does_not_close_the_issue_under_a_green_run() -> Bool { - match decide(admission: green_admission(), receipt: red_receipt(), state: StateMalformed { detail: "bad" }, now: 6000) { - NotifyAlertControllerUnavailable { cause: _, issue_disposition: _, notification: _ } => true - _ => false - } -} - -data guard_order_divergence_note: String = "THE TWO CLAIMS BELOW ARE NOT REDUNDANT, AND DELETING THE SECOND WOULD DELETE THE WHOLE CLAIM. Read quickly they look like the same witness twice: both feed an untrusted event and both expect RefuseUntrustedEvent. The difference is the receipt, and the difference is the entire point.\\n\\nAN ORDERING CLAIM NEEDS AN INPUT ON WHICH THE ORDERINGS DIVERGE. Trust-first and receipt-first agree on every input where the receipt decodes, so the first claim — untrusted event, good receipt — passes under BOTH orderings and therefore proves the ordering by inference rather than by measurement. Anywhere two candidate implementations agree, a test between them is measuring something else. The second claim — untrusted event AND an undecodable receipt — is the only shape on which they disagree, and it is exactly the security-relevant one: a receipt-first program decodes attacker-supplied content before concluding it was never allowed to look at it. That is the input the trust wall exists for.\\n\\nThis is recorded here rather than only in the pull request because the pull request is not where the next author will be standing. Anyone tidying this file will see two near-identical witnesses and reach for the shorter one; the shorter one is the one that carries nothing." - -test fn an_untrusted_event_refuses_before_anything_else() -> Bool { - match decide_observed(admission: admission_of(json: untrusted_event_json()), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 6000) { - RefuseUntrustedEvent { admission: a } => - match a { - AlertRefusedHeadBranchNotMain { observed: o, expected: _ } => o == "topic/experiment" - _ => false - } - _ => false - } -} - -test fn an_untrusted_event_refuses_even_when_the_receipt_is_undecodable() -> Bool { - match decide_observed( - admission: admission_of(json: untrusted_event_json()), - receipt: ReceiptUndecodable { decoding: ReceiptNotJson { detail: "x" } }, - observation: NoOpenAlertIssue, - now: 6000 - ) { - RefuseUntrustedEvent { admission: _ } => true - _ => false - } -} - -test fn a_mismatched_receipt_refuses_distinctly_from_a_malformed_one() -> Bool { - let mismatch = decide_observed( - admission: red_admission(), - receipt: ReceiptSubjectRejected { - mismatch: ReceiptSubjectRunIdMismatch { receipt: "999" as NonEmptyStr, event: "31000000001" as NonEmptyStr } - }, - observation: NoOpenAlertIssue, - now: 6000 - ) - let malformed = decide_observed( - admission: red_admission(), - receipt: ReceiptUndecodable { decoding: ReceiptNotJson { detail: "x" } }, - observation: NoOpenAlertIssue, - now: 6000 - ) - match mismatch { - NotifyAlertControllerUnavailable { cause: cm, issue_disposition: _, notification: _ } => - match cm { - ControllerReceiptMismatch { mismatch: _ } => - match malformed { - NotifyAlertControllerUnavailable { cause: cd, issue_disposition: _, notification: _ } => - match cd { ControllerReceiptMalformed { decoding: _ } => true, _ => false } - _ => false - } - _ => false - } - _ => false - } -} - -data escalation_separation_claims_note: String = "The two halves of the escalation/ownership separation, asserted in both directions. Fusing them is the easy mistake — there is exactly one handle in the tree and no lane owners at all — and fusing them either way loses a real fact." - -test fn every_notifying_arm_carries_the_escalation_mention() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) - let opened = decide_observed(admission: red_admission(), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 5000) - let heartbeat = decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: 5000 + millisecond_count(m: falsifier_alert_heartbeat_window)) - let changed = decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: signature_of_fixture(component: other_failing_component), last: 5000), now: 5001) - let green = decide(admission: green_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: 6000) - let legacy = decide(admission: red_admission(), receipt: red_receipt(), state: LegacyStateWithoutLastNotification { first_red: FirstRedObserved { at: 1000 }, signature: "old" as NonEmptyStr }, now: 6000) - fold([opened, heartbeat, changed, green, legacy], init: true, f: (acc, d) => - acc && match alert_decision_notification(d: d) { - Present { value: n } => notification_escalates(n: n) - Absent => false - }) -} - -test fn an_undeclared_lane_owner_does_not_suppress_escalation() -> Bool { - let d = alert_decision( - admission: red_admission(), - receipt: red_receipt(), - observation: NoOpenAlertIssue, - now: 5000, - escalation: declared_escalation(), - routings: unowned_routings() - ) - match alert_decision_notification(d: d) { - Present { value: n } => notification_escalates(n: n) && notification_has_unowned_routing(n: n) - Absent => false - } -} - -data escalation_refusal_supersedes_the_old_claim_note: String = "This claim previously asserted that a notification built with an undeclared escalation recipient carried no mention and no unowned routing. It passed, and it was measuring the wrong thing: a notification that mentions nobody is not the correct handling of a missing recipient, it is the incident this lane exists to prevent, rendered structurally. The corrected behaviour refuses before any notifying arm can be constructed, so the claim now asserts the refusal AND that a declared lane owner does not rescue it — ownership of the failing lane says nothing about who is told the observer is broken." - -test fn a_declared_lane_owner_does_not_substitute_for_a_missing_escalation_recipient() -> Bool { - match alert_decision( - admission: red_admission(), - receipt: red_receipt(), - observation: NoOpenAlertIssue, - now: 5000, - escalation: undeclared_escalation(), - routings: owned_routings() - ) { - RefuseEscalationRecipientUndeclared { cause: _ } => true - _ => false - } -} - -test fn a_non_notifying_arm_carries_no_notification_at_all() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) - let quiet = decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: 5001) - match alert_decision_notification(d: quiet) { - Absent => !alert_decision_notifies(d: quiet) - Present { value: _ } => false - } -} - -data payload_driven_claims_note: String = "THE SAME SIX ARMS, REACHED THROUGH THE PAYLOAD DECODER RATHER THAN THROUGH A HAND-BUILT STATE VALUE. The claims above construct CurrentState and StateMalformed directly, which isolates the decision but skips the seam that produces them in production: the alert reads a JSON marker out of an issue body, and falsifier_alert_state_from_payload is what turns those bytes into the coproduct. A decision that is correct on hand-built inputs and a decoder that is correct in isolation can still disagree about which value a given marker denotes, and no witness on either side alone would see it.\\n\\nThese six moved here when FalsifierAlertNotificationDecision was deleted. They previously exercised a SECOND throttle implementation in gunbc.falsifier_alert_state that computed the same window comparison, the same signature comparison and the same silent_for as alert_decision_red — one rule, two copies, and the copy had no production consumer at all. A review read the overlap as intentional lane staging; it was not, it was a fork, and forked rules stay in agreement only by diligence. The rule now lives once and these witnesses point at it, so the payload-decoder coverage they carry survived the consolidation instead of being deleted with the machinery." - -fn state_marker_current(first_red: Int, signature: String, last: Int) -> String { - concat( - concat(concat("{\"first_red\":", first_red as String), concat(",\"signature\":\"", signature)), - concat(concat("\",\"last_notification_at\":", last as String), "}") - ) -} - -fn state_marker_legacy(first_red: Int, signature: String) -> String { - concat( - concat(concat("{\"first_red\":", first_red as String), concat(",\"signature\":\"", signature)), - "\"}" - ) -} - -fn decide_from_marker(admission: FalsifierAlertAdmission, payload: String, now: Int) -> AlertDecision { - decide(admission: admission, receipt: red_receipt(), state: falsifier_alert_state_from_payload(payload: payload), now: now) -} - -data absence_is_not_a_payload_note: String = "AN ABSENT MARKER IS NOT AN EMPTY PAYLOAD, AND THIS CLAIM PINS THE DIFFERENCE. StateAbsent means the issue body carried no marker at all; falsifier_alert_state_from_payload never produces it, because by the time bytes reach the decoder a marker was found. Absence is decided one seam earlier, by whoever searched the body.\\n\\nThis witness was first written as `an empty payload opens a first red` and it FAILED, which is the useful part: an empty string is not valid JSON, so it decodes to StateMalformed and the alert refuses. That is the correct answer and the fixture was the thing that was wrong — but the failure is worth keeping as a claim rather than a deleted mistake, because the tempting repair is on the wrong side. Making the decoder map an empty payload to StateAbsent would turn `I read a marker and could not understand it` into `there was no marker`, which is the empty-observation narrow DESIGN names: an unreadable incident record would silently start a NEW incident and overwrite the old one. The refusal is load-bearing, so it is asserted." - -test fn an_empty_payload_refuses_rather_than_reading_as_an_absent_marker() -> Bool { - match decide_from_marker(admission: red_admission(), payload: "", now: 9999999) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { ControllerMarkerMalformed { detail: _ } => true, _ => false } - _ => false - } -} - -test fn a_decoded_legacy_marker_notifies_exactly_once_as_a_migration() -> Bool { - match decide_from_marker(admission: red_admission(), payload: state_marker_legacy(first_red: 1000, signature: "a:b:c"), now: 9999999) { - NotifyLegacyStateMigration { issue: _, first_red: f, signature: _, next_state: _, notification: _ } => - match f { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } - _ => false - } -} - -test fn a_decoded_changed_signature_always_notifies_even_inside_the_window() -> Bool { - let previous = incident_signature_render(sig: signature_struct_of(component: other_failing_component)) - let marker = state_marker_current(first_red: 1000, signature: previous as String, last: 5000) - match decide_from_marker(admission: red_admission(), payload: marker, now: 5001) { - RefreshAndNotifyChangedClass { issue: _, previous: p, current: _, next_state: _, notification: _ } => - incident_signature_eq(left: p, right: signature_struct_of(component: other_failing_component)) - _ => false - } -} - -test fn a_decoded_unchanged_signature_is_suppressed_inside_the_window() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) as String - match decide_from_marker(admission: red_admission(), payload: state_marker_current(first_red: 1000, signature: sig, last: 5000), now: 5001) { - RefreshIssueWithoutNotification { signature: _, silent_for: s } => millisecond_count(m: s) == 1 - _ => false - } -} - -test fn a_decoded_unchanged_signature_heartbeats_once_the_window_elapses() -> Bool { - let sig = signature_of_fixture(component: one_failing_component) as String - let marker = state_marker_current(first_red: 1000, signature: sig, last: 5000) - match decide_from_marker(admission: red_admission(), payload: marker, now: 5000 + millisecond_count(m: falsifier_alert_heartbeat_window)) { - RefreshAndNotifyHeartbeat { signature: _, silent_for: s, notification: _ } => - millisecond_count(m: s) == millisecond_count(m: falsifier_alert_heartbeat_window) - _ => false - } -} - -test fn a_decoded_malformed_marker_refuses_instead_of_starting_a_new_incident() -> Bool { - match decide_from_marker(admission: red_admission(), payload: "{\"first_red\":\"not-a-number\",\"signature\":\"x\"}", now: 9999999) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { ControllerMarkerMalformed { detail: _ } => true, _ => false } - _ => false - } -} - -data operator_verdict_claims_note: String = "The operator verdict's five #7935 corrections. Each one had a fixture that decoded and decided cleanly BEFORE the correction — the decision was always well-typed, it was simply deciding on a fact it did not have — so every claim here is written on the input that separates the corrected behaviour from the original, not on one that merely exercises the arm." - -test fn an_existing_issue_without_a_marker_is_adopted_rather_than_duplicated() -> Bool { - match decide_observed(admission: red_admission(), receipt: red_receipt(), observation: observed(state: StateAbsent), now: 6000) { - NotifyLegacyStateMigration { issue: iss, first_red: f, signature: _, next_state: ns, notification: _ } => - iss.number == 4242 - && match f { FirstRedUnknownBeforeTracking => true, FirstRedObserved { at: _ } => false } - && match ns.first_red { FirstRedUnknownBeforeTracking => true, FirstRedObserved { at: _ } => false } - _ => false - } -} - -test fn an_existing_issue_without_a_marker_is_closed_on_green_rather_than_ignored() -> Bool { - match decide_observed(admission: green_admission(), receipt: red_receipt(), observation: observed(state: StateAbsent), now: 6000) { - NotifyGreenAndClose { issue: iss, notification: _ } => iss.number == 4242 - _ => false - } -} - -test fn two_open_alert_issues_refuse_rather_than_picking_one() -> Bool { - match decide_observed( - admission: red_admission(), - receipt: red_receipt(), - observation: MultipleOpenAlertIssues { issues: [fixture_issue(), fixture_issue()] }, - now: 6000 - ) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { ControllerMultipleOpenIssues { count: n } => n == 2, _ => false } - _ => false - } -} - -test fn a_failed_issue_lookup_refuses_rather_than_reading_as_no_issue() -> Bool { - match decide_observed( - admission: red_admission(), - receipt: red_receipt(), - observation: AlertIssueLookupRefused { cause: "api unavailable" as NonEmptyStr }, - now: 6000 - ) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { ControllerIssueLookupRefused { cause: _ } => true, _ => false } - _ => false - } -} - -test fn an_undeclared_escalation_recipient_refuses_before_any_notification_is_built() -> Bool { - match alert_decision( - admission: red_admission(), - receipt: red_receipt(), - observation: NoOpenAlertIssue, - now: 5000, - escalation: undeclared_escalation(), - routings: unowned_routings() - ) { - RefuseEscalationRecipientUndeclared { cause: _ } => true - _ => false - } -} - -data signature_structure_claims_note: String = "The order- and delimiter-independence of the incident identity, asserted directly on the structure. The receipt fixtures cannot easily be reordered through the decoder, so these compare signatures built from the same members in two orders — which is the property that matters and the one the joined string did not have." - -fn identity_member(index: Nat, outcome: String, mode: String) -> ComponentIncidentIdentity { - ComponentIncidentIdentity { index: index, outcome_tag: outcome as NonEmptyStr, failure_mode_tag: mode as NonEmptyStr } -} - -test fn the_same_failing_set_in_a_different_order_is_the_same_incident() -> Bool { - let a = IncidentSignature { members: [identity_member(index: 6, outcome: "failed", mode: "WitnessRed"), identity_member(index: 2, outcome: "failed", mode: "Infra")] } - let b = IncidentSignature { members: [identity_member(index: 2, outcome: "failed", mode: "Infra"), identity_member(index: 6, outcome: "failed", mode: "WitnessRed")] } - incident_signature_eq(left: a, right: b) -} - -test fn a_different_failure_class_is_a_different_incident() -> Bool { - let a = IncidentSignature { members: [identity_member(index: 6, outcome: "failed", mode: "WitnessRed")] } - let b = IncidentSignature { members: [identity_member(index: 6, outcome: "failed", mode: "Infra")] } - !incident_signature_eq(left: a, right: b) -} - -test fn a_rendered_signature_reads_back_into_the_same_structure() -> Bool { - let sig = IncidentSignature { members: [identity_member(index: 2, outcome: "failed", mode: "Infra"), identity_member(index: 6, outcome: "refused", mode: "BudgetExceeded")] } - match alert_signature_of_marker(marker: incident_signature_render(sig: sig)) { - Present { value: back } => incident_signature_eq(left: sig, right: back) - Absent => false - } -} - -test fn an_unparseable_stored_signature_refuses_rather_than_reading_as_changed() -> Bool { - match decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: "not-a-signature" as NonEmptyStr, last: 5000), now: 5001) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { ControllerMarkerMalformed { detail: _ } => true, _ => false } - _ => false - } -} - -data next_state_claims_note: String = "The next-state policy, one claim per writing arm, because the arms disagree about first_red and that disagreement is the entire content of the policy. The changed-class claim is the load-bearing one: it is the arm where restarting the incident clock would be most tempting and most wrong." - -test fn a_first_red_starts_the_incident_clock_and_the_notification_clock_together() -> Bool { - match decide_observed(admission: red_admission(), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 5000) { - OpenIssue { signature: _, next_state: ns, notification: _ } => - match ns.first_red { FirstRedObserved { at: t } => t == 5000, FirstRedUnknownBeforeTracking => false } - && ns.last_notification_at == 5000 - _ => false - } -} - -test fn a_heartbeat_preserves_the_incident_clock_and_moves_the_notification_clock() -> Bool { - let sig = incident_signature_render(sig: signature_struct_of_fixture()) - let now = 5000 + millisecond_count(m: falsifier_alert_heartbeat_window) - match decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: now) { - RefreshAndNotifyHeartbeat { issue: _, signature: _, next_state: ns, silent_for: _, notification: _ } => - match ns.first_red { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } && ns.last_notification_at == now - _ => false - } -} - -test fn a_silent_refresh_moves_neither_clock() -> Bool { - let sig = incident_signature_render(sig: signature_struct_of_fixture()) - match decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: sig, last: 5000), now: 5001) { - RefreshIssueWithoutNotification { issue: _, signature: _, next_state: ns, silent_for: _ } => - match ns.first_red { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } && ns.last_notification_at == 5000 - _ => false - } -} - -test fn a_changed_class_preserves_the_incident_clock_rather_than_restarting_it() -> Bool { - let previous = incident_signature_render(sig: IncidentSignature { members: [identity_member(index: 6, outcome: "failed", mode: "Infra")] }) - match decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: previous, last: 5000), now: 5001) { - RefreshAndNotifyChangedClass { issue: _, previous: _, current: _, next_state: ns, notification: _ } => - match ns.first_red { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } && ns.last_notification_at == 5001 - _ => false - } -} - -data conclusion_policy_claims_note: String = "A run that never reached a corpus verdict is not a green corpus. These three assert the split the operator ruled on, and the startup-failure one is the case the original mapped to silence — a falsifier failing at startup on every run would have been reported by nobody while every run produced a clean NoAction." - -test fn a_startup_failure_notifies_that_the_observer_is_unavailable() -> Bool { - let d = decide_observed(admission: admission_of(json: trusted_event_json_with_conclusion(conclusion: "startup_failure")), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 6000) - match d { - OpenObserverIncident { conclusion_tag: t, next_state: ns, notification: _ } => - (t as String) == "startup_failure" && alert_decision_notifies(d: d) && ns.last_notification_at == 6000 - _ => false - } -} - -test fn a_timed_out_run_notifies_that_the_observer_is_unavailable() -> Bool { - match decide_observed(admission: admission_of(json: trusted_event_json_with_conclusion(conclusion: "timed_out")), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 6000) { - OpenObserverIncident { conclusion_tag: t, next_state: _, notification: _ } => (t as String) == "timed_out" - _ => false - } -} - -test fn a_skipped_run_is_a_configuration_fact_not_a_green_corpus() -> Bool { - match decide_observed(admission: admission_of(json: trusted_event_json_with_conclusion(conclusion: "skipped")), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 6000) { - NoAction { reason: r } => - match r { - RunPreventedByConfiguration { conclusion_tag: t } => (t as String) == "skipped" - _ => false - } - _ => false - } -} - -data routing_join_claims_note: String = "The routing join, one claim per mismatch direction. The missing-routing case is the one that matters operationally: an issue that names no owner for a failing component looks exactly like an issue for a component nobody owns, and the difference is whether the routing computation is broken." - -fn routing_for(index: Nat) -> FalsifierRouting { - RoutingOwnerUndeclared { index: index, lane: LaneSubstrateLongLane, cause: "no owner row for this lane" as NonEmptyStr } -} - -fn decide_with_routings(routings: List) -> AlertDecision { - alert_decision( - admission: red_admission(), - receipt: red_receipt(), - observation: NoOpenAlertIssue, - now: 5000, - escalation: declared_escalation(), - routings: routings - ) -} - -test fn a_failing_component_with_no_routing_refuses() -> Bool { - match decide_with_routings(routings: []) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { - ControllerRoutingJoinRefused { mismatch: m } => - match m { RoutingsMissingForComponents { indices: xs } => count(xs) == 1, _ => false } - _ => false - } - _ => false - } -} - -test fn a_routing_for_a_non_failing_component_refuses() -> Bool { - match decide_with_routings(routings: [routing_for(index: 6), routing_for(index: 99)]) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { - ControllerRoutingJoinRefused { mismatch: m } => - match m { RoutingsForNonFailingComponents { indices: xs } => count(xs) == 1, _ => false } - _ => false - } - _ => false - } -} - -test fn a_duplicated_routing_refuses() -> Bool { - match decide_with_routings(routings: [routing_for(index: 6), routing_for(index: 6)]) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { - ControllerRoutingJoinRefused { mismatch: m } => - match m { RoutingsDuplicated { indices: _ } => true, _ => false } - _ => false - } - _ => false - } -} - -test fn an_exact_routing_join_proceeds() -> Bool { - match decide_with_routings(routings: [routing_for(index: 6)]) { - OpenIssue { signature: _, next_state: _, notification: _ } => true - _ => false - } -} - -data live_head_verdict_claims_note: String = "The operator live-head items 1-4 plus review 49873. Each of these was a case the previous revision handled plausibly and wrongly: a timed-out run reported the floor's writer broken, an adopted issue claimed to know when the incident started, a controller failure completed the workflow in silence, and a hand-edited marker index parsed into a valid-looking identity." - -test fn a_timed_out_run_with_no_receipt_reports_the_observer_not_the_writer() -> Bool { - match alert_decision( - admission: admission_of(json: trusted_event_json_with_conclusion(conclusion: "timed_out")), - receipt: ReceiptUndecodable { decoding: ReceiptNotJson { detail: "no receipt was written" } }, - observation: NoOpenAlertIssue, - now: 6000, - escalation: declared_escalation(), - routings: [] - ) { - OpenObserverIncident { conclusion_tag: t, next_state: _, notification: _ } => (t as String) == "timed_out" - _ => false - } -} - -data observer_throttle_claims_note: String = "These four claims exist because the observer path was NOT throttled for one revision (review 50351) while two notes asserted it was. The old witness here is the reason it survived: it asked the repeated-outage case at now 6000 against last 5000 — a one-second gap inside a twenty-hour window — and asserted RefreshObserverIncident, so it PINNED the spam as the contract and would have gone red against the correct behavior. A witness that agrees with the defect is worse than no witness, because it converts a fix into an apparent regression. It now asks the same repeat at the same instants and asserts suppression, and the notifying cases get their own inputs where the window has genuinely elapsed." - -test fn a_repeated_observer_outage_within_the_window_is_suppressed() -> Bool { - match alert_decision( - admission: admission_of(json: trusted_event_json_with_conclusion(conclusion: "timed_out")), - receipt: ReceiptUndecodable { decoding: ReceiptNotJson { detail: "no receipt" } }, - observation: observed(state: current_state(signature: "observer-unavailable:timed_out" as NonEmptyStr, last: 5000)), - now: 6000, - escalation: declared_escalation(), - routings: [] - ) { - RefreshObserverIncidentWithoutNotification { issue: iss, conclusion_tag: _, next_state: ns, silent_for: sf } => - iss.number == 4242 - && ns.last_notification_at == 5000 - && millisecond_count(m: sf) == 1000 - && match ns.first_red { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } - _ => false - } -} - -fn observer_decision_at(last: EpochMs, now: EpochMs) -> AlertDecision { - alert_decision( - admission: admission_of(json: trusted_event_json_with_conclusion(conclusion: "timed_out")), - receipt: ReceiptUndecodable { decoding: ReceiptNotJson { detail: "no receipt" } }, - observation: observed(state: current_state(signature: "observer-unavailable:timed_out" as NonEmptyStr, last: last)), - now: now, - escalation: declared_escalation(), - routings: [] - ) -} - -test fn a_suppressed_observer_refresh_does_not_advance_the_notification_instant() -> Bool { - let just_under = 5000 + millisecond_count(m: falsifier_alert_heartbeat_window) - 1 - let carried = match observer_decision_at(last: 5000, now: just_under) { - RefreshObserverIncidentWithoutNotification { issue: _, conclusion_tag: _, next_state: ns, silent_for: _ } => ns.last_notification_at - _ => just_under - } - match observer_decision_at(last: carried, now: 5000 + millisecond_count(m: falsifier_alert_heartbeat_window)) { - RefreshObserverIncident { issue: _, conclusion_tag: _, next_state: _, silent_for: _, notification: _ } => carried == 5000 - _ => false - } -} - -test fn a_repeated_observer_outage_heartbeats_once_the_window_elapses() -> Bool { - let boundary = 5000 + millisecond_count(m: falsifier_alert_heartbeat_window) - match observer_decision_at(last: 5000, now: boundary) { - RefreshObserverIncident { issue: iss, conclusion_tag: _, next_state: ns, silent_for: sf, notification: _ } => - iss.number == 4242 - && ns.last_notification_at == boundary - && millisecond_count(m: sf) == millisecond_count(m: falsifier_alert_heartbeat_window) - _ => false - } -} - -test fn a_changed_observer_class_notifies_even_inside_the_window() -> Bool { - match alert_decision( - admission: admission_of(json: trusted_event_json_with_conclusion(conclusion: "timed_out")), - receipt: ReceiptUndecodable { decoding: ReceiptNotJson { detail: "no receipt" } }, - observation: observed(state: current_state(signature: "observer-unavailable:startup_failure" as NonEmptyStr, last: 5000)), - now: 6000, - escalation: declared_escalation(), - routings: [] - ) { - RefreshObserverIncident { issue: _, conclusion_tag: t, next_state: ns, silent_for: _, notification: _ } => - (t as String) == "timed_out" - && (ns.signature as String) == "observer-unavailable:timed_out" - && ns.last_notification_at == 6000 - _ => false - } -} - -test fn an_adopted_issue_does_not_claim_to_know_when_the_incident_started() -> Bool { - match decide_observed(admission: red_admission(), receipt: red_receipt(), observation: observed(state: StateAbsent), now: 6000) { - NotifyLegacyStateMigration { issue: _, first_red: f, signature: _, next_state: ns, notification: _ } => - match f { FirstRedUnknownBeforeTracking => true, FirstRedObserved { at: _ } => false } - && match ns.first_red { FirstRedUnknownBeforeTracking => true, FirstRedObserved { at: _ } => false } - _ => false - } -} - -test fn an_unknown_first_red_round_trips_through_the_marker() -> Bool { - let marker = serialize_json(v: falsifier_alert_state_json(state: FalsifierAlertState { - first_red: FirstRedUnknownBeforeTracking, - signature: "6:failed:WitnessRed" as NonEmptyStr, - last_notification_at: 5000 - })) - match falsifier_alert_state_from_payload(payload: marker) { - CurrentState { state: st } => - match st.first_red { FirstRedUnknownBeforeTracking => true, FirstRedObserved { at: _ } => false } - _ => false - } -} - -test fn a_controller_failure_notifies_rather_than_completing_in_silence() -> Bool { - let d = decide_observed( - admission: red_admission(), - receipt: ReceiptUndecodable { decoding: ReceiptNotJson { detail: "receipt is not valid JSON" } }, - observation: NoOpenAlertIssue, - now: 6000 - ) - alert_decision_notifies(d: d) -} - -test fn an_untrusted_event_still_does_not_notify() -> Bool { - let d = decide_observed(admission: admission_of(json: untrusted_event_json()), receipt: red_receipt(), observation: NoOpenAlertIssue, now: 6000) - !alert_decision_notifies(d: d) -} - -test fn a_negative_index_in_a_stored_marker_refuses_rather_than_reading_as_changed() -> Bool { - match decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: "-1:failed:WitnessRed" as NonEmptyStr, last: 5000), now: 5001) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { ControllerMarkerMalformed { detail: _ } => true, _ => false } - _ => false - } -} - -test fn a_fractional_index_in_a_stored_marker_refuses() -> Bool { - match decide(admission: red_admission(), receipt: red_receipt(), state: current_state(signature: "6.5:failed:WitnessRed" as NonEmptyStr, last: 5000), now: 5001) { - NotifyAlertControllerUnavailable { cause: c, issue_disposition: _, notification: _ } => - match c { ControllerMarkerMalformed { detail: _ } => true, _ => false } - _ => false - } -} diff --git a/dag/test/claim/falsifier_alert_migration_witness_test.dag b/dag/test/claim/falsifier_alert_migration_witness_test.dag deleted file mode 100644 index 02deb455086..00000000000 --- a/dag/test/claim/falsifier_alert_migration_witness_test.dag +++ /dev/null @@ -1,844 +0,0 @@ -module test.claim.falsifier_alert_migration_witness_test - -import std.types { Bool, Int, String, NonEmptyStr, EpochMs, CommitSha } -import extdeps.languages.yaml.emit { serialize_yaml } -import extdeps.languages.yaml.gha_workflow { workflow_trigger_entry } -import extdeps.languages.yaml.types { yaml_mapping } -import extdeps.github.actions { WorkflowTrigger, WorkflowRunCompleted, MergeGroup } -import extdeps.github.workflow_run_event { - WorkflowRunEvent, - WorkflowRunEventObservation, - WorkflowRunEventObserved, - WorkflowRunEventMemberAbsent, - WorkflowRunEventMemberMalformed, - WorkflowRunEventMalformed, - workflow_run_event_from_json -} -import extdeps.github.workflow_runs { Success, Failure } -import gunbc.falsifier_alert_admission { - FalsifierAlertAdmission, - AlertAdmitted, - AlertRefusedWorkflowNotObserved, - AlertRefusedWorkflowPathNotObserved, - AlertRefusedRepositoryNotOwned, - RepositoryField, EnclosingRepository, HeadRepository, - AlertRefusedHeadBranchNotMain, - AlertRefusedOriginatingEventNotAdmitted, - AlertRefusedActivityNotCompleted, - AlertRefusedEventUnreadable, - falsifier_alert_admit, - falsifier_alert_job_condition -} -import gunbc.falsifier_alert_state { - FirstRedStanding, FirstRedObserved, FirstRedUnknownBeforeTracking, - FalsifierAlertState, - FalsifierAlertStateDecoding, - CurrentState, LegacyStateWithoutLastNotification, StateAbsent, StateMalformed, - falsifier_alert_state_from_payload, - falsifier_alert_heartbeat_window -} -import std.measure { Millisecond, millisecond, millisecond_count } -import gunbc.floor_component_receipt_document { - FloorComponentReceiptSubject, - FloorComponentReceiptDecoding, - ReceiptDecoded, ReceiptNotJson, ReceiptMemberAbsent, ReceiptMemberMalformed, ReceiptSchemaUnknown, - ReceiptSubjectMatch, ReceiptSubjectMatches, - ReceiptSubjectRunIdMismatch, ReceiptSubjectWorkflowMismatch, ReceiptSubjectHeadShaMismatch, - ReceiptComponentCountMismatch, ReceiptUnsuccessfulComponentIdentityNotUnique, - ReceiptUnsuccessfulPopulationMismatch, - ComponentAlertSummary, - ComponentOutcomeRead, ComponentConcluded, ComponentNotConcluded, - FloorComponentFailureMode, floor_component_failure_mode_tag, - summary_outcome_is_unsuccessful, - floor_component_receipt_decode_with, - floor_component_receipt_subject_matches_event -} -import gunbc.falsifier_alert_residue { - LanguageNormalFormResidue, - ResidueTarget, ECMAScript, - ResidueRuntime, GithubScriptAction, - ResidueKind, ExecutableSourceString, - ResidueDisposition, ReplaceWithLanguageIndependentBehavior, - falsifier_alert_residue_registry, - falsifier_alert_embedded_program_residue -} -import extdeps.github.issues { - IssueState, Open, Closed, - IssueStateRead, IssueStateFound, IssueStateUnmodelledWire, - parse_issue_state -} -import std.observation { ObservationOutcome, Failed } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data falsifier_alert_migration_witness_note: String = "ALERT-0..3's executing evidence. Every claim here runs against a FIXTURE authored in this file — a hand-written event payload, a hand-written state marker, a hand-written receipt — never against the live tree or a live API, because what is under test is a decision procedure and its inputs are exactly the discriminating ones. The fixtures are the smallest payloads that cross the boundary being tested plus the one field that decides it, per DESIGN's witness-cost rule.\n\nEACH GREEN CLAIM IS PAIRED WITH A RED CONTROL that fails for the intended reason, because a decoder that accepted everything and a wall that admitted everything would both pass the positive half alone. The admission claims are the ones this matters most for: a trust wall proven only by admitting a good event is indistinguishable from `return true`." - -data alert_expected_schema: NonEmptyStr = "floor-component-receipt/v1" - -fn trusted_event_json() -> String { - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000001,\"name\":\"affected-set-falsifier\",\"workflow_id\":161803,\"path\":\".github/workflows/falsifier.yml\",\"conclusion\":\"failure\",\"html_url\":\"https://github.com/gunb-ai/gunbc/actions/runs/31000000001\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"main\",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":\"schedule\"}}" -} - -fn fork_event_json() -> String { - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000002,\"name\":\"affected-set-falsifier\",\"workflow_id\":161803,\"path\":\".github/workflows/falsifier.yml\",\"conclusion\":\"failure\",\"html_url\":\"https://github.com/gunb-ai/gunbc/actions/runs/31000000002\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"main\",\"head_repository\":{\"full_name\":\"attacker/gunbc\"},\"event\":\"pull_request\"}}" -} - -fn non_main_event_json() -> String { - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000003,\"name\":\"affected-set-falsifier\",\"workflow_id\":161803,\"path\":\".github/workflows/falsifier.yml\",\"conclusion\":\"failure\",\"html_url\":\"https://github.com/gunb-ai/gunbc/actions/runs/31000000003\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"topic/experiment\",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":\"schedule\"}}" -} - -fn other_workflow_event_json() -> String { - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000004,\"name\":\"ci\",\"workflow_id\":271828,\"path\":\".github/workflows/ci.yml\",\"conclusion\":\"success\",\"html_url\":\"https://github.com/gunb-ai/gunbc/actions/runs/31000000004\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"main\",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":\"schedule\"}}" -} - -fn event_missing_conclusion_json() -> String { - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000005,\"name\":\"affected-set-falsifier\",\"workflow_id\":161803,\"path\":\".github/workflows/falsifier.yml\",\"conclusion\":null,\"html_url\":\"https://github.com/gunb-ai/gunbc/actions/runs/31000000005\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"main\",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":\"schedule\"}}" -} - -fn admission_of(json: String) -> FalsifierAlertAdmission { - falsifier_alert_admit(observation: workflow_run_event_from_json(text: json)) -} - -test fn workflow_run_completed_trigger_projects_workflow_run_key() -> Bool { - let emitted = serialize_yaml(v: yaml_mapping(entries: [ - workflow_trigger_entry(trigger: WorkflowRunCompleted { workflows: ["affected-set-falsifier"] }) - ])) - emitted.contains(s: "workflow_run") - && emitted.contains(s: "affected-set-falsifier") - && emitted.contains(s: "completed") -} - -test fn workflow_run_trigger_is_not_the_merge_group_projection() -> Bool { - let emitted = serialize_yaml(v: yaml_mapping(entries: [ - workflow_trigger_entry(trigger: WorkflowRunCompleted { workflows: ["affected-set-falsifier"] }) - ])) - !emitted.contains(s: "merge_group") -} - -test fn workflow_run_event_decodes_every_declared_field() -> Bool { - match workflow_run_event_from_json(text: trusted_event_json()) { - WorkflowRunEventObserved { event: e } => - (e.run_id as String) == "31000000001" - && e.workflow_name == "affected-set-falsifier" - && e.head_branch == "main" - && e.originating_event == "schedule" - && e.activity == "completed" - && e.repository_full_name == "gunb-ai/gunbc" - && e.head_repository_full_name == "gunb-ai/gunbc" - && (e.head_sha as String) == "0123456789abcdef0123456789abcdef01234567" - _ => false - } -} - -test fn workflow_run_event_null_conclusion_is_located_not_absorbed() -> Bool { - match workflow_run_event_from_json(text: event_missing_conclusion_json()) { - WorkflowRunEventMemberMalformed { member: m, detail: _ } => m == "conclusion" - _ => false - } -} - -test fn workflow_run_event_non_json_refuses() -> Bool { - match workflow_run_event_from_json(text: "not json at all") { - WorkflowRunEventMalformed { detail: _ } => true - _ => false - } -} - -test fn trust_wall_admits_the_scheduled_main_falsifier_run() -> Bool { - match admission_of(json: trusted_event_json()) { - AlertAdmitted { event: e } => e.workflow_name == "affected-set-falsifier" - _ => false - } -} - -test fn trust_wall_refuses_a_fork_head_repository() -> Bool { - match admission_of(json: fork_event_json()) { - AlertRefusedRepositoryNotOwned { field: HeadRepository, observed: o, expected: _ } => - o == "attacker/gunbc" - _ => false - } -} - -data fork_field_discriminator_note: String = "The fork claim asserts the FIELD, not just the observed value, because that is what review 49380 found missing. Its fixture is the fork shape exactly: the enclosing repository is ours and only head_repository diverges, so a wall that checked only the enclosing repository would admit it and a refusal that did not name the field would report it identically to a plain wrong-repo delivery. Matching HeadRepository in the pattern means both failures red this claim." - -test fn trust_wall_refuses_a_non_main_head_branch() -> Bool { - match admission_of(json: non_main_event_json()) { - AlertRefusedHeadBranchNotMain { observed: o, expected: _ } => o == "topic/experiment" - _ => false - } -} - -test fn trust_wall_refuses_a_different_workflow() -> Bool { - match admission_of(json: other_workflow_event_json()) { - AlertRefusedWorkflowNotObserved { observed: o, expected: _ } => o == "ci" - _ => false - } -} - -test fn trust_wall_refuses_an_unreadable_event() -> Bool { - match admission_of(json: "{}") { - AlertRefusedEventUnreadable { observation: _ } => true - _ => false - } -} - -fn current_state_marker(first_red: Int, signature: String, last: Int) -> String { - concat( - concat(concat("{\"first_red\":", first_red as String), concat(",\"signature\":\"", signature)), - concat(concat("\",\"last_notification_at\":", last as String), "}") - ) -} - -fn legacy_state_marker(first_red: Int, signature: String) -> String { - concat( - concat(concat("{\"first_red\":", first_red as String), concat(",\"signature\":\"", signature)), - "\"}" - ) -} - -test fn current_state_marker_round_trips() -> Bool { - match falsifier_alert_state_from_payload(payload: current_state_marker(first_red: 1000, signature: "6:witness discovery:WitnessRed:failed", last: 5000)) { - CurrentState { state: s } => - match s.first_red { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } - && s.last_notification_at == 5000 - && (s.signature as String) == "6:witness discovery:WitnessRed:failed" - _ => false - } -} - -test fn legacy_marker_is_its_own_state_not_malformed() -> Bool { - match falsifier_alert_state_from_payload(payload: legacy_state_marker(first_red: 1000, signature: "6:witness discovery:failed")) { - LegacyStateWithoutLastNotification { first_red: f, signature: _ } => - match f { FirstRedObserved { at: t } => t == 1000, FirstRedUnknownBeforeTracking => false } - _ => false - } -} - -test fn malformed_marker_is_not_read_as_legacy() -> Bool { - match falsifier_alert_state_from_payload(payload: "{\"first_red\":\"not-a-number\",\"signature\":\"x\"}") { - StateMalformed { detail: _ } => true - _ => false - } -} - -fn receipt_json(schema: String, workflow: String, run_id: String, head_sha: String) -> String { - concat( - concat( - concat(concat("{\"schema\":\"", schema), concat("\",\"workflow_name\":\"", workflow)), - concat(concat("\",\"run_id\":\"", run_id), concat("\",\"head_sha\":\"", head_sha)) - ), - "\",\"component_count\":0,\"affected_set_cold_control\":null,\"selection_degradation\":null,\"run_terminal\":null,\"unsuccessful_components\":[],\"components\":[]}" - ) -} - -fn trusted_receipt() -> String { - receipt_json( - schema: "floor-component-receipt/v1", - workflow: "affected-set-falsifier", - run_id: "31000000001", - head_sha: "0123456789abcdef0123456789abcdef01234567" - ) -} - -test fn receipt_document_decodes_its_subject() -> Bool { - match floor_component_receipt_decode_with(text: trusted_receipt(), expected_schema: alert_expected_schema) { - ReceiptDecoded { document: d } => - (d.subject.run_id as String) == "31000000001" - && (d.subject.workflow_name as String) == "affected-set-falsifier" - && d.component_count == 0 - _ => false - } -} - -test fn receipt_with_an_unknown_schema_refuses() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_json(schema: "floor-component-receipt/v2", workflow: "affected-set-falsifier", run_id: "1", head_sha: "abc"), - expected_schema: alert_expected_schema - ) { - ReceiptSchemaUnknown { observed: o, expected: _ } => o == "floor-component-receipt/v2" - _ => false - } -} - -test fn receipt_missing_its_subject_refuses_by_member() -> Bool { - match floor_component_receipt_decode_with( - text: "{\"schema\":\"floor-component-receipt/v1\",\"components\":[]}", - expected_schema: alert_expected_schema - ) { - ReceiptMemberAbsent { member: m } => m == "workflow_name" - _ => false - } -} - -test fn receipt_that_is_not_json_refuses() -> Bool { - match floor_component_receipt_decode_with(text: "404", expected_schema: alert_expected_schema) { - ReceiptNotJson { detail: _ } => true - _ => false - } -} - -fn trusted_event() -> WorkflowRunEvent? { - match workflow_run_event_from_json(text: trusted_event_json()) { - WorkflowRunEventObserved { event: e } => Present { value: e } - _ => none - } -} - -fn subject_match_against_trusted_event(receipt: String) -> ReceiptSubjectMatch? { - match floor_component_receipt_decode_with(text: receipt, expected_schema: alert_expected_schema) { - ReceiptDecoded { document: d } => - match trusted_event() { - Present { value: e } => - Present { value: floor_component_receipt_subject_matches_event(subject: d.subject, event: e) } - Absent => none - } - _ => none - } -} - -test fn a_receipt_from_the_triggering_run_matches() -> Bool { - match subject_match_against_trusted_event(receipt: trusted_receipt()) { - Present { value: m } => - match m { - ReceiptSubjectMatches => true - _ => false - } - Absent => false - } -} - -test fn a_receipt_from_another_run_is_refused_by_run_id() -> Bool { - let other = receipt_json( - schema: "floor-component-receipt/v1", - workflow: "affected-set-falsifier", - run_id: "39999999999", - head_sha: "0123456789abcdef0123456789abcdef01234567" - ) - match subject_match_against_trusted_event(receipt: other) { - Present { value: m } => - match m { - ReceiptSubjectRunIdMismatch { receipt: r, event: _ } => (r as String) == "39999999999" - _ => false - } - Absent => false - } -} - -test fn a_receipt_about_another_tree_is_refused_by_head_sha() -> Bool { - let other = receipt_json( - schema: "floor-component-receipt/v1", - workflow: "affected-set-falsifier", - run_id: "31000000001", - head_sha: "ffffffffffffffffffffffffffffffffffffffff" - ) - match subject_match_against_trusted_event(receipt: other) { - Present { value: m } => - match m { - ReceiptSubjectHeadShaMismatch { receipt: _, event: _ } => true - _ => false - } - Absent => false - } -} - -data falsifier_alert_residue_claim_note: String = "ALERT-0's carrier has an executing consumer HERE, which is the difference between a declared residue and a comment. A registry nothing reads is the inert-carrier tier DESIGN §6 names — it looks like accounting and enforces nothing — so the row's disposition and dissolution trigger are asserted rather than merely written. The RED that discriminates this claim is changing the disposition to EmitFromModel, which is exactly the wrong turn this row exists to prevent: it is the decision to build a JavaScript emitter instead of deleting the JavaScript." - -test fn the_embedded_program_is_declared_as_replaceable_residue() -> Bool { - match falsifier_alert_embedded_program_residue { - LanguageNormalFormResidue { - site: site, - target: ECMAScript, - runtime: GithubScriptAction, - kind: ExecutableSourceString, - disposition: ReplaceWithLanguageIndependentBehavior, - dissolution: trigger - } => - (site as String) == ".github/workflows/falsifier-alert.yml" - && (trigger as String) != "" - _ => false - } -} - -test fn the_residue_registry_carries_exactly_the_declared_row() -> Bool { - count(falsifier_alert_residue_registry) == 1 -} - -data falsifier_alert_job_condition_claim_note: String = "The job-level condition is the OUTER half of a wall enforced twice, so it gets its own claim: the in-program checks above prove nothing about the text GitHub evaluates before the job starts. It is asserted on the SERIALIZED output because that string is what GitHub reads, and it is derived from the same constants the in-program wall uses — so a change to the expected workflow or branch that reached only one of the two enforcement points reds here." - -test fn the_job_condition_lowers_from_the_same_constants_as_the_wall() -> Bool { - let c = falsifier_alert_job_condition() - c.contains(s: "github.event.workflow_run.name == 'affected-set-falsifier'") - && c.contains(s: "github.event.workflow_run.head_branch == 'main'") - && c.contains(s: "github.event.workflow_run.event == 'schedule'") - && c.contains(s: "github.event.workflow_run.event == 'workflow_dispatch'") - && c.contains(s: "&&") - && c.contains(s: "||") -} - -data falsifier_alert_condition_precedence_note: String = "The condition is asserted to be DISTRIBUTED — the workflow and branch equalities appearing in BOTH originating-event arms — because that is what makes it precedence-safe without parentheses. The factored shape `A && B && (s || d)` is what a reader would naturally write, and GitHub's tighter && binding turns it into `(A && B && s) || d` if the parentheses are ever lost, whose right arm admits a workflow_dispatch run of any workflow on any branch. This claim reds if the condition is refactored into the factored shape, which is the refactor that looks like a simplification and is not." - -test fn the_job_condition_is_distributed_so_precedence_needs_no_grouping() -> Bool { - let c = falsifier_alert_job_condition() - let arm_schedule = "github.event.workflow_run.name == 'affected-set-falsifier' && github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.event == 'schedule'" - let arm_dispatch = "github.event.workflow_run.name == 'affected-set-falsifier' && github.event.workflow_run.head_branch == 'main' && github.event.workflow_run.event == 'workflow_dispatch'" - c == concat(concat(arm_schedule, " || "), arm_dispatch) -} - -data issue_state_read_claim_note: String = "The unmodelled-wire arm is claimed because it is the one that would otherwise be indistinguishable from a missing member. GitHub adding a state is a realistic future event, and the decode must report WHAT it saw rather than that it saw nothing." - -test fn an_unmodelled_issue_state_reports_what_it_saw() -> Bool { - match parse_issue_state(raw: "merged") { - IssueStateUnmodelledWire { raw: r } => r == "merged" - _ => false - } -} - -test fn the_modelled_issue_states_decode() -> Bool { - match parse_issue_state(raw: "open") { - IssueStateFound { state: Open } => - match parse_issue_state(raw: "closed") { - IssueStateFound { state: Closed } => true - _ => false - } - _ => false - } -} - -data alert35_strict_boundary_note: String = "ALERT-3.5's evidence. Every claim here plants ONE wrong value in an otherwise-valid fixture and requires a LOCATED refusal naming the member that was wrong. That shape is the point: a decoder that refuses for the right reason and a decoder that refuses for some reason are indistinguishable on a fixture that is wrong in several ways at once, and the second is useless to debug against." - -data numeric_plant_note: String = "THE PLANT REPLACES THE VALUE IN PLACE; IT DOES NOT APPEND A DUPLICATE MEMBER. The first version of these fixtures appended a second copy of the member carrying a number, and every one of them passed — but they passed because json_object_unique_member refuses a DUPLICATED member, which fires before any type check and fires identically whether the decoder is strict or permissive. Proven by execution: reverting head_branch to the permissive decoder left that claim green, so it was measuring duplicate detection and reporting it as type strictness. Each field now has exactly one occurrence carrying a raw number, so the only thing that can refuse is the type check being asserted." - -fn event_json_with(name: String, conclusion: String, head_sha: String, head_branch: String, originating: String) -> String { - concat(concat(concat(concat(concat(concat(concat(concat(concat( - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000009,\"workflow_id\":161803,\"path\":\".github/workflows/falsifier.yml\",\"name\":", - name), ",\"conclusion\":"), conclusion), ",\"html_url\":\"https://x\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":"), - head_sha), ",\"head_branch\":"), head_branch), - ",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":"), concat(originating, "}}")) -} - -data plant_valid_name: String = "\"affected-set-falsifier\"" -data plant_valid_conclusion: String = "\"failure\"" -data plant_valid_head_sha: String = "\"0123456789abcdef0123456789abcdef01234567\"" -data plant_valid_head_branch: String = "\"main\"" -data plant_valid_event: String = "\"schedule\"" -data plant_number: String = "12345" - -fn numeric_plant_refuses_at(field: String) -> Bool { - let text = if field == "name" { - event_json_with(name: plant_number, conclusion: plant_valid_conclusion, head_sha: plant_valid_head_sha, head_branch: plant_valid_head_branch, originating: plant_valid_event) - } else if field == "conclusion" { - event_json_with(name: plant_valid_name, conclusion: plant_number, head_sha: plant_valid_head_sha, head_branch: plant_valid_head_branch, originating: plant_valid_event) - } else if field == "head_sha" { - event_json_with(name: plant_valid_name, conclusion: plant_valid_conclusion, head_sha: plant_number, head_branch: plant_valid_head_branch, originating: plant_valid_event) - } else if field == "head_branch" { - event_json_with(name: plant_valid_name, conclusion: plant_valid_conclusion, head_sha: plant_valid_head_sha, head_branch: plant_number, originating: plant_valid_event) - } else { - event_json_with(name: plant_valid_name, conclusion: plant_valid_conclusion, head_sha: plant_valid_head_sha, head_branch: plant_valid_head_branch, originating: plant_number) - } - match workflow_run_event_from_json(text: text) { - WorkflowRunEventMemberMalformed { member: m, detail: _ } => m == field - _ => false - } -} - -test fn the_all_valid_plant_baseline_decodes() -> Bool { - match workflow_run_event_from_json(text: event_json_with(name: plant_valid_name, conclusion: plant_valid_conclusion, head_sha: plant_valid_head_sha, head_branch: plant_valid_head_branch, originating: plant_valid_event)) { - WorkflowRunEventObserved { event: e } => e.head_branch == "main" - _ => false - } -} - -test fn a_numeric_workflow_name_refuses_located() -> Bool { - numeric_plant_refuses_at(field: "name") -} - -test fn a_numeric_conclusion_refuses_located() -> Bool { - numeric_plant_refuses_at(field: "conclusion") -} - -test fn a_numeric_head_sha_refuses_located() -> Bool { - numeric_plant_refuses_at(field: "head_sha") -} - -test fn a_numeric_head_branch_refuses_located() -> Bool { - numeric_plant_refuses_at(field: "head_branch") -} - -test fn a_numeric_originating_event_refuses_located() -> Bool { - numeric_plant_refuses_at(field: "event") -} - -test fn the_run_id_still_accepts_its_numeric_wire_form() -> Bool { - match workflow_run_event_from_json(text: trusted_event_json()) { - WorkflowRunEventObserved { event: e } => (e.run_id as String) == "31000000001" - _ => false - } -} - -data workflow_path_claim_note: String = "The display name and the file path are asserted as SEPARATE refusals because they are separate facts: a workflow can be renamed without moving, and a file can be moved without being renamed. A wall that checked only the name would admit a run of a different file that had been given the expected name." - -fn event_with_path(path: String) -> String { - concat(concat( - "{\"action\":\"completed\",\"repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"workflow_run\":{\"id\":31000000010,\"workflow_id\":161803,\"path\":\"", - path), "\",\"name\":\"affected-set-falsifier\",\"conclusion\":\"failure\",\"html_url\":\"https://x\",\"run_started_at\":\"2026-08-06T00:00:00Z\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"head_branch\":\"main\",\"head_repository\":{\"full_name\":\"gunb-ai/gunbc\"},\"event\":\"schedule\"}}") -} - -test fn the_trust_wall_refuses_an_impostor_file_wearing_the_expected_name() -> Bool { - match falsifier_alert_admit(observation: workflow_run_event_from_json(text: event_with_path(path: ".github/workflows/attacker.yml"))) { - AlertRefusedWorkflowPathNotObserved { observed: o, expected: _ } => - o == ".github/workflows/attacker.yml" - _ => false - } -} - -test fn the_trust_wall_admits_the_expected_workflow_file() -> Bool { - match falsifier_alert_admit(observation: workflow_run_event_from_json(text: event_with_path(path: ".github/workflows/falsifier.yml"))) { - AlertAdmitted { event: _ } => true - _ => false - } -} - -data malformed_state_claim_note: String = "The load-bearing claim of item B: a malformed marker must NOT reach any notify arm, because every notify arm is followed by a write that would overwrite the corrupt marker and destroy the only record of when the incident began. THE WITNESSES FOR IT NO LONGER LIVE IN THIS FILE. They moved to falsifier_alert_decision_witness_test when the forked throttle decision was deleted, and they execute there against alert_decision as a_decoded_malformed_marker_refuses_instead_of_starting_a_new_incident. This note is kept where the claim was first argued; a reader looking for its executing evidence should look there, not here." - -data receipt_strictness_claim_note: String = "Item C's claims. The count check is the one worth naming: the decoder previously IGNORED the wire component_count and recomputed it from the array, which is the recompute-instead-of-check pattern — it cannot disagree with itself, so it can never report that the producer and its own array are inconsistent. Checking the declared value against the decoded one is what makes the field mean anything." - -fn receipt_with(component_count: String, components: String, unsuccessful: String) -> String { - concat(concat(concat(concat( - "{\"schema\":\"floor-component-receipt/v1\",\"workflow_name\":\"affected-set-falsifier\",\"run_id\":\"31000000001\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"component_count\":", - component_count), ",\"affected_set_cold_control\":null,\"selection_degradation\":null,\"run_terminal\":null,\"unsuccessful_components\":"), - unsuccessful), concat(",\"components\":", concat(components, "}"))) -} - -data one_component: String = "{\"index\":6,\"label\":\"witness discovery\",\"outcome\":\"failed\",\"error\":\"claim is false\",\"output\":\"\",\"failure_mode\":\"WitnessRed\"}" - -data one_done_component: String = "{\"index\":6,\"label\":\"witness discovery\",\"outcome\":\"done\",\"failure_mode\":\"none\"}" - -test fn a_declared_component_count_that_disagrees_with_the_array_refuses() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "7", components: concat(concat("[", one_done_component), "]"), unsuccessful: "[]"), - expected_schema: alert_expected_schema - ) { - ReceiptComponentCountMismatch { declared: d, decoded: n } => d == "7" && n == 1 - _ => false - } -} - -test fn an_agreeing_component_count_decodes() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", one_done_component), "]"), unsuccessful: "[]"), - expected_schema: alert_expected_schema - ) { - ReceiptDecoded { document: doc } => doc.component_count == 1 - _ => false - } -} - -test fn duplicate_unsuccessful_component_identities_refuse() -> Bool { - let two = concat(concat(concat("[", one_component), concat(",", one_component)), "]") - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "2", components: concat(concat(concat("[", one_component), concat(",", one_component)), "]"), unsuccessful: two), - expected_schema: alert_expected_schema - ) { - ReceiptUnsuccessfulComponentIdentityNotUnique { count: n } => n == 2 - _ => false - } -} - -test fn the_alert_summary_decodes_the_four_signature_fields() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", one_component), "]"), unsuccessful: concat(concat("[", one_component), "]")), - expected_schema: alert_expected_schema - ) { - ReceiptDecoded { document: doc } => - match doc.unsuccessful_summaries.first() { - Present { value: sm } => - sm.index == 6 - && (sm.label as String) == "witness discovery" - && summary_outcome_is_unsuccessful(s: sm) - && floor_component_failure_mode_tag(m: sm.failure_mode) == "WitnessRed" - Absent => false - } - _ => false - } -} - -test fn an_unsuccessful_component_missing_failure_mode_refuses_located() -> Bool { - let no_mode = "{\"index\":6,\"label\":\"witness discovery\",\"outcome\":\"failed\"}" - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", no_mode), "]"), unsuccessful: concat(concat("[", no_mode), "]")), - expected_schema: alert_expected_schema - ) { - ReceiptMemberAbsent { member: m } => m == "failure_mode" - _ => false - } -} - -test fn a_required_auxiliary_member_absent_refuses_rather_than_becoming_null() -> Bool { - match floor_component_receipt_decode_with( - text: "{\"schema\":\"floor-component-receipt/v1\",\"workflow_name\":\"affected-set-falsifier\",\"run_id\":\"1\",\"head_sha\":\"abc\",\"component_count\":0,\"unsuccessful_components\":[],\"components\":[]}", - expected_schema: alert_expected_schema - ) { - ReceiptMemberAbsent { member: m } => m == "affected_set_cold_control" - _ => false - } -} - -test fn a_numeric_workflow_name_in_the_receipt_refuses() -> Bool { - match floor_component_receipt_decode_with( - text: "{\"schema\":\"floor-component-receipt/v1\",\"workflow_name\":42,\"run_id\":\"1\",\"head_sha\":\"abc\",\"component_count\":0,\"affected_set_cold_control\":null,\"selection_degradation\":null,\"run_terminal\":null,\"unsuccessful_components\":[],\"components\":[]}", - expected_schema: alert_expected_schema - ) { - ReceiptMemberMalformed { member: m, detail: _ } => m == "workflow_name" - _ => false - } -} - -data component_summary_strictness_note: String = "The component summary's string fields get the same numeric-plant treatment as the event envelope, because they are the same class and were the residue review 49571 found: one decoder served all four fields and widened numbers on all four while the note beside it claimed only index did. Each plant replaces a value in place — not appended as a duplicate — for the reason the event plants record." - -fn component_with(index: String, label: String, outcome: String, mode: String) -> String { - concat(concat(concat(concat(concat(concat(concat( - "{\"index\":", index), ",\"label\":"), label), ",\"outcome\":"), outcome), ",\"failure_mode\":"), concat(mode, "}")) -} - -data csum_valid_index: String = "6" -data csum_valid_label: String = "\"witness discovery\"" -data csum_valid_outcome: String = "\"done\"" -data csum_valid_mode: String = "\"none\"" - -fn decode_receipt_with_component(component: String) -> FloorComponentReceiptDecoding { - floor_component_receipt_decode_with( - text: receipt_with( - component_count: "1", - components: concat(concat("[", component), "]"), - unsuccessful: "[]" - ), - expected_schema: alert_expected_schema - ) -} - -fn component_numeric_plant_refuses_at(field: String) -> Bool { - let c = if field == "label" { - component_with(index: csum_valid_index, label: plant_number, outcome: csum_valid_outcome, mode: csum_valid_mode) - } else if field == "outcome" { - component_with(index: csum_valid_index, label: csum_valid_label, outcome: plant_number, mode: csum_valid_mode) - } else { - component_with(index: csum_valid_index, label: csum_valid_label, outcome: csum_valid_outcome, mode: plant_number) - } - match decode_receipt_with_component(component: c) { - ReceiptMemberMalformed { member: m, detail: _ } => m == field - _ => false - } -} - -test fn a_numeric_component_label_refuses_located() -> Bool { - component_numeric_plant_refuses_at(field: "label") -} - -test fn a_numeric_component_outcome_refuses_located() -> Bool { - component_numeric_plant_refuses_at(field: "outcome") -} - -test fn a_numeric_component_failure_mode_refuses_located() -> Bool { - component_numeric_plant_refuses_at(field: "failure_mode") -} - -test fn the_component_index_still_accepts_its_numeric_wire_form() -> Bool { - match decode_receipt_with_component(component: component_with(index: csum_valid_index, label: csum_valid_label, outcome: csum_valid_outcome, mode: csum_valid_mode)) { - ReceiptDecoded { document: doc } => - match doc.component_summaries.first() { - Present { value: sm } => sm.index == 6 - Absent => false - } - _ => false - } -} - -data operator_strict_boundary_claims_note: String = "The operator verdict's four decision-grain corrections, each asserted on the arm that was NOT already working. Every one of these fixtures decoded cleanly before the corrections landed, which is the whole point: the boundary guaranteed the fields were PRESENT and it did not guarantee they MEANT anything, and presence is invisible to a witness that only ever feeds well-formed input." - -data component_with_text_index: String = "{\"index\":\"6\",\"label\":\"witness discovery\",\"outcome\":\"done\",\"failure_mode\":\"none\"}" - -test fn a_text_component_index_refuses_rather_than_being_read_as_an_identity() -> Bool { - match decode_receipt_with_component(component: component_with_text_index) { - ReceiptMemberMalformed { member: m, detail: _ } => m == "index" - _ => false - } -} - -data component_with_invented_outcome: String = "{\"index\":6,\"label\":\"witness discovery\",\"outcome\":\"banana\",\"failure_mode\":\"none\"}" - -test fn an_outcome_outside_the_modelled_vocabulary_refuses() -> Bool { - match decode_receipt_with_component(component: component_with_invented_outcome) { - ReceiptMemberMalformed { member: m, detail: _ } => m == "outcome" - _ => false - } -} - -data component_with_invented_mode: String = "{\"index\":6,\"label\":\"witness discovery\",\"outcome\":\"done\",\"failure_mode\":\"looks-plausible\"}" - -test fn a_failure_mode_outside_the_modelled_vocabulary_refuses() -> Bool { - match decode_receipt_with_component(component: component_with_invented_mode) { - ReceiptMemberMalformed { member: m, detail: _ } => m == "failure_mode" - _ => false - } -} - -test fn a_failed_outcome_without_its_error_payload_refuses_rather_than_defaulting() -> Bool { - match decode_receipt_with_component(component: "{\"index\":6,\"label\":\"x\",\"outcome\":\"failed\",\"output\":\"\",\"failure_mode\":\"WitnessRed\"}") { - ReceiptMemberMalformed { member: m, detail: _ } => m == "outcome" - _ => false - } -} - -data population_join_claims_note: String = "The identity join, asserted in BOTH directions, because the two failures are not symmetric in consequence. A row listed as unsuccessful that is not failing over-reports and is merely noisy; a failing row MISSING from the list under-reports, and the alert then tells an operator that a component is fine while the receipt beside it says otherwise. The second is the one a uniqueness check could never see, so it is the one written first." - -test fn a_failing_component_omitted_from_the_unsuccessful_list_refuses() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", one_component), "]"), unsuccessful: "[]"), - expected_schema: alert_expected_schema - ) { - ReceiptUnsuccessfulPopulationMismatch { listed: l, derived: d } => l == 0 && d == 1 - _ => false - } -} - -test fn a_successful_component_listed_as_unsuccessful_refuses() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", one_done_component), "]"), unsuccessful: concat(concat("[", one_done_component), "]")), - expected_schema: alert_expected_schema - ) { - ReceiptUnsuccessfulPopulationMismatch { listed: l, derived: d } => l == 1 && d == 0 - _ => false - } -} - -test fn an_unsuccessful_row_naming_an_absent_component_refuses() -> Bool { - let ghost = "{\"index\":99,\"label\":\"never ran\",\"outcome\":\"failed\",\"error\":\"e\",\"output\":\"\",\"failure_mode\":\"WitnessRed\"}" - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", one_component), "]"), unsuccessful: concat(concat("[", ghost), "]")), - expected_schema: alert_expected_schema - ) { - ReceiptUnsuccessfulPopulationMismatch { listed: _, derived: _ } => true - _ => false - } -} - -test fn the_matching_population_decodes() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", one_component), "]"), unsuccessful: concat(concat("[", one_component), "]")), - expected_schema: alert_expected_schema - ) { - ReceiptDecoded { document: doc } => count(doc.unsuccessful_summaries) == 1 && count(doc.component_summaries) == 1 - _ => false - } -} - -test fn a_string_component_count_refuses_rather_than_comparing_as_text() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "\"1\"", components: concat(concat("[", one_done_component), "]"), unsuccessful: "[]"), - expected_schema: alert_expected_schema - ) { - ReceiptMemberMalformed { member: m, detail: _ } => m == "component_count" - _ => false - } -} - -test fn the_unrecorded_failure_mode_the_writer_emits_decodes() -> Bool { - match decode_receipt_with_component(component: "{\"index\":6,\"label\":\"x\",\"outcome\":\"done\",\"failure_mode\":\"unrecorded\"}") { - ReceiptDecoded { document: _ } => true - _ => false - } -} - -data pair_and_strict_number_claims_note: String = "The operator's live-head items B and C. Every fixture below carries two individually VALID typed values, or a numeric lexeme JSON is happy to call a number — so each one decoded cleanly under the previous revision and would have flowed into routing and incident identity." - -test fn an_impossible_outcome_and_mode_pair_refuses_even_though_both_are_typed() -> Bool { - match decode_receipt_with_component(component: "{\"index\":6,\"label\":\"x\",\"outcome\":\"done\",\"failure_mode\":\"WitnessRed\"}") { - ReceiptMemberMalformed { member: m, detail: _ } => m == "outcome" - _ => false - } -} - -test fn a_failed_outcome_claiming_no_failure_mode_refuses() -> Bool { - match decode_receipt_with_component(component: "{\"index\":6,\"label\":\"x\",\"outcome\":\"failed\",\"error\":\"e\",\"output\":\"\",\"failure_mode\":\"none\"}") { - ReceiptMemberMalformed { member: m, detail: _ } => m == "outcome" - _ => false - } -} - -test fn the_unrecorded_mode_keeps_its_broader_relationship() -> Bool { - let c = "{\"index\":6,\"label\":\"x\",\"outcome\":\"failed\",\"error\":\"e\",\"output\":\"\",\"failure_mode\":\"unrecorded\"}" - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "1", components: concat(concat("[", c), "]"), unsuccessful: concat(concat("[", c), "]")), - expected_schema: alert_expected_schema - ) { - ReceiptDecoded { document: _ } => true - _ => false - } -} - -test fn a_failed_outcome_output_is_read_rather_than_fabricated() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with( - component_count: "1", - components: "[{\"index\":6,\"label\":\"x\",\"outcome\":\"failed\",\"error\":\"e\",\"output\":\"the real captured output\",\"failure_mode\":\"WitnessRed\"}]", - unsuccessful: "[{\"index\":6,\"label\":\"x\",\"outcome\":\"failed\",\"error\":\"e\",\"output\":\"the real captured output\",\"failure_mode\":\"WitnessRed\"}]" - ), - expected_schema: alert_expected_schema - ) { - ReceiptDecoded { document: doc } => - match doc.unsuccessful_summaries.first() { - Present { value: sm } => - match sm.outcome { - ComponentConcluded { outcome: o } => - match o { - Failed { error: _, output: out } => out == "the real captured output" - _ => false - } - ComponentNotConcluded => false - } - Absent => false - } - _ => false - } -} - -test fn a_failed_outcome_missing_its_output_member_refuses() -> Bool { - match decode_receipt_with_component(component: "{\"index\":6,\"label\":\"x\",\"outcome\":\"failed\",\"error\":\"e\",\"failure_mode\":\"WitnessRed\"}") { - ReceiptMemberMalformed { member: m, detail: _ } => m == "outcome" - _ => false - } -} - -data strict_natural_claims_note: String = "Four lexemes JSON calls numbers and a cardinal index cannot be. Under parse_int each produced a value — a truncation, a wrong magnitude, or a negative position — with nothing marking the input as outside what the field means." - -test fn a_negative_component_index_refuses() -> Bool { - match decode_receipt_with_component(component: "{\"index\":-1,\"label\":\"x\",\"outcome\":\"done\",\"failure_mode\":\"none\"}") { - ReceiptMemberMalformed { member: m, detail: _ } => m == "index" - _ => false - } -} - -test fn a_fractional_component_index_refuses() -> Bool { - match decode_receipt_with_component(component: "{\"index\":6.5,\"label\":\"x\",\"outcome\":\"done\",\"failure_mode\":\"none\"}") { - ReceiptMemberMalformed { member: m, detail: _ } => m == "index" - _ => false - } -} - -test fn an_exponent_component_index_refuses() -> Bool { - match decode_receipt_with_component(component: "{\"index\":6e3,\"label\":\"x\",\"outcome\":\"done\",\"failure_mode\":\"none\"}") { - ReceiptMemberMalformed { member: m, detail: _ } => m == "index" - _ => false - } -} - -test fn a_negative_component_count_refuses() -> Bool { - match floor_component_receipt_decode_with( - text: receipt_with(component_count: "-1", components: "[]", unsuccessful: "[]"), - expected_schema: alert_expected_schema - ) { - ReceiptMemberMalformed { member: m, detail: _ } => m == "component_count" - _ => false - } -} diff --git a/dag/test/claim/falsifier_lane_witness_test.dag b/dag/test/claim/falsifier_lane_witness_test.dag deleted file mode 100644 index 21362baaa7a..00000000000 --- a/dag/test/claim/falsifier_lane_witness_test.dag +++ /dev/null @@ -1,69 +0,0 @@ -module test.claim.falsifier_lane_witness - -import gunbc.falsifier_lane { - witness_planned_components_skip_unenrolled_and_renumber, - witness_lane_names_are_distinct, - witness_standing_green_on_matching_plan, - witness_standing_reds_on_missing_component, - witness_standing_reds_on_surplus_component, - witness_standing_reds_on_duplicate_component, - witness_standing_fails_closed_on_empty_plan, - witness_standing_reds_when_counts_agree_but_identities_do_not, - witness_complete_standing_does_not_project_to_observed, - witness_incomplete_standing_refuses_observed, - witness_routing_attributes_failing_component_to_owner, - witness_routing_refuses_lane_undetermined, - witness_routing_refuses_owner_undeclared_but_names_lane, - witness_routing_empty_owner_roster_still_determines_lane, - witness_unsuccessful_routings_exclude_done_rows, - witness_failure_class_separates_budget_from_witness_red, - witness_failure_class_records_the_infra_collapse, - witness_failing_set_names_lane_and_class_per_component, - witness_class_signature_distinguishes_a_class_transition, - witness_class_signature_stable_when_class_persists -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data falsifier_lane_witness_grain_note: String = "Every row here is fixture-grain: hand-built enrollment lists and component rows constructed through the receipt's own floor_component_row_of, never a scan of the live tree and never a real cadence receipt. The live-plan half — that the falsifier schedule and the lane attribution stay derived from one enrollment list — is proven in src/v2/test/claim/falsifier_lane_plan_agreement_test.dag, which reaches the plan module and carries its own disposition. Keeping the two apart is the Class C split: a stamp is file-grain, so a file mixing fixture algebra with a live-plan read would have to take the fail-closed value and lose predict-skip eligibility for rows that genuinely do not read the tree." - -test fn falsifier_lane_planned_roster_is_enrollment_ordered() -> Bool { - witness_planned_components_skip_unenrolled_and_renumber() - && witness_lane_names_are_distinct() -} - -test fn falsifier_run_standing_is_an_identity_join() -> Bool { - witness_standing_green_on_matching_plan() - && witness_standing_reds_on_missing_component() - && witness_standing_reds_on_surplus_component() - && witness_standing_reds_on_duplicate_component() - && witness_standing_fails_closed_on_empty_plan() - && witness_standing_reds_when_counts_agree_but_identities_do_not() -} - -test fn falsifier_run_standing_never_projects_to_observed() -> Bool { - witness_complete_standing_does_not_project_to_observed() - && witness_incomplete_standing_refuses_observed() -} - -test fn falsifier_routing_attributes_or_refuses_by_named_cause() -> Bool { - witness_routing_attributes_failing_component_to_owner() - && witness_routing_refuses_lane_undetermined() - && witness_routing_refuses_owner_undeclared_but_names_lane() - && witness_routing_empty_owner_roster_still_determines_lane() - && witness_unsuccessful_routings_exclude_done_rows() -} - -data falsifier_failing_set_test_note: String = "The per-window failing-set rows. falsifier_class_signature_marks_transitions is the control for the live defect that reprioritized this lane: issue #7737 stayed open and accurate as a status while its BODY described a failure class that had stopped occurring thirty hours earlier, because nothing re-derived the failing set per window and nothing compared one window's classes to the previous one's." - -test fn falsifier_failure_class_is_carried_per_component() -> Bool { - witness_failure_class_separates_budget_from_witness_red() - && witness_failure_class_records_the_infra_collapse() - && witness_failing_set_names_lane_and_class_per_component() -} - -test fn falsifier_class_signature_marks_transitions() -> Bool { - witness_class_signature_distinguishes_a_class_transition() - && witness_class_signature_stable_when_class_persists() -} diff --git a/dag/test/claim/falsifier_run_control_witness_test.dag b/dag/test/claim/falsifier_run_control_witness_test.dag deleted file mode 100644 index d5abae08112..00000000000 --- a/dag/test/claim/falsifier_run_control_witness_test.dag +++ /dev/null @@ -1,65 +0,0 @@ -module test.claim.falsifier_run_control_witness_test - -import std.types { Bool, String, Int } -import gunbc.falsifier_run_control { - falsifier_required_control_roles, - falsifier_control_prerequisite_if, - falsifier_control_prerequisite_execution_proof_note, - compile_clean_cold_control_step, - native_cache_cold_control_step, - AffectedSetPredictOnlyCold, - CompileCleanWholeTreeCold, - NativeCacheCold, -} -import gunbc.falsifier_workflow { expected_falsifier_yml } -import extdeps.github.actions { RunStep } - -data falsifier_run_control_witness_note: String = "F0 executing consumer (operator mandate 2026-08-04): cold controls must use always()+release_build prerequisite, not default success(). Verified defect on run 30935833427 where steps 13-14 were SKIPPED while step 12 receipt upload PASSED. The closed control-role roster must enumerate exactly three roles so a control cannot silently vanish." - -test fn falsifier_required_control_roles_is_closed_population_of_three() -> Bool { - count(xs: falsifier_required_control_roles) == 3 - && falsifier_required_control_roles[0] == AffectedSetPredictOnlyCold - && falsifier_required_control_roles[1] == CompileCleanWholeTreeCold - && falsifier_required_control_roles[2] == NativeCacheCold -} - -test fn falsifier_cold_controls_use_prerequisite_if_not_default_success() -> Bool { - match compile_clean_cold_control_step() { - RunStep { name: _, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: cc, continue_on_error: _, timeout_minutes: _ } => - match native_cache_cold_control_step() { - RunStep { name: _, id: _, run: _, shell: _, env: _, working_directory: _, if_condition: nc, continue_on_error: _, timeout_minutes: _ } => - match cc { - Present { value: s } => - (s == falsifier_control_prerequisite_if) - && match nc { - Present { value: s2 } => s2 == falsifier_control_prerequisite_if - _ => false - } - _ => false - } - _ => false - } - _ => false - } -} - -test fn falsifier_yml_cold_controls_carry_prerequisite_if() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: falsifier_control_prerequisite_if) - && string_contains(s: expected_falsifier_yml(), pattern: "release_build") -} - -test fn falsifier_prerequisite_if_discriminates_from_bare_always() -> Bool { - falsifier_control_prerequisite_if != "always()" - && string_contains(s: falsifier_control_prerequisite_if, pattern: "release_bins") -} - -test fn falsifier_prerequisite_if_cites_same_job_step() -> Bool { - !string_contains(s: falsifier_control_prerequisite_if, pattern: "release_build") - && string_contains(s: falsifier_control_prerequisite_if, pattern: "steps.release_bins.outcome") -} - -test fn falsifier_execution_proof_note_states_the_real_acceptance_gate() -> Bool { - string_contains(s: falsifier_control_prerequisite_execution_proof_note, pattern: "condition SHAPE") - && string_contains(s: falsifier_control_prerequisite_execution_proof_note, pattern: "never 'skipped'") - && string_contains(s: falsifier_control_prerequisite_execution_proof_note, pattern: "not entitled to be declared done at merge time") -} diff --git a/dag/test/claim/falsifier_workflow_witness_test.dag b/dag/test/claim/falsifier_workflow_witness_test.dag deleted file mode 100644 index 1a32e8025d5..00000000000 --- a/dag/test/claim/falsifier_workflow_witness_test.dag +++ /dev/null @@ -1,488 +0,0 @@ -module test.claim.falsifier_workflow_witness_test - -import std.dissolution { dissolution_description } - -import std.types { Bool, Int, String } -import extdeps.cron.schedule_model { render_cron_schedule } -import gunbc.falsifier_workflow { - falsifier_cadence_cron, - falsifier_workflow, - gunbc_falsifier_job_backstop_timeout_minutes, - gunbc_falsifier_build_job_backstop_timeout_minutes, - gunbc_falsifier_selection_control_job_backstop_timeout_minutes, - gunbc_falsifier_cold_corpus_job_backstop_timeout_minutes, - gunbc_falsifier_aggregate_verdict_job_backstop_timeout_minutes, - gunbc_falsifier_step_timeout_minutes, - gunbc_falsifier_step_timeout_basis_is_measured_not_composed, - gunbc_falsifier_receipt_flush_allowance_minutes, - gunbc_falsifier_soft_deadline_minutes, - gunbc_falsifier_soft_deadline_precedes_the_hard_kill, - falsifier_aggregate_verdict_if, - falsifier_aggregate_verdict_shell_emit_dissolution_trigger, - falsifier_aggregate_verdict_write_receipt, - expected_falsifier_yml -} -import gunbc.falsifier_run_control { - gunbc_falsifier_compile_clean_cold_control_timeout_minutes, - gunbc_falsifier_native_cache_cold_control_timeout_minutes, - falsifier_control_prerequisite_if, -} -import gunbc.falsifier_cold_corpus_execution { - falsifier_cold_corpus_execution_receipt_path, - falsifier_cold_corpus_job_id, - classify_cold_corpus_execution, - cold_corpus_execution_is_executed, - cold_corpus_execution_receipt_json, - cold_corpus_execution_tag, - corpus_not_run_build_failed_tag, - corpus_not_run_build_cancelled_tag, - corpus_not_run_build_skipped_tag, - corpus_not_run_cold_failed_before_receipt_tag, - corpus_not_run_cold_receipt_artifact_absent_tag, - aggregate_shell_receipt_build_failed, - aggregate_shell_receipt_build_cancelled, - aggregate_shell_receipt_build_skipped, - aggregate_shell_receipt_cold_skipped, - aggregate_shell_receipt_cold_cancelled, - aggregate_shell_receipt_cold_failed_before_receipt, - aggregate_shell_receipt_cold_receipt_artifact_absent, - aggregate_shell_receipt_corpus_executed, - corpus_executed_tag, - corpus_not_run_tag, - cadence_verdict_should_fail, - JobOutcomeSuccess, - JobOutcomeFailure, - JobOutcomeSkipped, - JobOutcomeCancelled, - BuildJobFailed, - ColdCorpusFailedBeforeReceipt, - ColdCorpusReceiptArtifactAbsent, - CorpusExecuted, - CorpusNotRun, -} -import gunbc.floor_component_receipt { - floor_component_receipt_path, - floor_component_receipt_artifact_name, - floor_component_receipt_schema, -} -import gunbc.ci_workflow { gunbc_ci_selection_control_step_timeout_minutes } -import extdeps.github.actions { ConcurrencyMappingQueueNotMax, CancelInProgressBool } -import gunbc.ci_workflow { - gunbc_ci_release_build_step_timeout_minutes, gunbc_ci_aux_step_timeout_minutes, gunbc_ci_prelude_allowance_minutes, - gunbc_ci_artifact_transfer_step_timeout_minutes -} -import gunbc.ci_yaml_emit { expected_ci_yml } -import gunbc.ci_workflow { ci_workflow } -import gunbc.ci_materialization { step_display_name } -import v2.workflow.ci_floor_peak_emit { - ci_floor_phase_journal_artifact_name -} -import extdeps.github.actions { Step } -import gunbc.generated_artifact { FalsifierYamlArtifact, artifact_path } -import gunbc.shell_bash_runner { bash_escape_for_double_quotes } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -test fn falsifier_cron_renders_every_four_hours_utc() -> Bool { - render_cron_schedule(s: falsifier_cadence_cron) == "0 0,4,8,12,16,20 * * *" -} - -test fn falsifier_cron_render_discriminates() -> Bool { - !(render_cron_schedule(s: falsifier_cadence_cron) == "0 7 * * *") -} - -test fn falsifier_concurrency_queues_not_cancels() -> Bool { - match falsifier_workflow.concurrency { - Present { value: spec } => - match spec { - ConcurrencyMappingQueueNotMax { group: g, cancel_in_progress: cip, explicit_single: _ } => - g == "affected-set-falsifier" && - match cip { - Present { value: c } => - match c { - CancelInProgressBool { value: v } => !v - _ => false - } - _ => false - } - _ => false - } - _ => false - } -} - -test fn falsifier_step_timeout_basis_is_measured_not_composed() -> Bool { - gunbc_falsifier_step_timeout_basis_is_measured_not_composed() -} - -test fn falsifier_backstop_is_step_sum_plus_prelude() -> Bool { - gunbc_falsifier_job_backstop_timeout_minutes() == (gunbc_ci_release_build_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_selection_control_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_falsifier_step_timeout_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_falsifier_compile_clean_cold_control_timeout_minutes + gunbc_falsifier_native_cache_cold_control_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes + gunbc_ci_artifact_transfer_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes) - && gunbc_falsifier_job_backstop_timeout_minutes() == (gunbc_falsifier_build_job_backstop_timeout_minutes() + gunbc_falsifier_selection_control_job_backstop_timeout_minutes() + gunbc_falsifier_cold_corpus_job_backstop_timeout_minutes() + gunbc_falsifier_aggregate_verdict_job_backstop_timeout_minutes()) - && !(gunbc_falsifier_job_backstop_timeout_minutes() == gunbc_falsifier_step_timeout_minutes) -} - -data falsifier_soft_deadline_witness_note: String = "The soft deadline's ONE correctness property is an ordering, not a value: it must fall strictly inside the step cap it is subtracted from, because a deadline at or past the runner's SIGKILL cannot fire and would be a mechanism that exists without ever executing. Asserting the derivation rather than the number 167 is what makes that survive a re-basis of the cap — the pair below moves together by construction, and a witness pinned to a literal would have to be edited in the same change and could be edited wrongly. The strict-inequality half is the load-bearing one; the positive-allowance half is what forbids the degenerate derivation where allowance is zero and the two collapse onto the same instant." - -test fn falsifier_soft_deadline_is_derived_and_strictly_inside_the_hard_cap() -> Bool { - gunbc_falsifier_soft_deadline_precedes_the_hard_kill() - && gunbc_falsifier_soft_deadline_minutes() == (gunbc_falsifier_step_timeout_minutes - gunbc_falsifier_receipt_flush_allowance_minutes) - && gunbc_falsifier_soft_deadline_minutes() < gunbc_falsifier_step_timeout_minutes -} - -data selection_control_step_name: String = "Affected-set selection control (floor_skip_discovery_witness)" - -test fn selection_control_rides_falsifier_not_per_pr_ci() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: selection_control_step_name) - && !string_contains(s: expected_ci_yml(), pattern: selection_control_step_name) -} - -data selection_control_order_witness_note: String = "STRUCTURAL order pin (2026-08-07 four-job topology): selection-control job holds exactly one control step after release-bin unpack; cold-corpus job holds peak bracket + falsifier_step + cold controls. cold-corpus needs only falsifier-build so selector RED cannot skip the corpus." - -fn step_index_of(steps: List, name: String) -> Int { - let seen = fold(steps, init: { idx: 0, hit: 0 - 1 }, f: fn(acc, s) { - if step_display_name(s: s) == name { - if acc.hit >= 0 { { idx: acc.idx + 1, hit: acc.hit } } else { { idx: acc.idx + 1, hit: acc.idx } } - } else { - { idx: acc.idx + 1, hit: acc.hit } - } - }) - seen.hit -} - -fn step_count_named(steps: List, name: String) -> Int { - fold(steps, init: 0, f: fn(n, s) { - if step_display_name(s: s) == name { n + 1 } else { n } - }) -} - -fn falsifier_job_steps(job_id: String) -> List { - fold(falsifier_workflow.jobs, init: [], f: fn(acc, j) { - if j.id == job_id { j.steps } else { acc } - }) -} - -fn falsifier_build_job_steps() -> List { - falsifier_job_steps(job_id: "falsifier-build") -} - -fn falsifier_selection_control_job_steps() -> List { - falsifier_job_steps(job_id: "selection-control") -} - -fn falsifier_cold_corpus_job_steps() -> List { - falsifier_job_steps(job_id: "cold-corpus") -} - -fn ci_job_steps() -> List { - fold(ci_workflow.jobs, init: [], f: fn(acc, j) { - if j.id == "ci" { j.steps } else { acc } - }) -} - -test fn selection_control_sits_after_unpack_in_selection_job() -> Bool { - let steps = falsifier_selection_control_job_steps() - let unpack = step_index_of(steps: steps, name: "Unpack + verify release bins (claim_executor --verify-build-artifacts; fail-closed)") - let control = step_index_of(steps: steps, name: selection_control_step_name) - (unpack >= 0) && (control >= 0) && (unpack < control) -} - -test fn cold_corpus_job_needs_build_only_not_selection() -> Bool { - fold(falsifier_workflow.jobs, init: false, f: fn(acc, j) { - if j.id == falsifier_cold_corpus_job_id { - any(j.needs, n => n == "falsifier-build") - && !any(j.needs, n => n == "selection-control") - } else { - acc - } - }) -} - -test fn falsifier_has_four_jobs_in_topology_order() -> Bool { - count(falsifier_workflow.jobs) == 4 - && falsifier_workflow.jobs[0].id == "falsifier-build" - && falsifier_workflow.jobs[1].id == "selection-control" - && falsifier_workflow.jobs[2].id == falsifier_cold_corpus_job_id - && falsifier_workflow.jobs[3].id == "aggregate-verdict" -} - -test fn selection_control_enrolled_exactly_once_on_falsifier_and_never_on_ci() -> Bool { - step_count_named(steps: falsifier_build_job_steps(), name: selection_control_step_name) == 0 - && step_count_named(steps: falsifier_selection_control_job_steps(), name: selection_control_step_name) == 1 - && step_count_named(steps: falsifier_cold_corpus_job_steps(), name: selection_control_step_name) == 0 - && step_count_named(steps: ci_job_steps(), name: selection_control_step_name) == 0 -} - -test fn peak_bracket_brackets_only_cold_corpus_floor_path() -> Bool { - let steps = falsifier_cold_corpus_job_steps() - let peak_pre = step_index_of(steps: steps, name: "Floor cgroup peak pre-read (calibration; reset if permitted)") - let falsifier = step_index_of(steps: steps, name: "affected-set falsifier (predict-only cold run)") - (peak_pre >= 0) && (falsifier >= 0) && (peak_pre < falsifier) -} - -test fn falsifier_artifact_path_is_workflow_file() -> Bool { - artifact_path(a: FalsifierYamlArtifact) == ".github/workflows/falsifier.yml" -} - -test fn falsifier_yaml_projection_evaluates() -> Bool { - length_of(s: expected_falsifier_yml()) > 0 -} - -test fn falsifier_cold_control_steps_follow_floor_in_job_order() -> Bool { - let steps = falsifier_cold_corpus_job_steps() - let floor = step_index_of(steps: steps, name: "affected-set falsifier (predict-only cold run)") - let compile_clean = step_index_of(steps: steps, name: "compile-clean whole-tree cold control (scoped-PR admission counterpart)") - let native_cache = step_index_of(steps: steps, name: "native-cache cold control (warm-tier admission counterpart)") - (floor >= 0) && (compile_clean >= 0) && (native_cache >= 0) - && (floor < compile_clean) - && (compile_clean < native_cache) -} - -data red_floor_cold_control_fixture_note: String = "Discriminating workflow fixture (operator ruling 2026-08-05, P0 merge condition on #7812): verified defect run 30935833427 — affected-set floor step reddened and compile-clean + native-cache cold controls SKIPPED because they inherited default success(). The repair is always()+release_bins success, NOT floor success." - -test fn red_floor_workflow_fixture_cold_controls_still_execute() -> Bool { - falsifier_cold_control_steps_follow_floor_in_job_order() - && string_contains(s: expected_falsifier_yml(), pattern: falsifier_control_prerequisite_if) - && string_contains(s: falsifier_control_prerequisite_if, pattern: "always()") - && !string_contains(s: falsifier_control_prerequisite_if, pattern: "steps.floor") -} - -test fn falsifier_red_floor_fixture_reds_if_prerequisite_requires_floor_success() -> Bool { - let broken_gate = "success() && steps.floor.outcome == 'success'" - falsifier_control_prerequisite_if != broken_gate - && !string_contains(s: falsifier_control_prerequisite_if, pattern: "steps.floor.outcome == 'success'") -} - -test fn aggregate_verdict_job_waits_for_all_arms() -> Bool { - fold(falsifier_workflow.jobs, init: false, f: fn(acc, j) { - if j.id == "aggregate-verdict" { - j.if_condition == Present { value: falsifier_aggregate_verdict_if } - && any(j.needs, n => n == "falsifier-build") - && any(j.needs, n => n == "selection-control") - && any(j.needs, n => n == falsifier_cold_corpus_job_id) - } else { - acc - } - }) -} - -test fn aggregate_verdict_shell_has_dissolve_on_marker() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: dissolution_description(condition: falsifier_aggregate_verdict_shell_emit_dissolution_trigger)) -} - -test fn aggregate_verdict_shell_receipt_literals_match_model() -> Bool { - let yml = expected_falsifier_yml() - string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_build_failed())) - && string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_build_cancelled())) - && string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_build_skipped())) - && string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_cold_skipped())) - && string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_cold_cancelled())) - && string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_cold_failed_before_receipt())) - && string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_cold_receipt_artifact_absent())) - && string_contains(s: yml, pattern: bash_escape_for_double_quotes(s: aggregate_shell_receipt_corpus_executed())) -} - -test fn aggregate_shell_receipt_builders_are_receipt_json_authority() -> Bool { - aggregate_shell_receipt_build_failed() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeFailure, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) - && aggregate_shell_receipt_build_cancelled() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeCancelled, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) - && aggregate_shell_receipt_build_skipped() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSkipped, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) - && aggregate_shell_receipt_cold_skipped() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) - && aggregate_shell_receipt_cold_cancelled() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeCancelled, floor_receipt_present: false) - ) - && aggregate_shell_receipt_cold_failed_before_receipt() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: false) - ) - && aggregate_shell_receipt_cold_receipt_artifact_absent() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSuccess, floor_receipt_present: false) - ) - && aggregate_shell_receipt_corpus_executed() == cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: true) - ) -} - -test fn aggregate_verdict_shell_distinguishes_build_cancelled_from_failed() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: corpus_not_run_build_cancelled_tag) - && string_contains(s: expected_falsifier_yml(), pattern: corpus_not_run_build_skipped_tag) -} - -test fn aggregate_verdict_writes_cold_corpus_execution_receipt() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: falsifier_cold_corpus_execution_receipt_path) -} - -test fn cold_corpus_job_id_is_not_legacy_falsifier_job() -> Bool { - !any(falsifier_workflow.jobs, j => j.id == "falsifier") -} - -test fn aggregate_verdict_downloads_floor_component_receipt() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: "Download floor component receipt (cold-corpus execution witness)") - && string_contains(s: expected_falsifier_yml(), pattern: floor_component_receipt_artifact_name) - && string_contains(s: expected_falsifier_yml(), pattern: "continue-on-error: true") -} - -test fn cold_corpus_uploads_floor_phase_journal() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: "Upload floor phase journal (survives killed floor)") - && string_contains(s: expected_falsifier_yml(), pattern: ci_floor_phase_journal_artifact_name) - && string_contains(s: expected_falsifier_yml(), pattern: "if-no-files-found: warn") - && string_contains(s: expected_falsifier_yml(), pattern: "if: always()") -} - -test fn aggregate_verdict_shell_checks_floor_receipt_schema() -> Bool { - string_contains(s: expected_falsifier_yml(), pattern: floor_component_receipt_schema) - && string_contains(s: expected_falsifier_yml(), pattern: corpus_not_run_cold_failed_before_receipt_tag) -} - -test fn aggregate_verdict_floor_receipt_presence_test_has_no_spurious_bracket() -> Bool { - string_contains( - s: expected_falsifier_yml(), - pattern: concat("grep -q ", concat(floor_component_receipt_schema, " target/floor-component-receipt.json; then")) - ) - && !string_contains(s: expected_falsifier_yml(), pattern: "floor-component-receipt.json ]; then") -} - -test fn aggregate_verdict_write_receipt_redirects_printf_on_same_line() -> Bool { - let line = falsifier_aggregate_verdict_write_receipt(json: "{\"schema\":\"test\"}") - string_contains(s: line, pattern: "> target/falsifier-cold-corpus-execution.json") - && !string_contains(s: line, pattern: "\n > ") -} - -test fn cold_corpus_executed_when_cold_job_ran_even_if_red() -> Bool { - match classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: true) { - CorpusExecuted { receipt_path: path } => path == floor_component_receipt_path - _ => false - } -} - -test fn cold_corpus_not_run_when_failed_before_receipt() -> Bool { - match classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: false) { - CorpusNotRun { cause: ColdCorpusFailedBeforeReceipt } => true - _ => false - } -} - -test fn cold_corpus_not_run_when_receipt_artifact_absent_on_success() -> Bool { - match classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSuccess, floor_receipt_present: false) { - CorpusNotRun { cause: ColdCorpusReceiptArtifactAbsent } => true - _ => false - } -} - -test fn cold_success_without_receipt_is_not_failed_before_receipt() -> Bool { - match classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSuccess, floor_receipt_present: false) { - CorpusNotRun { cause: ColdCorpusFailedBeforeReceipt } => false - CorpusNotRun { cause: ColdCorpusReceiptArtifactAbsent } => true - _ => false - } -} - -test fn cold_failure_without_receipt_is_not_receipt_artifact_absent() -> Bool { - match classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: false) { - CorpusNotRun { cause: ColdCorpusReceiptArtifactAbsent } => false - CorpusNotRun { cause: ColdCorpusFailedBeforeReceipt } => true - _ => false - } -} - -test fn cold_failure_without_receipt_is_not_corpus_executed() -> Bool { - !cold_corpus_execution_is_executed( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: false) - ) -} - -test fn cold_failure_with_receipt_is_corpus_executed_even_when_red() -> Bool { - cold_corpus_execution_is_executed( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: true) - ) -} - -test fn cold_corpus_not_run_when_build_failed() -> Bool { - match classify_cold_corpus_execution(build: JobOutcomeFailure, cold: JobOutcomeSkipped, floor_receipt_present: false) { - CorpusNotRun { cause: BuildJobFailed } => true - _ => false - } -} - -test fn cold_corpus_not_run_is_not_regression_evidence() -> Bool { - !cold_corpus_execution_is_executed( - c: classify_cold_corpus_execution(build: JobOutcomeFailure, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) -} - -test fn selection_red_with_corpus_executed_still_counts_as_executed() -> Bool { - cold_corpus_execution_is_executed( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: true) - ) - && cadence_verdict_should_fail( - build: JobOutcomeSuccess, - selection: JobOutcomeFailure, - cold: JobOutcomeFailure, - floor_receipt_present: true - ) -} - -test fn failed_before_receipt_still_fails_cadence() -> Bool { - cadence_verdict_should_fail( - build: JobOutcomeSuccess, - selection: JobOutcomeSuccess, - cold: JobOutcomeFailure, - floor_receipt_present: false - ) -} - -test fn cold_corpus_execution_receipt_json_discriminates_build_failed() -> Bool { - string_contains( - s: cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeFailure, cold: JobOutcomeSkipped, floor_receipt_present: false) - ), - pattern: corpus_not_run_build_failed_tag - ) - && cold_corpus_execution_tag( - c: classify_cold_corpus_execution(build: JobOutcomeFailure, cold: JobOutcomeSkipped, floor_receipt_present: false) - ) == corpus_not_run_tag -} - -test fn cold_corpus_execution_receipt_json_discriminates_failed_before_receipt() -> Bool { - string_contains( - s: cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: false) - ), - pattern: corpus_not_run_cold_failed_before_receipt_tag - ) - && !string_contains( - s: cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeFailure, floor_receipt_present: false) - ), - pattern: corpus_not_run_cold_receipt_artifact_absent_tag - ) -} - -test fn cold_corpus_execution_receipt_json_discriminates_receipt_artifact_absent() -> Bool { - string_contains( - s: cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSuccess, floor_receipt_present: false) - ), - pattern: corpus_not_run_cold_receipt_artifact_absent_tag - ) - && !string_contains( - s: cold_corpus_execution_receipt_json( - c: classify_cold_corpus_execution(build: JobOutcomeSuccess, cold: JobOutcomeSuccess, floor_receipt_present: false) - ), - pattern: corpus_not_run_cold_failed_before_receipt_tag - ) -} - -fn length_of(s: String) -> Int { - s.length() -} - -fn string_contains(s: String, pattern: String) -> Bool { - s.contains(pattern) -} diff --git a/dag/test/claim/floor_batch_clamp_authority_witness_test.dag b/dag/test/claim/floor_batch_clamp_authority_witness_test.dag index aecaf691c99..576308f9921 100644 --- a/dag/test/claim/floor_batch_clamp_authority_witness_test.dag +++ b/dag/test/claim/floor_batch_clamp_authority_witness_test.dag @@ -5,18 +5,23 @@ import std.realization_schedule { runnable_batch_clamp_ms, } import std.decl_ref { decl_ref } -import std.measure { second, millisecond, second_count, millisecond_count } +import std.measure { second, millisecond, second_count } import std.types { NonEmptyStr } import gunbc.ci_spec { gunbc_ci_floor_batch_clamp_params, gunbc_ci_compile_clean_clamp } -import gunbc.ci_layer_roots { v1_claim_scoped_witness_batch } import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly -// The two populations that feed one aligned clamp list, asserted at their own declarations. A -// refusal that reports one population's number while citing the other's row is the defect these -// witnesses exist to keep unwritable (gunbc#7869: clamp_ms=360000 beside -// gunbc_ci_floor_batch_clamp_params[0], whose overhead is 240 seconds). +// ONE POPULATION NOW FEEDS THE CLAMP LIST, and that is why this file shrank rather than being +// deleted. The defect it was written for (gunbc#7869: a refusal reporting clamp_ms=360000 while +// citing gunbc_ci_floor_batch_clamp_params[0], whose overhead is 240 seconds) needed TWO +// independently owned populations aligned into one positional list; the second population was the +// scoped witness batch's own clamp row, deleted 2026-08-15 with affected-set selection. A +// misattributed citation is therefore no longer constructible, so the discriminating pair and the +// scoped rate assertions that proved it are removed rather than left asserting against one side of +// a comparison that has nothing to compare. What survives is the surviving population's own +// citation, plus the formula control -- because runnable_batch_clamp_ms is still live and its +// unit-rate arithmetic is still the thing a future clamp row will be read through. fn positional_clamp_row_zero() -> RunnableBatchClamp { match gunbc_ci_floor_batch_clamp_params { Empty => gunbc_ci_compile_clean_clamp @@ -24,10 +29,6 @@ fn positional_clamp_row_zero() -> RunnableBatchClamp { } } -fn scoped_clamp() -> RunnableBatchClamp { - v1_claim_scoped_witness_batch.resource_profile.clamp -} - test fn positional_clamp_row_zero_cites_the_ci_spec_list_it_lives_in() -> Bool { let c = positional_clamp_row_zero() (c.authority.module_path as String == "gunbc.ci_spec") @@ -35,40 +36,8 @@ test fn positional_clamp_row_zero_cites_the_ci_spec_list_it_lives_in() -> Bool { && (second_count(s: c.overhead) == 240) } -test fn scoped_batch_clamp_cites_its_own_declaration_not_the_positional_list() -> Bool { - let c = scoped_clamp() - (c.authority.module_path as String == "gunbc.ci_layer_roots") - && (c.authority.decl_name as String == "v1_claim_scoped_witness_batch") - && (second_count(s: c.overhead) == 720) - && (millisecond_count(m: c.per_unit) == 0) -} - -// THE DISCRIMINATING CONTROL, and the reason the pair above is not two restatements of one fact: -// the two authorities carry DIFFERENT numbers, so a citation pointing at the wrong one is decidable -// rather than cosmetic. Re-point the scoped clamp's authority at gunbc.ci_spec and this goes red; -// so does making the two overheads equal, which would silently restore the ambiguity. -test fn the_two_clamp_authorities_are_distinguishable_by_value() -> Bool { - let positional = positional_clamp_row_zero() - let scoped = scoped_clamp() - let positional_decl = positional.authority.decl_name as String - let scoped_decl = scoped.authority.decl_name as String - let positional_ms = runnable_batch_clamp_ms(clamp: positional, units: 27) - let scoped_ms = runnable_batch_clamp_ms(clamp: scoped, units: 27) - (positional_decl != scoped_decl) && (positional_ms != scoped_ms) -} - -// units IS in the expression and contributes exactly zero on this row. The refusal prints -// `units=27`, which invites trimming the roster or splitting the batch; neither can move the -// threshold, and the split form would hand the same work a second overhead allowance. -test fn scoped_clamp_is_identical_at_one_unit_and_at_twenty_seven() -> Bool { - let c = scoped_clamp() - (runnable_batch_clamp_ms(clamp: c, units: 1) == runnable_batch_clamp_ms(clamp: c, units: 27)) - && (runnable_batch_clamp_ms(clamp: c, units: 27) == 720000) -} - -// The positive control for the one above: a row whose rate is NONZERO must move with the unit -// count, or the equality test proves nothing about the formula and only that this file's arithmetic -// is constant. +// THE FORMULA CONTROL. A row whose rate is NONZERO must move with the unit count, or nothing in +// this file distinguishes runnable_batch_clamp_ms from a constant. test fn a_nonzero_rate_clamp_does_move_with_the_unit_count() -> Bool { let priced = RunnableBatchClamp { overhead: second(count: 300), diff --git a/dag/test/claim/floor_component_receipt_witness_test.dag b/dag/test/claim/floor_component_receipt_witness_test.dag index 19e6afbebb1..527a5e573c5 100644 --- a/dag/test/claim/floor_component_receipt_witness_test.dag +++ b/dag/test/claim/floor_component_receipt_witness_test.dag @@ -12,15 +12,10 @@ import std.measure { Millisecond, millisecond } import std.measure { ClockBasis, CpuClock, WallClock } import gunbc.floor_component_receipt { FloorComponentRow, - FloorControlState, - ControlConcluded, - ControlAbsent, - ControlAmbiguous, floor_component_row, floor_component_row_of_failure_mode, floor_component_row_not_concluded, floor_component_row_is_done, - floor_affected_set_control_state, floor_unsuccessful_component_rows, floor_component_receipt_document, floor_component_receipt_document_incomplete, @@ -43,7 +38,6 @@ fn fcr_control_row_with(outcome_tag: NonEmptyStr, detail: NonEmptyStr) -> FloorC run_id: fcr_run_id, index: 1, label: "discovery-corpus predict-only" as NonEmptyStr, - selection_tag: "predict_only" as NonEmptyStr, witnesses: 5217, outcome_tag: outcome_tag, detail: detail, @@ -62,7 +56,6 @@ fn fcr_silent_pick_row() -> FloorComponentRow? { run_id: fcr_run_id, index: 4, label: "discovery-corpus silent-pick gate" as NonEmptyStr, - selection_tag: "applied" as NonEmptyStr, witnesses: 1, outcome_tag: "refused" as NonEmptyStr, detail: fcr_silent_pick_diagnostic, @@ -79,7 +72,6 @@ fn fcr_timed_out_row() -> FloorComponentRow? { run_id: fcr_run_id, index: 4, label: "discovery-corpus silent-pick gate" as NonEmptyStr, - selection_tag: "applied" as NonEmptyStr, witnesses: 1, outcome_tag: "timed_out" as NonEmptyStr, detail: "unused by the TimedOut arm" as NonEmptyStr, @@ -96,7 +88,6 @@ fn fcr_expect_red_row(index: Nat) -> FloorComponentRow? { run_id: fcr_run_id, index: index, label: "discovery-corpus expect_red" as NonEmptyStr, - selection_tag: "applied" as NonEmptyStr, witnesses: 6, outcome_tag: "done" as NonEmptyStr, detail: "expect_red still-red OK" as NonEmptyStr, @@ -129,24 +120,13 @@ fn fcr_real_run_rows() -> List { ]) } -fn fcr_control_verified(rows: List) -> Bool { - match floor_affected_set_control_state(rows: rows) { - ControlConcluded { row: r } => floor_component_row_is_done(row: r) - ControlAbsent { cause: _ } => false - ControlAmbiguous { cause: _, matched: _ } => false - } -} - -test fn fcr_real_run_reports_control_verified_and_names_silent_pick() -> Bool { +test fn fcr_real_run_names_the_silent_pick_component() -> Bool { let rows = fcr_real_run_rows() let failed = floor_unsuccessful_component_rows(rows: rows) let doc = floor_component_receipt_document(workflow_name: fcr_workflow_name, run_id: fcr_run_id, head_sha: fcr_head_sha, rows: rows) count(rows) == 4 - && fcr_control_verified(rows: rows) && count(failed) == 1 && string_contains(s: doc, pattern: "\"schema\": \"floor-component-receipt/v1\"") - && string_contains(s: doc, pattern: "\"state\": \"present\"") - && string_contains(s: doc, pattern: "\"verified\": true") && string_contains(s: doc, pattern: "resolution_divergence_silent_pick_gate_keystone_holds") && string_contains(s: doc, pattern: "900000ms whole-receipt budget") && string_contains(s: doc, pattern: "\"outcome\": \"refused\"") @@ -162,51 +142,11 @@ test fn fcr_timed_out_arm_projects_budget_and_elapsed() -> Bool { && string_contains(s: doc, pattern: "\"elapsed_ms\": 900766") } -test fn fcr_red_control_control_itself_failed_is_not_verified() -> Bool { - let rows = fcr_rows_of(opts: [ - fcr_control_row_with( - outcome_tag: "failed" as NonEmptyStr, - detail: "predict-only corpus red" as NonEmptyStr - ), - fcr_silent_pick_row() - ]) - count(rows) == 2 && !fcr_control_verified(rows: rows) -} - -test fn fcr_red_control_absent_control_is_not_silently_verified() -> Bool { - let rows = fcr_rows_of(opts: [fcr_silent_pick_row()]) - let doc = floor_component_receipt_document(workflow_name: fcr_workflow_name, run_id: fcr_run_id, head_sha: fcr_head_sha, rows: rows) - count(rows) == 1 - && !fcr_control_verified(rows: rows) - && (match floor_affected_set_control_state(rows: rows) { - ControlConcluded { row: _ } => false - ControlAbsent { cause: _ } => true - ControlAmbiguous { cause: _, matched: _ } => false - }) - && string_contains(s: doc, pattern: "\"state\": \"absent\"") - && string_contains(s: doc, pattern: "\"verified\": false") -} - -test fn fcr_red_control_ambiguous_control_refuses() -> Bool { - let rows = fcr_rows_of(opts: [ - fcr_control_row_with(outcome_tag: "done" as NonEmptyStr, detail: "first" as NonEmptyStr), - fcr_control_row_with(outcome_tag: "done" as NonEmptyStr, detail: "second" as NonEmptyStr) - ]) - count(rows) == 2 - && !fcr_control_verified(rows: rows) - && (match floor_affected_set_control_state(rows: rows) { - ControlConcluded { row: _ } => false - ControlAbsent { cause: _ } => false - ControlAmbiguous { cause: _, matched: m } => m == 2 - }) -} - test fn fcr_red_control_unknown_tags_fail_closed() -> Bool { let bad_outcome = floor_component_row( run_id: fcr_run_id, index: 1, label: "x" as NonEmptyStr, - selection_tag: "predict_only" as NonEmptyStr, witnesses: 1, outcome_tag: "probably_fine" as NonEmptyStr, detail: "d" as NonEmptyStr, @@ -216,22 +156,7 @@ test fn fcr_red_control_unknown_tags_fail_closed() -> Bool { shown_failures: 0, wall: millisecond(count: 1) ) - let bad_selection = floor_component_row( - run_id: fcr_run_id, - index: 1, - label: "x" as NonEmptyStr, - selection_tag: "whatever" as NonEmptyStr, - witnesses: 1, - outcome_tag: "done" as NonEmptyStr, - detail: "d" as NonEmptyStr, - basis: WallClock, - budget: millisecond(count: 0), - elapsed: millisecond(count: 0), - shown_failures: 0, - wall: millisecond(count: 1) - ) (match bad_outcome { Absent => true Present { value: _ } => false }) - && (match bad_selection { Absent => true Present { value: _ } => false }) && fcr_all_present(opts: [ fcr_control_row_with(outcome_tag: "done" as NonEmptyStr, detail: "ok" as NonEmptyStr) ]) @@ -258,7 +183,6 @@ fn fcr_mode_row(mode: NonEmptyStr) -> FloorComponentRow? { run_id: fcr_run_id, index: 4, label: "discovery-corpus silent-pick gate" as NonEmptyStr, - selection_tag: "applied" as NonEmptyStr, witnesses: 1, failure_mode: mode, detail: fcr_silent_pick_diagnostic, @@ -271,7 +195,6 @@ fn fcr_not_concluded_mode_row(mode: NonEmptyStr, detail: NonEmptyStr) -> FloorCo run_id: fcr_run_id, index: 7, label: "discovery-corpus wet self-host" as NonEmptyStr, - selection_tag: "applied" as NonEmptyStr, failure_mode: mode, detail: detail ) @@ -349,61 +272,6 @@ test fn fcr_red_control_unmodelled_failure_mode_refuses_never_widens() -> Bool { && (match budget { Absent => false Present { value: _ } => true }) } -data fcr_unreached_control_note: String = "The projection half of the receipt's TOTALITY property (the seed half is claim_executor's unreached_components_carry_planned_identity_not_placeholder). An enrolled component the stop policy never reached is padded into the receipt so the component count stays total. WHICH IDENTITY that padded row carries decides whether the receipt can still tell two different states apart. Carrying the PLANNED selection tag, an unreached cold control stays a predict_only row and resolves to ControlConcluded with a Skipped outcome — enrolled, did not run, verified false. Carrying a placeholder off tag instead, the same run resolves to ControlAbsent, whose cause reads 'the affected-set cold control did not run' — true by accident, and indistinguishable from a run where the control was never enrolled at all. Two states with different remedies collapsing to one output is the state-space conflation this module exists to prevent, so the pair below asserts they stay distinct rather than asserting either arm alone." - -fn fcr_unreached_control_row(selection_tag: NonEmptyStr) -> FloorComponentRow? { - floor_component_row( - run_id: fcr_run_id, - index: 2, - label: "discovery-corpus predict-only" as NonEmptyStr, - selection_tag: selection_tag, - witnesses: 0, - outcome_tag: "skipped" as NonEmptyStr, - detail: "batch not reached — an earlier batch failed under the stop policy" as NonEmptyStr, - basis: WallClock, - budget: millisecond(count: 0), - elapsed: millisecond(count: 0), - shown_failures: 0, - wall: millisecond(count: 0) - ) -} - -test fn fcr_unreached_control_keeps_its_identity_and_is_not_verified() -> Bool { - let rows = fcr_rows_of(opts: [ - fcr_unreached_control_row(selection_tag: "predict_only" as NonEmptyStr) - ]) - let doc = floor_component_receipt_document(workflow_name: fcr_workflow_name, run_id: fcr_run_id, head_sha: fcr_head_sha, rows: rows) - count(rows) == 1 - && !fcr_control_verified(rows: rows) - && (match floor_affected_set_control_state(rows: rows) { - ControlConcluded { row: _ } => true - ControlAbsent { cause: _ } => false - ControlAmbiguous { cause: _, matched: _ } => false - }) - && string_contains(s: doc, pattern: "\"state\": \"present\"") - && string_contains(s: doc, pattern: "\"verified\": false") - && string_contains(s: doc, pattern: "\"outcome\": \"skipped\"") -} - -test fn fcr_red_control_placeholder_identity_erases_the_cold_control() -> Bool { - let padded = fcr_rows_of(opts: [ - fcr_unreached_control_row(selection_tag: "off" as NonEmptyStr) - ]) - let planned = fcr_rows_of(opts: [ - fcr_unreached_control_row(selection_tag: "predict_only" as NonEmptyStr) - ]) - let padded_doc = floor_component_receipt_document(workflow_name: fcr_workflow_name, run_id: fcr_run_id, head_sha: fcr_head_sha, rows: padded) - let planned_doc = floor_component_receipt_document(workflow_name: fcr_workflow_name, run_id: fcr_run_id, head_sha: fcr_head_sha, rows: planned) - count(padded) == 1 - && count(planned) == 1 - && (match floor_affected_set_control_state(rows: padded) { - ControlConcluded { row: _ } => false - ControlAbsent { cause: _ } => true - ControlAmbiguous { cause: _, matched: _ } => false - }) - && !(padded_doc == planned_doc) -} - data fcr_failure_mode_edge_note: String = "The row-grain failure-mode edge, and the collapse it exists to undo. floor_component_outcome_of_failure_mode maps Infra and WitnessRed onto the SAME ObservationOutcome (Failed), which is right for the observation record and wrong for anyone deciding what to do next: a dead runner and a genuinely false claim are different faults with different owners. Before the edge, a consumer holding the Failed arm could only tell them apart by reading the diagnostic prose — the string classification the seed boundary already refuses. The pair below asserts BOTH halves of the property, because either alone is satisfiable by a broken projection: the outcomes must still agree (both Failed — the edge did not fork the observation record) AND the modes must differ (Infra vs WitnessRed — the edge actually recovers the distinction). A projection that renamed the outcomes apart would pass a modes-differ check while breaking the record; one that dropped the mode would pass an outcomes-agree check while restoring the blindness." fn fcr_mode_of(mode: NonEmptyStr) -> String { @@ -491,9 +359,9 @@ test fn fcr_red_control_tag_built_row_records_no_mode_rather_than_guessing() -> && !string_contains(s: doc, pattern: "\"failure_mode\": \"none\"") } -data selection_degradation_round_trip_note: String = "The writer/reader round trip is witnessed on the NO-SELECTION path specifically, because that is the path that was broken: the selection path always emitted the member and would have passed a round-trip check that never exercised its sibling. A claim that only covers the arm which already worked is the shape that let this ship." +data receipt_round_trip_note: String = "THE WRITER'S OUTPUT DECODES THROUGH THE STRICT READER, and this witness exists because that once stopped being true. The writer emitted a selection_degradation member only when a selection snapshot existed, while the reader REQUIRED it, so the no-selection path produced a document the reader refused (review 49594). Both members are now deleted with affected-set selection itself — the writer no longer emits them and the reader no longer requires them — so the specific break is gone. The round trip is still witnessed, because what made that defect possible is structural rather than incidental: the writer and the reader are two hand-maintained member lists, and nothing but this execution joins them. Dissolve-on: the document type derives both projections, at which point a writer that omits a required member is unrepresentable and this witness becomes redundant with the type." -test fn fcr_no_selection_receipt_decodes_through_the_strict_reader() -> Bool { +test fn fcr_receipt_decodes_through_the_strict_reader() -> Bool { let doc = floor_component_receipt_document( workflow_name: fcr_workflow_name, run_id: fcr_run_id, @@ -508,7 +376,7 @@ test fn fcr_no_selection_receipt_decodes_through_the_strict_reader() -> Bool { data fcr_run_terminal_legacy_absent_note: String = "Pre-PR receipts under artifact retention omit run_terminal entirely. receipt_run_terminal_at maps absent to null so the alert decoder does not refuse them (review 51856); same transitional pattern as component_outcome_wire_legacy_pending_tag_note." -data fcr_legacy_receipt_without_run_terminal: String = "{\"schema\":\"floor-component-receipt/v1\",\"workflow_name\":\"affected-set-falsifier\",\"run_id\":\"30509024051\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"component_count\":0,\"affected_set_cold_control\":null,\"selection_degradation\":null,\"unsuccessful_components\":[],\"components\":[]}" +data fcr_legacy_receipt_without_run_terminal: String = "{\"schema\":\"floor-component-receipt/v1\",\"workflow_name\":\"affected-set-falsifier\",\"run_id\":\"30509024051\",\"head_sha\":\"0123456789abcdef0123456789abcdef01234567\",\"component_count\":0,\"unsuccessful_components\":[],\"components\":[]}" test fn fcr_legacy_receipt_without_run_terminal_member_decodes() -> Bool { match floor_component_receipt_decode_with( diff --git a/dag/test/claim/floor_gate_failure_receipt_witness_test.dag b/dag/test/claim/floor_gate_failure_receipt_witness_test.dag deleted file mode 100644 index 0705e7e9d1e..00000000000 --- a/dag/test/claim/floor_gate_failure_receipt_witness_test.dag +++ /dev/null @@ -1,108 +0,0 @@ -module test.claim.floor_gate_failure_receipt_witness - -import std.process { ProcessExit, ExitSuccess, exit_failure } -import gunbc.test_module_hygiene { failure_receipt_companion, Optional, Present } -import gunbc.generated_artifact_assessment { - GeneratedArtifactObservation, GeneratedArtifactObserved, assess_generated_artifact_population, - first_failing_diagnostic_path -} -import gunbc.generated_artifact { CiYamlArtifact, GitignoreArtifact } -import tools.dag_compile_clean_gate { dag_compile_clean_failure_reason } -import tools.generated_artifact_gate { generated_artifact_drift_failure_reason } -import tools.regen_verify_transport { regen_verify_failure_detail } -import tools.regen_verify_gate { regen_verify_failure_reason } - -data witness_note: String = "Floor gate failure-receipt companions must name located reasons on Bool(false), not only returned Bool(false). Controls pin the naming convention via gunbc.test_module_hygiene.failure_receipt_companion and the reason projection helpers without re-running the expensive live gates." - -data planted_regen_stderr: String = "Stage0 is stale: 1 generated file(s) differ from fresh self-compile.\nChanged generated file(s): v1_compiler_emit_rust.rs\n" - -data planted_artifact_path: String = ".github/workflows/ci.yml" - -fn constructed_drift_observation(path: String) -> GeneratedArtifactObserved { - GeneratedArtifactObserved { - artifact: CiYamlArtifact, - path: path, - generated_content: "expected bytes", - committed_content: concat("expected bytes", "\n# drift"), - extra_validation: true - } -} - -test fn regen_verify_failure_detail_names_drifted_file_holds() -> Bool { - string_contains( - s: regen_verify_failure_detail(stdout: "regen_divergence_count=1\n", stderr: planted_regen_stderr), - pattern: "v1_compiler_emit_rust.rs" - ) -} - -test fn regen_verify_failure_detail_refuses_empty_capture_holds() -> Bool { - string_contains( - s: regen_verify_failure_detail(stdout: "", stderr: ""), - pattern: "no diagnostic output" - ) -} - -test fn regen_verify_failure_reason_empty_only_on_success() -> Bool { - regen_verify_failure_reason(exit: ExitSuccess) == "" -} - -test fn generated_artifact_drift_verdict_names_planted_path_holds() -> Bool { - let observations = [ - constructed_drift_observation(path: planted_artifact_path), - GeneratedArtifactObserved { - artifact: GitignoreArtifact, - path: ".gitignore", - generated_content: "same", - committed_content: "same", - extra_validation: true - } - ] - string_contains( - s: first_failing_diagnostic_path( - expected: [CiYamlArtifact, GitignoreArtifact], - observations: observations - ), - pattern: planted_artifact_path - ) - && !assess_generated_artifact_population( - expected: [CiYamlArtifact, GitignoreArtifact], - observations: observations - ) -} - -test fn generated_artifact_drift_failure_reason_empty_only_on_success() -> Bool { - generated_artifact_drift_failure_reason(exit: ExitSuccess) == "" - && string_contains( - s: generated_artifact_drift_failure_reason( - exit: exit_failure( - reason: concat("generated-artifact drift/validation failed: ", planted_artifact_path) - ) - ), - pattern: planted_artifact_path - ) -} - -test fn dag_compile_clean_failure_reason_empty_only_on_success() -> Bool { - dag_compile_clean_failure_reason(exit: ExitSuccess) == "" - && string_contains( - s: dag_compile_clean_failure_reason( - exit: exit_failure(reason: "compile-clean: unresolved import in dag/test/example.dag") - ), - pattern: "dag/test/example.dag" - ) -} - -test fn floor_gate_failure_receipt_companion_names_holds() -> Bool { - match failure_receipt_companion(function: "dag_compile_clean_gate_passes") { - Present { value: companion } => companion == "dag_compile_clean_gate_failure_receipt" - _ => false - } - && match failure_receipt_companion(function: "generated_artifact_drift_gate_passes") { - Present { value: companion } => companion == "generated_artifact_drift_gate_failure_receipt" - _ => false - } - && match failure_receipt_companion(function: "regen_verify_gate_passes") { - Present { value: companion } => companion == "regen_verify_gate_failure_receipt" - _ => false - } -} diff --git a/dag/test/claim/floor_skip_discovery_witness_test.dag b/dag/test/claim/floor_skip_discovery_witness_test.dag deleted file mode 100644 index 743eddb84ff..00000000000 --- a/dag/test/claim/floor_skip_discovery_witness_test.dag +++ /dev/null @@ -1,8 +0,0 @@ -module test.claim.floor_skip_discovery_witness_test - - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -test fn floor_skip_discovery_keystone_holds() -> Bool { - run_floor_skip_discovery_witness() -} diff --git a/dag/test/claim/generated_artifact_drift_test.dag b/dag/test/claim/generated_artifact_drift_test.dag deleted file mode 100644 index 4e9dcd74c0c..00000000000 --- a/dag/test/claim/generated_artifact_drift_test.dag +++ /dev/null @@ -1,611 +0,0 @@ - -module test.claim.generated_artifact_drift - -import gunbc.generated_artifact { - GeneratedArtifact, CiYamlArtifact, FalsifierYamlArtifact, FleetConvergeYamlArtifact, GitignoreArtifact, GitattributesArtifact, RoadmapArtifact, DesignArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, RunnerDeployArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, Stage0CratePartitionGeneratedDagArtifact, Stage0EmitPlanGeneratedDagArtifact, V1InterpreterDispatchGeneratedRsArtifact, AutoinstallUserDataArtifact, ProxyDhcpDnsmasqArtifact, PlanArtifact, - RepoConsumer, GitProtocol, GithubActionsWorkflow, ProjectDocumentation, HostReconciler, - CommitPolicy, CommitRequired, NotCommitted, - generated_artifact_registry, - committed_generated_artifacts, artifact_path, artifact_commit_policy, artifact_is_committed, - registry_contains -} -import gunbc.ci_heal_credential { live_heal_push_binding_resolution, live_heal_control_plane, ci_heal_checkout_step_ref } -import gunbc.auth.github_credential { PushCredentialBindingMissing } -import gunbc.heal_push_plan { - HealRepairDisposition, HealRepairNoDrift, HealRepairAutoPushEligibleOnly, - HealRepairAuthorCommitRequired, HealRepairMixed, - HealPushPlan, HealPushNothingToDo, HealPushReady, HealPushPartial, HealPushRefused, - HealPushRefusal, HealPushRefusalCause, - ActionsJobCredentialScopeUnavailable, ActionsJobCredentialScopeNotGranted, - ActionsJobCredentialForkPolicyUnobserved, ManagedInstallationGrantUnobserved, - ManagedCredentialSubjectMismatch, PushBindingMissingOnCheckoutStep, PushBindingLeaseUnresolved, - PushBindingStepKindNotSupported, PushBindingActionNotCheckout, - PushBindingInputObservationDuplicated, ActionsJobCredentialAxisNotModeled, - ActionsJobCredentialDeclaredAccessInvalid, - HealPushRemediation, HealAutomatically, AuthorCommitRequired, MachineRepairRequired, - ProviderObservationRequired, HealNothingToRemediate, HealPlanInconsistent, - HealPushPlanInconsistent, RemedyOwner, RemedyAuthor, RemedyMachine, - RemedyProviderObservation, - HealPushFailure, PushBindingInputValueUnsupported, - HealPushBindingSite, - failure_causes, refusal_causes_token, remediation_for_refusal, - refusal_cause_remedy_owner, plan_remediation, live_heal_remediation, - remediation_author_commit_paths, - heal_push_refusal_cause_token, live_heal_push_refusal_cause_token, - plan_heal_push, plan_heal_push_from_binding, live_heal_push_plan, - auto_push_eligible_committed_artifacts, author_commit_required_committed_artifacts, - classify_heal_repair_paths, path_requires_author_commit -} -import gunbc.generated_artifact_emit { artifact_extra_valid, ArtifactGenerated, ArtifactGenerationRefused } -import gunbc.generated_artifact_assessment { - GeneratedArtifactObservation, GeneratedArtifactObserved, GeneratedArtifactObservationRefused, - assess_generated_artifact_observation, assess_generated_artifact_population, - first_failing_observation_path, first_failing_diagnostic_path -} -import gunbc.os_install { srv3_autoinstall_spec, fleet_autoinstall_specs, srv3_install_server_spec, fleet_install_server_specs } -import gunbc.gitignore_emit { path_is_ignored } -import gunbc.plan_registry { all_plans } -import gunbc.plans.idea_machine { idea_machine_plan } -import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree } - -data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree - -data pure_perturb_control_note: String = "P0 (operator-directed, 2026-08-05): the former per-artifact live perturb loop called artifact_generate three times per committed artifact just to prove generated != generated + suffix — a GENERIC string-inequality fact, re-proved once per generator, that never touched a real committed byte (DESIGN section 6: do not test that the processor does math well). Deleted. The pure leaf (assess_generated_artifact_observation) and pure group (assess_generated_artifact_population) policies in gunbc.generated_artifact_assessment are exercised below with tiny CONSTRUCTED receipts — no producer call, no Filesystem, no artifact_generate — covering clean, drift, generation-refusal, committed-read-refusal, extra-validation-refusal and group-identity (missing/duplicate/unknown) verdicts. gunbc.generated_artifact_assessment imports gunbc.generated_artifact ONLY — it cannot import Filesystem or the generator, so purity here is by construction, not by convention (loyal-ram-550 review of #7823). The one remaining LIVE fact — every registered committed artifact observed exactly once, byte-clean, against real disk state — is the production drift gate itself (dag/tools/generated_artifact_gate.dag, run_generated_artifact_drift_gate_body), which now calls the live producer exactly once per artifact per run; its byte-for-byte fixed point is additionally isolated at dag/test/claim/long/generated_artifact_drift_fixed_point_witness_test.dag." - -data perturb: String = "\n# gunbc-generated-artifact-drift-receipt-perturb" - -fn constructed_clean(a: GeneratedArtifact, content: String) -> GeneratedArtifactObservation { - GeneratedArtifactObserved { artifact: a, path: "fixture/path", generated_content: content, committed_content: content, extra_validation: true } -} - -test fn witness_pure_leaf_clean_when_bytes_match_and_extra_valid_holds() -> Bool { - assess_generated_artifact_observation(o: constructed_clean(CiYamlArtifact, "same bytes")) -} - -test fn witness_pure_leaf_drifts_on_perturbed_committed_bytes() -> Bool { - !assess_generated_artifact_observation(o: GeneratedArtifactObserved { - artifact: CiYamlArtifact, path: "fixture/path", generated_content: "same bytes", committed_content: concat("same bytes", perturb), extra_validation: true - }) -} - -test fn witness_pure_leaf_refuses_on_generation_refusal() -> Bool { - !assess_generated_artifact_observation(o: GeneratedArtifactObservationRefused { - artifact: CiYamlArtifact, path: "fixture/path", cause: "generation refused: boom" - }) -} - -test fn witness_pure_leaf_refuses_on_committed_read_refusal() -> Bool { - !assess_generated_artifact_observation(o: GeneratedArtifactObservationRefused { - artifact: CiYamlArtifact, path: "fixture/path", cause: "committed read failed: no such file" - }) -} - -test fn witness_pure_leaf_refuses_on_extra_validation_failure() -> Bool { - !assess_generated_artifact_observation(o: GeneratedArtifactObserved { - artifact: CiYamlArtifact, path: "fixture/path", generated_content: "same bytes", committed_content: "same bytes", extra_validation: false - }) -} - -test fn witness_pure_group_passes_when_every_expected_identity_observed_once_and_clean() -> Bool { - assess_generated_artifact_population( - expected: [CiYamlArtifact, GitignoreArtifact], - observations: [constructed_clean(CiYamlArtifact, "a"), constructed_clean(GitignoreArtifact, "b")] - ) -} - -test fn witness_pure_group_refuses_on_missing_identity() -> Bool { - !assess_generated_artifact_population( - expected: [CiYamlArtifact, GitignoreArtifact], - observations: [constructed_clean(CiYamlArtifact, "a")] - ) -} - -test fn witness_pure_group_refuses_on_duplicate_identity() -> Bool { - !assess_generated_artifact_population( - expected: [CiYamlArtifact], - observations: [constructed_clean(CiYamlArtifact, "a"), constructed_clean(CiYamlArtifact, "a")] - ) -} - -test fn witness_pure_group_refuses_on_unknown_identity() -> Bool { - !assess_generated_artifact_population( - expected: [CiYamlArtifact], - observations: [constructed_clean(CiYamlArtifact, "a"), constructed_clean(GitignoreArtifact, "b")] - ) -} - -test fn witness_pure_group_refuses_when_a_retained_leaf_is_dirty() -> Bool { - !assess_generated_artifact_population( - expected: [CiYamlArtifact], - observations: [GeneratedArtifactObserved { artifact: CiYamlArtifact, path: "fixture/path", generated_content: "a", committed_content: "b", extra_validation: true }] - ) -} - -test fn witness_first_failing_observation_path_names_the_dirty_leaf() -> Bool { - first_failing_observation_path(observations: [ - constructed_clean(GitignoreArtifact, "a"), - GeneratedArtifactObserved { artifact: CiYamlArtifact, path: "dirty/path", generated_content: "a", committed_content: "b", extra_validation: true } - ]) == "dirty/path" -} - -test fn witness_first_failing_observation_path_empty_when_all_leaves_clean() -> Bool { - first_failing_observation_path(observations: [constructed_clean(CiYamlArtifact, "a")]) == "" -} - -test fn witness_first_failing_diagnostic_path_falls_back_to_missing_identity() -> Bool { - first_failing_diagnostic_path(expected: [CiYamlArtifact], observations: []) == artifact_path(a: CiYamlArtifact) -} - -test fn witness_committed_registry_nonempty() -> Bool { - count(committed_generated_artifacts()) > 0 -} - -data fixed_point_witness_long_lane_note: String = "witness_committed_is_fixed_point and witness_committed_fixed_point_red_control rehomed to dag/test/claim/long/generated_artifact_drift_fixed_point_witness_test.dag (operator 5-second rule, 2026-08-03). This note is the ONE home for why; the sibling note there and the falsifier_substrate_long_lane_rows reason field in gunbc.ci_layer_roots carry the enrollment fact and point here, so the cause cannot drift across three copies (DESIGN 3). THE REHOME IS CORRECT AND DOES NOT REST ON A MEASUREMENT: the witness reads the live tree — Filesystem.Read at artifact_path for every row of committed_generated_artifacts(), then artifact_generate regenerating each — so its cost scales with the number and size of the generated artifacts and with the carrier rows their generators fold, quantities that grow with the repository and that this witness's own source does not determine. A flat per-witness ceiling is the wrong SHAPE of bound for that, whatever number it is set to. (Stated precisely because a looser version of it was wrong: committed_generated_artifacts() filters the static generated_artifact_registry, so the enumeration is not a tree walk and is fully visible to the compiled closure. The live-tree dependence is in the bytes read and compared, not in the row count.) MEASURED, and this one IS a like-for-like comparison in a way the 1005-versus-5004 pair never was: on a local claim_batch run at head 01564d73 the witness returned 7944ms while witness_committed_fixed_point_red_control — same file, same receipt path, same clock, same process, but reading and regenerating ONE artifact instead of all of them — returned 91ms, with the run's expectation frontier reporting 70 Filesystem.Read dispatches. Both figures come from the same producer, so the ratio carries information even though neither figure is CPU, and it makes the scaling claim above a measurement rather than an argument (loosely, not a constant per artifact: generating DESIGN.md is not the same work as generating a githook script). It says nothing about the cap, and deliberately so: 7944ms is ABOVE 5000, and by residual finding one a wall figure OVER the cap proves nothing about CPU. What it does establish is that the dissolve-on trigger below is not satisfied today. THE CAUSE PREVIOUSLY RECORDED BESIDE IT IS RETRACTED (2026-08-04, sessions wise-ram-22 / still-bat-561 / merry-raven-690): three prose copies attributed the 5004ms crossing to host contention. That is false and could not have been true. cli_run.rs run_claim_measured arms the budget through v1_interpreter.rs arm_eval_deadline, which seeds thread_cpu_nanos() — CLOCK_THREAD_CPUTIME_ID — so neither co-residence nor cold page cache accrues against it; run_claim_measured's own comment states that insulation as the reason the clock was chosen. THREE SUSPECTS FALSIFIED, recorded so nobody re-raises them: (1) contention or cold I/O — wrong clock, above, and the two-budget discriminator settles that rather than assuming it. cli_run.rs BudgetKind is Cpu or Wall and run_claim_measured applies BOTH completion arms, so a Wall crossing would put contention back in play; but the Wall arm is armed only from wet_receipt_wall_budget_ms, which is populated solely when plan_function is gunbc_falsifier_plan and valued at gunbc_falsifier_self_host_wet_receipt_wall_budget_ms = 600000ms. A 5004ms crossing is the 5000ms gunbc_ci_fast_lane_eval_budget_ms — the CPU arm, two orders of magnitude under the wall ceiling — so the kind is Cpu and contention cannot reach it (discriminator raised by still-bat-561, checked here); (2) corpus-index construction — v1 load_bare_edge_index / build_both_closure_edge_index sit on the RESOLVE path and all four set_witness_eval_budget call sites (cli_run.rs x2, bin/claim_batch.rs x2) arm the budget after resolve completes, so index cost is outside the budget on every path; (3) budget accumulating across a batch — run_claim_measured arms and clears per witness, so a late witness inherits no earlier witness's CPU. WHAT IS NOT ESTABLISHED, said plainly rather than filled in: the positive cause of 1005ms versus 5004ms. Those two figures are NOT ON THE SAME CLOCK, which has to be said before any ratio is quoted from them. 1005ms comes from the receipt, and v1_interpreter.rs performance_receipt_from_witness is handed wall_nanos; cli_run.rs run_claim_measured computes cpu_nanos beside it, spends it on budget_completion_outcome, and persists it nowhere, so no CPU column exists in the tree and witness_row_cost_basis's eval_ms is WALL despite the name. 5004ms comes from the kill path, and that is CPU: v1_interpreter.rs eval_expr stride-polls thread_cpu_nanos every 4096 evals against the armed baseline and raises InterpError EvalBudgetExceeded from inside eval — a prose-carried arm, not the typed TimedOut, which is only the completion-side backstop for rows that finish. So the 5x is a wall-to-CPU ratio, not a like-for-like one (found by still-bat-561 running the log grep after the wiring argument had already settled the budget kind). Beyond the clock, three variables still move at once — host (srv_fleet_arm64 vs the falsifier runner), head, and route (a narrow single-entry claim_batch vs discovery-corpus batch 1 over a far larger pool, run 30550328673) — and a further candidate, that the generators simply do more work as the corpus grows, is untested. So the gap is an OBSERVATION, not a diagnosis. The discriminating experiment is one host, one head, both routes; it cannot be run off today's receipts, because comparing them measures wall on both sides and answers the route question while leaving the cap question untouched. AND IT NEEDS REPEATS, NOT ONE PAIR — measured, not assumed (still-bat-561, off the falsifier row-cost receipt): the RED control reads 731ms on the discovery route against 91ms on the narrow one, a factor of 8.0 on a row whose work is 91ms. That figure is unambiguous — 731ms is nowhere near any cap, so it is a completed row's cost — and 8x of route-attributable swing is wide enough to swamp any single paired comparison. The witness row on the same receipt reads 5018ms against 7944ms narrow, which would be a factor in the OPPOSITE direction; that one is NOT quotable as a cost, because 5018 sits 18ms past the 5000 cap and a killed row records where the kill landed rather than what the row costs, so its true value is unbounded above and its sign is unknown. The variance case therefore rests on the control alone, which is enough: the experiment above settles nothing if it is run once. RESIDUAL FINDING ONE, larger than this witness and not fixed here: fast-lane eligibility is decided on the wrong clock. The cap is enforced on CPU and every recorded measurement is wall, so admitting or re-homing any witness compares one quantity against a bound on another; cpu_nanos already exists at the run_claim_measured call site and is dropped. This does NOT kill the dissolve-on triggers that name that budget, and the asymmetry is the point: eval is single-threaded, so thread CPU is bounded above by wall, and a recorded wall figure UNDER the cap does prove CPU under the cap. The triggers therefore stay decidable in exactly the direction that fires them. What is not available is the other direction — how near the cap a row sits, and whether an over-cap wall figure reflects CPU at all — which is the diagnostic direction, and the one every re-measurement of this row would want. The mismatch also has a second half that the cap cannot report, because it is the half the cap is blind to by construction: nothing bounds waiting, so a row with small CPU and large wait NEVER crosses the cap — never killed, never counted, never ranked — while still costing the corpus its full wall on every run. The cap and the receipt therefore measure different populations, and the wall receipt is the poor instrument for the first and the only instrument for the second (extension by still-bat-561 off this note's own counterexample; a structural convergence claim in the other direction — that near-cap wall must approximate CPU — was raised and withdrawn, since wall is an unbounded sum and not a budget being consumed). That belongs to the witness-cost lane. Dissolve-on: PerformanceReceipt persists cpu_nanos and the cost basis carries a CPU column, at which point the diagnostic direction opens too. RESIDUAL FINDING TWO, which the rehome mitigates but does not close: a per-witness CPU budget is applied to a witness whose cost grows with the repository. That is a SCOPE mismatch, not a tolerance one — no threshold is correct for a quantity that grows with the corpus — and it belongs to the cost-envelope work rather than to this file. Dissolve-on: witnesses declare an input envelope and route derives from it, at which point a live-tree reader is admitted on its declared input rather than measured against a flat per-witness ceiling. The drift gate run_generated_artifact_drift_gate_body still reads the same bytes as one conjunct; the long-lane witness ISOLATES the fixed-point property as a separately-falsifiable claim with its own RED control." - -test fn witness_all_known_committed() -> Bool { - artifact_is_committed(a: CiYamlArtifact) - && artifact_is_committed(a: FalsifierYamlArtifact) - && artifact_is_committed(a: GitignoreArtifact) - && artifact_is_committed(a: GitattributesArtifact) - && artifact_is_committed(a: RoadmapArtifact) - && artifact_is_committed(a: DesignArtifact) - && artifact_is_committed(a: GithooksPrePushArtifact) - && artifact_is_committed(a: GeneratedArtifactMergeDriverArtifact) - && artifact_is_committed(a: GithooksPreCommitArtifact) - && artifact_is_committed(a: PlanArtifact { plan: idea_machine_plan }) - && !artifact_is_committed(a: RunnerDeployArtifact) - && !artifact_is_committed(a: AutoinstallUserDataArtifact { spec: srv3_autoinstall_spec }) - && !artifact_is_committed(a: ProxyDhcpDnsmasqArtifact { spec: srv3_install_server_spec }) - && !path_is_ignored(path: ".github/workflows/ci.yml") - && !path_is_ignored(path: ".github/workflows/falsifier.yml") - && !path_is_ignored(path: ".gitignore") - && !path_is_ignored(path: ".gitattributes") - && !path_is_ignored(path: "ROADMAP.md") - && !path_is_ignored(path: "DESIGN.md") - && !path_is_ignored(path: ".githooks/pre-push") - && !path_is_ignored(path: ".githooks/pre-commit") - && !path_is_ignored(path: "dag/gunbc/stage0_crate_layout_generated.dag") - && !path_is_ignored(path: "dag/gunbc/stage0_crate_partition_generated.dag") - && !path_is_ignored(path: "dag/gunbc/stage0_emit_plan_generated.dag") - && !path_is_ignored(path: "src/v1/stage0/src/v1_interpreter_dispatch_generated.rs") - && !path_is_ignored(path: "src/v1/stage0/src/bootstrap_stage0_crate_layout_generated.rs") - && !path_is_ignored(path: "docs/plans/idea-machine.md") - && !path_is_ignored(path: ".github/live-deploy-srv1-apply.sh") - && !path_is_ignored(path: ".github/live-deploy-srv1-retract.sh") -} - -test fn witness_ignored_paths_excluded() -> Bool { - path_is_ignored(path: "target/release/gunbc") - && path_is_ignored(path: "foo/.DS_Store") - && path_is_ignored(path: "src/scratch.swp") - && path_is_ignored(path: "node_modules/pkg/index.js") - && path_is_ignored(path: ".github/fleet-runner-deploy.manifest") - && path_is_ignored(path: "provisioning/srv3/user-data") - && !path_is_ignored(path: "provisioning/srv3/dnsmasq.conf") -} - -test fn witness_registry_complete() -> Bool { - count(generated_artifact_registry) == (16 + count(fleet_autoinstall_specs) + count(fleet_install_server_specs) + count(all_plans)) - && registry_contains(a: CiYamlArtifact) - && registry_contains(a: FalsifierYamlArtifact) - && registry_contains(a: FleetConvergeYamlArtifact) - && registry_contains(a: GitignoreArtifact) - && registry_contains(a: GitattributesArtifact) - && registry_contains(a: RoadmapArtifact) - && registry_contains(a: DesignArtifact) - && registry_contains(a: GithooksPrePushArtifact) - && registry_contains(a: GithooksPreCommitArtifact) - && registry_contains(a: GeneratedArtifactMergeDriverArtifact) - && registry_contains(a: RunnerDeployArtifact) - && registry_contains(a: Stage0CrateLayoutGeneratedDagArtifact) - && registry_contains(a: Stage0CrateLayoutGeneratedRsArtifact) - && registry_contains(a: Stage0CratePartitionGeneratedDagArtifact) - && registry_contains(a: Stage0EmitPlanGeneratedDagArtifact) - && registry_contains(a: V1InterpreterDispatchGeneratedRsArtifact) - && registry_contains(a: AutoinstallUserDataArtifact { spec: srv3_autoinstall_spec }) - && registry_contains(a: PlanArtifact { plan: idea_machine_plan }) - && fleet_install_server_specs.length() == 0 - && artifact_is_committed(a: CiYamlArtifact) - && artifact_is_committed(a: FalsifierYamlArtifact) - && artifact_is_committed(a: FleetConvergeYamlArtifact) - && artifact_is_committed(a: GitignoreArtifact) - && artifact_is_committed(a: GitattributesArtifact) - && artifact_is_committed(a: RoadmapArtifact) - && artifact_is_committed(a: DesignArtifact) - && artifact_is_committed(a: GithooksPrePushArtifact) - && artifact_is_committed(a: GeneratedArtifactMergeDriverArtifact) - && artifact_is_committed(a: GithooksPreCommitArtifact) - && artifact_is_committed(a: PlanArtifact { plan: idea_machine_plan }) - && artifact_is_committed(a: Stage0CrateLayoutGeneratedDagArtifact) - && artifact_is_committed(a: Stage0CrateLayoutGeneratedRsArtifact) - && artifact_is_committed(a: Stage0CratePartitionGeneratedDagArtifact) - && artifact_is_committed(a: Stage0EmitPlanGeneratedDagArtifact) - && artifact_is_committed(a: V1InterpreterDispatchGeneratedRsArtifact) - && !artifact_is_committed(a: RunnerDeployArtifact) - && !artifact_is_committed(a: AutoinstallUserDataArtifact { spec: srv3_autoinstall_spec }) - && !artifact_is_committed(a: ProxyDhcpDnsmasqArtifact { spec: srv3_install_server_spec }) -} - -fn consumer_is(a: GeneratedArtifact, expected: RepoConsumer) -> Bool { - match artifact_commit_policy(a: a) { - CommitRequired { consumer } => match consumer { - GitProtocol => match expected { GitProtocol => true _ => false } - GithubActionsWorkflow => match expected { GithubActionsWorkflow => true _ => false } - ProjectDocumentation => match expected { ProjectDocumentation => true _ => false } - HostReconciler => match expected { HostReconciler => true _ => false } - } - NotCommitted => false - } -} - -test fn witness_commit_policy_reasons() -> Bool { - consumer_is(a: GitignoreArtifact, expected: GitProtocol) - && consumer_is(a: GitattributesArtifact, expected: GitProtocol) - && consumer_is(a: GithooksPrePushArtifact, expected: GitProtocol) - && consumer_is(a: GeneratedArtifactMergeDriverArtifact, expected: GitProtocol) - && consumer_is(a: GithooksPreCommitArtifact, expected: GitProtocol) - && consumer_is(a: CiYamlArtifact, expected: GithubActionsWorkflow) - && consumer_is(a: FalsifierYamlArtifact, expected: GithubActionsWorkflow) - && consumer_is(a: FleetConvergeYamlArtifact, expected: GithubActionsWorkflow) - && consumer_is(a: RoadmapArtifact, expected: ProjectDocumentation) - && consumer_is(a: DesignArtifact, expected: ProjectDocumentation) - && consumer_is(a: PlanArtifact { plan: idea_machine_plan }, expected: ProjectDocumentation) - && consumer_is(a: Stage0CrateLayoutGeneratedDagArtifact, expected: GitProtocol) - && consumer_is(a: Stage0CrateLayoutGeneratedRsArtifact, expected: GitProtocol) - && consumer_is(a: Stage0CratePartitionGeneratedDagArtifact, expected: GitProtocol) - && consumer_is(a: Stage0EmitPlanGeneratedDagArtifact, expected: GitProtocol) - && consumer_is(a: V1InterpreterDispatchGeneratedRsArtifact, expected: GitProtocol) - && match artifact_commit_policy(a: RunnerDeployArtifact) { NotCommitted => true _ => false } - && match artifact_commit_policy(a: AutoinstallUserDataArtifact { spec: srv3_autoinstall_spec }) { NotCommitted => true _ => false } - && match artifact_commit_policy(a: ProxyDhcpDnsmasqArtifact { spec: srv3_install_server_spec }) { NotCommitted => true _ => false } -} - -fn plan_refuses_workflow_paths(plan: HealPushPlan) -> Bool { - match plan { - HealPushPartial { ready: _, refused, cause: _ } => - any(map(refused, a => artifact_path(a: a)), p => p == ".github/workflows/ci.yml") - HealPushRefused { refused, cause: _ } => - any(map(refused, a => artifact_path(a: a)), p => p == ".github/workflows/ci.yml") - HealPushReady { artifacts: _ } => false - HealPushNothingToDo => false - HealPushPlanInconsistent { refused_paths: _ } => false - } -} - -fn refusal_is_actions_scope_unavailable(cause: HealPushRefusal) -> Bool { - count(cause.failures) == 1 - && fold_list( - xs: cause.failures, - empty: true, - cons: fn(acc, f) { - acc && match f.missing { - Absent => false - Present { value: axis } => permission_axis_wire_name(axis: axis) == "workflows" - } && match f.cause { - ActionsJobCredentialScopeUnavailable => true - _ => false - } - } - ) -} - -fn plan_cause_is_kind_cannot_satisfy(plan: HealPushPlan) -> Bool { - match plan { - HealPushPartial { ready: _, refused: _, cause } => refusal_is_actions_scope_unavailable(cause: cause) - HealPushRefused { refused: _, cause } => refusal_is_actions_scope_unavailable(cause: cause) - HealPushReady { artifacts: _ } => false - HealPushNothingToDo => false - HealPushPlanInconsistent { refused_paths: _ } => false - } -} - -test fn witness_live_heal_plan_refuses_workflow_paths_structurally() -> Bool { - plan_refuses_workflow_paths(plan: live_heal_push_plan) - && plan_cause_is_kind_cannot_satisfy(plan: live_heal_push_plan) -} - -fn owner_is_machine(c: HealPushRefusalCause) -> Bool { - match refusal_cause_remedy_owner(cause: c) { RemedyMachine => true _ => false } -} - -test fn witness_only_a_structurally_unavailable_scope_is_author_work() -> Bool { - match refusal_cause_remedy_owner(cause: ActionsJobCredentialScopeUnavailable) { - RemedyAuthor => true - _ => false - } - && owner_is_machine(c: PushBindingMissingOnCheckoutStep) - && owner_is_machine(c: PushBindingLeaseUnresolved) - && owner_is_machine(c: PushBindingStepKindNotSupported) - && owner_is_machine(c: PushBindingActionNotCheckout) - && owner_is_machine(c: PushBindingInputObservationDuplicated) - && owner_is_machine(c: PushBindingInputValueUnsupported) - && owner_is_machine(c: ManagedCredentialSubjectMismatch) - && owner_is_machine(c: ActionsJobCredentialAxisNotModeled) - && owner_is_machine(c: ActionsJobCredentialDeclaredAccessInvalid) - && owner_is_machine(c: ActionsJobCredentialScopeNotGranted) - && match refusal_cause_remedy_owner(cause: ManagedInstallationGrantUnobserved) { - RemedyProviderObservation => true - _ => false - } - && match refusal_cause_remedy_owner(cause: ActionsJobCredentialForkPolicyUnobserved) { - RemedyProviderObservation => true - _ => false - } -} - -test fn witness_binding_refusal_retains_its_locator() -> Bool { - let broken = plan_heal_push_from_binding( - artifacts: [CiYamlArtifact, GitignoreArtifact], - resolution: PushCredentialBindingMissing { checkout_step: ci_heal_checkout_step_ref }, - control_plane: live_heal_control_plane - ) - match broken { - HealPushRefused { refused: _, cause } => - (count(cause.failures) == 1) && any( - cause.failures, - f => match f.site { - Absent => false - Present { value: site } => - site.checkout_step.module_path == ci_heal_checkout_step_ref.module_path - && site.checkout_step.decl_name == ci_heal_checkout_step_ref.decl_name - && match site.input { Absent => true _ => false } - } - ) - _ => false - } -} - -// witness_refusal_cause_tokens_are_pairwise_distinct's fold_list cons lambda, third clause -// (t != "HealPushRefusalPopulationEmpty"): this pins what refusal_causes_token's -// fold relies on. It reuses the empty-population marker as its own "nothing accumulated -// yet" state, so a cause token colliding with that marker would make the first joined -// cause silently replace the marker instead of appending. Safe today by coincidence; -// this makes it safe by execution (review 49204). -test fn witness_refusal_cause_tokens_are_pairwise_distinct() -> Bool { - let causes = [ - ActionsJobCredentialScopeUnavailable, ActionsJobCredentialScopeNotGranted, - ActionsJobCredentialForkPolicyUnobserved, ActionsJobCredentialAxisNotModeled, - ActionsJobCredentialDeclaredAccessInvalid, PushBindingMissingOnCheckoutStep, - PushBindingLeaseUnresolved, PushBindingStepKindNotSupported, - PushBindingActionNotCheckout, PushBindingInputObservationDuplicated, - PushBindingInputValueUnsupported, ManagedInstallationGrantUnobserved, - ManagedCredentialSubjectMismatch - ] - let tokens = map(causes, c => heal_push_refusal_cause_token(cause: c)) - fold_list( - xs: tokens, - empty: true, - cons: fn(ok, t) { - ok && (count(filter(tokens, u => u == t)) == 1) && (t != "") - && (t != "HealPushRefusalPopulationEmpty") - } - ) -} - -test fn witness_machine_fault_never_becomes_author_work() -> Bool { - let broken_checkout = plan_heal_push_from_binding( - artifacts: [CiYamlArtifact, GitignoreArtifact], - resolution: PushCredentialBindingMissing { checkout_step: ci_heal_checkout_step_ref }, - control_plane: live_heal_control_plane - ) - match plan_remediation(plan: broken_checkout) { - MachineRepairRequired { causes } => - (count(causes) == 1) && any( - map(causes, c => heal_push_refusal_cause_token(cause: c)), - t => t == "PushBindingMissingOnCheckoutStep" - ) - _ => false - } && (count(remediation_author_commit_paths(r: plan_remediation(plan: broken_checkout))) == 0) - && match live_heal_remediation { - AuthorCommitRequired { paths, causes } => - (count(paths) == 3) && (count(causes) == 1) && any( - map(causes, c => heal_push_refusal_cause_token(cause: c)), - t => t == "ActionsJobCredentialScopeUnavailable" - ) - _ => false - } -} - -fn remediation_token(r: HealPushRemediation) -> String { - match r { - HealAutomatically { paths: _ } => "HealAutomatically" - AuthorCommitRequired { paths: _, causes: _ } => "AuthorCommitRequired" - MachineRepairRequired { causes: _ } => "MachineRepairRequired" - ProviderObservationRequired { causes: _ } => "ProviderObservationRequired" - HealNothingToRemediate => "HealNothingToRemediate" - HealPlanInconsistent { refused_paths: _ } => "HealPlanInconsistent" - } -} - -test fn witness_a_machine_repairable_failure_dominates_the_author_fallback() -> Bool { - let workflow_path = RepositoryPath { value: ".github/workflows/ci.yml" } - let both = HealPushRefusal { - paths: [workflow_path], - failures: [ - HealPushFailure { - cause: ActionsJobCredentialScopeNotGranted, - missing: Present { value: ContentsAxis } - }, - HealPushFailure { - cause: ActionsJobCredentialScopeUnavailable, - missing: Present { value: WorkflowsAxis } - } - ] - } - let residual_only = HealPushRefusal { - paths: [workflow_path], - failures: [ - HealPushFailure { - cause: ActionsJobCredentialScopeUnavailable, - missing: Present { value: WorkflowsAxis } - } - ] - } - remediation_token(r: remediation_for_refusal(refusal: both)) == "MachineRepairRequired" - && remediation_token(r: remediation_for_refusal(refusal: residual_only)) == "AuthorCommitRequired" - && (count(remediation_author_commit_paths(r: remediation_for_refusal(refusal: both))) == 0) - && match remediation_for_refusal(refusal: both) { - MachineRepairRequired { causes } => count(causes) == 1 - _ => false - } -} - -test fn witness_author_commit_requires_the_exact_workflow_path_residual() -> Bool { - let non_workflow = HealPushRefusal { - paths: [RepositoryPath { value: ".gitignore" }], - failures: [ - HealPushFailure { - cause: ActionsJobCredentialScopeUnavailable, - missing: Present { value: WorkflowsAxis } - } - ] - } - let wrong_axis = HealPushRefusal { - paths: [RepositoryPath { value: ".github/workflows/ci.yml" }], - failures: [ - HealPushFailure { - cause: ActionsJobCredentialScopeUnavailable, - missing: Present { value: ContentsAxis } - } - ] - } - let axis_absent = HealPushRefusal { - paths: [RepositoryPath { value: ".github/workflows/ci.yml" }], - failures: [ - HealPushFailure { cause: ActionsJobCredentialScopeUnavailable, missing: none } - ] - } - remediation_token(r: remediation_for_refusal(refusal: non_workflow)) == "HealPlanInconsistent" - && remediation_token(r: remediation_for_refusal(refusal: wrong_axis)) == "HealPlanInconsistent" - && remediation_token(r: remediation_for_refusal(refusal: axis_absent)) == "HealPlanInconsistent" -} - -test fn witness_provider_observation_outranks_author_but_not_machine() -> Bool { - let workflow_path = RepositoryPath { value: ".github/workflows/ci.yml" } - let provider_and_residual = HealPushRefusal { - paths: [workflow_path], - failures: [ - HealPushFailure { - cause: ActionsJobCredentialForkPolicyUnobserved, - missing: Present { value: ContentsAxis } - }, - HealPushFailure { - cause: ActionsJobCredentialScopeUnavailable, - missing: Present { value: WorkflowsAxis } - } - ] - } - let machine_and_provider = HealPushRefusal { - paths: [workflow_path], - failures: [ - HealPushFailure { - cause: ActionsJobCredentialForkPolicyUnobserved, - missing: Present { value: ContentsAxis } - }, - HealPushFailure { - cause: ActionsJobCredentialScopeNotGranted, - missing: Present { value: ContentsAxis } - } - ] - } - remediation_token(r: remediation_for_refusal(refusal: provider_and_residual)) == "ProviderObservationRequired" - && remediation_token(r: remediation_for_refusal(refusal: machine_and_provider)) == "MachineRepairRequired" -} - -test fn witness_refusal_population_is_retained_not_collapsed() -> Bool { - let two = HealPushRefusal { - paths: [RepositoryPath { value: ".github/workflows/ci.yml" }], - failures: [ - HealPushFailure { - cause: ActionsJobCredentialScopeNotGranted, - missing: Present { value: ContentsAxis } - }, - HealPushFailure { - cause: ActionsJobCredentialScopeUnavailable, - missing: Present { value: WorkflowsAxis } - } - ] - } - (count(two.failures) == 2) - && (refusal_causes_token(causes: failure_causes(fs: two.failures)) == "ActionsJobCredentialScopeNotGranted+ActionsJobCredentialScopeUnavailable") -} - -test fn witness_live_refusal_cause_token_is_derived_from_the_plan() -> Bool { - live_heal_push_refusal_cause_token() == "ActionsJobCredentialScopeUnavailable" - && live_heal_push_refusal_cause_token() != "GitHubAppLacksWorkflowsWrite" - && heal_push_refusal_cause_token(cause: ManagedInstallationGrantUnobserved) == "ManagedInstallationGrantUnobserved" - && heal_push_refusal_cause_token(cause: ManagedCredentialSubjectMismatch) == "ManagedCredentialSubjectMismatch" - && heal_push_refusal_cause_token(cause: ActionsJobCredentialForkPolicyUnobserved) == "ActionsJobCredentialForkPolicyUnobserved" -} - -test fn witness_heal_plan_empty_input_is_nothing_to_do() -> Bool { - match plan_heal_push_from_binding( - artifacts: [], - resolution: live_heal_push_binding_resolution, - control_plane: live_heal_control_plane - ) { - HealPushNothingToDo => true - HealPushPlanInconsistent { refused_paths: _ } => false - HealPushReady { artifacts: _ } => false - HealPushPartial { ready: _, refused: _, cause: _ } => false - HealPushRefused { refused: _, cause: _ } => false - } -} - -test fn witness_heal_plan_non_workflow_artifacts_are_ready() -> Bool { - match plan_heal_push_from_binding( - artifacts: [GitignoreArtifact, DesignArtifact], - resolution: live_heal_push_binding_resolution, - control_plane: live_heal_control_plane - ) { - HealPushReady { artifacts } => count(artifacts) == 2 - HealPushNothingToDo => false - HealPushPlanInconsistent { refused_paths: _ } => false - HealPushPartial { ready: _, refused: _, cause: _ } => false - HealPushRefused { refused: _, cause: _ } => false - } -} - -test fn witness_heal_plan_workflow_only_refuses_wholesale() -> Bool { - match plan_heal_push_from_binding( - artifacts: [CiYamlArtifact, FalsifierYamlArtifact], - resolution: live_heal_push_binding_resolution, - control_plane: live_heal_control_plane - ) { - HealPushRefused { refused, cause: _ } => count(refused) == 2 - HealPushNothingToDo => false - HealPushPlanInconsistent { refused_paths: _ } => false - HealPushReady { artifacts: _ } => false - HealPushPartial { ready: _, refused: _, cause: _ } => false - } -} - -test fn witness_heal_policy_workflow_artifacts_require_author_commit() -> Bool { - (count(author_commit_required_committed_artifacts()) == 3) - && (count(auto_push_eligible_committed_artifacts()) == count(committed_generated_artifacts()) - 3) - && path_requires_author_commit(path: ".github/workflows/ci.yml") - && path_requires_author_commit(path: ".github/workflows/falsifier.yml") - && path_requires_author_commit(path: ".github/workflows/fleet-converge.yml") - && !path_requires_author_commit(path: ".gitignore") - -} - -data witness_extra_validation_wired_note: String = "P0 (operator-directed, 2026-08-05; loyal-ram-550 review of #7823): artifact_extra_valid takes the already-computed generation outcome rather than generating internally, and this witness proves it is WIRED, not that generation itself works (generation is proven elsewhere, by the observer and the gate) — so it hands each arm a SYNTHETIC ArtifactGenerated { content: \"x\" }, never a real artifact_generate(a:) call; no generation happens in this witness at all. Only two of the twelve arms (Stage0EmitPlanGeneratedDagArtifact, V1InterpreterDispatchGeneratedRsArtifact) read the generated parameter — the other ten ignore it and return true or delegate to ci_yml_parses. The positive alone cannot tell an arm that reads the parameter from one that discards it and returns true unconditionally, so witness_extra_validation_wired_refuses_on_generation_refusal is the discriminating RED: it hands those same two arms an ArtifactGenerationRefused and asserts false — a result only reachable if the arm genuinely matches on the value threaded through it. That RED cannot pass under a bare arrow-true stub." - -test fn witness_extra_validation_wired() -> Bool { - artifact_extra_valid(a: GitignoreArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: GitattributesArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: RoadmapArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: DesignArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: CiYamlArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: FalsifierYamlArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: Stage0CrateLayoutGeneratedDagArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: Stage0CrateLayoutGeneratedRsArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: Stage0EmitPlanGeneratedDagArtifact, generated: ArtifactGenerated { content: "x" }) - && artifact_extra_valid(a: V1InterpreterDispatchGeneratedRsArtifact, generated: ArtifactGenerated { content: "x" }) -} - -test fn witness_extra_validation_wired_refuses_on_generation_refusal() -> Bool { - !artifact_extra_valid(a: Stage0EmitPlanGeneratedDagArtifact, generated: ArtifactGenerationRefused { reason: "x" }) - && !artifact_extra_valid(a: V1InterpreterDispatchGeneratedRsArtifact, generated: ArtifactGenerationRefused { reason: "x" }) -} diff --git a/dag/test/claim/heal_author_commit_witness_test.dag b/dag/test/claim/heal_author_commit_witness_test.dag deleted file mode 100644 index 6627f0bdf1a..00000000000 --- a/dag/test/claim/heal_author_commit_witness_test.dag +++ /dev/null @@ -1,84 +0,0 @@ - -module test.claim.heal_author_commit_witness - -import gunbc.generated_artifact { - CiYamlArtifact, FalsifierYamlArtifact, GitignoreArtifact, DesignArtifact, - artifact_path -} -import gunbc.heal_push_plan { - classify_heal_repair_paths, - HealRepairNoDrift, - HealRepairAutoPushEligibleOnly, - HealRepairAuthorCommitRequired, - HealRepairMixed, - path_requires_author_commit -} -import gunbc.ci_spec { - ci_heal_author_commit_regen_command, - gunbc_ci_heal_commit_push_script -} - -data heal_author_commit_witness_note: String = "Synthetic executing controls for the two repair dispositions (operator brief 2026-08-02). Control 1: non-workflow generated drift classifies as AutoPushEligibleOnly — the heal shell stages auto_push_eligible paths and retains git push for that population. Control 2: workflow-only drift classifies as AuthorCommitRequired — the shell detects workflow paths, packages heal-author-commit-required/, emits HealAuthorCommitRequired with every affected path and the local regen command, and never git-adds workflow paths. RED controls flip the classification or shell structure." - -test fn control_non_workflow_drift_is_auto_push_eligible_only() -> Bool { - match classify_heal_repair_paths(changed_paths: [".gitignore", "DESIGN.md"]) { - HealRepairAutoPushEligibleOnly { paths } => - (paths == [".gitignore", "DESIGN.md"]) - HealRepairNoDrift => false - HealRepairAuthorCommitRequired { paths: _ } => false - HealRepairMixed { auto_push_paths: _, author_commit_paths: _ } => false - } -} - -test fn control_workflow_only_drift_is_author_commit_required() -> Bool { - match classify_heal_repair_paths(changed_paths: [ - artifact_path(a: CiYamlArtifact), - artifact_path(a: FalsifierYamlArtifact) - ]) { - HealRepairAuthorCommitRequired { paths } => - (paths == [ - artifact_path(a: CiYamlArtifact), - artifact_path(a: FalsifierYamlArtifact) - ]) - HealRepairNoDrift => false - HealRepairAutoPushEligibleOnly { paths: _ } => false - HealRepairMixed { auto_push_paths: _, author_commit_paths: _ } => false - } -} - -test fn control_mixed_drift_partitions_both_populations() -> Bool { - match classify_heal_repair_paths(changed_paths: [ - ".gitignore", - artifact_path(a: CiYamlArtifact) - ]) { - HealRepairMixed { auto_push_paths, author_commit_paths } => - (auto_push_paths == [".gitignore"]) - && (author_commit_paths == [artifact_path(a: CiYamlArtifact)]) - HealRepairNoDrift => false - HealRepairAutoPushEligibleOnly { paths: _ } => false - HealRepairAuthorCommitRequired { paths: _ } => false - } -} - -test fn control_workflow_shell_never_stages_workflow_paths() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - !string_contains(s: script, pattern: concat("git add \"", artifact_path(a: CiYamlArtifact))) - && !string_contains(s: script, pattern: concat("git add \"", artifact_path(a: FalsifierYamlArtifact))) - && string_contains(s: script, pattern: concat("git add \"", artifact_path(a: GitignoreArtifact))) -} - -test fn control_workflow_shell_emits_regen_command_and_artifact_dir() -> Bool { - let script = gunbc_ci_heal_commit_push_script() - string_contains(s: script, pattern: "HealAuthorCommitRequired") - && string_contains(s: script, pattern: ci_heal_author_commit_regen_command) - && string_contains(s: script, pattern: "heal-author-commit-required") - && string_contains(s: script, pattern: "author_commit_paths=$AUTHOR_COMMIT_DRIFT") -} - -test fn red_control_gitignore_is_not_author_commit_required() -> Bool { - !path_requires_author_commit(path: ".gitignore") -} - -test fn red_control_ci_yml_is_author_commit_required() -> Bool { - path_requires_author_commit(path: artifact_path(a: CiYamlArtifact)) -} diff --git a/dag/test/claim/heal_revalidation_integration_witness_test.dag b/dag/test/claim/heal_revalidation_integration_witness_test.dag deleted file mode 100644 index 7a882c919a1..00000000000 --- a/dag/test/claim/heal_revalidation_integration_witness_test.dag +++ /dev/null @@ -1,47 +0,0 @@ -module test.claim.heal_revalidation_integration_witness - -import test.claim.heal_revalidation_witness { - heal_no_change_creates_no_revalidation_obligation, - heal_produced_is_immediately_revalidation_required, - produced_head_supersedes_prior_run, - accepted_dispatch_is_not_revalidation, - refused_dispatch_stays_required_and_located, - only_exact_healed_head_complete_coverage_admits, - manual_dispatch_without_expected_sha_cannot_masquerade_as_heal_revalidation, - expected_sha_preflight_binds_run_subject_and_checkout_exactly -} -import test.claim.workflow_dispatch_input_witness { - workflow_dispatch_nonempty_inputs_are_realized_not_dropped, - workflow_dispatch_empty_inputs_preserve_null_projection -} -import test.claim.ci_heal_job_witness { - actions_write_is_scoped_to_heal_only, - workflow_dispatch_carries_optional_exact_healed_sha_input, - heal_produced_dispatches_and_supersedes_old_run, - dispatch_failure_is_loud_and_has_no_push_event_fallback, - heal_dispatch_step_exports_github_token_authority -} -import v2.workflow.ci_heal_revalidation_preflight_emit_test { - preflight_is_exact_head_and_precedes_any_witness, - preflight_absent_input_is_ordinary_manual_ci -} - -test fn heal_revalidation_integration_witnesses_hold() -> Bool { - heal_no_change_creates_no_revalidation_obligation() - && heal_produced_is_immediately_revalidation_required() - && produced_head_supersedes_prior_run() - && accepted_dispatch_is_not_revalidation() - && refused_dispatch_stays_required_and_located() - && only_exact_healed_head_complete_coverage_admits() - && manual_dispatch_without_expected_sha_cannot_masquerade_as_heal_revalidation() - && expected_sha_preflight_binds_run_subject_and_checkout_exactly() - && workflow_dispatch_nonempty_inputs_are_realized_not_dropped() - && workflow_dispatch_empty_inputs_preserve_null_projection() - && actions_write_is_scoped_to_heal_only() - && workflow_dispatch_carries_optional_exact_healed_sha_input() - && heal_produced_dispatches_and_supersedes_old_run() - && dispatch_failure_is_loud_and_has_no_push_event_fallback() - && heal_dispatch_step_exports_github_token_authority() - && preflight_is_exact_head_and_precedes_any_witness() - && preflight_absent_input_is_ordinary_manual_ci() -} diff --git a/dag/test/claim/long/generated_artifact_drift_fixed_point_witness_test.dag b/dag/test/claim/long/generated_artifact_drift_fixed_point_witness_test.dag deleted file mode 100644 index 201dc801f61..00000000000 --- a/dag/test/claim/long/generated_artifact_drift_fixed_point_witness_test.dag +++ /dev/null @@ -1,41 +0,0 @@ -module test.claim.long.generated_artifact_drift_fixed_point_witness - -import gunbc.generated_artifact { - GeneratedArtifact, CiYamlArtifact, - committed_generated_artifacts, artifact_path, -} -import gunbc.generated_artifact_emit { ArtifactGenerated, ArtifactGenerationRefused, artifact_generate } -import extdeps.filesystem.filesystem_io { Filesystem } -import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree } - -data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree - -data generated_artifact_drift_fixed_point_long_note: String = "Rehomed from dag/test/claim/generated_artifact_drift_test.dag (operator 5-second rule, 2026-08-03): witness_committed_is_fixed_point and its RED control read REAL committed bytes off disk (Filesystem.Read, ReadsLiveTree) and regenerate every committed artifact — measured 1005ms warm on srv_fleet_arm64 (witness_row_cost_basis.tsv) and 5004ms in falsifier discovery-corpus batch 1 (run 30550328673, BudgetExceeded) — a wall figure and a CPU figure respectively, so do not read a ratio off them without reading that note first. WHY those differ is diagnosed once, in fixed_point_witness_long_lane_note (dag/test/claim/generated_artifact_drift_test.dag), and deliberately not restated here — this was the THIRD prose copy of one cause, and all three said host contention, which that note retracts as false on the thread-CPU clock the budget is armed on (corrected 2026-08-04; DESIGN 3, one fact one home). The fast witnesses (registry completeness, per-artifact generate-to-generate RED, policy rows) stay per-PR discovered in the parent file. Enrolled on falsifier_substrate_long_lane_entries (nightly falsifier batch 6, 180s eval budget). Local recipe: claim_batch --source-root dag --source-root src/v2 --entry dag/test/claim/long/generated_artifact_drift_fixed_point_witness_test.dag --functions witness_committed_is_fixed_point,witness_committed_fixed_point_red_control. Dissolve-on: eval lands under gunbc_ci_fast_lane_witness_eval_budget on a measured cold run and re-enrolls per-PR discovery." - -data fixed_point_witness_note: String = "Fixed-point / byte-idempotence leg (ci-chores P0, 2026-07-22): witness_committed_is_fixed_point reads the REAL committed bytes off disk (Filesystem.Read, ReadsLiveTree) and asserts a fresh artifact_generate reproduces them byte-for-byte for every committed artifact. This is the executable form of `regen yields zero diff` — the property the automated chore commit relies on. It differs from witness_per_artifact_red_receipts (which compares generate-to-generate and so is blind to a committed-vs-generated mismatch such as the missing-trailing-newline defect P0 chased). RED control: witness_committed_fixed_point_red_control perturbs the read bytes and requires the equality to fail, so a false-green fixed point is unwritable." - -data perturb: String = "\n# gunbc-generated-artifact-drift-receipt-perturb" - -fn artifact_drifted(a: GeneratedArtifact, committed: String) -> Bool { - match artifact_generate(a: a) { - ArtifactGenerationRefused { reason: _ } => true - ArtifactGenerated { content } => !(committed == content) - } -} - -fn artifact_committed_matches(a: GeneratedArtifact) -> Bool { - let committed = Filesystem.Read(path: artifact_path(a: a)) - committed.success && !artifact_drifted(a: a, committed: committed.content) -} - -test fn witness_committed_is_fixed_point() -> Bool { - count(committed_generated_artifacts()) > 0 - && all(committed_generated_artifacts(), a => artifact_committed_matches(a: a)) -} - -test fn witness_committed_fixed_point_red_control() -> Bool { - let a = CiYamlArtifact - let committed = Filesystem.Read(path: artifact_path(a: a)) - committed.success - && artifact_drifted(a: a, committed: concat(committed.content, perturb)) -} diff --git a/dag/test/claim/observation_emit_census_witness_test.dag b/dag/test/claim/observation_emit_census_witness_test.dag index 5f8827b064b..e01a3286323 100644 --- a/dag/test/claim/observation_emit_census_witness_test.dag +++ b/dag/test/claim/observation_emit_census_witness_test.dag @@ -26,7 +26,6 @@ import gunbc.observation_emit_census { assembly_split_site, witness_row_cost_site, witness_row_cost_migration_disclosure_site, - selection_degradation_site, } data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree @@ -131,9 +130,7 @@ test fn w_post_snapshot_live_tags_are_rostered_bidirectional() -> Bool { census_marker_present(site: witness_row_cost_site) && emit_site_is_frontier(site: witness_row_cost_site) && census_marker_present(site: witness_row_cost_migration_disclosure_site) && - emit_site_is_frontier(site: witness_row_cost_migration_disclosure_site) && - census_marker_present(site: selection_degradation_site) && - emit_site_is_frontier(site: selection_degradation_site) + emit_site_is_frontier(site: witness_row_cost_migration_disclosure_site) } test fn w_the_raw_byte_dump_shape_is_gone_from_the_seed() -> Bool { diff --git a/dag/test/claim/os_install_deduction_witness_test.dag b/dag/test/claim/os_install_deduction_witness_test.dag index 62c04d6343c..e01e2730f7e 100644 --- a/dag/test/claim/os_install_deduction_witness_test.dag +++ b/dag/test/claim/os_install_deduction_witness_test.dag @@ -6,7 +6,6 @@ import extdeps.os.ubuntu_autoinstall { NoCloudLocal, StoragePolicyDirectLayout, import gunbc.os_install_deduction { AutoinstallIncompleteNotBootable, ForeignOsPresent, KvmOperatorAttestation, LoginPrompt, RequiresStoragePolicy, SubiquityStorageScreen, UnknownDiskState, fold_nbd_proxy_os_install_preflight_verdict, plan_for_os_install_preflight_verdict, runtime_verdict_from_kvm_attestation } import gunbc.os_install_emit { autoinstall_user_data } import std.types { Bool } -import test.claim.falsifier_workflow_witness_test { string_contains } import v2.std.live_tree { LiveTreeDisposition } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -217,3 +216,10 @@ test fn kvm_login_prompt_is_weak_not_os_installed() -> Bool { _ => false } } + +// Local since the falsifier witness that used to declare it was deleted with the CI wipe +// (2026-08-15). One line over one builtin: a cross-test import for this is a dependency on +// another witness's incidental helper, not on a shared authority. +fn string_contains(s: String, pattern: String) -> Bool { + s.contains(pattern) +} diff --git a/dag/test/claim/push_before_main_push_selection_witness_test.dag b/dag/test/claim/push_before_main_push_selection_witness_test.dag deleted file mode 100644 index 5e9c698733d..00000000000 --- a/dag/test/claim/push_before_main_push_selection_witness_test.dag +++ /dev/null @@ -1,137 +0,0 @@ -module test.claim.push_before_main_push_selection_witness_test - -import std.logic { Bool } -import std.types { String, NonEmptyStr, list_length, List } -import std.nat { Nat } -import gunbc.diff_baseline { - CiDiffEvent, - DiffBaseline, - DiffBaselineResolution, - PushBefore, - PushBeforeSha, - BaselineSelected, - BaselineRefused, - BaselineSourceConflict, - resolve_diff_baseline -} -import gunbc.repo_identity { gunbc_merge_target_ref, gunbc_default_remote_name } -import gunbc.selection_degradation_receipt { - selection_degradation_receipt_of, - selection_degradation_receipt_line, - selection_degradation_is_applied_narrowed, - selection_degradation_state_tag -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data push_before_selection_witness_note: String = "Discriminating witness for push-before main-push selection (checklist step 6): a planted push delta observes PushBefore (not self-compare), carries a non-empty changed-path population, and the selection-degradation receipt reads SelectionApplied with selected/total derived from that population (selected>0, selected0 matters: a zero-path diff still classifies as SelectionApplied with selected=0 — the empty-observation narrow trap the push-before baseline closes." - -data planted_before_sha: String = "1111111111111111111111111111111111111111" -data planted_head_sha: String = "2222222222222222222222222222222222222222" - -data roster_entry_push_event: String = "dag/extdeps/github/push_event.dag" -data roster_entry_diff_baseline: String = "dag/gunbc/diff_baseline.dag" -data roster_entry_ci_spec: String = "dag/gunbc/ci_spec.dag" - -fn planted_entry_group_roster() -> List { - [roster_entry_push_event, roster_entry_diff_baseline, roster_entry_ci_spec] -} - -fn planted_push_delta_changed_paths() -> List { - [roster_entry_push_event, roster_entry_diff_baseline] -} - -fn roster_entry_selected(entry: String, changed_paths: List) -> Bool { - fold( - changed_paths, - init: false, - f: (acc, path) => acc || path == entry - ) -} - -fn count_selected_entry_groups(roster: List, changed_paths: List) -> Nat { - fold( - roster, - init: 0, - f: (acc, entry) => - if roster_entry_selected(entry: entry, changed_paths: changed_paths) { - acc + 1 - } else { - acc - } - ) -} - -fn planted_main_push_baseline_resolution() -> DiffBaselineResolution { - resolve_diff_baseline( - event: CiDiffEvent { - override_ref: none, - event_name: "push", - base_ref: none, - push_before: Present { value: PushBeforeSha { sha: planted_before_sha } }, - head_sha: Present { value: planted_head_sha }, - diff_window: none - }, - push_parent_ref: gunbc_merge_target_ref, - default_remote_name: gunbc_default_remote_name - ) -} - -test fn witness_main_push_resolves_push_before_not_parent() -> Bool { - match planted_main_push_baseline_resolution() { - BaselineSelected { baseline: PushBefore { ref: ref } } => - (ref as String) == planted_before_sha - BaselineRefused { reason: _ } => false - BaselineSourceConflict { window_detail: _, override_ref: _ } => false - BaselineSelected { baseline: _ } => false - } -} - -test fn witness_self_compare_would_observe_zero_changed_paths() -> Bool { - list_length(items: planted_push_delta_changed_paths()) > 0 - && list_length(items: []) == 0 -} - -test fn witness_main_push_selection_degradation_applied_from_planted_delta() -> Bool { - let roster = planted_entry_group_roster() - let changed = planted_push_delta_changed_paths() - let total = list_length(items: roster) - let selected = count_selected_entry_groups(roster: roster, changed_paths: changed) - let line = selection_degradation_receipt_line( - selection_mode_tag: "applied" as NonEmptyStr, - selected: selected, - total: total, - categorization_unavailable: false, - categorization_reason: "" - ) - let receipt = selection_degradation_receipt_of( - selection_mode_tag: "applied" as NonEmptyStr, - selected: selected, - total: total, - categorization_unavailable: false, - categorization_reason: "" - ) - selection_degradation_is_applied_narrowed(receipt: receipt) - && selected > 0 - && selected < total - && selection_degradation_state_tag(state: receipt.selection_state) == "SelectionApplied" - && string_contains(s: line, pattern: "selected_entry_groups=2") - && string_contains(s: line, pattern: "total_entry_groups=3") -} - -test fn witness_empty_delta_zero_selected_still_reads_applied_red() -> Bool { - let roster = planted_entry_group_roster() - let total = list_length(items: roster) - let selected = count_selected_entry_groups(roster: roster, changed_paths: []) - let receipt = selection_degradation_receipt_of( - selection_mode_tag: "applied" as NonEmptyStr, - selected: selected, - total: total, - categorization_unavailable: false, - categorization_reason: "" - ) - selected == 0 - && selection_degradation_is_applied_narrowed(receipt: receipt) - && selection_degradation_state_tag(state: receipt.selection_state) == "SelectionApplied" -} diff --git a/dag/test/claim/realization_schedule_witness_test.dag b/dag/test/claim/realization_schedule_witness_test.dag index da3fdc1b255..078e3ca5fbe 100644 --- a/dag/test/claim/realization_schedule_witness_test.dag +++ b/dag/test/claim/realization_schedule_witness_test.dag @@ -2,8 +2,6 @@ module test.claim.realization_schedule_witness import std.content_hash { ContentHash, content_hash_of_value } -import v2.workflow.ci_floor_plan { cheap_floor_gate_step_labels } - 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." @@ -25,7 +23,6 @@ fn synthetic_correct_schedule() -> List> { source_roots: ["dag"] scan_dirs: [] explicit_entries: [] - node_frontier_selection: SelectionOff profile: runnable_resource_profile_negligible() exclude_substrings: [] discovery_scope_dirs: [] @@ -51,34 +48,3 @@ fn perturbed_schedule_wrong_order(correct: List>) -> List Bool { - match v2.lens.schedule_lens.schedule_lens_verdict_for_ci_floor_ordinary( - plan: synthetic_correct_plan(), - compile_gate_fn: compile_gate_fn, - cheap_gate_labels: cheap_floor_gate_step_labels() - ) { - Holds => true - Violation { diagnostic: _ } => false - NotApplicable { diagnostic: _ } => false - Unrealized { diagnostic: _ } => false - } -} - -test fn witness_schedule_lens_red_when_corpus_runs_first_on_synthetic() -> Bool { - let perturbed = RealizationPlan { - target: synthetic_target - objective: RealizationObjective { goals: [] } - schedule: perturbed_schedule_wrong_order(correct: synthetic_correct_schedule()) - total: cost_account_predicted_zero() - } - match v2.lens.schedule_lens.schedule_lens_verdict_for_ci_floor_ordinary( - plan: perturbed, - compile_gate_fn: compile_gate_fn, - cheap_gate_labels: cheap_floor_gate_step_labels() - ) { - Holds => false - Violation { diagnostic: _ } => true - NotApplicable { diagnostic: _ } => false - Unrealized { diagnostic: _ } => false - } -} diff --git a/dag/test/claim/runnable_resource_profile_witness_test.dag b/dag/test/claim/runnable_resource_profile_witness_test.dag index c55bb0d4b8c..daf6f64fe00 100644 --- a/dag/test/claim/runnable_resource_profile_witness_test.dag +++ b/dag/test/claim/runnable_resource_profile_witness_test.dag @@ -47,7 +47,6 @@ test fn witness_corpus_never_forbids_co_residence() -> Bool { source_roots: [] scan_dirs: [] explicit_entries: [] - node_frontier_selection: SelectionOff profile: runnable_resource_profile( heavy_whole_tree_resolve: true, spawns_host_compiler: false, diff --git a/dag/test/claim/seed_debt_bundle_item_2_floor_scope.dag b/dag/test/claim/seed_debt_bundle_item_2_floor_scope.dag index e4bbb134795..8eddc5156ea 100644 --- a/dag/test/claim/seed_debt_bundle_item_2_floor_scope.dag +++ b/dag/test/claim/seed_debt_bundle_item_2_floor_scope.dag @@ -2,7 +2,6 @@ module test.claim.seed_debt_bundle_item_2_floor_scope import gunbc.ci_layer_roots { witness_layer_roots } import std.realization_schedule { - SelectionOff, Runnable, RunnableDiscoveryBatch, ScheduleWitnessEntry, @@ -28,7 +27,6 @@ fn seed_debt_floor_scope_batches() -> List> { source_roots: witness_layer_roots, scan_dirs: [], explicit_entries: seed_debt_witness_entries(), - node_frontier_selection: SelectionOff, exclude_substrings: [], discovery_scope_dirs: [], profile: runnable_resource_profile_negligible() diff --git a/dag/test/claim/selection_degradation_receipt_witness_test.dag b/dag/test/claim/selection_degradation_receipt_witness_test.dag deleted file mode 100644 index eff5c8c8d77..00000000000 --- a/dag/test/claim/selection_degradation_receipt_witness_test.dag +++ /dev/null @@ -1,140 +0,0 @@ -module test.claim.selection_degradation_receipt_witness_test - -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } -import std.types { String, Bool, NonEmptyStr } -import std.nat { Nat } -import gunbc.selection_degradation_receipt { - SelectionDegradationReceipt, - SelectionDegradationApplied, - SelectionDegradationSuperset, - SelectionDegradationOff, - selection_degradation_receipt_of, - selection_degradation_receipt_line, - selection_degradation_receipt_body, - selection_degradation_is_superset, - selection_degradation_is_applied_narrowed, - selection_degradation_state_tag, -} - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -// Executing consumer for gunbc.selection_degradation_receipt (floor prep-tax P2). THE PAIR IS THE PROOF: a narrowed affected run must read SelectionApplied with honest counts; a whole-corpus affected run must read SelectionSuperset with an explicit fallback_reason — never quiet success. RED controls mislabel a superset as applied. -test fn sdr_applied_narrowed_receipt() -> Bool { - let line = selection_degradation_receipt_line( - selection_mode_tag: "applied" as NonEmptyStr, - selected: 602, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - let r = selection_degradation_receipt_of( - selection_mode_tag: "applied" as NonEmptyStr, - selected: 602, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - selection_degradation_is_applied_narrowed(receipt: r) - && string_contains(s: line, pattern: "selection_state=SelectionApplied") - && string_contains(s: line, pattern: "selected_entry_groups=602") - && string_contains(s: line, pattern: "total_entry_groups=842") - && string_contains(s: line, pattern: "selection_ratio=0.7149") - && string_contains(s: line, pattern: "fallback_reason=") -} - -test fn sdr_superset_whole_corpus_is_loud() -> Bool { - let line = selection_degradation_receipt_line( - selection_mode_tag: "applied" as NonEmptyStr, - selected: 842, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - let r = selection_degradation_receipt_of( - selection_mode_tag: "applied" as NonEmptyStr, - selected: 842, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - selection_degradation_is_superset(receipt: r) - && string_contains(s: line, pattern: "selection_state=SelectionSuperset") - && string_contains(s: line, pattern: "selected_entry_groups=842") - && string_contains(s: line, pattern: "total_entry_groups=842") - && string_contains(s: line, pattern: "selection_ratio=1.0000") - && string_contains(s: line, pattern: "counted performance degradation") -} - -test fn sdr_off_mode_reports_full_run() -> Bool { - let line = selection_degradation_receipt_line( - selection_mode_tag: "off" as NonEmptyStr, - selected: 842, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - let r = selection_degradation_receipt_of( - selection_mode_tag: "off" as NonEmptyStr, - selected: 842, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - selection_degradation_state_tag(state: r.selection_state) == "SelectionOff" - && string_contains(s: line, pattern: "selection_state=SelectionOff") -} - -test fn sdr_superset_must_not_read_as_applied_red() -> Bool { - let r = selection_degradation_receipt_of( - selection_mode_tag: "applied" as NonEmptyStr, - selected: 842, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - !selection_degradation_is_applied_narrowed(receipt: r) -} - -test fn sdr_categorization_unavailable_superset_still_superset() -> Bool { - let r = selection_degradation_receipt_of( - selection_mode_tag: "applied" as NonEmptyStr, - selected: 842, - total: 842, - categorization_unavailable: true, - categorization_reason: "module graph facts absent" - ) - selection_degradation_is_superset(receipt: r) - && string_contains( - s: r.fallback_reason, - pattern: "upfront import-closure categorization failed" - ) -} - -test fn sdr_receipt_body_carries_all_five_fields() -> Bool { - let body = selection_degradation_receipt_body( - selection_mode_tag: "applied" as NonEmptyStr, - selected: 602, - total: 842, - categorization_unavailable: false, - categorization_reason: "" - ) - string_contains(s: body, pattern: "selection_state=SelectionApplied") - && string_contains(s: body, pattern: "selected_entry_groups=602") - && string_contains(s: body, pattern: "total_entry_groups=842") - && string_contains(s: body, pattern: "selection_ratio=0.7149") - && string_contains(s: body, pattern: "fallback_reason=") -} - -test fn sdr_unknown_mode_tag_is_unavailable_fail_closed() -> Bool { - let r = selection_degradation_receipt_of( - selection_mode_tag: "bogus" as NonEmptyStr, - selected: 1, - total: 2, - categorization_unavailable: false, - categorization_reason: "" - ) - selection_degradation_state_tag(state: r.selection_state) == "SelectionUnavailable" - && string_contains(s: r.fallback_reason, pattern: "unknown selection_mode_tag") - && string_contains(s: r.fallback_reason, pattern: "bogus") - && !string_contains(s: r.fallback_reason, pattern: "categorization failed") -} diff --git a/dag/test/claim/srv3_install_server_emit_test.dag b/dag/test/claim/srv3_install_server_emit_test.dag index e4556ae8c36..ef28ba6fe4e 100644 --- a/dag/test/claim/srv3_install_server_emit_test.dag +++ b/dag/test/claim/srv3_install_server_emit_test.dag @@ -6,7 +6,6 @@ import extdeps.provisioning.dhcp_client_arch { dhcp_client_processor_architectur import extdeps.provisioning.network_boot { UefiHttpBoot } import gunbc.install_server_emit { install_server_dnsmasq_conf } import std.types { Bool } -import test.claim.falsifier_workflow_witness_test { string_contains } import v2.std.live_tree { LiveTreeDisposition } import v2.std.optional { Present } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -50,3 +49,10 @@ test fn rfc4578_client_arch_mapping_is_grounded() -> Bool { Absent => true } } + +// Local since the falsifier witness that used to declare it was deleted with the CI wipe +// (2026-08-15). One line over one builtin: a cross-test import for this is a dependency on +// another witness's incidental helper, not on a shared authority. +fn string_contains(s: String, pattern: String) -> Bool { + s.contains(pattern) +} diff --git a/dag/test/claim/uri_grounding_witness_test.dag b/dag/test/claim/uri_grounding_witness_test.dag index d7207234419..23c9a1bea5a 100644 --- a/dag/test/claim/uri_grounding_witness_test.dag +++ b/dag/test/claim/uri_grounding_witness_test.dag @@ -2,7 +2,6 @@ module test.claim.uri_grounding_witness import extdeps.uri { Https, Uri, uri_is_url, uri_wire } import std.types { Bool } -import test.claim.falsifier_workflow_witness_test { string_contains } import v2.std.live_tree { LiveTreeDisposition } data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly @@ -21,3 +20,9 @@ test fn w_nonempty_str_html_url_holds() -> Bool { string_contains(url, pattern: "github.com") } +// Local since the falsifier witness that used to declare it was deleted with the CI wipe +// (2026-08-15). One line over one builtin: a cross-test import for this is a dependency on +// another witness's incidental helper, not on a shared authority. +fn string_contains(s: String, pattern: String) -> Bool { + s.contains(pattern) +} diff --git a/dag/test/claim/yaml_ingest_witness_test.dag b/dag/test/claim/yaml_ingest_witness_test.dag index 9ea7a22fa79..3713269eed9 100644 --- a/dag/test/claim/yaml_ingest_witness_test.dag +++ b/dag/test/claim/yaml_ingest_witness_test.dag @@ -41,10 +41,6 @@ test fn witness_empty_string_scalar_round_trips() -> Bool { round_trips(v: yaml_mapping(entries: [kv(key: "rustflags", value: yaml_string(s: ""))])) } -test fn witness_real_ci_yml_parses() -> Bool { - yaml_source_parses(src: expected_ci_yml()) -} - test fn witness_empty_document_rejected() -> Bool { yaml_source_parses(src: "") == false } diff --git a/dag/tools/dag_compile_clean_scope.dag b/dag/tools/dag_compile_clean_scope.dag index df28ba4db1f..2d9bc63d58e 100644 --- a/dag/tools/dag_compile_clean_scope.dag +++ b/dag/tools/dag_compile_clean_scope.dag @@ -193,10 +193,10 @@ data scope_disposition_rows: List = [ ScopeDispositionRow { touched: "docs/plans/example.md", expect: ExpectSkip }, ScopeDispositionRow { touched: "./docs/plans/example.md", expect: ExpectSkip }, ScopeDispositionRow { touched: "dag/gunbc/plans/example.dag", expect: ExpectWholeTree }, - ScopeDispositionRow { touched: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag", expect: ExpectScopedContaining { required_entry: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag" } }, + ScopeDispositionRow { touched: "src/v2/test/fixture/walk_plan_stage/overlap_peer_a_test.dag", expect: ExpectScopedContaining { required_entry: "src/v2/test/fixture/walk_plan_stage/overlap_peer_a_test.dag" } }, ScopeDispositionRow { touched: "src/v1/stage0/src/cli_run.rs", expect: ExpectWholeTree }, ScopeDispositionRow { touched: ".github/workflows/ci.yml", expect: ExpectWholeTree }, - ScopeDispositionRow { touched: "src/v2/test/fixture/floor_skip/floor_disc_shared_helper.dag", expect: ExpectScopedContaining { required_entry: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag" } } + ScopeDispositionRow { touched: "src/v2/test/fixture/walk_plan_stage/overlap_coordination.dag", expect: ExpectScopedContaining { required_entry: "src/v2/test/fixture/walk_plan_stage/overlap_peer_a_test.dag" } } ] fn touched_path_disposition_matches_with_roster( @@ -238,15 +238,15 @@ fn touched_path_disposition_matches_with_roster( } data scope_disposition_witness_roster: List = [ - "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag", - "src/v2/test/fixture/floor_skip/floor_disc_data_witness_test.dag" + "src/v2/test/fixture/walk_plan_stage/overlap_peer_a_test.dag", + "src/v2/test/fixture/walk_plan_stage/cleanup_test.dag" ] data scope_disposition_witness_pool_roots: List = [ - "src/v2/test/fixture/floor_skip" + "src/v2/test/fixture/walk_plan_stage" ] -data scope_disposition_witness_roster_note: String = "Pinned fixture-grain roster AND pool for the disposition-row witness, not compile_clean_shard_entry_paths() over the live pool: each interpreted entry_affected_by_touched_paths call materializes whole-pool dependency facts as interpreter values, so live-pool rows cost ~100s and multi-GB under the Wet interpreter (measured 2026-07-16; OOM-kill class in the witness corpus and in capped dev containers). The fixture pool makes every walking row cheap while staying REAL: self-selection (node_precise_discriminator_test selects itself) and cross-file selection through a genuine import edge (touching floor_disc_shared_helper selects node_precise_discriminator_test, which imports it, and NOT floor_disc_data_witness_test — a strict-subset proof). Live-pool, live-roster selection is proven by execution on the host-realized floor fast path (entry_file_touched_via_import_closure — certified against v2.lens.module_graph by the module-grain receipt harness, exercised by floor_fast_plan_scopes_touched_dag_entry_via_import_closure and every non-docs PR floor run)." +data scope_disposition_witness_roster_note: String = "Pinned fixture-grain roster AND pool for the disposition-row witness, not compile_clean_shard_entry_paths() over the live pool: each interpreted entry_affected_by_touched_paths call materializes whole-pool dependency facts as interpreter values, so live-pool rows cost ~100s and multi-GB under the Wet interpreter (measured 2026-07-16; OOM-kill class in the witness corpus and in capped dev containers). The fixture pool makes every walking row cheap while staying REAL: self-selection (overlap_peer_a_test selects itself) and cross-file selection through a genuine import edge (touching overlap_coordination selects overlap_peer_a_test, which imports it, and NOT cleanup_test, which does not — a strict-subset proof). The specimens moved from test/fixture/floor_skip to test/fixture/walk_plan_stage on 2026-08-15 because the former fixture home was deleted with affected-set selection; the two properties the rows prove are unchanged, and the pair was chosen to preserve the strict-subset half rather than merely to compile. Live-pool, live-roster selection is proven by execution on the host-realized floor fast path (entry_file_touched_via_import_closure — certified against v2.lens.module_graph by the module-grain receipt harness, exercised by floor_fast_plan_scopes_touched_dag_entry_via_import_closure and every non-docs PR floor run)." fn touched_path_disposition_matches(row: ScopeDispositionRow) -> Bool { touched_path_disposition_matches_with_roster( diff --git a/dag/tools/emit_falsifier_yaml.dag b/dag/tools/emit_falsifier_yaml.dag deleted file mode 100644 index 4e3f08aa475..00000000000 --- a/dag/tools/emit_falsifier_yaml.dag +++ /dev/null @@ -1,17 +0,0 @@ -module tools.emit_falsifier_yaml - -import std.process { ProcessExit, ExitSuccess, exit_failure } -import extdeps.filesystem.filesystem_io { Filesystem } -import gunbc.falsifier_workflow { expected_falsifier_yml } -import gunbc.generated_artifact { FalsifierYamlArtifact, artifact_path } - -func main() -> ProcessExit { - let path = artifact_path(a: FalsifierYamlArtifact) - let content = expected_falsifier_yml() - let w = Filesystem.Write(path: path, content: content) - if w.success { - ExitSuccess - } else { - exit_failure(reason: concat(concat("write failed for ", path), concat(": ", w.error))) - } -} diff --git a/dag/tools/floor_skip_discovery_witness_transport.dag b/dag/tools/floor_skip_discovery_witness_transport.dag deleted file mode 100644 index 7ec3b7f4527..00000000000 --- a/dag/tools/floor_skip_discovery_witness_transport.dag +++ /dev/null @@ -1,12 +0,0 @@ -module tools.floor_skip_discovery_witness_transport - -import tools.host_prelude { run_witness_bin } -import std.logic { Bool } - -fn run_floor_skip_discovery_witness() -> Bool { - run_witness_bin( - var_name: "FLOOR_SKIP_DISCOVERY_WITNESS", - bin_name: "floor_skip_discovery_witness", - args: [] - ) -} diff --git a/docs/plans/ci-selection-vs-scheduling.md b/docs/plans/ci-selection-vs-scheduling.md deleted file mode 100644 index 5592e24c6a7..00000000000 --- a/docs/plans/ci-selection-vs-scheduling.md +++ /dev/null @@ -1,52 +0,0 @@ -# CI selection vs scheduling — the two orthogonal axes (§1/§4 seam) - -> The framing behind the §1 "floor runs the right things" bullets. DESIGN refs: §1 (safety — a wrong answer caught late is paid "at interest"), §2 (parallelization-by-realization, the `std/realization.dag` Schedule/Placement/Width arm), §4 (affected-set selection over the Node dep-graph), §6 (don't build machinery for near-zero residue). Authored from warm-lark-306's analysis (2026-06-21), §1-lead input by quick-ant-298. **Carriers are the authority** — this doc exists only to keep the ROADMAP bullets terse (no dual representation). - -## 0. The reject: "expensive → nightly" routes by the wrong axis - -The stood-down nightly lane (proud-deer's #5447, closed by operator decision 2026-06-21) routed tests to cadences by **cost**. That fuses two facts that must stay separate, and the fusion is **unsound**: it lets an *affected* test be dropped from the per-PR gate merely because it is slow — so a breaking change merges green and is caught hours later on the nightly run, the §1-safety harm paid "at interest". Cost is a *scheduling* fact; whether a test must gate *this* PR is a *selection* fact. Routing by the wrong axis is the design the operator said we were side-stepping. - -## 1. The two axes (they never cross) - -| | **SELECTION** (§4) | **SCHEDULING** (§1) | -| --- | --- | --- | -| Question | does this result depend on what I changed? | given the must-run set, when / where / how-wide? | -| Authority | the **affected set** — transitive closure of changed nodes over the dep graph | cost + hermeticity profile of each test | -| Derived from | a property of the **change** | a property of the **test's resources**, not the change | -| Discipline | sound, **fail-closed** — never skip an affected test | measured — cadence, placement, width | - -**The load-bearing rule: cost informs SCHEDULING, never SELECTION.** The answer to "the affected set is expensive" is *"run it faster"* (parallelize + cache — the §2 realization arm), never *"run it later"*. - -## 2. The three distinctions the bullets must preserve - -1. **Cost may inform scheduling, never selection** — the §1-safety violation, the whole reason #5447 was rejected. -2. **`#5427` run-all is the SOUND BASELINE** (a superset of the affected set, already fail-closed on selection). Affected-set is an **affordability refinement that *shrinks* it — not a correction**. #5427 is step 1, not superseded; affected-set is step 2 on top of it. -3. **Nightly = full-corpus selector-backstop + non-hermetic residue, NOT a slow-test dump** — and the backstop (a) is precisely what makes the step-2 shrink *safe*. - -## 3. Per-PR membership: sound baseline → minimal sound set - -- **Step 1 — the sound baseline:** run-all-unless-`#[ignore]`d-with-a-written-reason (#5427, fierce-hawk-540). A superset of the affected set; fail-closed on selection by construction (it never skips an affected test). The completeness lens — "no affected test unrun; no un-run test without a written reason" — gates this (the `#[ignore]` residue is the legit §6 unstructurable bit). -- **Step 2 — shrink to the affected set:** the **existing** `v2.lens.affected_set` (compile-time, structural over `Node`/`DependencyView`, git-diff edit locus, fail-closed, CI-enrolled) refines the baseline down to the minimal sound set. This is an **affordability** move *on top of* #5427's soundness, not a replacement for it. Membership stays bounded by **affectedness, not cost**: expensive-but-affected tests run per-PR, their cost absorbed by parallelize + cache. - -## 4. Off per-PR cadence: only two things (neither is "expensive") - -1. **Non-hermetic residue** — live-network / real-external-service captures that *cannot* gate deterministically regardless of cost. Routed by **determinism**, not expense. Small, irreducible. -2. **The full-corpus selector-backstop** — run *everything* on a slow cadence as soundness insurance that affected-set selection missed no dep edge. This **fail-closes the selector itself**, and is exactly the insurance that lets step 2 shrink the per-PR set safely. It is an audit of *all* tests, **not** a dumping ground for slow ones. - -The "expensive" category drains toward ~this residue as #5456 (opt-level=3, debug-amplification fix — restores Pop-A to per-PR) and #5450 (build-once for Pop-B) land. So lane machinery is **residue-gated, built only after measurement shows a genuine irreducible set** (§6 — no machinery for near-zero residue). The scheduled-workflow CI-gen (`gunbc ci` / `ci_spec`) is load-bearing — escalate before editing it. - -## 5. Why this unifies the §1 story - -Affected-set and parallelization-by-realization are the **same work from two ends**: selection shrinks **what** runs per-PR (to the affected set); realization shrinks **how long** it takes (width / placement / cache / Share). Together they make *"run the affected set per-PR, fast"* the default — which dissolves the need for a cost-based nightly dump entirely. The only residue is (1) non-hermetic and (2) the selector backstop — neither is "expensive"; both are about soundness / determinism. - -## 6. The seam, precisely - -§4 selection produces the must-run set; §1 scheduling runs **that** set affordably (parallelism / cache) and runs the **complement** on a backstop cadence. Selection decides *membership*; scheduling decides *cadence / placement / width*. Cost lives only on the scheduling side. - -## 7. 2026-07-04 — the run-all baseline stood down IN CI (opt-in inversion) - -Step 1's "sound baseline" stopped being a baseline the day the floor stopped *completing*: at ~1,551 discovered witnesses the composed pass hit the 90-minute job timeout on every run — maximum cost, **zero delivered signal**, and every merge effectively fail-open (a gate that always times out gates nothing). A run-all that never finishes is not a superset of the affected set; it is the empty set billed at full price. Operator decision: invert to **declared opt-in enrollment** — `CiSpec.witness_entries`, projected from `CommitWitnessClaim` rows on the `GithubActionsCiJob` surface of `commit_gate_roster`; an empty roster puts zero witness-corpus nodes in the floor plan. This is NOT the §0 cost-routed selection this doc rejects: no affected test is demoted by expense, because *no* witness currently gates by discovery — the inversion replaces an always-red-by-timeout gate with an honest, completing floor (gates + declared witnesses), and the discovery roster remains the local path (`claim_batch --roster-from-discovery`). The §3 ladder is unchanged as the *destination*: land affected-set selection + floor memoization, then re-enroll the corpus through the affected set and dissolve the opt-in roster (dissolve-on marker lives on `ci_witness_optin_inversion` in `gunbc.commit_workflow`). Found during the inversion: `resolve_floor_runner_context` had been failing on a comment block the v1 grammar cannot parse (`affected_set_floor_runner.dag`), so the affected-set skip silently fell back to full-corpus on every run — step 2 was dead in CI while the doc described it as CI-enrolled. - -## Dissolution trigger (DESIGN §6) - -Delete this doc when the per-PR gate is the affected set (step 2 landed on top of #5427's baseline), the nightly cadence is the full-corpus backstop + non-hermetic residue (no cost-based selector), and the completeness lens runs executably — at which point the carriers (the lens + the CI-gen spec) state the policy and this framing is redundant. diff --git a/src/v1/stage0/Cargo.toml b/src/v1/stage0/Cargo.toml index eb935a421d3..bb619fab99d 100644 --- a/src/v1/stage0/Cargo.toml +++ b/src/v1/stage0/Cargo.toml @@ -190,14 +190,6 @@ path = "src/bin/auth_declared_but_unwired_witness.rs" name = "bootstrap_witness" path = "src/bin/bootstrap_witness.rs" -# Host-physics floor witness for the affected-set floor skip/discovery mechanism -# (run_discovery_corpus_with_options node-precise skip semantics). Runtime host-effect -# behavior (git diff observation, multi-entry resolve, per-witness skip decisions), not -# pure logic, so a bare .dag test fn would be spec-without-execution (DESIGN §5). -[[bin]] -name = "floor_skip_discovery_witness" -path = "src/bin/floor_skip_discovery_witness.rs" - [[bin]] name = "p1_cohort_probe" path = "src/bin/p1_cohort_probe.rs" @@ -219,16 +211,6 @@ path = "src/bin/measure_worker_private_memory.rs" name = "regen_floor_skip_witness" path = "src/bin/regen_floor_skip_witness.rs" -# Affected-set selection-control skip witness. Declared explicitly for the same reason every -# other witness here is: edition-2021 autodiscovery WOULD find src/bin/*.rs (cargo metadata -# lists this target with or without this block, and CI's --bin build has been green -# throughout), but an undeclared target is invisible to a reader of the manifest and would -# vanish if autobins were ever turned off. Consistency with the roster above, not a fix -# (review 44778 read the omission as a build break; it was not). -[[bin]] -name = "selection_control_skip_witness" -path = "src/bin/selection_control_skip_witness.rs" - # Host-physics floor witness for the v1 interpreter recorded-fixture record -> # hermetic-replay -> fail-closed lifecycle (DESIGN §5 determinism). Drives the real # claim_batch binary with --record/--hermetic/--fixture-store + mutates fixtures on diff --git a/src/v1/stage0/src/bin/claim_executor.rs b/src/v1/stage0/src/bin/claim_executor.rs index a930237e8e8..8c620d65263 100644 --- a/src/v1/stage0/src/bin/claim_executor.rs +++ b/src/v1/stage0/src/bin/claim_executor.rs @@ -16,16 +16,14 @@ use v1_compiler::cli_run::{ enable_floor_compile_clean_lazy_install, heartbeat_feed_enter_batch, heartbeat_feed_entry_completed, heartbeat_feed_snapshot, install_floor_compile_clean_receipt, make_eval_context, project_witness_cost_receipt, record_resolution_divergence_phase, - render_selection_degradation_receipt_body, reset_resolution_divergence_phase_receipt, - resolution_divergence_parent_plan_capture_begin, + reset_resolution_divergence_phase_receipt, resolution_divergence_parent_plan_capture_begin, resolution_divergence_parent_plan_capture_finish, resolve_entry_graph, resolve_entry_graph_shared, run_claim, run_discovery_corpus_with_options, run_value, set_phase, top_n_slowest_witnesses, verify_floor_discovery_terminal_for_coordinator, BudgetKind, ClaimOutcome, DiscoveryCorpusOptions, DiscoverySummary, DiscoveryWidthPolicy, - DiscoveryWitnessOutcome, FloorDiscoveryConsumerRole, FloorPhase, HistogramData, - NodeFrontierSelectionMode, PhaseProfile, ResolutionDivergencePhase, - ResolutionDivergencePhaseState, SelectionDegradationSnapshot, TimingPercentiles, - WitnessRowCost, DEFAULT_SLOWEST_WITNESS_ATTRIBUTION_N, + DiscoveryWitnessOutcome, FloorDiscoveryConsumerRole, FloorPhase, HistogramData, PhaseProfile, + ResolutionDivergencePhase, ResolutionDivergencePhaseState, TimingPercentiles, WitnessRowCost, + DEFAULT_SLOWEST_WITNESS_ATTRIBUTION_N, }; use v1_compiler::memory_governor::{ binding_cap_cgroup_dir, binding_high_cgroup_dir, floor_budget_below_minimum_footprint, @@ -747,7 +745,6 @@ enum Runnable { scan_dirs: Vec, explicit_entries: Vec<(String, String)>, native_bundle_entries: Vec<(String, String)>, - node_frontier_selection: NodeFrontierSelectionMode, exclude_substrings: Vec, discovery_scope_dirs: Vec, execution_mode: ExecutionMode, @@ -759,7 +756,6 @@ enum Runnable { source_roots_digest: String, entries: Vec, scan_dirs: Vec, - node_frontier_selection: NodeFrontierSelectionMode, execution_authority: ScopedWitnessExecutionAuthority, profile: ParsedRunnableProfile, clamp: ResolvedFloorBatchClamp, @@ -1138,41 +1134,6 @@ fn runnable_from_value(value: &Value, ctx: &InterpContext) -> Result (Vec::new(), Vec::new()), }; - let node_frontier_selection = match ctx.field(fields, "node_frontier_selection") { - Some(Value::Variant { variant_name, .. }) => { - if ctx.sym_eq(*variant_name, "SelectionOff") { - NodeFrontierSelectionMode::Off - } else if ctx.sym_eq(*variant_name, "SelectionApplied") { - NodeFrontierSelectionMode::Applied - } else if ctx.sym_eq(*variant_name, "SelectionPredictOnly") { - NodeFrontierSelectionMode::PredictOnly - } else { - return Err(format!( - "RunnableDiscoveryBatch.node_frontier_selection: unknown \ - NodeFrontierSelection variant `{}`", - ctx.resolve(*variant_name) - )); - } - } - Some(other) => { - return Err(format!( - "RunnableDiscoveryBatch.node_frontier_selection must be a \ - NodeFrontierSelection variant, got {}", - other.type_label_public() - )) - } - // Absent is a REFUSAL, not a default: the former Bool defaulted to false - // when the field was missing — a fail-open where a stale plan silently - // ran without its declared selection semantics. - None => { - return Err( - "RunnableDiscoveryBatch.node_frontier_selection is absent — the \ - plan row must declare its selection mode (SelectionOff / \ - SelectionApplied / SelectionPredictOnly); no silent default" - .to_string(), - ) - } - }; let exclude_substrings = match ctx.field(fields, "exclude_substrings") { Some(v) => str_list_from_value(v, ctx)?, // Field absent means the plan author specified no exclusions — default is empty, @@ -1193,7 +1154,6 @@ fn runnable_from_value(value: &Value, ctx: &InterpContext) -> Result Result str_list_from_value(v, ctx)?, None => return Err("ScopedWitnessBatch missing field `scan_dirs`".to_string()), }; - let node_frontier_selection = match ctx.field(batch, "node_frontier_selection") { - Some(Value::Variant { variant_name, .. }) - if ctx.sym_eq(*variant_name, "SelectionOff") => NodeFrontierSelectionMode::Off, - Some(Value::Variant { variant_name, .. }) - if ctx.sym_eq(*variant_name, "SelectionApplied") => NodeFrontierSelectionMode::Applied, - Some(Value::Variant { variant_name, .. }) - if ctx.sym_eq(*variant_name, "SelectionPredictOnly") => NodeFrontierSelectionMode::PredictOnly, - Some(other) => { - return Err(format!( - "ScopedWitnessBatch.node_frontier_selection must be NodeFrontierSelection, got {}", - other.type_label_public() - )) - } - None => return Err("ScopedWitnessBatch missing field `node_frontier_selection`".to_string()), - }; let execution_authority = match ctx.field(batch, "execution_authority") { Some(Value::Variant { variant_name, .. }) if ctx.sym_eq(*variant_name, "InheritedWalkSourceRoots") => @@ -1426,7 +1371,6 @@ fn runnable_from_value(value: &Value, ctx: &InterpContext) -> Result, /// Discovery batch only: finalized selection-degradation facts for floor receipts. - selection_degradation: Option, /// Recorded at the reuse decision site for rostered obligation subjects only. /// Disposition is NEVER inferred from `resolve_nanos` alone — timing is cost evidence. resolve_realization: Option, @@ -2067,7 +2010,6 @@ fn pre_verdict_unverified_claim_result( expectation_refusal: Some(refusal), budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, } } @@ -2442,7 +2384,6 @@ enum BatchUnit { source_roots: Vec, scan_dirs: Vec, explicit_entries: Vec<(String, String)>, - node_frontier_selection: NodeFrontierSelectionMode, exclude_substrings: Vec, discovery_scope_dirs: Vec, execution_mode: ExecutionMode, @@ -2454,7 +2395,6 @@ enum BatchUnit { entries_with_kind: Vec, source_roots: Vec, scan_dirs: Vec, - node_frontier_selection: NodeFrontierSelectionMode, execution_authority: ScopedWitnessExecutionAuthority, execution_mode: ExecutionMode, spawns_host_compiler: bool, @@ -2516,7 +2456,6 @@ fn group_batch_units(batch: &[Runnable]) -> Vec { scan_dirs, explicit_entries, native_bundle_entries, - node_frontier_selection, exclude_substrings, discovery_scope_dirs, execution_mode, @@ -2527,7 +2466,6 @@ fn group_batch_units(batch: &[Runnable]) -> Vec { source_roots: source_roots.clone(), scan_dirs: scan_dirs.clone(), explicit_entries: explicit_entries.clone(), - node_frontier_selection: *node_frontier_selection, exclude_substrings: exclude_substrings.clone(), discovery_scope_dirs: discovery_scope_dirs.clone(), execution_mode: *execution_mode, @@ -2548,7 +2486,6 @@ fn group_batch_units(batch: &[Runnable]) -> Vec { source_roots_digest, entries, scan_dirs, - node_frontier_selection, execution_authority, profile, .. @@ -2558,7 +2495,6 @@ fn group_batch_units(batch: &[Runnable]) -> Vec { entries_with_kind: entries.clone(), source_roots: source_roots.clone(), scan_dirs: scan_dirs.clone(), - node_frontier_selection: *node_frontier_selection, execution_authority: *execution_authority, execution_mode: profile.execution_mode, spawns_host_compiler: profile.spawns_host_compiler, @@ -2627,7 +2563,6 @@ fn claim_result_for_outcome( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization, }, ClaimOutcome::Fail => { @@ -2658,7 +2593,6 @@ fn claim_result_for_outcome( expectation_refusal: None, budget_refusal: None, host_dependency_refusal, - selection_degradation: None, resolve_realization, } } @@ -2677,7 +2611,6 @@ fn claim_result_for_outcome( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization, }, ClaimOutcome::RuntimeError { message } => ClaimResult { @@ -2695,7 +2628,6 @@ fn claim_result_for_outcome( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization, }, ClaimOutcome::TimedOut { @@ -2731,7 +2663,6 @@ fn claim_result_for_outcome( kind, }), host_dependency_refusal: None, - selection_degradation: None, resolve_realization, }, } @@ -3091,7 +3022,6 @@ fn run_native_bundle_unit( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }; if execution_mode != ExecutionMode::Wet { @@ -3124,7 +3054,6 @@ fn run_native_bundle_unit( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: resolve_observation(), }; let ctx = make_eval_context(&graph, indices, ExecutionMode::Wet); @@ -3298,7 +3227,6 @@ fn run_native_bundle_unit( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: Some(ResolveRealizationObservation::ColdResolvePerformed { resolve_nanos, }), @@ -3341,7 +3269,6 @@ fn run_batch_unit( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }], BatchUnit::NativeBundle { @@ -3360,7 +3287,6 @@ fn run_batch_unit( source_roots: roots, scan_dirs, explicit_entries, - node_frontier_selection, exclude_substrings, discovery_scope_dirs, execution_mode, @@ -3385,7 +3311,6 @@ fn run_batch_unit( execution_authority_source_roots, scan_dirs, explicit_entries, - node_frontier_selection, exclude_substrings, discovery_scope_dirs, governor, @@ -3407,7 +3332,6 @@ fn run_batch_unit( entries_with_kind, source_roots: roots, scan_dirs, - node_frontier_selection, execution_authority, execution_mode, spawns_host_compiler, @@ -3423,7 +3347,6 @@ fn run_batch_unit( execution_authority_source_roots, scan_dirs, explicit_entries, - node_frontier_selection, Vec::new(), Vec::new(), governor, @@ -3500,7 +3423,6 @@ fn run_shared_entry_claims( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }) .collect(); @@ -3590,7 +3512,6 @@ fn run_memo_shared_claims( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }) .collect(); @@ -4180,11 +4101,7 @@ fn scoped_witness_summary_outcome( ), }); } - summary - .selection_skipped_rows - .iter() - .find(|row| row.entry == entry && row.function == function) - .map(|row| ("selection-skipped", row.provenance.clone())) + None } fn append_scoped_witness_receipt_rows( @@ -4245,7 +4162,6 @@ fn discovery_claim_result( function: String, ok: bool, detail: String, - selection: NodeFrontierSelectionMode, summary: &DiscoverySummary, projected: Result, String>, expectation_refusal: Option, @@ -4254,45 +4170,23 @@ fn discovery_claim_result( // incomplete row set must refuse the discovery claim (typed/located), never silently // emit a partial receipt as complete (§5 / review 43261 + review 43274). match projected { - Ok(mut witness_row_costs) => { - for row in &summary.selection_skipped_rows { - // Zeros here are placeholders the writer never renders: the row's own - // `selection-skipped` outcome routes every timing cell to UNMEASURED. The - // CPU slot is `None` for the stronger reason that it is not a placeholder - // at all — an unexecuted row has no clock reading of any kind, and the type - // now says so rather than leaving a zero to be believed. - witness_row_costs.push(WitnessRowCost { - entry: row.entry.clone(), - function: row.function.clone(), - eval_wall_nanos: 0, - eval_cpu_nanos: None, - resolve_nanos: 0, - warm_nanos: 0, - outcome: "selection-skipped".to_string(), - detail: row.provenance.clone(), - }); - } - ClaimResult { - function, - entry: DISCOVERY_AGGREGATE_ENTRY.to_string(), - ok, - detail, - wall_nanos: 0, - resolve_nanos: 0, - corpus_resolve_nanos: summary.total_resolve_nanos, - corpus_eval_nanos: summary.total_measured_nanos, - corpus_witnesses: summary.total, - runtime_unit_count: discovery_runtime_unit_count_from_summary(summary.total), - witness_row_costs, - expectation_refusal, - budget_refusal: discovery_budget_refusal(summary), - host_dependency_refusal: discovery_host_dependency_refusal(summary), - selection_degradation: Some(SelectionDegradationSnapshot::from_summary( - selection, summary, - )), - resolve_realization: None, - } - } + Ok(witness_row_costs) => ClaimResult { + function, + entry: DISCOVERY_AGGREGATE_ENTRY.to_string(), + ok, + detail, + wall_nanos: 0, + resolve_nanos: 0, + corpus_resolve_nanos: summary.total_resolve_nanos, + corpus_eval_nanos: summary.total_measured_nanos, + corpus_witnesses: summary.total, + runtime_unit_count: discovery_runtime_unit_count_from_summary(summary.total), + witness_row_costs, + expectation_refusal, + budget_refusal: discovery_budget_refusal(summary), + host_dependency_refusal: discovery_host_dependency_refusal(summary), + resolve_realization: None, + }, Err(msg) => { eprintln!("[witness-row-cost] refused: {msg}"); // Preserve the caller's failure context (e.g. "N of M discovery witness(es) @@ -4323,9 +4217,6 @@ fn discovery_claim_result( expectation_refusal, budget_refusal: discovery_budget_refusal(summary), host_dependency_refusal: discovery_host_dependency_refusal(summary), - selection_degradation: Some(SelectionDegradationSnapshot::from_summary( - selection, summary, - )), resolve_realization: None, } } @@ -4357,7 +4248,6 @@ fn run_discovery_batch_node( execution_authority_source_roots: Vec, scan_dirs: Vec, explicit_entries: Vec<(String, String)>, - node_frontier_selection: NodeFrontierSelectionMode, exclude_substrings: Vec, discovery_scope_dirs: Vec, governor: Arc, @@ -4400,7 +4290,6 @@ fn run_discovery_batch_node( execution_mode, DiscoveryWidthPolicy::Adaptive(governor), DiscoveryCorpusOptions { - node_frontier_selection, execution_authority_source_roots, explicit_roster_only: false, exclude_substrings, @@ -4436,10 +4325,6 @@ fn run_discovery_batch_node( expectation_refusal: None, budget_refusal: discovery_budget_refusal(&summary), host_dependency_refusal: discovery_host_dependency_refusal(&summary), - selection_degradation: Some(SelectionDegradationSnapshot::from_summary( - node_frontier_selection, - &summary, - )), resolve_realization: None, }; } @@ -4570,7 +4455,6 @@ fn run_discovery_batch_node( label, false, refusal.detail(), - node_frontier_selection, &summary, projected, Some(refusal), @@ -4579,7 +4463,6 @@ fn run_discovery_batch_node( format!("{label} ({} witnesses)", summary.total), true, String::new(), - node_frontier_selection, &summary, projected, None, @@ -4612,10 +4495,6 @@ fn run_discovery_batch_node( expectation_refusal: None, budget_refusal: discovery_budget_refusal(&summary), host_dependency_refusal: discovery_host_dependency_refusal(&summary), - selection_degradation: Some(SelectionDegradationSnapshot::from_summary( - node_frontier_selection, - &summary, - )), resolve_realization: None, }; } @@ -4643,7 +4522,6 @@ fn run_discovery_batch_node( label, false, refusal.detail(), - node_frontier_selection, &summary, projected, Some(refusal), @@ -4660,7 +4538,6 @@ fn run_discovery_batch_node( format!("{label} (expect_red still-red OK)"), true, String::new(), - node_frontier_selection, &summary, projected, None, @@ -4682,7 +4559,6 @@ fn run_discovery_batch_node( }, summary.failures.join("; ") ), - node_frontier_selection, &summary, projected, None, @@ -4747,7 +4623,6 @@ fn run_discovery_batch_node( expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, } } @@ -5345,56 +5220,10 @@ struct BatchRecord { /// receipt keys on (`gunbc.floor_component_receipt` role note): the affected-set /// cold control is the `predict_only` component, never "batch 1" — indices shift /// when a `gunbc_falsifier_batches` enrollment flag flips. - selection_tag: &'static str, /// Wet-profiled batches (bin_witness wet corpus, falsifier wet follow-on, …). is_wet: bool, } -/// Materialization-ladder receipt: how many entry resolves this floor run actually -/// paid (walk_memo hits charge resolve_nanos == 0 and are excluded — this counts the -/// duplicated work across DISTINCT entries, the cross-entry share the memo cannot do). -/// Discovery corpus resolve time is reported on its own key, never folded into the -/// entry count (different grain; conflating them would mask either regression). -/// Consumed by the ci.yml resolve-receipt gate emitted from dag/gunbc/ci_materialization.dag. -/// Returns false on a write error — the walk fails closed at the point of -/// failure rather than relying only on the downstream missing-file gate. -/// The batch's node-frontier selection role, as the tag vocabulary -/// `gunbc.floor_component_receipt.floor_component_selection_of_tag` admits. -/// Two or more DISTINCT selections in one batch returns `"ambiguous"`, which that -/// function refuses — the role would not identify a unique component, and a silently -/// picked first one is exactly the kind of guess the receipt exists to remove. -fn batch_selection_tag(batch: &[Runnable]) -> &'static str { - let mut seen: Vec<&'static str> = Vec::new(); - for r in batch { - let selection = match r { - Runnable::DiscoveryBatch { - node_frontier_selection, - .. - } - | Runnable::ScopedWitnessBatch { - node_frontier_selection, - .. - } => Some(node_frontier_selection), - Runnable::SingleClaim { .. } => None, - }; - if let Some(node_frontier_selection) = selection { - let tag = match node_frontier_selection { - NodeFrontierSelectionMode::Off => "off", - NodeFrontierSelectionMode::Applied => "applied", - NodeFrontierSelectionMode::PredictOnly => "predict_only", - }; - if !seen.contains(&tag) { - seen.push(tag); - } - } - } - match seen.len() { - 0 => "off", - 1 => seen[0], - _ => "ambiguous", - } -} - /// One batch's failure MODE and detail — the seed's existing `falsifier_failure_mode` /// vocabulary verbatim, with `"none"` for a clean batch. This function deliberately /// makes NO judgment: the mode-to-`ObservationOutcome` mapping lives in @@ -5578,7 +5407,6 @@ fn write_floor_component_receipt_at( &run_id, rec.batch_index as i64 + 1, &rec.label, - rec.selection_tag, batch_witness_count(rec) as i64, failure_mode, &detail, @@ -5591,33 +5419,27 @@ fn write_floor_component_receipt_at( // Batches the stop policy never reached are Skipped with their cause — a named // state, never an absent row the alert would have to guess about. // - // They carry their PLANNED identity, not a placeholder. `batch_heartbeat_label` and - // `batch_selection_tag` are pure functions of `batches[bi]`, so the roster identity of - // an unreached component is fully available here; the earlier version discarded it and - // wrote a literal "not reached" / "off" pair. That made the receipt complete by COUNT - // and anonymous by IDENTITY for exactly the components that did not run — the shape - // DESIGN §5 rules out ("Completeness is an identity join, not a count equality"). + // They carry their PLANNED identity, not a placeholder. `batch_heartbeat_label` is a pure + // function of `batches[bi]`, so the roster identity of an unreached component is fully + // available here; an earlier version discarded it and wrote a literal "not reached". That + // made the receipt complete by COUNT and anonymous by IDENTITY for exactly the components + // that did not run -- the shape DESIGN section 5 rules out ("Completeness is an identity + // join, not a count equality"). // - // The erased `selection_tag` was the load-bearing half. The affected-set cold control is - // identified by the property that DEFINES it — `predict_only` - // (`gunbc.floor_component_receipt` role note) — so padding it as "off" deleted the cold - // control from its own receipt: `floor_affected_set_control_state` then returned - // `ControlAbsent`, which cannot distinguish "the control was never enrolled" from "the - // control was enrolled and an earlier batch stopped the line before it ran". Two states, - // two different remedies, one output — a state-space conflation in the receipt whose - // whole purpose is to keep component states distinct. With the planned tag carried, that - // run instead yields `ControlConcluded` with a `Skipped` outcome, and the alert reports - // the control RED with its real cause. + // A second erased field, the per-component selection tag, used to be the load-bearing half + // of this argument: padding the affected-set cold control's `predict_only` tag as "off" + // deleted that control from its own receipt. Both the tag and the control are gone with + // affected-set selection (2026-08-15), so the label is now the whole identity -- which + // makes carrying it accurately the only thing standing between an unreached component and + // anonymity. for bi in batch_records.len()..total_batches { let label = batch_heartbeat_label(&batches[bi]); - let selection_tag = batch_selection_tag(&batches[bi]); let row = if unreached == UnreachedCause::RunIncomplete { floor_component_row_not_concluded_value( &ctx, &run_id, bi as i64 + 1, &label, - selection_tag, unreached.failure_mode(), unreached.detail(), ) @@ -5627,7 +5449,6 @@ fn write_floor_component_receipt_at( &run_id, bi as i64 + 1, &label, - selection_tag, 0, unreached.failure_mode(), unreached.detail(), @@ -5707,7 +5528,6 @@ fn floor_component_row_value( run_id: &str, index: i64, label: &str, - selection_tag: &str, witnesses: i64, failure_mode: &str, detail: &str, @@ -5738,10 +5558,6 @@ fn floor_component_row_value( (Some("run_id".to_string()), Value::Str(run_id.to_string())), (Some("index".to_string()), Value::Int(index)), (Some("label".to_string()), Value::Str(label.to_string())), - ( - Some("selection_tag".to_string()), - Value::Str(selection_tag.to_string()), - ), (Some("witnesses".to_string()), Value::Int(witnesses)), ( Some("failure_mode".to_string()), @@ -5770,8 +5586,7 @@ fn floor_component_row_value( Ok(Value::Null) => { eprintln!( "claim_executor: floor component receipt REFUSED — {constructor} returned \ - absent for batch {index}: selection_tag={selection_tag:?} \ - failure_mode={failure_mode:?} are outside the .dag vocabulary" + absent for batch {index}: failure_mode={failure_mode:?} are outside the .dag vocabulary" ); None } @@ -5795,7 +5610,6 @@ fn floor_component_row_not_concluded_value( run_id: &str, index: i64, label: &str, - selection_tag: &str, failure_mode: &str, detail: &str, ) -> Option { @@ -5804,10 +5618,6 @@ fn floor_component_row_not_concluded_value( (Some("run_id".to_string()), Value::Str(run_id.to_string())), (Some("index".to_string()), Value::Int(index)), (Some("label".to_string()), Value::Str(label.to_string())), - ( - Some("selection_tag".to_string()), - Value::Str(selection_tag.to_string()), - ), ( Some("failure_mode".to_string()), Value::Str(failure_mode.to_string()), @@ -5834,8 +5644,7 @@ fn floor_component_row_not_concluded_value( Ok(Value::Null) => { eprintln!( "claim_executor: floor component receipt REFUSED — {constructor} returned \ - absent for batch {index}: selection_tag={selection_tag:?} \ - failure_mode={failure_mode:?} are outside the .dag vocabulary" + absent for batch {index}: failure_mode={failure_mode:?} are outside the .dag vocabulary" ); None } @@ -5862,11 +5671,10 @@ fn write_floor_component_receipt_document( batch_records: &[BatchRecord], ) -> Option { let rows_list = Value::List(Rc::new(rows.into())); - let snapshot = selection_degradation_from_batch_records(batch_records); if unreached == UnreachedCause::RunIncomplete { let concluded_count = batch_records.len() as i64; let pending_from_index = (batch_records.len() + 1) as i64; - let mut args: Vec<(Option, Value)> = vec![ + let args: Vec<(Option, Value)> = vec![ ( Some("workflow_name".to_string()), Value::Str(workflow_name.to_string()), @@ -5890,33 +5698,7 @@ fn write_floor_component_receipt_document( Value::Int(pending_from_index), ), ]; - let constructor = if let Some(snapshot) = snapshot { - args.extend([ - ( - Some("selection_mode_tag".to_string()), - Value::Str(snapshot.selection_mode_tag.clone()), - ), - ( - Some("selected".to_string()), - Value::Int(snapshot.selected_entry_groups as i64), - ), - ( - Some("total".to_string()), - Value::Int(snapshot.total_entry_groups as i64), - ), - ( - Some("categorization_unavailable".to_string()), - Value::Bool(snapshot.categorization_unavailable), - ), - ( - Some("categorization_reason".to_string()), - Value::Str(snapshot.categorization_reason.clone()), - ), - ]); - "floor_component_receipt_document_incomplete_with_selection" - } else { - "floor_component_receipt_document_incomplete" - }; + let constructor = "floor_component_receipt_document_incomplete"; match run_in_context_with_args(ctx, constructor, &args, false) { Ok(Value::Str(s)) => Some(s), Ok(other) => { @@ -5933,60 +5715,6 @@ fn write_floor_component_receipt_document( None } } - } else if let Some(snapshot) = snapshot { - match run_in_context_with_args( - ctx, - "floor_component_receipt_document_with_selection", - &[ - ( - Some("workflow_name".to_string()), - Value::Str(workflow_name.to_string()), - ), - (Some("run_id".to_string()), Value::Str(run_id.to_string())), - ( - Some("head_sha".to_string()), - Value::Str(head_sha.to_string()), - ), - (Some("rows".to_string()), rows_list), - ( - Some("selection_mode_tag".to_string()), - Value::Str(snapshot.selection_mode_tag.clone()), - ), - ( - Some("selected".to_string()), - Value::Int(snapshot.selected_entry_groups as i64), - ), - ( - Some("total".to_string()), - Value::Int(snapshot.total_entry_groups as i64), - ), - ( - Some("categorization_unavailable".to_string()), - Value::Bool(snapshot.categorization_unavailable), - ), - ( - Some("categorization_reason".to_string()), - Value::Str(snapshot.categorization_reason.clone()), - ), - ], - false, - ) { - Ok(Value::Str(s)) => Some(s), - Ok(other) => { - eprintln!( - "claim_executor: floor component receipt REFUSED — \ - floor_component_receipt_document_with_selection returned {other:?}, not Str" - ); - None - } - Err(e) => { - eprintln!( - "claim_executor: floor component receipt REFUSED — \ - floor_component_receipt_document_with_selection eval: {e}" - ); - None - } - } } else { match run_in_context_with_args( ctx, @@ -7077,47 +6805,6 @@ fn write_on_success_receipt( true } -fn selection_degradation_from_batch_records( - batch_records: &[BatchRecord], -) -> Option { - batch_records - .iter() - .flat_map(|rec| &rec.results) - .find_map(|result| result.selection_degradation.clone()) -} - -fn write_selection_degradation_receipt_at( - base: &std::path::Path, - source_roots: &[String], - batch_records: &[BatchRecord], -) -> bool { - let Some(snapshot) = selection_degradation_from_batch_records(batch_records) else { - return true; - }; - let body = match render_selection_degradation_receipt_body(source_roots, &snapshot) { - Ok(body) => body, - Err(msg) => { - eprintln!("claim_executor: {msg}"); - return false; - } - }; - let path = base.join("floor-selection-degradation-receipt.txt"); - if let Err(e) = std::fs::create_dir_all(base).and_then(|_| std::fs::write(&path, &body)) { - eprintln!( - "claim_executor: failed to write selection degradation receipt {}: {e} — walk fails closed", - path.display() - ); - return false; - } - eprintln!( - "[receipt] floor selection degradation: {} entry group(s) selected of {} (receipt: {})", - snapshot.selected_entry_groups, - snapshot.total_entry_groups, - path.display() - ); - true -} - /// Receipt line derived from transported obligations joined to observed realizations. #[derive(Debug, Clone, PartialEq, Eq)] struct ResolveObligationLine { @@ -7337,7 +7024,7 @@ fn append_resolve_obligation_receipt_body( fn write_resolve_receipt_at( base: &std::path::Path, - source_roots: &[String], + _source_roots: &[String], batch_records: &[BatchRecord], floor_finalization: Option<&FloorFinalization>, ) -> bool { @@ -7365,19 +7052,6 @@ fn write_resolve_receipt_at( return false; } } - if let Some(snapshot) = selection_degradation_from_batch_records(batch_records) { - match render_selection_degradation_receipt_body(source_roots, &snapshot) { - Ok(selection_body) => { - body.push_str("\n[selection_degradation]\n"); - body.push_str(&selection_body); - body.push('\n'); - } - Err(msg) => { - eprintln!("claim_executor: resolve receipt selection degradation refused: {msg}"); - return false; - } - } - } let path = base.join("floor-resolve-receipt.txt"); if let Err(e) = std::fs::create_dir_all(base).and_then(|_| std::fs::write(&path, &body)) { eprintln!( @@ -8841,7 +8515,6 @@ fn run_walk( runtime_units: batch_runtime_units, results: batch_results, label: label.clone(), - selection_tag: batch_selection_tag(batch), is_wet: batch_is_wet(batch), }); // CHECKPOINT. The receipt used to be written once, after every batch, so the one @@ -8924,14 +8597,6 @@ fn run_walk( let resolve_receipt_ok = !emit_ordinary_floor_receipts || write_resolve_receipt(source_roots, &batch_records, floor_finalization); trace_floor_phase("resolve-receipt", "completed", ""); - trace_floor_phase("selection-degradation-receipt", "started", ""); - let selection_degradation_receipt_ok = !emit_ordinary_floor_receipts - || write_selection_degradation_receipt_at( - std::path::Path::new("target"), - source_roots, - &batch_records, - ); - trace_floor_phase("selection-degradation-receipt", "completed", ""); trace_floor_phase("batch-wall-receipt", "started", ""); let batch_wall_receipt_ok = !emit_ordinary_floor_receipts || write_batch_wall_receipt(&batch_records); @@ -9016,7 +8681,6 @@ fn run_walk( || !wet_witness_row_outcome_receipt_ok || !witness_row_cost_drift_receipt_ok || !witness_row_cost_migration_disclosure_receipt_ok - || !selection_degradation_receipt_ok || !floor_component_receipt_ok || !materialization_receipt_ok; push_ordinary_receipt_write_refusals( @@ -9028,7 +8692,6 @@ fn run_walk( wet_witness_row_outcome_receipt_ok, witness_row_cost_drift_receipt_ok, witness_row_cost_migration_disclosure_receipt_ok, - selection_degradation_receipt_ok, floor_component_receipt_ok, materialization_receipt_ok, ); @@ -9488,7 +9151,6 @@ fn run_perturb_check( scan_dirs, explicit_entries, native_bundle_entries, - node_frontier_selection, exclude_substrings, discovery_scope_dirs, execution_mode, @@ -9498,7 +9160,6 @@ fn run_perturb_check( scan_dirs: scan_dirs.iter().map(|d| remap_root(d)).collect(), explicit_entries: explicit_entries.clone(), native_bundle_entries: native_bundle_entries.clone(), - node_frontier_selection: *node_frontier_selection, exclude_substrings: exclude_substrings.clone(), discovery_scope_dirs: discovery_scope_dirs.clone(), execution_mode: *execution_mode, @@ -9510,7 +9171,6 @@ fn run_perturb_check( source_roots_digest, entries, scan_dirs, - node_frontier_selection, execution_authority, profile, clamp, @@ -9530,7 +9190,6 @@ fn run_perturb_check( }) .collect(), scan_dirs: scan_dirs.iter().map(|d| remap_root(d)).collect(), - node_frontier_selection: *node_frontier_selection, execution_authority: *execution_authority, profile: *profile, clamp: clamp.clone(), @@ -10386,7 +10045,6 @@ struct ScopedExecutionRequest { source_roots_digest: String, entries: Vec, scan_dirs: Vec, - node_frontier_selection: NodeFrontierSelectionMode, execution_authority: ScopedWitnessExecutionAuthority, profile: ParsedRunnableProfile, clamp: ResolvedFloorBatchClamp, @@ -10410,7 +10068,6 @@ impl ScopedExecutionRequest { source_roots_digest: self.source_roots_digest.clone(), entries: self.entries.clone(), scan_dirs: self.scan_dirs.clone(), - node_frontier_selection: self.node_frontier_selection, execution_authority: self.execution_authority, profile: self.profile, clamp: self.clamp.clone(), @@ -10435,7 +10092,6 @@ fn scoped_execution_requests_from_rows( source_roots_digest, entries, scan_dirs, - node_frontier_selection, execution_authority, profile, clamp, @@ -10453,7 +10109,6 @@ fn scoped_execution_requests_from_rows( source_roots_digest: source_roots_digest.clone(), entries: entries.clone(), scan_dirs: scan_dirs.clone(), - node_frontier_selection: *node_frontier_selection, execution_authority: *execution_authority, profile: *profile, clamp: clamp.clone(), @@ -11698,7 +11353,6 @@ fn push_ordinary_receipt_write_refusals( wet_witness_row_outcome_receipt_ok: bool, witness_row_cost_drift_receipt_ok: bool, witness_row_cost_migration_disclosure_receipt_ok: bool, - selection_degradation_receipt_ok: bool, floor_component_receipt_ok: bool, materialization_receipt_ok: bool, ) { @@ -11735,10 +11389,6 @@ fn push_ordinary_receipt_write_refusals( witness_row_cost_migration_disclosure_receipt_ok, "ordinary-floor witness row-cost migration disclosure receipt write refused", ); - push( - selection_degradation_receipt_ok, - "ordinary-floor selection degradation receipt write refused", - ); push( floor_component_receipt_ok, "ordinary-floor floor component receipt write refused", @@ -12071,7 +11721,6 @@ mod tests { unit_count: 0, runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, label: "finalization-fixture".to_string(), - selection_tag: "fixture", is_wet: false, results: resolve_counts .iter() @@ -12090,7 +11739,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }) .collect(), @@ -12283,7 +11931,6 @@ mod tests { unit_count: 0, runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, label: "obligation-fixture".to_string(), - selection_tag: "fixture", is_wet: false, results: vec![ ClaimResult { @@ -12301,7 +11948,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: resolve_observation_for_nanos(anchor_nanos), }, ClaimResult { @@ -12321,7 +11967,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: resolve_observation_for_nanos(native_nanos), }, ], @@ -12351,7 +11996,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }); let refusals = validate_floor_finalization(&fin, TEST_PLAN_SITE, &records, false); @@ -12374,7 +12018,6 @@ mod tests { unit_count: 0, runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, label: "emit-only".to_string(), - selection_tag: "fixture", is_wet: false, results: vec![ClaimResult { function: "emit_host_gate_passes".to_string(), @@ -12391,7 +12034,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }], }]; @@ -12429,7 +12071,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }); let refusals = validate_floor_finalization(&fin, TEST_PLAN_SITE, &records, false); @@ -12460,7 +12101,6 @@ mod tests { unit_count: 0, runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, label: "cheap-gates".to_string(), - selection_tag: "fixture", is_wet: false, results: vec![ClaimResult { function: "cheap_claim_pool_gate_passes".to_string(), @@ -12477,7 +12117,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: Some( ResolveRealizationObservation::ColdResolvePerformed { resolve_nanos: 9 }, ), @@ -12490,7 +12129,6 @@ mod tests { unit_count: 0, runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, label: "compile-anchor".to_string(), - selection_tag: "fixture", is_wet: false, results: vec![ClaimResult { function: "dag_compile_clean_gate_passes".to_string(), @@ -12507,7 +12145,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: Some( ResolveRealizationObservation::SatisfiedFromSharedPool { computation_identity: format!("entry-closure:{anchor_entry}:Hermetic"), @@ -12523,7 +12160,6 @@ mod tests { unit_count: 0, runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, label: "native-bundle".to_string(), - selection_tag: "fixture", is_wet: false, results: vec![ClaimResult { function: "native_selected_logic_production_spec".to_string(), @@ -12542,7 +12178,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: resolve_observation_for_nanos(3), }], }, @@ -12573,7 +12208,6 @@ mod tests { unit_count: 0, runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, label: "memo-regression".to_string(), - selection_tag: "fixture", is_wet: false, results: vec![ ClaimResult { @@ -12591,7 +12225,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: Some( ResolveRealizationObservation::ColdResolvePerformed { resolve_nanos: 9 }, ), @@ -12611,7 +12244,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: Some( ResolveRealizationObservation::ColdResolvePerformed { resolve_nanos: 7 }, ), @@ -13220,7 +12852,6 @@ mod tests { expectation_refusal: refusal, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, } } @@ -13840,7 +13471,6 @@ mod tests { runtime_units: FloorRuntimeUnitCount::Observed { units: unit_count }, results, label: "batch-under-test".to_string(), - selection_tag: "off", is_wet: false, } } @@ -13873,7 +13503,6 @@ mod tests { kind: BudgetKind::Wall, }), host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }; // Sanity: the string classifier alone really would misclassify this detail. @@ -13903,7 +13532,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }; let (mode, _) = batch_failure_mode_and_detail(&batch_record_for_test(vec![plain])); @@ -13934,7 +13562,6 @@ mod tests { tool: "npm".to_string(), hint: "apt install npm".to_string(), }), - selection_degradation: None, resolve_realization: None, }; assert_eq!( @@ -14221,7 +13848,6 @@ mod tests { scan_dirs: vec!["dag/test/claim".to_string()], explicit_entries: Vec::new(), native_bundle_entries: Vec::new(), - node_frontier_selection: NodeFrontierSelectionMode::PredictOnly, exclude_substrings: Vec::new(), discovery_scope_dirs: Vec::new(), execution_mode: ExecutionMode::Hermetic, @@ -14238,7 +13864,6 @@ mod tests { runtime_units: FloorRuntimeUnitCount::Observed { units: 1 }, results: Vec::new(), label: batch_heartbeat_label(&batches[0]), - selection_tag: batch_selection_tag(&batches[0]), is_wet: false, }]; @@ -14298,7 +13923,6 @@ mod tests { budget_refusal: None, host_dependency_refusal: None, expectation_refusal: None, - selection_degradation: None, resolve_realization: None, }; let units = aggregate_batch_runtime_units(&[discovery_fail]); @@ -14322,7 +13946,6 @@ mod tests { budget_refusal: None, host_dependency_refusal: None, expectation_refusal: None, - selection_degradation: None, resolve_realization: None, }; assert_eq!( @@ -14358,7 +13981,6 @@ mod tests { runtime_units: runtime_unit_count_unavailable("discovery corpus failed: test"), results: Vec::new(), label: "discovery-corpus".to_string(), - selection_tag: "applied", is_wet: false, }]; assert!(write_batch_wall_receipt_at(&base, &records)); @@ -14419,7 +14041,6 @@ mod tests { unit_count: 1, results: Vec::new(), label: batch_heartbeat_label(&batches[0]), - selection_tag: batch_selection_tag(&batches[0]), is_wet: false, }]; @@ -14500,7 +14121,6 @@ mod tests { runtime_units: FloorRuntimeUnitCount::Observed { units: 3 }, results: Vec::new(), label: "batch-0".to_string(), - selection_tag: "off", is_wet: false, }, BatchRecord { @@ -14511,7 +14131,6 @@ mod tests { runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, results: Vec::new(), label: "batch-1".to_string(), - selection_tag: "off", is_wet: false, }, ]; @@ -14532,7 +14151,6 @@ mod tests { runtime_units: FloorRuntimeUnitCount::Observed { units: 0 }, results: Vec::new(), label: "batch-0".to_string(), - selection_tag: "off", is_wet: false, }]; assert!(write_batch_wall_receipt_at(&base, &unbudgeted_records)); @@ -15719,7 +15337,6 @@ mod tests { scan_dirs: vec!["dag/test/claim".to_string()], explicit_entries: vec![], native_bundle_entries: vec![], - node_frontier_selection: NodeFrontierSelectionMode::Applied, exclude_substrings: vec![], discovery_scope_dirs: vec![], execution_mode: ExecutionMode::Hermetic, @@ -15786,7 +15403,6 @@ mod tests { scan_dirs: vec![], explicit_entries: vec![], native_bundle_entries: vec![("bundle.dag".to_string(), "bundle_spec".to_string())], - node_frontier_selection: NodeFrontierSelectionMode::Applied, exclude_substrings: vec![], discovery_scope_dirs: vec![], execution_mode: ExecutionMode::Wet, @@ -16564,7 +16180,6 @@ mod tests { unit_count: 3, runtime_units: FloorRuntimeUnitCount::Observed { units: 3 }, label: "bin-witness-corpus".to_string(), - selection_tag: "applied", is_wet: true, results: vec![ClaimResult { function: "bin-witness-corpus (3 witnesses)".to_string(), @@ -16613,7 +16228,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }], }]; @@ -16662,7 +16276,6 @@ mod tests { unit_count: 2, runtime_units: FloorRuntimeUnitCount::Observed { units: 2 }, label: "collision".to_string(), - selection_tag: "applied", is_wet: false, results: vec![ClaimResult { function: "discovery-corpus".to_string(), @@ -16715,7 +16328,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, }], }] @@ -17006,7 +16618,6 @@ mod tests { "discovery-corpus".into(), false, killed_detail.to_string(), - NodeFrontierSelectionMode::Applied, &summary_with(killed.clone()), projected, None, @@ -17024,7 +16635,6 @@ mod tests { "discovery-corpus".into(), false, "red".into(), - NodeFrontierSelectionMode::Applied, &summary_with(ClaimOutcome::Fail), Ok(Vec::new()), None, @@ -17089,7 +16699,6 @@ mod tests { "discovery-corpus".into(), false, aggregate_detail.clone(), - NodeFrontierSelectionMode::Applied, &summary_with(ClaimOutcome::Fail, vec![failure.clone()]), projected, None, @@ -17106,7 +16715,6 @@ mod tests { "discovery-corpus".into(), false, "red".into(), - NodeFrontierSelectionMode::Applied, &summary_with(ClaimOutcome::Fail, vec!["returned Bool(false)".into()]), Ok(Vec::new()), None, @@ -17154,7 +16762,6 @@ mod tests { "probe".into(), false, prior.to_string(), - NodeFrontierSelectionMode::Applied, &summary, Err("[witness-row-cost] REFUSED: missing measured resolve parent for e.dag".into()), None, @@ -17231,7 +16838,6 @@ mod tests { expectation_refusal: None, budget_refusal: None, host_dependency_refusal: None, - selection_degradation: None, resolve_realization: None, } } @@ -17648,7 +17254,6 @@ mod scoped_execution_request_tests { source_roots_digest: "digest".to_string(), entries, scan_dirs: Vec::new(), - node_frontier_selection: NodeFrontierSelectionMode::Applied, execution_authority: ScopedWitnessExecutionAuthority::InheritedWalkSourceRoots, profile: ParsedRunnableProfile { provenance: ParsedProfileProvenance::Declared, diff --git a/src/v1/stage0/src/bin/floor_skip_discovery_witness.rs b/src/v1/stage0/src/bin/floor_skip_discovery_witness.rs deleted file mode 100644 index c146e0897c0..00000000000 --- a/src/v1/stage0/src/bin/floor_skip_discovery_witness.rs +++ /dev/null @@ -1,751 +0,0 @@ -#![allow(clippy::disallowed_macros)] - -use std::path::PathBuf; -use std::process::ExitCode; - -use v1_compiler::cli_run::{ - build_multi_entry_index, resolve_entry_graph_shared, resolve_entry_with_index, - run_discovery_corpus_with_options, workspace_root, DiscoveryCorpusOptions, DiscoverySummary, - DiscoveryWidthPolicy, NodeFrontierSelectionMode, SELECTION_CONTROL_BUDGET_ROSTER_REL, - SELECTION_CONTROL_CI_FLOOR_PLAN_REL, SELECTION_CONTROL_DOC_REACHABILITY_REL, - SELECTION_CONTROL_FALSIFIER_CONTROL_REL, SELECTION_CONTROL_FLOOR_RUNNER_REL, - SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL, SELECTION_CONTROL_LIVE_TREE_DECLARED_REL, - SELECTION_CONTROL_NODE_PRECISE_REL, SELECTION_CONTROL_REALIZATION_SCHEDULE_REL, - SELECTION_CONTROL_SHARED_HELPER_REL, -}; -use v1_compiler::v1_interpreter::ExecutionMode; - -fn fail(msg: impl std::fmt::Display) -> ExitCode { - eprintln!("floor_skip_discovery_witness: {msg}"); - ExitCode::from(1) -} - -fn chdir_workspace() { - std::env::set_current_dir(workspace_root()).expect("chdir to workspace root"); -} - -fn floor_skip_source_roots() -> Vec { - let ws = workspace_root(); - vec![ - ws.join("src/v2").to_string_lossy().into_owned(), - ws.join("dag").to_string_lossy().into_owned(), - ] -} - -fn floor_skip_test_roster() -> (Vec, Vec<(String, String)>) { - let ws = workspace_root(); - let entry = ws - .join(SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL) - .to_string_lossy() - .into_owned(); - let function = "floor_test_untouched_skips_assumed_green_holds".to_string(); - (floor_skip_source_roots(), vec![(entry, function)]) -} - -fn discovery_options(skip: bool) -> DiscoveryCorpusOptions { - DiscoveryCorpusOptions { - node_frontier_selection: if skip { - NodeFrontierSelectionMode::Applied - } else { - NodeFrontierSelectionMode::Off - }, - execution_authority_source_roots: floor_skip_source_roots(), - explicit_roster_only: true, - ..Default::default() - } -} - -fn run_explicit_roster(skip: bool) -> Result { - chdir_workspace(); - let (source_roots, explicit) = floor_skip_test_roster(); - run_discovery_corpus_with_options( - &source_roots, - &[], - &explicit, - ExecutionMode::Wet, - DiscoveryWidthPolicy::Serial, - discovery_options(skip), - ) -} - -struct EnvVarGuard { - key: &'static str, - previous: Option, -} - -impl EnvVarGuard { - fn set(key: &'static str, value: &str) -> Self { - let previous = std::env::var(key).ok(); - std::env::set_var(key, value); - Self { key, previous } - } -} - -impl Drop for EnvVarGuard { - fn drop(&mut self) { - match &self.previous { - Some(v) => std::env::set_var(self.key, v), - None => std::env::remove_var(self.key), - } - } -} - -fn fixture_line(text: &str, needle: &str) -> i64 { - text.lines() - .position(|l| l.contains(needle)) - .map(|i| (i + 1) as i64) - .unwrap_or_else(|| panic!("discriminator fixture missing line containing `{needle}`")) -} - -/// The `git diff --name-status -z` record for a single MODIFIED file, coherent with the unified -/// hunk injected on the other channel, in the injection transport's AT-REST encoding: each -/// wire-format NUL separator is written as the octal escape `\000`, because a POSIX environment -/// variable is a C string and cannot carry a raw NUL byte (`std::env::set_var` panics on one — -/// proven by execution 2026-07-10). The injection arm in `floor_diff_observe.dag` -/// (`floor_name_status_injection_encoding_note`) decodes with `printf %b`, so the consumer sees -/// the identical NUL-separated bytes the real-git arm produces and `git.dag`'s -/// `from_code_point(0)` split stays the single parse authority. Without this channel injected, -/// the name-status read falls through to the real checkout diff — a non-hermetic two-channel -/// observation measuring the working tree instead of the fixture. -fn injected_name_status_modify(rel_path: &str) -> String { - format!("M\\000{rel_path}\\000") -} - -fn run_injected_diff_roster( - rel_path: &str, - line: i64, - roster: &[(String, String)], -) -> DiscoverySummary { - let unified = format!("+++ b/{rel_path}\n@@ -{line},0 +{line},1 @@\n+// synthetic touch\n"); - let _diff = EnvVarGuard::set("GUNBC_CI_DIFF_UNIFIED", &unified); - let _name_status = EnvVarGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - &injected_name_status_modify(rel_path), - ); - run_discovery_corpus_with_options( - &floor_skip_source_roots(), - &[], - roster, - ExecutionMode::Wet, - DiscoveryWidthPolicy::Serial, - discovery_options(true), - ) - .expect("node-precise skip path must not error (FreeMonoid decode root fix)") -} - -fn run_injected_diff_roster_with_mode( - rel_path: &str, - line: i64, - roster: &[(String, String)], - mode: NodeFrontierSelectionMode, -) -> DiscoverySummary { - let unified = format!("+++ b/{rel_path}\n@@ -{line},0 +{line},1 @@\n+// synthetic touch\n"); - let _diff = EnvVarGuard::set("GUNBC_CI_DIFF_UNIFIED", &unified); - let _name_status = EnvVarGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - &injected_name_status_modify(rel_path), - ); - run_discovery_corpus_with_options( - &floor_skip_source_roots(), - &[], - roster, - ExecutionMode::Wet, - DiscoveryWidthPolicy::Serial, - DiscoveryCorpusOptions { - node_frontier_selection: mode, - execution_authority_source_roots: floor_skip_source_roots(), - explicit_roster_only: true, - ..Default::default() - }, - ) - .expect("predict-only path must not error") -} - -fn live_tree_declared_roster() -> Vec<(String, String)> { - let ws = workspace_root(); - vec![( - ws.join(SELECTION_CONTROL_LIVE_TREE_DECLARED_REL) - .to_string_lossy() - .into_owned(), - "live_tree_declared_control_holds".to_string(), - )] -} - -fn doc_reachability_roster(function: &str) -> Vec<(String, String)> { - let ws = workspace_root(); - vec![( - ws.join(SELECTION_CONTROL_DOC_REACHABILITY_REL) - .to_string_lossy() - .into_owned(), - function.to_string(), - )] -} - -fn declared_live_tree_row_runs_on_unrelated_diff() { - chdir_workspace(); - // The diff touches an UNRELATED fixture; a declared-ReadsLiveTree row must - // still RUN (its inputs are outside the diff, so no diff proves it unaffected). - let summary = run_injected_diff_roster( - SELECTION_CONTROL_NODE_PRECISE_REL, - 3, - &live_tree_declared_roster(), - ); - assert_eq!(summary.total, 1); - assert_eq!( - summary.skipped, 0, - "a declared ReadsLiveTree row must never take the node-frontier skip" - ); - assert_eq!(summary.passed, 1, "the live-tree row runs and is green"); -} - -fn declared_live_tree_row_never_predicted_unaffected() { - chdir_workspace(); - let summary = run_injected_diff_roster_with_mode( - SELECTION_CONTROL_NODE_PRECISE_REL, - 3, - &live_tree_declared_roster(), - NodeFrontierSelectionMode::PredictOnly, - ); - assert!( - summary.predicted_unaffected.is_empty(), - "predict-only must never predict a declared ReadsLiveTree row unaffected \ - (live-tree rows never predict-skip)" - ); - assert_eq!(summary.passed, 1); -} - -/// #7023 discriminating witness: a docs-only diff must RUN the doc-graph wall, not bypass it -/// via the retired `documentation_only_skip` shell shortcut. The entry already declares -/// `ReadsLiveTree`; selection's never-predict-skip lane is the sole authority — no hand edge. -fn doc_reachability_runs_on_docs_only_diff() { - chdir_workspace(); - let summary = run_injected_diff_roster( - "docs/plans/synthetic-orphan-doc-reachability-red-control.md", - 1, - &doc_reachability_roster("doc_graph_has_no_orphan_docs"), - ); - assert_eq!(summary.total, 1); - assert_eq!( - summary.skipped, 0, - "doc-reachability must RUN on a docs-only diff (ReadsLiveTree never predict-skips; \ - #7023 class: shell documentation_only_skip bypass retired)" - ); - assert_eq!(summary.passed, 1, "clean tree: orphan wall is green"); -} - -fn doc_reachability_never_predicted_unaffected_on_docs_only_diff() { - chdir_workspace(); - let summary = run_injected_diff_roster_with_mode( - "docs/plans/synthetic-orphan-doc-reachability-red-control.md", - 1, - &doc_reachability_roster("doc_graph_has_no_orphan_docs"), - NodeFrontierSelectionMode::PredictOnly, - ); - assert!( - summary.predicted_unaffected.is_empty(), - "predict-only must never predict doc-reachability unaffected on a docs-only diff" - ); - assert_eq!(summary.passed, 1); -} - -fn falsifier_control_roster(function: &str) -> Vec<(String, String)> { - let ws = workspace_root(); - vec![( - ws.join(SELECTION_CONTROL_FALSIFIER_CONTROL_REL) - .to_string_lossy() - .into_owned(), - function.to_string(), - )] -} - -fn predict_only_red_predicted_unaffected_is_divergence() { - chdir_workspace(); - // Diff touches an UNRELATED fixture, so the red control is predicted-unaffected. - let summary = run_injected_diff_roster_with_mode( - SELECTION_CONTROL_NODE_PRECISE_REL, - 3, - &falsifier_control_roster("falsifier_red_control_holds"), - NodeFrontierSelectionMode::PredictOnly, - ); - assert_eq!(summary.skipped, 0, "predict-only never applies the skip"); - assert_eq!( - summary.predicted_unaffected.len(), - 1, - "the prediction must be recorded per row" - ); - assert_eq!( - summary.failures.len(), - 1, - "the red row still fails the batch" - ); - assert_eq!( - summary.divergences.len(), - 1, - "predicted-unaffected + red = exactly one counted divergence" - ); -} - -fn predict_only_green_predicted_unaffected_no_divergence() { - chdir_workspace(); - let summary = run_injected_diff_roster_with_mode( - SELECTION_CONTROL_NODE_PRECISE_REL, - 3, - &falsifier_control_roster("falsifier_green_control_holds"), - NodeFrontierSelectionMode::PredictOnly, - ); - assert_eq!(summary.predicted_unaffected.len(), 1); - assert_eq!(summary.passed, 1, "predicted-unaffected rows still run"); - assert!( - summary.divergences.is_empty(), - "a green predicted-unaffected row is a confirmed prediction, not a divergence" - ); -} - -fn predict_only_red_predicted_affected_is_not_divergence() { - chdir_workspace(); - // Diff edits the red control's own declaration line → predicted-AFFECTED → its red - // is an ordinary failure. Divergence must discriminate, not count every red. - let ws = workspace_root(); - let text = std::fs::read_to_string(ws.join(SELECTION_CONTROL_FALSIFIER_CONTROL_REL)) - .expect("falsifier control fixture readable"); - let line = fixture_line(&text, "test fn falsifier_red_control_holds"); - let summary = run_injected_diff_roster_with_mode( - SELECTION_CONTROL_FALSIFIER_CONTROL_REL, - line, - &falsifier_control_roster("falsifier_red_control_holds"), - NodeFrontierSelectionMode::PredictOnly, - ); - assert!( - summary.predicted_unaffected.is_empty(), - "editing the declaration line predicts the row affected" - ); - assert_eq!(summary.failures.len(), 1, "the red still fails the batch"); - assert!( - summary.divergences.is_empty(), - "predicted-affected + red is NOT a divergence — divergence must discriminate" - ); -} - -fn budget_roster_completeness_entry(ws: &std::path::Path) -> String { - ws.join(SELECTION_CONTROL_BUDGET_ROSTER_REL) - .to_string_lossy() - .into_owned() -} - -// Selection-control step D3 (CI floor endgame, 2026-07-23): this suite paid THREE cold -// whole-pool index builds per run — the two budget_roster cases each called bare -// build_multi_entry_index, then the first corpus case built the thread-shared index — -// which is why the step measured 4m51s in CI against 80s local (the cold-index class, -// attribution doc section 9, under the post-floor slot's swapped-out cgroup). The warmup -// case now resolves through resolve_entry_graph_shared, so its warmup entries AND every -// later corpus case share ONE process index. The cold case below deliberately keeps its -// own bare build — it is the named cold-resolution control (the import-strip Class-B -// pool-coincidence class needs a fresh-index resolution witness), one cold build by design. -// -// REGRESSED, and this note read as resolved while it was not (2026-07-29): the step measured -// 9m02s on run 30482171871 (job 90679506428) — ~1.9x the 4m51s state the D3 fix above was -// written to repair. Accounting from that job log: the assertions cost nothing (every witness -// row reports 0.0-0.3ms), and the wall is 18 serial scenario setups — ~2m15s for the shared -// index build in the warmup case below, ~2m34s for the deliberate cold build after it, ~34s -// total for the eight scenarios that hit the shared index, ~3m30s for the ~7 that land in the -// affected closure and pay ~30s each resolving to decide the node frontier, and 11.2s of -// thread-local teardown at exit. Two of those are addressed in the same change as this line: -// the teardown (see main — removed by construction via process::exit, with the 11.2s being the -// CI-measured cost of the removed path rather than a fresh paired before/after timing, which -// the suite's runtime put outside the local measurement window) and the step's placement, which -// is now affected-set scoped by gunbc.ci_workflow's selection-control step so most PRs do not -// pay any of it — though that scoping is itself a trade, priced in that step's note. The ~30s -// per-resolve unit is NOT explained — it is 4x the ~7.2s/resolve the floor resolve receipt -// records, so it is either a genuinely larger closure or a PROCESS_RESOLVE_STORE miss, and it -// is left as a named measurement rather than a guessed fix. -fn budget_roster_resolves_after_frontier_warmup() { - chdir_workspace(); - let roots = floor_skip_source_roots(); - for path in [ - SELECTION_CONTROL_REALIZATION_SCHEDULE_REL, - SELECTION_CONTROL_FLOOR_RUNNER_REL, - SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL, - ] { - let _ = resolve_entry_graph_shared(&roots, path); - } - let entry = budget_roster_completeness_entry(&workspace_root()); - resolve_entry_graph_shared(&roots, &entry).expect("budget_roster should resolve"); -} - -// The ONE deliberate cold build in this suite (see the note above): a fresh index with no -// warmup, proving the budget_roster entry resolves without pool-membership coincidence. -fn budget_roster_resolves_cold() { - chdir_workspace(); - let roots = floor_skip_source_roots(); - let index = build_multi_entry_index(&roots); - let entry = budget_roster_completeness_entry(&workspace_root()); - resolve_entry_with_index(&index, &entry).expect("budget_roster should resolve cold"); -} - -fn discovery_corpus_skip_disabled_runs_without_panic() { - let summary = run_explicit_roster(false).expect("skip-disabled discovery must not panic"); - assert_eq!(summary.skipped, 0, "skip disabled → no skips"); - assert!( - summary.passed >= 1, - "skip-disabled path must run at least one witness" - ); -} - -fn discovery_corpus_skip_enabled_empty_diff_skips_unaffected() { - let _base = EnvVarGuard::set("GUNBC_CI_DIFF_BASE", "HEAD"); - let _head = EnvVarGuard::set("GUNBC_CI_DIFF_HEAD", "HEAD"); - let summary = run_explicit_roster(true).expect("empty diff path must not panic"); - // Ruling 2026-07-05: empty diff is not a state — an empty touched-path set - // flows through the general disposition, so every unaffected row skips. - // The old assertion here (skipped == 0, "fail-closed run-all") enshrined - // the absorbing fallback this contract now forbids. - assert!( - summary.skipped >= 1, - "empty diff = computed ∅ — unaffected rows must skip (got {} skips)", - summary.skipped - ); - assert_eq!( - summary.passed, 0, - "empty diff must not run unaffected witnesses (run-all is the absorbing arm)" - ); -} - -fn discovery_corpus_skip_enabled_git_observation_refuses() { - let _base = EnvVarGuard::set("GUNBC_CI_DIFF_BASE", "__gunbc_invalid_diff_base__"); - let _head = EnvVarGuard::set("GUNBC_CI_DIFF_HEAD", "HEAD"); - let _merge = EnvVarGuard::set("GUNBC_CI_DIFF_MERGE_BASE", "0"); - // Ruling 2026-07-05: observation failure is the one ignorance state and it - // REFUSES — a typed, counted error naming its cause — never a silent - // run-everything or a silent selection-off. - let err = run_explicit_roster(true) - .expect_err("git observation failure must refuse, not run or skip"); - assert!( - err.contains("DiffObservationRefusal"), - "refusal must name its cause (got: {err})" - ); -} - -fn node_precise_referenced_runs_orphan_skips_by_execution() { - chdir_workspace(); - let ws = workspace_root(); - let rel = SELECTION_CONTROL_NODE_PRECISE_REL; - let abs = ws.join(rel); - let text = std::fs::read_to_string(&abs).expect("discriminator fixture readable"); - let entry = abs.to_string_lossy().into_owned(); - let roster = vec![( - entry.clone(), - "floor_disc_witness_transitive_holds".to_string(), - )]; - - let c_line = fixture_line(&text, "^floor_disc_node_c_symbol"); - let run = run_injected_diff_roster(rel, c_line, &roster); - assert_eq!(run.total, 1); - assert!( - run.failures.is_empty(), - "referenced-node edit failures: {:?}", - run.failures - ); - assert_eq!(run.skipped, 0, "editing a referenced node must NOT skip"); - assert_eq!( - run.passed, 1, - "editing a referenced node must RUN the witness" - ); - - let orphan_line = fixture_line(&text, "^floor_disc_orphan_symbol"); - let skip = run_injected_diff_roster(rel, orphan_line, &roster); - assert_eq!(skip.total, 1); - assert!( - skip.failures.is_empty(), - "orphan-node edit failures: {:?}", - skip.failures - ); - assert_eq!( - skip.passed, 0, - "editing an orphan node must NOT run the witness" - ); - assert_eq!( - skip.skipped, 1, - "editing an orphan node must SKIP (node precision; a file-level impl re-runs it)" - ); -} - -fn node_precise_transitive_c_edit_runs_conj_witness() { - chdir_workspace(); - let ws = workspace_root(); - let rel = SELECTION_CONTROL_NODE_PRECISE_REL; - let abs = ws.join(rel); - let text = std::fs::read_to_string(&abs).expect("discriminator fixture readable"); - let c_line = fixture_line(&text, "^floor_disc_node_c_symbol"); - let entry = abs.to_string_lossy().into_owned(); - - let summary = run_injected_diff_roster( - rel, - c_line, - &[( - entry.clone(), - "floor_disc_witness_transitive_holds".to_string(), - )], - ); - assert_eq!(summary.total, 1); - assert!( - summary.failures.is_empty(), - "C-edit transitive witness failures: {:?}", - summary.failures - ); - assert_eq!( - summary.skipped, 0, - "transitive witness must RUN when inner node C's span changed (shallow closure would skip)" - ); - assert_eq!(summary.passed, 1); -} - -fn node_precise_test_fn_body_edit_runs_only_that_witness() { - chdir_workspace(); - let ws = workspace_root(); - let rel = SELECTION_CONTROL_NODE_PRECISE_REL; - let abs = ws.join(rel); - let text = std::fs::read_to_string(&abs).expect("discriminator fixture readable"); - let entry = abs.to_string_lossy().into_owned(); - let roster = vec![(entry.clone(), "floor_disc_witness_a_only_holds".to_string())]; - - let a_fn_line = fixture_line(&text, "test fn floor_disc_witness_a_only_holds"); - let a = run_injected_diff_roster(rel, a_fn_line, &roster); - assert_eq!(a.total, 1); - assert!( - a.failures.is_empty(), - "witness-A body edit failures: {:?}", - a.failures - ); - assert_eq!( - a.skipped, 0, - "editing witness A's own body must NOT skip it" - ); - assert_eq!( - a.passed, 1, - "editing witness A's own body must RUN it (finding 1)" - ); - - let b_fn_line = fixture_line(&text, "test fn floor_disc_witness_b_only_holds"); - let b = run_injected_diff_roster(rel, b_fn_line, &roster); - assert_eq!(b.total, 1); - assert!( - b.failures.is_empty(), - "witness-B body edit failures: {:?}", - b.failures - ); - assert_eq!( - b.passed, 0, - "editing witness B's body must NOT run witness A" - ); - assert_eq!( - b.skipped, 1, - "editing witness B's body must SKIP witness A (per-function precision)" - ); -} - -fn entry_file_helper_fn_edit_scopes_runs_to_touched_entry_only() { - chdir_workspace(); - let ws = workspace_root(); - let disc_rel = SELECTION_CONTROL_NODE_PRECISE_REL; - let disc_abs = ws.join(disc_rel); - let text = std::fs::read_to_string(&disc_abs).expect("discriminator fixture readable"); - let helper_line = fixture_line(&text, "fn floor_disc_helper_fn"); - let disc_entry = disc_abs.to_string_lossy().into_owned(); - let runner_entry = ws - .join(SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL) - .to_string_lossy() - .into_owned(); - let roster = vec![ - ( - disc_entry.clone(), - "floor_disc_witness_a_only_holds".to_string(), - ), - ( - runner_entry, - "floor_test_untouched_skips_assumed_green_holds".to_string(), - ), - ]; - - let summary = run_injected_diff_roster(disc_rel, helper_line, &roster); - assert_eq!(summary.total, 2); - assert!( - summary.failures.is_empty(), - "helper-fn edit cross-entry roster failures: {:?}", - summary.failures - ); - assert_eq!( - summary.passed, 1, - "helper-fn edit must RUN the witness in the touched entry" - ); - assert_eq!( - summary.skipped, 1, - "helper-fn edit must SKIP witnesses in unrelated entries (replaces force_run_all)" - ); -} - -fn import_closure_helper_fn_edit_runs_importer_entry_only() { - chdir_workspace(); - let ws = workspace_root(); - let helper_rel = SELECTION_CONTROL_SHARED_HELPER_REL; - let helper_abs = ws.join(helper_rel); - let text = std::fs::read_to_string(&helper_abs).expect("shared helper readable"); - let helper_line = fixture_line(&text, "fn floor_disc_shared_helper"); - let disc_entry = ws - .join(SELECTION_CONTROL_NODE_PRECISE_REL) - .to_string_lossy() - .into_owned(); - let runner_entry = ws - .join(SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL) - .to_string_lossy() - .into_owned(); - let roster = vec![ - (disc_entry, "floor_disc_witness_a_only_holds".to_string()), - ( - runner_entry, - "floor_test_untouched_skips_assumed_green_holds".to_string(), - ), - ]; - - let summary = run_injected_diff_roster(helper_rel, helper_line, &roster); - assert_eq!(summary.total, 2); - assert!( - summary.failures.is_empty(), - "cross-file helper-fn edit roster failures: {:?}", - summary.failures - ); - assert_eq!( - summary.passed, 1, - "cross-file helper-fn edit must RUN the witness in the importing entry" - ); - assert_eq!( - summary.skipped, 1, - "cross-file helper-fn edit must SKIP witnesses in unrelated entries" - ); -} - -fn frontier_warmup_does_not_poison_corpus_resolution() { - chdir_workspace(); - let ws = workspace_root(); - let poisoner_rel = SELECTION_CONTROL_CI_FLOOR_PLAN_REL; - let poisoner_abs = ws.join(poisoner_rel); - let text = std::fs::read_to_string(&poisoner_abs).expect("ci_floor_plan readable"); - let data_line = fixture_line(&text, "data floor_corpus_node"); - let budget = budget_roster_completeness_entry(&ws); - let roster = vec![( - budget, - "complexity_budget_roster_family_gate_holds".to_string(), - )]; - - let summary = run_injected_diff_roster(poisoner_rel, data_line, &roster); - assert_eq!(summary.total, 1); - assert!( - summary.failures.is_empty(), - "corpus must resolve cleanly after frontier warmup (no FreeMonoid poison): {:?}", - summary.failures - ); - assert_eq!( - summary.skipped, 1, - "budget_roster does not reference the edited ci_floor_plan node → skips after a clean resolve" - ); -} - -fn main() -> ExitCode { - let _workspace_marker: PathBuf = workspace_root(); - - let tests: Vec<(&str, fn())> = vec![ - ( - "budget_roster_resolves_after_frontier_warmup", - budget_roster_resolves_after_frontier_warmup, - ), - ("budget_roster_resolves_cold", budget_roster_resolves_cold), - ( - "discovery_corpus_skip_disabled_runs_without_panic", - discovery_corpus_skip_disabled_runs_without_panic, - ), - ( - "discovery_corpus_skip_enabled_empty_diff_skips_unaffected", - discovery_corpus_skip_enabled_empty_diff_skips_unaffected, - ), - ( - "discovery_corpus_skip_enabled_git_observation_refuses", - discovery_corpus_skip_enabled_git_observation_refuses, - ), - ( - "predict_only_red_predicted_unaffected_is_divergence", - predict_only_red_predicted_unaffected_is_divergence, - ), - ( - "predict_only_green_predicted_unaffected_no_divergence", - predict_only_green_predicted_unaffected_no_divergence, - ), - ( - "predict_only_red_predicted_affected_is_not_divergence", - predict_only_red_predicted_affected_is_not_divergence, - ), - ( - "declared_live_tree_row_runs_on_unrelated_diff", - declared_live_tree_row_runs_on_unrelated_diff, - ), - ( - "declared_live_tree_row_never_predicted_unaffected", - declared_live_tree_row_never_predicted_unaffected, - ), - ( - "doc_reachability_runs_on_docs_only_diff", - doc_reachability_runs_on_docs_only_diff, - ), - ( - "doc_reachability_never_predicted_unaffected_on_docs_only_diff", - doc_reachability_never_predicted_unaffected_on_docs_only_diff, - ), - ( - "node_precise_referenced_runs_orphan_skips_by_execution", - node_precise_referenced_runs_orphan_skips_by_execution, - ), - ( - "node_precise_transitive_c_edit_runs_conj_witness", - node_precise_transitive_c_edit_runs_conj_witness, - ), - ( - "node_precise_test_fn_body_edit_runs_only_that_witness", - node_precise_test_fn_body_edit_runs_only_that_witness, - ), - ( - "entry_file_helper_fn_edit_scopes_runs_to_touched_entry_only", - entry_file_helper_fn_edit_scopes_runs_to_touched_entry_only, - ), - ( - "import_closure_helper_fn_edit_runs_importer_entry_only", - import_closure_helper_fn_edit_runs_importer_entry_only, - ), - ( - "frontier_warmup_does_not_poison_corpus_resolution", - frontier_warmup_does_not_poison_corpus_resolution, - ), - ]; - - for (name, test) in tests { - let result = std::panic::catch_unwind(test); - if result.is_err() { - return fail(format!("{name} panicked")); - } - } - - // Exit WITHOUT running thread-local destructors. `cli_run`'s PROCESS_RESOLVE_INDEX - // (`Rc`, the whole-pool index) and PROCESS_RESOLVE_STORE (one - // `Rc` per scenario resolved above) are thread-locals, and thread-locals - // ARE dropped when the main thread ends — so returning normally spent 11.2s walking - // Rc/HashMap destructors for a whole-corpus graph the process is about to abandon - // (measured: run 30482171871 job 90679506428, last receipt line 19:30:55.34, step - // completion 19:31:06.53, nothing logged in between). The OS reclaims the address space, - // so that teardown buys nothing. - // - // Safe because no destructor here is load-bearing: every receipt this suite emits is - // printed eagerly during the scenarios (visible in the CI log before the gap), the - // scenarios are each wrapped in `catch_unwind` above so a panic is already handled, and - // the process holds no buffers other than stdout/stderr — flushed explicitly first, - // since `process::exit` does not run libstd's at-exit flush. - let _ = std::io::Write::flush(&mut std::io::stdout()); - let _ = std::io::Write::flush(&mut std::io::stderr()); - std::process::exit(0); -} diff --git a/src/v1/stage0/src/bin/p1_cohort_probe.rs b/src/v1/stage0/src/bin/p1_cohort_probe.rs index 2eda8d59a65..cb7995b8c32 100644 --- a/src/v1/stage0/src/bin/p1_cohort_probe.rs +++ b/src/v1/stage0/src/bin/p1_cohort_probe.rs @@ -36,7 +36,6 @@ use v1_compiler::cli_run::{ heartbeat_feed_snapshot, p1_cohort_cgroup_memory, p1_experimental_arm_shared_typed_store, run_discovery_corpus_with_options, shared_typecheck_store_counters_snapshot, typecheck_compute_count, DiscoveryCorpusOptions, DiscoveryWidthPolicy, - NodeFrontierSelectionMode, }; use v1_compiler::memory_governor::{ leaf_cgroup_dir, read_cgroup_raw, read_cgroup_u64, MemoryGovernor, @@ -308,7 +307,6 @@ fn main() -> ExitCode { ); let options = DiscoveryCorpusOptions { - node_frontier_selection: NodeFrontierSelectionMode::Off, execution_authority_source_roots: source_roots.clone(), explicit_roster_only: true, ..Default::default() diff --git a/src/v1/stage0/src/bin/selection_control_skip_witness.rs b/src/v1/stage0/src/bin/selection_control_skip_witness.rs deleted file mode 100644 index 1de5518b673..00000000000 --- a/src/v1/stage0/src/bin/selection_control_skip_witness.rs +++ /dev/null @@ -1,103 +0,0 @@ -#![allow(clippy::disallowed_macros)] - -//! Affected-set selection-control skip witness (host fast path). -//! -//! Prints `selection_control_not_affected_skip` when the merge-base diff touches no input -//! of the `floor_skip_discovery_witness` control suite (`src/v1/**`, the suite's declared -//! `.dag` entries plus their import closure through `[src/v2, dag]`, and the Cargo/toolchain -//! build config), else `run_selection_control`. -//! -//! Fail-closed by REFUSING, not by widening. A diff-observation or closure-computation failure -//! means the affected set is UNKNOWN, which is a different state from "everything is affected" -//! and has a different remedy — so this bin prints a typed, located, countable diagnostic to -//! stderr and exits NON-ZERO, stopping the line. It never prints a label in that case, so the -//! CI step's string comparison cannot mistake ignorance for an answer, and `bash -e` aborts the -//! step RED rather than silently running the suite and passing. -//! -//! That is DESIGN §5's absorbing-fallback rule ("a failure arm must refuse, never widen") and -//! matches the ruling already recorded in `floor_diff_baseline_law`: a diff-observation failure -//! HALTS with a typed AFFECTED-SET REFUSAL (operator ruling 2026-07-05). Deliberately UNLIKE the -//! `regen_floor_skip_witness` precedent, which suppresses stderr and defaults via a shell -//! fallback — that shape is the thing this one refuses to copy. -//! -//! The whole decision lives in `cli_run::selection_control_skip_label_for_ci`; this bin is just -//! the transport. - -use std::process::ExitCode; - -use v1_compiler::cli_run::{selection_control_skip_label_for_ci, workspace_root}; - -fn main() -> ExitCode { - std::env::set_current_dir(workspace_root()).expect("chdir to workspace root"); - match selection_control_skip_label_for_ci() { - Ok(label) => { - println!("{label}"); - ExitCode::SUCCESS - } - Err(refusal) => { - // stderr + non-zero, and NO label on stdout: the step must stop, not proceed. - eprintln!("{}", refusal.diagnostic()); - ExitCode::FAILURE - } - } -} - -#[cfg(test)] -mod tests { - use v1_compiler::cli_run::{ - selection_control_input_sources, selection_control_skip_label_for_ci, workspace_root, - RUN_SELECTION_CONTROL_LABEL, SELECTION_CONTROL_DECLARED_ENTRIES, - SELECTION_CONTROL_NOT_AFFECTED_SKIP_LABEL, - }; - - #[test] - fn labels_are_distinct() { - assert_ne!( - SELECTION_CONTROL_NOT_AFFECTED_SKIP_LABEL, - RUN_SELECTION_CONTROL_LABEL - ); - let label = selection_control_skip_label_for_ci() - .expect("a clean tree observes its diff and answers with a label"); - assert!( - label == SELECTION_CONTROL_NOT_AFFECTED_SKIP_LABEL - || label == RUN_SELECTION_CONTROL_LABEL, - "unexpected label: {label}" - ); - } - - /// Every declared entry must exist on disk. A stale path would silently shrink the - /// closure (the read error is fail-closed at label time, but the roster would be lying), - /// so this pins the authority against the tree. - #[test] - fn declared_entries_exist() { - let ws = workspace_root(); - for rel in SELECTION_CONTROL_DECLARED_ENTRIES { - assert!( - ws.join(rel).is_file(), - "declared selection-control entry missing from tree: {rel}" - ); - } - } - - /// The closure must contain every declared entry, and must be a strict SUPERSET of them - /// — an import closure that returned only the entries themselves would mean the walk - /// found no imports, which for these entries is impossible and would silently narrow the - /// skip decision. - #[test] - fn closure_covers_entries_and_reaches_imports() { - let ws = workspace_root(); - let closure = selection_control_input_sources(&ws).expect("closure must compute"); - for rel in SELECTION_CONTROL_DECLARED_ENTRIES { - assert!( - closure.iter().any(|p| p == rel), - "closure omits declared entry {rel}" - ); - } - assert!( - closure.len() > SELECTION_CONTROL_DECLARED_ENTRIES.len(), - "closure ({}) did not reach past the {} declared entries — import walk is dead", - closure.len(), - SELECTION_CONTROL_DECLARED_ENTRIES.len() - ); - } -} diff --git a/src/v1/stage0/src/cli_run.rs b/src/v1/stage0/src/cli_run.rs index 85c3799337e..28bd222312c 100644 --- a/src/v1/stage0/src/cli_run.rs +++ b/src/v1/stage0/src/cli_run.rs @@ -3768,423 +3768,13 @@ pub fn regen_floor_skip_label_for_ci() -> String { } } -// --------------------------------------------------------------------------- -// Affected-set SELECTION-CONTROL skip — the selection mechanism applied to itself. -// -// `floor_skip_discovery_witness` is the per-PR control suite for affected-set selection: -// the skip / refuse / divergence arms, the declared-live-tree pin, and the node-frontier -// precision cases. It ran UNCONDITIONALLY on every PR — 9m02s measured (run 30482171871, -// job 90679506428, step "Affected-set selection control") against the 80s local basis -// declared in `gunbc.ci_workflow` `gunbc_ci_selection_control_step_note` — because it is a -// Rust bin rather than a `.dag` witness and therefore sat outside the very affected-set -// corpus its own subject matter governs. -// -// The suite's verdict is a function of exactly one input set: every `src/v1/**` source (the -// selection implementation in this file, the witness bin, and the committed stage0 outputs -// the release binary is built from), the suite's declared `.dag` entries plus their -// transitive `import` closure through `[src/v2, dag]`, and the Cargo/toolchain build -// config. A PR touching none of those provably cannot change the suite's verdict. -// -// NOT circular. The skip decision is a coarse path / import-closure intersection — the same -// authority SHAPE `regen_floor_skip_label_for_ci` uses — and never the node-frontier -// selector the suite exists to verify. A broken selector therefore cannot suppress its own -// control. -// -// Fail-closed on every arm, in TWO different ways — the distinction is load-bearing: -// - STRUCTURAL arms (empty diff, ANY departed path, ANY markdown path, any closure -// intersection) RUN the suite. The diff was observed, so the answer is computed. -// - REFUSAL arms (diff-observation failure, input-closure failure) REFUSE: typed, located, -// countable, non-zero exit, no label. They do NOT run the suite, because "I could not -// compute what is affected" is a different state from "everything is affected" and has a -// different remedy (DESIGN §5 absorbing fallback; the ruling recorded in -// `floor_diff_baseline_law`, operator 2026-07-05). -// Corrected after review 44778 caught this comment still claiming the failure arms RUN — the -// same Rust-side single-authority drift review 44768 fixed in the emitted policy note. -// -// RESIDUAL, stated rather than elided, and mirroring the regen precedent's accepted trade -// exactly: the suite builds its resolve index over the WHOLE of `[src/v2, dag]`, so an -// unrelated file that breaks index construction is outside this import closure. The -// mitigation is regen's: the CI shell gates the skip to pull_request events, so push-to-main -// runs the suite unconditionally and a wrong closure surfaces as a red main within one -// merge (the one-merge acceptance window, the discovery-flip shape). -// --------------------------------------------------------------------------- - -pub const SELECTION_CONTROL_NOT_AFFECTED_SKIP_LABEL: &str = "selection_control_not_affected_skip"; -pub const RUN_SELECTION_CONTROL_LABEL: &str = "run_selection_control"; - -// The suite's declared `.dag` surface, one named const per entry. These are the SINGLE -// authority: `floor_skip_discovery_witness` builds its rosters from them, and the closure -// below decides whether a diff can affect them. Declaring them here rather than in the bin -// is what keeps the two from forking — a fixture added to the suite with its own private -// path literal would be invisible to the skip decision, which is precisely the silent -// under-run this whole mechanism exists to prevent. -pub const SELECTION_CONTROL_REALIZATION_SCHEDULE_REL: &str = "dag/std/realization_schedule.dag"; -pub const SELECTION_CONTROL_DOC_REACHABILITY_REL: &str = - "dag/test/claim/doc_reachability_witness_test.dag"; -pub const SELECTION_CONTROL_BUDGET_ROSTER_REL: &str = - "src/v2/test/claim/complexity_gate/budget_roster_completeness_test.dag"; -pub const SELECTION_CONTROL_FALSIFIER_CONTROL_REL: &str = - "src/v2/test/fixture/floor_skip/falsifier_divergence_control_test.dag"; -pub const SELECTION_CONTROL_SHARED_HELPER_REL: &str = - "src/v2/test/fixture/floor_skip/floor_disc_shared_helper.dag"; -pub const SELECTION_CONTROL_LIVE_TREE_DECLARED_REL: &str = - "src/v2/test/fixture/floor_skip/live_tree_declared_test.dag"; -pub const SELECTION_CONTROL_NODE_PRECISE_REL: &str = - "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag"; -pub const SELECTION_CONTROL_FLOOR_RUNNER_REL: &str = - "src/v2/workflow/affected_set_floor_runner.dag"; -pub const SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL: &str = - "src/v2/workflow/affected_set_floor_runner_test.dag"; -pub const SELECTION_CONTROL_CI_FLOOR_PLAN_REL: &str = "src/v2/workflow/ci_floor_plan.dag"; - -pub const SELECTION_CONTROL_DECLARED_ENTRIES: &[&str] = &[ - SELECTION_CONTROL_REALIZATION_SCHEDULE_REL, - SELECTION_CONTROL_DOC_REACHABILITY_REL, - SELECTION_CONTROL_BUDGET_ROSTER_REL, - SELECTION_CONTROL_FALSIFIER_CONTROL_REL, - SELECTION_CONTROL_SHARED_HELPER_REL, - SELECTION_CONTROL_LIVE_TREE_DECLARED_REL, - SELECTION_CONTROL_NODE_PRECISE_REL, - SELECTION_CONTROL_FLOOR_RUNNER_REL, - SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL, - SELECTION_CONTROL_CI_FLOOR_PLAN_REL, -]; - -/// The two-entry incident subject for live-read selection controls and P3 A/B parity. -/// -/// A = the node-precise discriminator fixture (the entry the diff touches). -/// B = the affected-set floor runner test (the unrelated entry whose closure reaches a -/// live-read carrier home). B is what the retired predicate made unskippable on any nonempty -/// `.dag` diff, which is the `2 selected / 1 expected` incident. -pub fn selection_control_incident_subject_roster() -> Vec<(String, String)> { - let ws = workspace_root(); - vec![ - ( - ws.join(SELECTION_CONTROL_NODE_PRECISE_REL) - .to_string_lossy() - .into_owned(), - "floor_disc_witness_a_only_holds".to_string(), - ), - ( - ws.join(SELECTION_CONTROL_FLOOR_RUNNER_TEST_REL) - .to_string_lossy() - .into_owned(), - "floor_test_untouched_skips_assumed_green_holds".to_string(), - ), - ] -} - -/// The suite's source roots — `[src/v2, dag]`, the roots its rosters resolve against. -/// Single authority for the same reason as the entry consts above. -pub fn selection_control_source_roots(workspace: &Path) -> Vec { - vec![workspace.join("src/v2"), workspace.join("dag")] -} - -/// Module-path -> every candidate file, over the suite's roots. -/// -/// Deliberately unlike `regen_build_module_index`, which REFUSES on a duplicate module -/// path: this keeps all candidates so the closure below is a superset. For a SKIP closure a -/// superset is the fail-closed direction (more paths in the closure = more PRs run the -/// suite), whereas regen's error arm is the correct one for regen, whose emit must be -/// single-valued. -fn selection_control_module_index( - roots: &[PathBuf], -) -> Result>, String> { - let mut index: std::collections::HashMap> = - std::collections::HashMap::new(); - for root in roots { - if !root.exists() { - return Err(format!("source root does not exist: {}", root.display())); - } - let mut dag_paths = Vec::new(); - regen_collect_dag_files(root, &mut dag_paths)?; - for path in dag_paths { - let content = std::fs::read_to_string(&path) - .map_err(|e| format!("read {}: {e}", path.display()))?; - if let Some(module_path) = extract_module_path(&content) { - index.entry(module_path).or_default().push(path); - } - } - } - Ok(index) -} - -/// Every workspace-relative `.dag` path whose content can change the selection-control -/// suite's verdict: the declared entries plus their transitive `import` closure through -/// `[src/v2, dag]`, sorted. -/// -/// 🟡 dissolve-on (two triggers, near then terminal): -/// -/// NEAR — the import walk here duplicates the shape of `regen_input_sources`'s -/// walk. They are NOT unified yet because regen's closure is guarded by a byte-identical -/// oracle (`regen_stage0 --verify`) that this change is not in a position to re-verify, and -/// the two differ in duplicate policy (refuse vs. superset) and entry selection (whole-root -/// walk vs. declared list). DISSOLVES WHEN the walk is lifted to one parameterized helper -/// (duplicate policy + entry source as arguments) and regen's byte oracle re-greens on it. -/// -/// TERMINAL — owning lane: `docs/plans/affected-set-precompute-pruning.md`, whose **Step 5 -/// "delete Rust parallel"** (NOT STARTED, gated on Step 4) is what retires host-side -/// selection Rust in favour of the `.dag` authority. This fn and -/// `selection_control_skip_label_for_ci` are new members of exactly that Rust-parallel set — -/// a path/import-closure selection decision living in the seed rather than in -/// `.dag` — so they inherit Step 5's terminal condition. They are ENUMERATED on that roster as -/// an explicit deferral (the "Step 5 roster — CI skip-decision surfaces" row, added by this -/// change), which is what makes this a declared, countable seed-retained surface rather than a -/// silent escape hatch (DESIGN §7). Why deferred rather than modeled now: the decision must run -/// BEFORE the floor resolves anything — that is its entire purpose — so a `.dag` consumer would -/// pay the ~100s cold whole-pool resolve the skip exists to avoid; it therefore dissolves with -/// the persistent content-keyed node store, not on its own schedule. -/// -/// Receipt bar, per DESIGN §5: this is a scaffold because the decision is *checkable* by -/// execution — 9 label arms below (7 structural + 2 refusal), discriminating in both -/// directions, plus 3 bin unit tests. -pub fn selection_control_input_sources(workspace: &Path) -> Result, String> { - let roots = selection_control_source_roots(workspace); - let index = selection_control_module_index(&roots)?; - let mut seen: HashSet = HashSet::new(); - let mut queue: Vec = Vec::new(); - for rel in SELECTION_CONTROL_DECLARED_ENTRIES { - let path = workspace.join(rel); - let content = std::fs::read_to_string(&path) - .map_err(|e| format!("read declared selection-control entry {rel}: {e}"))?; - seen.insert(normalize_repo_path(rel)); - queue.push(content); - } - while let Some(content) = queue.pop() { - for module_path in extract_import_paths(&content) { - let Some(candidates) = index.get(&module_path) else { - continue; - }; - for path in candidates { - let rel = normalize_repo_path(®en_workspace_relpath(path, workspace)); - if !seen.insert(rel) { - continue; - } - let file_content = std::fs::read_to_string(path) - .map_err(|e| format!("read imported module {}: {e}", path.display()))?; - queue.push(file_content); - } - } - } - let mut result: Vec = seen.into_iter().collect(); - result.sort(); - Ok(result) -} - -/// Does a diff-changed path belong to the selection-control input surface? -fn selection_control_path_affects_suite(changed: &str, dag_closure: &HashSet) -> bool { - let p = normalize_repo_path(changed); - // src/v1/** = the selection implementation (this file's discovery / affected-set / - // node-frontier paths), the witness bin itself, and every committed stage0 output the - // release binary is built from. - if p.starts_with("src/v1/") { - return true; - } - // Cargo/toolchain build config: the witness binary is built from these (whole-file - // matches, no substring), same fail-closed arm as regen's. - if p == "Cargo.lock" - || p == "Cargo.toml" - || p.ends_with("/Cargo.toml") - || p == "rust-toolchain.toml" - || p == "rust-toolchain" - || p == ".cargo/config.toml" - || p == ".cargo/config" - { - return true; - } - // Markdown: the doc-reachability declared entry (`SELECTION_CONTROL_DOC_REACHABILITY_REL`) - // declares `LiveTreeDisposition = ReadsLiveTree` and folds the whole markdown doc graph - // (`gunbc.doc_graph_roots.doc_graph_roots_all` — registered plan docs ∪ hand-authored - // binds) to decide `doc_graph_has_no_orphan_docs` / `doc_graph_has_no_dangling_links`. - // A `.md` add/edit/delete can therefore flip this suite's verdict, and that reach is NOT - // discoverable through the `.dag` import walk above — a live-tree read is not an import - // edge. So every markdown path runs the suite. - // - // This is a structural over-approximation computed AS the answer (DESIGN §5: "a - // dependency-closure superset is the model's precision frontier, not an absorption"), - // not a failure arm that widens — the entry really does read every markdown root, so no - // `.md` diff can be proven irrelevant by path. - // - // FOUND BY REVIEW (review 44682, this PR): the first draft bounded inputs by - // `src/v1/**` ∪ dag-import-closure ∪ Cargo config and skipped docs-only diffs, while its - // own green control asserted that skip on `docs/plans/example.md` — enshrining the - // suppression of exactly the docs-only orphan regression this suite carries per-PR. - if p.ends_with(".md") { - return true; - } - dag_closure.contains(&p) -} - -/// Typed cause for a selection-control REFUSAL — the arms where the affected set could not be -/// computed at all. -/// -/// DESIGN §5: "can't compute the affected set → rerun the entire suite" is the named absorbing -/// fallback — ⊤-as-ignorance conflated with ⊤-as-answer. It fails open twice: the deficit's -/// frequency is zeroed by construction (so it never ranks for fixing), and the cost is -/// denominated in the corpus rather than the change. The repo already ruled on exactly this -/// arm: `floor_diff_baseline_law` (src/v2/workflow/floor_diff_observe.dag) records that a -/// `BaselineRefused` → `NameStatusDiffFail` "HALTS the floor with a typed AFFECTED-SET REFUSAL -/// (refuses every enrolled row, never widens to a full-corpus run; operator ruling -/// 2026-07-05)". This enum is that ruling applied to the selection-control step's own skip -/// decision — FOUND BY REVIEW (review 44745), whose first draft returned the RUN label from -/// both failure arms and stayed green. -/// -/// `token()` is the stable, greppable discriminator that makes each refusal COUNTABLE in the -/// job log, so its frequency is observable and prioritizable rather than absorbed. -#[derive(Debug, Clone, PartialEq, Eq)] -pub enum SelectionControlRefusalCause { - /// The merge-base diff could not be observed (`floor_git_diff_name_status_range` failed). - DiffObservationFailed, - /// The suite's input closure could not be computed (entry unreadable, import walk failed). - InputClosureFailed, -} - -impl SelectionControlRefusalCause { - pub fn token(&self) -> &'static str { - match self { - Self::DiffObservationFailed => "DiffObservationFailed", - Self::InputClosureFailed => "InputClosureFailed", - } - } -} - -/// A typed, located, countable refusal. Carries the cause, the mechanism that could not answer -/// (`located`), and the underlying detail — everything analysis needs before the line restarts. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct SelectionControlSkipRefusal { - pub cause: SelectionControlRefusalCause, - pub located: &'static str, - pub detail: String, -} - -impl SelectionControlSkipRefusal { - /// The single-line diagnostic. Stable prefix + `cause=` token so occurrences are countable. - pub fn diagnostic(&self) -> String { - format!( - "SELECTION_CONTROL_REFUSED cause={} at={} detail={} \ - — the affected set could not be computed, so this step REFUSES rather than \ - widening to a full run (DESIGN §5 absorbing fallback; operator ruling 2026-07-05, \ - floor_diff_baseline_law). Analyse the cause before restarting the line.", - self.cause.token(), - self.located, - self.detail - ) - } -} - -/// CI label for the affected-set selection-control step's skip arm. -/// -/// `Ok(selection_control_not_affected_skip)` iff the merge-base diff touches no input of the -/// control suite; `Ok(run_selection_control)` on any intersection, empty diff, or ANY departed -/// path — those are STRUCTURAL answers, computed from an observed diff. -/// -/// `Err(SelectionControlSkipRefusal)` when the affected set could not be computed at all -/// (diff observation or closure failure). Those arms REFUSE rather than widening to a run: -/// see `SelectionControlRefusalCause` for the §5 reasoning and the 2026-07-05 ruling. The -/// distinction is the whole point — "everything is affected" and "I could not compute what is -/// affected" are different states with different remedies, and only the first may be answered -/// with a label. -/// -/// This computes the decision only; the CI shell gates the skip to pull_request events, so -/// push-to-main runs the suite unconditionally as the cold control. -pub fn selection_control_skip_label_for_ci() -> Result { - let (changed_paths, departed_paths) = match floor_git_diff_name_status_range() { - Ok(v) => v, - Err(detail) => { - // REFUSE, never widen: "diff unavailable → run everything" is the §5 absorbing - // fallback. Returning the RUN label here would keep CI green and zero this - // deficit's observed frequency, which is exactly how it never gets fixed. - return Err(SelectionControlSkipRefusal { - cause: SelectionControlRefusalCause::DiffObservationFailed, - located: "cli_run::floor_git_diff_name_status_range \ - (src/v2/workflow/floor_diff_observe.dag \ - floor_observe_git_diff_name_status_for_ci)", - detail, - }); - } - }; - // Empty diff is a STRUCTURAL state, not a failure arm: the observation succeeded and - // reported zero changed paths. It is therefore answerable with a label, unlike the - // refusals above. It answers RUN (conservative) rather than SKIP because an empty - // merge-base diff on a pull_request is degenerate — a PR changes something by definition — - // so the honest reading is "this observation tells us nothing useful about THIS PR". - // - // Noted for the record, because it is adjacent to a ruling: DESIGN's floor-runner receipt - // has the empty diff "dissolved into the general disposition, never a special arm" - // (operator rulings 2026-07-05). Dissolving it here would make it SKIP (no changed path - // can intersect the closure). That is a live question about THIS step rather than the - // floor runner, and it moves in the less-checking direction, so it is deliberately not - // decided here — flagged for the operator instead of quietly picked. - if changed_paths.is_empty() { - eprintln!( - "selection-control skip: empty diff — run the control suite (degenerate observation \ - for a pull_request; structural arm, not a refusal)" - ); - return Ok(RUN_SELECTION_CONTROL_LABEL.to_string()); - } - // Departed (deleted / renamed-from) paths: NO carve-out. Two independent causes, which - // together leave no departed path provably irrelevant: - // - non-docs: the closure is computed from the CURRENT tree, so a deleted `.dag` file - // that WAS in the suite's closure is invisible to the intersection below; - // - markdown: a deleted doc changes the live doc graph the `ReadsLiveTree` - // doc-reachability entry folds — removing a link target creates a dangling link, - // removing a linker orphans its target. Either flips the suite red. - // The regen/compile-clean departed arms exempt `docs/` because markdown is genuinely - // outside THEIR closures; it is inside this one (see the `.md` arm in - // `selection_control_path_affects_suite`), so copying their carve-out here was the bug. - // `min()` rather than `iter().next()`: the set's iteration order is not stable, and this - // path is printed into the CI log as the reason. A nondeterministic diagnostic is the - // determinism class `v2.lens.determinism` gates on — the arm fires on ANY departed path, - // so which one it names must not vary run to run. - if let Some(gone) = departed_paths.iter().min() { - eprintln!( - "selection-control skip: departed path in diff ({}) — run the control suite (current-tree closure cannot see deletions; a departed doc changes the live doc graph)", - normalize_repo_path(gone) - ); - return Ok(RUN_SELECTION_CONTROL_LABEL.to_string()); - } - let workspace = workspace_root(); - let dag_closure: HashSet = match selection_control_input_sources(&workspace) { - Ok(sources) => sources.into_iter().collect(), - Err(detail) => { - // REFUSE, never widen — same §5 arm as the diff-observation failure above. An - // unreadable entry or a dead import walk means the input set is UNKNOWN, which is - // a different state from "everything is affected" and has a different remedy. - return Err(SelectionControlSkipRefusal { - cause: SelectionControlRefusalCause::InputClosureFailed, - located: "cli_run::selection_control_input_sources", - detail, - }); - } - }; - match changed_paths - .iter() - .find(|p| selection_control_path_affects_suite(p, &dag_closure)) - { - Some(example) => { - eprintln!( - "selection-control skip: diff intersects the control suite's inputs (e.g. {}) — run the control suite", - normalize_repo_path(example) - ); - Ok(RUN_SELECTION_CONTROL_LABEL.to_string()) - } - None => { - eprintln!( - "selection-control skip: {} changed path(s), none intersect the control suite's input closure (src/v1/** ∪ declared-entry dag import-closure ∪ every .md ∪ Cargo/toolchain config) — the suite's verdict is provably unchanged (push-to-main runs it unconditionally as the cold control)", - changed_paths.len() - ); - Ok(SELECTION_CONTROL_NOT_AFFECTED_SKIP_LABEL.to_string()) - } - } -} - // --------------------------------------------------------------------------- // Class B import-closure gate affected-set skip (#7835). // // `run_class_b_import_closure_gate` costs ~2.3 min wall per cold run; skip when the // merge-base diff is provably disjoint from the gate's input closure (declared-import // pool ∪ witness layer ∪ perturbation fixtures ∪ gate transport modules). Same shape as -// regen_floor_skip_label_for_ci / selection_control_skip_label_for_ci: skip only on a +// regen_floor_skip_label_for_ci: skip only on a // non-empty diff proven disjoint; run on empty diff, departed non-docs paths, and any // observation/closure failure (fail-closed — regen shape: still RUN the gate, but the two // failure arms carry grep-countable labels distinct from structural run_class_b_gate). @@ -4254,12 +3844,41 @@ fn class_b_pool_source_roots(workspace: &Path, pool_roots: &[String]) -> Vec source-file index over a set of `.dag` source roots. +/// +/// Named for what it computes rather than for its first caller: it was previously +/// `selection_control_module_index`, homed with the affected-set selection-control suite that +/// happened to reach it first, while the Class B import-closure gate below already depended on +/// it across that seam. The suite is deleted; the index is not, because the question it answers +/// -- which file declares this module -- is what any import walk needs. +fn dag_module_index( + roots: &[PathBuf], +) -> Result>, String> { + let mut index: std::collections::HashMap> = + std::collections::HashMap::new(); + for root in roots { + if !root.exists() { + return Err(format!("source root does not exist: {}", root.display())); + } + let mut dag_paths = Vec::new(); + regen_collect_dag_files(root, &mut dag_paths)?; + for path in dag_paths { + let content = std::fs::read_to_string(&path) + .map_err(|e| format!("read {}: {e}", path.display()))?; + if let Some(module_path) = extract_module_path(&content) { + index.entry(module_path).or_default().push(path); + } + } + } + Ok(index) +} + fn import_closure_dag_files( workspace: &Path, source_roots: &[PathBuf], seed_entries: &[&str], ) -> Result, String> { - let index = selection_control_module_index(source_roots)?; + let index = dag_module_index(source_roots)?; let mut seen: HashSet = HashSet::new(); let mut queue: Vec = Vec::new(); for rel in seed_entries { @@ -4323,7 +3942,7 @@ fn collect_repo_files_under_prefix( /// /// 🟡 dissolve-on (two triggers, near then terminal): /// -/// NEAR — the import walk here duplicates the shape of `selection_control_input_sources` and +/// NEAR — the import walk here duplicates the shape the deleted selection-control suite used, and /// `regen_input_sources`. They are NOT unified yet because regen's closure is guarded by a /// byte-identical oracle (`regen_stage0 --verify`) that this change is not in a position to /// re-verify, and the three differ in duplicate policy (refuse vs. superset) and entry @@ -6788,10 +6407,6 @@ fn entry_eligible_for_discovery_skip_before_resolve( struct DiscoveryEntryResolve { ctx: v1_interpreter::InterpContext, closure_subject: String, - frontier_nodes: Vec, - touches_frontier: bool, - entry_file_touched: bool, - entry_runtime_dependency_touched: bool, resolve_nanos: u128, stage_nanos: ResolveStageNanos, } @@ -6801,10 +6416,6 @@ fn resolve_discovery_entry_for_corpus_row( entry_path: &str, execution_mode: v1_interpreter::ExecutionMode, whole_tree_published_keys: Option>>, - skip_enabled: bool, - diff_edits: &FloorDiffEdits, - touched_entry_paths: &[String], - module_graph_declared_paths: &HashSet, closure_modules: &mut HashSet, ) -> Result { let sources = load_sources_for_entry_with_pool(index, entry_path) @@ -6829,64 +6440,9 @@ fn resolve_discovery_entry_for_corpus_row( None, whole_tree_published_keys, ); - let (frontier_nodes, touches_frontier, entry_file_touched, entry_runtime_dependency_touched) = - if skip_enabled { - let frontier_nodes = - rerun_frontier_nodes_for_entry(&entry_ctx, entry_path, diff_edits)?; - let touches_frontier = if frontier_nodes.is_empty() { - false - } else { - entry_touches_rerun_frontier( - &entry_ctx, - &list_value_from_vec(frontier_nodes.clone()), - )? - }; - let entry_file_touched = if touched_entry_paths.is_empty() { - false - } else { - entry_file_touched_via_import_closure( - entry_path, - &index.module_graph_facts, - module_graph_declared_paths, - touched_entry_paths, - )? - }; - let declared_axis = declared_source_refs_axis_for_entry( - entry_path, - &index.module_graph_facts, - &default_source_roots(), - touched_entry_paths, - ); - let entry_runtime_dependency_touched = - runtime_data_dependency_touched_via_carrier_closure( - entry_path, - &index.module_graph_facts, - touched_entry_paths, - ) || match declared_axis { - DeclaredSourceRefAxis::Absent => effect_reach_touched_via_path_literals( - entry_path, - &index.module_graph_facts, - touched_entry_paths, - ), - DeclaredSourceRefAxis::Touched | DeclaredSourceRefAxis::Unresolved => true, - DeclaredSourceRefAxis::Untouched => false, - }; - ( - frontier_nodes, - touches_frontier, - entry_file_touched, - entry_runtime_dependency_touched, - ) - } else { - (Vec::new(), true, true, true) - }; Ok(DiscoveryEntryResolve { ctx: entry_ctx, closure_subject, - frontier_nodes, - touches_frontier, - entry_file_touched, - entry_runtime_dependency_touched, resolve_nanos, stage_nanos, }) @@ -11882,146 +11438,6 @@ fn emit_floor_drain_receipt( ); } -const SELECTION_DEGRADATION_RECEIPT_ENTRY: &str = "dag/gunbc/selection_degradation_receipt.dag"; - -/// Kept so `gunbc.observation_emit_census` roster hygiene cannot go stale after the -/// raw `[selection-degradation]` receipt line dissolves into the observation projection. -#[allow(dead_code)] -pub const SELECTION_DEGRADATION_CENSUS_MARKER: &str = "[selection-degradation]"; - -fn node_frontier_selection_mode_tag(mode: NodeFrontierSelectionMode) -> &'static str { - match mode { - NodeFrontierSelectionMode::Off => "off", - NodeFrontierSelectionMode::Applied => "applied", - NodeFrontierSelectionMode::PredictOnly => "predict_only", - } -} - -/// Measured selection-degradation facts finalized at discovery completion. -#[derive(Debug, Clone)] -pub struct SelectionDegradationSnapshot { - pub selection_mode_tag: String, - pub selected_entry_groups: usize, - pub total_entry_groups: usize, - pub categorization_unavailable: bool, - pub categorization_reason: String, -} - -impl SelectionDegradationSnapshot { - pub fn from_summary(selection: NodeFrontierSelectionMode, summary: &DiscoverySummary) -> Self { - Self { - selection_mode_tag: node_frontier_selection_mode_tag(selection).to_string(), - selected_entry_groups: summary.selected_entry_groups, - total_entry_groups: summary.total_entry_groups, - categorization_unavailable: summary.selection_categorization_reason.is_some(), - categorization_reason: summary - .selection_categorization_reason - .clone() - .unwrap_or_default(), - } - } -} - -fn selection_degradation_interp_ctx( - source_roots: &[String], -) -> Result<(v1_interpreter::InterpContext, String), String> { - let entry = resolve_entry_file_under_roots(source_roots, SELECTION_DEGRADATION_RECEIPT_ENTRY) - .map_err(|_| { - format!( - "selection-degradation receipt REFUSED — {SELECTION_DEGRADATION_RECEIPT_ENTRY} \ - not found under source roots" - ) - })?; - let (graph, indices) = resolve_entry_graph_shared(source_roots, &entry) - .map_err(|e| format!("selection-degradation receipt REFUSED — resolve {entry}: {e}"))?; - Ok(( - make_eval_context(&graph, indices, v1_interpreter::ExecutionMode::Hermetic), - entry, - )) -} - -fn selection_degradation_dag_args( - snapshot: &SelectionDegradationSnapshot, -) -> Vec<(Option, v1_interpreter::Value)> { - vec![ - ( - Some("selection_mode_tag".to_string()), - v1_interpreter::Value::Str(snapshot.selection_mode_tag.clone()), - ), - ( - Some("selected".to_string()), - v1_interpreter::Value::Int(snapshot.selected_entry_groups as i64), - ), - ( - Some("total".to_string()), - v1_interpreter::Value::Int(snapshot.total_entry_groups as i64), - ), - ( - Some("categorization_unavailable".to_string()), - v1_interpreter::Value::Bool(snapshot.categorization_unavailable), - ), - ( - Some("categorization_reason".to_string()), - v1_interpreter::Value::Str(snapshot.categorization_reason.clone()), - ), - ] -} - -fn eval_selection_degradation_fn( - source_roots: &[String], - fn_name: &str, - snapshot: &SelectionDegradationSnapshot, -) -> Result { - let (ctx, entry) = selection_degradation_interp_ctx(source_roots)?; - match v1_interpreter::run_in_context_with_args( - &ctx, - fn_name, - &selection_degradation_dag_args(snapshot), - false, - ) { - Ok(v1_interpreter::Value::Str(line)) => Ok(line), - Ok(other) => Err(format!( - "selection-degradation receipt REFUSED — {fn_name} returned `{}`, expected Str \ - (entry {entry})", - ctx.format_value(&other) - )), - Err(e) => Err(format!( - "selection-degradation receipt REFUSED — {fn_name} eval: {e}" - )), - } -} - -/// Bracket-tagged stderr line for discovery completion (also embedded in `[measurement]`). -pub fn render_selection_degradation_receipt_line( - source_roots: &[String], - snapshot: &SelectionDegradationSnapshot, -) -> Result { - eval_selection_degradation_fn(source_roots, "selection_degradation_receipt_line", snapshot) -} - -/// Key=value body written to `target/floor-selection-degradation-receipt.txt` and appended to -/// `floor-resolve-receipt.txt`. -pub fn render_selection_degradation_receipt_body( - source_roots: &[String], - snapshot: &SelectionDegradationSnapshot, -) -> Result { - eval_selection_degradation_fn(source_roots, "selection_degradation_receipt_body", snapshot) -} - -/// P2 floor prep-tax receipt on stderr after every discovery completion. -pub fn emit_selection_degradation_receipt( - source_roots: &[String], - selection: NodeFrontierSelectionMode, - summary: &DiscoverySummary, -) { - let _ = SELECTION_DEGRADATION_CENSUS_MARKER; - let snapshot = SelectionDegradationSnapshot::from_summary(selection, summary); - match render_selection_degradation_receipt_line(source_roots, &snapshot) { - Ok(line) => eprintln!("{line}"), - Err(msg) => eprintln!("{msg}"), - } -} - /// Enforce the host-budget-derived entry cap on the private typed cache. Evictions /// are counted and logged — a typed, located diagnostic, never a silent widen. /// Victim selection is arbitrary (first `HashMap` key), not LRU or load-aware: @@ -19180,13 +18596,6 @@ pub struct DiscoveryWitnessOutcome { pub execution_leg: String, } -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct SelectionSkippedDiscoveryRow { - pub entry: String, - pub function: String, - pub provenance: String, -} - /// A witness row excluded from discovery enrollment (exclusion substring, long lane, …). /// Counted and logged at roster build — never a silent skip (§5 deferred-and-detected). #[derive(Debug, Clone, PartialEq, Eq)] @@ -19236,13 +18645,6 @@ pub struct DiscoverySummary { pub skipped: usize, /// Witness rows excluded from discovery at scan time — counted, typed, observable. pub deferred_rows: Vec, - /// PredictOnly mode: rows the selection predicted unaffected (they still ran). - pub predicted_unaffected: Vec<(String, String)>, - /// Applied mode: enrolled rows retained with the provenance by which affected-set - /// selection declined execution. This is an honest nonfailure, never absence-as-pass. - pub selection_skipped_rows: Vec, - /// PredictOnly mode: predicted-unaffected rows whose cold run was red — each line is a - /// counted, typed attribution of a missing selection edge (never a rerun trigger). pub divergences: Vec, pub failures: Vec, pub witness_outcomes: Vec, @@ -19262,18 +18664,13 @@ pub struct DiscoverySummary { /// cache MISSES on the current thread and is never reset in production, so it equals a closure /// size only from a cold start — a condition this measurement cannot assume. It is warm here on /// the `width == 1` path (the same thread already resolved the changed-file entries in - /// `floor_diff_edits_from_line_ranges` and both prefix entries), and warm across repeat calls in - /// `floor_skip_discovery_witness`, which runs discovery three times in one thread. The union of - /// module names is a property of the source closure: independent of cache warmth, resolve order, - /// and — critically for a calibration datum — of the diff under test. + /// module names is a property of the source closure: independent of cache warmth and resolve + /// order. pub roster_closure_nodes: usize, /// Entry-group grain of the discovery roster (`entry_row_groups`); set at completion. pub total_entry_groups: usize, - /// Distinct entries with at least one executed witness (not selection-skipped only). + /// Distinct entries with at least one executed witness. pub selected_entry_groups: usize, - /// When Applied mode could not run upfront import-closure categorization; per-shard - /// selection remains authoritative and the completion receipt still publishes counts. - pub selection_categorization_reason: Option, } #[derive(Debug, Clone)] @@ -21090,23 +20487,6 @@ fn eprintln_deferred_discovery_rows(rows: &[DeferredDiscoveryRow]) { } } -/// §5 never-skip tooth: a `ReadsLiveTree` row must never take node-frontier selection skip. -fn refuse_reads_live_tree_selection_skip( - row: &DiscoveryRow, - skip_kind: &str, -) -> Result<(), String> { - if row.reads_live_tree { - return Err(format!( - "NEVER-SKIP REFUSAL cause=ReadsLiveTreeSelectionSkip rows=1 — \ - `{skip_kind}` would skip {} ({}) but the entry declares (or fail-closed \ - defaults to) ReadsLiveTree; a live-tree witness must run or refuse loudly, \ - never be silently selected out (§5; masks memo-wedge class defects when skipped)", - row.function, row.entry - )); - } - Ok(()) -} - pub(crate) fn collect_dag_files_tolerant(dir: &Path, out: &mut Vec) { let entries = match std::fs::read_dir(dir) { Ok(e) => e, @@ -22021,19 +21401,7 @@ pub(crate) fn refuse_on_module_graph_read_refusals( )) } -/// Host realization of std.realization_schedule.NodeFrontierSelection (signed design: -/// docs/plans/affected-set-differential-falsifier.md). PredictOnly computes would-skip -/// per row, RECORDS the prediction, and runs the row anyway — the falsifier cadence -/// compares predictions against cold verdicts. -#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] -pub enum NodeFrontierSelectionMode { - Off, - Applied, - PredictOnly, -} - pub struct DiscoveryCorpusOptions { - pub node_frontier_selection: NodeFrontierSelectionMode, /// Module universe that owns executor decisions such as affected-set selection and witness /// execution-leg classification. Normally identical to `source_roots`; scoped batches /// inherit the enclosing walk roots so executor machinery does not widen the witness subject. @@ -22077,7 +21445,6 @@ impl DiscoveryCorpusOptions { impl Default for DiscoveryCorpusOptions { fn default() -> Self { Self { - node_frontier_selection: NodeFrontierSelectionMode::Off, execution_authority_source_roots: vec![], explicit_roster_only: false, exclude_substrings: witness_exclusion_substrings(), @@ -22698,7 +22065,6 @@ struct FloorDiffEdits { touched_entry_files: HashSet, } -const FLOOR_RUNNER_ENTRY: &str = "src/v2/workflow/affected_set_floor_runner.dag"; const MODULE_GRAPH_ENTRY: &str = "src/v2/lens/module_graph.dag"; // `entry_file_touched_via_dependency_view` (the fn-arrow DependencyView wrapper) was @@ -24265,7 +23631,6 @@ pub fn run_discovery_corpus_with_options( options: DiscoveryCorpusOptions, ) -> Result { let pump_started = std::time::Instant::now(); - let selection = options.node_frontier_selection; let out = run_discovery_corpus_with_options_inner( source_roots, scan_dirs, @@ -24278,9 +23643,6 @@ pub fn run_discovery_corpus_with_options( &discovery_phase_totals::PUMP_WALL_MS, pump_started.elapsed(), ); - if let Ok(summary) = &out { - emit_selection_degradation_receipt(source_roots, selection, summary); - } out } @@ -24354,7 +23716,6 @@ fn run_discovery_corpus_with_options_inner( } eprintln_deferred_discovery_rows(&deferred_rows); set_phase(FloorPhase::Discovery, "discovery-roster"); - let selection_enabled = options.node_frontier_selection != NodeFrontierSelectionMode::Off; if options.execution_authority_source_roots.is_empty() { return Err( "discovery execution requires an explicit executor-authority source-root universe" @@ -24362,57 +23723,6 @@ fn run_discovery_corpus_with_options_inner( ); } let execution_authority_is_subject = options.execution_authority_source_roots == source_roots; - // No degradation arm: a non-Off node_frontier_selection is a DECLARED capability, - // so every input it needs (the git-diff observation, the frontier attribution, the - // affected-set runner) must be present — a failure is a loud typed error, never a - // silent run-everything fallback. To run without selection, declare the flag false. - let diff_observe_started = std::time::Instant::now(); - let diff_text = if selection_enabled { - floor_git_diff_range().map_err(|msg| { - format!( - "AFFECTED-SET REFUSAL cause=DiffObservationRefusal rows={} — git diff \ - observation failed ({msg}); observation failure is the only ignorance \ - state (operator ruling 2026-07-05) and refuses every enrolled row rather \ - than widening to a full-corpus run (declare node_frontier_selection: \ - SelectionOff to run without selection)", - rows.len() - ) - })? - } else { - String::new() - }; - // Path grain (changed_paths, departed_paths) is observed via the typed - // `git diff --name-status -z` interface (extdeps.git), not scraped from the - // unified diff's `diff --git a/OLD b/NEW` header: name-status is git's own - // machine surface for path identity/rename, so it is the single authority — - // the unified diff below stays scoped to LINE grain (hunk ranges) only. - let (name_status_changed_paths, name_status_departed_paths) = - if options.node_frontier_selection != NodeFrontierSelectionMode::Off { - floor_git_diff_name_status_range().map_err(|msg| { - format!( - "AFFECTED-SET REFUSAL cause=DiffObservationRefusal rows={} — git \ - diff --name-status observation failed ({msg}); observation failure \ - is the only ignorance state (operator ruling 2026-07-05) and \ - refuses every enrolled row rather than widening to a full-corpus \ - run (declare node_frontier_selection: SelectionOff to run without \ - selection)", - rows.len() - ) - })? - } else { - (Vec::new(), HashSet::new()) - }; - let mut line_ranges_by_file = parse_unified_diff_line_ranges(&diff_text); - for path in &name_status_changed_paths { - line_ranges_by_file.entry(path.clone()).or_default(); - } - let changed_new_lines_by_file = parse_unified_diff_changed_new_lines(&diff_text); - let added_paths = parse_unified_diff_added_paths(&diff_text); - let changed_paths: Vec = name_status_changed_paths; - discovery_phase_totals::add( - &discovery_phase_totals::DIFF_OBSERVE_MS, - diff_observe_started.elapsed(), - ); // Union-resolve S1 (resolver-graph-major-design.md §7): ONE index for the whole // process step on the pump thread — prelude-warmed parse/typed caches instead of a // private cold build per consumer. S2a increment C (cross-worker-typecheck-share- @@ -24443,12 +23753,7 @@ fn run_discovery_corpus_with_options_inner( // the post-resolve union so this pre-resolve count stays paired with calibration. let preresolve_calibration_started = std::time::Instant::now(); let pre_resolve_closure_nodes = { - let prefix_entries: &[&str] = if selection_enabled && execution_authority_is_subject { - &[FLOOR_RUNNER_ENTRY] - } else { - &[] - }; - let n = roster_import_closure_nodes_pre_resolve(&rows, prefix_entries, &index)?; + let n = roster_import_closure_nodes_pre_resolve(&rows, &[], &index)?; eprintln!( "[calibration] roster_import_closure_nodes={} rows={} (loader both-closure union, pre-resolve, no resolve/typecheck; pairs with the floor cgroup memory.peak steps — on a killed run this line plus the last [gantt] rss_mib sample are the lower-bound receipt)", n, @@ -24460,144 +23765,15 @@ fn run_discovery_corpus_with_options_inner( &discovery_phase_totals::PRERESOLVE_CALIBRATION_MS, preresolve_calibration_started.elapsed(), ); - // Empty diff is not a state (operator ruling 2026-07-05): an empty touched-path - // set flows through the general selection machinery — empty frontier, zero edited - // fns — so every row takes the normal not-affected skip. Disabling selection here - // was the run-everything absorbing arm. - let frontier_attribution_started = std::time::Instant::now(); - let (skip_enabled, diff_edits) = if selection_enabled { - match floor_diff_edits_from_line_ranges( - &index, - &line_ranges_by_file, - &changed_new_lines_by_file, - &name_status_departed_paths, - &added_paths, - ) { - Ok(edits) => (true, edits), - Err(msg) => { - return Err(format!( - "node-frontier population failed ({msg}) — the diff-to-declaration \ - attribution is declared selection machinery; no silent full-corpus \ - fallback" - )); - } - } - } else { - (false, FloorDiffEdits::default()) - }; - discovery_phase_totals::add( - &discovery_phase_totals::FRONTIER_ATTRIBUTION_MS, - frontier_attribution_started.elapsed(), - ); - let runner_resolve_started = std::time::Instant::now(); - let floor_runner_ctx = if selection_enabled { - let resolved = if execution_authority_is_subject { - // Ordinary discovery consumes one source-root authority, so preserve the shared - // prefix resolve and its measured retention behavior. - resolve_entry_with_index(&index, FLOOR_RUNNER_ENTRY) - } else { - // Scoped discovery keeps its subject universe narrow. The selector is an enclosing - // walk authority and resolves against that walk's roots without entering the subject - // index, digest, or clamp population. - resolve_entry_graph( - &options.execution_authority_source_roots, - FLOOR_RUNNER_ENTRY, - ) - }; - match resolved { - Ok((graph, source_indices)) => { - Some(make_eval_context(&graph, source_indices, execution_mode)) - } - Err(msg) => { - return Err(format!( - "floor runner resolve failed ({msg}) — a non-Off node_frontier_selection \ - declares the affected-set machinery ({FLOOR_RUNNER_ENTRY}) and it \ - must resolve; no silent full-corpus fallback" - )); - } - } - } else { - None - }; - discovery_phase_totals::add( - &discovery_phase_totals::RUNNER_RESOLVE_MS, - runner_resolve_started.elapsed(), - ); - let skip_precompute = if skip_enabled { - let live_row_count = discovery_rows_live_tree_count(&rows); - match floor_runner_ctx.as_ref() { - Some(ctx) => { - let touched_runtime_dependency_entry_count = - discovery_rows_runtime_dependency_touched_count( - &rows, - &index.module_graph_facts, - &changed_paths, - ); - let precompute = call_floor_row_precompute_would_skip( - ctx, - live_row_count, - &changed_paths, - diff_edits.overlapping_data_items.len(), - diff_edits.edited_test_fns.len(), - diff_edits.touched_entry_files.len(), - touched_runtime_dependency_entry_count, - ); - match precompute { - Ok(skip) => skip, - Err(msg) => { - return Err(format!( - "floor precompute_would_skip failed ({msg}) — declared selection \ - machinery must evaluate; no silent fallback" - )); - } - } - } - None => false, - } - } else { - false - }; - let whole_tree_published_keys = if skip_precompute { - eprintln!( - "run_discovery_corpus: skipping whole-tree published-mock precompute (scoped diff, empty node frontier, no edited test fns, no entry-file fn edits)" - ); - None - } else { - match precompute_whole_tree_published_mock_keys(source_roots) { - Ok(keys) if keys.is_empty() => None, - Ok(keys) => Some(keys), - Err(e) => { - return Err(format!( - "whole-tree published mock corpus precompute failed: {e}" - )); - } + let whole_tree_published_keys = match precompute_whole_tree_published_mock_keys(source_roots) { + Ok(keys) if keys.is_empty() => None, + Ok(keys) => Some(keys), + Err(e) => { + return Err(format!( + "whole-tree published mock corpus precompute failed: {e}" + )); } }; - eprintln_affected_set_categorization( - options.node_frontier_selection, - &rows, - &index, - &diff_edits, - &changed_paths, - ); - let selection_categorization_reason = - if options.node_frontier_selection == NodeFrontierSelectionMode::Applied { - let declared_paths = index.module_graph_facts.declared_repo_paths(); - let touched: Vec = diff_edits.touched_entry_files.iter().cloned().collect(); - match discovery_entry_fast_skip_without_resolve( - &rows, - &index.module_graph_facts, - &declared_paths, - &touched, - &changed_paths, - &diff_edits, - ) { - Ok(_) => None, - Err(e) => Some(e), - } - } else { - None - }; // Derive every leg for the WHOLE roster here, above the width dispatch, while this // thread's shared index is warm. At width > 1 the pool hands each worker its own chunk // of rows, so priming inside `run_discovery_rows` would build one interpreter context @@ -24627,11 +23803,6 @@ fn run_discovery_corpus_with_options_inner( &rows, &index, execution_mode, - options.node_frontier_selection, - &changed_paths, - &diff_edits, - floor_runner_ctx.as_ref(), - execution_authority_is_subject, whole_tree_published_keys.clone(), options.witness_budget_policy(), ShardStyle { @@ -24664,13 +23835,7 @@ fn run_discovery_corpus_with_options_inner( "[calibration] closure consistency: pre-resolve loader-closure union == post-resolve union == {} node(s)", pre_resolve_closure_nodes ); - Ok(finalize_discovery_summary( - summary, - &rows, - options.node_frontier_selection, - selection_categorization_reason.clone(), - deferred_rows, - )) + Ok(finalize_discovery_summary(summary, &rows, deferred_rows)) } DiscoveryWidthPolicy::ControlledWidthTwo => { const CONTROLLED_WIDTH: usize = 2; @@ -24704,18 +23869,12 @@ fn run_discovery_corpus_with_options_inner( )); let abort = std::sync::Arc::new(AtomicBool::new(false)); let source_roots_owned = source_roots.to_vec(); - let execution_authority_roots_owned = options.execution_authority_source_roots.clone(); - let execution_authority_is_subject_for_workers = execution_authority_is_subject; - let selection_for_workers = options.node_frontier_selection; let budget_policy_for_workers = options.witness_budget_policy(); let mut handles = Vec::with_capacity(CONTROLLED_WIDTH); for worker_ordinal in 0..CONTROLLED_WIDTH { let queue_for_worker = queue.clone(); let abort_for_worker = abort.clone(); let roots = source_roots_owned.clone(); - let execution_authority_roots = execution_authority_roots_owned.clone(); - let seeds = diff_edits.clone(); - let paths = changed_paths.clone(); let keys = whole_tree_published_keys.clone(); let store = cross_worker_store.clone(); let arm_shared_for_worker = arm_shared_store; @@ -24728,33 +23887,12 @@ fn run_discovery_corpus_with_options_inner( handles.push(std::thread::spawn( move || -> Result, String> { let index = if arm_shared_for_worker { - let store = store.expect( - "shared typed store armed but cross_worker_store missing", - ); + let store = store + .expect("shared typed store armed but cross_worker_store missing"); build_multi_entry_index_with_shared_caches(&roots, store) } else { build_multi_entry_index(&roots) }; - let runner = if selection_for_workers != NodeFrontierSelectionMode::Off { - let resolved = if execution_authority_is_subject_for_workers { - resolve_entry_with_index(&index, FLOOR_RUNNER_ENTRY) - } else { - resolve_entry_graph(&execution_authority_roots, FLOOR_RUNNER_ENTRY) - }; - match resolved { - Ok((graph, source_indices)) => { - Some(make_eval_context(&graph, source_indices, execution_mode)) - } - Err(msg) => { - abort_for_worker.store(true, Ordering::SeqCst); - return Err(format!( - "floor runner resolve failed in controlled-width worker ({msg})" - )); - } - } - } else { - None - }; let mut worker_summaries = Vec::new(); loop { if abort_for_worker.load(Ordering::SeqCst) { @@ -24768,11 +23906,6 @@ fn run_discovery_corpus_with_options_inner( &group_rows, &index, execution_mode, - selection_for_workers, - &paths, - &seeds, - runner.as_ref(), - execution_authority_is_subject_for_workers, keys.clone(), budget_policy_for_workers, style, @@ -24811,8 +23944,6 @@ fn run_discovery_corpus_with_options_inner( Ok(finalize_discovery_summary( merge_discovery_summaries(summaries), &rows, - options.node_frontier_selection, - selection_categorization_reason, deferred_rows, )) } @@ -24900,11 +24031,6 @@ fn run_discovery_corpus_with_options_inner( &group_rows, &index, execution_mode, - options.node_frontier_selection, - &changed_paths, - &diff_edits, - floor_runner_ctx.as_ref(), - execution_authority_is_subject, whole_tree_published_keys.clone(), options.witness_budget_policy(), style, @@ -24981,8 +24107,6 @@ fn run_discovery_corpus_with_options_inner( return Ok(finalize_discovery_summary( merge_discovery_summaries(summaries), &rows, - options.node_frontier_selection, - selection_categorization_reason.clone(), deferred_rows, )); } @@ -25007,9 +24131,6 @@ fn run_discovery_corpus_with_options_inner( )); let abort = std::sync::Arc::new(AtomicBool::new(false)); let source_roots_owned = source_roots.to_vec(); - let execution_authority_roots_owned = options.execution_authority_source_roots.clone(); - let execution_authority_is_subject_for_workers = execution_authority_is_subject; - let selection_for_workers = options.node_frontier_selection; let budget_policy_for_workers = options.witness_budget_policy(); let mut handles = Vec::new(); let mut worker_ordinal: usize = 0; @@ -25028,9 +24149,6 @@ fn run_discovery_corpus_with_options_inner( let abort_for_worker = abort.clone(); let governor_for_worker = governor.clone(); let roots = source_roots_owned.clone(); - let execution_authority_roots = execution_authority_roots_owned.clone(); - let seeds = diff_edits.clone(); - let paths = changed_paths.clone(); let keys = whole_tree_published_keys.clone(); let spawn_target_width = governor.current_target_width(); let cross_worker_store_for_worker = if spawn_target_width > 1 { @@ -25068,28 +24186,6 @@ fn run_discovery_corpus_with_options_inner( } None => build_multi_entry_index(&roots), }; - let runner = if selection_for_workers != NodeFrontierSelectionMode::Off { - let resolved = if execution_authority_is_subject_for_workers { - resolve_entry_with_index(&index, FLOOR_RUNNER_ENTRY) - } else { - resolve_entry_graph(&execution_authority_roots, FLOOR_RUNNER_ENTRY) - }; - match resolved { - Ok((graph, source_indices)) => { - Some(make_eval_context(&graph, source_indices, execution_mode)) - } - Err(msg) => { - abort_for_worker.store(true, Ordering::SeqCst); - return Err(format!( - "floor runner resolve failed in worker ({msg}) — declared \ - affected-set machinery must resolve; no silent \ - run-everything fallback" - )); - } - } - } else { - None - }; // The front-loaded admission cost (index build + runner resolve) has // landed and is visible to the creep signals: unblock admission pacing. slot.note_first_cost_paid(); @@ -25110,11 +24206,6 @@ fn run_discovery_corpus_with_options_inner( &group_rows, &index, execution_mode, - selection_for_workers, - &paths, - &seeds, - runner.as_ref(), - execution_authority_is_subject_for_workers, keys.clone(), budget_policy_for_workers, style, @@ -25160,8 +24251,6 @@ fn run_discovery_corpus_with_options_inner( Ok(finalize_discovery_summary( merge_discovery_summaries(summaries), &rows, - options.node_frontier_selection, - selection_categorization_reason, deferred_rows, )) } @@ -25171,8 +24260,6 @@ fn run_discovery_corpus_with_options_inner( fn finalize_discovery_summary( mut summary: DiscoverySummary, rows: &[DiscoveryRow], - _selection: NodeFrontierSelectionMode, - selection_categorization_reason: Option, deferred_rows: Vec, ) -> DiscoverySummary { summary.deferred_rows = deferred_rows; @@ -25183,7 +24270,6 @@ fn finalize_discovery_summary( .map(|o| o.entry.as_str()) .collect::>() .len(); - summary.selection_categorization_reason = selection_categorization_reason; emit_batch_summary(&summary); summary } @@ -25217,8 +24303,6 @@ fn merge_discovery_summaries(summaries: Vec) -> DiscoverySumma passed: 0, skipped: 0, deferred_rows: Vec::new(), - predicted_unaffected: Vec::new(), - selection_skipped_rows: Vec::new(), divergences: Vec::new(), failures: Vec::new(), witness_outcomes: Vec::new(), @@ -25230,18 +24314,11 @@ fn merge_discovery_summaries(summaries: Vec) -> DiscoverySumma roster_closure_nodes: 0, total_entry_groups: 0, selected_entry_groups: 0, - selection_categorization_reason: None, }; for summary in summaries { merged.total += summary.total; merged.passed += summary.passed; merged.skipped += summary.skipped; - merged - .predicted_unaffected - .extend(summary.predicted_unaffected); - merged - .selection_skipped_rows - .extend(summary.selection_skipped_rows); merged.divergences.extend(summary.divergences); merged.failures.extend(summary.failures); merged.witness_outcomes.extend(summary.witness_outcomes); @@ -25358,65 +24435,6 @@ fn floor_ts() -> String { format!("{h:02}:{m:02}:{s:02}.{millis:03}") } -/// One upfront line categorizing the corpus before any witness runs — the operator-facing -/// "N skipped, M impacted, running X" read of the affected-set selection. The skip count here -/// is the cheap import-closure disposition (entry-grain, no resolve); the finer per-node -/// frontier decision runs the affected closure down further, so `[measurement]` at the end -/// reports the exact ran/skipped tally. Print-only: the authoritative decision (and its -/// fail-closed refusal on a provenance gap) still happens per-shard in `run_discovery_rows`. -fn eprintln_affected_set_categorization( - selection: NodeFrontierSelectionMode, - rows: &[DiscoveryRow], - index: &MultiEntryIndex, - diff_edits: &FloorDiffEdits, - changed_paths: &[String], -) { - let total = rows.len(); - let entries = rows - .iter() - .map(|r| r.entry.as_str()) - .collect::>() - .len(); - let ts = floor_ts(); - match selection { - NodeFrontierSelectionMode::Off => { - eprintln!( - "{ts} [affected-set] selection off — running all {total} witness(es) across {entries} entr(y/ies)" - ); - } - NodeFrontierSelectionMode::PredictOnly => { - eprintln!( - "{ts} [affected-set] predict-only — running all {total} witness(es) cold across {entries} entr(y/ies); node-frontier predictions recorded, divergences counted" - ); - } - NodeFrontierSelectionMode::Applied => { - let declared_paths = index.module_graph_facts.declared_repo_paths(); - let touched: Vec = diff_edits.touched_entry_files.iter().cloned().collect(); - let skipped = discovery_entry_fast_skip_without_resolve( - rows, - &index.module_graph_facts, - &declared_paths, - &touched, - changed_paths, - diff_edits, - ) - .map(|fast| rows.iter().filter(|r| fast.contains(&r.entry)).count()); - // The baseline is read back ONLY in the state that needs locating, so the - // ordinary path pays nothing for it. - let located = changed_paths - .is_empty() - .then(|| match floor_diff_baseline_readout() { - Ok((base, event)) => format!("baseline='{base}' event='{event}'"), - Err(e) => format!("baseline=UNREADABLE ({e})"), - }); - eprintln!( - "{ts} {}", - affected_set_applied_report_line(total, entries, skipped, located.as_deref()) - ); - } - } -} - /// The Applied-mode report, rendered purely so both of its states are assertable. /// /// Its other state — `located` is `Some` — names the case in which the observation @@ -25594,11 +24612,6 @@ fn run_discovery_rows( rows: &[DiscoveryRow], index: &MultiEntryIndex, execution_mode: v1_interpreter::ExecutionMode, - selection: NodeFrontierSelectionMode, - changed_paths: &[String], - diff_edits: &FloorDiffEdits, - floor_runner_ctx: Option<&v1_interpreter::InterpContext>, - execution_authority_is_subject: bool, whole_tree_published_keys: Option>, budgets: WitnessBudgetPolicy, style: ShardStyle, @@ -25608,8 +24621,6 @@ fn run_discovery_rows( passed: 0, skipped: 0, deferred_rows: Vec::new(), - predicted_unaffected: Vec::new(), - selection_skipped_rows: Vec::new(), divergences: Vec::new(), failures: Vec::new(), witness_outcomes: Vec::with_capacity(rows.len()), @@ -25621,27 +24632,12 @@ fn run_discovery_rows( roster_closure_nodes: 0, total_entry_groups: 0, selected_entry_groups: 0, - selection_categorization_reason: None, }; - let skip_enabled = selection != NodeFrontierSelectionMode::Off; - // This shard's SUBJECT union closure, accumulated from the graphs it resolves. An ordinary - // batch's floor-runner prefix shares that subject universe and is included; a scoped batch's - // inherited selector authority is deliberately excluded from the subject digest/clamp grain. - // Row closures fold in below as each entry resolves. + // This shard's SUBJECT union closure, accumulated from the graphs it resolves as each + // entry is loaded. It once also folded in a floor-runner prefix context, resolved before the + // roster so the affected-set machinery was available to every row; that prefix is gone with + // selection, so the closure is exactly the rows' own graphs. let mut closure_modules: HashSet = HashSet::new(); - for prefix_ctx in [floor_runner_ctx] - .into_iter() - .flatten() - .filter(|_| execution_authority_is_subject) - { - collect_typed_module_names( - prefix_ctx.modules.iter().cloned(), - &prefix_ctx.source_indices, - &mut closure_modules, - ); - } - // Existence set for the entry_file_touched refuse-vs-answer decision, built once per shard. - let module_graph_declared_paths = index.module_graph_facts.declared_repo_paths(); // Schedule-derived retention is armed by the CALLER over the WHOLE batch schedule // (Serial: the single call; Adaptive width=1: once before the entry-group loop), so a // shared module's refcount spans every entry that reaches it and it stays resident until @@ -25658,31 +24654,8 @@ fn run_discovery_rows( let mut current_entry: Option = None; let mut current_closure_subject: Option = None; let mut ctx: Option = None; - let mut current_entry_touches = true; - let mut current_entry_frontier_nodes: Vec = Vec::new(); - let mut current_entry_file_touched = true; - let mut current_entry_runtime_dependency_touched = true; - let touched_entry_paths: Vec = diff_edits.touched_entry_files.iter().cloned().collect(); let pool_roots = witness_layer_roots(); let whole_tree_published_keys = whole_tree_published_keys.map(Rc::new); - let entry_fast_skip = if selection == NodeFrontierSelectionMode::Applied { - discovery_entry_fast_skip_without_resolve( - rows, - &index.module_graph_facts, - &module_graph_declared_paths, - &touched_entry_paths, - changed_paths, - diff_edits, - )? - } else { - HashSet::new() - }; - if !entry_fast_skip.is_empty() && floor_verbose() { - eprintln!( - "run_discovery_corpus: skip-before-resolve fast path for {} entr(y/ies) (import-closure unaffected, no declaration edits, no data-item edits in closure, no host-scaffold)", - entry_fast_skip.len() - ); - } for row in rows { // Schedule-derived eviction: when the entry advances, the previous entry's // rows are all behind us (rows are sorted by entry), so its per-module state @@ -25698,78 +24671,13 @@ fn run_discovery_rows( } schedule_prev_entry = Some(row.entry.clone()); } - // Applied only: PredictOnly must resolve + run cold and record via the post-resolve - // would_skip path (falsifier semantics — docs/plans/affected-set-differential-falsifier.md). - if selection == NodeFrontierSelectionMode::Applied && entry_fast_skip.contains(&row.entry) { - refuse_reads_live_tree_selection_skip(&row, "skip-before-resolve-fast-path")?; - if current_entry.as_deref() != Some(row.entry.as_str()) { - augment_closure_modules_from_import_facts( - &index, - &row.entry, - &mut closure_modules, - )?; - current_entry = Some(row.entry.clone()); - current_entry_touches = false; - current_entry_file_touched = false; - current_entry_runtime_dependency_touched = false; - current_entry_frontier_nodes.clear(); - current_closure_subject = None; - ctx = None; - } - summary.skipped += 1; - summary - .selection_skipped_rows - .push(SelectionSkippedDiscoveryRow { - entry: row.entry.clone(), - function: row.function.clone(), - provenance: "skip-before-resolve-fast-path".to_string(), - }); - if floor_verbose() { - eprintln!( - "SKIP [assumed-green node-frontier] {} ({})", - row.function, row.entry - ); - } - continue; - } if current_entry.as_deref() != Some(row.entry.as_str()) { - if entry_eligible_for_discovery_skip_before_resolve( - skip_enabled, - row.reads_live_tree, - &row.entry, - &index.module_graph_facts, - &module_graph_declared_paths, - changed_paths, - diff_edits, - )? { - if floor_verbose() { - eprintln!( - "SKIP-RESOLVE [unaffected import-closure] {} (cold entry resolve elided)", - row.entry - ); - } - collect_import_closure_module_names_from_facts( - &index, - &row.entry, - &mut closure_modules, - )?; - ctx = None; - current_closure_subject = None; - current_entry_frontier_nodes.clear(); - current_entry_touches = false; - current_entry_file_touched = false; - current_entry_runtime_dependency_touched = false; - current_entry = Some(row.entry.clone()); - } else { + { let resolved = resolve_discovery_entry_for_corpus_row( index, &row.entry, execution_mode, whole_tree_published_keys.clone(), - skip_enabled, - diff_edits, - &touched_entry_paths, - &module_graph_declared_paths, &mut closure_modules, )?; summary.total_resolve_nanos += resolved.resolve_nanos; @@ -25781,11 +24689,6 @@ fn run_discovery_rows( stage_nanos: resolved.stage_nanos, }); current_closure_subject = Some(resolved.closure_subject); - current_entry_frontier_nodes = resolved.frontier_nodes; - current_entry_touches = resolved.touches_frontier; - current_entry_file_touched = resolved.entry_file_touched; - current_entry_runtime_dependency_touched = - resolved.entry_runtime_dependency_touched; ctx = Some(resolved.ctx); if let Some(c) = ctx.as_ref() { c.set_witness_eval_budget(budgets.cpu_eval_budget_ms); @@ -25794,89 +24697,12 @@ fn run_discovery_rows( current_entry = Some(row.entry.clone()); } } - let function_edited = skip_enabled - && diff_edits.edited_test_fns.iter().any(|(file, func)| { - diff_file_matches_entry(file, &row.entry) && func == &row.function - }); - let entry_file_touched = skip_enabled && current_entry_file_touched; - let runtime_data_dependency_touched = - skip_enabled && current_entry_runtime_dependency_touched; - let would_skip = if skip_enabled { - match floor_runner_ctx { - Some(runner_ctx) => { - let skip = call_floor_row_would_skip( - runner_ctx, - row.reads_live_tree, - changed_paths, - ¤t_entry_frontier_nodes, - current_entry_touches, - function_edited, - entry_file_touched, - runtime_data_dependency_touched, - ); - match skip { - Ok(skip) => skip, - Err(msg) => { - return Err(format!( - "floor would_skip failed for {} ({}): {msg} — declared \ - selection machinery must evaluate; no silent \ - run-everything fallback", - row.function, row.entry - )); - } - } - } - None => false, - } - } else { - false - }; - if would_skip { - refuse_reads_live_tree_selection_skip(&row, "node-frontier-selection")?; - match selection { - NodeFrontierSelectionMode::Applied => { - summary.skipped += 1; - summary - .selection_skipped_rows - .push(SelectionSkippedDiscoveryRow { - entry: row.entry.clone(), - function: row.function.clone(), - provenance: "node-frontier-selection".to_string(), - }); - if floor_verbose() { - eprintln!( - "SKIP [assumed-green node-frontier] {} ({})", - row.function, row.entry - ); - } - continue; - } - NodeFrontierSelectionMode::PredictOnly => { - // Falsifier semantics: record the prediction and run the row cold anyway. - summary - .predicted_unaffected - .push((row.entry.clone(), row.function.clone())); - if floor_verbose() { - eprintln!( - "PREDICT [unaffected node-frontier] {} ({})", - row.function, row.entry - ); - } - } - // would_skip is only computed when selection is enabled. - NodeFrontierSelectionMode::Off => {} - } - } if ctx.is_none() { let resolved = resolve_discovery_entry_for_corpus_row( index, &row.entry, execution_mode, whole_tree_published_keys.clone(), - skip_enabled, - diff_edits, - &touched_entry_paths, - &module_graph_declared_paths, &mut closure_modules, )?; summary.total_resolve_nanos += resolved.resolve_nanos; @@ -25888,10 +24714,6 @@ fn run_discovery_rows( stage_nanos: resolved.stage_nanos, }); current_closure_subject = Some(resolved.closure_subject); - current_entry_frontier_nodes = resolved.frontier_nodes; - current_entry_touches = resolved.touches_frontier; - current_entry_file_touched = resolved.entry_file_touched; - current_entry_runtime_dependency_touched = resolved.entry_runtime_dependency_touched; ctx = Some(resolved.ctx); if let Some(c) = ctx.as_ref() { c.set_witness_eval_budget(budgets.cpu_eval_budget_ms); @@ -25939,20 +24761,6 @@ fn run_discovery_rows( wall_nanos, matches!(outcome, ClaimOutcome::Pass), ); - if selection == NodeFrontierSelectionMode::PredictOnly - && would_skip - && !matches!(outcome, ClaimOutcome::Pass) - { - // The red itself already fails the batch through the failure channel below; - // this line is the ATTRIBUTION receipt — a missing selection edge, counted. - let line = format!( - "DIVERGENCE [affected-set-falsifier] {} ({}) predicted=unaffected \ - actual=red class=node-frontier", - row.function, row.entry - ); - eprintln!("{line}"); - summary.divergences.push(line); - } match outcome { ClaimOutcome::Pass => summary.passed += 1, ClaimOutcome::Fail => { @@ -30643,8 +29451,7 @@ mod discovery_summary_merge_tests { repo_relative_dag_path, run_discovery_corpus_with_options, top_n_slowest_witnesses, witness_execution_leg_cache_put, ClaimOutcome, DiscoveryCorpusOptions, DiscoveryRow, DiscoverySummary, DiscoveryWidthPolicy, DiscoveryWitnessOutcome, EntryResolveReceipt, - NodeFrontierSelectionMode, ResolveStageNanos, SelectionDegradationSnapshot, - SelectionSkippedDiscoveryRow, + ResolveStageNanos, SelectionSkippedDiscoveryRow, }; use crate::v1_interpreter::{ExecutionMode, PerformanceReceipt}; @@ -30665,8 +29472,6 @@ mod discovery_summary_merge_tests { passed: 3, skipped: 0, deferred_rows: Vec::new(), - predicted_unaffected: Vec::new(), - selection_skipped_rows: Vec::new(), divergences: Vec::new(), failures: Vec::new(), witness_outcomes: vec![ @@ -30738,7 +29543,6 @@ mod discovery_summary_merge_tests { roster_closure_nodes: 42, total_entry_groups: 2, selected_entry_groups: 2, - selection_categorization_reason: None, } } @@ -30756,93 +29560,6 @@ mod discovery_summary_merge_tests { assert_eq!(merged.roster_closure_nodes, 71); } - /// RED control: skip-before-resolve records `selection_skipped_rows` but does NOT add - /// `witness_outcomes` for those entries. `selected_entry_groups` must count executed - /// entry groups only — otherwise narrowed Applied runs mislabel as Superset. - #[test] - fn finalize_discovery_summary_selected_entry_groups_exclude_skip_before_resolve() { - let rows = vec![ - DiscoveryRow { - label: "w1".into(), - entry: "entry_a.dag".into(), - function: "f1".into(), - reads_live_tree: false, - }, - DiscoveryRow { - label: "w2".into(), - entry: "entry_b.dag".into(), - function: "f2".into(), - reads_live_tree: false, - }, - DiscoveryRow { - label: "w3".into(), - entry: "entry_c.dag".into(), - function: "f3".into(), - reads_live_tree: false, - }, - ]; - let summary = DiscoverySummary { - total: 2, - passed: 2, - skipped: 1, - deferred_rows: Vec::new(), - predicted_unaffected: Vec::new(), - selection_skipped_rows: vec![SelectionSkippedDiscoveryRow { - entry: "entry_c.dag".into(), - function: "f3".into(), - provenance: "skip-before-resolve-fast-path".into(), - }], - divergences: Vec::new(), - failures: Vec::new(), - witness_outcomes: vec![ - DiscoveryWitnessOutcome { - entry: "entry_a.dag".into(), - module_path: "test.a".into(), - function: "f1".into(), - outcome: ClaimOutcome::Pass, - execution_leg: "InterpretedLeg".into(), - }, - DiscoveryWitnessOutcome { - entry: "entry_b.dag".into(), - module_path: "test.b".into(), - function: "f2".into(), - outcome: ClaimOutcome::Pass, - execution_leg: "InterpretedLeg".into(), - }, - ], - entry_resolve_receipts: Vec::new(), - total_resolve_nanos: 0, - total_stage_nanos: ResolveStageNanos::default(), - performance_receipts: Vec::new(), - total_measured_nanos: 0, - roster_closure_nodes: 0, - total_entry_groups: 0, - selected_entry_groups: 0, - selection_categorization_reason: None, - }; - let finalized = finalize_discovery_summary( - summary, - &rows, - NodeFrontierSelectionMode::Applied, - None, - Vec::new(), - ); - assert_eq!(finalized.total_entry_groups, 3); - assert_eq!(finalized.selected_entry_groups, 2); - let snapshot = SelectionDegradationSnapshot::from_summary( - NodeFrontierSelectionMode::Applied, - &finalized, - ); - let line = - render_selection_degradation_receipt_line(&source_roots(), &snapshot).expect("receipt"); - assert!( - line.contains("selection_state=SelectionApplied"), - "skip-before-resolve must not inflate selected to total (would read Superset): {line}" - ); - assert!(line.contains("selected_entry_groups=2")); - assert!(line.contains("total_entry_groups=3")); - } - #[test] fn production_witness_cost_projection_preserves_failed_and_refused() { let mut summary = sample_summary(); @@ -30975,7 +29692,6 @@ mod discovery_summary_merge_tests { ExecutionMode::Hermetic, DiscoveryWidthPolicy::Serial, DiscoveryCorpusOptions { - node_frontier_selection: NodeFrontierSelectionMode::Off, execution_authority_source_roots: roots.clone(), explicit_roster_only: true, exclude_substrings: Vec::new(), @@ -38878,225 +37594,6 @@ mod witness_layer_roots_compile_clean_tests { }); } - /// Selection-control skip, the GREEN arm: a diff that touches nothing in the control - /// suite's closure skips. Paired with the RUN arms below — that pair is what makes - /// this a decision rather than a constant. - /// - /// The subject is ASSERTED outside the closure rather than assumed: if a new import edge - /// or declared entry ever pulls it in, this test panics instead of quietly passing for - /// the wrong reason. It is deliberately NOT a `.md` path — markdown is an input through - /// the `ReadsLiveTree` doc-reachability entry. The first draft of this test used - /// `docs/plans/example.md`, i.e. it asserted the very suppression review 44682 caught. - #[test] - fn selection_control_skip_skips_on_unrelated_path() { - const UNRELATED: &str = "src/v2/lens/machine_shape.dag"; - let closure = selection_control_input_sources(&workspace_root()) - .expect("selection-control closure must compute"); - assert!( - !closure.iter().any(|p| p == UNRELATED), - "{UNRELATED} entered the suite's input closure — choose a new skip subject; \ - do not weaken this arm to keep it green" - ); - assert!( - !UNRELATED.ends_with(".md"), - "the skip subject must not be markdown (markdown always runs the suite)" - ); - with_env_test_lock(|| { - with_workspace_cwd(|| { - let _ns = EnvGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - &format!("M\\000{UNRELATED}\\000"), - ); - assert_eq!( - selection_control_skip_label_for_ci() - .expect("structural arm must answer with a label, not refuse"), - SELECTION_CONTROL_NOT_AFFECTED_SKIP_LABEL - ); - }); - }); - } - - /// RUN arm 1 — a declared entry of the suite is touched. - #[test] - fn selection_control_skip_runs_on_declared_entry() { - with_env_test_lock(|| { - with_workspace_cwd(|| { - let _ns = EnvGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - "M\\000src/v2/workflow/affected_set_floor_runner.dag\\000", - ); - assert_eq!( - selection_control_skip_label_for_ci() - .expect("structural arm must answer with a label, not refuse"), - RUN_SELECTION_CONTROL_LABEL - ); - }); - }); - } - - /// RUN arm 2 — a TRANSITIVELY imported module, not a declared entry. This is the arm - /// that proves the import walk is load-bearing: the path is chosen from the computed - /// closure at test time, so if the walk ever stopped at the declared entries this test - /// would fail to find a subject and panic rather than silently weaken. - #[test] - fn selection_control_skip_runs_on_transitively_imported_module() { - let closure = selection_control_input_sources(&workspace_root()) - .expect("selection-control closure must compute"); - let transitive = closure - .iter() - .find(|p| !SELECTION_CONTROL_DECLARED_ENTRIES.contains(&p.as_str())) - .expect("closure must reach past the declared entries (import walk is dead)") - .clone(); - with_env_test_lock(|| { - with_workspace_cwd(|| { - let _ns = EnvGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - &format!("M\\000{transitive}\\000"), - ); - assert_eq!( - selection_control_skip_label_for_ci() - .expect("structural arm must answer with a label, not refuse"), - RUN_SELECTION_CONTROL_LABEL, - "a transitively imported closure member ({transitive}) must run the suite" - ); - }); - }); - } - - /// RUN arm 3 — the `src/v1/**` prefix: the selection implementation and the witness bin - /// live there, and neither is reachable through the `.dag` import walk. - #[test] - fn selection_control_skip_runs_on_src_v1_path() { - with_env_test_lock(|| { - with_workspace_cwd(|| { - let _ns = EnvGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - "M\\000src/v1/stage0/src/cli_run.rs\\000", - ); - assert_eq!( - selection_control_skip_label_for_ci() - .expect("structural arm must answer with a label, not refuse"), - RUN_SELECTION_CONTROL_LABEL - ); - }); - }); - } - - /// RUN arm 4 — departed path. The closure is computed from the CURRENT tree, so a - /// deletion is invisible to the intersection; the guard discriminates on D, not on - /// path. The subject is the SAME path the skip control above modifies, so the pair - /// isolates the D/M axis: modified → skip, departed → run. - #[test] - fn selection_control_skip_runs_on_departed_path() { - with_env_test_lock(|| { - with_workspace_cwd(|| { - let _ns = EnvGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - "D\\000src/v2/lens/machine_shape.dag\\000", - ); - assert_eq!( - selection_control_skip_label_for_ci() - .expect("structural arm must answer with a label, not refuse"), - RUN_SELECTION_CONTROL_LABEL - ); - }); - }); - } - - /// RUN arm 5 — a docs-only diff. THE REGRESSION CONTROL for review 44682: the suite's - /// `dag/test/claim/doc_reachability_witness_test.dag` entry declares - /// `LiveTreeDisposition = ReadsLiveTree` and folds the live markdown doc graph, and the - /// suite's own `doc_reachability_runs_on_docs_only_diff` scenario asserts the orphan wall - /// is green against the real tree. So a docs-only PR that orphans a doc flips this suite - /// red — and the first draft skipped it. Markdown is an input; it runs. - #[test] - fn selection_control_skip_runs_on_docs_only_diff() { - with_env_test_lock(|| { - with_workspace_cwd(|| { - let _ns = EnvGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - "M\\000docs/plans/example.md\\000", - ); - assert_eq!( - selection_control_skip_label_for_ci() - .expect("structural arm must answer with a label, not refuse"), - RUN_SELECTION_CONTROL_LABEL, - "a docs-only diff must RUN the control suite: its doc-reachability entry \ - reads the live doc graph, so markdown changes its verdict" - ); - }); - }); - } - - /// RUN arm 6 — a DEPARTED doc. Deletion is the direction the orphan/dangling wall is - /// most sensitive to (removing a link target creates a dangling link; removing a linker - /// orphans its target), and it is the arm the copied `!starts_with("docs/")` carve-out - /// from regen/compile-clean would have skipped. - #[test] - fn selection_control_skip_runs_on_departed_doc() { - with_env_test_lock(|| { - with_workspace_cwd(|| { - let _ns = EnvGuard::set( - "GUNBC_CI_DIFF_NAME_STATUS", - "D\\000docs/plans/example.md\\000", - ); - assert_eq!( - selection_control_skip_label_for_ci() - .expect("structural arm must answer with a label, not refuse"), - RUN_SELECTION_CONTROL_LABEL, - "a departed doc must RUN the control suite (it changes the live doc graph)" - ); - }); - }); - } - - /// REFUSAL arm — the discriminating control for review 44745. An unrecognized git - /// `--name-status` status letter makes the modeled observation answer `NameStatusDiffFail`, - /// i.e. the affected set is UNKNOWN. The step must REFUSE (typed, located, countable), not - /// widen to a run: "can't compute the affected set → rerun everything" is DESIGN §5's named - /// absorbing fallback, and `floor_diff_baseline_law` already records the 2026-07-05 ruling - /// that this arm HALTS rather than widening. - /// - /// This is the RED that would go green again if anyone reinstated the old widening arm: - /// with the fail-open version, this returned `Ok(run_selection_control)` and CI stayed green. - #[test] - fn selection_control_skip_refuses_when_diff_observation_fails() { - with_env_test_lock(|| { - with_workspace_cwd(|| { - // 'Z' is not a status letter git emits; the modeled observation rejects it. - let _ns = - EnvGuard::set("GUNBC_CI_DIFF_NAME_STATUS", "Z\\000src/v1/whatever.rs\\000"); - let refusal = selection_control_skip_label_for_ci() - .expect_err("an unobservable diff must REFUSE, never widen to a run"); - assert_eq!( - refusal.cause, - SelectionControlRefusalCause::DiffObservationFailed - ); - let d = refusal.diagnostic(); - assert!( - d.contains("SELECTION_CONTROL_REFUSED") - && d.contains("cause=DiffObservationFailed"), - "the refusal must be countable by a stable token: {d}" - ); - assert!( - !d.contains(RUN_SELECTION_CONTROL_LABEL) - && !d.contains(SELECTION_CONTROL_NOT_AFFECTED_SKIP_LABEL), - "a refusal must not carry a label — ignorance is not an answer: {d}" - ); - }); - }); - } - - /// The two refusal causes must stay distinguishable, so each is separately countable in the - /// job log. A single fused cause would re-absorb the deficits into one unprioritizable bucket. - #[test] - fn selection_control_refusal_causes_are_distinct_and_countable() { - assert_ne!( - SelectionControlRefusalCause::DiffObservationFailed.token(), - SelectionControlRefusalCause::InputClosureFailed.token() - ); - } - fn repair_receipt_touched_paths() -> Vec { vec![ "dag/extdeps/systems/nvidia.dag".to_string(), diff --git a/src/v2/compiler/self_host/frontier_probe_survey.dag b/src/v2/compiler/self_host/frontier_probe_survey.dag index 5c973c8bbb1..76062ded497 100644 --- a/src/v2/compiler/self_host/frontier_probe_survey.dag +++ b/src/v2/compiler/self_host/frontier_probe_survey.dag @@ -26,7 +26,7 @@ import v2.compiler.self_host.frontier_probe_types { frontier_probe_receipt_located_reason, frontier_probe_receipt_module_path } -import std.realization_schedule { scoped_witness_exact_head_text_holds } +import std.types { commit_sha_text_holds } import std.content_hash { ContentHash, compare_content_hash, ContentHashEqual } import v2.compiler.name_resolve { Admission } import v2.compiler.source_authority { SourceRootIngest } @@ -181,7 +181,7 @@ fn frontier_survey_probe_policy_revision_holds(revision: ContentHash) -> Bool { } fn frontier_survey_subject_well_formed_holds(subject: FrontierSurveySubject) -> Bool { - scoped_witness_exact_head_text_holds(head: subject.source_commit) + commit_sha_text_holds(head: subject.source_commit) && frontier_survey_executable_sha256_holds(digest: subject.survey_executable) && frontier_survey_source_roots_digest_holds(digest: subject.source_roots_digest) && frontier_survey_probe_policy_revision_holds(revision: subject.probe_policy_revision) diff --git a/src/v2/lens/fallback_arm_census.dag b/src/v2/lens/fallback_arm_census.dag index 2eb58e01cd7..4d556d35800 100644 --- a/src/v2/lens/fallback_arm_census.dag +++ b/src/v2/lens/fallback_arm_census.dag @@ -316,7 +316,6 @@ data fallback_arm_seed_compiled_fallback_inventory: List CiSpec { - CiSpec { - gates: concat(spec.gates, [RegenVerifyGate]), - witness_entries: spec.witness_entries, - discovery_scan_dirs: spec.discovery_scan_dirs, - diff_policy: spec.diff_policy, - notice_title: spec.notice_title, - deploy_stages: spec.deploy_stages, - } -} - -data heavy_pair_spec: CiSpec = ci_spec_with_extra_heavy_gate(spec: optin_spec) - -data zero_roster_spec: CiSpec = ci_spec_with_witness_entries( - spec: discovery_free_base_spec, - entries: [] -) - -fn runnable_function(r: Runnable) -> String { - match r { - RunnableSingleClaim { entry: _, function: f, profile: _ } => f - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => corpus_sentinel - RunnableScopedWitnessBatch { batch: _ } => "__scoped_witness_batch__" - RunnableKernelWorkload { fused_op_count: _ } => "__kernel_workload__" - } -} - -fn batch_functions(b: List) -> List { - fold(b, init: [], f: fn(acc, r) { list_snoc_item(xs: acc, item: runnable_function(r: r)) }) -} - -fn list_contains_str(xs: List, target: String) -> Bool { - fold(xs, init: false, f: fn(acc, x) { acc || (x == target) }) -} - -fn schedule_discovery_batch_count(batches: List>) -> Int { - fold(batches, init: 0, f: fn(acc, b) { - fold(b, init: acc, f: fn(inner, r) { - if runnable_function(r: r) == corpus_sentinel { inner + 1 } else { inner } - }) - }) -} - -fn batch_index_of(batches: List>, target: String) -> Int { - if length(xs: batches) == 0 { - 0 - 1 - } else if list_contains_str(xs: batch_functions(b: batches.first()), target: target) { - 0 - } else { - let rest = batch_index_of(batches: skip(xs: batches, n: 1), target: target) - if rest < 0 { rest } else { rest + 1 } - } -} - -fn witness_live_floor_discovery_tracks_optin_roster() -> Bool { - let live_count = schedule_discovery_batch_count(batches: gunbc_ci_floor_ordinary_batches()) - if length(xs: gunbc_ci_spec.witness_entries) == 0 && length(xs: gunbc_ci_spec.discovery_scan_dirs) == 0 { - live_count == 0 - } else { - live_count > 0 - } -} - -fn witness_cheap_gates_precede_compile_root() -> Bool { - let batches = gunbc_ci_floor_ordinary_batches() - let compile_idx = batch_index_of(batches: batches, target: "dag_compile_clean_gate_passes") - (compile_idx == 1) - && floor_batch_has_any_cheap_gate(batch: batches.first()) - && !list_contains_str(xs: batch_functions(b: batches.first()), target: "dag_compile_clean_gate_passes") -} - -fn witness_cheap_gate_membership_declared() -> Bool { - (length(xs: gunbc_ci_cheap_floor_gate_membership) == 5) - && gate_in_cheap_floor_membership(g: CheapClaimPoolGate) - && gate_in_cheap_floor_membership(g: ExtdepsExternalAuthorityGate) - && gate_in_cheap_floor_membership(g: GeneratedArtifactDriftGate) - && gate_in_cheap_floor_membership(g: ExtdepsScopePlacementGate) - && gate_in_cheap_floor_membership(g: ProseRowIntroductionGate) - && !gate_in_cheap_floor_membership(g: DagCompileCleanGate) -} - -fn witness_corpus_not_before_compile() -> Bool { - let batches = gunbc_ci_floor_ordinary_batches() - !list_contains_str(xs: batch_functions(b: batches.first()), target: corpus_sentinel) -} - -fn witness_independent_jobs_parallelize() -> Bool { - fold(gunbc_ci_floor_ordinary_batches().skip(n: 2), init: false, f: fn(found_parallel, batch) { - found_parallel || (length(xs: batch) > 1) - }) -} - -fn runnable_is_heavy_discovery(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - runnable_heavy_whole_tree_resolve(profile: p) - RunnableScopedWitnessBatch { batch: batch } => runnable_heavy_whole_tree_resolve(profile: batch.resource_profile.runnable) - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn batch_has_corpus_and_gate(b: List) -> Bool { - let fns = batch_functions(b: b) - let has_heavy_corpus = fold(b, init: false, f: fn(found, r) { - found || runnable_is_heavy_discovery(r: r) - }) - let has_gate = fold(fns, init: false, f: fn(found, fn_name) { - found || ((fn_name != corpus_sentinel) && (fn_name != "__gunbc_ci_floor_unmapped__")) - }) - has_heavy_corpus && has_gate -} - -fn witness_floor_discovery_flip_gates_isolated_from_corpus_for(spec: CiSpec) -> Bool { - if length(xs: spec.discovery_scan_dirs) == 0 { - true - } else { - fold(floor_schedule_for(spec: spec, serialize_heavy: true), init: true, f: fn(ok, b) { - ok && !batch_has_corpus_and_gate(b: b) - }) - } -} - -fn witness_floor_discovery_flip_gates_isolated_from_corpus() -> Bool { - witness_floor_discovery_flip_gates_isolated_from_corpus_for(spec: discovery_flip_enrolled_spec) -} - -fn witness_plan_serializes_heavy_resolves() -> Bool { - gunbc_ci_floor_plan_serializes_heavy_resolves() && - floor_plan_co_runs_heavy_without_serialization_for(spec: heavy_pair_spec) -} - -fn discovery_carries_exactly(r: Runnable, expected: ScheduleWitnessEntry) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: roots, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: scope, profile: _ } => - (length(xs: dirs) == 0) && - (length(xs: scope) == 0) && - (length(xs: entries) == 1) && - schedule_witness_entry_eq(a: entries.first(), b: expected) && - list_contains_str(xs: roots, target: witness_layer_roots.first()) - _ => false - } -} - -test fn witness_optin_corpus_carries_exactly_roster_rows() -> Bool { - discovery_carries_exactly(r: corpus_runnable_for(spec: optin_spec), expected: synthetic_corpus_row) -} - -test fn witness_optin_execution_partition() -> Bool { - discovery_carries_exactly(r: execution_corpus_runnable_for(spec: optin_spec), expected: synthetic_execution_row) -} - -test fn witness_kind_wins_over_path() -> Bool { - let spec = ci_spec_with_witness_entries( - spec: gunbc_ci_spec, - entries: [synthetic_exec_kind_nonexec_path_row] - ) - (length(xs: execution_witness_entries(spec: spec)) == 1) && - (length(xs: corpus_witness_entries(spec: spec)) == 0) && - discovery_carries_exactly( - r: execution_corpus_runnable_for(spec: spec), - expected: synthetic_exec_kind_nonexec_path_row - ) -} - -fn runnable_batch_index(batches: List>, target: Runnable) -> Int { - if length(xs: batches) == 0 { - 0 - 1 - } else { - let present = fold(batches.first(), init: false, f: fn(found, r) { - found || r == target - }) - if present { - 0 - } else { - let rest = runnable_batch_index(batches: skip(xs: batches, n: 1), target: target) - if rest < 0 { rest } else { rest + 1 } - } - } -} - -test fn witness_v1_claim_scoped_batch_is_file_grain_and_batch_owned() -> Bool { - let target = RunnableScopedWitnessBatch { batch: v1_claim_scoped_witness_batch } - (length(xs: scoped_witness_batches) == 1) - && ((v1_claim_scoped_witness_entries |> count) > 0) - && (v1_claim_scoped_witness_entries |> all(e => e.function == "")) - && (v1_claim_scoped_witness_batch.source_roots == ["dag", "src/v1"]) - && (v1_claim_scoped_witness_batch.scan_dirs == []) - && (v1_claim_scoped_witness_batch.node_frontier_selection == SelectionApplied) - && (v1_claim_scoped_witness_batch.execution_authority == InheritedWalkSourceRoots {}) - && execution_mode_eq(left: v1_claim_scoped_witness_batch.execution_mode, right: Hermetic) - && (v1_claim_scoped_witness_batch.resource_profile.process_isolation == SequentialChildProcess) - && match runnable_batch_clamp_source(r: target) { - RunnableOwnsBatchClamp { clamp: clamp } => (second_count(s: clamp.overhead) == 720) && (millisecond_count(m: clamp.per_unit) == 0) - _ => false - } - && witness_layer_roots == ["dag", "src/v2"] -} - -test fn witness_scoped_batch_is_singleton_and_outside_positional_clamps() -> Bool { - let batches = gunbc_ci_floor_ordinary_batches() - let target = RunnableScopedWitnessBatch { batch: v1_claim_scoped_witness_batch } - let v1_envelope_known_red_enrolled = v1_claim_scoped_known_red_probe_batch_enrolled() - (batch_index_of(batches: batches, target: "dag_compile_clean_gate_passes") == 1) - && (runnable_batch_index(batches: batches, target: target) >= 0) - && (v1_envelope_known_red_enrolled == (length(xs: known_red_probe_v1_envelope_roster()) > 0)) - && (!v1_envelope_known_red_enrolled || fold(batches, init: false, f: fn(found, batch) { - found || fold(batch, init: false, f: fn(inner, r) { - inner || v1_claim_scoped_known_red_probe_batch_holds(r: r) - }) - })) - && (length(xs: gunbc_ci_floor_batch_clamp_params) == length(xs: batches) - 1) -} - -fn v1_claim_scoped_known_red_probe_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: roots, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - (roots == ["dag", "src/v1"]) - && (length(xs: dirs) == 0) - && (length(xs: entries) == length(xs: known_red_probe_v1_envelope_roster())) - && (mode == SelectionApplied) - && discovery_batch_declares_hermetic(r: r) - && (p.spawns_host_compiler == false) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -test fn witness_v1_claim_scoped_known_red_probe_batch_uses_v1_roots() -> Bool { - let enrolled = v1_claim_scoped_known_red_probe_batch_enrolled() - (enrolled == (length(xs: known_red_probe_v1_envelope_roster()) > 0)) - && (!enrolled || fold(gunbc_ci_floor_ordinary_batches(), init: false, f: fn(found, batch) { - found || fold(batch, init: false, f: fn(inner, r) { - inner || v1_claim_scoped_known_red_probe_batch_holds(r: r) - }) - })) -} - -test fn scoped_witness_execution_receipt_decoder_accepts_writer_projection() -> Bool { - match scoped_witness_execution_receipt_decode(text: "head_sha\tbatch_id\tsource_roots_digest\tentry\tfunction\twitness_kind\toutcome\tdetail\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\tv1-claim-scoped-witnesses\t0123456789abcdef\tsrc/v1/tests/claim/caret_parse_smoke_test.dag\tw_caret_tokenizes_as_sh_caret\tcorpus\texecuted\ttrue\n") { - ScopedWitnessExecutionReceiptDecoded { rows: rows } => - length(xs: rows) == 1 - && match rows.first().outcome { - ScopedWitnessExecuted { ok: ok } => ok - _ => false - } - ScopedWitnessExecutionReceiptRefused { detail: _ } => false - } -} - -test fn scoped_witness_execution_receipt_decoder_refuses_empty_ledger() -> Bool { - match scoped_witness_execution_receipt_decode(text: "head_sha\tbatch_id\tsource_roots_digest\tentry\tfunction\twitness_kind\toutcome\tdetail\n") { - ScopedWitnessExecutionReceiptDecoded { rows: _ } => false - ScopedWitnessExecutionReceiptRefused { detail: detail } => detail != "" - } -} - -test fn scoped_witness_execution_receipt_decoder_preserves_selection_skip_provenance() -> Bool { - match scoped_witness_execution_receipt_decode(text: "head_sha\tbatch_id\tsource_roots_digest\tentry\tfunction\twitness_kind\toutcome\tdetail\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\tv1-claim-scoped-witnesses\t0123456789abcdef\tsrc/v1/tests/claim/caret_parse_smoke_test.dag\tw_caret_tokenizes_as_sh_caret\tcorpus\tselection-skipped\tskip-before-resolve-fast-path\n") { - ScopedWitnessExecutionReceiptDecoded { rows: rows } => - length(xs: rows) == 1 - && match rows.first().outcome { - ScopedWitnessSelectionSkipped { provenance: provenance } => provenance == "skip-before-resolve-fast-path" - _ => false - } - ScopedWitnessExecutionReceiptRefused { detail: _ } => false - } -} - -test fn scoped_witness_execution_receipt_decoder_refuses_sha1_digest_family() -> Bool { - match scoped_witness_execution_receipt_decode(text: "head_sha\tbatch_id\tsource_roots_digest\tentry\tfunction\twitness_kind\toutcome\tdetail\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\tv1-claim-scoped-witnesses\t0123456789abcdef0123456789abcdef01234567\tsrc/v1/tests/claim/caret_parse_smoke_test.dag\tw_caret_tokenizes_as_sh_caret\tcorpus\texecuted\ttrue\n") { - ScopedWitnessExecutionReceiptDecoded { rows: _ } => false - ScopedWitnessExecutionReceiptRefused { detail: detail } => detail != "" - } -} - -test fn scoped_witness_execution_receipt_decoder_refuses_sha256_digest_family() -> Bool { - match scoped_witness_execution_receipt_decode(text: "head_sha\tbatch_id\tsource_roots_digest\tentry\tfunction\twitness_kind\toutcome\tdetail\naaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\tv1-claim-scoped-witnesses\t0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\tsrc/v1/tests/claim/caret_parse_smoke_test.dag\tw_caret_tokenizes_as_sh_caret\tcorpus\texecuted\ttrue\n") { - ScopedWitnessExecutionReceiptDecoded { rows: _ } => false - ScopedWitnessExecutionReceiptRefused { detail: detail } => detail != "" - } -} - -test fn floor_worker_observation_outcome_is_derived_from_evidence() -> Bool { - let completed = FloorWorkerObservation { - worker: OrdinaryFloorWorker, - termination: ProcessExited { code: 0 }, - terminal_receipt: FloorWorkerTerminalReceiptObserved { - report: FloorWorkerReportedCompleted { detail: "walk terminal exit code 0" } - }, - } - let contradicted = FloorWorkerObservation { - worker: OrdinaryFloorWorker, - termination: ProcessSignaled { signal: 9 }, - terminal_receipt: FloorWorkerTerminalReceiptObserved { - report: FloorWorkerReportedCompleted { detail: "walk terminal exit code 0" } - }, - } - match floor_worker_observation_outcome(observation: completed) { - FloorWorkerCompleted => match floor_worker_observation_outcome(observation: contradicted) { - FloorWorkerFailed { detail: detail } => detail != "" - _ => false - } - _ => false - } -} - -test fn witness_optin_roster_drives_corpus_presence() -> Bool { - (schedule_discovery_batch_count(batches: floor_schedule_for(spec: zero_roster_spec, serialize_heavy: true)) == 0) && - (schedule_discovery_batch_count(batches: floor_schedule_for(spec: corpus_only_spec, serialize_heavy: true)) == 1) && - (schedule_discovery_batch_count(batches: floor_schedule_for(spec: optin_spec, serialize_heavy: true)) == 2) -} - -test fn witness_optin_plan_gates_corpus_after_compile() -> Bool { - let batches = floor_schedule_for(spec: optin_spec, serialize_heavy: true) - !list_contains_str(xs: batch_functions(b: batches.first()), target: corpus_sentinel) && - (batch_index_of(batches: batches, target: "dag_compile_clean_gate_passes") == 1) && - (batch_index_of(batches: batches, target: corpus_sentinel) >= 2) -} - -data source_ingest_ordering_spec_note: String = "SourceRootIngestGate left the per-PR floor for the falsifier cadence on 2026-07-26 (gunbc.commit_workflow gate_gauntlet_flip_basis_note), so optin_spec — which derives its gates from the LIVE roster — no longer carries it and this ordering claim went unsatisfiable. The property under witness is the SCHEDULER's behaviour (a source-root-ingest runnable is serialized after the corpus batches), which is a fact about the planner and must stay pinned no matter which lane the live roster currently routes that gate through. So the spec is made synthetic here, exactly as heavy_pair_spec_note does for the deleted EmitDeterminismGate: re-add the gate to a local spec and assert the ordering against it. DELETING THIS WITNESS WAS THE ALTERNATIVE AND IT IS THE WRONG ONE — a scheduler ordering rule would then have no executing consumer at all, and the flip would have quietly bought a coverage loss in the planner that has nothing to do with where the gate runs. Re-pointing at a synthetic spec preserves the claim; dropping it would be the narrowing this file's own substrate_long_lane_is_a_sibling_cadence_note warns against." - -fn ci_spec_with_source_ingest_gate(spec: CiSpec) -> CiSpec { - CiSpec { - gates: concat(spec.gates, [SourceRootIngestGate]), - witness_entries: spec.witness_entries, - discovery_scan_dirs: spec.discovery_scan_dirs, - diff_policy: spec.diff_policy, - notice_title: spec.notice_title, - deploy_stages: spec.deploy_stages, - } -} - -data source_ingest_ordering_spec: CiSpec = ci_spec_with_source_ingest_gate(spec: optin_spec) - -test fn witness_optin_source_ingest_serialized_after_corpus() -> Bool { - let batches = floor_schedule_for(spec: source_ingest_ordering_spec, serialize_heavy: true) - let corpus_idx = batch_index_of(batches: batches, target: corpus_sentinel) - let ingest_idx = batch_index_of(batches: batches, target: "source_root_ingest_gate_passes") - (corpus_idx >= 1) && (ingest_idx > corpus_idx) -} - -test fn witness_optin_exclusion_edges_track_roster() -> Bool { - witness_floor_corpus_exclusion_edges_exist(spec: optin_spec) && - (length(xs: floor_corpus_exclusion_resource_edges(spec: zero_roster_spec)) == 0) && - witness_floor_no_corpus_resource_edge_to_compile_anchor(spec: optin_spec) -} - -test fn witness_optin_plan_serializes_heavy_resolves() -> Bool { - floor_plan_serializes_heavy_resolves_for(spec: heavy_pair_spec) && - floor_plan_co_runs_heavy_without_serialization_for(spec: heavy_pair_spec) -} - -fn batch_has_both_emit_and_corpus(b: List) -> Bool { - let fns = batch_functions(b: b) - list_contains_str(xs: fns, target: "emit_host_gate_passes") && - list_contains_str(xs: fns, target: corpus_sentinel) -} - -test fn witness_optin_emit_host_isolated_from_corpus() -> Bool { - fold(floor_schedule_for(spec: optin_spec, serialize_heavy: true), init: true, f: fn(ok, b) { - ok && !batch_has_both_emit_and_corpus(b: b) - }) -} - -test fn witness_optin_emit_host_co_runs_corpus_without_serialization() -> Bool { - fold(floor_schedule_for(spec: optin_spec, serialize_heavy: false), init: false, f: fn(found, b) { - found || batch_has_both_emit_and_corpus(b: b) - }) -} - -fn discovery_batch_declares_hermetic(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - execution_mode_eq(left: p.execution_mode, right: Hermetic) - RunnableScopedWitnessBatch { batch: batch } => execution_mode_eq(left: batch.execution_mode, right: Hermetic) - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn witness_hermetic_floor_posture_declared() -> Bool { - discovery_batch_declares_hermetic(r: corpus_runnable_for(spec: gunbc_ci_spec)) - && !discovery_batch_declares_hermetic(r: execution_corpus_runnable_for(spec: gunbc_ci_spec)) - && discovery_batch_declares_hermetic(r: gunbc_falsifier_ordinary_batches().first().first()) -} - -fn discovery_batch_selection_is(r: Runnable, expected: NodeFrontierSelection) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => - node_frontier_selection_eq(left: mode, right: expected) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -// The three ordinary merge-critical witness batches run their whole roster. Pinned -// positively (each is SelectionOff) AND negatively (none is SelectionApplied), because a -// three-valued field makes "not applied" and "off" different claims: a drift to -// SelectionPredictOnly would satisfy the negative half alone while quietly restoring a -// mechanism the flip exists to stop consuming. -test fn witness_ordinary_floor_batches_run_the_whole_roster() -> Bool { - discovery_batch_selection_is(r: corpus_runnable_for(spec: gunbc_ci_spec), expected: SelectionOff) - && discovery_batch_selection_is(r: execution_corpus_runnable_for(spec: gunbc_ci_spec), expected: SelectionOff) - && discovery_batch_selection_is(r: bin_witness_corpus_runnable_for(), expected: SelectionOff) - && !discovery_batch_selection_is(r: corpus_runnable_for(spec: gunbc_ci_spec), expected: SelectionApplied) - && !discovery_batch_selection_is(r: execution_corpus_runnable_for(spec: gunbc_ci_spec), expected: SelectionApplied) - && !discovery_batch_selection_is(r: bin_witness_corpus_runnable_for(), expected: SelectionApplied) -} - -// The declared scope boundary of the flip, asserted rather than described: the falsifier's -// cold control still carries its predict-only arm, and the v1 scoped batch still selects. -// If a later change widens the flip to either, this reds and the widening becomes a -// decision instead of a side effect. -test fn witness_selection_flip_scope_is_exactly_the_ordinary_corpus() -> Bool { - (v1_claim_scoped_witness_batch.node_frontier_selection == SelectionApplied) - && discovery_batch_selection_is( - r: gunbc_falsifier_ordinary_batches().first().first(), - expected: SelectionPredictOnly - ) -} - -test fn witness_emit_host_profile_forbids_corpus_co_residence() -> Bool { - runnable_forbids_corpus_co_residence(r: gate_runnable(g: EmitHostGate)) -} - -test fn witness_light_gate_profile_allows_corpus_co_residence() -> Bool { - !runnable_forbids_corpus_co_residence(r: gate_runnable(g: ExtdepsExternalAuthorityGate)) -} - -fn falsifier_batch_selection(mode: NodeFrontierSelection) -> Bool { - match mode { - SelectionPredictOnly => true - SelectionApplied => false - SelectionOff => false - } -} - -fn discovery_batch_declares_wet(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - execution_mode_eq(left: p.execution_mode, right: Wet) - RunnableScopedWitnessBatch { batch: batch } => execution_mode_eq(left: batch.execution_mode, right: Wet) - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn falsifier_predict_only_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - falsifier_batch_selection(mode: mode) - && (length(xs: entries) == 0) - && (length(xs: dirs) == 3) - && execution_mode_eq(left: p.execution_mode, right: Hermetic) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn falsifier_self_host_wet_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - match mode { - SelectionApplied => true - SelectionPredictOnly => false - SelectionOff => false - } - && (length(xs: dirs) == 0) - && (length(xs: entries) == length(xs: falsifier_self_host_wet_entries())) - && discovery_batch_declares_wet(r: r) - && p.spawns_host_compiler - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -data known_red_probe_lane_partition_witness_note: String = "The known-red probe lane carries ONE runnable PER (EXPECTATION KIND, DECLARED BUDGET) PAIR — at most four, never one runnable holding the whole roster. BUDGET because eval ceilings are scoped per batch, so a mixed batch could only obtain the long ceiling by widening every fast sibling with it. EXPECTATION KIND because a pre-verdict row stops the batch at RESOLVE before any witness produces an outcome, and that stop is admitted only when EVERY entry declared a pre-verdict refusal — so one such row mixed in with assertion-false rows reds siblings that were holding quarantine correctly (cursor review 50216). Both are the same axis conflation, one layer apart. What is pinned: the runnable count equals the number of NONEMPTY derived rosters, the batches match those rosters IN ORDER and each equals its roster as a SET (known_red_roster_set_eq — duplicate-free both sides, containment both ways), every runnable independently keeps the lane hermetic/no-host-compiler/SelectionApplied profile, and the union of all scheduled entries set-equals the whole corpus roster so the four-way split can neither drop a row nor double-count one. Pinning only the total would let rosters be swapped between runnables; pinning only the count would let either carry the wrong rows." - -data known_red_roster_set_eq_note: String = "SET equality, and the two-way half of it is load-bearing (defect found in review, 2026-08-07). The first shape of this witness asserted length agreement PLUS one-way containment (every actual entry appears in the expected roster), and called that an identity join. It is not: actual [A, A] against expected [A, B] satisfies both — the lengths agree at 2 and every actual entry is present — while B is DROPPED and A is DUPLICATED. So a same-sized wrong population passed, which is precisely the property the note claimed to establish and the PR's whole thesis (identity agreement replacing count agreement). The repair asserts duplicate-freedom on BOTH sides and containment in BOTH directions, which for rosters that are identity sets is set equality. Why one-way containment looked sufficient: the swap probe that verified this witness exchanges the two rosters, and one-way containment DOES catch that, because a fast entry is genuinely absent from the long roster. Multiplicity is an orthogonal axis the swap never perturbs — evidence that a clause is non-vacuous is not evidence that it is exact, and one discriminating RED can only establish the failure mode it actually drives." - -fn known_red_roster_occurrence_count(xs: List, w: ScheduleWitnessEntry) -> Int { - fold(xs, init: 0, f: fn(acc, x) { - if schedule_witness_entry_eq(a: x, b: w) { acc + 1 } else { acc } - }) -} - -fn known_red_roster_duplicate_free(xs: List) -> Bool { - fold(xs, init: true, f: fn(ok, x) { - ok && (known_red_roster_occurrence_count(xs: xs, w: x) == 1) - }) -} - -fn known_red_roster_subset(a: List, b: List) -> Bool { - fold(a, init: true, f: fn(ok, x) { - ok && schedule_witness_entry_roster_contains(xs: b, w: x) - }) -} - -fn known_red_roster_set_eq(a: List, b: List) -> Bool { - known_red_roster_duplicate_free(xs: a) - && known_red_roster_duplicate_free(xs: b) - && known_red_roster_subset(a: a, b: b) - && known_red_roster_subset(a: b, b: a) -} - -test fn witness_known_red_roster_set_eq_is_exact_not_a_length_agreement() -> Bool { - let a = synthetic_corpus_row - let b = synthetic_execution_row - known_red_roster_set_eq(a: [a, b], b: [a, b]) - && known_red_roster_set_eq(a: [a, b], b: [b, a]) - && !known_red_roster_set_eq(a: [a, a], b: [a, b]) - && !known_red_roster_set_eq(a: [a, b], b: [a, a]) - && !known_red_roster_set_eq(a: [a], b: [a, b]) - && !known_red_roster_set_eq(a: [a, b], b: [a]) -} - -fn known_red_probe_batch_matches_roster(r: Runnable, roster: List) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - match mode { - SelectionApplied => true - SelectionPredictOnly => false - SelectionOff => false - } - && (length(xs: dirs) == 0) - && known_red_roster_set_eq(a: entries, b: roster) - && discovery_batch_declares_hermetic(r: r) - && (p.spawns_host_compiler == false) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn known_red_expected_batch_rosters() -> List> { - fold( - [ - known_red_probe_corpus_fast_budget_roster(), - known_red_probe_corpus_long_budget_roster(), - known_red_probe_corpus_pre_verdict_fast_budget_roster(), - known_red_probe_corpus_pre_verdict_long_budget_roster() - ], - init: [], - f: fn(acc, roster) { - if length(xs: roster) > 0 { list_snoc_item(xs: acc, item: roster) } else { acc } - } - ) -} - -fn known_red_batches_match_rosters_pairwise(b: List, rosters: List>) -> Bool { - let checked = fold(rosters, init: { ok: true, at: 0 }, f: fn(acc, roster) { - let remaining = skip(xs: b, n: acc.at) - let matched = if length(xs: remaining) > 0 { - known_red_probe_batch_matches_roster(r: remaining.first(), roster: roster) - } else { - false - } - { ok: acc.ok && matched, at: acc.at + 1 } - }) - checked.ok && (checked.at == length(xs: b)) -} - -fn known_red_all_scheduled_entries() -> List { - fold(known_red_expected_batch_rosters(), init: [], f: fn(acc, roster) { concat(acc, roster) }) -} - -fn falsifier_known_red_probe_batches_hold(b: List) -> Bool { - let rosters = known_red_expected_batch_rosters() - let count_ok = length(xs: b) == length(xs: rosters) - let pairwise_ok = known_red_batches_match_rosters_pairwise(b: b, rosters: rosters) - let covers_lane = known_red_roster_set_eq( - a: known_red_all_scheduled_entries(), - b: known_red_probe_corpus_roster() - ) - count_ok && pairwise_ok && covers_lane -} - -fn falsifier_self_host_wet_known_red_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - match mode { - SelectionApplied => true - SelectionPredictOnly => false - SelectionOff => false - } - && (length(xs: dirs) == 0) - && (length(xs: entries) == length(xs: falsifier_self_host_wet_known_red_entries)) - && discovery_batch_declares_wet(r: r) - && p.spawns_host_compiler - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn falsifier_silent_pick_gate_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - match mode { - SelectionApplied => true - SelectionPredictOnly => false - SelectionOff => false - } - && (length(xs: dirs) == 0) - && (length(xs: entries) == length(xs: falsifier_silent_pick_gate_entries)) - && discovery_batch_declares_wet(r: r) - && p.spawns_host_compiler - && p.heavy_whole_tree_resolve - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn falsifier_substrate_long_lane_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - match mode { - SelectionApplied => true - SelectionPredictOnly => false - SelectionOff => false - } - && (length(xs: dirs) == 0) - && (length(xs: entries) == length(xs: falsifier_substrate_long_lane_entries())) - && discovery_batch_declares_hermetic(r: r) - && (p.spawns_host_compiler == false) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn falsifier_self_host_wet_budget_declared_holds() -> Bool { - gunbc_falsifier_self_host_wet_receipt_wall_budget_ms() == 600000 - && gunbc_falsifier_self_host_wet_interp_eval_budget_ms() == 120000 - && gunbc_falsifier_silent_pick_gate_receipt_wall_budget_ms() == 900000 - && gunbc_ci_fast_lane_eval_budget_ms() == 5000 - && gunbc_falsifier_substrate_long_lane_eval_budget_ms() == 180000 -} - -fn falsifier_substrate_long_lane_budget_exceeds_fast_lane_holds() -> Bool { - gunbc_falsifier_substrate_long_lane_eval_budget_ms() > gunbc_ci_fast_lane_eval_budget_ms() -} - -fn falsifier_cadence_witness_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: p } => - match mode { - SelectionApplied => true - SelectionPredictOnly => false - SelectionOff => false - } - && (length(xs: dirs) == 0) - && (length(xs: entries) == length(xs: falsifier_cadence_witness_entries())) - && discovery_batch_declares_wet(r: r) - && p.spawns_host_compiler - && (p.heavy_whole_tree_resolve == false) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn falsifier_plan_structure_holds() -> Bool { - let batches = gunbc_falsifier_ordinary_batches() - let predict_ok = (batches.first().length() == 1) - && falsifier_predict_only_batch_holds(r: batches.first().first()) - let wet_enrolled = falsifier_self_host_wet_batch_enrolled() - let wet_known_red_enrolled = falsifier_self_host_wet_known_red_batch_enrolled() - let probe_enrolled = falsifier_known_red_probe_batch_enrolled() - let silent_pick_gate_enrolled = falsifier_silent_pick_gate_batch_enrolled() - let rehomed_enrolled = falsifier_rehomed_bin_wet_batch_enrolled() - let substrate_long_enrolled = falsifier_substrate_long_lane_batch_enrolled() - let cadence_enrolled = falsifier_cadence_witness_batch_enrolled() - let gate_enrolled = falsifier_gate_batch_enrolled() - let expected_batches = 1 + (if wet_enrolled { 1 } else { 0 }) + (if wet_known_red_enrolled { 1 } else { 0 }) + (if probe_enrolled { 1 } else { 0 }) + (if silent_pick_gate_enrolled { 1 } else { 0 }) + (if rehomed_enrolled { 1 } else { 0 }) + (if substrate_long_enrolled { 1 } else { 0 }) + (if cadence_enrolled { 1 } else { 0 }) + (if gate_enrolled { 1 } else { 0 }) - let wet_ok = if wet_enrolled { - let wet_batch = skip(xs: batches, n: 1).first() - (wet_batch.length() == 1) - && falsifier_self_host_wet_batch_holds(r: wet_batch.first()) - } else { - true - } - let wet_known_red_ok = if wet_known_red_enrolled { - let wet_known_red_offset = 1 + (if wet_enrolled { 1 } else { 0 }) - let wet_known_red_batch = skip(xs: batches, n: wet_known_red_offset).first() - (wet_known_red_batch.length() == 1) - && falsifier_self_host_wet_known_red_batch_holds(r: wet_known_red_batch.first()) - } else { - true - } - let probe_ok = if probe_enrolled { - let probe_offset = 1 + (if wet_enrolled { 1 } else { 0 }) + (if wet_known_red_enrolled { 1 } else { 0 }) - let probe_batch = skip(xs: batches, n: probe_offset).first() - falsifier_known_red_probe_batches_hold(b: probe_batch) - } else { - true - } - let silent_pick_gate_ok = if silent_pick_gate_enrolled { - let silent_pick_gate_offset = 1 + (if wet_enrolled { 1 } else { 0 }) + (if wet_known_red_enrolled { 1 } else { 0 }) + (if probe_enrolled { 1 } else { 0 }) - let silent_pick_gate_batch = skip(xs: batches, n: silent_pick_gate_offset).first() - (silent_pick_gate_batch.length() == 1) - && falsifier_silent_pick_gate_batch_holds(r: silent_pick_gate_batch.first()) - } else { - true - } - let rehomed_ok = if rehomed_enrolled { - let rehomed_offset = 1 + (if wet_enrolled { 1 } else { 0 }) + (if wet_known_red_enrolled { 1 } else { 0 }) + (if probe_enrolled { 1 } else { 0 }) + (if silent_pick_gate_enrolled { 1 } else { 0 }) - let rehomed_batch = skip(xs: batches, n: rehomed_offset).first() - (rehomed_batch.length() == 1) - } else { - true - } - let substrate_long_ok = if substrate_long_enrolled { - let substrate_long_offset = 1 + (if wet_enrolled { 1 } else { 0 }) + (if wet_known_red_enrolled { 1 } else { 0 }) + (if probe_enrolled { 1 } else { 0 }) + (if silent_pick_gate_enrolled { 1 } else { 0 }) + (if rehomed_enrolled { 1 } else { 0 }) - let substrate_long_batch = skip(xs: batches, n: substrate_long_offset).first() - (substrate_long_batch.length() == 1) - && falsifier_substrate_long_lane_batch_holds(r: substrate_long_batch.first()) - } else { - true - } - let cadence_ok = if cadence_enrolled { - let cadence_offset = 1 + (if wet_enrolled { 1 } else { 0 }) + (if wet_known_red_enrolled { 1 } else { 0 }) + (if probe_enrolled { 1 } else { 0 }) + (if silent_pick_gate_enrolled { 1 } else { 0 }) + (if rehomed_enrolled { 1 } else { 0 }) + (if substrate_long_enrolled { 1 } else { 0 }) - let cadence_batch = skip(xs: batches, n: cadence_offset).first() - (cadence_batch.length() == 1) - && falsifier_cadence_witness_batch_holds(r: cadence_batch.first()) - } else { - true - } - let gate_ok = if gate_enrolled { - let gate_offset = 1 + (if wet_enrolled { 1 } else { 0 }) + (if wet_known_red_enrolled { 1 } else { 0 }) + (if probe_enrolled { 1 } else { 0 }) + (if silent_pick_gate_enrolled { 1 } else { 0 }) + (if rehomed_enrolled { 1 } else { 0 }) + (if substrate_long_enrolled { 1 } else { 0 }) + (if cadence_enrolled { 1 } else { 0 }) - let gate_batch = skip(xs: batches, n: gate_offset).first() - falsifier_gate_batch_carries_the_flipped_gates(batch: gate_batch) - } else { - true - } - (length(xs: batches) == expected_batches) && predict_ok && wet_ok && wet_known_red_ok && probe_ok && silent_pick_gate_ok && rehomed_ok && substrate_long_ok && cadence_ok && gate_ok -} - -data falsifier_gate_batch_pin_note: String = "This pin names the two flipped gates by their RUNNABLE FUNCTION rather than asserting a batch length, and the difference is the whole point. A length check (`gate_batch.length() == length(falsifier_gate_runnables())`) is tautological — both sides read the same projection, so it passes for an empty batch, a batch of the wrong gates, or a batch built from a broken projector. The claim worth making is the one the flip is actually asserting: source_root_ingest and self_host_realized_comparison LEFT the per-PR floor and ARRIVED here, executing. Naming them means a future de-enrollment that empties the lane reds on this pin rather than silently satisfying it, which is the same failure the gate-half wall exists to catch, read one layer down at the batch instead of the roster." - -fn falsifier_gate_batch_carries_the_flipped_gates(batch: List) -> Bool { - let fns = batch_functions(b: batch) - list_contains_str(xs: fns, target: "source_root_ingest_gate_passes") - && list_contains_str(xs: fns, target: "self_host_realized_comparison_reads_real_bytes_gate_holds") -} - -fn witness_cheap_gates_are_resource_anchors() -> Bool { - gate_in_cheap_floor_membership(g: ExtdepsExternalAuthorityGate) - && floor_resource_anchor_node(node: gate_node(g: ExtdepsExternalAuthorityGate)) -} - -fn bin_witness_wet_batch_holds(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: entries, node_frontier_selection: mode, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => - match mode { - SelectionApplied => false - SelectionPredictOnly => false - SelectionOff => true - } - && (length(xs: dirs) == 0) - && (length(xs: entries) == length(xs: bin_witness_wet_entries)) - && discovery_batch_declares_wet(r: r) - RunnableScopedWitnessBatch { batch: _ } => false - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -test fn witness_live_floor_schedules_bin_witness_wet_batch() -> Bool { - let enrolled = bin_witness_corpus_enrolled(spec: gunbc_ci_spec) - (!enrolled || fold(gunbc_ci_floor_ordinary_batches(), init: false, f: fn(found, batch) { - found || fold(batch, init: false, f: fn(inner, r) { inner || bin_witness_wet_batch_holds(r: r) }) - })) -} - -test fn witness_live_floor_discovery_batch_count_includes_wet_lanes() -> Bool { - if bin_witness_corpus_enrolled(spec: gunbc_ci_spec) { - schedule_discovery_batch_count(batches: gunbc_ci_floor_ordinary_batches()) >= 3 - } else { - true - } -} - -test fn witness_live_floor_discovery_batch_count_is_four() -> Bool { - schedule_discovery_batch_count(batches: gunbc_ci_floor_ordinary_batches()) == 4 -} - -test fn ci_floor_plan_witnesses() -> Bool { - witness_known_red_roster_set_eq_is_exact_not_a_length_agreement() && - witness_floor_compile_gate_honest_heavy_profile() && - witness_cheap_gate_membership_declared() && - witness_cheap_gates_are_resource_anchors() && - witness_live_floor_discovery_tracks_optin_roster() && - witness_cheap_gates_precede_compile_root() && - witness_cheap_gates_precede_all_corpus_batches() && - witness_floor_schedule_preserves_enrolled_set() && - witness_live_floor_schedules_bin_witness_wet_batch() && - witness_live_floor_discovery_batch_count_includes_wet_lanes() && - witness_live_floor_discovery_batch_count_is_four() && - witness_non_cheap_gate_absent_from_early_batch() && - witness_floor_stop_policy_pr_is_fail_fast() && - witness_floor_stop_policy_push_is_full_ledger() && - witness_floor_stop_policy_unknown_defaults_full_ledger() && - witness_floor_batch_stop_policy_plan_roster_enrolled() && - gunbc_ci_floor_schedule_lens_holds() && - witness_merge_admission_capture_is_typed_pre_walk_subprocess() && - witness_corpus_not_before_compile() && - witness_independent_jobs_parallelize() && - witness_plan_serializes_heavy_resolves() - && falsifier_plan_structure_holds() - && falsifier_self_host_wet_budget_declared_holds() - && witness_hermetic_floor_posture_declared() - && witness_floor_arm_time_budget_refusal_plan_roster_authority() - && witness_floor_arm_time_budget_refusal_materialized_roster_matches_seed() - && witness_floor_batch_clamp_params_cover_schedule() - && witness_floor_batch_clamp_overhead_all_positive() - && witness_floor_batch_clamp_rate_all_nonneg() - && falsifier_rehomed_bin_wet_batch_enrolled() - && falsifier_substrate_long_lane_batch_enrolled() - && falsifier_substrate_long_lane_budget_exceeds_fast_lane_holds() -} - -test fn ci_corpus_discovery_flip_witnesses() -> Bool { - witness_ci_corpus_discovery_is_live() - && witness_ci_corpus_discovery_flip_authored() - && witness_floor_discovery_flip_serializes_gates_after_corpus(spec: gunbc_ci_spec) - && witness_floor_discovery_flip_no_corpus_edge_to_compile_anchor(spec: gunbc_ci_spec) - && witness_floor_discovery_flip_gates_isolated_from_corpus() - && witness_regen_spec_carries_no_witness_corpus() - && schedule_discovery_batch_count(batches: floor_schedule_for(spec: zero_roster_spec, serialize_heavy: true)) == 0 -} - -data floor_finalization_witness_note: String = "THESE ROWS ARE THE ENFORCEMENT, and that is a correction to what was expected. The review that asked for finalization witnesses expected the parameterized WalkPlan to do the work by construction — the floor's return type rejecting the empty policy — leaving these rows as secondary evidence. Probed by execution: it does not. Substituting NoFinalizationDeclared \{\} into gunbc_ci_floor_plan while its signature still reads WalkPlan typechecks and fails only at the first field access, because the typechecker does not check a declared return type against the body (a narrower probe: `fn f() -> Int \{ \"not an int\" \}` also typechecks, while argument position IS checked). So the signature declares intent and the row below is what actually refuses. std.realization_schedule walk_finalization_note carries the finding and its dissolve-on. - -ONE property is genuinely not witnessable: materialization disclosure is intrinsic to FloorFinalization, so there is no Bool to assert. - -The three no-finalization rows below WERE briefly omitted as tautologies, and that reasoning was wrong (review 2026-07-30, corrected). It assumed the declared return type bounds the runtime value. The probe above shows it does not: a function declared `-> WalkPlan` can return a record carrying FloorFinalization, and a caller reading the signature would never know. Matching the ACTUAL value is therefore load-bearing, not a match over a one-inhabitant type — the inhabitant set at runtime is not one. Their mutation control is to substitute FloorFinalization into each body while leaving the signature unchanged; each corresponding row must red. - -What IS falsifiable is WHICH obligation population the floor projects: any List typechecks, so the row below asserts it projects the single authority gunbc.ci_materialization.ci_floor_expected_resolve_obligations(), and the RED control drops one obligation and proves the same predicate refuses. Both execute." - -fn floor_plan_obligation_count() -> Int { - length(xs: gunbc_ci_floor_plan().finalization.expected_resolve_obligations) -} - -fn plan_transports_authority_obligations(p: WalkPlan) -> Bool { - p.finalization.expected_resolve_obligations == ci_floor_expected_resolve_obligations() -} - -fn anchor_only_obligations() -> List { - [expected_obligation(id: CompileAnchorWholeTree)] -} - -fn forked_obligation_floor_plan() -> WalkPlan { - WalkPlan { - pre_walk_execution: NoPreWalkExecution {}, - batches: gunbc_ci_floor_ordinary_batches(), - finalization: FloorFinalization { - expected_resolve_obligations: anchor_only_obligations(), - }, - on_success_stages: [], - ordinary_budget: none, - on_success_budget: none, - } -} - -test fn floor_plan_projects_the_declared_obligation_authority() -> Bool { - plan_transports_authority_obligations(p: gunbc_ci_floor_plan()) - && floor_plan_obligation_count() == ci_floor_expected_resolve_obligation_count() -} - -test fn floor_plan_carries_disjoint_ordinary_and_postcondition_budgets() -> Bool { - let plan = gunbc_ci_floor_plan() - match plan.ordinary_budget { - Absent => false - Present { value: ordinary } => - match plan.on_success_budget { - Absent => false - Present { value: postcondition } => - (millisecond_count(m: ordinary) == minute_count(m: gunbc_ci_ordinary_floor_budget_minutes) * 60000) - && (millisecond_count(m: postcondition) == minute_count(m: gunbc_ci_admission_postcondition_budget_minutes) * 60000) - && (millisecond_count(m: ordinary) + millisecond_count(m: postcondition) == 85 * 60000) - } - } -} - -test fn forked_obligation_population_is_refused_by_the_same_predicate() -> Bool { - !plan_transports_authority_obligations(p: forked_obligation_floor_plan()) -} - -fn plan_carries_no_finalization(plan: WalkPlan) -> Bool { - match plan.finalization { - NoFinalizationDeclared => true - _ => false - } -} - -test fn regen_plan_carries_no_finalization() -> Bool { - plan_carries_no_finalization(plan: gunbc_ci_regen_floor_plan()) -} - -test fn plan_artifact_plan_carries_no_finalization() -> Bool { - plan_carries_no_finalization(plan: gunbc_ci_plan_artifact_plan()) -} - -test fn falsifier_plan_carries_no_finalization() -> Bool { - plan_carries_no_finalization(plan: gunbc_falsifier_plan()) -} - -data falsifier_native_cache_cold_plan_row_note: String = "The FIFTH plan function, absent from this roster until 2026-08-01 — and its absence is the point. walk_plan_uniformity_note names these rows as the enforcement for the WalkPlan shape precisely because the typechecker does not check a declared return type against a body, so a plan function missing from THIS roster has no enforcement at all. gunbc_falsifier_native_cache_cold_plan was missed by the #7470 rename, kept returning a bare List>, and the executor's strict parser refused it on all 8 falsifier runs that reached the native-cache cold control step. Nothing here could red on that, because the roster counted four." - -test fn falsifier_native_cache_cold_plan_carries_no_finalization() -> Bool { - plan_carries_no_finalization(plan: gunbc_falsifier_native_cache_cold_plan()) -} - -data plan_roster_exhaustiveness_note: String = "WHAT THIS ROW ENFORCES, AND WHAT IT DOES NOT — the second half corrected after review 46883 caught this note claiming a guarantee it does not deliver, which is the rung-inflation failure DESIGN 4b names and is worth more than a quiet edit because the overclaim repeated the very completeness failure this change exists to remove.\n\nWHAT IS ENFORCED. plan_variant_is_walk_plan_shaped matches over gunbc.cli_invoke PlanFunction, the only way to name a plan target at claim_executor_run_plan_shell. Adding a sixth variant makes that match non-exhaustive, so this file STOPS COMPILING until the new target is given an arm. That is real and it is compile-time.\n\nWHAT IS NOT ENFORCED, stated plainly because an earlier revision of this note said the opposite. Compile-time forces the arm to EXIST; it does NOT force the arm to be EXECUTED. plan_target_roster below is hand-maintained, so an author who adds a variant, writes its arm, and does not extend the roster leaves that arm unrun while this row stays green — and because the typechecker does not check a declared return type against a body (floor_finalization_witness_note carries the probe), a malformed arm can sit there green. So the claim is NOT that the target set and the proof set are the same set by construction. The claim is narrower: every target IN THE ROSTER carries its declared finalization, and no target can exist without at least an arm.\n\nWHERE THE REAL TEETH ARE for the class that caused this incident: every_emitted_plan_target_names_its_variant and no_emitted_plan_target_retains_the_batches_shape read the GENERATED workflows, which are what CI actually executes. An emitted target is the only kind that can break CI, and those rows tie emissions to declared variants rather than to this roster.\n\nDissolve-on: variant enumeration over a closed coproduct (a total roster derived from the type rather than authored beside it), at which point plan_target_roster is derived, the gap above closes, and this paragraph deletes. Nothing in the language offers that today, so the residue is named rather than implied." - -fn plan_variant_is_walk_plan_shaped(p: PlanFunction) -> Bool { - match p { - CiFloorPlan => plan_transports_authority_obligations(p: gunbc_ci_floor_plan()) - CiRegenFloorPlan => plan_carries_no_finalization(plan: gunbc_ci_regen_floor_plan()) - CiPlanArtifactPlan => plan_carries_no_finalization(plan: gunbc_ci_plan_artifact_plan()) - FalsifierPlan => plan_carries_no_finalization(plan: gunbc_falsifier_plan()) - FalsifierNativeCacheColdPlan => plan_carries_no_finalization(plan: gunbc_falsifier_native_cache_cold_plan()) - } -} - -data plan_target_roster: List = [ - CiFloorPlan, - CiRegenFloorPlan, - CiPlanArtifactPlan, - FalsifierPlan, - FalsifierNativeCacheColdPlan -] - -fn every_plan_target_shaped(targets: List) -> Bool { - fold(targets, init: true, f: (acc, p) => acc && plan_variant_is_walk_plan_shaped(p: p)) -} - -test fn declared_plan_targets_are_walk_plan_shaped() -> Bool { - every_plan_target_shaped(targets: plan_target_roster) -} - -data plan_roster_control_placement_note: String = "THERE IS DELIBERATELY NO RUNTIME RED CONTROL FOR THE ROSTER ROW, and writing one would have been a lie worth naming. The obvious candidate — fold a deliberately-short target list and assert it refuses — is a tautology: every variant in the roster IS correctly shaped, so a short list returns true and the assertion would pass for the wrong reason, reporting coverage while discriminating nothing.\n\nThe compile-time half likewise has no Bool control: its failure mode is a build error, not a false value, so its control is a compile failure. Note the bound plan_roster_exhaustiveness_note states — that half forces an arm to exist, not to be executed — so neither the runtime nor the compile-time half is a universal-coverage claim, and this row must not be read as one.\n\nWhat DOES carry runtime teeth is per-variant and already enrolled: forked_declared_count_is_refused_by_the_same_predicate forks the floor declared count and requires the same predicate to refuse, and the three no-finalization rows carry the substitution control floor_finalization_witness_note describes. no_emitted_plan_target_retains_the_batches_shape is the regression control for THIS incident — it goes red if the pre-repair literal returns to either emitted artifact, and stays enrolled permanently rather than retiring now that the wall landed (4b: dissolution deletes the obsoleted production machinery, never the evidence)." - -test fn every_emitted_plan_target_names_its_variant() -> Bool { - string_contains(s: expected_ci_yml(), pattern: concat("--plan-function ", plan_function_name(p: CiFloorPlan))) - && string_contains(s: expected_ci_yml(), pattern: concat("--plan-function ", plan_function_name(p: CiRegenFloorPlan))) - && string_contains(s: expected_falsifier_yml(), pattern: concat("--plan-function ", plan_function_name(p: FalsifierPlan))) - && string_contains(s: expected_falsifier_yml(), pattern: concat("--plan-function ", plan_function_name(p: CiPlanArtifactPlan))) - && string_contains(s: expected_falsifier_yml(), pattern: concat("--plan-function ", plan_function_name(p: FalsifierNativeCacheColdPlan))) -} - -test fn no_emitted_plan_target_retains_the_batches_shape() -> Bool { - !string_contains(s: expected_ci_yml(), pattern: "--plan-function gunbc_falsifier_native_cache_cold_batches") - && !string_contains(s: expected_falsifier_yml(), pattern: "--plan-function gunbc_falsifier_native_cache_cold_batches") -} diff --git a/src/v2/test/claim/falsifier_lane_plan_agreement_test.dag b/src/v2/test/claim/falsifier_lane_plan_agreement_test.dag deleted file mode 100644 index ac0883e9a5b..00000000000 --- a/src/v2/test/claim/falsifier_lane_plan_agreement_test.dag +++ /dev/null @@ -1,57 +0,0 @@ -module v2.test.claim.falsifier_lane_plan_agreement_test - -import v2.workflow.ci_floor_plan { - gunbc_falsifier_lane_batches, - gunbc_falsifier_ordinary_batches, - gunbc_falsifier_planned_components -} -import gunbc.falsifier_lane { - FalsifierPlannedComponent, - falsifier_lane_eq, - falsifier_planned_indices -} -import v2.std.algebra { length, filter, fold_list, list_map } -import v2.std.collection { list_at_optional } -import v2.std.logic { Bool } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data falsifier_lane_plan_agreement_note: String = "The live half of the lane-attribution wall: these rows run against the REAL falsifier plan, not a fixture, so they red if the schedule and the component attribution ever stop being projections of one enrollment list. That is a weaker claim than it looks and deliberately so — since gunbc_falsifier_ordinary_batches and gunbc_falsifier_planned_components both fold gunbc_falsifier_lane_batches, agreement is true BY CONSTRUCTION and these rows cannot fail while that shape holds. They are the regression control for the shape itself (DESIGN section 4b, meta-obligation 4: the discriminating control stays enrolled after the climb so the higher rung stays real). Reintroducing a second hand-authored lane table, or appending a batch outside the roster, breaks them immediately — which is the only failure mode the construction leaves open. Fixture-grain algebra for the join and the routing arms lives in dag/test/claim/falsifier_lane_witness_test.dag; this file exists separately because it reaches the plan module and the two grains cannot share one live-tree stamp." - -test fn falsifier_schedule_and_attribution_agree_on_the_live_plan() -> Bool { - length(xs: gunbc_falsifier_ordinary_batches()) == length(xs: gunbc_falsifier_planned_components()) -} - -test fn falsifier_planned_components_are_dense_one_based() -> Bool { - let indices = falsifier_planned_indices(planned: gunbc_falsifier_planned_components()) - fold_list( - xs: indices, - empty: true, - cons: fn(acc, i) { acc && (i >= 1) && (i <= length(xs: indices)) } - ) && (length(xs: indices) == length(xs: gunbc_falsifier_planned_components())) -} - -data falsifier_enrolled_subset_note: String = "Every planned component corresponds to an ENROLLED row, in roster order. This is what makes the index a sound join key against a receipt: the executor numbers the batches it actually ran, so an unenrolled lane must consume no index rather than leaving a hole. witness_planned_components_skip_unenrolled_and_renumber proves the renumbering on a fixture where a middle lane is disabled; this row proves the same property holds of the live roster whatever its current enrollment happens to be." - -test fn falsifier_planned_components_track_enrolled_rows_in_order() -> Bool { - let enrolled_lanes = list_map( - xs: filter(xs: gunbc_falsifier_lane_batches(), predicate: fn(row) { row.enrolled }), - f: fn(row) { row.lane } - ) - let planned_lanes = list_map( - xs: gunbc_falsifier_planned_components(), - f: fn(c) { c.lane } - ) - (length(xs: enrolled_lanes) == length(xs: planned_lanes)) - && fold_list( - xs: gunbc_falsifier_planned_components(), - empty: true, - cons: fn(acc, c) { - acc && match list_at_optional(xs: enrolled_lanes, index: c.index - 1) { - Present { value: l } => falsifier_lane_eq(left: l, right: c.lane) - Absent => false - } - } - ) -} diff --git a/src/v2/test/claim/pr_native_batch_test.dag b/src/v2/test/claim/pr_native_batch_test.dag index 7c7012234e0..d1745ef6734 100644 --- a/src/v2/test/claim/pr_native_batch_test.dag +++ b/src/v2/test/claim/pr_native_batch_test.dag @@ -6,7 +6,6 @@ import v2.workflow.ci_floor_plan { gunbc_ci_floor_ordinary_batches, gunbc_ci_floor_realization_plan_for } -import gunbc.ci_layer_roots { scoped_witness_batches } import gunbc.ci_spec { gunbc_ci_spec } import v2.std.algebra { length } import v2.std.logic { Bool } @@ -29,7 +28,7 @@ test fn witness_selected_native_bundle_enrolled() -> Bool { } test fn witness_floor_appends_one_selected_native_batch() -> Bool { - length(xs: gunbc_ci_floor_ordinary_batches()) == length(xs: gunbc_ci_floor_realization_plan_for(spec: gunbc_ci_spec).schedule) + length(xs: scoped_witness_batches) + 1 + length(xs: gunbc_ci_floor_ordinary_batches()) == length(xs: gunbc_ci_floor_realization_plan_for(spec: gunbc_ci_spec).schedule) + 1 } fn native_transition_receipt_fixture(selected: Int, native: Int, interpreted: Int, unavailable: Int, diverged: Int, fallback: Int, verdict: NativeProductionTransitionVerdict) -> NativeWitnessProductionTransitionReceipt { diff --git a/src/v2/test/claim/schedule_occurrence_multiplicity_test.dag b/src/v2/test/claim/schedule_occurrence_multiplicity_test.dag index dbc2fbdfea9..34811cb11a8 100644 --- a/src/v2/test/claim/schedule_occurrence_multiplicity_test.dag +++ b/src/v2/test/claim/schedule_occurrence_multiplicity_test.dag @@ -5,7 +5,6 @@ import std.realization_schedule { Runnable, RunnableDiscoveryBatch, RunnableKernelWorkload, - RunnableScopedWitnessBatch, RunnableSingleClaim, runnable_resource_profile_negligible, ScheduleWitnessEntry, @@ -46,13 +45,10 @@ fn runnable_subject_occurrences(runnable: Runnable, subject: ScheduleWitnessEntr source_roots: _, scan_dirs: _, explicit_entries: explicit_entries, - node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => schedule_entry_occurrences(entries: explicit_entries, subject: subject) - RunnableScopedWitnessBatch { batch: batch } => - schedule_entry_occurrences(entries: batch.entries, subject: subject) RunnableKernelWorkload { fused_op_count: _ } => 0 } } diff --git a/src/v2/test/claim/walk_plan_schedule_lens_test.dag b/src/v2/test/claim/walk_plan_schedule_lens_test.dag index 1cc73484fa1..a26469c58dd 100644 --- a/src/v2/test/claim/walk_plan_schedule_lens_test.dag +++ b/src/v2/test/claim/walk_plan_schedule_lens_test.dag @@ -8,7 +8,6 @@ import std.realization_schedule { RunnableSingleClaim, RunnableDiscoveryBatch, RunnableKernelWorkload, - SelectionOff, WalkPlan, NoWalkFinalization, NoFinalizationDeclared, @@ -127,7 +126,6 @@ fn discovery_runnable() -> Runnable { source_roots: ["dag"], scan_dirs: [], explicit_entries: [], - node_frontier_selection: SelectionOff, exclude_substrings: [], discovery_scope_dirs: [], profile: runnable_resource_profile_negligible() diff --git a/src/v2/test/claim/workflow/provenance_fail_closed_contract_test.dag b/src/v2/test/claim/workflow/provenance_fail_closed_contract_test.dag deleted file mode 100644 index 0637fc0b8de..00000000000 --- a/src/v2/test/claim/workflow/provenance_fail_closed_contract_test.dag +++ /dev/null @@ -1,112 +0,0 @@ -module v2.test.claim.workflow.provenance_fail_closed_contract -import v2.compiler.source_authority { source_root_coverage_is_complete } - -import v2.compiler.source_authority { source_root_coverage_is_complete } - -import v2.std.algebra { length } -import v2.std.logic { Bool } -import v2.std.node { Atom, Node, SyntheticOccurrence, TypeNode } -import v2.std.verification { - EqualsClaim, - TestClaim, - ManualAnchorAbsent, - TestClassification, - Tier1, - Unit, - manual_claim_anchor -} -import v2.test.workflow.host_source_root_ingest_manifest { - host_source_root_ingest, - host_source_root_ingest_coverage_receipt -} -import v2.workflow.affected_set_floor_runner { - DiffPathsProduced, - FloorDiffObservation, - FloorRerunFrontier, - FrontierFailClosed, - FrontierProduced, - RunWitness, - SkipAssumedGreen, - Refused, - DiffObservationRefusal, - FrontierQueryRefusal, - floor_precompute_would_skip, - floor_witness_run_disposition -} -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data scout_manifest_provenance_live: Bool = source_root_coverage_is_complete(coverage: host_source_root_ingest_coverage_receipt.coverage) && (host_source_root_ingest_coverage_receipt.ingest_read_count > 0) && (length(xs: host_source_root_ingest) > 0) - -data scout_unrelated_frontier_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^scout_unrelated_frontier_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data scout_orphan_claim: TestClaim = EqualsClaim { - label: "scout: orphan claim off diff frontier", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: scout_orphan_claim_node, - rhs: scout_orphan_claim_node, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -data scout_orphan_claim_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^scout_orphan_claim_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data scout_nonempty_diff: FloorDiffObservation = DiffPathsProduced { - changed_paths: ["src/v2/lens/affected_set.dag"] -} - -data scout_provenance_present_frontier: FloorRerunFrontier = FrontierProduced { - nodes: [scout_unrelated_frontier_node] -} - -data scout_provenance_absent_frontier: FloorRerunFrontier = FrontierFailClosed { - reason: "provenance unavailable" -} - -test fn provenance_fail_closed_contract_holds() -> Bool { - let manifest_absent = scout_manifest_provenance_live == false - let absent_witness_refuses = match floor_witness_run_disposition( - diff: scout_nonempty_diff, - frontier: scout_provenance_absent_frontier, - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - Refused { cause: cause } => - match cause { - FrontierQueryRefusal { reason: reason } => reason == "provenance unavailable" - DiffObservationRefusal { reason: _ } => false - } - RunWitness { reason: _ } => false - SkipAssumedGreen => false - } - let present_witness_skips = match floor_witness_run_disposition( - diff: scout_nonempty_diff, - frontier: scout_provenance_present_frontier, - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - SkipAssumedGreen => true - RunWitness { reason: _ } => false - Refused { cause: _ } => false - } - let absent_precompute_runs_all = !floor_precompute_would_skip( - diff: scout_nonempty_diff, - frontier: scout_provenance_absent_frontier, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 0 - ) - manifest_absent && absent_witness_refuses && present_witness_skips && absent_precompute_runs_all -} diff --git a/src/v2/test/fixture/floor_skip/budget_red_control_plan.dag b/src/v2/test/fixture/floor_skip/budget_red_control_plan.dag deleted file mode 100644 index 5f91e0f55c9..00000000000 --- a/src/v2/test/fixture/floor_skip/budget_red_control_plan.dag +++ /dev/null @@ -1,66 +0,0 @@ -module v2.test.fixture.floor_skip.budget_red_control_plan - -import std.realization_schedule { - Runnable, - RunnableSingleClaim, - WalkPlan, - NoPreWalkExecution, - runnable_resource_profile_negligible -} -import gunbc.ci_materialization { - FloorFinalization, - ResolveObligation, - ResolveObligationSubject, - CompileAnchorWholeTree, -} -import v2.std.collection { List } -import std.types { Int } - -data budget_red_control_plan_note: String = "THE COST WALL's by-execution RED-control fixture (endgame D5): a minimal plan whose fn is NAMED gunbc_ci_floor_plan so claim_executor arms the per-batch derived clamp against it — one tiny hermetic batch, one generous overhead row (600s) with rate 0, so the computed clamp is 600s. RED direction: GUNBC_FLOOR_BATCH_BUDGET_TIGHTEN_MS=0 tightens the budget to zero, the batch overruns by construction, and the run must exit nonzero with the typed FLOOR-BATCH-OVER-BUDGET refusal naming batch 1. GREEN direction: the same invocation without the env exits zero. The injection is tighten-only (min), so this fixture can force the refusal but can never widen a real budget — a fault injection, not an escape hatch. Recipe: target/release/claim_executor --source-root dag --source-root src/v2 --plan-entry src/v2/test/fixture/floor_skip/budget_red_control_plan.dag --plan-function gunbc_ci_floor_plan. Lives under test/fixture/floor_skip/ (discovery-excluded at dir grain) and declares no test fns, so it is invisible to the witness corpus — driven only by this recipe." - -fn budget_red_control_claim() -> Runnable { - RunnableSingleClaim { - entry: "src/v2/test/fixture/floor_skip/falsifier_divergence_control_test.dag", - function: "falsifier_green_control_holds", - profile: runnable_resource_profile_negligible() - } -} - -data budget_red_control_declared_resolve_note: String = "The fixture DECLARES its finalization policy in its own plan value (declared 1: exactly one single-claim batch paying exactly one entry resolve) — it no longer needs a name-impersonated projection fn, because the policy is a WalkPlan FIELD (walk_finalization_note): the executor reads the parsed value. The return type WalkPlan declares which family this fixture carries; it does not make the empty policy unwritable, since the typechecker does not check a return type against the body (std.realization_schedule walk_finalization_note). Materialization disclosure is intrinsic to FloorFinalization, so this fixture obligates both floor laws by inhabiting the type — there is no Bool to set." - -fn gunbc_ci_floor_plan() -> WalkPlan { - WalkPlan { - pre_walk_execution: NoPreWalkExecution {}, - batches: [[budget_red_control_claim()]], - finalization: FloorFinalization { - expected_resolve_obligations: [ - ResolveObligation { - identity: CompileAnchorWholeTree, - subject: ResolveObligationSubject { - entry: "src/v2/test/fixture/floor_skip/falsifier_divergence_control_test.dag", - function: "falsifier_green_control_holds", - }, - }, - ], - }, - on_success_stages: [], - ordinary_budget: none, - on_success_budget: none, - } -} - -fn gunbc_ci_floor_batch_clamp_overhead_seconds() -> List { - [600] -} - -fn gunbc_ci_floor_batch_clamp_per_unit_ms() -> List { - [0] -} - -fn gunbc_ci_floor_batch_clamp_authority_modules() -> List { - ["v2.test.fixture.floor_skip.budget_red_control_plan"] -} - -fn gunbc_ci_floor_batch_clamp_authority_decls() -> List { - ["gunbc_ci_floor_batch_clamp_overhead_seconds"] -} diff --git a/src/v2/test/fixture/floor_skip/falsifier_divergence_control_test.dag b/src/v2/test/fixture/floor_skip/falsifier_divergence_control_test.dag deleted file mode 100644 index 3d69bd5036b..00000000000 --- a/src/v2/test/fixture/floor_skip/falsifier_divergence_control_test.dag +++ /dev/null @@ -1,14 +0,0 @@ -module v2.test.fixture.floor_skip.falsifier_divergence_control - -import v2.std.logic { Bool } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -test fn falsifier_red_control_holds() -> Bool { - false -} - -test fn falsifier_green_control_holds() -> Bool { - true -} diff --git a/src/v2/test/fixture/floor_skip/floor_disc_data_source.dag b/src/v2/test/fixture/floor_skip/floor_disc_data_source.dag deleted file mode 100644 index f658699efc4..00000000000 --- a/src/v2/test/fixture/floor_skip/floor_disc_data_source.dag +++ /dev/null @@ -1,9 +0,0 @@ -module v2.test.fixture.floor_skip.floor_disc_data_source - -import v2.std.node { Atom, Node, TypeNode, SyntheticOccurrence } - -data floor_disc_cross_file_data: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_disc_cross_file_data_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} diff --git a/src/v2/test/fixture/floor_skip/floor_disc_data_witness_test.dag b/src/v2/test/fixture/floor_skip/floor_disc_data_witness_test.dag deleted file mode 100644 index ce97d502381..00000000000 --- a/src/v2/test/fixture/floor_skip/floor_disc_data_witness_test.dag +++ /dev/null @@ -1,31 +0,0 @@ -module v2.test.fixture.floor_skip.floor_disc_data_witness - -import v2.std.verification { - EqualsClaim, - TestClaim, - ManualAnchorAbsent, - TestClassification, - Tier1, - Unit, - manual_claim_anchor -} -import v2.test.fixture.floor_skip.floor_disc_data_source { floor_disc_cross_file_data } -import v2.workflow.affected_set_floor_runner { floor_claim_touches_rerun_frontier } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data floor_disc_data_claim: TestClaim = EqualsClaim { - label: "floor_disc: claim on cross-file data item", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: floor_disc_cross_file_data, - rhs: floor_disc_cross_file_data, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -test fn floor_disc_data_witness_holds() -> Bool { - floor_claim_touches_rerun_frontier( - claim: floor_disc_data_claim, - frontier: [floor_disc_cross_file_data] - ) -} diff --git a/src/v2/test/fixture/floor_skip/floor_disc_shared_helper.dag b/src/v2/test/fixture/floor_skip/floor_disc_shared_helper.dag deleted file mode 100644 index 569ac34f432..00000000000 --- a/src/v2/test/fixture/floor_skip/floor_disc_shared_helper.dag +++ /dev/null @@ -1,7 +0,0 @@ -module v2.test.fixture.floor_skip.floor_disc_shared_helper - -import v2.std.logic { Bool } - -fn floor_disc_shared_helper() -> Bool { - true -} diff --git a/src/v2/test/fixture/floor_skip/live_tree_declared_test.dag b/src/v2/test/fixture/floor_skip/live_tree_declared_test.dag deleted file mode 100644 index a364d1013cb..00000000000 --- a/src/v2/test/fixture/floor_skip/live_tree_declared_test.dag +++ /dev/null @@ -1,12 +0,0 @@ -module v2.test.fixture.floor_skip.live_tree_declared - -import v2.std.logic { Bool } -import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree } - -data live_tree_disposition: LiveTreeDisposition = ReadsLiveTree - -data live_tree_declared_fixture_note: String = "Control fixture for the declared live-tree disposition: this entry DECLARES ReadsLiveTree, so no diff-derived affected set may predict-skip its rows (floor_skip_discovery_witness proves by execution that an unrelated diff still RUNS the witness, and that predict-only mode never records it predicted-unaffected). The sibling falsifier_divergence_control fixture declares SubstrateInputsOnly and proves the enforcement side: a declared-not-live row that reds while predicted-unaffected is a counted divergence." - -test fn live_tree_declared_control_holds() -> Bool { - true -} diff --git a/src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag b/src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag deleted file mode 100644 index 65ba95d2787..00000000000 --- a/src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag +++ /dev/null @@ -1,110 +0,0 @@ -module v2.test.fixture.floor_skip.node_precise_discriminator - -import v2.std.node { Atom, Conj, Edge, Node, Positional, TypeNode, SyntheticOccurrence } -import v2.std.verification { - EqualsClaim, - TestClaim, - ManualAnchorAbsent, - TestClassification, - Tier1, - Unit, - manual_claim_anchor -} -import v2.test.fixture.floor_skip.floor_disc_shared_helper { floor_disc_shared_helper } -import v2.workflow.affected_set_floor_runner { floor_claim_touches_rerun_frontier } -import v2.std.live_tree { LiveTreeDisposition, SubstrateInputsOnly } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data floor_disc_node_a: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_disc_node_a_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data floor_disc_node_b: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_disc_node_b_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data floor_disc_node_c: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_disc_node_c_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data floor_disc_orphan_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_disc_orphan_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data floor_disc_helper_conj: Node = Node { - kind: TypeNode { connective: Conj }, - children: [ - Edge { - label: Positional, - target: floor_disc_node_c - } - ], - occurrence_id: SyntheticOccurrence -} - -fn floor_disc_helper_fn() -> Bool { - floor_disc_shared_helper() -} - -data floor_disc_claim_on_a: TestClaim = EqualsClaim { - label: "floor_disc: claim on node A", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: floor_disc_node_a, - rhs: floor_disc_node_a, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -data floor_disc_claim_on_b: TestClaim = EqualsClaim { - label: "floor_disc: claim on node B", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: floor_disc_node_b, - rhs: floor_disc_node_b, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -data floor_disc_claim_transitive: TestClaim = EqualsClaim { - label: "floor_disc: conj-wrapped transitive claim", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: floor_disc_helper_conj, - rhs: floor_disc_helper_conj, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -test fn floor_disc_witness_a_only_holds() -> Bool { - floor_disc_helper_fn() - && floor_claim_touches_rerun_frontier( - claim: floor_disc_claim_on_a, - frontier: [floor_disc_node_a] - ) - && !floor_claim_touches_rerun_frontier( - claim: floor_disc_claim_on_a, - frontier: [floor_disc_node_b] - ) -} - -test fn floor_disc_witness_b_only_holds() -> Bool { - floor_claim_touches_rerun_frontier( - claim: floor_disc_claim_on_b, - frontier: [floor_disc_node_b] - ) - && !floor_claim_touches_rerun_frontier( - claim: floor_disc_claim_on_b, - frontier: [floor_disc_node_a] - ) -} - -test fn floor_disc_witness_transitive_holds() -> Bool { - floor_claim_touches_rerun_frontier( - claim: floor_disc_claim_transitive, - frontier: [floor_disc_node_c] - ) -} diff --git a/src/v2/workflow/affected_set_floor_runner.dag b/src/v2/workflow/affected_set_floor_runner.dag deleted file mode 100644 index e1930e43a25..00000000000 --- a/src/v2/workflow/affected_set_floor_runner.dag +++ /dev/null @@ -1,259 +0,0 @@ -module v2.workflow.affected_set_floor_runner - -import gunbc.ci_spec { gunbc_ci_spec, DiffPolicy } -import v2.std.algebra { any, length, list_flat_map } -import v2.std.collection { List } -import v2.std.logic { Bool } -import v2.std.node { Node } -import v2.std.text { String } -import v2.std.integer { Int } -import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree, SubstrateInputsOnly } -import v2.std.verification { - TestClaim, - test_claim_evaluation_node_touches_frontier, - test_claim_evaluation_nodes, - test_claim_evaluation_touches_rerun_frontier -} - -type FloorDiffObservation - = DiffPathsProduced { changed_paths: List } - | DiffObservationFailClosed { reason: String } - -type FloorRerunFrontier - = FrontierProduced { nodes: List } - | FrontierFailClosed { reason: String } - -type WitnessRefusalCause - = DiffObservationRefusal { reason: String } - | FrontierQueryRefusal { reason: String } - -type WitnessRunDisposition - = RunWitness { reason: String } - | SkipAssumedGreen - | Refused { cause: WitnessRefusalCause } - -type FloorWitnessRow { - label: String - entry: String - function: String - reads_live_tree: LiveTreeDisposition -} - -type FloorDiffLineTouch { - path: String - start_line: Int - end_line: Int -} - -fn floor_diff_line_touches_decl( - touch: FloorDiffLineTouch, - file_path: String, - decl_line: Int, - decl_end_line: Int -) -> Bool { - touch.path == file_path - && touch.start_line <= decl_end_line - && touch.end_line >= decl_line -} - -fn floor_test_fn_declaration_edited( - touches: List, - file_path: String, - test_fn_decl_line: Int, - test_fn_decl_end_line: Int -) -> Bool { - any( - xs: touches, - predicate: fn(t) { - floor_diff_line_touches_decl( - touch: t, - file_path: file_path, - decl_line: test_fn_decl_line, - decl_end_line: test_fn_decl_end_line - ) - } - ) -} - -fn floor_rust_run_implies_dag_run( - rust_touches_frontier: Bool, - rust_function_edited: Bool, - dag_touches_frontier: Bool, - dag_function_edited: Bool -) -> Bool { - let rust_run = rust_touches_frontier || rust_function_edited - let dag_run = dag_touches_frontier || dag_function_edited - !rust_run || dag_run -} - -fn floor_skip_git_diff_policy() -> DiffPolicy { - gunbc_ci_spec.diff_policy -} - -fn floor_any_node_touches_frontier(nodes: List, frontier: List) -> Bool { - any( - xs: nodes, - predicate: fn(n) { - test_claim_evaluation_node_touches_frontier(n: n, frontier: frontier) - } - ) -} - -fn floor_claim_touches_rerun_frontier(claim: TestClaim, frontier: List) -> Bool { - test_claim_evaluation_touches_rerun_frontier(c: claim, frontier: frontier) -} - -fn floor_any_claim_touches_rerun_frontier(claims: List, frontier: List) -> Bool { - any( - xs: claims, - predicate: fn(c) { floor_claim_touches_rerun_frontier(claim: c, frontier: frontier) } - ) -} - -fn floor_witness_nodes_touch_frontier(witness_nodes: List, frontier: List) -> Bool { - floor_any_node_touches_frontier(nodes: witness_nodes, frontier: frontier) -} - -fn floor_witness_run_disposition( - diff: FloorDiffObservation, - frontier: FloorRerunFrontier, - touches_frontier: Bool, - function_edited: Bool, - entry_file_touched: Bool, - runtime_data_dependency_touched: Bool -) -> WitnessRunDisposition { - match diff { - DiffObservationFailClosed { reason: reason } => - Refused { cause: DiffObservationRefusal { reason: reason } } - DiffPathsProduced { changed_paths: _ } => - match frontier { - FrontierFailClosed { reason: reason } => - Refused { cause: FrontierQueryRefusal { reason: reason } } - FrontierProduced { nodes: _ } => - if touches_frontier { - RunWitness { reason: "witness node-closure intersects rerun frontier" } - } else if function_edited { - RunWitness { reason: "witness test fn declaration directly edited" } - } else if entry_file_touched { - RunWitness { reason: "witness entry import-closure has non-data fn edit in diff" } - } else if runtime_data_dependency_touched { - RunWitness { reason: "witness entry's proven runtime-read closure intersects a touched path" } - } else { - SkipAssumedGreen - } - } - } -} - -fn floor_kernel_would_skip( - changed_paths: List, - frontier_nodes: List, - touches_frontier: Bool, - function_edited: Bool, - entry_file_touched: Bool, - runtime_data_dependency_touched: Bool -) -> Bool { - match floor_witness_run_disposition( - diff: DiffPathsProduced { changed_paths: changed_paths }, - frontier: FrontierProduced { nodes: frontier_nodes }, - touches_frontier: touches_frontier, - function_edited: function_edited, - entry_file_touched: entry_file_touched, - runtime_data_dependency_touched: runtime_data_dependency_touched - ) { - SkipAssumedGreen => true - RunWitness { reason: _ } => false - Refused { cause: _ } => false - } -} - -fn floor_row_would_skip( - reads_live_tree: LiveTreeDisposition, - changed_paths: List, - frontier_nodes: List, - touches_frontier: Bool, - function_edited: Bool, - entry_file_touched: Bool, - runtime_data_dependency_touched: Bool -) -> Bool { - match reads_live_tree { - ReadsLiveTree => false - SubstrateInputsOnly => - floor_kernel_would_skip( - changed_paths: changed_paths, - frontier_nodes: frontier_nodes, - touches_frontier: touches_frontier, - function_edited: function_edited, - entry_file_touched: entry_file_touched, - runtime_data_dependency_touched: runtime_data_dependency_touched - ) - } -} - -fn floor_precompute_would_skip( - diff: FloorDiffObservation, - frontier: FloorRerunFrontier, - edited_test_fn_count: Int, - touched_entry_file_count: Int, - touched_runtime_dependency_entry_count: Int -) -> Bool { - match diff { - DiffObservationFailClosed { reason: _ } => false - DiffPathsProduced { changed_paths: _ } => - match frontier { - FrontierFailClosed { reason: _ } => false - FrontierProduced { nodes: nodes } => - (length(xs: nodes) == 0) - && (edited_test_fn_count == 0) - && (touched_entry_file_count == 0) - && (touched_runtime_dependency_entry_count == 0) - } - } -} - -fn floor_kernel_precompute_would_skip( - changed_paths: List, - frontier_node_count: Int, - edited_test_fn_count: Int, - touched_entry_file_count: Int, - touched_runtime_dependency_entry_count: Int -) -> Bool { - if frontier_node_count > 0 { - false - } else { - floor_precompute_would_skip( - diff: DiffPathsProduced { changed_paths: changed_paths }, - frontier: FrontierProduced { nodes: [] }, - edited_test_fn_count: edited_test_fn_count, - touched_entry_file_count: touched_entry_file_count, - touched_runtime_dependency_entry_count: touched_runtime_dependency_entry_count - ) - } -} - -data floor_live_tree_row_policy_note: String = "A witness row whose entry declares (or fail-closed defaults to) ReadsLiveTree has inputs outside the diff-derived affected set, so no diff can prove it unaffected: it never skips and, corpus-wide, its presence pins the whole-tree precompute. The declaration authority is the entry file's `data live_tree_disposition: LiveTreeDisposition` row (see v2.std.live_tree); the executor passes each row's declared disposition here rather than classifying text (the witness_test_fn_uses_live_host_scan scaffold and the floor:host_scaffold marker are deleted)." - -fn floor_row_precompute_would_skip( - live_row_count: Int, - changed_paths: List, - frontier_node_count: Int, - edited_test_fn_count: Int, - touched_entry_file_count: Int, - touched_runtime_dependency_entry_count: Int -) -> Bool { - if live_row_count > 0 { - false - } else { - floor_kernel_precompute_would_skip( - changed_paths: changed_paths, - frontier_node_count: frontier_node_count, - edited_test_fn_count: edited_test_fn_count, - touched_entry_file_count: touched_entry_file_count, - touched_runtime_dependency_entry_count: touched_runtime_dependency_entry_count - ) - } -} - -fn floor_witness_eval_nodes_from_claims(claims: List) -> List { - list_flat_map(xs: claims, f: fn(claim) { test_claim_evaluation_nodes(c: claim) }) -} diff --git a/src/v2/workflow/affected_set_floor_runner_test.dag b/src/v2/workflow/affected_set_floor_runner_test.dag deleted file mode 100644 index 5a497aa77e2..00000000000 --- a/src/v2/workflow/affected_set_floor_runner_test.dag +++ /dev/null @@ -1,512 +0,0 @@ -module v2.test.workflow.affected_set_floor_runner - -import v2.std.algebra { count_equal, length } -import v2.std.collection { List } -import v2.std.logic { Bool } -import v2.std.node { Atom, Conj, Edge, Node, Positional, Symbol, TypeNode, SyntheticOccurrence } -import v2.std.text { String } -import v2.std.verification { - EqualsClaim, - TestClaim, - TestClassification, - ManualAnchorAbsent, - Tier1, - Unit, - manual_claim_anchor, - test_claim_evaluation_nodes, - test_claim_evaluation_touches_rerun_frontier -} -import v2.std.integer { Int } -import v2.std.live_tree { LiveTreeDisposition, ReadsLiveTree, SubstrateInputsOnly } -import v2.workflow.affected_set_floor_runner { - DiffObservationFailClosed, - DiffPathsProduced, - FloorDiffLineTouch, - FloorDiffObservation, - FloorRerunFrontier, - FloorWitnessRow, - FrontierFailClosed, - FrontierProduced, - RunWitness, - SkipAssumedGreen, - Refused, - DiffObservationRefusal, - FrontierQueryRefusal, - floor_any_claim_touches_rerun_frontier, - floor_claim_touches_rerun_frontier, - floor_row_would_skip, - floor_row_precompute_would_skip, - floor_kernel_would_skip, - floor_kernel_precompute_would_skip, - floor_precompute_would_skip, - floor_rust_run_implies_dag_run, - floor_skip_git_diff_policy, - floor_test_fn_declaration_edited, - floor_witness_eval_nodes_from_claims, - floor_witness_nodes_touch_frontier, - floor_witness_run_disposition -} -import gunbc.ci_spec { DiffMergeBase } - -data live_tree_disposition: LiveTreeDisposition = SubstrateInputsOnly - -data floor_test_untouched_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_test_untouched_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data floor_test_touched_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_test_touched_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data floor_test_other_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^floor_test_other_symbol } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data floor_test_conj_wrapped_touched_node: Node = Node { - kind: TypeNode { connective: Conj }, - children: [ - Edge { - label: Positional, - target: floor_test_touched_node - } - ], - occurrence_id: SyntheticOccurrence -} - -data floor_test_claim_untouched: TestClaim = EqualsClaim { - label: "floor_runner: untouched claim", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: floor_test_untouched_node, - rhs: floor_test_untouched_node, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -data floor_test_claim_touched: TestClaim = EqualsClaim { - label: "floor_runner: touched claim", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: floor_test_touched_node, - rhs: floor_test_touched_node, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -data floor_test_claim_conj_wrapped: TestClaim = EqualsClaim { - label: "floor_runner: conj-wrapped touched claim", - anchor: manual_claim_anchor(anchor: ManualAnchorAbsent), - lhs: floor_test_conj_wrapped_touched_node, - rhs: floor_test_conj_wrapped_touched_node, - classification: TestClassification { tier: Tier1, layer: Unit } -} - -data floor_test_row_untouched: FloorWitnessRow = FloorWitnessRow { - label: "floor_runner: untouched witness", - entry: "src/v2/workflow/affected_set_floor_runner_test.dag", - function: "floor_test_untouched_witness_holds", - reads_live_tree: SubstrateInputsOnly -} - -data floor_test_row_touched: FloorWitnessRow = FloorWitnessRow { - label: "floor_runner: touched witness", - entry: "src/v2/workflow/affected_set_floor_runner_test.dag", - function: "floor_test_touched_witness_holds", - reads_live_tree: ReadsLiveTree -} - -data floor_test_diff_nonempty: FloorDiffObservation = DiffPathsProduced { - changed_paths: ["src/v2/lens/affected_set.dag"] -} - -data floor_test_diff_empty: FloorDiffObservation = DiffPathsProduced { - changed_paths: [] -} - -data floor_test_diff_fail_closed: FloorDiffObservation = DiffObservationFailClosed { - reason: "git diff unavailable" -} - -data floor_test_frontier_touched: FloorRerunFrontier = FrontierProduced { - nodes: [floor_test_touched_node] -} - -data floor_test_frontier_fail_closed: FloorRerunFrontier = FrontierFailClosed { - reason: "provenance unavailable" -} - -test fn floor_test_untouched_skips_assumed_green_holds() -> Bool { - match floor_witness_run_disposition( - diff: floor_test_diff_nonempty, - frontier: floor_test_frontier_touched, - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - SkipAssumedGreen => true - RunWitness { reason: _ } => false - Refused { cause: _ } => false - } -} - -test fn floor_test_touched_runs_holds() -> Bool { - match floor_witness_run_disposition( - diff: floor_test_diff_nonempty, - frontier: floor_test_frontier_touched, - touches_frontier: true, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - RunWitness { reason: _ } => true - SkipAssumedGreen => false - Refused { cause: _ } => false - } -} - -test fn floor_test_function_edited_runs_holds() -> Bool { - match floor_witness_run_disposition( - diff: floor_test_diff_nonempty, - frontier: floor_test_frontier_touched, - touches_frontier: false, - function_edited: true, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - RunWitness { reason: reason } => - reason == "witness test fn declaration directly edited" - SkipAssumedGreen => false - Refused { cause: _ } => false - } -} - -test fn floor_test_entry_file_touched_runs_holds() -> Bool { - match floor_witness_run_disposition( - diff: floor_test_diff_nonempty, - frontier: floor_test_frontier_touched, - touches_frontier: false, - function_edited: false, - entry_file_touched: true, - runtime_data_dependency_touched: false - ) { - RunWitness { reason: reason } => - reason == "witness entry import-closure has non-data fn edit in diff" - SkipAssumedGreen => false - Refused { cause: _ } => false - } -} - -test fn floor_test_empty_diff_flows_general_skip_holds() -> Bool { - match floor_witness_run_disposition( - diff: floor_test_diff_empty, - frontier: FrontierProduced { nodes: [] }, - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - SkipAssumedGreen => true - RunWitness { reason: _ } => false - Refused { cause: _ } => false - } -} - -test fn floor_test_diff_fail_closed_refuses_holds() -> Bool { - match floor_witness_run_disposition( - diff: floor_test_diff_fail_closed, - frontier: floor_test_frontier_touched, - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - Refused { cause: cause } => - match cause { - DiffObservationRefusal { reason: reason } => reason == "git diff unavailable" - FrontierQueryRefusal { reason: _ } => false - } - RunWitness { reason: _ } => false - SkipAssumedGreen => false - } -} - -test fn floor_test_frontier_fail_closed_refuses_holds() -> Bool { - match floor_witness_run_disposition( - diff: floor_test_diff_nonempty, - frontier: floor_test_frontier_fail_closed, - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) { - Refused { cause: cause } => - match cause { - FrontierQueryRefusal { reason: reason } => reason == "provenance unavailable" - DiffObservationRefusal { reason: _ } => false - } - RunWitness { reason: _ } => false - SkipAssumedGreen => false - } -} - -test fn floor_test_claim_touch_discriminates_holds() -> Bool { - floor_claim_touches_rerun_frontier( - claim: floor_test_claim_touched, - frontier: [floor_test_touched_node] - ) - && !floor_claim_touches_rerun_frontier( - claim: floor_test_claim_untouched, - frontier: [floor_test_touched_node] - ) -} - -test fn floor_test_inner_frontier_discriminates_holds() -> Bool { - floor_claim_touches_rerun_frontier( - claim: floor_test_claim_conj_wrapped, - frontier: [floor_test_touched_node] - ) - && !floor_claim_touches_rerun_frontier( - claim: floor_test_claim_untouched, - frontier: [floor_test_touched_node] - ) -} - -test fn floor_test_live_row_never_skips_when_kernel_would_holds() -> Bool { - floor_row_would_skip( - reads_live_tree: SubstrateInputsOnly, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_nodes: [floor_test_touched_node], - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) - && !floor_row_would_skip( - reads_live_tree: ReadsLiveTree, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_nodes: [floor_test_touched_node], - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) -} - -test fn floor_test_live_row_runs_when_kernel_runs_holds() -> Bool { - !floor_row_would_skip( - reads_live_tree: SubstrateInputsOnly, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_nodes: [floor_test_touched_node], - touches_frontier: true, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) - && !floor_row_would_skip( - reads_live_tree: ReadsLiveTree, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_nodes: [floor_test_touched_node], - touches_frontier: true, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: false - ) -} - -test fn floor_test_runtime_data_dependency_touched_runs_holds() -> Bool { - !floor_row_would_skip( - reads_live_tree: SubstrateInputsOnly, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_nodes: [floor_test_touched_node], - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: true - ) - && match floor_witness_run_disposition( - diff: floor_test_diff_nonempty, - frontier: floor_test_frontier_touched, - touches_frontier: false, - function_edited: false, - entry_file_touched: false, - runtime_data_dependency_touched: true - ) { - RunWitness { reason: reason } => - reason == "witness entry's proven runtime-read closure intersects a touched path" - SkipAssumedGreen => false - Refused { cause: _ } => false - } -} - -test fn floor_test_precompute_skip_holds() -> Bool { - floor_precompute_would_skip( - diff: floor_test_diff_nonempty, - frontier: FrontierProduced { nodes: [] }, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 0 - ) - && floor_precompute_would_skip( - diff: floor_test_diff_empty, - frontier: FrontierProduced { nodes: [] }, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 0 - ) - && !floor_precompute_would_skip( - diff: floor_test_diff_nonempty, - frontier: floor_test_frontier_touched, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 0 - ) - && !floor_precompute_would_skip( - diff: floor_test_diff_nonempty, - frontier: FrontierProduced { nodes: [] }, - edited_test_fn_count: 1, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 0 - ) - && !floor_precompute_would_skip( - diff: floor_test_diff_nonempty, - frontier: FrontierProduced { nodes: [] }, - edited_test_fn_count: 0, - touched_entry_file_count: 1, - touched_runtime_dependency_entry_count: 0 - ) - && !floor_precompute_would_skip( - diff: floor_test_diff_nonempty, - frontier: FrontierProduced { nodes: [] }, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 1 - ) -} - -test fn floor_test_precompute_live_corpus_never_skips_holds() -> Bool { - floor_row_precompute_would_skip( - live_row_count: 0, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_node_count: 0, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 0 - ) - && !floor_row_precompute_would_skip( - live_row_count: 1, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_node_count: 0, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 0 - ) - && !floor_row_precompute_would_skip( - live_row_count: 1, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_node_count: 0, - edited_test_fn_count: 0, - touched_entry_file_count: 1, - touched_runtime_dependency_entry_count: 0 - ) - && !floor_row_precompute_would_skip( - live_row_count: 1, - changed_paths: ["src/v2/lens/affected_set.dag"], - frontier_node_count: 0, - edited_test_fn_count: 0, - touched_entry_file_count: 0, - touched_runtime_dependency_entry_count: 1 - ) -} - -test fn floor_test_eval_nodes_from_claims_holds() -> Bool { - let nodes = floor_witness_eval_nodes_from_claims( - claims: [floor_test_claim_conj_wrapped, floor_test_claim_untouched] - ) - (length(xs: nodes) > 0) - && floor_witness_nodes_touch_frontier( - witness_nodes: nodes, - frontier: [floor_test_touched_node] - ) -} - -test fn floor_test_any_claim_touch_holds() -> Bool { - floor_any_claim_touches_rerun_frontier( - claims: [floor_test_claim_untouched, floor_test_claim_touched], - frontier: [floor_test_touched_node] - ) - && count_equal( - xs: [floor_test_claim_touched], - item: floor_test_claim_touched, - eq: fn(left, right) { left == right } - ) != 0 -} - -test fn floor_test_diff_policy_matches_ci_spec_holds() -> Bool { - floor_skip_git_diff_policy().base == "origin/main" - && floor_skip_git_diff_policy().head == "HEAD" - && floor_skip_git_diff_policy().mode == DiffMergeBase -} - -data floor_test_fn_edit_touch: FloorDiffLineTouch = FloorDiffLineTouch { - path: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag", - start_line: 74, - end_line: 74 -} - -data floor_test_fn_body_edit_touch: FloorDiffLineTouch = FloorDiffLineTouch { - path: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag", - start_line: 78, - end_line: 78 -} - -test fn floor_test_fn_declaration_edited_holds() -> Bool { - floor_test_fn_declaration_edited( - touches: [floor_test_fn_edit_touch], - file_path: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag", - test_fn_decl_line: 74, - test_fn_decl_end_line: 84 - ) - && floor_test_fn_declaration_edited( - touches: [floor_test_fn_body_edit_touch], - file_path: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag", - test_fn_decl_line: 74, - test_fn_decl_end_line: 84 - ) - && !floor_test_fn_declaration_edited( - touches: [floor_test_fn_edit_touch], - file_path: "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag", - test_fn_decl_line: 15, - test_fn_decl_end_line: 19 - ) -} - -test fn floor_test_rust_run_implies_dag_run_superset_holds() -> Bool { - floor_rust_run_implies_dag_run( - rust_touches_frontier: true, - rust_function_edited: false, - dag_touches_frontier: true, - dag_function_edited: false - ) - && floor_rust_run_implies_dag_run( - rust_touches_frontier: false, - rust_function_edited: true, - dag_touches_frontier: false, - dag_function_edited: true - ) - && floor_rust_run_implies_dag_run( - rust_touches_frontier: false, - rust_function_edited: false, - dag_touches_frontier: false, - dag_function_edited: false - ) - && !floor_rust_run_implies_dag_run( - rust_touches_frontier: true, - rust_function_edited: false, - dag_touches_frontier: false, - dag_function_edited: false - ) -} - diff --git a/src/v2/workflow/ci_floor_plan.dag b/src/v2/workflow/ci_floor_plan.dag deleted file mode 100644 index 78d88ed9fb1..00000000000 --- a/src/v2/workflow/ci_floor_plan.dag +++ /dev/null @@ -1,1678 +0,0 @@ -module v2.workflow.ci_floor_plan - -import std.execution_mode { Hermetic, Wet } -import gunbc.explicit_witness_admission { - known_red_probe_corpus_roster, - known_red_probe_corpus_fast_budget_roster, - known_red_probe_corpus_long_budget_roster, - known_red_probe_corpus_pre_verdict_fast_budget_roster, - known_red_probe_corpus_pre_verdict_long_budget_roster, - known_red_probe_v1_envelope_roster, - known_red_pre_verdict_refusal_roster -} -import gunbc.ci_layer_roots { witness_layer_roots, witness_exclusion_substrings, witness_discovery_scan_dirs, bin_witness_wet_entries, scoped_witness_batches, known_red_probe_roster, falsifier_silent_pick_gate_entries, falsifier_silent_pick_gate_roster, falsifier_rehomed_bin_wet_entries, falsifier_substrate_long_lane_entries, witness_long_eval_budget_entries } -import v2.compiler.self_host.wet_receipt_enrollment { - falsifier_self_host_wet_entries, - falsifier_native_cache_cold_roster, - falsifier_self_host_wet_cadence_is_active, - falsifier_self_host_wet_known_red_entries, - falsifier_self_host_wet_known_red_batch_enrolled, - falsifier_self_host_wet_known_red_roster -} -import gunbc.ci_materialization { ci_floor_expected_resolve_obligations, FloorFinalization } -import gunbc.ci_spec { - gunbc_ci_spec, gunbc_ci_regen_spec, CiSpec, - ci_spec_with_discovery_scan_dirs, - floor_plan_function, - plan_artifact_plan_function, - FloorBatchStopPolicy, - gunbc_ci_floor_batch_clamp_params, - gunbc_ci_compile_clean_clamp, - gunbc_ci_ordinary_floor_budget_minutes, - gunbc_ci_admission_postcondition_budget_minutes, -} -import gunbc.falsifier_workflow { falsifier_plan_function, gunbc_falsifier_soft_deadline_minutes } -import gunbc.falsifier_lane { - FalsifierLane, - LanePredictOnly, - LaneSelfHostWet, - LaneSelfHostWetKnownRed, - LaneKnownRedProbe, - LaneSilentPickGate, - LaneRehomedBinWet, - LaneSubstrateLongLane, - LaneCadenceWitness, - LaneGates, - FalsifierLaneEnrollment, - FalsifierPlannedComponent, - falsifier_planned_components -} -import gunbc.commit_workflow { commit_gate_roster, project_falsifier_witness_entries, project_falsifier_gates } -import gunbc.ci_gate { - Gate, EmitHostGate, CheapClaimPoolGate, - ExtdepsExternalAuthorityGate, DagCompileCleanGate, GeneratedArtifactDriftGate, ExtdepsScopePlacementGate, - ProseRowIntroductionGate, - SourceRootIngestGate, RegenVerifyGate, - SelfHostReadsRealBytesGate, SelfHostStalenessGate -} -import std.disposition { Disposition, Scaffold, SingleAuthority } -import std.decl_ref { DeclarationRef, WholeDeclaration } -import v2.std.algebra { filter, length, list_map, list_snoc_item, skip, zip_map } -import v2.std.collection { - List -} -import v2.std.optional { - Optional, - Absent, - Present -} -import v2.std.dependency { DataDependsOn, ResourceDependsOn, DependencyView } -import v2.std.node { Atom, Node, TypeNode, SyntheticOccurrence } -import v2.std.text { String } -import std.types { Int } -import std.content_hash { ContentHash, content_hash_of_value } -import std.nat { Nat } -import std.measure { Second, second, second_count, millisecond_count, minute_to_millisecond } -import std.realization_width { width_fold_objective_goals } -import std.realization_schedule { - SelectionApplied, - SelectionPredictOnly, - SelectionOff, - RealizationPlan, - RealizationObjective, - Runnable, - RunnableSingleClaim, - RunnableDiscoveryBatch, - RunnableScopedWitnessBatch, - ScopedWitnessBatch, - RunnableUsesFloorPositionalClamp, - RunnableOwnsBatchClamp, - runnable_batch_clamp_source, - ScheduleWitnessEntry, - WitnessKind, CorpusWitnessKind, ExecutionWitnessKind, NativeBundleWitnessKind, - RunnableResourceProfile, - runnable_resource_profile, - runnable_resource_profile_negligible, - runnable_memory_negligible, - runnable_memory_substantial, - runnable_excludes_corpus_co_residence, - runnable_heavy_whole_tree_resolve, - runnable_forbids_corpus_co_residence, - cost_account_predicted_zero, - runnable_step_label, - WalkPlan, - TypedClaimSubprocess, - NoPreWalkExecution, - NoWalkFinalization, - NoFinalizationDeclared, -} -import v2.lens.schedule_lens { walk_plan_schedule_lens_verdict_for_ci_floor, schedule_lens_batch_has_any_cheap_gate } -import v2.std.lens_verdict { Holds, NotApplicable, Unrealized, Violation } -import v2.workflow.executor { - ExecutorBatch -} -import v2.workflow.realization_runner { - RunnerScheduleBlocked, - RunnerScheduleComplete, - runner_ordering_only, - runner_schedule_plan_from_dependencies, - runner_schedule_store_covers_nodes -} - -data ci_floor_plan_resolve_finalization_transport_note: String = "0B AUTHORITY SPLIT: WalkPlan.finalization.expected_resolve_obligations projects gunbc.ci_materialization ci_floor_expected_resolve_obligations() unchanged — this plan does NOT author a second obligation roster. claim_executor records ResolveRealizationObservation at reuse sites and joins observed rows to the transported subjects." - -data ci_floor_target_digest: ContentHash = content_hash_of_value(value: "gunbc-ci-floor-v1") -data ci_floor_compile_gate_fn: String = "dag_compile_clean_gate_passes" - -data floor_gate_witness_entry: String = "dag/tools/floor_effect_gate_witness.dag" - -data floor_source_root_ingest_gate_entry: String = "src/v2/workflow/source_root_ingest_gate.dag" - -data floor_self_host_realized_comparison_gate_entry: String = "src/v2/workflow/self_host_realized_comparison_gate.dag" - -data floor_self_host_realized_comparison_claims_entry: String = "src/v2/workflow/self_host_realized_comparison_claims.dag" - -data floor_merge_admission_entry: String = "dag/tools/merge_admission_walk.dag" - -data floor_merge_admission_capture_entry: String = "dag/tools/merge_admission_capture.dag" - -data floor_merge_admission_capture_transport_entry: String = "dag/tools/merge_admission_capture_transport.dag" - -data floor_merge_admission_capture_transport_function: String = "run_merge_admission_capture_subprocess" - -data floor_merge_admission_capture_function: String = "capture_tested_subject" - -data floor_merge_admission_stamp_function: String = "stamp_tested_floor" - -data floor_merge_admission_gate_function: String = "refresh_current_target_and_gate" - -data floor_merge_admission_schedule_note: String = "The admission path is modeled as one typed pre-walk capture subprocess plus two singleton success stages. The child runs capture_tested_subject through gunbc.WitnessBin.Run before batch 1 and dies before the ordinary floor begins, so its evaluator arena cannot contaminate discovery residency. Any child refusal is located to the transport and subject claim and blocks the walk. Stamp and gate share one entry but may pay one resolve per singleton stage; their disk-visible receipts and barriers, not sibling order or cross-stage memo retention, carry the dependency, while fresh fetch and classification remain one composite stage-2 function. The two stage profiles are Wet, negligible, non-heavy, and non-host-compiler: the exact shape std.realization_schedule on_success_runnable_disposition admits." - -fn floor_merge_admission_profile() -> RunnableResourceProfile { - gate_profile_negligible_wet_declared() -} - -fn floor_merge_admission_stamp_runnable() -> Runnable { - RunnableSingleClaim { - entry: floor_merge_admission_entry, - function: floor_merge_admission_stamp_function, - profile: floor_merge_admission_profile() - } -} - -fn floor_merge_admission_gate_runnable() -> Runnable { - RunnableSingleClaim { - entry: floor_merge_admission_entry, - function: floor_merge_admission_gate_function, - profile: floor_merge_admission_profile() - } -} - -data gunbc_ci_cheap_floor_gate_membership: List = [ - GeneratedArtifactDriftGate, - ExtdepsExternalAuthorityGate, - ExtdepsScopePlacementGate, - ProseRowIntroductionGate, - CheapClaimPoolGate, -] - -data gunbc_ci_cheap_floor_gate_membership_note: String = "Declared cheap-floor gate membership (operator ruling 2026-07-22, fail-fast lane): the negligible-memory wet-declared gates (gate_profile_negligible_wet_declared) that check extdeps authority and generated-artifact drift — seconds each, no whole-tree compile. (The layering-imports direction gate was a member until the direction rule's deletion, operator ruling 2026-07-24; the publication-placement gate was deleted by operator ruling 2026-08-01.) They run in batch 0 BEFORE DagCompileCleanGate so an authority or drift violation reds in seconds instead of after the ~4min compile-clean anchor. WITHIN the cheap batch, GeneratedArtifactDriftGate is first: CheapClaimPoolGate was measured holding 9+ GiB for minutes as entry 0, and a later drift Bool(false) with HealNoChange + local green is consistent with running the live regenerate-and-compare pass after that pressure (CI #7765 @ d1e8d56). Membership is an explicit list, not inferred from profile fields, so enrollment changes are counted roster edits, never silent drift. Cheap gates are also floor_resource_anchor nodes: excluding them from discovery-flip corpus→gate serialization avoids a scheduler deadlock (cheap→compile data order requires cheap first; corpus→cheap resource order requires corpus first; compile→corpus data order closes the cycle). Dissolve-on: when per-gate cost attribution lands, derive from measurement." - -data gunbc_ci_cheap_floor_gate_membership_disposition: Disposition = Scaffold { - dissolves_to: SingleAuthority, - bind: DeclarationRef { - module_path: "v2.workflow.ci_floor_plan", - decl_name: "gunbc_ci_cheap_floor_gate_membership", - field: WholeDeclaration - } -} - -fn gate_in_cheap_floor_membership(g: Gate) -> Bool { - fold(gunbc_ci_cheap_floor_gate_membership, init: false, f: fn(found, member) { - match member { - CheapClaimPoolGate => match g { CheapClaimPoolGate => true _ => found } - ExtdepsExternalAuthorityGate => match g { ExtdepsExternalAuthorityGate => true _ => found } - GeneratedArtifactDriftGate => match g { GeneratedArtifactDriftGate => true _ => found } - ExtdepsScopePlacementGate => match g { ExtdepsScopePlacementGate => true _ => found } - ProseRowIntroductionGate => match g { ProseRowIntroductionGate => true _ => found } - _ => found - } - }) -} - -fn spec_enrolls_gate(spec: CiSpec, g: Gate) -> Bool { - fold(spec.gates, init: false, f: fn(found, sg) { - match sg { - CheapClaimPoolGate => match g { CheapClaimPoolGate => true _ => found } - ExtdepsExternalAuthorityGate => match g { ExtdepsExternalAuthorityGate => true _ => found } - GeneratedArtifactDriftGate => match g { GeneratedArtifactDriftGate => true _ => found } - ExtdepsScopePlacementGate => match g { ExtdepsScopePlacementGate => true _ => found } - ProseRowIntroductionGate => match g { ProseRowIntroductionGate => true _ => found } - DagCompileCleanGate => match g { DagCompileCleanGate => true _ => found } - EmitHostGate => match g { EmitHostGate => true _ => found } - SourceRootIngestGate => match g { SourceRootIngestGate => true _ => found } - RegenVerifyGate => match g { RegenVerifyGate => true _ => found } - SelfHostReadsRealBytesGate => match g { SelfHostReadsRealBytesGate => true _ => found } - SelfHostStalenessGate => match g { SelfHostStalenessGate => true _ => found } - } - }) -} - -fn floor_compile_depends_on_cheap_gate(g: Gate) -> DependencyView { - DependencyView { - source: gate_node(g: g), - dependent: floor_compile_root_node(), - kind: DataDependsOn, - usage_site: floor_compile_root_node() - } -} - -fn floor_cheap_gates_precede_compile_edges(spec: CiSpec) -> List { - fold(gunbc_ci_cheap_floor_gate_membership, init: [], f: fn(acc, g) { - if spec_enrolls_gate(spec: spec, g: g) { - list_snoc_item(xs: acc, item: floor_compile_depends_on_cheap_gate(g: g)) - } else { - acc - } - }) -} - -data floor_corpus_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^gunbc_floor_corpus } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -fn entry_kind_is_execution(w: ScheduleWitnessEntry) -> Bool { - match w.kind { - ExecutionWitnessKind => true - CorpusWitnessKind => false - NativeBundleWitnessKind => true - } -} - -fn corpus_witness_entries(spec: CiSpec) -> List { - filter(xs: spec.witness_entries, predicate: fn(w) { - !entry_kind_is_execution(w: w) - }) -} - -fn execution_witness_entries(spec: CiSpec) -> List { - filter(xs: spec.witness_entries, predicate: fn(w) { - entry_kind_is_execution(w: w) - }) -} - -fn bin_witness_corpus_enrolled(spec: CiSpec) -> Bool { - length(xs: spec.discovery_scan_dirs) > 0 && length(xs: bin_witness_wet_entries) > 0 -} - -fn corpus_plan_nodes(spec: CiSpec) -> List { - concat( - if length(xs: corpus_witness_entries(spec: spec)) > 0 || length(xs: spec.discovery_scan_dirs) > 0 { [floor_corpus_node] } else { [] }, - concat( - if length(xs: execution_witness_entries(spec: spec)) > 0 { [execution_corpus_node] } else { [] }, - if bin_witness_corpus_enrolled(spec: spec) { [bin_witness_corpus_node] } else { [] } - ) - ) -} - -fn gate_node(g: Gate) -> Node { - match g { - EmitHostGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_emit } }, children: [], occurrence_id: SyntheticOccurrence } - CheapClaimPoolGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_cheap_claim_pool } }, children: [], occurrence_id: SyntheticOccurrence } - ExtdepsExternalAuthorityGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_extdeps_external_authority } }, children: [], occurrence_id: SyntheticOccurrence } - DagCompileCleanGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_compile } }, children: [], occurrence_id: SyntheticOccurrence } - GeneratedArtifactDriftGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_generated_artifact } }, children: [], occurrence_id: SyntheticOccurrence } - ExtdepsScopePlacementGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_extdeps_scope_placement } }, children: [], occurrence_id: SyntheticOccurrence } - ProseRowIntroductionGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_prose_row_introduction } }, children: [], occurrence_id: SyntheticOccurrence } - SourceRootIngestGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_sourceingest } }, children: [], occurrence_id: SyntheticOccurrence } - RegenVerifyGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_regen_verify } }, children: [], occurrence_id: SyntheticOccurrence } - SelfHostReadsRealBytesGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_self_host_reads_real_bytes } }, children: [], occurrence_id: SyntheticOccurrence } - SelfHostStalenessGate => Node { kind: TypeNode { connective: Atom { identity: ^gunbc_floor_gate_self_host_staleness } }, children: [], occurrence_id: SyntheticOccurrence } - } -} - -fn floor_compile_root_node() -> Node { - gate_node(g: DagCompileCleanGate) -} - -fn floor_resource_anchor_node(node: Node) -> Bool { - (node == floor_compile_root_node()) - || (node == floor_corpus_node) - || (node == execution_corpus_node) - || (node == bin_witness_corpus_node) - || fold(gunbc_ci_cheap_floor_gate_membership, init: false, f: fn(acc, g) { - acc || (node == gate_node(g: g)) - }) -} - -data gate_profile_memory_marker_note: String = "Gate memory classes are structural markers (Negligible vs Substantial) since the 2026-07-12 adaptive-width ruling: the fabricated per-gate byte predictions (per-shard peak, host-compiler spawn peak, and their sums) retired with the width folds they fed. Run-time concurrency is governed by the executor's memory governor against the slot's own cgroup budget; the marker still feeds co-residence structure (runnable_excludes_corpus_co_residence)." - -fn gate_runnable_profile(g: Gate) -> RunnableResourceProfile { - let substantial = runnable_memory_substantial() - match g { - DagCompileCleanGate => - runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: false, - memory: substantial, - execution_mode: Wet - ) - SourceRootIngestGate => - runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: false, - memory: substantial, - execution_mode: Wet - ) - RegenVerifyGate => - runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: true, - memory: substantial, - execution_mode: Wet - ) - SelfHostReadsRealBytesGate => - runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: true, - memory: substantial, - execution_mode: Wet - ) - SelfHostStalenessGate => - runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: true, - memory: substantial, - execution_mode: Wet - ) - EmitHostGate => - runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: true, - memory: substantial, - execution_mode: Wet - ) - CheapClaimPoolGate => gate_profile_negligible_wet_declared() - ExtdepsExternalAuthorityGate => gate_profile_negligible_wet_declared() - GeneratedArtifactDriftGate => gate_profile_negligible_wet_declared() - ExtdepsScopePlacementGate => gate_profile_negligible_wet_declared() - ProseRowIntroductionGate => gate_profile_negligible_wet_declared() - } -} - -data gate_profile_wet_declaration_note: String = "Every floor GATE declares execution_mode: Wet explicitly — an honest declaration of pre-existing reality (the executor hardwired ExecutionMode::Wet at every witness-execution site until the profile field landed), kept while gates run effectful work (fmt/nextest, emit-host, regen, compile-clean shell receipts). The negligible-memory gates (extdeps external-authority scan and generated-artifact drift) are wet-DECLARED via gate_profile_negligible_wet_declared; per-gate hermetic tightening is a follow-on, each flip proven by a green hermetic run of that gate entry. The DISCOVERY and FALSIFIER corpus batches flipped to Hermetic with the audit receipt (claim_batch default-hermetic census 2026-07-12: 1042 PASS / 105 FAIL before remediation; the mode-typed refusals zeroed by the Filesystem.Read checkout carve-out, the git.Inspect.Toplevel checkout-root mock case, and the six wet-integration offline rows in gunbc.ci_layer_roots — see wet_integration_offline_note). The fail-closed default (runnable_resource_profile_negligible = Hermetic, absent profile = Hermetic at the executor) applies to every NEW runnable: an undeclared live effect refuses with a typed, located diagnostic instead of dispatching." - -fn gate_profile_negligible_wet_declared() -> RunnableResourceProfile { - runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: false, - memory: runnable_memory_negligible(), - execution_mode: Wet - ) -} - -fn gate_runnable(g: Gate) -> Runnable { - let profile = gate_runnable_profile(g: g) - match g { - EmitHostGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "emit_host_gate_passes", profile: profile } - CheapClaimPoolGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "cheap_claim_pool_gate_passes", profile: profile } - ExtdepsExternalAuthorityGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "extdeps_external_authority_gate_passes", profile: profile } - DagCompileCleanGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "dag_compile_clean_gate_passes", profile: profile } - GeneratedArtifactDriftGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "generated_artifact_drift_gate_passes", profile: profile } - ExtdepsScopePlacementGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "extdeps_scope_placement_gate_passes", profile: profile } - ProseRowIntroductionGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "prose_row_introduction_gate_passes", profile: profile } - SourceRootIngestGate => RunnableSingleClaim { - entry: floor_source_root_ingest_gate_entry, - function: "source_root_ingest_gate_passes", - profile: profile - } - RegenVerifyGate => RunnableSingleClaim { entry: floor_gate_witness_entry, function: "regen_verify_gate_passes", profile: profile } - SelfHostReadsRealBytesGate => RunnableSingleClaim { - entry: floor_self_host_realized_comparison_gate_entry, - function: "self_host_realized_comparison_reads_real_bytes_gate_holds", - profile: profile - } - SelfHostStalenessGate => RunnableSingleClaim { - entry: floor_self_host_realized_comparison_gate_entry, - function: "self_host_realized_comparison_staleness_gate_holds", - profile: profile - } - } -} - -fn cheap_floor_gate_step_labels() -> List { - list_map( - xs: gunbc_ci_cheap_floor_gate_membership, - f: fn(g) { runnable_step_label(r: gate_runnable(g: g)) } - ) -} - -fn floor_batch_has_any_cheap_gate(batch: List) -> Bool { - schedule_lens_batch_has_any_cheap_gate(batch: batch, cheap_gate_labels: cheap_floor_gate_step_labels()) -} - -fn gunbc_ci_floor_batch_stop_policy_for_github_event(event: String) -> FloorBatchStopPolicy { - match event { - "pull_request" => StopBeforeDependents - _ => FullLedger - } -} - -fn gunbc_ci_floor_plan_uses_batch_stop_policy(plan_function: String) -> Bool { - (plan_function == floor_plan_function) - || (plan_function == plan_artifact_plan_function) - || (plan_function == falsifier_plan_function) -} - -fn gunbc_ci_floor_enrolled_runnable_labels_for(spec: CiSpec) -> List { - let gate_labels = list_map(xs: spec.gates, f: fn(g) { - runnable_single_claim_function(r: gate_runnable(g: g)) - }) - let corpus_labels = list_map(xs: corpus_plan_nodes(spec: spec), f: fn(node) { - runnable_single_claim_function(r: runnable_for_node(node: node, spec: spec)) - }) - let spec_labels = concat(concat(gate_labels, corpus_labels), map(scoped_witness_batches, batch => "__scoped_witness_batch__")) - if gunbc_pr_native_batch_enrolled() { - list_snoc_item(xs: spec_labels, item: runnable_single_claim_function(r: gunbc_pr_native_batch())) - } else { - spec_labels - } -} - -fn gunbc_ci_floor_schedule_runnable_labels(batches: List>) -> List { - fold(batches, init: [], f: fn(acc, batch) { - fold(batch, init: acc, f: fn(inner, r) { - list_snoc_item(xs: inner, item: runnable_single_claim_function(r: r)) - }) - }) -} - -fn runnable_is_discovery_batch(r: Runnable) -> Bool { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => true - RunnableScopedWitnessBatch { batch: _ } => true - RunnableSingleClaim { entry: _, function: _, profile: _ } => false - RunnableKernelWorkload { fused_op_count: _ } => false - } -} - -fn batch_has_discovery_corpus(batch: List) -> Bool { - fold(batch, init: false, f: fn(found, r) { found || runnable_is_discovery_batch(r: r) }) -} - -fn witness_cheap_gates_only_in_early_batch(batches: List>) -> Bool { - fold(cheap_floor_gate_step_labels(), init: true, f: fn(ok, label) { - ok && floor_batch_contains_function(batch: batches.first(), target: label) - }) - && fold(skip(xs: batches, n: 1), init: true, f: fn(ok, batch) { - ok && !floor_batch_has_any_cheap_gate(batch: batch) - }) -} - -fn witness_no_corpus_batch_contains_cheap_gate(batches: List>) -> Bool { - fold(batches, init: true, f: fn(ok, batch) { - if batch_has_discovery_corpus(batch: batch) { - ok && !floor_batch_has_any_cheap_gate(batch: batch) - } else { - ok - } - }) -} - -fn witness_cheap_gates_precede_all_corpus_batches() -> Bool { - let batches = gunbc_ci_floor_ordinary_batches() - witness_cheap_gates_only_in_early_batch(batches: batches) - && witness_no_corpus_batch_contains_cheap_gate(batches: batches) -} - -fn witness_non_cheap_gate_absent_from_early_batch() -> Bool { - !floor_batch_contains_function( - batch: gunbc_ci_floor_ordinary_batches().first(), - target: ci_floor_compile_gate_fn - ) -} - -fn witness_floor_stop_policy_pr_is_fail_fast() -> Bool { - match gunbc_ci_floor_batch_stop_policy_for_github_event(event: "pull_request") { - StopBeforeDependents => true - FullLedger => false - } -} - -fn witness_floor_stop_policy_push_is_full_ledger() -> Bool { - match gunbc_ci_floor_batch_stop_policy_for_github_event(event: "push") { - FullLedger => true - StopBeforeDependents => false - } -} - -fn witness_floor_stop_policy_unknown_defaults_full_ledger() -> Bool { - match gunbc_ci_floor_batch_stop_policy_for_github_event(event: "__unknown_event__") { - FullLedger => true - StopBeforeDependents => false - } -} - -fn witness_floor_batch_stop_policy_plan_roster_enrolled() -> Bool { - gunbc_ci_floor_plan_uses_batch_stop_policy(plan_function: floor_plan_function) - && gunbc_ci_floor_plan_uses_batch_stop_policy(plan_function: plan_artifact_plan_function) - && gunbc_ci_floor_plan_uses_batch_stop_policy(plan_function: falsifier_plan_function) - && !gunbc_ci_floor_plan_uses_batch_stop_policy(plan_function: "bre_claim_batches") -} - -fn corpus_source_roots() -> List { - witness_layer_roots -} - -data gunbc_ci_adaptive_width_note: String = "Adaptive width (operator ruling 2026-07-12, superseding the pinned-cap regime): the plan no longer authors spawn widths or per-shard byte predictions — the retired machinery was gunbc_ci_corpus_discovery_spawn_width_cap (pinned 1 after the run 28999086030 width=2 OOM), the per-plan *_plan_spawn_width fns the executor evaluated by name, and the gunbc.ci_floor_measurement width folds over hand-edited peak samples (pins freezing derivations: stale samples predated the enrollment flip, and the base-overhead re-measure chased its own tail — the July OOM/wedge regime). The executor now governs concurrency at run time: v1_compiler::memory_governor admits workers AIMD-style against the slot's OWN declared budget (memory.high else memory.max else MemAvailable else MemTotal — MemAvailable precedes MemTotal on uncapped hosts because the kernel's availability estimate excludes the co-tenant baseline that let run 29180195694 reach physical RAM; GUNBC_MEMORY_BUDGET_BYTES to override). Admission is paced (at most one worker whose front-loaded index-build cost has not yet landed), predictive (the run measures its first worker's share over the pool baseline and admits only while current + share fits under high-water), and ceilinged at half the budget — the maturation reserve: the 2026-07-12 run series proved admitted demand matures minutes after admission at ~7x its digest-time footprint, so reactive arms alone always observe it too late and half the pipe stays reserved for in-flight growth. The creep-episode edge (memory.current high-water, PSI some avg10, swap growth) halves the window AND holds admissions — early congestion is TCP's ECN, not a stop-and-hope — while hard events halve it again (memory.events high/oom_kill deltas) and memory.current crossing the declared budget itself collapses the window to one (the reachable loss signal on uncapped hosts, where memory.events never fires); the width-1 progress floor still guarantees forward motion. The window re-grows additively on calm completions. Every hold/back-off is typed, counted, and surfaced in the [governor] receipt line (DESIGN §5: loud bounded degradation, never an absorbing widen). Dissolve-on: graph-derived per-node demand (CostAccount.space measured, the realization-measurement lane) replaces the reactive estimator and the governor demotes to a safety net." - -data gunbc_ci_fast_lane_rule_note: String = "Fast-lane 5-second rule (operator ruling 2026-07-12): a witness whose OWN eval takes 5 seconds or longer does not run in per-PR discovery — it lives under a long/ test dir (dag/test/claim/long/, src/v2/test/claim/long/), excluded from discovery at dir grain (gunbc.ci_layer_roots) and triggered independently (local recipe: claim_batch --source-root dag --source-root src/v2 --entry --functions ; scheduled-lane enrollment rides the falsifier follow-on). Enforcement is by execution, not census: the executor arms a cooperative per-witness eval deadline from the budget row below (v1_interpreter EvalBudgetExceeded — a typed FAIL row naming the over-budget witness; the bound unwinds from INSIDE eval because in-process worker threads have no kill authority, the Phase A governor lesson). The deadline arms at eval start, so resolve/index cost is infra and never counted against the witness (the operator's carve-out: 'assuming the infra isn't the problem'). This is also the wedge tourniquet: an unbounded eval that previously burned the 270-minute step cap in billed silence (run 29183446733: 243 of 270 minutes after the last progress line, zero witnesses completed) now fails red in seconds with its name in the log. Dissolve-on: per-witness declared cost envelopes (the witness-cost-locality admission law) replace the blanket lane budget with declared rows." - -data gunbc_ci_fast_lane_witness_eval_budget: Second = second(count: 5) - -fn gunbc_ci_fast_lane_eval_budget_ms() -> v2.std.nat.Nat { - second_count(s: gunbc_ci_fast_lane_witness_eval_budget) * 1000 -} - -fn gunbc_ci_floor_batch_clamp_overhead_seconds() -> List { - map(gunbc_ci_floor_batch_clamp_params, c => second_count(s: c.overhead)) -} - -fn gunbc_ci_floor_batch_clamp_per_unit_ms() -> List { - map(gunbc_ci_floor_batch_clamp_params, c => millisecond_count(m: c.per_unit)) -} - -// The positional clamp's citation is PROJECTED from the same rows the numbers come from, never -// spelled in the executor's format string. That is the difference between a diagnostic whose -// authority is derived and one that merely agrees with the model until someone edits one of them: -// a hardcoded citation stays green while the value it names moves, which is exactly the failure -// this pair exists to make unwritable (std.realization_schedule RunnableBatchClamp). -fn gunbc_ci_floor_batch_clamp_authority_modules() -> List { - map(gunbc_ci_floor_batch_clamp_params, c => c.authority.module_path) -} - -fn gunbc_ci_floor_batch_clamp_authority_decls() -> List { - map(gunbc_ci_floor_batch_clamp_params, c => c.authority.decl_name) -} - -fn gunbc_ci_compile_clean_clamp_overhead_seconds() -> Int { - second_count(s: gunbc_ci_compile_clean_clamp.overhead) -} - -fn gunbc_ci_compile_clean_clamp_rate_per_unit_ms() -> Int { - millisecond_count(m: gunbc_ci_compile_clean_clamp.per_unit) -} - -fn gunbc_ci_compile_clean_clamp_ms(units: Int) -> Int { - (second_count(s: gunbc_ci_compile_clean_clamp.overhead) * 1000) + (units * millisecond_count(m: gunbc_ci_compile_clean_clamp.per_unit)) -} - -fn gunbc_ci_compile_clean_wall_exceeds_clamp(observed_ms: Int, units: Int) -> Bool { - observed_ms > gunbc_ci_compile_clean_clamp_ms(units: units) -} - -fn witness_floor_batch_clamp_params_cover_schedule() -> Bool { - let positional_batches = fold(gunbc_ci_floor_ordinary_batches(), init: 0, f: fn(count, batch) { - if fold(batch, init: false, f: fn(found, runnable) { - found || match runnable_batch_clamp_source(r: runnable) { - RunnableUsesFloorPositionalClamp => true - RunnableOwnsBatchClamp { clamp: _ } => false - } - }) { - count + 1 - } else { - count - } - }) - length(xs: gunbc_ci_floor_batch_clamp_params) == positional_batches -} - -fn witness_floor_batch_clamp_overhead_all_positive() -> Bool { - fold(gunbc_ci_floor_batch_clamp_overhead_seconds(), init: true, f: fn(ok, b) { ok && (b > 0) }) -} - -fn witness_floor_batch_clamp_rate_all_nonneg() -> Bool { - fold(gunbc_ci_floor_batch_clamp_per_unit_ms(), init: true, f: fn(ok, b) { ok && (b >= 0) }) -} - -data gunbc_falsifier_self_host_wet_receipt_budget_note: String = "Whole-receipt wall-time budget for the nightly falsifier Wet self-host lane (operator ruling 2026-07-15, Wave 2 CI substrate STEP 3; kill-at-deadline 2026-07-25): bounds emit+cargo total wall time per witness — the wet receipt IS each module's Definition-of-Done, and cargo dominates (std/logic template ~101s wall, 06_translate ~52s measured Refinement-1). claim_executor arms this budget for discovery batches whose explicit entries intersect falsifier_self_host_wet_entries OR falsifier_self_host_wet_known_red_entries — never for silent-pick (owns gunbc_falsifier_silent_pick_gate_receipt_wall_budget) or rehomed bin. Primary refusal is WitnessWallBudgetExceeded: shell waits kill the process group at the ceiling (Finding 1 kill-at-deadline); wall_budget_completion_outcome remains the completion-side backstop. Secondary gunbc_falsifier_self_host_wet_interp_eval_budget arms the cooperative CPU eval deadline for interpreter-wedge detection only (subprocess cargo I/O is wall-counted, not CPU-counted). Receipted ceilings: logic template 101s, 06_translate 52s — 600s per receipt leaves headroom for larger modules while keeping 11-module upper bound (~9.5min measured) far under the 270m falsifier step budget. A raise requires a dated re-basis note (same discipline as floor batch walls) — never to absorb a cache-cold host." - -data gunbc_falsifier_self_host_wet_receipt_wall_budget: Second = second(count: 600) - -fn gunbc_falsifier_self_host_wet_receipt_wall_budget_ms() -> v2.std.nat.Nat { - second_count(s: gunbc_falsifier_self_host_wet_receipt_wall_budget) * 1000 -} - -data gunbc_falsifier_self_host_wet_interp_eval_budget: Second = second(count: 120) - -fn gunbc_falsifier_self_host_wet_interp_eval_budget_ms() -> v2.std.nat.Nat { - second_count(s: gunbc_falsifier_self_host_wet_interp_eval_budget) * 1000 -} - -data gunbc_falsifier_silent_pick_gate_receipt_budget_note: String = "Whole-receipt wall-time budget for the nightly falsifier silent-pick gate (review #7199 2026-07-25): after the category-error fix removed the mis-scoped self-host 600s ceiling, this row must not go unbudgeted — it is the largest corpus-denominated computational witness on the falsifier and grows with the tree. Basis (two-tier: worst host + spread): run 30164623968 srv3-04 PASS at 717940ms; prior fail-under-mis-scope 30158767015 at 707687ms; main-class cold 30160229060 at 815018ms. Worst observed 815s + ~100s host spread → 900s dated ceiling. Kill-at-deadline applies (same WitnessWallBudgetExceeded arm). Raise requires an appended dated re-basis — never a silent widen." - -data gunbc_falsifier_silent_pick_gate_receipt_wall_budget: Second = second(count: 900) - -fn gunbc_falsifier_silent_pick_gate_receipt_wall_budget_ms() -> v2.std.nat.Nat { - second_count(s: gunbc_falsifier_silent_pick_gate_receipt_wall_budget) * 1000 -} - -data gunbc_falsifier_substrate_long_lane_budget_note: String = "Per-witness eval budget for the Hermetic substrate long lane (falsifier batch 6), dated 2026-07-26. WHY IT EXISTS: budgets are scoped by LANE, never by witness kind. claim_executor previously selected the eval ceiling by execution_mode.is_hermetic(), so every Hermetic batch inherited gunbc_ci_fast_lane_witness_eval_budget — including the one lane whose entire purpose is hosting rows OVER that budget. The lane's first scheduled execution (run 30176416535, 2026-07-25) reddened with 7 of 10 rows killed at 5001-5013ms by a refusal whose own text says the row 'lives in a long/ test dir and runs via its dedicated lane': the budget had followed it there. The executor now arms this row for discovery batches whose explicit entries intersect falsifier_substrate_long_lane_entries, and the residual (Hermetic, no lane roster) keeps the fast lane — so a future lane that forgets to declare a ceiling reds loudly at 5s rather than running unbounded (the arm narrows, never widens, DESIGN 5). BASIS (two-tier: worst row + host spread; all ten rows measured by execution, cold, local, 2026-07-26 — CI had never produced a green row on this lane). Seven affected_set_provenance_producer rows: 11906, 12213, 12229, 12714, 13032, 13654, 13770ms. Two edit_locus_source_provenance rows: 12384, 12558ms — measurable only after repair, since both were self-recursing wrappers that had never executed (edit_locus_source_provenance_wrapper_shadowing_note). One wave1_gate1_d census row: 126921ms here, 134526ms on the merry-ibex-306 cold run 2026-07-25 (the worst observed, and the row's declared basis). Worst observed 134.5s + host spread (the floor runs under adaptive-width memory pressure; the silent-pick lane's receipted spread was ~12% of an 815s row) -> 180s dated ceiling. Same shape as the wet lanes: one lane ceiling sized to its worst row, not per-row envelopes. A raise requires an appended dated re-basis — never a silent widen to absorb a slow host. Dissolve-on: per-witness declared cost envelopes (the witness-cost-locality admission law, the same trigger gunbc_ci_fast_lane_rule_note names) replace every blanket lane budget with declared per-row rows." - -data gunbc_falsifier_substrate_long_lane_witness_eval_budget: Second = second(count: 180) - -fn gunbc_falsifier_substrate_long_lane_eval_budget_ms() -> v2.std.nat.Nat { - second_count(s: gunbc_falsifier_substrate_long_lane_witness_eval_budget) * 1000 -} - -data gunbc_falsifier_soft_deadline_projection_note: String = "A UNIT PROJECTION, NOT A SECOND BUDGET. The value is gunbc.falsifier_workflow gunbc_falsifier_soft_deadline_minutes, which is itself derived by subtracting the flush allowance from the step timeout the workflow declares — this function only converts that one authority's minutes into the milliseconds the seed's budget seam reads, exactly as gunbc_falsifier_substrate_long_lane_eval_budget_ms converts seconds beside it. Re-deriving the subtraction here, or writing the minute count as a literal, would be a second representation of a number whose whole correctness property is that it stays below the cap it is subtracted from." - -fn gunbc_falsifier_soft_deadline_ms() -> Int { - gunbc_falsifier_soft_deadline_minutes() * 60 * 1000 -} - -// THE THREE ORDINARY-FLOOR WITNESS BATCHES RUN THEIR WHOLE ROSTER (operator directive -// 2026-08-13: "just run all the witnesses unconditionally, since they don't actually take -// very long anyway"). This batch, execution_corpus_runnable_for and -// bin_witness_corpus_runnable_for carry SelectionOff; the falsifier cadence lanes, the -// expect-red quarantine probes and the v1 scoped batch are deliberately unchanged and -// named in corpus_selection_off_note below. -// -// WHY THE PREMISE HOLDS, measured rather than assumed: on the last main run to complete -// (31672107941) the corpus node reported resolve 931.0s against evalu 96.1s across 9024 -// discovered witnesses, of which 4840 were skipped. Evaluation is ~9% of the node and the -// preparation it gates is the other ~91%, so selection was buying avoided PREPARATION, -// not avoided checking -- and that preparation is the entry-major defect the floor -// program exists to remove, not a cost worth building a second mechanism to dodge. -fn corpus_runnable_for(spec: CiSpec) -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: spec.discovery_scan_dirs, - explicit_entries: corpus_witness_entries(spec: spec), - node_frontier_selection: SelectionOff, - exclude_substrings: witness_exclusion_substrings(), - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: false, - memory: runnable_memory_substantial(), - execution_mode: Hermetic - ) - } -} - -data execution_corpus_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^gunbc_floor_execution_corpus } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -fn execution_corpus_runnable_for(spec: CiSpec) -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: execution_witness_entries(spec: spec), - node_frontier_selection: SelectionOff, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: false, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -data bin_witness_corpus_node: Node = Node { - kind: TypeNode { connective: Atom { identity: ^gunbc_floor_bin_witness_corpus } }, - children: [], - occurrence_id: SyntheticOccurrence -} - -data bin_witness_corpus_note: String = "The bin-execution witness batch: the declared Wet lane for witnesses whose fns execute compiled seed witness binaries (gunbc.ci_layer_roots bin_witness_wet_entries — see bin_witness_wet_note there). They ran silently wet inside the discovery corpus until the hermetic flip; now the discovery batch is Hermetic and these rows keep their per-PR coverage under an explicit Wet profile (spawns_host_compiler: the runner may cargo-build a missing witness bin locally; in CI the build job prebuilds them). Enrolled only when the spec runs live discovery (bin_witness_corpus_enrolled), so regen/emit-determinism/synthetic specs carry no bin batch." - -fn bin_witness_corpus_runnable_for() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: bin_witness_wet_entries, - node_frontier_selection: SelectionOff, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -fn floor_nodes(spec: CiSpec) -> List { - let roots = corpus_plan_nodes(spec: spec) - fold(spec.gates, init: roots, f: fn(acc, g) { - list_snoc_item(xs: acc, item: gate_node(g: g)) - }) -} - -fn floor_depends_on_compile(dependent: Node) -> DependencyView { - DependencyView { - source: floor_compile_root_node(), - dependent: dependent, - kind: DataDependsOn, - usage_site: dependent - } -} - -fn floor_resource_depends_on(source: Node, dependent: Node) -> DependencyView { - DependencyView { - source: source, - dependent: dependent, - kind: ResourceDependsOn, - usage_site: dependent - } -} - -fn floor_corpus_exclusion_resource_edges(spec: CiSpec) -> List { - let corpus_nodes = corpus_plan_nodes(spec: spec) - let floor_present = length(xs: corpus_witness_entries(spec: spec)) > 0 || length(xs: spec.discovery_scan_dirs) > 0 - let after_floor_corpus = concat( - if floor_present && length(xs: execution_witness_entries(spec: spec)) > 0 { - [floor_resource_depends_on(source: floor_corpus_node, dependent: execution_corpus_node)] - } else { - [] - }, - if floor_present && bin_witness_corpus_enrolled(spec: spec) { - [floor_resource_depends_on(source: floor_corpus_node, dependent: bin_witness_corpus_node)] - } else { - [] - } - ) - fold(spec.gates, init: after_floor_corpus, f: fn(acc, g) { - let node = gate_node(g: g) - if floor_resource_anchor_node(node: node) { - acc - } else if runnable_excludes_corpus_co_residence(profile: gate_runnable_profile(g: g)) { - fold(corpus_nodes, init: acc, f: fn(edges, corpus_node) { - list_snoc_item( - xs: edges, - item: floor_resource_depends_on(source: corpus_node, dependent: node) - ) - }) - } else { - acc - } - }) -} - -fn floor_heavy_resolve_chain_resource_edges(spec: CiSpec) -> List { - let heavy_nodes = fold(spec.gates, init: [], f: fn(acc, g) { - let node = gate_node(g: g) - if floor_resource_anchor_node(node: node) { - acc - } else if runnable_heavy_whole_tree_resolve(profile: gate_runnable_profile(g: g)) { - list_snoc_item(xs: acc, item: node) - } else { - acc - } - }) - zip_map( - a: heavy_nodes, - b: skip(xs: heavy_nodes, n: 1), - f: fn(prev, next) { - floor_resource_depends_on(source: prev, dependent: next) - } - ) -} - -fn floor_spec_has_compile_gate(spec: CiSpec) -> Bool { - fold(spec.gates, init: false, f: fn(acc, g) { - match g { - DagCompileCleanGate => true - _ => acc - } - }) -} - -fn floor_data_dependencies(spec: CiSpec) -> List { - if floor_spec_has_compile_gate(spec: spec) { - concat( - floor_cheap_gates_precede_compile_edges(spec: spec), - fold( - spec.gates, - init: fold(corpus_plan_nodes(spec: spec), init: [], f: fn(acc, corpus_node) { - list_snoc_item(xs: acc, item: floor_depends_on_compile(dependent: corpus_node)) - }), - f: fn(acc, g) { - match g { - DagCompileCleanGate => acc - _ => - if gate_in_cheap_floor_membership(g: g) { - acc - } else { - list_snoc_item( - xs: acc, - item: floor_depends_on_compile(dependent: gate_node(g: g)) - ) - } - } - } - ) - ) - } else { - [] - } -} - -fn floor_regen_emit_artifact_resource_edges(spec: CiSpec) -> List { - let has_staleness = fold(spec.gates, init: false, f: fn(acc, g) { - match g { - SelfHostStalenessGate => true - _ => acc - } - }) - let has_regen = fold(spec.gates, init: false, f: fn(acc, g) { - match g { - RegenVerifyGate => true - _ => acc - } - }) - if has_staleness && has_regen { - [ - floor_resource_depends_on( - source: gate_node(g: RegenVerifyGate), - dependent: gate_node(g: SelfHostStalenessGate) - ) - ] - } else { - [] - } -} - -data gunbc_ci_corpus_discovery_batch_isolation_note: String = "Discovery-flip batch isolation under cheap-gate-early ordering (operator ruling 2026-07-22, fail-fast lane; run 29120615071 receipt retained under adaptive width): when discovery_scan_dirs is non-empty, resource edges from every enrolled corpus plan node (floor_corpus_node, execution_corpus_node when ExecutionWitnessKind rows exist, bin_witness_corpus_node when enrolled) to every non-anchor gate still isolate corpus batches from gates so gates start only after discovery completes and walk_memo holds the shared index. Cheap gates are floor_resource_anchor nodes and are EXCLUDED from corpus→gate serialization (the anchor carve-out): cheap→compile data deps require cheap first; corpus→cheap would deadlock with compile→corpus data order; anchors break the cycle by letting cheap gates run without waiting behind corpus while still feeding walk_memo to later gates. Dissolve-on: when per-gate cost attribution lands, derive from measurement." - -fn floor_discovery_flip_corpus_serializes_before_gates_edges(spec: CiSpec) -> List { - if length(xs: spec.discovery_scan_dirs) > 0 { - let corpus_nodes = corpus_plan_nodes(spec: spec) - fold(spec.gates, init: [], f: fn(acc, g) { - let node = gate_node(g: g) - if floor_resource_anchor_node(node: node) { - acc - } else { - fold(corpus_nodes, init: acc, f: fn(edges, corpus_node) { - list_snoc_item( - xs: edges, - item: floor_resource_depends_on(source: corpus_node, dependent: node) - ) - }) - } - }) - } else { - [] - } -} - -fn floor_discovery_flip_corpus_gate_serialization_edge_count(spec: CiSpec) -> Int { - floor_non_anchor_gate_count(spec: spec) * length(xs: corpus_plan_nodes(spec: spec)) -} - -fn floor_non_anchor_gate_count(spec: CiSpec) -> Int { - fold(spec.gates, init: 0, f: fn(count, g) { - if floor_resource_anchor_node(node: gate_node(g: g)) { count } else { count + 1 } - }) -} - -fn floor_resource_dependencies(spec: CiSpec) -> List { - concat( - floor_discovery_flip_corpus_serializes_before_gates_edges(spec: spec), - concat( - floor_corpus_exclusion_resource_edges(spec: spec), - concat( - floor_heavy_resolve_chain_resource_edges(spec: spec), - floor_regen_emit_artifact_resource_edges(spec: spec) - ) - ) - ) -} - -fn floor_dependencies_with(spec: CiSpec, serialize_heavy: Bool) -> List { - let data_deps = floor_data_dependencies(spec: spec) - if serialize_heavy { - concat(data_deps, floor_resource_dependencies(spec: spec)) - } else { - data_deps - } -} - -fn floor_unrunnable_sentinel() -> Runnable { - RunnableSingleClaim { - entry: "", - function: "__gunbc_ci_floor_unmapped__", - profile: runnable_resource_profile_negligible() - } -} - -fn runnable_for_node(node: Node, spec: CiSpec) -> Runnable { - if node == floor_corpus_node { - corpus_runnable_for(spec: spec) - } else if node == execution_corpus_node { - execution_corpus_runnable_for(spec: spec) - } else if node == bin_witness_corpus_node { - bin_witness_corpus_runnable_for() - } else { - fold(spec.gates, init: floor_unrunnable_sentinel(), f: fn(acc, g) { - if node == gate_node(g: g) { gate_runnable(g: g) } else { acc } - }) - } -} - -fn runnables_for_batch(batch: ExecutorBatch, spec: CiSpec) -> List { - fold(batch.jobs, init: [], f: fn(acc, job) { - list_snoc_item(xs: acc, item: runnable_for_node(node: job.node, spec: spec)) - }) -} - -fn runnables_for_executor_batches(batches: List, spec: CiSpec) -> List> { - fold(batches, init: [], f: fn(acc, batch) { - list_snoc_item(xs: acc, item: runnables_for_batch(batch: batch, spec: spec)) - }) -} - -fn floor_schedule_via_runner_for(spec: CiSpec, serialize_heavy: Bool) -> List> { - match runner_schedule_plan_from_dependencies( - nodes: floor_nodes(spec: spec), - dependencies: floor_dependencies_with(spec: spec, serialize_heavy: serialize_heavy), - value: runner_ordering_only - ) { - RunnerScheduleComplete { batches: batches, store: store } => - if runner_schedule_store_covers_nodes(store: store, nodes: floor_nodes(spec: spec)) { - runnables_for_executor_batches(batches: batches, spec: spec) - } else { - [[floor_unrunnable_sentinel()]] - } - RunnerScheduleBlocked { evidence: _ } => [[floor_unrunnable_sentinel()]] - } -} - -fn floor_schedule_for(spec: CiSpec, serialize_heavy: Bool) -> List> { - floor_schedule_via_runner_for(spec: spec, serialize_heavy: serialize_heavy) -} - -fn gunbc_ci_floor_schedule_inner() -> List> { - floor_schedule_for(spec: gunbc_ci_spec, serialize_heavy: true) -} - -fn gunbc_ci_floor_realization_plan_for(spec: CiSpec) -> RealizationPlan { - RealizationPlan { - target: ci_floor_target_digest - objective: RealizationObjective { goals: width_fold_objective_goals() } - schedule: floor_schedule_for(spec: spec, serialize_heavy: true) - total: cost_account_predicted_zero() - } -} - -fn gunbc_ci_floor_realization_plan() -> RealizationPlan { - let base = gunbc_ci_floor_realization_plan_for(spec: gunbc_ci_spec) - RealizationPlan { - target: base.target - objective: base.objective - schedule: gunbc_ci_floor_ordinary_batches() - total: base.total - } -} - -fn gunbc_falsifier_predict_only_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: gunbc_ci_spec.discovery_scan_dirs, - explicit_entries: [], - node_frontier_selection: SelectionPredictOnly, - exclude_substrings: witness_exclusion_substrings(), - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: false, - memory: runnable_memory_substantial(), - execution_mode: Hermetic - ) - } -} - -data falsifier_self_host_wet_batch_note: String = "Nightly falsifier batch 2 (Wave 2 CI substrate): the declared Wet lane for emit->compile->run->equals-seed self-host behavioral receipts (v2.compiler.self_host.wet_receipt_enrollment falsifier_self_host_wet_entries — template + frontier-flipped SelfEmitted bindings only; see falsifier_self_host_wet_note in gunbc.ci_layer_roots). Gate-4 std/logic is the inaugural green template; compiler modules enroll when frontier rows flip SelfEmitted with a declared binding — never known-red. Whole-receipt wall budget: gunbc_falsifier_self_host_wet_receipt_wall_budget. Runs SelectionApplied after the hermetic predict-only affected-set sweep; claim_executor halts batch 2 if batch 1 fails (fail-closed). REHOME 2026-07-25: enrollment gated on falsifier_self_host_wet_cadence_is_active (active since 2026-08-06 Lane D); roster retained for local recipe." - -fn falsifier_self_host_wet_batch_enrolled() -> Bool { - falsifier_self_host_wet_cadence_is_active() - && (length(xs: falsifier_self_host_wet_entries()) > 0) -} - -data falsifier_known_red_probe_batch_note: String = "Nightly falsifier batch 3 (Phase 0(b) admission invariant): the declared Hermetic probe lane for known-red quarantined witnesses whose subject resolves under witness_layer_roots (gunbc.explicit_witness_admission known_red_probe_corpus_roster — see known_red_probe_note). Rows needing the dag plus src/v1 envelope (src/v1 paths and dag witnesses that import v1.*) run on the ordinary floor under v1_claim_scoped_known_red_probe_batch. Runs SelectionApplied after the wet self-host batch; EXPECT RED on main so greening is a counted un-quarantine event, never a hand discovery. Distinct from falsifier_self_host_wet (green-only SelfEmitted receipts)." - -fn falsifier_known_red_probe_batch_enrolled() -> Bool { - length(xs: known_red_probe_corpus_roster()) > 0 -} - -data falsifier_silent_pick_gate_batch_note: String = "Nightly falsifier batch 4 (#6967 consumption — see falsifier_silent_pick_gate_note in gunbc.ci_layer_roots): the declared Wet bin-execution lane for the resolution-divergence-census silent-pick refusal. Runs SelectionApplied after the known-red probe batch; claim_executor halts this batch if an earlier one fails (fail-closed), matching the other three falsifier batches. Whole-receipt wall budget: gunbc_falsifier_silent_pick_gate_receipt_wall_budget (900s dated basis, review #7199)." - -fn falsifier_silent_pick_gate_batch_enrolled() -> Bool { - length(xs: falsifier_silent_pick_gate_entries) > 0 -} - -fn gunbc_falsifier_silent_pick_gate_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: falsifier_silent_pick_gate_entries, - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: true, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -data falsifier_self_host_wet_known_red_batch_note: String = "Nightly falsifier Wet expect_red quarantine (review #7199 2026-07-25): SelfEmitted module behavioral receipts that red on assemble — see falsifier_self_host_wet_known_red_note. Runs SelectionApplied after the green wet batch (when enrolled) / before the hermetic known-red probe; claim_executor expect_red-inverts. Whole-receipt wall budget: gunbc_falsifier_self_host_wet_receipt_wall_budget (kill-at-deadline). Greening is a counted un-quarantine." - -fn gunbc_falsifier_self_host_wet_known_red_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: falsifier_self_host_wet_known_red_entries, - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -data falsifier_known_red_probe_budget_partition_note: String = "ONE lane, FOUR batches at most, each homogeneous in BOTH facts that govern it: the declared EVAL BUDGET and the declared EXPECTATION KIND. Neither is authored — every batch is derived from the admission rows, so a new admission moves itself into the right batch without editing this plan, and an empty side schedules no batch (an empty explicit-entry discovery batch would be a run over nothing reporting green — the vacuity DESIGN 6 names). BUDGET, because claim_executor arms an eval ceiling per BATCH, so a batch mixing fast and long rows gives every fast row the long ceiling. EXPECTATION KIND, because a pre-verdict row stops the batch at RESOLVE before any witness produces an outcome, and that stop is admitted only when EVERY entry declared a pre-verdict refusal — so one such row mixed in with assertion-false rows reds siblings that were holding quarantine correctly (cursor review 50216 found exactly this; the budget split alone reintroduced the batch-wide coupling this lane exists to remove, one axis over). Lane count and lane enrollment are unchanged: the outer FalsifierLaneBatch.batch was already a list." - -fn gunbc_falsifier_known_red_probe_batch_over( - entries: List -) -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: entries, - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: false, - memory: runnable_memory_substantial(), - execution_mode: Hermetic - ) - } -} - -fn gunbc_falsifier_known_red_probe_batch_if_nonempty(entries: List) -> List { - if length(xs: entries) > 0 { - [gunbc_falsifier_known_red_probe_batch_over(entries: entries)] - } else { - [] - } -} - -fn gunbc_falsifier_known_red_probe_batches() -> List { - concat( - concat( - gunbc_falsifier_known_red_probe_batch_if_nonempty( - entries: known_red_probe_corpus_fast_budget_roster() - ), - gunbc_falsifier_known_red_probe_batch_if_nonempty( - entries: known_red_probe_corpus_long_budget_roster() - ) - ), - concat( - gunbc_falsifier_known_red_probe_batch_if_nonempty( - entries: known_red_probe_corpus_pre_verdict_fast_budget_roster() - ), - gunbc_falsifier_known_red_probe_batch_if_nonempty( - entries: known_red_probe_corpus_pre_verdict_long_budget_roster() - ) - ) - ) -} - -fn gunbc_falsifier_self_host_wet_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: falsifier_self_host_wet_entries(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -data gunbc_falsifier_native_cache_cold_note: String = "Native-cache cold control plan (widen-only, the compile-clean cold-control pattern): the COLD-VALID roster (falsifier_native_cache_cold_roster — agreement + native_cold legs only, never the full aggregates whose cold_then_warm legs assert the warm-ness this control deliberately destroys), run by the falsifier cold-control step with GUNBC_CI_NATIVE_CACHE_COLD_CONTROL=1 so every .native_ready marker is ignored and the full emit+cargo+run chain executes cold. Can only force MORE work per entry than the warm nightly batch, never less; a warm-poisoned entry (content_verified_on_read=false in extdeps.realization.native_artifact_cache) surfaces here as a cold-vs-warm receipt divergence." - -fn gunbc_falsifier_native_cache_cold_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: falsifier_native_cache_cold_roster(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -fn gunbc_falsifier_native_cache_cold_plan() -> WalkPlan { - WalkPlan { - pre_walk_execution: NoPreWalkExecution {}, - batches: [[gunbc_falsifier_native_cache_cold_batch()]], - finalization: NoFinalizationDeclared {}, - on_success_stages: [], - ordinary_budget: none, - on_success_budget: none, - } -} - -fn falsifier_batches_append_if_enrolled(acc: List>, enrolled: Bool, batch: Runnable) -> List> { - if enrolled { - list_snoc_item(xs: acc, item: [batch]) - } else { - acc - } -} - -data falsifier_gate_batch_note: String = "The EXECUTING consumer for gates enrolled on gunbc.commit_workflow's FalsifierCadenceJob surface — the gate counterpart of gunbc_falsifier_cadence_witness_batch, and it lands in the same change as project_falsifier_gates and the gate-half wall for the reason that note already states: a surface tag with no batch reading it is enrollment-by-illusion. Until this existed, the FalsifierCadenceJob surface accepted a gate row syntactically and executed it nowhere, and no witness could red on that because the bare-deenrollment wall filtered on enrollment_is_witness_claim. GRAIN: one batch holding every cadence gate, not one batch per gate — the gates are mutually independent (each is its own RunnableSingleClaim with its own profile from gate_runnable) and the falsifier's fail-closed halt already sequences batches, so splitting them would buy ordering nobody needs and cost a batch boundary each. AT LANDING THIS APPENDS NOTHING: no gate rides FalsifierCadenceJob until the measured flips land, so falsifier_gate_batch_enrolled() is false and the batch chain is byte-identical — the same zero-behaviour-change-until-flip discipline gunbc_pr_native_batch_note follows. Profile is NOT restated here: each runnable carries gate_runnable_profile(g), the single authority the per-PR floor reads, so a gate's resource shape cannot fork between the two lanes." - -fn falsifier_gate_runnables() -> List { - list_map(xs: project_falsifier_gates(roster: commit_gate_roster), f: fn(g) { gate_runnable(g: g) }) -} - -fn falsifier_gate_batch_enrolled() -> Bool { - length(xs: falsifier_gate_runnables()) > 0 -} - -data falsifier_rehomed_bin_wet_batch_note: String = "Nightly falsifier batch 5 (CI floor endgame D6, 2026-07-23): the declared Wet bin-execution lane for rows RE-HOMED off the per-PR bin-witness batch because their measured wall exceeds bin_witness_wet_per_row_wall_budget_seconds (gunbc.ci_layer_roots falsifier_rehomed_bin_wet_rows — typed frontier rows, reason + dissolve_on each). Same mechanism as the other falsifier lanes (RunnableDiscoveryBatch, SelectionApplied, fail-closed halt on earlier batch failure), so correctness coverage continues at the 4-hourly cadence while the per-PR floor keeps only short/quick rows." - -fn falsifier_rehomed_bin_wet_batch_enrolled() -> Bool { - length(xs: falsifier_rehomed_bin_wet_entries()) > 0 -} - -fn gunbc_falsifier_rehomed_bin_wet_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: falsifier_rehomed_bin_wet_entries(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -data falsifier_substrate_long_lane_batch_note: String = "Nightly falsifier batch 6 (test-decomposition Class C, 2026-07-25): the declared Hermetic lane for SubstrateInputsOnly ingest/parse pipeline witnesses whose own eval exceeds the per-PR 5s fast-lane budget (gunbc_ci_fast_lane_rule_note) — the live-grain half of the provenance-producer Class C split, joined 2026-07-25 by the wave1_gate1_d_census row (falsifier_substrate_long_lane_entries in gunbc.ci_layer_roots). Runs SelectionApplied after the rehomed-bin-wet batch; claim_executor halts this batch if an earlier one fails (fail-closed)." - -fn falsifier_substrate_long_lane_batch_enrolled() -> Bool { - length(xs: falsifier_substrate_long_lane_entries()) > 0 -} - -fn gunbc_falsifier_substrate_long_lane_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: falsifier_substrate_long_lane_entries(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: false, - memory: runnable_memory_substantial(), - execution_mode: Hermetic - ) - } -} - -data gunbc_falsifier_lane_batches_note: String = "THE SINGLE ENROLLMENT AUTHORITY, and the reason it replaced a chain of append-if-enrolled lets. Both the executed schedule and the per-component LANE attribution are projections of this one ordered list, so an added lane cannot reach the schedule without also reaching attribution — the divergence stops being writable rather than being caught afterwards (DESIGN section 5, construction over validation; the higher rung of section 4b's ladder). Before this, the lane fact was known only inside each batch's constructor name and was DISCARDED the moment the schedule flattened to List>: the receipt could say a batch was red but nothing could say which roster it was, because the label the seed stamps is generated from the runnable's shape ('discovery-corpus[N root(s)+M explicit, adaptive width]') and names no lane. A parallel hand-authored lane table would have restored the name at the cost of a second representation that drifts on the next enrollment flip (DESIGN section 3) — hence one list, two readings. ORDER IS LOAD-BEARING and is preserved exactly as the former let-chain appended: predict-only always first, then wet, wet-known-red, known-red probe, silent-pick gate, rehomed bin wet, substrate long lane, cadence witness, and the gate GROUP last. Position determines the 1-based component index the receipt reports, which is the join key gunbc.falsifier_lane uses; reordering these rows renumbers components and is a schedule change, not a refactor. Batches are constructed eagerly for unenrolled lanes exactly as the former helper's eager argument did, so enrollment gates membership and never construction." - -type FalsifierLaneBatch { - lane: FalsifierLane - enrolled: Bool - batch: List -} - -fn gunbc_falsifier_lane_batches() -> List { - [ - FalsifierLaneBatch { - lane: LanePredictOnly, - enrolled: true, - batch: [gunbc_falsifier_predict_only_batch()] - }, - FalsifierLaneBatch { - lane: LaneSelfHostWet, - enrolled: falsifier_self_host_wet_batch_enrolled(), - batch: [gunbc_falsifier_self_host_wet_batch()] - }, - FalsifierLaneBatch { - lane: LaneSelfHostWetKnownRed, - enrolled: falsifier_self_host_wet_known_red_batch_enrolled(), - batch: [gunbc_falsifier_self_host_wet_known_red_batch()] - }, - FalsifierLaneBatch { - lane: LaneKnownRedProbe, - enrolled: falsifier_known_red_probe_batch_enrolled(), - batch: gunbc_falsifier_known_red_probe_batches() - }, - FalsifierLaneBatch { - lane: LaneSilentPickGate, - enrolled: falsifier_silent_pick_gate_batch_enrolled(), - batch: [gunbc_falsifier_silent_pick_gate_batch()] - }, - FalsifierLaneBatch { - lane: LaneRehomedBinWet, - enrolled: falsifier_rehomed_bin_wet_batch_enrolled(), - batch: [gunbc_falsifier_rehomed_bin_wet_batch()] - }, - FalsifierLaneBatch { - lane: LaneSubstrateLongLane, - enrolled: falsifier_substrate_long_lane_batch_enrolled(), - batch: [gunbc_falsifier_substrate_long_lane_batch()] - }, - FalsifierLaneBatch { - lane: LaneCadenceWitness, - enrolled: falsifier_cadence_witness_batch_enrolled(), - batch: [gunbc_falsifier_cadence_witness_batch()] - }, - FalsifierLaneBatch { - lane: LaneGates, - enrolled: falsifier_gate_batch_enrolled(), - batch: falsifier_gate_runnables() - } - ] -} - -fn gunbc_falsifier_ordinary_batches() -> List> { - fold(gunbc_falsifier_lane_batches(), init: [], f: fn(acc, row) { - if row.enrolled { concat(acc, [row.batch]) } else { acc } - }) -} - -fn gunbc_falsifier_planned_components() -> List { - falsifier_planned_components( - enrollments: gunbc_falsifier_lane_batches() - |> map(row => FalsifierLaneEnrollment { lane: row.lane, enrolled: row.enrolled }) - ) -} - -data falsifier_cadence_witness_batch_note: String = "The live consumer for gunbc.commit_workflow's FalsifierCadenceJob surface — the scheduled home for declared CommitWitnessClaim rows priced out of the per-PR floor (falsifier_cadence_surface_note). WHY THIS BATCH HAS TO EXIST IN THE SAME CHANGE that re-homes the rows: a surface tag with no batch reading it is enrollment-by-illusion, the exact ~54-dark-file state under test/claim/long/ that the re-home is supposed to stop adding to, and it would present as a clean green diff. So the enrollment predicate and this batch land together, and gauntlet_lane_enrollment_witness_test reds per-PR if a row ever sits on the surface without reaching here. Profile mirrors gunbc_falsifier_rehomed_bin_wet_batch (Wet, host compiler, substantial memory): the re-homed rows are execution-kind witnesses whose cost is exactly why they left the floor. SelectionApplied so the cadence run still records predictions — the falsifier's own divergence accounting stays intact for these rows rather than being exempted." - -fn falsifier_cadence_witness_entries() -> List { - project_falsifier_witness_entries(roster: commit_gate_roster) -} - -fn falsifier_cadence_witness_batch_enrolled() -> Bool { - length(xs: falsifier_cadence_witness_entries()) > 0 -} - -fn gunbc_falsifier_cadence_witness_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: falsifier_cadence_witness_entries(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -data gunbc_pr_native_batch_note: String = "Production selected-entry native bundle, slice 1 (2026-08-02): the complete bounded population is meet, join, and complement from std.selected_witness_bundle's SelectedWitnessPlan. One NativeBundleWitnessKind row names the pure .dag process-spec selector; claim_executor preserves that kind and launches one content-addressed Rust bundle whose main directly calls all three members. The interpreter remains an explicitly timed equivalence ORACLE only (CI-0 cutover 2026-08-08: the counted interpreter fallback is deleted — native is authoritative for this population and native unavailability is a typed refusal carrying build log + stderr; std.selected_witness_bundle native_production_transition_no_fallback_note), and a separately content-addressed all-wrong bundle is the live planted RED. Scale to the next stable shard when either generated closure exceeds 32 members or measured cold compile / peak cgroup memory exceeds twice this slice's recorded baseline; those are observable code-generation and closure-scaling triggers, not a universal-bundle promise." - -fn gunbc_pr_native_entries() -> List { - [ScheduleWitnessEntry { - entry: "src/v2/test/claim/execution/native_selected_witness_bundle_production.dag" - function: "native_selected_logic_production_spec" - kind: NativeBundleWitnessKind - }] -} - -fn gunbc_pr_native_batch_enrolled() -> Bool { - length(xs: gunbc_pr_native_entries()) > 0 -} - -fn gunbc_pr_native_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: corpus_source_roots(), - scan_dirs: [], - explicit_entries: gunbc_pr_native_entries(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: true, - memory: runnable_memory_substantial(), - execution_mode: Wet - ) - } -} - -fn gunbc_ci_floor_ordinary_batches() -> List> { - let ordinary = falsifier_batches_append_if_enrolled( - acc: gunbc_ci_floor_realization_plan_for(spec: gunbc_ci_spec).schedule, - enrolled: gunbc_pr_native_batch_enrolled(), - batch: gunbc_pr_native_batch() - ) - let with_scoped = fold(scoped_witness_batches, init: ordinary, f: fn(acc, batch) { - list_snoc_item(xs: acc, item: [RunnableScopedWitnessBatch { batch: batch }]) - }) - falsifier_batches_append_if_enrolled( - acc: with_scoped, - enrolled: v1_claim_scoped_known_red_probe_batch_enrolled(), - batch: gunbc_v1_claim_scoped_known_red_probe_batch() - ) -} - -data v1_claim_scoped_known_red_probe_batch_note: String = "Per-PR Hermetic expect_red lane for known-red CorpusWitnessKind rows whose subject needs the dag plus src/v1 envelope (gunbc.explicit_witness_admission known_red_probe_v1_envelope_roster: src/v1 paths plus dag witnesses that import v1.*). The falsifier's corpus-root probe batch cannot resolve these entries; running them there would treat resolve-refuse as expect-red success without executing the predicate (DESIGN section 5 specification-without-execution). This batch mirrors v1_claim_scoped_witness_batch's dag plus src/v1 source-root envelope and runs SelectionApplied on the ordinary floor. ENROLLMENT COUPLING: enrolling this batch (known_red_probe_v1_envelope_roster becomes non-empty) requires adding its companion positional row to gunbc.ci_spec gunbc_ci_floor_batch_clamp_params in the same change — the clamp table is unconditional data while this batch is conditionally enrolled, so a roster-only edit that enrolls the batch without the clamp row fails with floor batch clamp params must cover N scheduled batches." - -fn v1_claim_scoped_known_red_probe_batch_enrolled() -> Bool { - length(xs: known_red_probe_v1_envelope_roster()) > 0 -} - -fn gunbc_v1_claim_scoped_known_red_probe_batch() -> Runnable { - RunnableDiscoveryBatch { - source_roots: ["dag", "src/v1"], - scan_dirs: [], - explicit_entries: known_red_probe_v1_envelope_roster(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile( - heavy_whole_tree_resolve: false, - spawns_host_compiler: false, - memory: runnable_memory_substantial(), - execution_mode: Hermetic - ) - } -} - -data corpus_selection_off_note: String = "EXACTLY WHAT STILL SELECTS, so the scope of this change is read off one row rather than inferred from a diff. FLIPPED TO SelectionOff (the ordinary merge-critical witness batches, whole roster every run): corpus_runnable_for, execution_corpus_runnable_for, bin_witness_corpus_runnable_for.\n\nDELIBERATELY UNCHANGED, each with its reason:\n- the falsifier cadence lanes (self-host wet, rehomed bin wet, substrate long, cadence witnesses) keep SelectionApplied — they are a 4-hourly cadence, not the merge-critical path, and retiring them belongs with the Runnable field removal rather than here;\n- the falsifier's SelectionPredictOnly sweep keeps its arm — it is the affected-set cold control, and with the floor no longer predicting it now measures a mechanism nothing on the required path consumes. That is a real loss of subject, declared here rather than discovered later, and it is the first thing the follow-on should retire;\n- the expect-red quarantine probe batches keep SelectionApplied — they invert their verdict, so widening them changes what greening means;\n- v1_claim_scoped_witness_batch keeps SelectionApplied — its 480-second clamp basis was measured on the assumption that unrelated PRs skip it (v1_claim_scoped_witness_batch_note), so flipping it without re-deriving that clamp would red the floor with FLOOR-BATCH-OVER-BUDGET for a reason unrelated to the question this change asks.\n\nTHE COST IS MEASURED, AND THE ESTIMATE WAS WRONG IN THE DIRECTION THAT MATTERS. The estimate that motivated the flip was ~10 minutes on a 57-minute step, from an assumed distribution of the 4840 skipped witnesses across entry files. Measured on run 31745991795: the ci step ran 64m32s evaluating 9267 discovery witnesses with selection off, against selection-on baselines of 65m on main and 47/60/65/65/74m across five PR branches. The added cost is smaller than the spread between two consecutive selection-on runs, so it is not separable from run-to-run noise on this fleet and no smaller claim than that is supportable from one run.\n\nWHY THAT IS THE EXPECTED SHAPE RATHER THAN A SURPRISE, stated so the number is not read as luck: the floor's wall is PREPARATION, not CHECKING. The same run measured resolve at 931.0s against eval at 96.1s, and selection removes checking while leaving preparation in place. Skipping half the roster was therefore avoiding the cheap phase. A future change that moves preparation off the per-entry key invalidates this measurement in the favourable direction and does not restore the case for selection.\n\nWHAT THE RUN DID NOT MEASURE: it refused at the end of batch 3, so the scoped workers never ran and their cost is not in the 64m32s figure. Of 9267 witnesses 3 failed, all three in this plan's own witness file and all three the same defect — a selection value pinned as part of a claim about a different axis — none of them a previously-skipped corpus witness." - -data gunbc_ci_witness_corpus_only_batches_note: String = "ITS CONSUMER IS ON-DEMAND, NOT AUTOMATIC — and this row has now been wrong in BOTH directions, so it states the mechanism instead of a summary. Before 2026-08-13 it read 'The pre-push local test gate (consumer: dag/gunbc/githooks_pre_push_emit.dag NEED_WITNESS)', which was stale: that hook has been fmt-only since the operator ruling of 2026-07-25 recorded in pre_push_fmt_only_note, so no git push invokes this. The SelectionOff flip then over-corrected it to 'nothing local reads this', which is FALSE and was caught by review 51807 — proving the hook does not call it is not proving nothing calls it, and generalizing from the first to the second is the same §3 class the correction was written to close.\n\nWHAT ACTUALLY REACHES IT, by symbol: claim_batch --pre-push (the flag is live in the seed's argument parser) runs pre_push.rs, which resolves pre_push_witness_corpus_plan_entry / pre_push_witness_corpus_plan_fn from gunbc.githooks_pre_push_plan, and that function row names this projection. So the path is real, manually invoked, and on no automatic path.\n\nBLAST RADIUS OF THE FLIP ON THAT PATH, stated because it is a behaviour change and not only a prose fix: corpus_runnable_for now carries SelectionOff, so claim_batch --pre-push runs the WHOLE witness roster rather than the diff's affected slice. That is the operator's directive applied consistently — a local command is not exempt from 'run all the witnesses unconditionally' — but whoever runs it pays corpus cost rather than diff cost, and should know that before invoking it rather than after.\n\nWHAT IT IS: the witness corpus CI runs (corpus_runnable_for(gunbc_ci_spec), now SelectionOff — whole roster, no affected-set shrink), MINUS two lanes on purpose: (1) the whole-tree --target dag compile-clean gate (the compile-clean anchor batch of gunbc_ci_floor_plan, after the cheap-gate early batch) - infeasible per-push (~72min emit), CI-owned; and (2) the Wet execution + bin-witness lanes (execution_corpus_node / bin_witness_corpus_node) - they need prebuilt release witness bins and spawn a host compiler, so they stay CI-owned. This is a DECLARED scope narrowing, not a silent one (the enforcement-intent rule): the hermetic discovery corpus catches the resolve / typecheck / witness-logic red class, and CI remains the whole wall. The former closing clause described selection's fail-closed refusal behaviour on this path; with SelectionOff there is no diff observation on these batches to refuse, so the clause is deleted rather than left describing a mechanism the batch no longer reaches. The fail-closed refusal itself is untouched where selection still runs (ci_spec_discovery_flip_note; compile_door_ledger; cli_run AFFECTED-SET REFUSAL)." - -fn gunbc_ci_witness_corpus_only_batches() -> List> { - [[corpus_runnable_for(spec: gunbc_ci_spec)]] -} - -fn runnable_scan_dir_count(r: Runnable) -> Int { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: dirs, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => length(xs: dirs) - RunnableScopedWitnessBatch { batch: batch } => length(xs: batch.scan_dirs) - RunnableSingleClaim { entry: _, function: _, profile: _ } => 0 - 1 - RunnableKernelWorkload { fused_op_count: _ } => 0 - 1 - } -} - -fn gunbc_ci_spec_discovery_flip_enrolled() -> CiSpec { - ci_spec_with_discovery_scan_dirs(spec: gunbc_ci_spec, dirs: witness_discovery_scan_dirs) -} - -fn witness_ci_corpus_discovery_flip_parked_on_live_spec() -> Bool { - (length(xs: gunbc_ci_spec.discovery_scan_dirs) == 0) - && (length(xs: witness_discovery_scan_dirs) > 0) -} - -fn witness_ci_corpus_discovery_flip_authored() -> Bool { - length(xs: witness_discovery_scan_dirs) > 0 -} - -// Discovery liveness is ENROLLMENT, not selection: the roster is discovered from -// authored scan dirs and the live batch actually scans them. The former fourth clause -// conjoined runnable_selection_applied, which is a claim about a DIFFERENT axis — how much -// of the discovered roster runs — and fusing the two meant flipping selection reported as -// discovery not being live at all. What that axis carries is asserted on its own, in both -// directions, by v2.test.claim.ci_floor_plan_witness_test -// witness_ordinary_floor_batches_run_the_whole_roster. -fn witness_ci_corpus_discovery_is_live() -> Bool { - witness_ci_corpus_discovery_flip_authored() - && (length(xs: gunbc_ci_spec.discovery_scan_dirs) > 0) - && (runnable_scan_dir_count(r: corpus_runnable_for(spec: gunbc_ci_spec)) > 0) -} - -fn witness_floor_discovery_flip_serializes_gates_after_corpus(spec: CiSpec) -> Bool { - if length(xs: spec.discovery_scan_dirs) == 0 { - true - } else { - length(xs: floor_discovery_flip_corpus_serializes_before_gates_edges(spec: spec)) == floor_discovery_flip_corpus_gate_serialization_edge_count(spec: spec) - } -} - -fn witness_floor_discovery_flip_no_corpus_edge_to_compile_anchor(spec: CiSpec) -> Bool { - fold(floor_discovery_flip_corpus_serializes_before_gates_edges(spec: spec), init: true, f: fn(ok, edge) { - ok && (edge.dependent != floor_compile_root_node()) - }) -} - -fn witness_regen_spec_carries_no_witness_corpus() -> Bool { - length(xs: corpus_plan_nodes(spec: gunbc_ci_regen_spec)) == 0 -} - -fn gunbc_ci_regen_floor_ordinary_batches() -> List> { - gunbc_ci_floor_realization_plan_for(spec: gunbc_ci_regen_spec).schedule -} - -fn runnable_single_claim_function(r: Runnable) -> String { - match r { - RunnableSingleClaim { entry: _, function: f, profile: _ } => f - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => "__discovery_corpus__" - RunnableScopedWitnessBatch { batch: _ } => "__scoped_witness_batch__" - RunnableKernelWorkload { fused_op_count: _ } => "__kernel_workload__" - } -} - -fn floor_batch_contains_function(batch: List, target: String) -> Bool { - fold(batch, init: false, f: fn(found, r) { - found || (runnable_single_claim_function(r: r) == target) - }) -} - -fn floor_compile_clean_batch(batches: List>) -> List> { - fold(batches, init: [], f: fn(acc, batch) { - if length(xs: acc) > 0 { - acc - } else if floor_batch_contains_function(batch: batch, target: ci_floor_compile_gate_fn) { - [batch] - } else { - acc - } - }) -} - -data gunbc_ci_plan_artifact_batches_note: String = "The docs-only / plan-artifact-only CI shortcut (ci_spec.ci_plan_artifact_compile_clean_invoke): the compile-clean anchor batch of the floor schedule (batch 1 after the cheap-gate early batch — see gunbc_ci_cheap_floor_gate_membership_note) runs alone through the SAME executor path, never a parallel gate runner. The gate must run inside claim_executor because it consumes the executor's in-run whole-tree --target dag compile receipt (standalone gunbc-run invocation refuses, by execution 2026-07-11); the pre-fix invoke passed gunbc-run-style --entry/--function flags claim_executor does not parse, so the shortcut arm died with exit 2 on the first plan-artifact-only diff to reach it." - -fn gunbc_ci_plan_artifact_ordinary_batches() -> List> { - floor_compile_clean_batch(batches: gunbc_ci_floor_ordinary_batches()) -} - -data walk_plan_uniformity_note: String = "EVERY plan function returns WalkPlan, including the three with no postconditions — on_success_stages: [] is a declared empty set, not an omission the executor papers over. The INSTANTIATION is where the four differ: this floor returns WalkPlan while regen, plan-artifact, and falsifier return WalkPlan. That DECLARES the intended finalization family and removes the std-level coproduct fork; it does not enforce either, because the typechecker does not check a declared return type against the body (probed by execution — std.realization_schedule walk_finalization_note carries it). Enforcement is the enrolled value witnesses in v2.test.claim.ci_floor_plan_witness plus the executor's runtime parser, and those dissolve when return-position checking lands. The executor has ONE strict parser for the record shape; there is deliberately NO fallback from a failed record parse to a bare-List> reading, because that fallback would let a malformed plan silently run with its success stages dropped — the exact silent-widen shape §5 forbids. The `_plan` names replace the `_batches` names in the same motion (operator ruling 2026-07-30): a function whose value now carries postcondition stages must not keep a name that says it returns only batches, or the next author reasonably assumes the stages are not part of the value. The FIVE argv/step consumers follow automatically because a plan target is no longer a name at all: gunbc.cli_invoke PlanFunction is a closed coproduct and claim_executor_run_plan_shell takes a variant, so a rename edits one match arm and every consumer follows.\n\nTHIS CENSUS SAID FOUR FOR TWO DAYS, AND THE WRONG COUNT IS HOW THE FIFTH GOT MISSED — recorded here rather than quietly corrected, because the miss is the note's own failure mode and not the migrating author's. #7470 landed the rename declaring itself INCOMPLETE, migrated the four consumers this sentence enumerated, and left gunbc_falsifier_native_cache_cold_batches returning a bare List> under its old name. The executor's strict parser then refused it — correctly, exactly as the no-fallback clause above promises — and the falsifier's native-cache cold control step went red on every one of the 8 runs that reached it (0 successes) until this repair. It read as intermittent rather than permanent only because the step is SKIPPED whenever the falsifier step fails first, so a deterministic red hid behind whatever witness was failing that cycle.\n\nTHE ROOT CAUSE WAS NOT THE COUNT, IT WAS AN UNTYPED PARAMETER. The clause 'they derive from the constants' was TRUE of four and FALSE of the fifth: native_cache_cold_control_invoke passed plan_function: \"gunbc_falsifier_native_cache_cold_batches\" as an inline string literal, so it derived from nothing and no rename could reach it. Because plan_function was an unconstrained String, plan identity crossed the modeled boundary as an argv token nothing could check, and the completeness argument could only ever be a hand-maintained count.\n\nThe first repair added a fifth naming constant beside the other four. That was still validation — it fixed this site and left the next author free to type a fresh literal — so the constant was deleted again in the same change that introduced the closed coproduct (§4b dissolution-on-climb: the wall replaces the machinery it obsoletes rather than accumulating beside it). An inline literal at a plan_function argument is now a TYPE ERROR, and adding a production target without a variant is impossible, so THIS census is no longer what makes the set complete — it is a receipt for how the set came to be closed. What remains hand-authored is BOTH the variant-to-plan-value pairing in v2.test.claim.ci_floor_plan_witness plan_variant_is_walk_plan_shaped AND the roster that feeds it: the match is exhaustive, so no target can exist without an arm, but nothing forces that arm to be executed, so a wrongly-paired or unexecuted arm remains possible (review 46883). Dissolve-on: a typed DeclarationRef over a resolved plan symbol, at which point the name projection and the hand pairing both delete." - -fn gunbc_ci_on_success_stages() -> List> { - [ - [floor_merge_admission_stamp_runnable()], - [floor_merge_admission_gate_runnable()] - ] -} - -fn witness_merge_admission_capture_is_typed_pre_walk_subprocess() -> Bool { - match gunbc_ci_floor_plan().pre_walk_execution { - TypedClaimSubprocess { transport_entry, transport_function, source_roots, claim_entry, claim_function } => - (transport_entry == floor_merge_admission_capture_transport_entry) - && (transport_function == floor_merge_admission_capture_transport_function) - && (source_roots == corpus_source_roots()) - && (claim_entry == floor_merge_admission_capture_entry) - && (claim_function == floor_merge_admission_capture_function) - NoPreWalkExecution {} => false - } -} - -fn gunbc_ci_floor_plan() -> WalkPlan { - WalkPlan { - pre_walk_execution: TypedClaimSubprocess { - transport_entry: floor_merge_admission_capture_transport_entry, - transport_function: floor_merge_admission_capture_transport_function, - source_roots: corpus_source_roots(), - claim_entry: floor_merge_admission_capture_entry, - claim_function: floor_merge_admission_capture_function, - }, - batches: gunbc_ci_floor_ordinary_batches(), - finalization: FloorFinalization { - expected_resolve_obligations: ci_floor_expected_resolve_obligations(), - }, - on_success_stages: gunbc_ci_on_success_stages(), - ordinary_budget: Present { value: minute_to_millisecond(m: gunbc_ci_ordinary_floor_budget_minutes) }, - on_success_budget: Present { value: minute_to_millisecond(m: gunbc_ci_admission_postcondition_budget_minutes) }, - } -} - -fn gunbc_ci_regen_floor_plan() -> WalkPlan { - WalkPlan { - pre_walk_execution: NoPreWalkExecution {}, - batches: gunbc_ci_regen_floor_ordinary_batches(), - finalization: NoFinalizationDeclared {}, - on_success_stages: [], - ordinary_budget: none, - on_success_budget: none, - } -} - -fn gunbc_ci_plan_artifact_plan() -> WalkPlan { - WalkPlan { - pre_walk_execution: NoPreWalkExecution {}, - batches: gunbc_ci_plan_artifact_ordinary_batches(), - finalization: NoFinalizationDeclared {}, - on_success_stages: [], - ordinary_budget: none, - on_success_budget: none, - } -} - -fn gunbc_falsifier_plan() -> WalkPlan { - WalkPlan { - pre_walk_execution: NoPreWalkExecution {}, - batches: gunbc_falsifier_ordinary_batches(), - finalization: NoFinalizationDeclared {}, - on_success_stages: [], - ordinary_budget: none, - on_success_budget: none, - } -} - -fn gunbc_ci_floor_schedule_lens_holds() -> Bool { - match walk_plan_schedule_lens_verdict_for_ci_floor( - plan: gunbc_ci_floor_plan(), - ordinary_plan: gunbc_ci_floor_realization_plan(), - expected_on_success_stages: gunbc_ci_on_success_stages(), - compile_gate_fn: ci_floor_compile_gate_fn, - cheap_gate_labels: cheap_floor_gate_step_labels() - ) { - Holds => true - Violation { diagnostic: _ } => false - NotApplicable { diagnostic: _ } => false - Unrealized { diagnostic: _ } => false - } -} - -fn gunbc_ci_floor_breadth() -> Int { - length(xs: gunbc_ci_spec.gates) -} - -fn floor_batch_heavy_gate_resolve_count(batch: List) -> Int { - fold(batch, init: 0, f: fn(acc, r) { - match r { - RunnableDiscoveryBatch { source_roots: _, scan_dirs: _, explicit_entries: _, node_frontier_selection: _, exclude_substrings: _, discovery_scope_dirs: _, profile: _ } => acc - RunnableScopedWitnessBatch { batch: _ } => acc - RunnableKernelWorkload { fused_op_count: _ } => acc - RunnableSingleClaim { entry: _, function: f, profile: p } => - if f == ci_floor_compile_gate_fn { - acc - } else if runnable_heavy_whole_tree_resolve(profile: p) { - acc + 1 - } else { - acc - } - } - }) -} - -fn floor_plan_at_most_one_heavy_gate_resolve_per_batch(batches: List>) -> Bool { - fold(batches, init: true, f: fn(ok, batch) { - ok && (floor_batch_heavy_gate_resolve_count(batch: batch) <= 1) - }) -} - -fn floor_plan_serializes_heavy_resolves_for(spec: CiSpec) -> Bool { - floor_plan_at_most_one_heavy_gate_resolve_per_batch( - batches: floor_schedule_for(spec: spec, serialize_heavy: true) - ) -} - -fn floor_plan_co_runs_heavy_without_serialization_for(spec: CiSpec) -> Bool { - floor_plan_at_most_one_heavy_gate_resolve_per_batch( - batches: floor_schedule_for(spec: spec, serialize_heavy: false) - ) == false -} - -fn gunbc_ci_floor_plan_serializes_heavy_resolves() -> Bool { - floor_plan_at_most_one_heavy_gate_resolve_per_batch(batches: gunbc_ci_floor_ordinary_batches()) -} - -fn witness_floor_corpus_exclusion_edges_exist(spec: CiSpec) -> Bool { - length(xs: floor_corpus_exclusion_resource_edges(spec: spec)) > 0 -} - -fn witness_floor_compile_gate_honest_heavy_profile() -> Bool { - runnable_heavy_whole_tree_resolve(profile: gate_runnable_profile(g: DagCompileCleanGate)) - && runnable_excludes_corpus_co_residence(profile: gate_runnable_profile(g: DagCompileCleanGate)) -} - -fn witness_floor_no_corpus_resource_edge_to_compile_anchor(spec: CiSpec) -> Bool { - fold(floor_corpus_exclusion_resource_edges(spec: spec), init: true, f: fn(ok, edge) { - ok && (edge.dependent != floor_compile_root_node()) - }) -} - -data gunbc_floor_arm_time_budget_refusal_plan_functions_claim_executor_seed: List = [ - floor_plan_function, - plan_artifact_plan_function, - falsifier_plan_function, -] - -data gunbc_floor_arm_time_budget_refusal_plan_functions: List = gunbc_floor_arm_time_budget_refusal_plan_functions_claim_executor_seed - -fn gunbc_floor_arm_time_budget_refusal_plan_function_roster() -> List { - gunbc_floor_arm_time_budget_refusal_plan_functions_claim_executor_seed -} - -fn gunbc_floor_arm_time_budget_refusal_applies(plan_function: String) -> Bool { - any(gunbc_floor_arm_time_budget_refusal_plan_functions, f => f == plan_function) -} - -fn witness_string_lists_have_same_members(a: List, b: List) -> Bool { - (length(xs: a) == length(xs: b)) - && all(a, item => any(b, x => x == item)) - && all(b, item => any(a, x => x == item)) -} - -fn witness_floor_schedule_preserves_enrolled_set() -> Bool { - witness_string_lists_have_same_members( - a: gunbc_ci_floor_enrolled_runnable_labels_for(spec: gunbc_ci_spec), - b: gunbc_ci_floor_schedule_runnable_labels(batches: gunbc_ci_floor_ordinary_batches()) - ) -} - -fn witness_floor_arm_time_budget_refusal_plan_roster_authority() -> Bool { - (length(xs: gunbc_floor_arm_time_budget_refusal_plan_functions) == 3) - && gunbc_floor_arm_time_budget_refusal_applies(plan_function: floor_plan_function) - && gunbc_floor_arm_time_budget_refusal_applies(plan_function: plan_artifact_plan_function) - && gunbc_floor_arm_time_budget_refusal_applies(plan_function: falsifier_plan_function) -} - -fn witness_floor_arm_time_budget_refusal_materialized_roster_matches_seed() -> Bool { - witness_string_lists_have_same_members( - a: gunbc_floor_arm_time_budget_refusal_plan_functions_claim_executor_seed, - b: gunbc_floor_arm_time_budget_refusal_plan_function_roster() - ) -} - -fn gunbc_pr_native_batches() -> List> { - [[gunbc_pr_native_batch()]] -} diff --git a/src/v2/workflow/ci_workflow_run_emit.dag b/src/v2/workflow/ci_workflow_run_emit.dag index 104de51f336..01a3da56540 100644 --- a/src/v2/workflow/ci_workflow_run_emit.dag +++ b/src/v2/workflow/ci_workflow_run_emit.dag @@ -48,8 +48,6 @@ data ci_native_cache_root_mkdir_command: String = "mkdir -p \"$RUNNER_TOOL_CACHE data ci_native_cache_root_echo_command: String = "echo \"GUNBC_NATIVE_CACHE_ROOT=$RUNNER_TOOL_CACHE/gunbc-native/$GUNBC_TOOLCHAIN_SEG\" >> \"$GITHUB_ENV\"" -data ci_selection_control_witness_invoke_command: String = "\"$ROOT/target/release/floor_skip_discovery_witness\"" - fn ci_pin_rustup_default_command() -> String { concat( "rustup default \"$(rustup show active-toolchain | awk '", @@ -176,82 +174,3 @@ fn ci_pin_rustup_default_intent() -> Pipeline { fn ci_pin_rustup_default_script() -> String { ci_workflow_run_emit_pipeline(p: ci_pin_rustup_default_intent()) } - -fn ci_selection_control_root_command() -> String { - concat("ROOT=", ci_repo_root_shell()) -} - -fn ci_selection_control_tail_command() -> String { - ci_selection_control_witness_invoke_command -} - -data ci_selection_control_skip_witness_invoke_command: String = "\"$ROOT/target/release/selection_control_skip_witness\"" - -data ci_selection_control_skip_label: String = "selection_control_not_affected_skip" - -data ci_selection_control_skip_binder: String = "_ci_selection_skip" - -data ci_selection_control_skip_policy_note: String = "Affected-set-scoped selection-control admission (pull_request only) — the selection mechanism applied to itself. selection_control_skip_witness intersects the merge-base diff with the control suite's input closure (cli_run::selection_control_input_sources: the suite's declared .dag entries plus their import closure through [src/v2, dag], the src/v1/** prefix covering the selection implementation and the witness bin, the Cargo/toolchain build config, and EVERY markdown path). The markdown arm is not incidental: the suite's declared entry dag/test/claim/doc_reachability_witness_test.dag declares LiveTreeDisposition = ReadsLiveTree and folds the live doc graph (gunbc.doc_graph_roots.doc_graph_roots_all) to decide doc_graph_has_no_orphan_docs, asserting the orphan wall green against the REAL tree — so a .md add/edit/delete genuinely changes this suite's verdict, and a live-tree read is not an import edge, so no closure walk can discover that reach. It is a structural over-approximation computed AS the answer (DESIGN §5: a closure superset is the precision frontier), not a widening failure arm. Found by review 44682 on this PR, whose first draft skipped docs-only diffs while its green control asserted that skip. A PR diff touching none of those provably cannot change the suite's verdict, so the step exits 0 immediately. NOT circular: the skip decision is a coarse path/import-closure intersection, never the node-frontier selector the suite verifies, so a broken selector cannot suppress its own control. TWO KINDS OF ARM, and the difference is the whole fail-closed story. STRUCTURAL arms — empty diff, ANY departed path (no docs carve-out — deleting a doc is the direction the orphan/dangling wall is most sensitive to, and regen's/compile-clean's docs exemption is correct only because markdown is outside THEIR closures), any markdown path, and any closure intersection — are label-valued: the diff WAS observed, so the answer is computed, and the witness exits 0 printing run_selection_control. REFUSAL arms — diff-observation failure and input-closure failure — do NOT run the suite and do NOT print a label: they STOP THE LINE. The witness prints a typed, located, countable diagnostic (SELECTION_CONTROL_REFUSED cause=DiffObservationFailed or cause=InputClosureFailed) to stderr and exits NON-ZERO, so the step goes RED. That is DESIGN §5's rule that a failure arm must refuse, never widen: 'can't compute the affected set → rerun everything' is the named absorbing fallback, conflating ⊤-as-ignorance with ⊤-as-answer, and it fails open twice — the deficit's frequency is zeroed by construction so it never ranks for fixing, and the cost is denominated in the corpus rather than the change. It is also the ruling already recorded in floor_diff_baseline_law (src/v2/workflow/floor_diff_observe.dag): a BaselineRefused → NameStatusDiffFail HALTS with a typed AFFECTED-SET REFUSAL, refusing every enrolled row rather than widening to a full-corpus run (operator ruling 2026-07-05). Corrected here after review 44768 caught this note still claiming the failure arms ran the suite — a §3 single-authority violation, since the note is emitted into ci.yml and would have been the authoritative description of the opposite behaviour. TWO DISTINCT fail-closed mechanisms sit outside that, and they are not the same arm: (a) the witness exits 0 but prints anything other than the skip label — the string comparison fails and the suite runs; (b) the witness exits NON-zero — either a deliberate typed REFUSAL (the two computation-failure arms above) or a panic (e.g. the workspace chdir failing) — GitHub runs this step under bash -e, so the command substitution's failure aborts the step RED rather than falling through. (b) is deliberately unlike the regen precedent, which suppresses stderr and defaults with a shell fallback; here a crashing skip witness stops the line loudly instead of being papered over, and stderr is left unredirected so the witness's own typed explanation of WHICH arm fired lands in the job log. COLD CONTROL: the skip is gated to pull_request events via GITHUB_EVENT_NAME, so push-to-main and workflow_dispatch run the suite UNCONDITIONALLY. A wrong closure that lets a PR wrongly skip therefore surfaces on the very next merge to main (the one-merge acceptance window, the regen-skip shape). MEASURED BASIS, including the part that makes this a trade rather than a free win. The step costs 9m02s per PR (run 30482171871, job 90679506428) against the 80s local basis gunbc.ci_workflow's step note declares. The skip witness itself costs ~100s per invocation (three local runs: 100.0s, 100.3s, 103.1s), because selection_control_skip_label_for_ci observes the diff through cli_run::floor_git_diff_name_status_range, which resolves floor_diff_observe.dag with a COLD whole-pool index — that observation, not the closure walk, is essentially the whole 100s. So: a skipping PR pays ~100s instead of 542s (saves ~7m22s); a NON-skipping PR pays 542s + ~100s (a ~100s REGRESSION, stated because it is real). SKIP RATE, MEASURED AGAINST THE REAL CLOSURE (corrected 2026-07-29, third revision — read the correction history, it is the point): over the last 100 origin/main commits, 35 touch src/v1/**, 36 touch markdown, 1 touches Cargo/toolchain, and of the 36 that survive those arms, 13 intersect the suite's actual 391-file import closure. TRUE SKIP RATE 23 of 100, so expected value is about -25s/PR (0.23 x -442s + 0.77 x +100s) — roughly 1.2 percent of a 33.6-minute ci job. Two earlier claims in this note were WRONG and are superseded: -7.7 min/PR from an unmeasured 85 percent skip rate, then -4.3 min/PR from a partially-measured <=66 percent ceiling that extrapolated the src/v1/** prefix alone and had not yet counted markdown or the closure. Each is recorded rather than quietly replaced, because the drift this very note documents (an 80s basis left standing against a 542s reality) is the same failure mode. CONSEQUENCE, stated plainly: the cost win alone does NOT justify this scaffold's hand-Rust under DESIGN §6 (denominate the benefit in displaced cost). What ruins the mean is the ~100s cold diff observation — the 🟡 deficit below, paid twice per PR — not the mechanism; dissolve that and the same code is about -102s/PR at near-zero cost. The teardown removal (-11.2s every PR) and this note's own measured corrections stand independently of the skip. 🟡 dissolve-on: the ~100s diff observation is now paid TWICE per PR, once here and once by regen_floor_skip_witness in the regen job, and both pay it as a cold whole-pool index build in a fresh process. It dissolves with the same persistent content-keyed node store gunbc.ci_materialization's resolve-receipt note names as the terminal condition for the per-entry cold resolve class; until then the double payment is counted here rather than hidden, and the non-skipping regression above is its visible cost." - -data ci_selection_control_skip_echo_command: String = "echo \"gunbc ci selection control: pull_request diff does not intersect the control suite's input closure — its verdict is provably unchanged; skipping (push-to-main runs it unconditionally as the cold control)\"" - -fn ci_selection_control_skip_bind_step() -> PipelineStep { - Let { - name: ci_selection_control_skip_binder, - value: ExprCmdSubst { - callee: ci_selection_control_skip_witness_invoke_command, - args: [] - } - } -} - -fn ci_selection_control_skip_taken_then() -> Pipeline { - Pipeline { - steps: [ - ci_workflow_do(command: ci_selection_control_skip_echo_command), - Exit { status: "0" } - ], - on_failure: FailFast - } -} - -fn ci_selection_control_skip_decide_step() -> PipelineStep { - If { - cond: StrEq { - lhs: concat("\"$", concat(ci_selection_control_skip_binder, "\"")), - rhs: ci_selection_control_skip_label - }, - then_: ci_selection_control_skip_taken_then(), - else_: Absent - } -} - -fn ci_selection_control_skip_step() -> PipelineStep { - If { - cond: StrEq { lhs: "\"$GITHUB_EVENT_NAME\"", rhs: "pull_request" }, - then_: Pipeline { - steps: [ - ci_selection_control_skip_bind_step(), - ci_selection_control_skip_decide_step() - ], - on_failure: FailFast - }, - else_: Absent - } -} - -fn ci_selection_control_intent() -> Pipeline { - Pipeline { - steps: [ - Comment { text: ci_selection_control_skip_policy_note }, - ci_workflow_do(command: ci_selection_control_root_command()), - ci_selection_control_skip_step(), - ci_workflow_do(command: ci_selection_control_tail_command()) - ], - on_failure: FailFast - } -} - -fn ci_selection_control_script() -> String { - ci_workflow_run_emit_pipeline(p: ci_selection_control_intent()) -} diff --git a/src/v2/workflow/floor_skip_proof_plan.dag b/src/v2/workflow/floor_skip_proof_plan.dag deleted file mode 100644 index 3045b503901..00000000000 --- a/src/v2/workflow/floor_skip_proof_plan.dag +++ /dev/null @@ -1,44 +0,0 @@ -module v2.workflow.floor_skip_proof_plan - -import gunbc.ci_layer_roots { witness_layer_roots } -import std.realization_schedule { - SelectionApplied, - Runnable, - RunnableDiscoveryBatch, - ScheduleWitnessEntry, - CorpusWitnessKind, - runnable_resource_profile_negligible -} -import std.types { List } - -data floor_skip_disc_entry: String = "src/v2/test/fixture/floor_skip/node_precise_discriminator_test.dag" - -fn floor_skip_proof_roster() -> List { - [ - ScheduleWitnessEntry { - entry: floor_skip_disc_entry, - function: "floor_disc_witness_transitive_holds", - kind: CorpusWitnessKind - }, - ScheduleWitnessEntry { - entry: floor_skip_disc_entry, - function: "floor_disc_witness_a_only_holds", - kind: CorpusWitnessKind - } - ] -} - -fn floor_skip_proof_batches() -> List> { - [[ - RunnableDiscoveryBatch { - source_roots: witness_layer_roots, - scan_dirs: [], - explicit_entries: floor_skip_proof_roster(), - node_frontier_selection: SelectionApplied, - exclude_substrings: [], - discovery_scope_dirs: [], - profile: runnable_resource_profile_negligible() - } - ]] -} -