Bascule shell runtime workspace — governed shell access layer for Substrate/Guildhouse FFC deployments. Crates: - bascule-agent: node agent with SSH server + command filtering - bascule-core: audit, grant engine, ceremony types, session - bascule-filter-core: log line filtering (stdio protocol) - bascule-gateway: OIDC auth, session management, SAT validation - bascule-node-agent: k8s DaemonSet agent (pod watcher, BPF manager) - bascule-proto: protobuf definitions - bascule-shell: governed SSH shell (commands, elevation, REPL) - bascule-tail: chronicle log tail + fanout - ceremony-engine: ceremony lifecycle (6 types + request/resolution) 172 tests passing. Implements SBS-SPEC-0001 shell model. Reference impl for SPEC-SHELLOPS-0001 Layer 1 (root shell).
58 lines
1.8 KiB
Rust
58 lines
1.8 KiB
Rust
use async_trait::async_trait;
|
|
|
|
use crate::governed::command_trait::*;
|
|
use crate::governed::session::{GovernedSession, Governed};
|
|
|
|
pub struct HistoryCommand;
|
|
|
|
#[async_trait]
|
|
impl ShellCommand for HistoryCommand {
|
|
fn name(&self) -> &str { "history" }
|
|
fn tier(&self) -> CommandTier { CommandTier::Analyst }
|
|
fn required_scope(&self) -> RequiredScope { RequiredScope::ReadOnly }
|
|
fn description(&self) -> &str { "Show mutation history for a registry" }
|
|
fn usage(&self) -> &str { "history <registry> [artifact_id]" }
|
|
|
|
async fn execute(
|
|
&self,
|
|
args: &[String],
|
|
session: &mut GovernedSession,
|
|
) -> Result<CommandOutput, CommandError> {
|
|
if session.tenant_context().is_none() {
|
|
return Err(CommandError::NoTenantContext);
|
|
}
|
|
|
|
if args.is_empty() {
|
|
return Err(CommandError::InvalidArgs(
|
|
"Usage: history <registry> [artifact_id]".to_string(),
|
|
));
|
|
}
|
|
|
|
let registry = &args[0];
|
|
let artifact_id = args.get(1);
|
|
|
|
// Phase 1: stub — shows placeholder history.
|
|
let scope = if let Some(id) = artifact_id {
|
|
format!("{}:{}", registry, id)
|
|
} else {
|
|
registry.clone()
|
|
};
|
|
|
|
let lines = vec![
|
|
OutputLine::Text(format!("Mutation history for: {}", scope)),
|
|
OutputLine::Table {
|
|
headers: vec![
|
|
"TIMESTAMP".to_string(),
|
|
"VERB".to_string(),
|
|
"ACTOR".to_string(),
|
|
"CEREMONY".to_string(),
|
|
],
|
|
rows: vec![
|
|
vec!["(no history loaded)".to_string(), "-".to_string(), "-".to_string(), "-".to_string()],
|
|
],
|
|
},
|
|
];
|
|
|
|
Ok(CommandOutput { lines })
|
|
}
|
|
}
|