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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cargo test -p aprender-contracts-cli --test repo_tree_pv
35 changes: 0 additions & 35 deletions crates/aprender-contracts-cli/tests/ev11_lint_ratchets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,41 +111,6 @@ fn lint(root: &Path, gates: &[&str]) -> Run {
pv(&args)
}

#[test]
fn the_probe_passes_on_the_real_corpus_and_writes_nothing() {
let baseline = repo_contracts().join("lint-baseline.json");
let before = std::fs::read(&baseline).expect("baseline readable");
let doc: serde_json::Value = serde_json::from_slice(&before).expect("baseline is JSON");
assert!(doc.is_object());
assert!(doc["unpaired_theorem_modules"].is_u64(), "{doc}");
assert!(doc["contracts_without_depends_on"].is_u64(), "{doc}");
assert_eq!(doc["command"], "make lint-ratchet");

let dir = repo_contracts();
let mut args = vec!["lint", s(&dir)];
args.extend_from_slice(&BOTH);
let r = pv(&args);
assert_eq!(r.code, 0, "{}", show(&r));
let got = reports(&r.stdout);
assert_eq!(got.len(), 2, "{}", show(&r));
for g in &got {
assert_eq!(g["verdict"], "Pass", "{g}");
}
assert_eq!(
got[0]["unpaired_theorem_modules"], doc["unpaired_theorem_modules"],
"the recorded baseline is the measured count (`make lint-ratchet` wrote it)"
);
assert_eq!(
got[1]["contracts_without_depends_on"],
doc["contracts_without_depends_on"]
);
assert_eq!(
std::fs::read(&baseline).expect("baseline readable"),
before,
"a gate wrote the baseline"
);
}

#[test]
fn at_the_baseline_both_gates_pass() {
let t = repo();
Expand Down
26 changes: 10 additions & 16 deletions crates/aprender-contracts-cli/tests/ont2b_sigma_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,6 @@ fn fixture(name: &str) -> PathBuf {
.join(name)
}

fn repo_contracts() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../contracts")
}

fn s(p: &Path) -> String {
p.to_str().expect("utf-8 path").to_string()
}
Expand All @@ -64,16 +60,6 @@ fn json_of(r: &Run) -> serde_json::Value {
serde_json::from_str(&r.stdout).unwrap_or_else(|e| panic!("stdout is JSON: {e}\n{}", show(r)))
}

#[test]
fn the_repo_corpus_passes_the_sigma_gate() {
let dir = s(&repo_contracts());
let r = pv(&["lint", &dir, "--gate", "sigma", "--format", "json"]);
assert_eq!(r.code, 0, "{}", show(&r));
let v = json_of(&r);
assert_eq!(v["gate"], "sigma", "{}", show(&r));
assert_eq!(v["verdict"], "Pass", "{}", show(&r));
}

#[test]
fn a_well_formed_fixture_corpus_passes() {
let dir = s(&fixture("sigma-ok"));
Expand Down Expand Up @@ -147,7 +133,7 @@ fn a_corpus_without_sigma_declines_at_exit_2() {

#[test]
fn an_unknown_gate_name_is_refused() {
let dir = s(&repo_contracts());
let dir = s(&fixture("sigma-ok"));
let r = pv(&["lint", &dir, "--gate", "no-such-gate", "--format", "json"]);
assert_ne!(r.code, 0, "{}", show(&r));
assert!(
Expand All @@ -160,7 +146,15 @@ fn an_unknown_gate_name_is_refused() {
/// `--gate` selects ONE gate: the report is that gate's, not the whole run's.
#[test]
fn the_gate_mode_reports_only_the_named_gate() {
let dir = s(&repo_contracts());
// One real contract in a tempdir (the fixtures are sigma corpora, not valid under `validate`), not the
// whole repo tree: #5914.
let tmp = tempfile::tempdir().expect("tempdir");
std::fs::copy(
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../contracts/softmax-kernel-v1.yaml"),
tmp.path().join("softmax-kernel-v1.yaml"),
)
.expect("control contract copied");
let dir = s(tmp.path());
let r = pv(&["lint", &dir, "--gate", "validate", "--format", "json"]);
assert_eq!(r.code, 0, "{}", show(&r));
let v = json_of(&r);
Expand Down
46 changes: 0 additions & 46 deletions crates/aprender-contracts-cli/tests/ont4_relations_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,6 @@ fn fixture(name: &str) -> PathBuf {
.join(name)
}

fn repo_contracts() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../contracts")
}

fn s(p: &Path) -> String {
p.to_str().expect("utf-8 path").to_string()
}
Expand All @@ -67,27 +63,6 @@ fn gate(dir: &Path) -> Run {
pv(&["lint", &s(dir), "--gate", "relations", "--format", "json"])
}

#[test]
fn the_repo_corpus_passes_the_relations_gate() {
let r = gate(&repo_contracts());
assert_eq!(r.code, 0, "{}", show(&r));
let v = json_of(&r);
assert_eq!(v["gate"], "relations", "{}", show(&r));
assert_eq!(v["verdict"], "Pass", "{}", show(&r));
// R-2 by construction: the real corpus must carry typed relations, or this would be a decline
assert!(
v["extra"]["relations_n"].as_u64().unwrap_or(0) > 0,
"the real corpus has typed relations\n{}",
show(&r)
);
// the legacy field is measured, never rewritten: 188 contracts carry it at 3409b29d
assert!(
v["extra"]["legacy_depends_on"].as_u64().unwrap_or(0) > 100,
"metadata.depends_on is counted\n{}",
show(&r)
);
}

#[test]
fn four_relations_are_accepted_and_contradicts_is_read_both_ways() {
let r = gate(&fixture("relations-ok"));
Expand Down Expand Up @@ -174,24 +149,3 @@ fn the_legacy_ratchet_rejects_a_rise_and_passes_a_hold() {
assert_eq!(rise.code, 1, "{}", show(&rise));
assert!(rise.stdout.contains("PV-ONT-010"), "{}", show(&rise));
}

/// R-8: the gate is computed in every `pv lint` run, not only under `--gate`.
#[test]
fn the_full_run_computes_the_relations_gate() {
let dir = s(&repo_contracts());
let r = pv(&["lint", &dir, "--format", "json"]);
let v = json_of(&r);
let names: Vec<String> = v["gates"]
.as_array()
.map(|g| {
g.iter()
.filter_map(|x| x["name"].as_str().map(String::from))
.collect()
})
.unwrap_or_default();
assert!(
names.iter().any(|n| n == "relations"),
"{names:?}\n{}",
show(&r)
);
}
102 changes: 0 additions & 102 deletions crates/aprender-contracts-cli/tests/ont4b_shapes_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ fn fixture(name: &str) -> PathBuf {
.join(name)
}

fn repo_contracts() -> PathBuf {
Path::new(env!("CARGO_MANIFEST_DIR")).join("../../contracts")
}

fn s(p: &Path) -> String {
p.to_str().expect("utf-8 path").to_string()
}
Expand All @@ -69,37 +65,6 @@ fn gate(dir: &Path) -> Run {
pv(&["lint", &s(dir), "--gate", "shapes", "--format", "json"])
}

#[test]
fn the_repo_corpus_passes_with_the_plant_fired_and_the_whole_corpus_as_focus_nodes() {
let r = gate(&repo_contracts());
assert_eq!(r.code, 0, "{}", show(&r));
let v = json_of(&r);
assert_eq!(v["gate"], "shapes");
assert_eq!(v["verdict"], "Pass", "{}", show(&r));
assert!(
v["extra"]["shapes_n"].as_u64().unwrap_or(0) >= 1,
"{}",
show(&r)
);
assert!(
v["extra"]["focus_nodes_n"].as_u64().unwrap_or(0) > 1000,
"every contract's projection is a focus node\n{}",
show(&r)
);
assert_eq!(v["extra"]["pc_shape"], "fired", "{}", show(&r));
// ONT-4b: exactly one, from ont:id minCount. ONT-4c1 plants a bare model:Model too, which draws
// ladder-measured's two minCounts: three on this corpus, and never zero. ONT-4f (#4330) arms the four GitHub
// shapes, and the plant draws every minCount they declare: github-repo 4 + github-issue 6 +
// github-pull-request 7 + github-milestone 6 = 23 more, so 26. ONT-4c (#3847) arms readme-root, claude-md,
// model-setfit-slice and csv-train, whose plants add sixteen: 42.
assert_eq!(
v["extra"]["plant_violations"],
42,
"ont:id minCount + ladder-measured's two (ONT-4c1) + the four GitHub shapes' 23 (ONT-4f) + the ONT-4c plants against readme-root, claude-md, model-setfit-slice, csv-train (16)\n{}",
show(&r)
);
}

#[test]
fn a_conforming_fixture_passes_at_exit_0() {
let r = gate(&fixture("shapes-ok"));
Expand Down Expand Up @@ -211,70 +176,3 @@ fn extract_is_deterministic_and_extract_check_sees_drift() {
show(&drift)
);
}

/// The tracked graph in this repository IS a fresh extraction (R-18), and `shapes.ttl` is the export.
#[test]
fn the_tracked_repo_graph_is_fresh() {
let r = pv(&["extract", &s(&repo_contracts()), "--check"]);
assert_eq!(r.code, 0, "{}", show(&r));
let v = json_of(&r);
assert!(v["triples"].as_u64().unwrap_or(0) > 5000, "{}", show(&r));
// MEASURED on this branch: `pv extract contracts --check` reports
// shapes_n=9, triples=15851 (the 0.69 batch, #3669, pinned pv 0.68.2 built from
// the tree; was 6 / 15620 before #3600 folded in). The count is deliberately hardcoded rather
// than derived — a shape added without anyone noticing is the thing this
// assertion exists to prevent, so adding one is SUPPOSED to turn it red and
// make you name the new shape here.
//
// It did exactly that for #3605's `refusal-receipt-v1`, and a quorum lane
// caught it rather than I did. Note for whoever merges second: this counter
// is shared across branches, so a sibling PR that also adds a shape
// (#3600's parity-receipt-v2) will need the number raised again at merge —
// that is the ratchet working, not a conflict to route around. It did: the
// 0.69 batch folded #3600 in and the count went 6 -> 9 with its three shapes. #3715 added the nine-shape
// `release-readiness-v1` family (shapes_n=18, triples=15863, measured on its branch); it contributes no focus
// node to a PR's graph — the release evidence is extracted only under `--release-*`. ONT-4f (#4330) adds
// `github-entities-v1`'s four armed shapes: 22. #3560 R1 adds `examples-well-formed` (reported, not armed): 23. R4 adds `examples-model-current` (reported): 24.
// ONT-4c (#3847) adds the four armed non-code shapes readme-root, claude-md, model-setfit-slice, csv-train: 28.
// ONT-4g/ONT-10 (#4502) add binary-target, surface-audit-ledger, binary-apr-http-mcp and fifteen
// binary-<bin>-surface shapes (apr-cli-apr, apr-corpus-ingest, aprender-cbtop, aprender-compute-xtask, aprender-db,
// aprender-explain, aprender-orchestrate-aprender-orchestrate, aprender-profile, aprender-ptx-debug, aprender-test-cli, aprender-zram-generator,
// apr-qa-readme-sync, pv, score, trueno-rag): 46. Each new ONT-10 slice raises this — name it here.
// The 0.70.0 car (#4429) added, disjoint from these: #3745 S2 (#3777) six DERIVED cell-class shapes (effect,
// probe, model-cell, effect-cell, crux-verb, crux) and a8's `sampling`, ONT-4c5 (PMAT-3972) `capability-cells`,
// and ONT-4c4 (#4069) kernel-parity, kernel-timing and kernel-safety: 46 + 8 + 3 = 57.
// ONT-10 rest (#4588, PR-2) adds eight more binary-<bin>-surface shapes (apr, apr-qa, aprender-data,
// aprender-present, aprender-ptop, aprender-simulate, aprender-train-lora, aprender-train-shell) and
// binary-aprender-apr-http-mcp: 57 + 9 = 66.
// #4455 adds `findings-ledger-v1` (not in `armed_shapes`; it grades zero focus nodes here): 67.
// KREG-001 (#4539) adds `kernel-registry-v1`'s one shape, a row per dispatchable kernel: 68.
// #3715 v2 adds `release-readiness-v2{.kernel,.model,.model-smoke,.sanitizer}` (like v1, a focus node only under
// `--v2-evidence`; the smoke is its own shape so no shape exports two `<shape>/node` subjects) and the
// per-forward `kernel-registry-v1.op`: 68 + 5 = 73.
assert_eq!(
v["shapes_n"],
73,
"ont-shapes-v1 + ladder-measured + ladder-green (ONT-4c1) + bound-symbols-resolve + lean-statements-grounded (ONT-4b2) + refusal-receipt-v1 (#3605) + parity-receipt-complete + parity-comparator-self + parity-comparator-oracle (parity-receipt-v2, #3600) + release-readiness-v1{{,.release,.host,.context,.model,.coverage,.tokenizer,.kernel,.refusal}} (#3715) + github-{{repo,issue,pull-request,milestone}} (#4330) + examples-well-formed (#3560 R1) + examples-model-current (#3560 R4) + readme-root + claude-md + model-setfit-slice + csv-train (ONT-4c, #3847) + binary-target + surface-audit-ledger + binary-apr-http-mcp + 15 binary-*-surface (ONT-10, #4502) + release-readiness-v1{{.effect,.probe,.model-cell,.effect-cell,.crux-verb,.crux,.sampling}} (#3745 S2) + capability-cells (ONT-4c5) + kernel-parity + kernel-timing + kernel-safety (ONT-4c4) + 8 binary-*-surface + binary-aprender-apr-http-mcp (ONT-10 rest, #4588) + findings-ledger-v1 (#4455) + kernel-registry-v1{{,.op}} (KREG-001 #4539, #3715 v2) + release-readiness-v2{{.kernel,.model,.model-smoke,.sanitizer}} (#3715 v2)\n{}",
show(&r)
);
}

/// R-8: the gate is computed in every `pv lint` run.
#[test]
fn the_full_run_computes_the_shapes_gate() {
let r = pv(&["lint", &s(&repo_contracts()), "--format", "json"]);
let v = json_of(&r);
let names: Vec<String> = v["gates"]
.as_array()
.map(|g| {
g.iter()
.filter_map(|x| x["name"].as_str().map(String::from))
.collect()
})
.unwrap_or_default();
assert!(
names.iter().any(|n| n == "shapes"),
"{names:?}\n{}",
show(&r)
);
}
17 changes: 0 additions & 17 deletions crates/aprender-contracts-cli/tests/ont4e_refines_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,23 +79,6 @@ fn liskov_witnesses(dir: &Path) -> Vec<PathBuf> {
.unwrap_or_default()
}

#[test]
fn the_spec_probe_holds_on_the_repo_corpus() {
// ONT-001 §5 ONT-4e probe: `"$PV" lint contracts/ --gate refines --format json >"$TMP/lk.json"
// && json_object "$TMP/lk.json" && jq -e '.liskov_pairs_checked>0 and .pc_checker=="fired" and .verdict=="Pass"'`
let r = gate(&repo().join("contracts"));
assert_eq!(r.code, 0, "{}", show(&r));
let v = json_of(&r);
assert!(v.is_object(), "json_object: {v}");
assert!(
v["liskov_pairs_checked"].as_u64().unwrap_or(0) > 0,
"liskov_pairs_checked>0: {v}"
);
assert_eq!(v["pc_checker"], "fired", "{v}");
assert_eq!(v["verdict"], "Pass", "{v}");
assert_eq!(v["witness"]["pc_reasoner"], "fired", "{v}");
}

#[test]
fn a_liskov_pair_passes_and_the_witness_is_a_chain() {
let (dir, r) = reasoned("refines-ok");
Expand Down
Loading
Loading