Merge nucleic/rustic-meadow-koala-wtwq into dev
This commit is contained in:
+56
-6
@@ -105,6 +105,20 @@ enum Event {
|
||||
},
|
||||
#[serde(rename = "dropped", rename_all = "camelCase")]
|
||||
Dropped { seq: u64, ts: u64, count: u64 },
|
||||
/// An operator lever nash was asked to act on (docs/NASH.md §4.3). `action` is
|
||||
/// `ignored` for a lever that arrived through the environment — the channel the
|
||||
/// observed process controls, which nash refuses — and `honored` for one the
|
||||
/// trusted policy file set. Either way it becomes a feed row, so a shell going
|
||||
/// dark is a visible event rather than an absence of events.
|
||||
#[serde(rename = "policy", rename_all = "camelCase")]
|
||||
Policy {
|
||||
seq: u64,
|
||||
ts: u64,
|
||||
lever: String,
|
||||
value: String,
|
||||
action: String,
|
||||
note: String,
|
||||
},
|
||||
}
|
||||
|
||||
/// The pipeline stage an exec event belongs to (docs/NASH.md §5.1). `id` is the same
|
||||
@@ -181,17 +195,31 @@ fn parse_hook_url(url: &str) -> Option<HookUrl> {
|
||||
}
|
||||
|
||||
impl Config {
|
||||
fn from_env() -> Option<Self> {
|
||||
if std::env::var("NUCLEIC_SHELL_CAPTURE").as_deref() == Ok("off") {
|
||||
/// Read transport config from the environment.
|
||||
///
|
||||
/// `require_observation` comes from the trusted policy file (docs/NASH.md §4.3) and
|
||||
/// closes the quietest bypass there was: `NUCLEIC_SHELL_CAPTURE=off`, or simply
|
||||
/// `env -u NUCLEIC_SHELL_HOOK_URL …`, used to leave nash running as an ordinary
|
||||
/// shell that reported nothing — no fallback event, no trace, from a process that
|
||||
/// merely rewrote its own environment. Under the policy, `off` from the environment
|
||||
/// is refused and a missing transport falls back to `fallback_spool`, which the
|
||||
/// host's spool drain already collects. An operator who genuinely wants a surface
|
||||
/// silent turns the policy's `require_observation` off (or omits the file) rather
|
||||
/// than setting a variable the agent could have set for them.
|
||||
fn from_env(require_observation: bool, fallback_spool: &Path) -> Option<Self> {
|
||||
if std::env::var("NUCLEIC_SHELL_CAPTURE").as_deref() == Ok("off") && !require_observation {
|
||||
return None;
|
||||
}
|
||||
let socket = std::env::var_os("NUCLEIC_SHELL_SOCKET").map(PathBuf::from);
|
||||
let hook_url = std::env::var("NUCLEIC_SHELL_HOOK_URL")
|
||||
.ok()
|
||||
.and_then(|u| parse_hook_url(&u));
|
||||
let spool = std::env::var_os("NUCLEIC_SHELL_SPOOL").map(PathBuf::from);
|
||||
let mut spool = std::env::var_os("NUCLEIC_SHELL_SPOOL").map(PathBuf::from);
|
||||
if socket.is_none() && hook_url.is_none() && spool.is_none() {
|
||||
return None;
|
||||
if !require_observation {
|
||||
return None;
|
||||
}
|
||||
spool = Some(fallback_spool.to_path_buf());
|
||||
}
|
||||
Some(Self {
|
||||
socket,
|
||||
@@ -716,10 +744,14 @@ fn flusher(cfg: Config, shell_id: String, parent_shell: Option<String>, rx: mpsc
|
||||
/// configured, installs the recording gate into brush-core and starts the
|
||||
/// flusher thread. Returns whether observation is active.
|
||||
///
|
||||
/// `require_observation` / `fallback_spool` come from the trusted policy file
|
||||
/// (docs/NASH.md §4.3): with it set, an environment that says "don't observe"
|
||||
/// no longer wins, because that environment belongs to the observed process.
|
||||
///
|
||||
/// Also threads shell lineage: reads `NUCLEIC_SHELL_PARENT` as this shell's
|
||||
/// parent and re-exports it as this shell's own id for child shells.
|
||||
pub fn install_from_env() -> bool {
|
||||
let Some(cfg) = Config::from_env() else {
|
||||
pub fn install_from_env(require_observation: bool, fallback_spool: &Path) -> bool {
|
||||
let Some(cfg) = Config::from_env(require_observation, fallback_spool) else {
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -759,6 +791,24 @@ pub fn flush_sync() {
|
||||
}
|
||||
}
|
||||
|
||||
/// Records an operator-lever event (docs/NASH.md §4.3): a lever nash refused to take
|
||||
/// from the environment (`action: "ignored"`) or one the trusted policy set
|
||||
/// (`action: "honored"`). Not flushed here — callers that are about to `exec` away
|
||||
/// call [`flush_sync`] themselves, and the ordinary path flushes at exit.
|
||||
pub fn report_policy(lever: &str, value: &str, action: &str, note: &str) {
|
||||
let Some(obs) = OBSERVER.get() else { return };
|
||||
obs.send(Event::Policy {
|
||||
seq: obs.seq(),
|
||||
ts: now_millis(),
|
||||
lever: lever.to_string(),
|
||||
// Bounded like any other agent-authored string on this path: the value is
|
||||
// whatever the command line put there.
|
||||
value: value.chars().take(512).collect(),
|
||||
action: action.to_string(),
|
||||
note: note.to_string(),
|
||||
});
|
||||
}
|
||||
|
||||
/// Records a compat-fallback event (docs/NASH.md §4.1): nash is about to
|
||||
/// re-exec the real bash because it could not handle `input`.
|
||||
pub fn report_fallback(reason: &str, input: &str) {
|
||||
|
||||
Reference in New Issue
Block a user