Add fennel::load_config helper for one-shot config loading
Extracts the Fennel::new()?.load_file() two-liner into a free function
so callers (global_config, future Repo::config) don't construct a VM
manually for simple config loads.

https://claude.ai/code/session_01XT5wwGPe79qUX5gBkwCHQ4
change
commit 52d569009094cf1653c700ed5f3533e348eb46b1
author Claude <noreply@anthropic.com>
date
parent cd0f94c0
diff --git a/quire-core/src/fennel.rs b/quire-core/src/fennel.rs
index faceb5d..b88b31f 100644
--- a/quire-core/src/fennel.rs
+++ b/quire-core/src/fennel.rs
@@ -180,6 +180,17 @@ impl Fennel {
     }
 }
 
+/// Create a fresh Fennel VM and load `path` into `T`.
+///
+/// Convenience wrapper for callers that only need a one-shot config load
+/// and don't need to reuse the VM.
+pub fn load_config<T>(path: &Path) -> Result<T, FennelError>
+where
+    T: serde::de::DeserializeOwned,
+{
+    Fennel::new()?.load_file(path)
+}
+
 impl FennelError {
     /// Construct an `Eval` error from an mlua error, extracting line
     /// information when available.
diff --git a/quire-server/src/quire/mod.rs b/quire-server/src/quire/mod.rs
index d71e66d..70b8af7 100644
--- a/quire-server/src/quire/mod.rs
+++ b/quire-server/src/quire/mod.rs
@@ -10,7 +10,6 @@ use crate::ci::{Ci, Executor, Runs};
 use crate::{Error, Result as AppResult};
 pub use quire_core::telemetry::SentryConfig;
 
-use quire_core::fennel::Fennel;
 use quire_core::secret::SecretString;
 
 /// Parsed global configuration (`/var/quire/config.fnl`).
@@ -224,8 +223,7 @@ impl Quire {
         if !config_path.exists() {
             return Err(Error::ConfigNotFound(config_path.display().to_string()));
         }
-        let fennel = Fennel::new()?;
-        Ok(fennel.load_file(&config_path)?)
+        Ok(quire_core::fennel::load_config(&config_path)?)
     }
 
     /// Validate a repository name and return its resolved path.