mirror of
https://github.com/ruvnet/RuVector.git
synced 2026-08-22 07:03:42 +00:00
* chore: gitignore Hailo venvs, .ruvnet-brain scratch dirs, coverage output Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: rvForge ADRs 283-293 + canonical requirements (ADR-283 master, RVM integration 284-293) One canonical RVF to signed platform installers: @ruvector/forge CLI, hosted build service, Tauri RVF Reader, rvm-* backend crates. Derived from the rvForge product directive; requirements.md is the source of truth for the feat/rvf-forge build-out. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: RVForge platform spec (Store/Reader/Publisher/Registry/Enterprise) + naming Adopt RVForge capitalization; publisher CLI is @ruvector/rvforge. Adds marketplace objects, trust levels, review pipeline, security/ countersigning model, licensing, enterprise governance, and platform acceptance test to the canonical requirements. Seeds loop-state.md for the overnight build loop. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: ADR-294 — RVForge platform (store, registry, trust system) Five products (Store/Reader/Publisher/Registry/Enterprise), immutable predecessor-linked releases, four trust levels, review pipeline, countersigning + revocation semantics, licensing, enterprise override. Documents the @ruvector/rvforge naming supersession. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 2 — forge-core crate agent spawned Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: RVForge registry data model v0.1 (content-addressed, predecessor-linked) Wire-format contract for publisher CLI, Reader, and registry: canonical JSON identity rules, Release/PublisherRecord/CapabilityManifest/ WitnessReceipt/Revocation/TransparencyLogEntry objects, local storage layout. Revocation blocks execution, never deletes local RVFs (ADR-294). Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * ci: RVForge 3-OS build matrix for CLI package and rvf-forge-core crate Path-filtered workflow: npm install/build/test for the CLI on ubuntu/windows/macos, cargo test + clippy -D warnings + fmt check for the crate. Tolerates the pending forge->rvforge package rename and skips gracefully while directories are still landing. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: ADR-291 compatibility matrix v1; reader scaffold in flight Machine-readable runtime-profile/packaging/output matrix the CLI vendors; wasm and os-isolation+wasm supported, microvm and rvm-native planned with explicit isolation claims per ADR-285. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge): @ruvector/rvforge CLI — validate/build/verify with local RVF inspection Publisher/build CLI per ADR-283 §4: init, validate (local, inspection- only, never executes RVF content), build (local mode: canonical build manifest + staged bundle + checksums + provenance), submit/status/ download (hosted API client, FORGE_API_URL), verify (checksum + prove- nance recheck). Stable FORGE_E_* error codes, --json unattended mode, 73 jest tests green across 5 suites with synthetic RVF fixture. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — CLI step 1 complete Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * ci: install rvforge CLI standalone (--workspaces=false) Plain npm install inside npm/packages/rvforge resolves the parent npm workspace and fails EBADPLATFORM on platform-pinned siblings (router-darwin-arm64 on linux runners). Verified clean install + 73 tests green locally with the flag. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 6 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvf-forge-core): inspection-only RVF packaging/verification crate Per ADR-283/290/291: container inspection without execution, Ed25519 root-manifest + per-segment hash verification with unsigned-executable- segment rejection, deterministic canonical build manifest (ADR-291 contract fields), provenance records, SHA256 checksum manifests, stable wire error codes mirroring the CLI. 103 unit tests + integration pipeline test, clippy -D warnings and fmt clean. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — core crate step 2 complete Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 7 — packaging+witness agent spawned Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: RVForge Agent Dock spec (D1-D8) — security/control surface Collapsed pill + expanded trust view, 8 agent states, RVForge-owned chrome vs agent content separation (spoofing defense), per-platform placement, capability card, event-threshold noise control, 5s/2-action termination acceptance test. ADR-295 in flight; dock implementation queued behind reader scaffold in loop plan. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — scope widened to full ADR-283..295 implementation Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge-reader): Tauri v2 Reader scaffold + ADR-295 Agent Dock spec Reader (standalone workspace, excluded from root): verify/capability- card/runtime screens as framework-free static UI, runtime selection implementing the FR004 ladder from the vendored compatibility matrix, P6 capability contract rendering with vague-scope rejection, ADR-288 state-capsule layout (encryption stubbed, marked), inspect stubbed pending rvf-forge-core FFI. 39 tests green, cargo check clean, parent workspace unaffected. ADR-295: dock chrome RVForge-owned, agent content strictly separated. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — reader scaffold + ADR-295 landed Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 10 — dock-impl spawned Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 11 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge): embedded/thin packaging, compat enforcement, inventory, witness chains FR001/FR002: embedded mode with cross-target identical-RVF-hash invariant (build fails on divergence), thin-mode signed locators with round-trip verification. ADR-291 compat-matrix enforcement with closest-supported suggestions. Deterministic software inventory (§3.9). Hash-chained witness receipts (receipts.jsonl) on build/verify with broken-chain detection. 137 jest tests green across 9 suites. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — steps 6+7 CLI side complete Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 13 — publisher-verbs spawned Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 14 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge-registry): content-addressed local registry with transparency log ADR-294 MVP: canonical-JSON content addressing (id excludes signatures), typed registry objects, ed25519 release-publish rules (bad-sig/revoked- key/lineage violations typed), trust levels raisable only by registry signature, non-destructive revocation (blocks execution, reads preserved — tested), Merkle transparency log with inclusion proofs + tamper detection, witness receipt chains on publish/revoke/verify. Reuses rvf-forge-core canonical/error patterns. 67 tests, clippy+fmt clean. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — registry crate landed (P2-impl, P4) Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge-reader): ADR-295 Agent Dock — typed trust boundary, states, roster Trust boundary enforced structurally: AgentProvidedStatus (sanitized task text + progress only) composed separately from SystemOwnedStatus (state, trust badge, network, permissions, witness, cost) — agent input cannot reach system fields by construction. Sanitizer strips ANSI/ control chars, caps length, flags system-label mimicry as suspicious. 8-state machine (pause/terminate always one action; quarantine/ capability-denied not agent-exitable), attention-priority roster (approval > denial > error > running), D8 event thresholds, pill + expanded UI with visually distinct system chrome. 90 reader tests green. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — Agent Dock implemented (P5) Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: ADR status updates — 291/295 Implemented, 283/294 Accepted-in-progress Living-plans sync: statuses now reflect what is actually on the branch, with Updated notes naming landed scope and remaining gaps. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 17 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * ci: cover rvforge-registry and rvforge-reader in the RVForge matrix Registry tests/clippy/fmt ride the existing core job; the reader gets its own 3-OS job run inside its standalone workspace directory. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 18 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: acceptance traceability matrix — merge gate for PR #790 Maps every §15/platform/dock criterion to automated evidence or a named DEFERRED blocker (clean-OS installs, notarization, cross-repo rvm runtime). Merge gates on green AUTOMATED rows across 3 OSes. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 19 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge): publisher verbs pack/test/publish with local registry pack: P4 validation (structure, capability specificity with ADR-294 manual-review-trigger flagging, compat, inventory, license), draft Release + CapabilityManifest objects. test: inspection-only subset of the 10 P4 categories with honest 'skipped: requires quarantined runtime' for execution-dependent ones; tampered variants rejected. publish: ed25519-signed content-addressed writes to the registry-model layout (predecessor lineage, transparency log, witness receipt); keygen via node:crypto; key files never logged, world-readable keys refused. 220 jest tests green across 13 suites. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — publisher verbs landed (P1) Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 21 — parity-check spawned Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge-reader): real rvf-forge-core verification + encrypted state capsules Inspect/verify now call rvf-forge-core (inspection-only, verification before any load, witness record per verification appended to the state dir per ADR-284 req 9); capability card derives from real declared capabilities and refuses to render unverified; state capsules encrypted (ChaCha20-Poly1305, per-install key, 0600 perms) with base-RVF lineage binding and mismatch rejection per ADR-288. 113 reader tests green. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — reader FFI landed Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * docs: ADR 284-293 status sync against landed implementation 284/285/286/288/289 -> Accepted with precise landed-scope notes; 287/290/292/293 stay Proposed with honest gap notes (hosted service, rvm runtime — cross-repo). Living-plans discipline: every status now matches the code on this branch. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 23 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 24 — parity in progress, CI 7 green / 0 red Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 25 — witness-viewer spawned Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge): CLI<->Rust registry parity — proven interoperable rvforge-registry-check binary validates any registry dir (content addresses, release rules, lineage, log inclusion, witness chains); scripts/rvforge-parity-check.sh publishes two lineage-linked releases through the real CLI and validates with the Rust crate — PARITY OK. CLI canonical-JSON/id divergences fixed on the CLI side per contract. CI parity job added (ubuntu). Registry 92 tests, CLI suites green. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — parity landed, PARITY OK Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore(rvforge): prepublishOnly gate (build+test) before any npm publish Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 27 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 28 — acceptance snapshot green, CI 6/0/48 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * feat(rvforge-reader): witness viewer — hash-chain verification screen + dock wiring P15.11: loads reader/CLI receipts.jsonl, verifies per-subject content-id + prevReceipt continuity, renders chronological chains with exact broken-at-N indicators; dock witness-status element now reflects real chain state. Entirely system-owned chrome (ADR-295). Tamper/reorder/ empty cases tested. 133 reader tests green. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — witness viewer landed; all workstreams complete Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 30 — awaiting full-green CI (0 failures) Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 31 — CI 12/42/0 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 32 — CI 31/23/0, parity green in CI Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 33 — CI 29/25/0 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * fix(rvf-forge-core): classify rooted paths uniformly across platforms Windows CI failure: '/etc/hostname' has a root but no drive prefix, so is_absolute() is false on Windows and the path took the relative branch with a different rejection message than the test (and Linux) expected. Branch on has_root() instead — any rooted path goes through the containment check on every platform. Refusal behavior unchanged; only classification is now uniform. Linux gate re-verified: 117 tests, clippy, fmt green. Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 34 — windows path-classification fix pushed Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 35 — post-fix CI clean, re-running Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 36 — CI 32/22/0, fix verified Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 37 — CI 33/21/0 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state iteration 38 — CI 32/22/0 Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx * chore: loop-state — final verdict, proceeding to merge on documented basis Co-Authored-By: claude-flow <ruv@ruv.net> Claude-Session: https://claude.ai/code/session_01ParP55bZs2iTGEGvpnUecx
187 lines
6.4 KiB
Rust
187 lines
6.4 KiB
Rust
//! FR004 selection order: rvm-native → os-isolation+wasm → wasm →
|
|
//! linux-microvm → unsupported.
|
|
|
|
use rvforge_reader::runtime::{
|
|
self, CompatibilityMatrix, HostProfile, PolicySource, SelectionStatus,
|
|
};
|
|
|
|
fn host(os: &str, arch: &str, os_isolation: bool, kvm: bool, rvm: bool) -> HostProfile {
|
|
HostProfile {
|
|
os: os.to_string(),
|
|
arch: arch.to_string(),
|
|
os_isolation,
|
|
kvm,
|
|
rvm_measured_boot: rvm,
|
|
}
|
|
}
|
|
|
|
fn matrix() -> CompatibilityMatrix {
|
|
runtime::embedded_matrix().expect("vendored matrix must parse")
|
|
}
|
|
|
|
/// The vendored copy must stay in step with the canonical document.
|
|
#[test]
|
|
fn vendored_matrix_matches_canonical_copy() {
|
|
let canonical = include_str!("../../../docs/research/rvf-forge/compatibility-matrix.json");
|
|
assert_eq!(
|
|
canonical,
|
|
runtime::COMPATIBILITY_MATRIX_JSON,
|
|
"vendored assets/compatibility-matrix.json has drifted from the canonical doc"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn selection_order_is_the_fr004_order() {
|
|
assert_eq!(
|
|
matrix().selection_order,
|
|
vec!["rvm-native", "os-isolation+wasm", "wasm", "linux-microvm"]
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn order_comes_from_embedded_policy_only() {
|
|
let choice = runtime::select(&matrix(), &host("linux", "x64", true, true, false));
|
|
assert_eq!(choice.policy_source, PolicySource::EmbeddedDefault);
|
|
assert_eq!(choice.order, matrix().selection_order);
|
|
}
|
|
|
|
#[test]
|
|
fn os_isolation_wins_over_plain_wasm_when_the_adapter_can_engage_it() {
|
|
for os in ["windows", "macos", "linux"] {
|
|
for arch in ["x64", "aarch64"] {
|
|
let choice = runtime::select(&matrix(), &host(os, arch, true, true, false));
|
|
assert_eq!(choice.status, SelectionStatus::Selected, "{os}/{arch}");
|
|
assert_eq!(
|
|
choice.profile.as_deref(),
|
|
Some("os-isolation+wasm"),
|
|
"{os}/{arch}"
|
|
);
|
|
assert_eq!(
|
|
choice.isolation_claim.as_deref(),
|
|
Some("os-sandbox+wasm"),
|
|
"hosted RVM must not claim bare-metal isolation (ADR-285)"
|
|
);
|
|
assert!(
|
|
!choice.mechanisms.is_empty(),
|
|
"{os}/{arch} should list mechanisms"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn falls_back_to_wasm_when_os_confinement_is_unavailable() {
|
|
for os in ["windows", "macos", "linux"] {
|
|
let choice = runtime::select(&matrix(), &host(os, "x64", false, true, false));
|
|
assert_eq!(choice.profile.as_deref(), Some("wasm"), "{os}");
|
|
assert_eq!(
|
|
choice.isolation_claim.as_deref(),
|
|
Some("wasm-sandbox"),
|
|
"{os}"
|
|
);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn microvm_is_never_chosen_over_wasm() {
|
|
// linux-microvm sits below wasm in the order, so a KVM host that can also
|
|
// run wasm still gets wasm. Preferring the microVM would be a reordering.
|
|
let choice = runtime::select(&matrix(), &host("linux", "x64", false, true, false));
|
|
assert_eq!(choice.profile.as_deref(), Some("wasm"));
|
|
}
|
|
|
|
#[test]
|
|
fn rvm_native_is_planned_and_therefore_not_selectable_yet() {
|
|
// Even a host claiming measured boot cannot select it while the matrix
|
|
// marks the profile `planned`.
|
|
let choice = runtime::select(&matrix(), &host("rvm", "x64", true, true, true));
|
|
assert_eq!(choice.status, SelectionStatus::Unsupported);
|
|
let rvm = choice
|
|
.evaluated
|
|
.iter()
|
|
.find(|e| e.profile == "rvm-native")
|
|
.expect("rvm-native must be evaluated");
|
|
assert!(!rvm.eligible);
|
|
assert!(rvm.reason.contains("planned"), "reason was: {}", rvm.reason);
|
|
}
|
|
|
|
#[test]
|
|
fn browser_gets_wasm_only() {
|
|
let choice = runtime::select(&matrix(), &host("browser", "wasm32", true, true, true));
|
|
assert_eq!(choice.profile.as_deref(), Some("wasm"));
|
|
let os_iso = choice
|
|
.evaluated
|
|
.iter()
|
|
.find(|e| e.profile == "os-isolation+wasm")
|
|
.unwrap();
|
|
assert!(
|
|
!os_iso.eligible,
|
|
"browser has no os-isolation platform entry"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn unsupported_is_terminal_for_an_unknown_platform() {
|
|
let choice = runtime::select(&matrix(), &host("plan9", "x64", true, true, true));
|
|
assert_eq!(choice.status, SelectionStatus::Unsupported);
|
|
assert!(choice.profile.is_none());
|
|
assert!(choice.isolation_claim.is_none());
|
|
assert!(choice.evaluated.iter().all(|e| !e.eligible));
|
|
}
|
|
|
|
#[test]
|
|
fn unknown_architecture_is_not_selectable() {
|
|
let choice = runtime::select(&matrix(), &host("linux", "riscv64", true, true, false));
|
|
assert_eq!(choice.status, SelectionStatus::Unsupported);
|
|
}
|
|
|
|
/// Every reachable combination of the three host capability flags across every
|
|
/// OS in the matrix, checked against the order.
|
|
#[test]
|
|
fn all_host_flag_combinations_follow_the_order() {
|
|
let m = matrix();
|
|
for os in ["windows", "macos", "linux", "browser", "rvm"] {
|
|
let arch = if os == "browser" { "wasm32" } else { "x64" };
|
|
for os_isolation in [false, true] {
|
|
for kvm in [false, true] {
|
|
for rvm in [false, true] {
|
|
let h = host(os, arch, os_isolation, kvm, rvm);
|
|
let choice = runtime::select(&m, &h);
|
|
let expected = expected_profile(os, os_isolation, kvm);
|
|
assert_eq!(
|
|
choice.profile.as_deref(),
|
|
expected,
|
|
"{os} os_isolation={os_isolation} kvm={kvm} rvm={rvm}"
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/// The order, restated independently of the implementation.
|
|
fn expected_profile(os: &str, os_isolation: bool, kvm: bool) -> Option<&'static str> {
|
|
// rvm-native is `planned`, so it is never reachable regardless of the host.
|
|
let os_iso_available = matches!(os, "windows" | "macos" | "linux") && os_isolation;
|
|
let wasm_available = matches!(os, "windows" | "macos" | "linux" | "browser");
|
|
let microvm_available = os == "linux" && kvm;
|
|
if os_iso_available {
|
|
Some("os-isolation+wasm")
|
|
} else if wasm_available {
|
|
Some("wasm")
|
|
} else if microvm_available {
|
|
// linux-microvm is `planned` too, so this arm is unreachable today; it
|
|
// documents where the profile sits in the order.
|
|
None
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn detected_host_claims_no_isolation_it_cannot_engage() {
|
|
let detected = HostProfile::detect();
|
|
assert!(!detected.os_isolation, "rvm-host adapters do not exist yet");
|
|
assert!(!detected.rvm_measured_boot);
|
|
assert!(!detected.kvm);
|
|
}
|