audit-verify, autopromote, histogramas y hot-reload caps

- audit::verify_chain_from_cas() recorre prev_sha desde head hasta genesis,
  valida sha256(blob)==sha del CAS para detectar tampering. Endpoint
  VerifyAudit + brainctl audit-verify.
- autopromote loop background: cada N segundos detecta cristales sobre
  threshold y los promueve sin operador. Anti-doble vía HashSet de pares
  (ant, con). Flag --autopromote-secs.
- GapHistogram con buckets exponenciales (1ms..1000s) capturado en
  observer.record(). top_gap_pairs(K) limita cardinalidad. Expuesto en
  Prometheus como ente_brain_pair_gap_seconds histogram per pair.
- BusRequest::UpdateCapabilities con auth obligatorio (sólo el dueño puede
  modificar sus caps). Incarnated.dynamic_provides separa runtime de la
  Card immutable. Graph mediator actualiza providers index + revoca grants.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sergio
2026-05-03 23:32:54 +00:00
parent a4fa42c781
commit badf4257ec
12 changed files with 406 additions and 8 deletions
+11
View File
@@ -52,6 +52,7 @@ async fn main() -> anyhow::Result<()> {
IntrospectRequest::ListAudit { limit }
}
"flush-audit" => IntrospectRequest::FlushAudit,
"audit-verify" | "verify" => IntrospectRequest::VerifyAudit,
"reload" => {
let path = args.get(2).cloned();
IntrospectRequest::ReloadRules { path }
@@ -130,6 +131,16 @@ fn print_response(r: &IntrospectResponse) {
IntrospectResponse::Reloaded { count } => {
println!("reload OK: {count} reglas activas tras reload");
}
IntrospectResponse::AuditVerified(rep) => {
if let Some(seq) = rep.broken_at_seq {
println!("✗ verificación FALLÓ tras seq={seq}");
if let Some(e) = &rep.error { println!(" motivo: {e}"); }
println!(" entries verificadas: {}", rep.verified);
} else {
println!("✓ chain verificada — {} entries íntegras", rep.verified);
if let Some(g) = rep.genesis_sha { println!(" genesis: {}", hex_long(g)); }
}
}
IntrospectResponse::Error(e) => eprintln!("error: {e}"),
}
}