β οΈ 1. The Spectrum of Agent Control Planes
Over the past three years, the autonomous coding landscape has evolved through several distinct architectural approaches to managing model side effects. While early CLI prototypes relied on a naive loopβgive the model read, write, and shell, execute changes directly on the developer's working directory, and dump raw test stderr back into the promptβmature tools have tackled this problem through differing control planes:
- Git-Centric Worktree CLIs (e.g., Aider, Claude Code): These tools leverage Git's native version control primitives. They isolate changes on dedicated git branches or secondary worktrees, employ user permission confirmations before running bash commands, and rely on
git diffandgit resetfor undo mechanics. This model has outstanding local developer ergonomics and zero database overhead. However, when applied to unattended, multi-turn background refactors or multi-agent swarms, shell execution still operates on the host OS with user credentials, and coordination lacks transactional row locking across concurrent tasks. - Full-Cloud Virtual Machine Agents (e.g., Devin): These platforms spin up full remote hypervisor VMs or ephemeral Docker containers in the cloud for every task. The agent enjoys unrestricted shell access because the entire environment is disposable. The trade-off is sovereign and financial: your entire proprietary codebase must be uploaded to third-party cloud infrastructure, cold starts take minutes, and running heavyweight VMs incurs ongoing SaaS and compute costs ($2.00β$5.00+ per agent-hour).
- The Invariant Headless Harness (Krusch): Krusch occupies a different design point: sovereign, local-first execution governed by a relational transaction manager. Rather than letting the agent own the checkout, code edits are staged as cryptographic relational diffs in PostgreSQL, verification runs inside local unprivileged Linux user-namespace jails (Bubblewrap), and files are applied to the physical working tree only after test suites pass and approval is granted.
The failure modes that Krusch targets are not theoretical; they are the standard hazards of unattended agent execution:
- Partial Multi-File Write Aborts: An agent refactoring an interface across five interdependent files fails on file 3 due to an HTTP timeout, rate limit, or provider error. The repository is left half-mutated, tests fail to compile, and Git status is polluted.
- Unconstrained Shell Side Effects: Permitting an autonomous agent to execute freeform shell scripts (
bash -c) risks uncontrolled package installs, dangling background daemons, credential leakage, or accidental destructive deletions (such asrm -rf). - Infinite Oscillation Loops: When verification fails, dumping raw compiler output back into the prompt without structural classification leads models to oscillate endlessly between two broken variants, exhausting API budgets without converging.
ποΈ 2. The Core Thesis: Ephemeral Compute vs. Transaction Manager
The Krusch architecture is founded on a clear separation of concerns: models are ephemeral compute; PostgreSQL is the brain and transaction manager. Models can crash, hallucinate, emit invalid syntax, or disconnect mid-turn without consequence. Primary task state, turn history, concurrency leases, and execution boundaries are owned exclusively by PostgreSQL.
krusch_phase_edges) govern every step: INIT β PLAN β IMPLEMENT β VERIFY β APPROVAL_GATE β COMMITTED. Phase revisit caps prevent runaway loops.
krusch_staged_diffs with SHA-256 validation. Changes are committed to disk only via write-ahead apply journals with drift detection.
read-only with network namespace isolation. Capability allowlists permit test runners only.
ContextManagement, ToolUse, ObservationManagement, or AgentLoop, injecting structured remediation instead of blind re-prompting.
π 3. The Pre-Commit Staging Invariant & Blob Storage
In Krusch, worker models have zero direct filesystem write privileges. When an agent invokes the stage_diff tool during the IMPLEMENT phase, the code payload is captured by the harness, validated, and staged into relational storage:
-- Primary pre-commit diff staging table
CREATE TABLE IF NOT EXISTS krusch_staged_diffs (
id SERIAL PRIMARY KEY,
task_id VARCHAR(64) NOT NULL REFERENCES krusch_tasks(id) ON DELETE CASCADE,
file_path TEXT NOT NULL,
base_sha256 VARCHAR(64),
staged_sha256 VARCHAR(64) NOT NULL,
diff_content TEXT NOT NULL,
status VARCHAR(32) DEFAULT 'PENDING'
CHECK (status IN ('PENDING', 'APPLYING', 'APPLIED', 'REJECTED', 'SUPERSEDED')),
explanation TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Content-addressed deduplication store
CREATE TABLE IF NOT EXISTS krusch_blobs (
sha256 VARCHAR(64) PRIMARY KEY,
byte_size INTEGER NOT NULL,
content TEXT NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
This staging architecture enforces three key invariants:
- Clean Working Trees: A model can explore ten alternative refactoring approaches, test them in isolated sandboxes, throw them away, and restage them. Throughout this iterative process, the developer's Git working tree remains completely untouched.
- Content-Addressed Deduplication: Identical file revisions across tasks, turns, and restaging cycles are indexed by their SHA-256 cryptographic digest in
krusch_blobs, minimizing database bloat and enabling instant preimage comparisons. - Monotonic Concurrency Leases: When multiple tasks or swarm workers operate concurrently, single-writer file concurrency is enforced via
krusch_file_leases. Files are locked using canonicalized absolute paths, monotonic lease counter increments, and strict TTL expirations to prevent race conditions or cross-agent clobbering.
π‘οΈ 4. Hard Sandbox Isolation & Cross-Platform Portability
Protecting the working tree during code generation is insufficient if running tests allows the agent to execute unconstrained shell commands on the host machine. In naive setups, running npm test or pytest executes with the developer's full user privileges, exposing local SSH keys, cloud credentials, and network sockets.
Krusch addresses this through a tiered sandboxing model:
Tier-1: Bubblewrap Unprivileged User Namespaces (Linux)
On Linux systems, Krusch invokes Bubblewrap (bwrap) to construct an unprivileged, unshare-isolated sandbox without requiring root or setuid binaries:
// Sandbox invocation in src/verify/sandbox.js
const bwrapArgs = [
'--unshare-all', // Unshare IPC, PID, UTS, and Network namespaces
'--unshare-net', // HARD NETWORK ISOLATION: Zero outbound socket access
'--ro-bind', '/', '/', // Mount host filesystem strictly READ-ONLY
'--ro-bind', projectRoot, projectRoot, // Mount working directory READ-ONLY
'--bind', stagedTreeDir, projectRoot, // Overlay shadow staged modifications in RAM
'--dev', '/dev', // Minimal pseudo-devices (/dev/null, /dev/urandom)
'--proc', '/proc', // Clean PID-isolated process tree
'--tmpfs', '/tmp', // Isolated scratch RAM disk
'--chdir', projectRoot,
'--',
...parsedCommand
];
- Read-Only Base Filesystem: The host root and project checkout are mounted
--ro-bind. Even if a test command attemptsrm -rf /, the Linux kernel rejects the write withEROFS(Read-only file system). - Network Isolation (
--unshare-net): Tests cannot dial out to third-party servers, preventing credential exfiltration and eliminating test flakiness caused by external network dependencies. - Capability Allowlisting: Verification commands are validated against an allowlist of recognized test runners (
npm test,node --test,pytest,cargo test,go test,vitest,jest). Arbitrary shell chaining, piping (curl | bash), and interactive commands are rejected before execution. - Durable Replay Tokens: Each verification records the sandbox type, environment snapshot, file manifest, command, exit code, and a deterministic SHA-256 replay token in
krusch_verification_runs.
Tier-2: Monitored Process Jails (macOS / Windows Fallback)
Bubblewrap leverages Linux user namespaces, which are not natively available on macOS or Windows. For cross-platform environments, Krusch provides an automated fallback to a Monitored Process Jail:
- Execution runs in a detached POSIX process group with an isolated temporary directory.
- Strict capability validation still intercepts and blocks dangerous commands (e.g.,
curl,wget, arbitrary bash scripts). - Process groups are monitored with hard wall-clock timeouts. On timeout or unhandled failure, the harness issues
SIGKILLacross the entire process group to ensure no orphan processes survive.
πΎ 5. Storage-Engine Apply Journal & Drift Detection
Once a task passes sandboxed verification and receives human or policy approval, its staged modifications must be written to disk. Krusch treats disk writes with the same rigor that a database storage engine treats write-ahead logging (WAL):
[ PENDING ] ββ(Verification Passed & Approved)ββ> [ APPLYING ] ββ(fsync & rename)ββ> [ APPLIED ]
β β
β (Crash / Drift Detected)
β β
ββββββββββββββ(Idempotent Rollback & Recovery)ββββββββ
The apply pipeline operates in four deterministic stages:
1. Upfront Working-Tree Drift Detection
Before modifying any file on disk, Krusch compares the real-time SHA-256 hashes of all target files against the base preimages recorded when the task was initialized. If the developer edited a file in their editor while the agent was running, Krusch detects the drift and aborts the entire batch with zero disk writes. No partial mutations occur.
2. Temporary Sibling Writes & Hardware fsync
Each modified file is written to a temporary sibling file in the same directory (e.g., src/calculator.js.krusch-tmp-1790046). The file descriptor is explicitly flushed to non-volatile physical storage media using fs.fsyncSync(fd), guaranteeing durability before the journal state advances.
3. Atomic POSIX Rename
Files are swapped into their destination paths using the atomic POSIX system call renameSync(). On modern filesystems (ext4, APFS, NTFS), an atomic rename guarantees that readers observe either the old file or the new file, never a truncated or half-written buffer.
4. Idempotent Crash Recovery
If power is lost or the process is killed mid-batch, the startup recovery routine (recoverApplyJournals()) inspects krusch_apply_journal. It identifies any journals stuck in APPLYING, restores already-renamed files to their base preimages stored in krusch_blobs, removes dangling temporary siblings, and marks the journal ROLLED_BACK. This recovery operation is completely idempotent and safe to replay repeatedly.
π 6. Authoritative Row-Locked FSM & Bounded Retries
Traditional agent loops rely on an unconstrained while(true) loop inside the orchestrator process. If the node process crashes, task state is obliterated. Furthermore, these unconstrained loops frequently enter runaway oscillation, repeatedly failing tests and re-prompting until the user's API credit limit is breached.
Krusch formalizes the agent lifecycle as an authoritative Finite State Machine (FSM) validated directly against PostgreSQL catalog tables:
-- Authoritative FSM transition catalog
CREATE TABLE IF NOT EXISTS krusch_phase_edges (
from_phase VARCHAR(32) NOT NULL,
to_phase VARCHAR(32) NOT NULL,
PRIMARY KEY (from_phase, to_phase)
);
-- Catalog of permitted transitions
INSERT INTO krusch_phase_edges (from_phase, to_phase) VALUES
('INIT', 'PLAN'),
('INIT', 'ABORTED'),
('PLAN', 'IMPLEMENT'),
('PLAN', 'COMMITTED'), -- Read-only tasks complete in PLAN
('PLAN', 'ABORTED'),
('IMPLEMENT', 'VERIFY'),
('IMPLEMENT', 'ABORTED'),
('VERIFY', 'APPROVAL_GATE'),
('VERIFY', 'IMPLEMENT'), -- Bounded cyclic retry edge
('VERIFY', 'ABORTED'),
('APPROVAL_GATE', 'COMMITTED'),
('APPROVAL_GATE', 'IMPLEMENT'),
('APPROVAL_GATE', 'ABORTED')
ON CONFLICT DO NOTHING;
Transitions are enforced within PostgreSQL using SELECT ... FOR UPDATE row locks. An agent cannot hallucinate a state transition; the database rejects any edge not explicitly cataloged.
Capping Runaway Oscillation (Phase Revisit Budgets)
The cyclic edge VERIFY β IMPLEMENT enables restaging when tests fail. However, unlike unconstrained agent frameworks, this edge is strictly governed by a Phase Revisit Budget (configured via max_phase_revisits, default: 3):
- Attempts 1 & 2: Verification fails. The harness transitions
VERIFY β IMPLEMENTand attaches structured failure diagnostics. - Attempt 3 (Budget Exhausted): If the test suite fails three times, the harness refuses to oscillate further. It records a budget exhaustion event in
krusch_eventsand terminates the task intoABORTED(or triggers model escalation to frontier reasoning like Claude 3.7 Sonnet or DeepSeek-R1).
π§ 7. Heuristic Failure Classification (Modular RSI Pattern)
When tests fail in conventional coding agents, the orchestrator dumps raw stderr into the context window: "Command failed with code 1. Please fix the error." This forces the LLM to waste reasoning tokens deducing whether the error was caused by a syntax typo, a missing file import, or a logic flaw.
Krusch replaces blind re-prompting with Heuristic Failure Classification via KruschFailureClassifier (implementing the Modular RSI pattern):
// Failure classifier in src/workflow/modular-rsi.js
export class KruschFailureClassifier {
static classify(failureOutput, exitCode) {
// 1. Missing module or import failure
if (/cannot find module|module_not_found|no module named/i.test(failureOutput)) {
return {
module: 'ContextManagement',
remediation: 'Verify module paths, export declarations, and project dependencies.'
};
}
// 2. Syntax, parsing, or tool invocation failure
if (/syntaxerror|unexpected token|parse error/i.test(failureOutput)) {
return {
module: 'ToolUse',
remediation: 'Inspect staged diff formatting, brackets, and language grammar.'
};
}
// 3. Logic or assertion failure
if (/assertionerror|expect\(.*received|failed [0-9]+ test/i.test(failureOutput)) {
return {
module: 'ObservationManagement',
remediation: 'Algorithm logic violation. Review test assertions against implementation.'
};
}
// 4. Budget or execution timeout
return {
module: 'AgentLoop',
remediation: 'Execution did not satisfy verification criteria within allotted turn budget.'
};
}
}
When transitioning back from VERIFY to IMPLEMENT, the harness injects this structured diagnosis directly into the model's next turn:
[krusch:classifier] Verification Failure attributed to [ContextManagement]:
Target module 'src/formatter.js' is missing named export 'formatResult'.
Remediation: Stage the missing export before requesting verification re-run.
βοΈ 8. Operational Costs & Trade-Offs of a Relational State Plane
Elevating PostgreSQL to the authoritative state plane introduces real operational trade-offs that any engineering team must evaluate before adopting Krusch:
- Database Operational Dependency: Krusch requires a running PostgreSQL instance (or the embedded PGlite WASM engine for local zero-dependency testing). You must manage migrations (
npm run migrate), connection pools, and database backups. If PostgreSQL is unavailable, the harness cannot execute. - Dual Source of Truth Tension: Git is the authoritative source of truth for repository history; PostgreSQL is the authoritative state plane for active tasks and staged diffs. Bridging these two substrates requires clean synchronization: upfront drift detection before apply, and clean patch export (
krusch diff --export) so that human developers can commit via Git. - When is Krusch Overkill? For a quick one-line typo fix, a human in an editor or a simple CLI assistant using a git worktree is faster and incurs zero database overhead. Krusch is engineered for:
- Autonomous, multi-turn background refactoring tasks.
- Multi-agent swarms editing shared repositories concurrently (requiring file concurrency leases).
- Unattended CI/CD repair pipelines where unverified disk mutations cannot be tolerated.
- Air-gapped and sovereign environments where code cannot be dispatched to third-party cloud VM providers.
π 9. Thin Frozen Stdio MCP Server (7 Tools)
Krusch is intentionally architected as a headless execution engine, completely decoupled from GUI presentation. It exposes its entire functionality to external IDEs (such as KD Code, Claude Desktop, Cursor, or Antigravity) via a thin Model Context Protocol (MCP) stdio bridge running over 7 frozen tools:
| Tool Name | Phase Scope | Description & Invariants |
|---|---|---|
krusch_run |
Any | Asynchronously initializes and launches an engineering task in PostgreSQL. Returns immediately with taskId for polling. |
krusch_task_status |
Any | Polls current FSM phase, verification run results, active diffs, token ledger, and invariant blockers. |
krusch_explain |
Any | Explains next transition feasibility with SQL invariant diagnostics (e.g., why COMMITTED is blocked until tests pass). |
krusch_diff |
Any | Retrieves a clean, PR-ready Myers unified diff of all staged modifications for visual review. |
krusch_reject |
APPROVAL_GATE |
Rejects a staged diff before application, recording operator feedback in krusch_events and reverting to IMPLEMENT. |
krusch_apply_diff |
APPROVAL_GATE |
Authorizes atomic commit of verified staged diffs to physical disk via the storage-engine apply journal. |
krusch_abort |
Non-terminal | Immediately aborts an active or oscillating task, recording operator reason and releasing all file concurrency leases. |
π 10. Comparative Architecture Matrix
How does the Krusch invariant harness compare against other prominent agent control planes across safety, statefulness, and operational mechanics?
| Architecture Dimension | Git-Centric CLIs (Aider, Claude Code) | Cloud VM Agents (Devin) | Krusch Coding Harness (v0.1.0) |
|---|---|---|---|
| Primary State Plane | In-memory process state, Git worktrees, and local JSON/markdown caches. | Proprietary cloud backend managing remote VM state and execution logs. | PostgreSQL 16 ACID Tables with row-locked catalog transitions and full audit trails. |
| Working-Tree Protection | Git branches / secondary worktrees. File edits are applied to worktree disk. | Full disposable remote cloud VM. Local checkout is completely isolated. | Pre-Commit DB Staging. Physical disk is untouched until tests pass and approval is granted. |
| Test Execution Sandbox | Host shell execution with interactive permission confirmation prompts. | Hardware-level hypervisor VM in cloud provider. Full shell access within VM. | Bubblewrap (bwrap) Jail: Read-only base tree, network disabled, PID-isolated (Linux). |
| Commit Atomicity | Git commit / reset operations at the VCS layer. | Git branch push from VM container. | Two-Phase Apply Journal: Upfront drift detection, fsync, atomic rename, and rollback. |
| Concurrency / Multi-Agent | Manual branch management. Concurrent agents risk git merge conflicts. | Parallel cloud VMs per session, merged via standard pull requests. | Single-Writer File Leases: Canonical paths, monotonic lease counters, TTL expirations. |
| Sovereignty & Data Locality | High. Runs locally on developer workstation. | Low. Codebase, environment, and credentials run in vendor cloud. | 100% Sovereign. Runs on-premise or local hardware; zero cloud dependency required. |
| Operational Overhead | Zero database dependencies. Minimal setup. | Zero local infra; ongoing cloud SaaS subscription costs ($2β$5+/hr). | PostgreSQL instance required (or sub-10s embedded PGlite for zero-setup eval). |
π 11. Evaluating Krusch (v0.1.0) in Under 10 Seconds
The entire Krusch coding harness is open-source under the MIT license, fully typed with TypeScript declarations, and designed to run out of the box with zero external cloud API dependencies:
In-Process Ephemeral Evaluation (PGlite)
You can evaluate the complete invariant lifecycleβfrom task initialization through diff staging, sandboxed verification, and atomic applyβusing in-process PostgreSQL (PGlite) and the deterministic mock adapter in under 10 seconds:
# 1. Clone the repository
git clone https://github.com/kruschdev/krusch.git
cd krusch
npm install
# 2. Run an end-to-end verified engineering task in-process
./bin/krusch.js run "Verify arithmetic module fix" --mock --ephemeral --auto-approve
# Output:
# [krusch] Initialized task task_1790046 in PGlite (Phase: INIT)
# [krusch:fsm] Planning completed. Transitioned PLAN -> IMPLEMENT
# [krusch] Staged diff for src/math.js (SHA-256: 8f3b2a...)
# [krusch:verify] Sandboxed verification passed with exit code 0
# [krusch:fsm] Auto-applied 1 staged diff(s) via Apply Journal. Task COMMITTED.
Running with Full PostgreSQL & The Test Suite
For production deployments on homelab hardware or cloud servers, bootstrap the schema with the versioned migration runner and run the full 79-test integration suite:
# Start PostgreSQL 16
docker compose up -d
# Bootstrap schema and probe connectivity
./bin/krusch.js init
# Run the complete test suite (Unit, Storage Engine Properties, Sandbox, FSM)
npm test
# Output:
# β Storage Engine Property: Pre-commit drift check mid-batch aborts without touching disk
# β Storage Engine Property: Partial batch apply crash recovery atomically rolls back
# β KruschSandbox: capability validator permits test runners and rejects dangerous shells
# β Integration: Phase revisit budget caps VERIFY -> IMPLEMENT oscillation
# βΉ pass 79 | fail 0 | duration_ms 13784