akicita 0.1.1

Bounded autonomy for self-acting systems: an autonomy ladder (off/suggest/safe-apply/full), protected surfaces that never auto-apply, blast-radius caps, rate limits, and dedupe — named for the Lakota camp marshals who kept warriors inside the bounds
Documentation

akicita

Bounded autonomy for self-acting systems. Named for the akicita, the Lakota camp marshals who policed the warriors within the tribe during the hunt — internal enforcement with bounded authority.

Extracted from Bad Apple's Curious self-improvement loop, generalized for any system that proposes and applies changes to itself: agents, daemons, robots, autopilots.

The ladder

Level Behavior
off Nothing runs. Proposals denied.
suggest Proposals recorded for human review. Nothing applied.
safe-apply In-bounds proposals on unprotected surfaces apply automatically.
full Same, without the safe-apply surface restriction — protected surfaces are still never auto-applied.

Protected surfaces are hard boundaries, not level settings: a proposal touching one is proposed and logged for human review at every level. Some doors only a human opens.

What the marshal enforces

  • Autonomy ladder — persisted to disk, re-read live so a human can lower autonomy mid-run.
  • Protected surfaces — basenames and path prefixes that never auto-apply.
  • Blast-radius caps — max lines/bytes per proposal; oversize holds (it isn't denied, it's escalated).
  • Rate limits — minimum interval between automatic applications.
  • Dedupe — a proposal already decided isn't refiled.
  • Journal — every decision lands as NDJSON. Refusals are as much the record as permits.

Usage

use akicita::{Akicita, Config, Decision, Level, Proposal};
use std::path::PathBuf;

let mut config = Config::default();
config.protected_basenames.insert("PolicyEngine.rs".into());
config.max_lines = 20;
config.max_bytes = 1_000;
config.journal_path = Some(PathBuf::from("marshal_journal.ndjson"));

let marshal = Akicita::new(
    Level::SafeApply,
    config,
    Some(PathBuf::from("autopilot_level")),
);

let patch = Proposal::patch(
    "src/feature.rs",
    "// old code",
    "// new code",
    "replace stub with implementation",
);
match marshal.check(&patch) {
    Decision::Permit => apply(&patch),
    Decision::Hold { reason } => record_for_human(&reason),
    Decision::Deny { reason } => drop_and_log(&reason),
}

See examples/marshal.rs for the full walk.

Origin

Bad Apple's self-improvement loop applies bounded patches to its own source — capped at 20 lines / 1000 bytes, one per run, with protected control files it can never touch automatically and a dedupe so rejected proposals aren't refiled. The marshal pattern survived nightly operation; this crate is the extracted organ.

License

MIT