Skip to main content

Module control

Module control 

Source
Expand description

Cross-process control inbox (design.md “Cross-process control”).

The single-writer rule (§4.3) means only the engine appends events.jsonl. Other processes (CLI kranz msg/pause/resume, the server) talk to a running engine by dropping ControlCommand JSON files into paths.control_dir(). File names are <zero-padded-nanos>-<8-hex>.json so lexicographic order == chronological order; writes go through a tmp file + rename so a draining engine never observes a partial file. The nanosecond prefix keeps back-to-back enqueues (e.g. pause immediately followed by resume) in issue order — a millisecond prefix left same-ms enqueues to be ordered by the random suffix.

The engine drains the inbox between worker runs, and a ControlWatcher polls peek_interrupt so an interrupt message can abort the active run.

§Authenticity (audit 2026-09-01 C1)

The inbox carries operator consent: approve-grant, approve-revision, answer-question, and config-change all land as events that are indistinguishable from a human decision. It used to be a plain directory any process with write access to the repo could drop a file into, which made forging consent a one-file operation for a worker, a validator, or any gate command.

Every file therefore carries a sig: a hex HMAC-SHA256 over the mission id, the file name, and the canonical JSON of the command, keyed by the repository authority key (crate::paths::authority_key_path). drain and peek_interrupt verify it with a constant-time compare and quarantine anything unsigned or wrongly signed to .bad, never applying it. acknowledge records the acknowledged file’s name as the mission’s control mark outside the repository, and any later file whose name is at or below the mark is quarantined as a replay even when its signature verifies.

Structs§

ControlWatcher
Spawn-able helper that polls peek_interrupt and fires a tokio::sync::Notify once an interrupt message is queued. The orchestrator selects on the notify alongside the active worker run.

Functions§

acknowledge
Remove a command returned by drain after its event has been durably applied. The delete stays relative to the same no-follow mission/control chain as enqueue and drain, so a swapped parent symlink cannot redirect acknowledgement outside the mission.
drain
Drain the inbox: parse every queued .json file, oldest first, NON-destructively.
enqueue
Enqueue one command into the mission’s control inbox.
peek_interrupt
True if any queued file AUTHENTICATES to Msg { interrupt: true }.
resolve_active_mission
Resolve the target mission for a mid-mission control command (config change, pause, resume): an ACTIVE (non-terminal) mission, chosen unambiguously. Shared by the Slack bridge (/kranz config|pause|resume) and the CLI (kranz config role), so both surfaces refuse the same hazardous targets: