use super::*;
#[test]
fn portfolio_palace_exposes_stable_id() {
let dir = tempfile::tempdir().expect("tempdir");
let palace = PortfolioPalace::provision(dir.path());
assert_eq!(palace.id(), PORTFOLIO_PALACE_ID);
assert_eq!(palace.id(), "tm-manager-portfolio");
}
#[cfg(not(feature = "manager-memory"))]
#[test]
fn portfolio_palace_reports_unavailable_without_feature() {
let dir = tempfile::tempdir().expect("tempdir");
let palace = PortfolioPalace::provision(dir.path());
assert!(!palace.is_available());
let reason = palace
.unavailable_reason()
.expect("unavailable palace must name a reason");
assert!(
reason.contains("manager-memory"),
"reason should point at the missing feature: {reason}"
);
}
#[cfg(feature = "manager-memory")]
#[test]
fn portfolio_palace_provisions_and_is_idempotent() {
use trusty_common::memory_core::retrieval::seed_shared_embedder_with_mock;
seed_shared_embedder_with_mock();
let dir = tempfile::tempdir().expect("tempdir");
let first = PortfolioPalace::provision(dir.path());
assert!(first.is_available(), "first provision must be available");
let mem = first.memory().expect("live memory under feature");
assert_eq!(mem.persisted_palace_count().expect("count"), 1);
assert_eq!(mem.palace_id().as_str(), PORTFOLIO_PALACE_ID);
let second = PortfolioPalace::provision(dir.path());
assert!(second.is_available());
assert_eq!(
second
.memory()
.expect("live memory")
.persisted_palace_count()
.expect("count"),
1,
"provisioning twice must yield exactly ONE portfolio palace"
);
}
#[cfg(feature = "manager-memory")]
#[test]
fn portfolio_ensure_palace_never_rewrites_metadata_of_a_present_but_unopenable_palace() {
use trusty_common::memory_core::retrieval::seed_shared_embedder_with_mock;
seed_shared_embedder_with_mock();
let dir = tempfile::tempdir().expect("tempdir");
let data_root = dir.path().join("palace");
let palace_dir = data_root.join(PORTFOLIO_PALACE_ID);
std::fs::create_dir_all(&palace_dir).expect("create palace dir");
let metadata = palace_dir.join("palace.json");
std::fs::write(
&metadata,
serde_json::to_vec_pretty(&serde_json::json!({
"id": PORTFOLIO_PALACE_ID,
"name": PORTFOLIO_PALACE_ID,
"description": serde_json::Value::Null,
"created_at": "2020-01-02T03:04:05Z",
"data_dir": palace_dir,
"schema_version": 1,
}))
.expect("serialise palace.json"),
)
.expect("write palace.json");
std::fs::create_dir(palace_dir.join("kg.redb")).expect("directory where the KG store belongs");
let metadata_before = std::fs::read(&metadata).expect("read palace.json");
let before: serde_json::Value =
serde_json::from_slice(&metadata_before).expect("parse palace.json");
let err = match PortfolioMemory::open(data_root) {
Ok(_) => {
panic!("opening a present-but-unopenable palace must fail, not silently recreate it")
}
Err(e) => e,
};
let after: serde_json::Value =
serde_json::from_slice(&std::fs::read(&metadata).expect("read palace.json"))
.expect("parse palace.json");
assert_eq!(
before["created_at"], after["created_at"],
"created_at was rewritten, so `ensure_palace` fell through to \
`create_palace` for a palace that exists but could not be read; the \
open error was: {err}"
);
assert_eq!(
metadata_before,
std::fs::read(&metadata).expect("read palace.json"),
"palace.json must be byte-identical — any rewrite means `create_palace` ran"
);
}
#[cfg(feature = "manager-memory")]
#[test]
#[should_panic(expected = "#8545")]
fn portfolio_palace_under_a_fenced_home_is_refused() {
use trusty_common::memory_core::retrieval::seed_shared_embedder_with_mock;
seed_shared_embedder_with_mock();
let root = crate::core::home_write_fence::armed_roots()
.iter()
.find(|r| r.ends_with(".trusty-mpm"))
.expect("the lib binary fences ~/.trusty-mpm");
let _ = PortfolioPalace::provision(&root.join("tm-8545-fence-probe"));
}
#[cfg(feature = "manager-memory")]
#[tokio::test]
async fn portfolio_memory_remember_then_recall_round_trips() {
use trusty_common::memory_core::retrieval::seed_shared_embedder_with_mock;
seed_shared_embedder_with_mock();
let dir = tempfile::tempdir().expect("tempdir");
let palace = PortfolioPalace::provision(dir.path());
let mem = palace.memory().expect("live memory under feature");
mem.remember(
"Portfolio digest 2026-07-14: widget shipped, gizmo stalled on review.",
vec!["digest".to_string()],
)
.await
.expect("remember");
let hits = mem
.recall("what shipped in the portfolio")
.await
.expect("recall");
assert!(
!hits.is_empty(),
"a remembered portfolio observation must be recallable"
);
}