Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions use-cases/hermes-everos-memory/OWNER_PACKET.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ but EverCore is not yet proven active on the remote loopback service.
- Raven Hermes chat bridge: `raven chat send`, bare-text/`/chat` REPL turns,
and the TUI Hermes panel share one sanitized adapter; TUI execution runs in
the background so redraw and key handling remain live.
- Raven single-agent loop surface: `raven loop`, `/loop`, and TUI `l` expose
capture, plan, act, observe, verify, and receipt phases above raw chat.
- Raven v2 research harness: `raven research lanes`, `raven research packet
<lane>`, and `raven research synthesize` keep v2 work as live-gate-calibrated
decision packets instead of freeform research prose.
Expand Down Expand Up @@ -51,6 +53,8 @@ cd use-cases/hermes-everos-memory && just raven-verify
cd use-cases/hermes-everos-memory && just raven-console-check
cd use-cases/hermes-everos-memory && just raven-status
cd use-cases/hermes-everos-memory && bin/raven status --json
cd use-cases/hermes-everos-memory && just raven-loop
cd use-cases/hermes-everos-memory && bin/raven loop --json
cd use-cases/hermes-everos-memory && just raven-research-lanes
cd use-cases/hermes-everos-memory && just raven-research-packet-smoke
cd use-cases/hermes-everos-memory && just raven-research-synthesis
Expand Down
5 changes: 4 additions & 1 deletion use-cases/hermes-everos-memory/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ raven-status:
raven-packet:
bin/raven packet show

raven-loop:
bin/raven loop

raven-gates:
bin/raven gates

Expand Down Expand Up @@ -112,7 +115,7 @@ raven-chat-receipt-smoke:
RAVEN_HERMES_BIN=/bin/echo bin/raven chat send --receipt - raven chat smoke

raven-repl-smoke:
printf '/status\n/gates\n/research native-feel\n/chat raven chat smoke\n/memory raven\n/agents\n/runs\n/audit\n/quit\n' | RAVEN_HERMES_BIN=/bin/echo bin/raven repl
printf '/status\n/loop\n/gates\n/research native-feel\n/chat raven chat smoke\n/memory raven\n/agents\n/runs\n/audit\n/quit\n' | RAVEN_HERMES_BIN=/bin/echo bin/raven repl

raven-tui-smoke:
RAVEN_TUI_ONCE=1 bin/raven tui
Expand Down
7 changes: 4 additions & 3 deletions use-cases/hermes-everos-memory/raven-console/src/audit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub fn run(ctx: &Context) -> NativeAuditReport {
"keybindings",
if source.contains("KeyCode::Char('q')")
&& source.contains("KeyCode::Char('?')")
&& source.contains("KeyCode::Char('l')")
&& source.contains("KeyCode::Char('h')")
&& source.contains("KeyCode::Char('i')")
&& source.contains("KeyCode::Char('o')")
Expand All @@ -30,7 +31,7 @@ pub fn run(ctx: &Context) -> NativeAuditReport {
} else {
Verdict::Block
},
"TUI exposes h/c chat, i prompt input, q, ?, :, /, s, p, m, a, g, r, o, d, n, Esc, and Ctrl-C paths.",
"TUI exposes l loop, h/c chat, i prompt input, q, ?, :, /, s, p, m, a, g, r, o, d, n, Esc, and Ctrl-C paths.",
true,
),
item(
Expand Down Expand Up @@ -88,13 +89,13 @@ pub fn run(ctx: &Context) -> NativeAuditReport {
item(
"typed IPC",
Verdict::Pass,
"RavenSnapshot, RavenReceipt, HermesChatTurn, and ScReport are serde-typed JSON contracts.",
"RavenSnapshot, AgenticLoopState, RavenReceipt, HermesChatTurn, and ScReport are serde-typed JSON contracts.",
false,
),
item(
"evidence visibility",
Verdict::Pass,
"remote hard gates, local gates, runs, docs, and watchlist evidence are visible.",
"remote hard gates, loop phases, local gates, runs, docs, and watchlist evidence are visible.",
false,
),
item(
Expand Down
22 changes: 22 additions & 0 deletions use-cases/hermes-everos-memory/raven-console/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ pub enum Commands {
#[command(subcommand)]
command: MemoryCommand,
},
/// Show the single-agent goal/act/observe/verify loop.
Loop {
#[command(subcommand)]
command: Option<LoopCommand>,
},
/// Show agent lane status.
Agents {
#[command(subcommand)]
Expand Down Expand Up @@ -116,6 +121,12 @@ pub enum AgentsCommand {
List,
}

#[derive(Subcommand)]
pub enum LoopCommand {
/// Show loop state.
Status,
}

#[derive(Subcommand)]
pub enum RunsCommand {
/// List saved receipts or configured verification commands.
Expand Down Expand Up @@ -227,6 +238,15 @@ pub fn execute(cli: Cli, ctx: &Context) -> RavenResult<()> {
}
}
},
Commands::Loop { command: _ } => {
let snapshot = snapshot::build(ctx);
if cli.json {
output::json(&snapshot.loop_state)
} else {
output::agentic_loop(&snapshot.loop_state);
Ok(())
}
}
Commands::Agents { command: _ } => {
let snapshot = snapshot::build(ctx);
if cli.json {
Expand Down Expand Up @@ -408,6 +428,7 @@ pub fn dispatch_repl(ctx: &Context, input: &str) -> RavenResult<bool> {
println!("/help");
println!("/status");
println!("/packet");
println!("/loop");
println!("/chat <prompt>");
println!("/memory <query>");
println!("/agents");
Expand All @@ -421,6 +442,7 @@ pub fn dispatch_repl(ctx: &Context, input: &str) -> RavenResult<bool> {
}
"/status" => output::status(&snapshot::build(ctx)),
"/packet" => output::packet(&snapshot::build(ctx)),
"/loop" => output::agentic_loop(&snapshot::build(ctx).loop_state),
"/agents" => output::agents(&snapshot::build(ctx)),
"/gates" => output::gates(&snapshot::build(ctx)),
"/research" => output::research_lanes(&research::list_lanes()),
Expand Down
53 changes: 53 additions & 0 deletions use-cases/hermes-everos-memory/raven-console/src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,36 @@ impl fmt::Display for Verdict {
}
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
#[serde(rename_all = "UPPERCASE")]
pub enum AgenticLoopPhase {
Capture,
Plan,
Act,
Observe,
Verify,
Receipt,
}

impl AgenticLoopPhase {
pub fn as_str(self) -> &'static str {
match self {
Self::Capture => "CAPTURE",
Self::Plan => "PLAN",
Self::Act => "ACT",
Self::Observe => "OBSERVE",
Self::Verify => "VERIFY",
Self::Receipt => "RECEIPT",
}
}
}

impl fmt::Display for AgenticLoopPhase {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct RunPacket {
pub id: String,
Expand Down Expand Up @@ -190,6 +220,28 @@ pub struct RunView {
pub receipt_path: Option<String>,
}

#[derive(Clone, Debug, Serialize)]
pub struct AgenticLoopStep {
pub phase: AgenticLoopPhase,
pub label: String,
pub verdict: Verdict,
pub evidence: String,
}

#[derive(Clone, Debug, Serialize)]
pub struct AgenticLoopState {
pub verdict: Verdict,
pub objective: String,
pub active_phase: AgenticLoopPhase,
pub mode: String,
pub mutation_policy: String,
pub allowed_actions: Vec<String>,
pub stop_conditions: Vec<String>,
pub evidence_required: Vec<String>,
pub output_contract: String,
pub steps: Vec<AgenticLoopStep>,
}

#[derive(Clone, Debug, Serialize)]
pub struct ScStatusView {
pub verdict: Verdict,
Expand Down Expand Up @@ -256,6 +308,7 @@ pub struct RavenSnapshot {
pub memory: MemoryHealth,
pub runs: Vec<RunView>,
pub sc: ScReport,
pub loop_state: AgenticLoopState,
pub risks: Vec<String>,
pub next_actions: Vec<String>,
pub public_safety: PublicSafetyResult,
Expand Down
39 changes: 36 additions & 3 deletions use-cases/hermes-everos-memory/raven-console/src/output.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::model::{
DoctorReport, HermesChatTurn, MemorySearchResult, NativeAuditReport, RavenReceipt,
RavenSnapshot, ResearchLane, ResearchPacket, ResearchSynthesis, ScProviderView, ScReport,
ScSessionView, ScStatusView, ScWorktreeView, Verdict,
AgenticLoopState, DoctorReport, HermesChatTurn, MemorySearchResult, NativeAuditReport,
RavenReceipt, RavenSnapshot, ResearchLane, ResearchPacket, ResearchSynthesis, ScProviderView,
ScReport, ScSessionView, ScStatusView, ScWorktreeView, Verdict,
};
use crate::sanitizer::{sanitize_json, sanitize_text};
use crate::util::one_line;
Expand Down Expand Up @@ -29,6 +29,10 @@ pub fn status(snapshot: &RavenSnapshot) {
"MEMORY: {} ({})",
snapshot.memory.verdict, snapshot.memory.status
));
line(&format!(
"LOOP: {} (phase {})",
snapshot.loop_state.verdict, snapshot.loop_state.active_phase
));
line("");
line("WATCHLIST:");
for issue in &snapshot.watchlist_issues {
Expand Down Expand Up @@ -70,6 +74,35 @@ pub fn packet(snapshot: &RavenSnapshot) {
}
}

pub fn agentic_loop(state: &AgenticLoopState) {
line("RAVEN_AGENTIC_LOOP");
line(&format!("VERDICT: {}", state.verdict));
line(&format!("OBJECTIVE: {}", state.objective));
line(&format!("ACTIVE_PHASE: {}", state.active_phase));
line(&format!("MODE: {}", state.mode));
line(&format!("MUTATION_POLICY: {}", state.mutation_policy));
line("ALLOWED_ACTIONS:");
for action in &state.allowed_actions {
line(&format!("- {action}"));
}
line("STOP_CONDITIONS:");
for condition in &state.stop_conditions {
line(&format!("- {condition}"));
}
line("EVIDENCE_REQUIRED:");
for item in &state.evidence_required {
line(&format!("- {item}"));
}
line("STEPS:");
for step in &state.steps {
line(&format!(
"- {}: {} {} evidence={}",
step.phase, step.verdict, step.label, step.evidence
));
}
line(&format!("OUTPUT_CONTRACT: {}", state.output_contract));
}

pub fn packet_export_markdown(snapshot: &RavenSnapshot) -> String {
let mut output = Vec::new();
output.push(format!("# {}", snapshot.packet.title));
Expand Down
Loading
Loading