fix(keyring): guard empty OPENHUMAN_WORKSPACE and improve boot diagnostics (#3427)

This commit is contained in:
Steven Enamakel
2026-06-06 07:07:52 -04:00
committed by GitHub
parent 7ef726c56a
commit 728073b0f8
4 changed files with 34 additions and 6 deletions
+6 -1
View File
@@ -11,6 +11,10 @@
# [optional] App environment selector: production | staging.
# Defaults to 'production' when unset. Uncomment and set to 'staging' to point
# at the staging backend, use the ~/.openhuman-staging workspace, etc.
# WARNING: staging uses a SEPARATE data directory (~/.openhuman-staging) from
# production (~/.openhuman). Credentials, config, and auth profiles do NOT
# carry over between environments. If you log in via the Tauri app in one
# environment, the CLI running in the other will not see those credentials.
# OPENHUMAN_APP_ENV=staging
# ---------------------------------------------------------------------------
@@ -84,7 +88,8 @@ OPENHUMAN_MAX_ACTIONS_PER_HOUR=20
# [optional] Default model to use
OPENHUMAN_MODEL=
# [optional] Workspace directory (default: ~/.openhuman or ~/.openhuman-staging when OPENHUMAN_APP_ENV=staging)
OPENHUMAN_WORKSPACE=
# Leave commented out to use the default. Setting to empty string is treated as unset.
# OPENHUMAN_WORKSPACE=
# [optional] Default: 0.7
OPENHUMAN_TEMPERATURE=0.7
# [optional] Language for background LLM artifacts such as memory-tree summaries,
+17 -2
View File
@@ -1493,6 +1493,15 @@ async fn run_server_inner(
// sets OPENHUMAN_WORKSPACE to a writable path, then restarts.
match crate::openhuman::config::Config::load_or_init().await {
Ok(cfg) => {
let keyring_dir =
crate::openhuman::keyring::store::workspace_dir_for_file_backend();
log::info!(
"[boot] paths: config={} workspace={} keyring_dir={} keyring_backend={}",
cfg.config_path.display(),
cfg.workspace_dir.display(),
keyring_dir.display(),
crate::openhuman::keyring::backend_name(),
);
match crate::openhuman::memory::global::init(cfg.workspace_dir.clone()) {
Ok(_) => log::info!(
"[boot] memory::global initialized (workspace={})",
@@ -1919,13 +1928,19 @@ fn register_domain_subscribers(
}
Ok(None) => {
log::info!(
"[auth] no session token at startup — scheduler gate set to signed_out"
"[auth] no session token at startup — scheduler gate set to signed_out \
(config_path={}, keyring_backend={})",
config.config_path.display(),
crate::openhuman::keyring::backend_name(),
);
crate::openhuman::scheduler_gate::set_signed_out(true);
}
Err(err) => {
log::warn!(
"[auth] failed to read session token at startup ({err}) — assuming signed_out"
"[auth] failed to read session token at startup ({err}) — assuming signed_out \
(config_path={}, keyring_backend={})",
config.config_path.display(),
crate::openhuman::keyring::backend_name(),
);
crate::openhuman::scheduler_gate::set_signed_out(true);
}
@@ -40,6 +40,10 @@ static MASTER_KEY: OnceLock<Option<[u8; KEY_LEN]>> = OnceLock::new();
pub fn init_master_key() {
// Ensure workspace dir is set for the backend before anything else.
let dir = crate::openhuman::keyring::store::workspace_dir_for_file_backend();
log::info!(
"[keyring] init_master_key: resolved workspace_dir={}",
dir.display()
);
crate::openhuman::keyring::init_workspace(&dir);
MASTER_KEY.get_or_init(|| {
+7 -3
View File
@@ -57,7 +57,8 @@ pub(super) fn build_backend() -> Box<dyn KeyringBackend> {
Some(BackendKind::File) => {
let path = workspace_dir_for_file_backend();
log::info!(
"[keyring] backend=file path={} (OPENHUMAN_KEYRING_BACKEND override)",
"[keyring] backend=file dir={} file={}/dev-keychain.json (OPENHUMAN_KEYRING_BACKEND override)",
path.display(),
path.display()
);
return Box::new(backend::FileBackend::new(&path));
@@ -98,7 +99,8 @@ pub(super) fn build_backend() -> Box<dyn KeyringBackend> {
))
} else {
log::info!(
"[keyring] backend=file path={} (dev environment)",
"[keyring] backend=file dir={} file={}/dev-keychain.json (dev environment)",
path.display(),
path.display()
);
Box::new(backend::FileBackend::new(&path))
@@ -159,7 +161,9 @@ pub fn workspace_dir_for_file_backend() -> PathBuf {
}
if let Ok(custom) = std::env::var("OPENHUMAN_WORKSPACE") {
return PathBuf::from(custom);
if !custom.trim().is_empty() {
return PathBuf::from(custom);
}
}
let home = dirs::home_dir().unwrap_or_else(|| {