Skip to content
46 changes: 46 additions & 0 deletions crates/loomweave-cli/tests/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -823,6 +823,52 @@ fn serve_http_files_storage_failure_returns_closed_error_without_raw_detail() {
assert!(!body.contains(&dir.path().display().to_string()));
}

/// The `GET /api/v1/_capabilities` federation golden, embedded BYTE-IDENTICAL
/// from the on-disk normative fixture. `include_str!` captures the exact bytes
/// (meta + `shape_decl` + examples), so this const IS the wire authority the
/// producer-recheck tests (`serve_http_responses_match_federation_fixture_contracts`
/// and `serve_http_capabilities_and_mcp_stdio_coexist`) compare the live
/// `get_capabilities` handler against.
const CAPABILITIES_GOLDEN: &str =
include_str!("../../../docs/federation/fixtures/get-api-v1-capabilities.json");

/// Layer-1 byte-pin: lowercase-hex `blake3` over the EXACT bytes of the
/// capabilities golden. Pins the whole fixture file so a silent reformat,
/// field reorder, or re-vendor reds here even when the semantic shape the
/// producer-recheck validates is unchanged.
///
/// Tamper proof: perturbing one byte of the fixture (or one hex char of this
/// const) makes `capabilities_golden_bytes_match_layer1_pin` fail with a
/// `left != right` mismatch; `capabilities_golden_byte_pin_rejects_a_mutated_byte`
/// additionally proves a single flipped input byte yields a DIFFERENT digest.
const CAPABILITIES_GOLDEN_BLAKE3: &str =
"74d5fd1230a62f7a279e54d2a798ce85b3ae8b962f593d1d6bd8c0e2db70dbf7";

#[test]
fn capabilities_golden_bytes_match_layer1_pin() {
let actual = blake3::hash(CAPABILITIES_GOLDEN.as_bytes())
.to_hex()
.to_string();
assert_eq!(
actual, CAPABILITIES_GOLDEN_BLAKE3,
"vendored get-api-v1-capabilities golden drifted from its byte-pin; \
re-vendor BYTE-IDENTICAL and update CAPABILITIES_GOLDEN_BLAKE3"
);
}

#[test]
fn capabilities_golden_byte_pin_rejects_a_mutated_byte() {
// Tamper proof: flipping one byte of the golden produces a digest that
// does NOT match the pin, demonstrating the byte-pin is load-bearing.
let mut tampered = CAPABILITIES_GOLDEN.as_bytes().to_vec();
tampered[0] ^= 0x01;
let mutated = blake3::hash(&tampered).to_hex().to_string();
assert_ne!(
mutated, CAPABILITIES_GOLDEN_BLAKE3,
"a single mutated byte must NOT collide with the pinned digest"
);
}

#[test]
fn serve_http_capabilities_and_mcp_stdio_coexist() {
let dir = tempfile::tempdir().expect("temp project");
Expand Down

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions crates/loomweave-mcp/src/catalogue/shortcuts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1072,11 +1072,11 @@ struct CandidateSet {
///
/// - non-code KINDS (file anchors, the project anchor, subsystems, guidance)
/// are never dead-CODE candidates;
/// - a plugin that emitted NO reachability root tags (the Rust plugin today —
/// binary/lib roots unsupported) would have its ENTIRE entity set
/// false-flagged dead, so its entities are excluded and counted for the
/// in-band scope marker instead — a wrong answer is worse than an honest
/// scope statement (the dogfooded `specimen-rs/src/main.rs` false positive).
/// - a plugin that emitted NO reachability root tags would have its ENTIRE
/// entity set false-flagged dead, so its entities are excluded and counted
/// for the in-band scope marker instead — a wrong answer is worse than an
/// honest scope statement (the Rust plugin hit this before ADR-054 gave it
/// root tags; cf. the dogfooded `specimen-rs/src/main.rs` false positive).
fn dead_code_candidate_set(
conn: &rusqlite::Connection,
reachable: &HashSet<String>,
Expand Down
386 changes: 386 additions & 0 deletions crates/loomweave-mcp/tests/entity_associations_conformance_oracle.rs

Large diffs are not rendered by default.

419 changes: 419 additions & 0 deletions crates/loomweave-mcp/tests/issue_detail_conformance_oracle.rs

Large diffs are not rendered by default.

30 changes: 25 additions & 5 deletions crates/loomweave-plugin-rust/src/root_tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,32 @@ fn attr_last_seg_in(attrs: &[Attribute], names: &[&str]) -> bool {
})
}

/// Any attribute that is the bare single ident `name` (no path) for one of
/// `names` — used where the attribute is never path-qualified (`#[proc_macro]`).
/// Any attribute whose path ident — after peeling a single edition-2024
/// `#[unsafe(<inner>)]` wrapper — is one of `names`. Covers both a bare
/// single-ident attribute (`#[proc_macro]`, never path-qualified) and the
/// unsafe-wrapped FFI exports: edition 2024 makes bare `#[no_mangle]` /
/// `#[export_name = "…"]` a hard error, so real code writes
/// `#[unsafe(no_mangle)]` / `#[unsafe(export_name = "…")]`, which syn parses as
/// `Meta::List { path: "unsafe", tokens: <inner attr> }` — the export ident
/// lives one level in. The inner may be a bare path (`no_mangle`) or a
/// name-value (`export_name = "…"`), so it is parsed as a full [`Meta`]. Missing
/// the wrapped form would under-root every edition-2024 FFI export (read dead).
fn attr_is_ident_in(attrs: &[Attribute], names: &[&str]) -> bool {
attrs
.iter()
.any(|a| names.iter().any(|n| a.path().is_ident(n)))
attrs.iter().any(|a| {
if names.iter().any(|n| a.path().is_ident(n)) {
return true;
}
let Meta::List(list) = &a.meta else {
return false;
};
if !list.path.is_ident("unsafe") {
return false;
}
let Ok(inner) = syn::parse2::<Meta>(list.tokens.clone()) else {
return false;
};
names.iter().any(|n| inner.path().is_ident(n))
})
}

/// Any `#[derive(...)]` whose derive list contains a path with a final segment
Expand Down
34 changes: 34 additions & 0 deletions crates/loomweave-plugin-rust/tests/root_tags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,24 @@ fn no_mangle_ffi_export_is_entry_point_and_exported_api() {
);
}

#[test]
fn unsafe_no_mangle_ffi_export_is_entry_point_and_exported_api() {
// Edition 2024 makes bare `#[no_mangle]` a hard error; real FFI code writes
// `#[unsafe(no_mangle)]`, which syn parses as `Meta::List { path: "unsafe",
// tokens: "no_mangle" }`. The export ident lives one level in — it must
// still root, or every edition-2024 FFI export reads as dead (the
// under-rooting failure ADR-054 fights).
let m = tags_by_id(
"k",
"k.m",
"#[unsafe(no_mangle)]\npub extern \"C\" fn ffi() {}\n",
);
assert_eq!(
tags(&m, "rust:function:k.m.ffi"),
["entry-point", "exported-api"]
);
}

// ---- test -----------------------------------------------------------------

#[test]
Expand Down Expand Up @@ -223,6 +241,22 @@ fn export_name_ffi_export_is_entry_point() {
);
}

#[test]
fn unsafe_export_name_ffi_export_is_entry_point() {
// Edition-2024 wrapped form (see `unsafe_no_mangle_…`): `#[unsafe(export_name
// = "…")]` parses as `unsafe(<NameValue>)`, so the inner `export_name` ident
// must be reached through the wrapper.
let m = tags_by_id(
"k",
"k.m",
"#[unsafe(export_name = \"my_export\")]\npub extern \"C\" fn exported() {}\n",
);
assert_eq!(
tags(&m, "rust:function:k.m.exported"),
["entry-point", "exported-api"]
);
}

// ---- regression guard: serde/typetag must NOT be mistaken for a root -------

#[test]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
[
{
"content_hash_at_compute": "beb500c7a64f99d4cfb1e96b5f003b05c35326f2b1d73d7b2bf6225ab1307875",
"qualname": "svc.read_raw",
"wardline_json": {
"content_hash_at_compute": "beb500c7a64f99d4cfb1e96b5f003b05c35326f2b1d73d7b2bf6225ab1307875",
"dead_code_root": {
"is_root": true,
"reason": "Wardline trust-decorated entity is externally reachable or trust-significant.",
"source": "wardline_trust_decorator",
"tags": [
"entry-point"
]
},
"findings": [],
"qualname": "svc.read_raw",
"schema_version": "wardline-taint-1",
"taint": {
"actual_return": "EXTERNAL_RAW",
"contributing_callee_qualname": null,
"declared_return": "EXTERNAL_RAW",
"resolved_call_count": 0,
"source": "anchored",
"unresolved_call_count": 0
}
}
},
{
"content_hash_at_compute": "beb500c7a64f99d4cfb1e96b5f003b05c35326f2b1d73d7b2bf6225ab1307875",
"qualname": "svc.helper",
"wardline_json": {
"content_hash_at_compute": "beb500c7a64f99d4cfb1e96b5f003b05c35326f2b1d73d7b2bf6225ab1307875",
"dead_code_root": {
"is_root": false,
"reason": null,
"source": null,
"tags": []
},
"findings": [],
"qualname": "svc.helper",
"schema_version": "wardline-taint-1",
"taint": {
"actual_return": "UNKNOWN_RAW",
"contributing_callee_qualname": null,
"declared_return": "UNKNOWN_RAW",
"resolved_call_count": 0,
"source": "fallback",
"unresolved_call_count": 0
}
}
},
{
"content_hash_at_compute": "beb500c7a64f99d4cfb1e96b5f003b05c35326f2b1d73d7b2bf6225ab1307875",
"qualname": "svc.leaky",
"wardline_json": {
"content_hash_at_compute": "beb500c7a64f99d4cfb1e96b5f003b05c35326f2b1d73d7b2bf6225ab1307875",
"dead_code_root": {
"is_root": true,
"reason": "Wardline trust-decorated entity is externally reachable or trust-significant.",
"source": "wardline_trust_decorator",
"tags": [
"entry-point"
]
},
"findings": [
{
"fingerprint": "9a291cac4a30b2cd8353f89eb428e184b01cb3919563ebeffd672745bf9cc665",
"line_start": 14,
"path": "svc.py",
"rule_id": "PY-WL-101"
}
],
"qualname": "svc.leaky",
"schema_version": "wardline-taint-1",
"taint": {
"actual_return": "EXTERNAL_RAW",
"contributing_callee_qualname": "svc.read_raw",
"declared_return": "INTEGRAL",
"resolved_call_count": 1,
"source": "anchored",
"unresolved_call_count": 0
}
}
}
]
Loading