diff --git a/libs/storage/include/merak/storage/image_store.hpp b/libs/storage/include/merak/storage/image_store.hpp index 61c01fa6..151cac63 100644 --- a/libs/storage/include/merak/storage/image_store.hpp +++ b/libs/storage/include/merak/storage/image_store.hpp @@ -18,7 +18,7 @@ class ImageStore { virtual std::string save(const std::string& key, const ImageData& data) = 0; // Load image bytes by key - virtual ImageData load(const std::string& key) = 0; + virtual ImageData load(const std::string& key) const = 0; // Delete image by key virtual void remove(const std::string& key) = 0; diff --git a/libs/storage/include/merak/storage/local_file_image_store.hpp b/libs/storage/include/merak/storage/local_file_image_store.hpp index ee4f6cda..57be96bb 100644 --- a/libs/storage/include/merak/storage/local_file_image_store.hpp +++ b/libs/storage/include/merak/storage/local_file_image_store.hpp @@ -12,7 +12,7 @@ class LocalFileImageStore : public ImageStore { LocalFileImageStore(std::string base_dir, std::string url_prefix); std::string save(const std::string& key, const ImageData& data) override; - ImageData load(const std::string& key) override; + ImageData load(const std::string& key) const override; void remove(const std::string& key) override; std::string public_url(const std::string& key) const override; diff --git a/libs/storage/src/local_file_image_store.cpp b/libs/storage/src/local_file_image_store.cpp index a1f560cd..143701d8 100644 --- a/libs/storage/src/local_file_image_store.cpp +++ b/libs/storage/src/local_file_image_store.cpp @@ -35,7 +35,7 @@ std::string LocalFileImageStore::save(const std::string& key, const ImageData& d return key; } -ImageData LocalFileImageStore::load(const std::string& key) { +ImageData LocalFileImageStore::load(const std::string& key) const { // Path traversal guard fs::path target = fs::weakly_canonical(fs::path(base_dir_) / key); fs::path base = fs::weakly_canonical(fs::path(base_dir_)); diff --git a/libs/worldbuilding/src/condition_evaluator.cpp b/libs/worldbuilding/src/condition_evaluator.cpp index bb82bd7e..52251d27 100644 --- a/libs/worldbuilding/src/condition_evaluator.cpp +++ b/libs/worldbuilding/src/condition_evaluator.cpp @@ -106,6 +106,13 @@ void ConditionEvaluator::register_all_builtins() { registry_["orphaned_foreshadowing"] = eval_orphaned_foreshadowing; registry_["scene_completeness"] = eval_scene_completeness; + // all_checks_passed is a compound type dispatched inside evaluate() + // (checks check_registry_ directly). Registered so list_condition_types() + // includes it; the function below is never actually called. + registry_["all_checks_passed"] = [](const ConditionDef&, const PipelineState&, pqxx::connection&) { + return ConditionResult{"all_checks_passed", true, std::nullopt, std::nullopt, {}}; + }; + // ─── KG condition types ─── registry_["kg_relation_count"] = [this](const ConditionDef& cond, const PipelineState& state, @@ -614,7 +621,7 @@ ConditionResult eval_relation_currency(const ConditionDef& cond, auto row = txn.exec_params1(R"( SELECT COUNT(*) FROM agent_relations ar - JOIN agents a ON (ar.agent_a_id = a.id OR ar.agent_b_id = a.id) + JOIN agents a ON (ar.agent_id = a.id OR ar.target_id = a.id) WHERE a.world_id = $1 AND ar.updated_at < $2 )", state.world_id, chapter_start); int stale = row[0].as(); diff --git a/libs/worldbuilding/tests/test_world_store.cpp b/libs/worldbuilding/tests/test_world_store.cpp index 97c53424..dff6cae9 100644 --- a/libs/worldbuilding/tests/test_world_store.cpp +++ b/libs/worldbuilding/tests/test_world_store.cpp @@ -192,9 +192,11 @@ TEST(WorldStore, CreateWorldCreatesAllDesignDirectoriesAndGodAgent) { "timeline.json")); auto agents = store.list_agents(world.id); - ASSERT_EQ(agents.size(), 1); + ASSERT_EQ(agents.size(), 2); EXPECT_EQ(agents[0].kind, AgentKind::God); EXPECT_EQ(agents[0].name, "god"); + EXPECT_EQ(agents[1].kind, AgentKind::RelationManager); + EXPECT_EQ(agents[1].name, "relation_manager"); } TEST(WorldStore, WorldsAreIsolated) {