Audit→CAS, reload rules, time-decay y forma canónica del hash chain
- AuditLog::flush_to_cas() persiste entries pendientes con bytes canónicos
(sha=[0;32]) para que CAS-sha == entry.sha. AuditHeadPointer en disco
tras cada flush — verificación posterior sin escanear el log entero.
- IntrospectRequest::FlushAudit / ReloadRules. brainctl flush-audit / reload.
- Auto-flush task cada 10s cuando --audit-head está configurado.
- ReloadRules { path? } vacía engine + carga (.k vía kcl CLI o .json).
- Observer con time-decay opcional: count * 0.5^(age/half_life).
conditional_prob y pmi consumen valores decayed transparentemente.
- --brain-half-life flag CLI.
- KCL Rust SDK descartado: kcl-* en crates.io son del proyecto KittyCAD,
no KusionStack. Subprocess al CLI sigue siendo la vía canónica.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,9 +51,14 @@ async fn main() -> anyhow::Result<()> {
|
||||
let limit: usize = args.get(2).and_then(|s| s.parse().ok()).unwrap_or(20);
|
||||
IntrospectRequest::ListAudit { limit }
|
||||
}
|
||||
"flush-audit" => IntrospectRequest::FlushAudit,
|
||||
"reload" => {
|
||||
let path = args.get(2).cloned();
|
||||
IntrospectRequest::ReloadRules { path }
|
||||
}
|
||||
other => {
|
||||
eprintln!("subcomando desconocido: {other}");
|
||||
eprintln!("válidos: list-rules | entropy | top <n> | crystals | crystal-kcl <i> | promote <i> | remove <ulid> | audit <limit>");
|
||||
eprintln!("válidos: list-rules | entropy | top <n> | crystals | crystal-kcl <i> | promote <i> | remove <ulid> | audit <limit> | flush-audit | reload [path]");
|
||||
std::process::exit(2);
|
||||
}
|
||||
};
|
||||
@@ -116,6 +121,15 @@ fn print_response(r: &IntrospectResponse) {
|
||||
e.seq, e.timestamp_ms, prev, sha, e.action);
|
||||
}
|
||||
}
|
||||
IntrospectResponse::Flushed { written, head_sha, total_flushed } => {
|
||||
println!("flushed: {written} entries esta pasada, total acumulado: {total_flushed}");
|
||||
if let Some(sha) = head_sha {
|
||||
println!("head sha: {}", hex_long(*sha));
|
||||
}
|
||||
}
|
||||
IntrospectResponse::Reloaded { count } => {
|
||||
println!("reload OK: {count} reglas activas tras reload");
|
||||
}
|
||||
IntrospectResponse::Error(e) => eprintln!("error: {e}"),
|
||||
}
|
||||
}
|
||||
@@ -123,3 +137,7 @@ fn print_response(r: &IntrospectResponse) {
|
||||
fn hex_short(sha: [u8; 32]) -> String {
|
||||
sha[..4].iter().map(|b| format!("{:02x}", b)).collect::<String>() + ".."
|
||||
}
|
||||
|
||||
fn hex_long(sha: [u8; 32]) -> String {
|
||||
sha.iter().map(|b| format!("{:02x}", b)).collect()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user