Comparative Architecture — Hermes · OpenCode · OpenHands · mini-SWE → KHAELOR
Phase 0 synthesis. Sources:
docs/research/HERMES_ANALYSIS.md,OPENCODE_ANALYSIS.md,OPENHANDS_ANALYSIS.md,MINI_SWE_ANALYSIS.md— all based on traced code paths, not READMEs. Every claim below cites the evidence recorded in those documents. Decisions are elaborated as ADRs inKHAELOR_ARCHITECTURE_DECISIONS.md.
1. Decision Matrix
| Capability | Hermes | OpenCode | OpenHands | mini-SWE | KHAELOR Decision |
|---|---|---|---|---|---|
| Agent loop | 7,740-line while loop; typed error hints; verification-on-stop |
State-derived runLoop over persisted messages; stream reducer split out |
Agent.step() + run() state machine; FinishTool; buried under integrations |
190-line loop; exceptions-carry-messages; role=="exit" |
Tiny state-derived loop (mini shape, OpenCode crash-safety); services around it (ADR-2) |
| TUI | Python REPL + React/Ink TUI + JSON-RPC bridge; settled-block streaming | SolidJS + own @opentui engine; 16 ms delta coalescing; 100-msg cap |
None (web app; Rich debug visualizer) | Rich prints; spinner | Phase 1 prototype spike; techniques (settled blocks, coalescing, bounded live region) adopted regardless (ADR-14) |
| Tools | ~93 tools + tool_search bridge |
2–4 params, prose-rich descriptions; 9-replacer edit; spill-to-file | Typed Action/Observation; str_replace with line-number errors | One bash tool |
Exactly 7 primitives; ≤5 params; replacer cascade + OpenHands failure UX (ADR-8) |
| Sessions | SQLite, 10.9K-line armor, mid-turn flush | SQLite + drizzle; events → atomic projections | File-per-event JSON; event tree; resume contract | JSON dump per step; write-only | Event-sourced JSONL, one file/session; resume = replay; linear log, parent_id-ready (ADR-3) |
| Context | ContextEngine ABC; 3-tier cached system prompt; token-triggered compressor |
Token-budget overflow; compaction as persisted loop task; cheap prune | Condenser; compaction-as-event; safe cut indices; event-count trigger (weak) | None; template head/tail truncation | Hermes interface + OpenHands compaction-as-event + real-token triggers + structured YAML checkpoint (ADR-6, ADR-7) |
| Memory | MEMORY.md/USER.md + provider plugins + background review agent | None (frecency for UI ranking only) | Microagents/skills systems (out of core) | None | Not V1; event-log seams left open (ADR-16) |
| Permissions | Layered gate; unbypassable hardline floor; LLM guardian | Last-match-wins rules; tree-sitter + arity "always allow git push *"; in-memory always (flaw) |
Risk/policy split; pending = unmatched action events | Mode + regex whitelist | Capability rules, last-match-wins; persisted always; conservative bash parsing V1 (ADR-9) |
| Workspace | Env backends for terminal only; file tools hit FS directly | None explicit; directory-scoped instances | BaseWorkspace; sandbox = relocate the agent |
3-method Environment protocol |
4-method Workspace; LocalWorkspace only; tools never touch Node globals (ADR-13) |
| Events | ~40-event gateway protocol; 33 ms coalescing | Durable typed events + atomic projectors; GlobalBus |
Event log as source of truth; visualize welded on (wart) |
None (message list is the log) | In-process typed bus; durable → JSONL, ephemeral deltas → TUI only (ADR-4) |
| Subagents | delegate_task, in-process threads, no parent context |
task → child session; deny-rule inheritance; depth 1 |
Delegate tooling in SDK | None — and >74% SWE-bench anyway | Not V1 (ADR-16) |
| Processes | terminal + process registry: best-in-class |
Gap: PTY exists, no model-facing tool | Soft-timeout terminal + is_input convention |
Fresh subshell, 30 s kill | Model-facing process.start/list/read/write/stop — the differentiator (ADR-8) |
| Model abstraction | OpenAI-dict lingua franca + adapter zoo + credential pools | ai SDK + per-provider transforms |
2,300-line litellm wrapper; typed error taxonomy | 164-line litellm wrapper | One ModelClient over Anthropic SDK; typed errors; no adapter framework (ADR-10) |
| Persistence | SQLite WAL + fallbacks + self-repair | SQLite WAL; JSON-blob payloads; ULID ids; incremental counters | FileStore, file-per-event, lock file, autosave | finally-block JSON dump |
Append-only JSONL, atomic line appends, flush at every loop boundary (ADR-3) |
| Git awareness | Verify pipeline detects changed files | Shadow-git snapshots; revert/unrevert; per-step patch parts | sdk/git diff/changes helpers feed UI |
None | Baseline capture + attribution; shadow-git deferred post-V1 (ADR-15) |
| Repository search | grep tools; output budgets | Bundled ripgrep service; 100-result cap; frecency file-finding | ripgrep-first with logged fallback | Model runs grep itself |
ripgrep-first, bounded structured results; trust the model to navigate; no index in V1 (ADR-8, §11) |
2. Capability Analyses
2.1 Agent loop
Problem. Turn a user request into a sequence of model calls and tool executions that terminates correctly, survives crashes, and stays comprehensible.
How each reference solves it.
- Hermes:
run_conversation()inagent/conversation_loop.py— one ~6,000-line loop body. Iteration budget with a "grace call", typedClassifiedErrorrecovery hints, dozens of inline# ──recovery regions, and verification-on-stop (agent/verification_stop.py): a model claiming completion after editing code gets a synthetic evidence-bearing nudge to run verify commands (max 2 attempts, withheld answer preserved). - OpenCode:
SessionPrompt.runLoopre-reads persisted messages each iteration and derives what to do from them; compaction and subtasks are persisted parts popped as tasks; exit conditions derive from message state, so a crashed process resumes mid-conversation. The stream reducer (SessionProcessor, a pure event switch) is separated from the loop. Doom-loop detection: 3 byte-identical consecutive tool calls → ask the user. - OpenHands:
Agent.step()is one LLM round dispatched throughclassify_response(); the outerLocalConversation.run()is a status state machine (IDLE/RUNNING/PAUSED/WAITING_FOR_CONFIRMATION/FINISHED/STUCK). Completion is an explicitFinishToolcall. The minimal loop is buried under MCP reconciliation, critics, hooks, and vision fallbacks (~28-parameter__init__). - mini-SWE:
DefaultAgent(190 lines):run()→step()→execute_actions(self.query()). All non-linear control flow is exceptions carrying the messages to append; termination is data-driven (role == "exit"). Scores >74% on SWE-bench Verified.
Trade-offs. mini proves the kernel can be tiny but omits everything a product needs (streaming, resume, compaction). Hermes proves rich recovery works but shows what happens when it lives inside the loop. OpenCode's state-derivation buys crash-safety and steerability at the cost of per-iteration state reads. OpenHands' explicit state machine is legible but its kernel accreted integrations — the exact failure Absolute Rule #3 guards against.
KHAELOR. mini's four-verb shape + OpenCode's state-derivation + Hermes' verification-on-stop, with error handling in a policy service outside the loop (Hermes proves the taxonomy; KHAELOR fixes the placement). See ADR-2, ADR-12.
2.2 TUI
Problem. Render streaming model output, tool activity, diffs, and input editing in a terminal, flicker-free, at full token-stream speed.
How each reference solves it.
- Hermes: paid the Python-first tax — an 18.7K-line prompt_toolkit REPL plus a React/vendored-Ink TUI plus a Python↔Node JSON-RPC bridge. Its
ui-tui/rendering discipline is excellent: settled-block incremental markdown (StreamScanStatefreezes completed blocks, re-parses only the live tail), hard live-render caps (16K chars / 240 lines — unbounded trails OOM-killed Node, issue #34095), virtualized scrollback, width-responsive status segments with pre-reserved spinner width, 33 ms delta coalescing. - OpenCode: built its own engine — SolidJS fine-grained reactivity over
@opentui's retained-mode renderable tree (Yoga flexbox → optimized cell buffer, 60 fps target). Delta-only streaming:message.part.delta→produce()append → single<markdown>node repaint; SSE events coalesced 16 ms intobatch(). No virtualization — a hard 100-message cap with part GC (users silently lose scrollback). Composer is extmark-based structured parts; native<diff>renderable; tree-sitter WASM highlighting. - OpenHands: no terminal product. A React/Electron web app; events carry a Rich
visualizeproperty (presentation welded into domain objects — an anti-pattern). - mini-SWE: Rich prints and a spinner; honest about being a research harness. Its interaction grammar (Ctrl-C → steering comment, "agent wants to finish" → prompt for next task) is worth preserving.
Trade-offs. Framework choice is the highest-variance decision: Ink is Node-native but coarse-grained; opentui is the best-in-class renderer but Bun-adjacent; custom ANSI is fully controlled but expensive. The techniques, however, converge across Hermes and OpenCode independently (settled blocks, coalescing, bounded live regions) — they are framework-independent facts about terminals.
KHAELOR. The one decision requiring a Phase 1 prototype spike, with measured criteria; techniques adopted regardless of framework. No 100-message UX cliff. See ADR-14.
2.3 Tools
Problem. Give the model action primitives that are powerful, observable, safe, and cheap in context.
How each reference solves it.
- Hermes: ~93 registered tools (browser, video, TTS, kanban…), requiring a
tool_searchdeferred-tool bridge to cope with its own count. But its tool-output economics are exemplary: per-result (100K chars) + per-turn (200K) budgets, head/tail truncation with explicit markers, spill-to-file with the path returned, ANSI stripping, secret redaction. - OpenCode: minimal schemas —
edithas 4 params,bash3; long guidance lives in description text files. The edit tool runs a nine-strategy replacer cascade (exact → line-trimmed → block-anchor Levenshtein → whitespace-normalized → indentation-flexible → escape-normalized → trimmed-boundary → context-aware → multi-occurrence) with uniqueness and disproportionate-match guards, CRLF/BOM preservation, and model-facing repair-prose errors.Truncate.outputspills oversized output to files the model can Read/Grep. - OpenHands: typed Pydantic Action/Observation pairs per tool;
ToolAnnotationsbehavior hints (readOnlyHintshort-circuits risk checks). The str_replace editor's failure UX is the reference standard: multiple-occurrence errors cite line numbers, "Maybe you meant {cwd/path}?", post-edit snippet so the model self-verifies without a re-read. - mini-SWE: one tool (
BASH_TOOL, one required param) scores >74% — proof that big agents' tool counts are largely accidental. But bash-only editing (sed/heredocs) is unobservable and unsafe outside disposable containers.
Trade-offs. More tools = more schema tokens per call and more permission surface; fewer tools = less observability (no diffs, no capability classification). The evidence triangulates on ~7 powerful primitives with tiny schemas.
KHAELOR. Exactly read/write/edit/grep/glob/bash/process. OpenCode's cascade + OpenHands' failure messages + Hermes' output budgeting. See ADR-8.
2.4 Sessions
Problem. Sessions must persist across crashes and restarts, resume with full fidelity, and stay separate from agent intelligence.
How each reference solves it.
- Hermes: SQLite with hard-won operational armor (
hermes_state.py, 10,888 lines): WAL with broken-build detection and DELETE-mode fallback, macOS fsync barriers, schema self-repair, incremental mid-turn flushes so a crash loses almost nothing. - OpenCode: SQLite + drizzle; persistence is a projection of durable events —
updateMessage/updatePartnever touch the DB, they publish events; projectors run in the same transaction. ULID-style monotonic IDs makeORDER BY id= insertion order. - OpenHands: one JSON file per event (
events/event-{idx}-{id}.json), append-only, lock-file cross-process safety, lazy load, O(1) length. Events carryparent_id— the conversation is a tree (branch/rewind for free), paid for with sentinel/legacy-fallback debt (issues #4057, #3053).AgentBase.verify()gives a precise resume contract: same agent class, tools add-only. - mini-SWE: full-state JSON dump in a
finallyblock every step — crash-safe recording, but write-only: no resume path exists.
Trade-offs. SQLite gives transactions and queries but adds a native dependency and (Hermes shows) an armor tax. File-per-event is dependency-free but inode-heavy. Trees enable rewind but cost invariant complexity.
KHAELOR. Append-only JSONL, one file per session — no DB dependency, no inode storm, atomic line appends; resume = replay; linear V1 log with schema room for parent_id. mini's finally-discipline applied at every loop boundary. See ADR-3.
2.5 Context
Problem. Long sessions exceed the context window; the model must receive the right information, and compaction must not corrupt API invariants or destroy evidence.
How each reference solves it.
- Hermes: the best-factored component in its codebase —
ContextEngineABC separatingselect_context/compress/on_turn_complete/prune_tool_results_only, fed by real API usage tokens (update_from_response). Default compressor: prune tool results (cheap, no LLM) → protect head → protect recent tail by token budget → summarize the middle on an auxiliary model → iteratively update the summary, with anti-thrash guards and per-turn attempt caps. - OpenCode:
isOverflow()compares real usage tokens againstusable()(input limit minus a reserved 20K buffer); when a step overflows, acompactiontask part is persisted and the loop processes it next iteration via a hidden compaction agent. Separate cheaperprune()blanks old tool outputs (protect newest 40K tokens) markedtime.compacted. - OpenHands: the cleanest structural insight — a
Condensationis an event in the log; theViewprojection re-applies it deterministically on every rebuild, cutting only atmanipulation_indiceswhere tool_use/tool_result pairing survives; condensation doubles as the recovery path for context-window errors. Weakness: the default trigger is event count (240), not tokens. - mini-SWE: none —
ContextWindowExceededErroraborts the run; the only management is template-level head/tail truncation of tool output (which is, notably, the cheap first 80%).
Trade-offs. Compaction-in-memory (Hermes mutates the stored list, its one sanctioned cache-break) vs compaction-as-event (OpenHands: replay-deterministic, inspectable, un-condensable). Event-count triggers are simple but blind; token triggers require honest accounting.
KHAELOR. Hermes' interface verbs + OpenHands' compaction-as-event mechanics + token triggers from real usage + KHAELOR's structured YAML checkpoint as the summary payload. Prune first, summarize second. See ADR-6, ADR-7.
2.6 Memory
Problem. Knowledge that should survive across sessions.
How each reference solves it. Hermes is the only serious implementation: MEMORY.md/USER.md frozen-snapshot injection (cache-conscious), a pluggable provider ABC (one external provider max), and a background review agent (forked, tool-whitelisted, cache-warm, cancelled by any new live turn) — ~10K+ lines including skills machinery. OpenCode: none (frecency ranks UI autocomplete only). OpenHands: microagents/skills exist as extension systems interleaved with the core. mini-SWE: none — and still scores >74%, evidence this layer is unnecessary for coding performance today.
Trade-offs. Memory pays off for a personal agent across months; it costs cache-stability discipline (Hermes freezes snapshots, accepting that mid-session writes are invisible until next session) and a large safety/curation apparatus.
KHAELOR. Not V1 (CLAUDE.md §23). The event log and kernel service boundaries leave the seam open; adopt Hermes' lessons (aux model, frozen snapshot, cancellable background work) when the time comes. See ADR-16.
2.7 Permissions
Problem. Let the agent act autonomously while keeping destructive or unusual actions visible and consented to — without nagging.
How each reference solves it.
- Hermes: a nine-layer command gate (
check_all_command_guards): an unbypassable hardline floor matched against de-obfuscated command variants (even in yolo mode), deny globs, an external analyzer binary, ~47 regex patterns, an LLM guardian, then the human — with "silence is not consent" timeout semantics. The permanent allowlist refuses commands containing shell operators. - OpenCode: the elegance benchmark — rules are
{permission, pattern, action}triples, evaluation is a 4-linefindLastwith wildcard matching; capability-ish keys (writefolds intoedit); deny rules also derive tool visibility (plan mode = permission policy, not a different agent). Bash commands are tree-sitter-parsed and an arity dictionary generates precise "always allowgit push *" suggestions; filesystem verbs triggerexternal_directorychecks. Flaw: v1alwaysapprovals are in-memory per session — users re-approve after restarts. Rejection-with-feedback becomes model steering (CorrectedError). - OpenHands: clean risk/policy separation — analyzer produces
SecurityRisk(UNKNOWN incomparable; analysis errors default HIGH), policy decides confirm-or-not; pending approval = unmatched ActionEvents persisted in the log, so approvals survive restarts. Default analyzer is the model grading its own homework (schema-injectedsecurity_riskself-assessment). - mini-SWE: mode (
human/confirm/yolo) + regex whitelist, ~10 lines — right-sized evaluator, wrong model for a product (no persistence, no scoping).
Trade-offs. Regex armories are brittle primary defenses (Hermes); deterministic capability rules are predictable but need good generalization UX (OpenCode's arity) to avoid prompt fatigue; LLM self-assessment is cheap but unsound as the gate.
KHAELOR. Capability-based rules, last-match-wins evaluator, persisted always grants (fixing OpenCode's flaw), conservative shell-word parsing for V1 suggestions, elegant inline panel. See ADR-9.
2.8 Workspace
Problem. One seam between the agent and "the world" so remote/sandboxed execution stays possible without proxying every syscall through premature abstraction.
How each reference solves it. Hermes: a clean Environment backend layer for terminal execution only (local/Docker/SSH/Modal…) — but file tools touch the local FS directly; the world is not one seam. OpenCode: no explicit workspace object; instances are directory-scoped server-side. OpenHands: BaseWorkspace (working_dir + execute/upload/download) — but tools also bypass it, opening files directly; sandboxing works by relocating the whole agent into the container (agent-server inside Docker) rather than proxying ops. mini-SWE: a 3-method Environment protocol; local↔Docker↔Singularity swaps cost ~100–150 lines each with zero kernel changes.
Trade-offs. Per-op proxying is clean but slow and invasive; relocate-the-agent is fast but demands a server stack. The OpenHands evidence says: keep the interface thin so the future remote strategy can be "run KHAELOR's core remotely," not "proxy every syscall."
KHAELOR. The 4-method Workspace from CLAUDE.md §9; LocalWorkspace only; tools depend on Workspace, never on Node globals directly. See ADR-13.
2.9 Events
Problem. One truthful stream that the UI, persistence, and resume/replay all consume — so streaming, history, and state never diverge.
How each reference solves it. Hermes: a ~40-event typed gateway protocol (message/thinking/tool/subagent/approval events) over JSON-RPC with 33 ms delta coalescing — but it exists to bridge two languages. OpenCode: the spine — EventV2 typed pub/sub where definitions can be durable ({durable: {aggregate, version}}); publishing a durable event transactionally appends it to the log and runs projectors; UI, DB, and remote clients consume the same stream. OpenHands: the event log is the single source of truth; everything the LLM sees and the UI shows is a projection — but presentation (visualize → Rich Text with emoji) is welded onto domain events. mini-SWE: none; the message list is the log — viable only with one linear consumer and no streaming.
Trade-offs. Durable/ephemeral distinction matters: persisting every text delta would bloat the log; dropping deltas entirely breaks streaming UX. Both OpenCode (16 ms) and Hermes (33 ms) independently converged on coalescing deltas into batched renders.
KHAELOR. In-process typed bus with the CLAUDE.md §7 vocabulary; durable events → JSONL log; ephemeral deltas → TUI only, coalesced ~16 ms; rendering strictly outside event types. See ADR-4, ADR-5.
2.10 Subagents
Problem. Delegate scoped work with isolation, without recursive explosions.
How each reference solves it. Hermes: one delegate_task tool, in-process daemon-thread children inheriting parent toolsets (never model choice), zero parent context (bare goal+context string), depth 1 by default, push-not-poll result delivery. OpenCode: task spawns a child session (fresh context by design); only parent deny rules propagate; task/todowrite force-denied for children; subagent_depth default 1. OpenHands: delegate tooling exists in the SDK amid six extension systems. mini-SWE: none — plus a strong model plans in-context to >74%; strong evidence orchestration layers are accidental complexity at current model capability.
Trade-offs. Fresh-context children are cheap and safe but poor for "continue this refactor" delegation (Hermes' own weakness). Any subagent system multiplies permission, budget, and UI surface.
KHAELOR. Not V1. Events already carry a session id and the tool registry is data-driven, so child sessions bolt on later without kernel rewrites. See ADR-16.
2.11 Processes
Problem. Dev servers, watchers, and REPLs must run while the agent keeps working — blocking bash makes them impossible.
How each reference solves it. Hermes: the best implementation surveyed — terminal (foreground, 180 s default / 600 s hard cap that redirects long commands to background) + process (list/poll/log/wait/kill/write/submit/close), a singleton registry with 200K-char rolling buffers, 64-process LRU cap, crash checkpoints with PID-reuse guards, and completion-notification events with rate limiting. OpenCode: the gap — PTY and background-job infra exist for clients, but the model cannot start/inspect/stop long-running processes; dev-server workflows degrade to blocking bash. OpenHands: one persistent terminal with a soft-timeout convention (exit_code = -1 "still running", is_input keystrokes) the model must learn from prose. mini-SWE: fresh subshell per command, 30 s process-group SIGKILL; long-running processes are impossible.
Trade-offs. A single soft-timeout terminal is fewer tools but an implicit contract; an explicit process manager is more schema but honest and observable.
KHAELOR. Strict bash vs process split; model-facing process.start/list/read/write/stop — Hermes validates the design almost line for line, and neither TS reference gets it right. This is a genuine differentiator. See ADR-8.
2.12 Model abstraction
Problem. Talk to the model reliably: streaming, retries, typed errors, honest usage accounting, cancellation.
How each reference solves it. Hermes: OpenAI-dict lingua franca + adapters for every provider + credential pools + failover chains — provider sprawl is its single largest complexity driver, leaking sanitizers throughout the loop. OpenCode: Vercel ai SDK + per-provider transforms + model-family prompt files — generality tax spread through the model layer. OpenHands: a 2,300-line litellm wrapper (four near-duplicate call paths) — but with the key idea intact: provider chaos mapped to a typed exception taxonomy (LLMContextWindowExceedError, …) that the loop branches on, and cost/cache tokens taken exclusively from real API metadata. Streaming is bolted on and silently degrades to off. mini-SWE: 164-line litellm wrapper; auto cache-control for Anthropic-looking models; hard failure when cost cannot be computed.
Trade-offs. Every reference pays a universal-adapter tax KHAELOR's Anthropic-only mandate amputates. The transferable parts are exactly three: typed errors, real usage accounting, cache-control planning.
KHAELOR. One ModelClient over the official Anthropic SDK; typed retryable/fatal/context-overflow taxonomy; AbortSignal cancellation; streaming first-class. See ADR-5, ADR-10.
2.13 Persistence
Problem. Never lose work — including mid-turn — without a heavy storage stack.
How each reference solves it. Hermes: incremental mid-turn SQLite flushes after every tool result; WAL fallbacks; schema self-repair; disk-full classification surfaced to the user. OpenCode: SQLite/WAL with JSON-blob payload columns, incremental token/cost counters maintained by delta at write time, keyset pagination. OpenHands: FileStore file-per-event + base_state.json with autosave-on-mutation; idempotent init (skip if a SystemPromptEvent already exists). mini-SWE: serialize everything in a finally block every iteration — durability in one line.
Trade-offs. DBs buy queries and transactions at the cost of native deps and armor code; plain files buy simplicity at the cost of hand-rolled atomicity and derived-state rebuilds.
KHAELOR. JSONL append with atomic line writes, flushed at every loop boundary (mini's discipline); derived metadata always rebuildable from the log. See ADR-3.
2.14 Git awareness
Problem. Protect user work: know what the agent changed vs what the user had, and never destroy either.
How each reference solves it. Hermes: the verify pipeline detects files changed per turn (feeding verification-on-stop) but has no baseline-protection story. OpenCode: the standout — shadow-git snapshots: a separate git dir operated against the real work tree (objects/info/alternates pointing at the real object DB + copied index = near-free seeding even on Chromium-sized repos), write-tree hashes stored in step parts, powering revert/unrevert and the diff viewer, invisible to git status. OpenHands: sdk/git diff/changes helpers feed the UI diff panel. mini-SWE: nothing.
Trade-offs. Shadow git is powerful but nontrivial machinery (orphan repos, index copying, size filters); baseline recording (branch, dirty files, diff hash) delivers the §16 protection guarantees with a fraction of the code.
KHAELOR. Baseline capture at session start and before first edit; explicit attribution; never auto-commit. Shadow git is the strongest post-V1 candidate on the list. See ADR-15.
2.15 Repository search
Problem. Understand a repository without stuffing it into context or maintaining a stale index.
How each reference solves it. Hermes: grep-style tools under strict output budgets; progressive disclosure (index-in-prompt, bodies on demand) proven on its skills corpus. OpenCode: a bundled ripgrep service behind grep/glob, hard 100-result caps with explicit truncation notices, and server-side fuzzy file finding with frecency ranking for @ mentions. OpenHands: ripgrep-first with an explicit logged fallback to system grep; bounded structured observations. mini-SWE: no tooling at all — the model runs ls/grep/find itself and navigates repositories well, at the cost of repeated token-burning discovery.
Trade-offs. Indexes (AST, embeddings) go stale and cost maintenance; honest search primitives never lie. mini demonstrates the model needs less retrieval help than agent frameworks assume.
KHAELOR. ripgrep-first grep/glob with bounded structured results; filesystem map + git state via the Context Engine; frecency-ranked file mentions in the TUI. No AST/embeddings/symbol index in V1 (CLAUDE.md §11).
Author: Simon-Pierre Boucher · contact@spboucher.ai