# akicita specification
Bounded-autonomy marshal for self-acting systems.
## Concepts
- **Proposal** — an act the system wants to take on a *surface* (file,
policy, config), carrying an intent string, a blast radius (lines,
bytes), and a dedupe fingerprint.
- **Level** — the autonomy ladder rung: `off`, `suggest`, `safe-apply`,
`full`.
- **Decision** — `permit`, `hold{reason}`, or `deny{reason}`.
- **Journal** — append-only NDJSON; every decision lands on it.
## Decision order
`check(proposal)` evaluates in this order — first match wins:
1. `level == off` → **deny** (`autonomy level is off`)
2. fingerprint already decided → **deny** (`already decided — not refiling`)
3. `lines > max_lines || bytes > max_bytes` → **hold** (oversize)
4. surface protected (basename or prefix match) → **hold** (never
auto-applied)
5. `level == suggest` → **hold** (recorded for review)
6. `safe-apply | full`: `min_interval` since last permit → **deny**
(rate-limited); else → **permit**
## Invariants
- Protected surfaces never auto-apply at any level, including `full`.
- Dedupe is fingerprint-based; a decided proposal is never refiled.
- Every decision — permit, hold, deny — is journaled.
- When a `level_path` is configured, the level is re-read on every
`check` so an operator can lower autonomy live by writing the file.
## Persistence
The level file contains one of `off`, `suggest`, `safe-apply`, `full`
(case-insensitive, trimmed). Written mode `0600` on Unix.
## Non-goals
- akicita does not apply patches — it decides whether the caller may.
- It is not a policy engine; it is a blast-radius and autonomy governor
in front of one.