KeiSeiKit-1.0/_primitives/_rust/kei-memory/src/backlog.rs
Parfii-bot 0be354a920 KeiSeiKit-public — clean state
Single-commit clean baseline after security scrub of niche-tells,
project codenames, internal jargon, and contributor-email leaks.

Contents:
- 100 Rust crates (_primitives/_rust/)
- 37 agent manifests (_manifests/) + generated specs (_generated/)
- 67 user-invocable skills (skills/)
- 33 hooks (hooks/)
- Composition blocks (_blocks/)
- Documentation (docs/, README.md)
- TS adapter packages (_ts_packages/)
- Assembler (_assembler/)
- Roles (_roles/)
- Templates (_templates/)
- Forgejo CI (.forgejo/)

Author: Denis Parfionovich <info@greendragon.info>

License: see LICENSE.
2026-05-01 12:09:03 +08:00

69 lines
2 KiB
Rust

//! Backlog — silent-first audit item CRUD.
//!
//! Constructor Pattern: one cube, one CLI subcommand's worth of logic.
//! Wire-point #3 of the injection guard (RULE 0.14 audit-CRUD path):
//! malicious content in audit items would be rendered into self-audit
//! reports verbatim, so we scan before persistence the same as
//! `ingest::insert_event` does for transcript messages.
use crate::injection_guard;
use chrono::Utc;
use rusqlite::{params, Connection};
use std::process::ExitCode;
fn err(msg: &str) -> ExitCode {
eprintln!("kei-memory: {msg}");
ExitCode::from(1)
}
pub fn cmd_backlog(
conn: &Connection,
add: Option<String>,
list: bool,
clear: bool,
) -> ExitCode {
let now = Utc::now().timestamp();
if let Some(item) = add {
if let Err(finding) = injection_guard::scan(&item) {
return err(&format!("backlog add blocked by injection guard: {finding}"));
}
if let Err(e) = conn.execute(
"INSERT INTO backlog (ts, item) VALUES (?1, ?2)",
params![now, item],
) {
return err(&format!("backlog add failed: {e}"));
}
println!("added");
return ExitCode::SUCCESS;
}
if clear {
let _ = conn.execute("UPDATE backlog SET processed = 1", []);
println!("cleared");
return ExitCode::SUCCESS;
}
if list {
return list_open(conn);
}
err("backlog: pass --add=<item> | --list | --clear")
}
fn list_open(conn: &Connection) -> ExitCode {
let mut stmt = match conn
.prepare("SELECT ts, item FROM backlog WHERE processed = 0 ORDER BY ts ASC")
{
Ok(s) => s,
Err(e) => return err(&format!("backlog list prep: {e}")),
};
let rows = match stmt.query_map([], |r| {
Ok((r.get::<_, i64>(0)?, r.get::<_, String>(1)?))
}) {
Ok(r) => r,
Err(e) => return err(&format!("backlog list query: {e}")),
};
for row in rows {
if let Ok((ts, it)) = row {
println!("{ts}\t{it}");
}
}
ExitCode::SUCCESS
}