Skip to content

Commit b4fb18e

Browse files
committed
fix(assay): drop flagged unwrap via let-else; proofs(storage): hexad round-trip
- assay::assimilate: replace `source.unwrap()` (flagged CWE-754 by Hypatia, though guarded) with a `let Some(source) = source else { ... }` that folds the already-handled None branch in. No behaviour change; zero unwrap. - storage: add proptest `hexad_json_roundtrip_is_identity` (PROOF-PROGRAMME §3.1, faithful form). The gateway octad projection is lossy by design, so the load-bearing integrity property is the on-disk serde round-trip used by write_*_hexad -> load_hexad_dir; this proves it is the identity on the hexad JSON representation. https://claude.ai/code/session_01K2TJLeQSyz4tpydZ18aRcb
1 parent ef1e235 commit b4fb18e

2 files changed

Lines changed: 64 additions & 3 deletions

File tree

src/assay/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ pub fn assimilate(config: AssimilateConfig) -> Result<AssimilationOutcome> {
400400
);
401401

402402
// No source and module already in-tree → call-site rewiring only.
403-
if source.is_none() {
403+
let Some(source) = source else {
404404
if cand.port_present {
405405
let record = AssimilationRecord {
406406
schema_version: assay_schema_version(),
@@ -427,8 +427,7 @@ pub fn assimilate(config: AssimilateConfig) -> Result<AssimilationOutcome> {
427427
"{}: no replacement source; supply --proven <DIR> or --from <FILE>",
428428
cand.id
429429
));
430-
}
431-
let source = source.unwrap();
430+
};
432431
if !source.is_file() {
433432
return Err(anyhow!(
434433
"{}: replacement source {} is not a file",

src/storage/mod.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,7 @@ pub fn latest_reports(dir: &Path, count: usize) -> Result<Vec<PathBuf>> {
13511351
#[cfg(test)]
13521352
mod tests {
13531353
use super::*;
1354+
use proptest::prelude::*;
13541355

13551356
#[test]
13561357
fn test_uuid_from_timestamp() {
@@ -1434,6 +1435,67 @@ mod tests {
14341435
}
14351436
}
14361437

1438+
// PROOF-PROGRAMME §3.1 (Hexad↔Octad), faithful form.
1439+
//
1440+
// The gateway projection `hexad_to_octad_request` is intentionally
1441+
// *lossy* — it flattens the semantic facet into a string metadata map
1442+
// and drops `id` / the optional sub-facets — so it is NOT an
1443+
// isomorphism. The property that actually underwrites on-disk integrity
1444+
// is the serde round-trip exercised by `write_*_hexad` → `load_hexad_dir`:
1445+
// a hexad serialised to its canonical JSON and read back must be
1446+
// identical. This proptest establishes that round-trip is the identity
1447+
// on the hexad's JSON representation (compared as `serde_json::Value`,
1448+
// so it is independent of key ordering). Equality is checked on the
1449+
// Value rather than the struct because `PanicAttackHexad` deliberately
1450+
// does not derive `PartialEq`.
1451+
proptest! {
1452+
#[test]
1453+
fn hexad_json_roundtrip_is_identity(
1454+
id in "[A-Za-z0-9:_./-]{0,48}",
1455+
program in "[A-Za-z0-9:_./-]{0,48}",
1456+
language in "[a-z]{0,12}",
1457+
version in "[0-9.]{1,8}",
1458+
total in 0usize..10_000,
1459+
crit in 0usize..10_000,
1460+
high in 0usize..10_000,
1461+
crashes in 0usize..10_000,
1462+
robustness in 0.0f64..=1.0,
1463+
cats in proptest::collection::vec("[A-Za-z]{1,16}", 0..6),
1464+
attest in proptest::option::of("[0-9a-f]{0,64}"),
1465+
) {
1466+
let hexad = PanicAttackHexad {
1467+
schema: "panic-attack-hexad/1".to_string(),
1468+
id,
1469+
created_at: "2026-06-04T00:00:00Z".to_string(),
1470+
provenance: HexadProvenance {
1471+
tool: "panic-attack".to_string(),
1472+
version,
1473+
program_path: program,
1474+
language,
1475+
attestation_hash: attest,
1476+
},
1477+
semantic: HexadSemantic {
1478+
total_weak_points: total,
1479+
critical_count: crit,
1480+
high_count: high,
1481+
total_crashes: crashes,
1482+
robustness_score: robustness,
1483+
categories: cats,
1484+
migration: None,
1485+
finding: None,
1486+
campaign: None,
1487+
crosslang: None,
1488+
},
1489+
document: serde_json::json!({ "weak_points": [], "n": total }),
1490+
};
1491+
let v1 = serde_json::to_value(&hexad).expect("serialise");
1492+
let back: PanicAttackHexad =
1493+
serde_json::from_value(v1.clone()).expect("deserialise");
1494+
let v2 = serde_json::to_value(&back).expect("re-serialise");
1495+
prop_assert_eq!(v1, v2);
1496+
}
1497+
}
1498+
14371499
#[test]
14381500
fn build_finding_id_stable_per_finding() {
14391501
let wp = sample_weak_point("src/main.rs", 42, WeakPointCategory::UnsafeCode);

0 commit comments

Comments
 (0)