merge: remove pod command env override
# Conflicts: # docs/environment.md
This commit is contained in:
commit
458a87e81a
|
|
@ -3,8 +3,6 @@ use std::fmt;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
pub const POD_COMMAND_OVERRIDE_ENV: &str = "INSOMNIA_POD_COMMAND";
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||||
pub struct PodRuntimeCommand {
|
pub struct PodRuntimeCommand {
|
||||||
pub program: PathBuf,
|
pub program: PathBuf,
|
||||||
|
|
@ -19,10 +17,6 @@ impl PodRuntimeCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn executable_only(program: impl Into<PathBuf>) -> Self {
|
|
||||||
Self::new(program, Vec::new())
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn for_current_exe() -> io::Result<Self> {
|
pub fn for_current_exe() -> io::Result<Self> {
|
||||||
Ok(Self::for_executable(std::env::current_exe()?))
|
Ok(Self::for_executable(std::env::current_exe()?))
|
||||||
}
|
}
|
||||||
|
|
@ -33,25 +27,12 @@ impl PodRuntimeCommand {
|
||||||
|
|
||||||
/// Resolve the Pod runtime command used for subprocess launches.
|
/// Resolve the Pod runtime command used for subprocess launches.
|
||||||
///
|
///
|
||||||
/// `INSOMNIA_POD_COMMAND` is intentionally executable-only: its value is
|
/// The default launch path is always the current `insomnia` executable plus
|
||||||
/// used as the program path without shell parsing and without the unified
|
/// the unified `pod` prefix argument.
|
||||||
/// `pod` prefix arg. That keeps development/test overrides safe while the
|
|
||||||
/// default path is always `current_exe() + ["pod"]`.
|
|
||||||
pub fn resolve() -> io::Result<Self> {
|
pub fn resolve() -> io::Result<Self> {
|
||||||
if let Some(command) = Self::from_override_env() {
|
|
||||||
return Ok(command);
|
|
||||||
}
|
|
||||||
Self::for_current_exe()
|
Self::for_current_exe()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_override_env() -> Option<Self> {
|
|
||||||
let raw = std::env::var_os(POD_COMMAND_OVERRIDE_ENV)?;
|
|
||||||
if raw.is_empty() {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(Self::executable_only(raw))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn program(&self) -> &Path {
|
pub fn program(&self) -> &Path {
|
||||||
&self.program
|
&self.program
|
||||||
}
|
}
|
||||||
|
|
@ -84,28 +65,6 @@ impl fmt::Display for PodRuntimeCommand {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::sync::Mutex;
|
|
||||||
|
|
||||||
static ENV_LOCK: Mutex<()> = Mutex::new(());
|
|
||||||
|
|
||||||
struct EnvRestore(Option<OsString>);
|
|
||||||
|
|
||||||
impl EnvRestore {
|
|
||||||
fn capture() -> Self {
|
|
||||||
Self(std::env::var_os(POD_COMMAND_OVERRIDE_ENV))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for EnvRestore {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe {
|
|
||||||
match &self.0 {
|
|
||||||
Some(value) => std::env::set_var(POD_COMMAND_OVERRIDE_ENV, value),
|
|
||||||
None => std::env::remove_var(POD_COMMAND_OVERRIDE_ENV),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn insomnia_binary_defaults_to_pod_prefix() {
|
fn insomnia_binary_defaults_to_pod_prefix() {
|
||||||
|
|
@ -139,18 +98,4 @@ mod tests {
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn env_override_is_executable_only_and_not_shell_parsed() {
|
|
||||||
let _guard = ENV_LOCK.lock().unwrap();
|
|
||||||
let _restore = EnvRestore::capture();
|
|
||||||
unsafe {
|
|
||||||
std::env::set_var(POD_COMMAND_OVERRIDE_ENV, "/tmp/mock pod --flag");
|
|
||||||
}
|
|
||||||
|
|
||||||
let command = PodRuntimeCommand::resolve().unwrap();
|
|
||||||
|
|
||||||
assert_eq!(command.program(), Path::new("/tmp/mock pod --flag"));
|
|
||||||
assert!(command.prefix_args().is_empty());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -220,6 +220,9 @@ pub struct SpawnPodTool {
|
||||||
/// Directory the spawned Pod should run in when the LLM did not
|
/// Directory the spawned Pod should run in when the LLM did not
|
||||||
/// override it. Defaults to the spawner's pwd — see module docs.
|
/// override it. Defaults to the spawner's pwd — see module docs.
|
||||||
spawner_pwd: PathBuf,
|
spawner_pwd: PathBuf,
|
||||||
|
/// Optional typed runtime command injected by tests. Production resolves
|
||||||
|
/// the runtime command from `std::env::current_exe()` at launch time.
|
||||||
|
runtime_command: Option<PodRuntimeCommand>,
|
||||||
/// Shared registry of spawned children, also used by the
|
/// Shared registry of spawned children, also used by the
|
||||||
/// pod-comm tools (`SendToPod` / `ReadPodOutput` / `StopPod`) and by
|
/// pod-comm tools (`SendToPod` / `ReadPodOutput` / `StopPod`) and by
|
||||||
/// Pod discovery. Writes the list to runtime and durable Pod state on
|
/// Pod discovery. Writes the list to runtime and durable Pod state on
|
||||||
|
|
@ -258,12 +261,14 @@ impl SpawnPodTool {
|
||||||
spawner_manifest: PodManifest,
|
spawner_manifest: PodManifest,
|
||||||
available_profiles: AvailableProfiles,
|
available_profiles: AvailableProfiles,
|
||||||
spawner_scope: SharedScope,
|
spawner_scope: SharedScope,
|
||||||
|
runtime_command: Option<PodRuntimeCommand>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
spawner_name,
|
spawner_name,
|
||||||
callback_socket,
|
callback_socket,
|
||||||
runtime_base,
|
runtime_base,
|
||||||
spawner_pwd,
|
spawner_pwd,
|
||||||
|
runtime_command,
|
||||||
registry,
|
registry,
|
||||||
parent_socket,
|
parent_socket,
|
||||||
spawner_manifest,
|
spawner_manifest,
|
||||||
|
|
@ -409,9 +414,14 @@ impl SpawnPodTool {
|
||||||
spawn_config_json: &str,
|
spawn_config_json: &str,
|
||||||
predicted_socket: &Path,
|
predicted_socket: &Path,
|
||||||
) -> Result<(), ToolError> {
|
) -> Result<(), ToolError> {
|
||||||
let runtime_command = PodRuntimeCommand::resolve().map_err(|error| {
|
let runtime_command = match &self.runtime_command {
|
||||||
ToolError::ExecutionFailed(format!("failed to resolve Pod runtime command: {error}"))
|
Some(command) => command.clone(),
|
||||||
})?;
|
None => PodRuntimeCommand::resolve().map_err(|error| {
|
||||||
|
ToolError::ExecutionFailed(format!(
|
||||||
|
"failed to resolve Pod runtime command: {error}"
|
||||||
|
))
|
||||||
|
})?,
|
||||||
|
};
|
||||||
|
|
||||||
// Pre-create the child's runtime dir so we have a stable place to
|
// Pre-create the child's runtime dir so we have a stable place to
|
||||||
// capture its stderr before it has had a chance to bind anything.
|
// capture its stderr before it has had a chance to bind anything.
|
||||||
|
|
@ -764,6 +774,59 @@ pub fn spawn_pod_tool(
|
||||||
spawner_manifest: PodManifest,
|
spawner_manifest: PodManifest,
|
||||||
spawner_scope: SharedScope,
|
spawner_scope: SharedScope,
|
||||||
prompts: Arc<PromptCatalog>,
|
prompts: Arc<PromptCatalog>,
|
||||||
|
) -> ToolDefinition {
|
||||||
|
spawn_pod_tool_impl(
|
||||||
|
spawner_name,
|
||||||
|
callback_socket,
|
||||||
|
runtime_base,
|
||||||
|
spawner_pwd,
|
||||||
|
registry,
|
||||||
|
parent_socket,
|
||||||
|
spawner_manifest,
|
||||||
|
spawner_scope,
|
||||||
|
prompts,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn spawn_pod_tool_with_runtime_command(
|
||||||
|
spawner_name: String,
|
||||||
|
callback_socket: PathBuf,
|
||||||
|
runtime_base: PathBuf,
|
||||||
|
spawner_pwd: PathBuf,
|
||||||
|
registry: Arc<SpawnedPodRegistry>,
|
||||||
|
parent_socket: Option<PathBuf>,
|
||||||
|
spawner_manifest: PodManifest,
|
||||||
|
spawner_scope: SharedScope,
|
||||||
|
prompts: Arc<PromptCatalog>,
|
||||||
|
runtime_command: PodRuntimeCommand,
|
||||||
|
) -> ToolDefinition {
|
||||||
|
spawn_pod_tool_impl(
|
||||||
|
spawner_name,
|
||||||
|
callback_socket,
|
||||||
|
runtime_base,
|
||||||
|
spawner_pwd,
|
||||||
|
registry,
|
||||||
|
parent_socket,
|
||||||
|
spawner_manifest,
|
||||||
|
spawner_scope,
|
||||||
|
prompts,
|
||||||
|
Some(runtime_command),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn spawn_pod_tool_impl(
|
||||||
|
spawner_name: String,
|
||||||
|
callback_socket: PathBuf,
|
||||||
|
runtime_base: PathBuf,
|
||||||
|
spawner_pwd: PathBuf,
|
||||||
|
registry: Arc<SpawnedPodRegistry>,
|
||||||
|
parent_socket: Option<PathBuf>,
|
||||||
|
spawner_manifest: PodManifest,
|
||||||
|
spawner_scope: SharedScope,
|
||||||
|
prompts: Arc<PromptCatalog>,
|
||||||
|
runtime_command: Option<PodRuntimeCommand>,
|
||||||
) -> ToolDefinition {
|
) -> ToolDefinition {
|
||||||
Arc::new(move || {
|
Arc::new(move || {
|
||||||
let schema = schemars::schema_for!(SpawnPodInput);
|
let schema = schemars::schema_for!(SpawnPodInput);
|
||||||
|
|
@ -794,6 +857,7 @@ pub fn spawn_pod_tool(
|
||||||
spawner_manifest.clone(),
|
spawner_manifest.clone(),
|
||||||
available_profiles,
|
available_profiles,
|
||||||
spawner_scope.clone(),
|
spawner_scope.clone(),
|
||||||
|
runtime_command.clone(),
|
||||||
));
|
));
|
||||||
(meta, tool)
|
(meta, tool)
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
//! Integration tests for the `SpawnPod` tool.
|
//! Integration tests for the `SpawnPod` tool.
|
||||||
//!
|
//!
|
||||||
//! These tests exercise the tool's pod-registry delegation, subprocess
|
//! These tests exercise the tool's pod-registry delegation, subprocess
|
||||||
//! launch, socket handoff, and `spawned_pods.json` write without relying
|
//! launch, socket handoff, and `spawned_pods.json` write through an injected
|
||||||
//! on the real Pod runtime executable. `INSOMNIA_POD_COMMAND` is pointed at
|
//! typed runtime command. The mock command exits immediately while a
|
||||||
//! `/bin/true` (which exits immediately) while a test-owned Unix
|
//! test-owned Unix listener pre-binds the predicted socket path, so the tool
|
||||||
//! listener pre-binds the predicted socket path, so the tool sees the
|
//! sees the "child" as live.
|
||||||
//! "child" as live.
|
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::sync::{LazyLock, Mutex};
|
use std::sync::{LazyLock, Mutex};
|
||||||
|
|
||||||
|
use insomnia::PodRuntimeCommand;
|
||||||
use llm_worker::tool::{ToolError, ToolOutput};
|
use llm_worker::tool::{ToolError, ToolOutput};
|
||||||
use manifest::{
|
use manifest::{
|
||||||
AuthRef, ModelManifest, Permission, PodManifest, PodManifestConfig, PodMetaConfig, SchemeKind,
|
AuthRef, ModelManifest, Permission, PodManifest, PodManifestConfig, PodMetaConfig, SchemeKind,
|
||||||
|
|
@ -18,7 +18,7 @@ use manifest::{
|
||||||
use pod::runtime::dir::{RuntimeDir, SpawnedPodRecord};
|
use pod::runtime::dir::{RuntimeDir, SpawnedPodRecord};
|
||||||
use pod::runtime::pod_registry::{self, LockFileGuard};
|
use pod::runtime::pod_registry::{self, LockFileGuard};
|
||||||
use pod::spawn::registry::SpawnedPodRegistry;
|
use pod::spawn::registry::SpawnedPodRegistry;
|
||||||
use pod::spawn::tool::spawn_pod_tool;
|
use pod::spawn::tool::spawn_pod_tool_with_runtime_command;
|
||||||
use protocol::stream::{JsonLineReader, JsonLineWriter};
|
use protocol::stream::{JsonLineReader, JsonLineWriter};
|
||||||
use protocol::{Event, Method};
|
use protocol::{Event, Method};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
@ -26,8 +26,8 @@ use std::sync::Arc;
|
||||||
use tempfile::TempDir;
|
use tempfile::TempDir;
|
||||||
use tokio::net::UnixListener;
|
use tokio::net::UnixListener;
|
||||||
|
|
||||||
/// Serialises tests that mutate `INSOMNIA_RUNTIME_DIR` /
|
/// Serialises tests that mutate `INSOMNIA_RUNTIME_DIR` across the
|
||||||
/// `INSOMNIA_POD_COMMAND` across the thread-pooled test harness.
|
/// thread-pooled test harness.
|
||||||
static ENV_LOCK: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
|
static ENV_LOCK: LazyLock<Mutex<()>> = LazyLock::new(|| Mutex::new(()));
|
||||||
|
|
||||||
struct EnvGuard {
|
struct EnvGuard {
|
||||||
|
|
@ -141,11 +141,8 @@ fn accept_one_method(listener: UnixListener) -> tokio::task::JoinHandle<Option<M
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn point_runtime_command_at_true() {
|
fn mock_runtime_command() -> PodRuntimeCommand {
|
||||||
let path = which_true();
|
PodRuntimeCommand::new(which_true(), Vec::new())
|
||||||
unsafe {
|
|
||||||
std::env::set_var("INSOMNIA_POD_COMMAND", &path);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `/bin/true` only exists on FHS-compliant systems. Resolve it via PATH
|
/// `/bin/true` only exists on FHS-compliant systems. Resolve it via PATH
|
||||||
|
|
@ -213,7 +210,6 @@ fn shared_scope_for(allow_root: &Path) -> SharedScope {
|
||||||
fn clear_env() {
|
fn clear_env() {
|
||||||
unsafe {
|
unsafe {
|
||||||
std::env::remove_var("INSOMNIA_RUNTIME_DIR");
|
std::env::remove_var("INSOMNIA_RUNTIME_DIR");
|
||||||
std::env::remove_var("INSOMNIA_POD_COMMAND");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -224,14 +220,13 @@ async fn spawn_pod_delegates_scope_and_sends_run() {
|
||||||
let allow_root = TempDir::new().unwrap();
|
let allow_root = TempDir::new().unwrap();
|
||||||
let (_tmp, runtime_base, spawner_socket, spawner_rd) =
|
let (_tmp, runtime_base, spawner_socket, spawner_rd) =
|
||||||
setup_spawner("root", allow_root.path()).await;
|
setup_spawner("root", allow_root.path()).await;
|
||||||
point_runtime_command_at_true();
|
|
||||||
|
|
||||||
let (_predicted_socket, listener) = bind_mock_pod_socket(&runtime_base, "child").await;
|
let (_predicted_socket, listener) = bind_mock_pod_socket(&runtime_base, "child").await;
|
||||||
let received = accept_one_method(listener);
|
let received = accept_one_method(listener);
|
||||||
|
|
||||||
let registry = SpawnedPodRegistry::new(spawner_rd.clone());
|
let registry = SpawnedPodRegistry::new(spawner_rd.clone());
|
||||||
let spawner_scope = shared_scope_for(allow_root.path());
|
let spawner_scope = shared_scope_for(allow_root.path());
|
||||||
let def = spawn_pod_tool(
|
let def = spawn_pod_tool_with_runtime_command(
|
||||||
"root".into(),
|
"root".into(),
|
||||||
spawner_socket.clone(),
|
spawner_socket.clone(),
|
||||||
runtime_base.clone(),
|
runtime_base.clone(),
|
||||||
|
|
@ -241,6 +236,7 @@ async fn spawn_pod_delegates_scope_and_sends_run() {
|
||||||
dummy_manifest(allow_root.path()),
|
dummy_manifest(allow_root.path()),
|
||||||
spawner_scope.clone(),
|
spawner_scope.clone(),
|
||||||
builtin_prompts(),
|
builtin_prompts(),
|
||||||
|
mock_runtime_command(),
|
||||||
);
|
);
|
||||||
let (_meta, tool) = def();
|
let (_meta, tool) = def();
|
||||||
|
|
||||||
|
|
@ -317,11 +313,10 @@ async fn spawn_pod_rejects_scope_outside_spawner() {
|
||||||
let outside = TempDir::new().unwrap();
|
let outside = TempDir::new().unwrap();
|
||||||
let (_tmp, runtime_base, spawner_socket, spawner_rd) =
|
let (_tmp, runtime_base, spawner_socket, spawner_rd) =
|
||||||
setup_spawner("root", allow_root.path()).await;
|
setup_spawner("root", allow_root.path()).await;
|
||||||
point_runtime_command_at_true();
|
|
||||||
|
|
||||||
let registry = SpawnedPodRegistry::new(spawner_rd);
|
let registry = SpawnedPodRegistry::new(spawner_rd);
|
||||||
let spawner_scope = shared_scope_for(allow_root.path());
|
let spawner_scope = shared_scope_for(allow_root.path());
|
||||||
let def = spawn_pod_tool(
|
let def = spawn_pod_tool_with_runtime_command(
|
||||||
"root".into(),
|
"root".into(),
|
||||||
spawner_socket,
|
spawner_socket,
|
||||||
runtime_base,
|
runtime_base,
|
||||||
|
|
@ -331,6 +326,7 @@ async fn spawn_pod_rejects_scope_outside_spawner() {
|
||||||
dummy_manifest(allow_root.path()),
|
dummy_manifest(allow_root.path()),
|
||||||
spawner_scope.clone(),
|
spawner_scope.clone(),
|
||||||
builtin_prompts(),
|
builtin_prompts(),
|
||||||
|
mock_runtime_command(),
|
||||||
);
|
);
|
||||||
let (_meta, tool) = def();
|
let (_meta, tool) = def();
|
||||||
|
|
||||||
|
|
@ -379,7 +375,6 @@ async fn spawn_pod_rolls_back_reservation_when_socket_never_appears() {
|
||||||
let allow_root = TempDir::new().unwrap();
|
let allow_root = TempDir::new().unwrap();
|
||||||
let (_tmp, runtime_base, spawner_socket, spawner_rd) =
|
let (_tmp, runtime_base, spawner_socket, spawner_rd) =
|
||||||
setup_spawner("root", allow_root.path()).await;
|
setup_spawner("root", allow_root.path()).await;
|
||||||
point_runtime_command_at_true();
|
|
||||||
|
|
||||||
// Deliberately do NOT bind a socket at the predicted path. The
|
// Deliberately do NOT bind a socket at the predicted path. The
|
||||||
// tool's wait_for_socket should time out, triggering rollback.
|
// tool's wait_for_socket should time out, triggering rollback.
|
||||||
|
|
@ -394,7 +389,7 @@ async fn spawn_pod_rolls_back_reservation_when_socket_never_appears() {
|
||||||
|
|
||||||
let registry = SpawnedPodRegistry::new(spawner_rd);
|
let registry = SpawnedPodRegistry::new(spawner_rd);
|
||||||
let spawner_scope = shared_scope_for(allow_root.path());
|
let spawner_scope = shared_scope_for(allow_root.path());
|
||||||
let def = spawn_pod_tool(
|
let def = spawn_pod_tool_with_runtime_command(
|
||||||
"root".into(),
|
"root".into(),
|
||||||
spawner_socket,
|
spawner_socket,
|
||||||
runtime_base,
|
runtime_base,
|
||||||
|
|
@ -404,6 +399,7 @@ async fn spawn_pod_rolls_back_reservation_when_socket_never_appears() {
|
||||||
dummy_manifest(allow_root.path()),
|
dummy_manifest(allow_root.path()),
|
||||||
spawner_scope.clone(),
|
spawner_scope.clone(),
|
||||||
builtin_prompts(),
|
builtin_prompts(),
|
||||||
|
mock_runtime_command(),
|
||||||
);
|
);
|
||||||
let (_meta, tool) = def();
|
let (_meta, tool) = def();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ Credential env var は interoperability のために現時点では残ってい
|
||||||
- `INSOMNIA_USER_MANIFEST` は通常の profile-based Pod/TUI startup の一部ではない。one-file manifest の debug / compatibility path には `insomnia pod --manifest <PATH>` を使う。
|
- `INSOMNIA_USER_MANIFEST` は通常の profile-based Pod/TUI startup の一部ではない。one-file manifest の debug / compatibility path には `insomnia pod --manifest <PATH>` を使う。
|
||||||
- ambient `.insomnia/manifest.toml` discovery は通常の fresh startup の一部ではない。
|
- ambient `.insomnia/manifest.toml` discovery は通常の fresh startup の一部ではない。
|
||||||
- `INSOMNIA_POD_COMMAND` は single-binary 化に伴って削除する。Pod runtime は `insomnia pod ...` の typed command として起動する。
|
- `INSOMNIA_POD_COMMAND` は single-binary 化に伴って削除する。Pod runtime は `insomnia pod ...` の typed command として起動する。
|
||||||
- 開発・テスト専用の環境変数は supported surface にしない。既存利用も削除する。
|
- `INSOMNIA_TEST_*` のような開発・テスト専用の環境変数は supported surface にしない。既存利用も削除する。
|
||||||
- `insomnia-pod` は installed command ではない。Pod runtime は `insomnia pod ...` から起動する。
|
- `insomnia-pod` は installed command ではない。Pod runtime は `insomnia pod ...` から起動する。
|
||||||
- 通常 runtime は `.env` ファイルを load しない。
|
- 通常 runtime は `.env` ファイルを load しない。
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ Credential env var は interoperability のために現時点では残ってい
|
||||||
1. test-only env var を削除し、public env behavior を検証する test だけを shared guard / test-support crate に集約する。
|
1. test-only env var を削除し、public env behavior を検証する test だけを shared guard / test-support crate に集約する。
|
||||||
2. path resolution は `manifest::paths` に集約し、path precedence rule を別の場所で重複実装しない。
|
2. path resolution は `manifest::paths` に集約し、path precedence rule を別の場所で重複実装しない。
|
||||||
3. credential source は resolved config 上で明示し、process-env convention を増やすより typed secret reference へ寄せる。encrypted secret store 導入時に credential env var 依存を削除する。
|
3. credential source は resolved config 上で明示し、process-env convention を増やすより typed secret reference へ寄せる。encrypted secret store 導入時に credential env var 依存を削除する。
|
||||||
4. `INSOMNIA_POD_COMMAND` は削除し、Pod runtime 起動は `current_exe() + ["pod"]` の typed command に一本化する。
|
4. Pod runtime 起動は環境変数ではなく `current_exe() + ["pod"]` の typed command に一本化する。
|
||||||
5. fallback env は独立した設定項目として増やさず、対応する main key の解決順として文書化する。
|
5. fallback env は独立した設定項目として増やさず、対応する main key の解決順として文書化する。
|
||||||
6. 空の env value は、変数 category に応じて unset / invalid のどちらとして扱うかを一貫させ、新しい supported variable を追加する場合は挙動を文書化する。
|
6. 空の env value は、変数 category に応じて unset / invalid のどちらとして扱うかを一貫させ、新しい supported variable を追加する場合は挙動を文書化する。
|
||||||
7. 外部 process integration が env inheritance / filtering を必要とする場合は、ambient な inherited process state に頼らず、明示的な policy boundary として設計する。
|
7. 外部 process integration が env inheritance / filtering を必要とする場合は、ambient な inherited process state に頼らず、明示的な policy boundary として設計する。
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user