feat(cli): the operator config surface — identity and output defaults (RFC-007 PR 1)

~/.omnigraph/config.yaml joins the resolution chains as the operator
surface: operator.actor becomes the last hop of THE actor chain (--as >
legacy cli.actor during the RFC-008 window > operator.actor > none, one
implementation for direct-engine and cluster commands alike) and
defaults.output joins the read-format cascade below every more-specific
source. Discovery honors $OMNIGRAPH_HOME (tilde-expanded, #139 finding 9);
an absent file is an empty layer; unknown keys WARN and load (a file
written for later slices must not break this CLI); malformed YAML is a
loud error. The module is CLI-only — the server never reads operator
config (invariant 11 by construction).

$OMNIGRAPH_CONFIG becomes a first-class stand-in for --config in
load_config (flag > env > ./omnigraph.yaml), one meaning in both binaries.

The test harness pins hermeticity: spawned binaries get a nonexistent
OMNIGRAPH_HOME by default so no test ever reads the developer's real
operator config. New coverage: loader unit tests, the env-precedence
matrix on load_config_in, and spawned-binary e2es for the actor chain
(operator wins with no flag/legacy key; legacy outranks it; --as wins) and
the format cascade.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
aaltshuler 2026-06-11 20:29:02 +03:00
parent 08ce8dc34d
commit be4bd46212
7 changed files with 445 additions and 36 deletions

View file

@ -12,12 +12,24 @@ use reqwest::blocking::Client;
use serde_json::Value;
use tempfile::{TempDir, tempdir};
/// Hermetic default: point OMNIGRAPH_HOME at a path that exists on no
/// machine, so spawned binaries never read the developer's real
/// ~/.omnigraph/ (an absent operator config is an empty layer). Tests
/// exercising the operator layer override the var explicitly.
pub const HERMETIC_OPERATOR_HOME: &str = "/nonexistent/omnigraph-test-home";
pub fn cli() -> Command {
Command::cargo_bin("omnigraph").unwrap()
let mut command = Command::cargo_bin("omnigraph").unwrap();
command.env("OMNIGRAPH_HOME", HERMETIC_OPERATOR_HOME);
command.env_remove("OMNIGRAPH_CONFIG");
command
}
pub fn cli_process() -> StdCommand {
StdCommand::new(assert_cmd::cargo::cargo_bin("omnigraph"))
let mut command = StdCommand::new(assert_cmd::cargo::cargo_bin("omnigraph"));
command.env("OMNIGRAPH_HOME", HERMETIC_OPERATOR_HOME);
command.env_remove("OMNIGRAPH_CONFIG");
command
}
fn server_process() -> StdCommand {