LUCIANO CARRIZO
All projects
ArchivedPrivate

openlucho

A persistence and continuity layer over Claude Code: it observes sessions Claude already writes to disk, persists them in SQLite, and builds living Markdown memory where every fact cites the real events it came from. It began as something else—an orchestrator meant to make subagents cheaper—until its own spike measured routing at 3.3× the cost and the product changed direction. Archived.

RustTypeScriptTauriSQLiteReact
What it is

Observe, persist, continue

openlucho is a persistence, continuity, and observable-progress layer over Claude Code. Claude already writes every session to disk as .jsonl transcripts under ~/.claude/projects/. The app watches them without invading them—it does not stand in the middle, wrap the agent, or depend on the API or SDK. The runtime is purely disk and observation. It normalizes events, persists them in SQLite, and presents them in a desktop app built with Tauri.

The chain organizing the entire project is observe → persist → continue. It addresses the familiar friction of working with an agent session after session: what happened last time remains in a file nobody reads, and starting over means recounting the entire context. The third link—continue—is what gives the first two their meaning.

The app (apps/visualizador) has six views. The one that most defines its tone is “Agentic”: it renders the conversation with Claude Code’s visual language—collapsible tools, red and green diffs, a bubble hierarchy—reading the .jsonl ephemerally and lazily without duplicating its content in the store. Observation is not paid for twice.

The pivot

I proposed a cheaper orchestrator, and my own spike killed it

The project did not begin as this. The original idea was an orchestrator: a mechanism for routing work between separate Claude Code sessions to avoid the cost of native subagents. The hypothesis was economic, not technical—moving work to independent sessions would be cheaper than delegating it through the official path.

I measured that hypothesis before building the product on top of it. A spike—A1, documented in docs/vision.md—falsified it in practice. Measurement exposed the reasoning I had missed: Claude Code’s native subagents already isolate the orchestrator’s context. They run in their own window and return only a summary. The extra cost I thought I was paying had already been solved elsewhere. Routing through MCP to separate sessions saves nothing. It costs 3.3× more at the system level.

That number decided the project. The original idea could not be rescued: if savings were the orchestrator’s reason to exist and those savings did not exist, what remained was not a smaller version of the same thing. It was another product. The direction changed toward what still stood from everything already built: observability and continuity. Persist what happens, make it readable, and resume it.

What I lost was the project’s most marketable hook—“spend less”—in exchange for one much harder to explain in a sentence. What I gained was that the spike, besides killing a hypothesis, cleared the way for the most original piece in the repository: the one that follows.

Living memory

Memory that cites its sources instead of synthesizing them

The crates/memoria crate is the project’s backbone after the pivot and the part I am most satisfied with. It writes transparent living memory in Markdown inside the observed project itself, under <project>/.openlucho/memoria/. Markdown, in the repository, readable without the app: memory is not a binary blob understood only by the tool that wrote it.

Capture is graded across three levels: auto (extracted from events), semi, and curated (passed through my judgment). Not everything remembered has the same value, and the grade travels with the fact instead of remaining in the author’s head. On top of that sits an automatic, dedicated FTS5 index in SQLite: searching memory is a query, not a manual grep across Markdown.

What makes the project different is the rotar command. When memory grows and must be compressed for a new session, the output is not a model-synthesized summary. It is a pasteable summary prompt where every fact cites the genuine events it came from. That is the anti-opacity mechanism, deliberately opposite to automatic summarization. A synthesized summary is convenient and opaque: you cannot audit where each statement came from, and when the model fills a gap it does so silently. Cited memory can be verified fact by fact.

The design was validated with another spike, A4—a disposable workspace crate written to measure and discard. It measured assisted rotation recall across six real sessions and 3,926 events, using the repository’s own ORCHESTRATOR.md as the gold standard:

ModeRecallInvented facts
Deterministic (no LLM)~40%0%
Assisted (agent citing events)~90%0%

The second column is the one that matters. The jump from ~40% to ~90% recall shows that the agent adds value—the deterministic approach alone is insufficient—but 0% invented facts validates the thesis: requiring the source event is not decorative auditability. It is what prevents model assistance from degrading into hallucination. It also establishes the mechanism’s honest ceiling: ~90% is not 100%. Assisted rotation misses some facts, and that remains explicit rather than averaged away.

A daemon, memoria capturar, completes the piece by ingesting live events and regenerating estado.md as the session progresses.

Architecture

A Rust workspace, with Clean Architecture per module

The backend is Rust (2021 edition), organized as a multi-crate workspace with Clean Architecture applied per module: crates/capturador (observe) and crates/memoria (persist and continue), each with domainapplicationinfrastructure layers and a domain free of external dependencies. That separation was not decorative symmetry. The capture crate survived the pivot intact precisely because it knew nothing about how its normalized events would be used.

The capture crate exposes its own CLI—ingest, sessions, stats, watch—and uses notify as a cross-platform file watcher for following .jsonl files live. Persistence uses SQLite through rusqlite with the bundled feature, where the memory FTS5 index also lives. Tauri 2 is the desktop shell, with React 19 + TypeScript + Vite inside. The app is deliberately excluded from the Cargo workspace because it needs the frontend dist to compile and is built separately.

Two non-code artifacts also define the repository’s discipline: a living ORCHESTRATOR.md handoff across sessions—state, decisions, gotchas, roadmap—and a docs/archive/ directory where discarded decisions move through git mv instead of being deleted. Preserve why, not only what. Sixty-one commits, one author.

The close

Why I left it, and what came from leaving it

The repository has had no activity since July 2, 2026, which is why it appears here as archived rather than “in progress.” I did not leave because it failed: the pivot was resolved, living memory works, and it was measured. I left because a larger question appeared along the way.

The repository’s last movement was a research PR—“research opcode as the base of the agent workspace”—that remains open today. On that same July 2, opcode-lucho began. The matching dates are not a coincidence; that fork is literally what came out of this research. Evaluating whether to build my own GUI from scratch or begin with an existing one ended in my own fork, and that is where the time this project never recovered went.

I still publish it, honestly marked archived, because the case’s value is not that it reached production—it did not. It lies in two measured decisions: a product hypothesis that did not survive its own spike, and a memory mechanism that prefers citation over synthesis.

Next step

The case shows the code. Let’s talk about what comes next.

openlucho is documented end to end: architecture, decisions, and what remains unfinished. If you have questions about the approach, write to me.

Let’s talk

or directly → LuchoC.dev@gmail.com