Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,9 @@ jobs:
- name: Phase 1 leaf-model R1 rustc boundary (gunbc#846 bypass)
if: needs.affected.outputs.v4 == 'true' || needs.affected.outputs.workflow_policy == 'true'
run: cargo test -p v3-compiler --test integration v4_leaf_model_rust_r1_rustc_test -- --quiet
- name: Phase 1 leaf-model python R1 boundary (gunbc#846 bypass)
if: needs.affected.outputs.v4 == 'true' || needs.affected.outputs.workflow_policy == 'true'
run: cargo test -p v3-compiler --test integration v4_leaf_model_python_r1_test -- --quiet
- name: Phase 1 leaf-model R2a/R2b/R3-external rustc boundary (gunbc#846 bypass)
if: needs.affected.outputs.v4 == 'true' || needs.affected.outputs.workflow_policy == 'true'
run: cargo test -p v3-compiler --test integration v4_leaf_model_rust_r2_r3_external_rustc_test -- --quiet
Expand Down
1 change: 1 addition & 0 deletions _internal/INVARIANTS_OPS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Per **Dispatch-Discipline Mechanisms (b)** above, each **new** path added to `EX
| `src/v3/compiler/tests/integration/v4_lens_identical_variant_payload_dag_smoke_test.rs` | **L1.4 IdenticalVariantPayload sub-signature:** `src/v4/lens/identical_variant_payload.dag` — Carrier-clone family scaffold (`CarrierCloneTrigger`, `IdenticalVariantPayloadVerdict` / `IdenticalVariantPayloadFact`); shared `coverage_defect_carrier_clone` per `docs/design-dissolution-lens.md` §5.1; does not block #3962 collapse. **ROADMAP:** `_internal/ROADMAP_OPS.md` § **Nine lanes** row **T-PB-B** / `pb_rust_tests_outside_residual_zero`. **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the smoke harness. **Dissolution:** remove when the lens consumes `v4.lens.structural_similarity` and enforcement runs without this host parse ratchet. **Interim ratchet:** `v4_lens_identical_variant_payload_dag_tokenizes_and_parses`; `v4_lens_identical_variant_payload_module_authority_and_entrypoints`. |
| `src/v3/compiler/tests/integration/coverage_defect_acceptance_dag_test.rs` | **Coverage-defect acceptance keys:** `src/v4/lens/coverage.dag` carries the canonical coverage-key set for `docs/design-dissolution-lens.md` §5.1; the old emit-template key is retired into `TemplateHole`, and the old string-escape key is split into `TemplateHole` plus `CanonicalCarrier`. **ROADMAP:** `_internal/ROADMAP_OPS.md` § **Nine lanes** row **T-PB-B** / `pb_rust_tests_outside_residual_zero`. **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the parse-level ratchet. **Dissolution:** remove when the v4 coverage lens runs as `.dag` / generated coverage and can assert the same acceptance rows without this host parser check. **Interim ratchet:** `coverage_defect_acceptance_keys_match_declared_rows` tokenizes/parses `src/v4/lens/coverage.dag` and asserts the exact parsed `(coverage_defect_* data row, CoverageDefectKey variant)` set matches the expected acceptance-key table while rejecting retired emit-template / string-escape names. |
| `src/v3/compiler/tests/boundary/v4_leaf_model_rust_r1_rustc_test.rs` | **Phase 1 leaf-model verification** (`docs/planning/v4-leaf-model-verification-2026-05-30.md` §7 R1): boundary `rustc` exercise for `src/v4/lens/leaf_model_verification.dag` happy + falsification fixtures; interim host runner `scripts/v4-leaf-model-rust-r1-verify.sh`. **ROADMAP:** `_internal/ROADMAP_OPS.md` § **Nine lanes** row **T-PB-B** / `pb_rust_tests_outside_residual_zero`; **TASKS.md** T-22/T-38 (Runtime/TestClaim verdict surface). **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the harness. **Dissolution:** delete when modeled `run_target_verification` exercises `src/v4/test/claim/language_model/rust_r1.dag` without this hand-Rust bridge. **Interim ratchet:** `v4_leaf_model_rust_r1_fixture_strings_match_dag_authority`, `v4_leaf_model_rust_r1_happy_fixture_rustc_accepts`, `v4_leaf_model_rust_r1_falsification_fixture_rustc_e0308`. |
| `src/v3/compiler/tests/boundary/v4_leaf_model_python_r1_test.rs` | **Phase 1 leaf-model verification — python.dag R1** (W2.6 / PR #3938 §11.4): boundary CPython exercise for `src/v4/lens/leaf_model_verification.dag` python happy + falsification fixtures; interim host runner `scripts/v4-leaf-model-python-r1-verify.sh`. **ROADMAP:** T-PB-B / T-22/T-38. **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs`. **Dissolution:** delete when modeled `run_target_verification` exercises `src/v4/test/claim/language_model/python_r1.dag` without this hand-Rust bridge. **Interim ratchet:** `v4_leaf_model_python_r1_fixture_strings_match_dag_authority`, `v4_leaf_model_python_r1_happy_fixture_python_accepts`, `v4_leaf_model_python_r1_falsification_fixture_python_name_error`. |
| `src/v3/compiler/tests/boundary/v4_leaf_model_rust_r2_r3_external_rustc_test.rs` | **Phase 1 leaf-model W1.7** (`docs/planning/v4-leaf-model-verification-2026-05-30.md` §7 R2a/R2b/R3-external): boundary `rustc` + runtime exercise for R2a algebra ops (E0599 falsification), R2b debug panic / release wrap on `i32::MAX + 1` runtime path, R3-external Symbol nominal carrier vs alias+ctor mismatch (E0423); interim host runners `scripts/v4-leaf-model-rust-r2a-verify.sh`, `scripts/v4-leaf-model-rust-r2b-verify.sh`, `scripts/v4-leaf-model-rust-r3-external-verify.sh`. **ROADMAP:** T-PB-B / T-22/T-38. **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs`. **Dissolution:** delete when modeled `run_target_verification` exercises `rust_r2a.dag` / `rust_r2b.dag` / `rust_r3_external.dag` without this bridge. **Interim ratchet:** nine tests in module (fixture authority + happy/falsification or runtime outcomes per claim). R2b sub-claims 3–4 remain `not_checked` until explicit `-C overflow-checks` runner lands (quick-tern-735). |
| `src/v3/compiler/tests/integration/v4_bin_main_dag_smoke_test.rs` | **T-15** (`src/v4/bin/main.dag` — trampoline **`String`** authority + B1 digest **placeholder** `Node`s; closed-tree invariant #2 / pure-bootstrap zero-floor per `docs/design-pure-bootstrap-zero.md`). **Grounded-indicator authoring on `main.dag` is HOLD** pending hub-relayed canonical spec (operator-direct format under-spec; pending canonical spec). **ROADMAP:** `_internal/ROADMAP_OPS.md` § **Nine lanes** row **T-PB-B** / `pb_rust_tests_outside_residual_zero`. **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the smoke harness. **Dissolution:** remove when `main.dag` is exercised only by `.dag` `TestClaim` rows / a generated harness without this per-file Rust probe. **Interim ratchet:** `v4_bin_main_dag_tokenizes_and_parses_with_trampoline_source_anchor` runs `tokenize_for_test` + `parse_for_test` on the pinned `include_str!` source and asserts the trampoline / stub `data` identifiers plus the escaped `include!` spelling remain present in source text (full `compile_to_dag` on `main.dag` alone is deferred: `import v4.std.node` is not linked in the single-file harness). |
| `src/v3/compiler/tests/integration/v4_t15_self_host_fixed_point_harness_test.rs` | **T-15** (`src/v4/TASKS.md` §T-15 — `bin/main.dag` trampoline authority + bootstrap `FixptStage1Stage2` stage1==stage2 wiring, **not** stage0==stage1; `claim_t15_self_host_fixed_point.dag` EqualsClaim over digest operand placeholders; optional v2 `gunbc compile` with `main.dag` entry root when `target/release/gunbc` exists). **ROADMAP:** `_internal/ROADMAP_OPS.md` § **Nine lanes** row **T-PB-B** / `pb_rust_tests_outside_residual_zero`. **PR receipt (P5 Mechanism (b)):** this INVARIANTS row + matching `EXPECTED_HAND_AUTHORED_TEST` line in `sg0_census_test.rs` land in the same PR as the harness + `claim_t15_self_host_fixed_point.dag`. **Dissolution:** remove when B1 merkle `content_hash` pins + T-22 eval execute the Equals probe and bootstrap fixpt without host structural receipts. **Interim ratchet:** `t_15_self_host_fixed_point` (TASKS.md CI gate name) tokenize/parse `main.dag`, `bootstrap.dag`, `self_host.dag`, and the T-15 claim; assert trampoline + fixpt stage1/stage2 digest convergence strings in `bootstrap_plan_well_formed`; assert `self_host_fixed_point_validate` stays fail-closed; optional v2 entry-root compile receipt. |
Expand Down
3 changes: 3 additions & 0 deletions scripts/ci-merge/sg0-pr-body-append.4022.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SG-0 hand-path delta: +1

SG-0 pairing: (c) Net +1 on `EXPECTED_HAND_AUTHORED_TEST` for `v4_leaf_model_python_r1_test.rs` (INVARIANTS §P5(b) Phase 1 leaf-model python R1 boundary CPython ratchet per PR #3938 §11.4 W2.6; pairs with `scripts/v4-leaf-model-python-r1-verify.sh`). Follow-up dispatch: retire when T-22 modeled `run_target_verification` exercises `src/v4/test/claim/language_model/python_r1.dag` without this hand-Rust bridge — gunb-ai/gunbc#4022 / T-PB-B `pb_rust_tests_outside_residual_zero` in `_internal/ROADMAP_OPS.md`.
174 changes: 174 additions & 0 deletions scripts/v4-leaf-model-python-r1-verify.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@
#!/usr/bin/env bash
# scripts/v4-leaf-model-python-r1-verify.sh
#
# Phase 1 leaf-model verification host runner — python.dag R1 (int surface spelling).
# Authority: src/v4/lens/leaf_model_verification.dag (fixture sources) +
# src/v4/test/claim/language_model/python_r1.dag (claim + receipt shape).
#
# Exercises CPython on happy + falsification fixtures; emits JSON receipt.
# Falsification probe expects NameError (undefined `i32` annotation) per W2.6 mirror of
# rust.dag R1 (wrong surface spelling for the claimed primitive).
#
# Dissolve-on-arrival: delete when T-22 modeled `run_target_verification` owns python3
# invocation and structured TestClaimRun verdicts replace this host bridge (same
# trigger as src/v3/compiler/tests/boundary/v4_leaf_model_python_r1_test.rs).

set -euo pipefail

root="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
cd "$root"

fixture_dag="src/v4/lens/leaf_model_verification.dag"
if [[ ! -f "$fixture_dag" ]]; then
echo "error: missing fixture authority at $fixture_dag" >&2
exit 1
fi

if ! command -v python3 >/dev/null 2>&1; then
echo "error: python3 not on PATH — required for leaf-model python R1 verification" >&2
exit 1
fi

eval "$(python3 - "$fixture_dag" <<'PY'
from __future__ import annotations

import re
import shlex
import sys
from pathlib import Path

path = Path(sys.argv[1])
text = path.read_text()

def extract(name: str) -> str:
pattern = rf'^data {name}: String = "(.*)"\s*$'
for line in text.splitlines():
m = re.match(pattern, line)
if m:
return bytes(m.group(1), "utf-8").decode("unicode_escape")
raise SystemExit(f"error: {path}: missing data {name}: String = ...")

happy = extract("python_r1_happy_fixture_source")
falsification = extract("python_r1_falsification_fixture_source")
print(f"happy_source={shlex.quote(happy)}")
print(f"falsification_source={shlex.quote(falsification)}")
PY
)"

run_suffix="${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-$$}"
tmp_root="${RUNNER_TEMP:-/tmp}"
scratch="${tmp_root}/v4-leaf-model-python-r1-${run_suffix}"
rm -rf "$scratch"
mkdir -p "$scratch"

exercise_python_fixture() {
local label="$1"
local source="$2"
local src_path="${scratch}/${label}.py"
local stderr_path="${scratch}/${label}.stderr"
printf '%s' "$source" >"$src_path"
set +e
python3 -m py_compile "$src_path" 2>"$stderr_path"
local py_compile_status=$?
if [[ "$py_compile_status" -ne 0 ]]; then
echo "$py_compile_status" >"${scratch}/${label}.exit"
cat "$stderr_path"
return
fi
python3 "$src_path" 2>>"$stderr_path"
local exec_status=$?
set -e
echo "$exec_status" >"${scratch}/${label}.exit"
cat "$stderr_path"
}

echo "=== leaf-model R1: python3 happy fixture (python.dag int surface spelling) ==="
happy_stderr="$(exercise_python_fixture happy "$happy_source")"
happy_status="$(cat "${scratch}/happy.exit")"

echo "=== leaf-model R1: python3 falsification fixture (NameError probe) ==="
falsification_stderr="$(exercise_python_fixture falsification "$falsification_source")"
falsification_status="$(cat "${scratch}/falsification.exit")"

happy_pass=false
falsification_pass=false
if [[ "$happy_status" -eq 0 ]]; then
happy_pass=true
fi
if [[ "$falsification_status" -ne 0 ]] && grep -qE 'NameError: name .i32. is not defined' <<<"$falsification_stderr"; then
falsification_pass=true
fi

proven=false
if [[ "$happy_pass" == true && "$falsification_pass" == true ]]; then
proven=true
fi

export V4_PYTHON_R1_HAPPY_STATUS="$happy_status"
export V4_PYTHON_R1_FALSIFICATION_STATUS="$falsification_status"
export V4_PYTHON_R1_HAPPY_PASS="$happy_pass"
export V4_PYTHON_R1_FALSIFICATION_PASS="$falsification_pass"
export V4_PYTHON_R1_PROVEN="$proven"
export V4_PYTHON_R1_FALSIFICATION_STDERR="$falsification_stderr"

python3 - <<'PY'
import json
import os
import re

stderr = os.environ.get("V4_PYTHON_R1_FALSIFICATION_STDERR", "")
print(
json.dumps(
{
"schema": "scripts/v4-leaf-model-python-r1-verify.sh::host_receipt_v1",
"claim_id": "PythonR1IntSurfaceSpelling",
"happy": {
"python_exit": int(os.environ["V4_PYTHON_R1_HAPPY_STATUS"]),
"verdict": "Pass"
if os.environ["V4_PYTHON_R1_HAPPY_PASS"] == "true"
else "Fail",
},
"falsification": {
"python_exit": int(os.environ["V4_PYTHON_R1_FALSIFICATION_STATUS"]),
"expected_diagnostic": "NameError:i32",
"name_error_i32_observed": bool(
re.search(r"NameError: name 'i32' is not defined", stderr)
),
"verdict": "Pass"
if os.environ["V4_PYTHON_R1_FALSIFICATION_PASS"] == "true"
else "Fail",
},
"proven": os.environ["V4_PYTHON_R1_PROVEN"] == "true",
},
indent=2,
)
)
PY

if [[ "$proven" != true ]]; then
echo "error: leaf-model python R1 verification failed (happy_pass=${happy_pass} falsification_pass=${falsification_pass})" >&2
if [[ "$happy_pass" != true ]]; then
echo "--- happy python stderr ---" >&2
printf '%s\n' "$happy_stderr" >&2
fi
if [[ "$falsification_pass" != true ]]; then
echo "--- falsification python stderr ---" >&2
printf '%s\n' "$falsification_stderr" >&2
fi
exit 1
fi

if [[ -n "${GITHUB_STEP_SUMMARY:-}" ]]; then
{
echo "### Leaf-model verification — python.dag R1 (int surface spelling)"
echo ""
echo "| path | verdict |"
echo "| --- | --- |"
echo "| happy \`def r1_test() -> int: return 0\` | Pass (python3 clean) |"
echo "| falsification \`def r1_test() -> i32: ...\` | Pass (NameError on i32) |"
echo ""
echo "_Authority: \`${fixture_dag}\` + \`src/v4/test/claim/language_model/python_r1.dag\`_"
} >> "$GITHUB_STEP_SUMMARY"
fi

echo "leaf-model python R1 verification PROVEN: happy runs clean; falsification rejected with NameError on i32"
121 changes: 121 additions & 0 deletions src/v3/compiler/tests/boundary/v4_leaf_model_python_r1_test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
//! **Layer:** boundary (TESTING.md § test layers — CPython exercise for v4 leaf-model python R1).
//!
//! Phase 1: python.dag claim R1 (int surface spelling) — fixture authority in
//! `src/v4/lens/leaf_model_verification.dag`; host runner
//! `scripts/v4-leaf-model-python-r1-verify.sh`.
//!
//! **P5 receipt:** matching `_internal/INVARIANTS_OPS.md` row +
//! `EXPECTED_HAND_AUTHORED_TEST` literal in `sg0_census_test.rs` (same PR).
//! **Dissolution:** retire when T-22 eval + modeled `run_target_verification` owns
//! python3 invocation without this hand-Rust bridge.

use std::io::Write;
use std::process::Command;

const FIXTURE_DAG: &str = include_str!("../../../../v4/lens/leaf_model_verification.dag");
const CLAIM_DAG: &str = include_str!("../../../../v4/test/claim/language_model/python_r1.dag");

const HAPPY_FIXTURE: &str = "def r1_test() -> int:\n return 0\n";
const FALSIFICATION_FIXTURE: &str = "def r1_test() -> i32:\n return 0\n";

fn unescape_dag_string_literal(body: &str) -> String {
let mut out = String::new();
let mut chars = body.chars();
while let Some(c) = chars.next() {
if c == '\\' {
match chars.next() {
Some('n') => out.push('\n'),
Some('"') => out.push('"'),
Some('\\') => out.push('\\'),
Some(other) => {
out.push('\\');
out.push(other);
}
None => out.push('\\'),
}
} else {
out.push(c);
}
}
out
}

fn extract_fixture_source(dag_text: &str, data_name: &str) -> Option<String> {
let needle = format!("data {data_name}: String = \"");
let line = dag_text.lines().find(|l| l.starts_with(&needle))?;
let rest = line.strip_prefix(&needle)?.strip_suffix('"')?;
Some(unescape_dag_string_literal(rest))
}

fn scratch_dir(label: &str) -> std::path::PathBuf {
let suffix = std::process::id();
std::env::temp_dir().join(format!("v4_leaf_model_python_r1_{label}_{suffix}"))
}

fn exercise_fixture(label: &str, source: &str) -> (i32, String) {
let tmp_dir = scratch_dir(label);
let _ = std::fs::remove_dir_all(&tmp_dir);
std::fs::create_dir_all(&tmp_dir).expect("create scratch dir");
let src_path = tmp_dir.join(format!("{label}.py"));
std::fs::File::create(&src_path)
.and_then(|mut f| f.write_all(source.as_bytes()))
.expect("write fixture source");

let py_compile = Command::new("python3")
.args(["-m", "py_compile"])
.arg(&src_path)
.output()
.expect("invoke python3 -m py_compile");
if !py_compile.status.success() {
let stderr = String::from_utf8_lossy(&py_compile.stderr).into_owned();
let _ = std::fs::remove_dir_all(&tmp_dir);
return (py_compile.status.code().unwrap_or(1), stderr);
}

let exec = Command::new("python3")
.arg(&src_path)
.output()
.expect("invoke python3 on fixture");
let stderr = String::from_utf8_lossy(&exec.stderr).into_owned();
let status = exec.status.code().unwrap_or(1);
let _ = std::fs::remove_dir_all(&tmp_dir);
(status, stderr)
}

#[test]
fn v4_leaf_model_python_r1_fixture_strings_match_dag_authority() {
let happy = extract_fixture_source(FIXTURE_DAG, "python_r1_happy_fixture_source")
.expect("python_r1_happy_fixture_source in lens/leaf_model_verification.dag");
let falsification =
extract_fixture_source(FIXTURE_DAG, "python_r1_falsification_fixture_source")
.expect("python_r1_falsification_fixture_source in lens/leaf_model_verification.dag");
assert_eq!(happy, HAPPY_FIXTURE);
assert_eq!(falsification, FALSIFICATION_FIXTURE);
assert!(
CLAIM_DAG.contains("python_r1_happy_fixture_source")
&& CLAIM_DAG.contains("python_surface_spelling_int"),
"claim module must reference fixture + fact anchors"
);
}

#[test]
fn v4_leaf_model_python_r1_happy_fixture_python_accepts() {
let (status, stderr) = exercise_fixture("happy", HAPPY_FIXTURE);
assert_eq!(
status, 0,
"python3 should accept R1 happy fixture; stderr:\n{stderr}"
);
}

#[test]
fn v4_leaf_model_python_r1_falsification_fixture_python_name_error() {
let (status, stderr) = exercise_fixture("falsification", FALSIFICATION_FIXTURE);
assert_ne!(
status, 0,
"falsification fixture must not run clean (wrong int surface spelling i32)"
);
assert!(
stderr.contains("NameError: name 'i32' is not defined"),
"expected NameError on undefined i32 annotation; stderr:\n{stderr}"
);
}
Loading
Loading