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.
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.
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:
| Mode | Recall | Invented 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.
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
domain → application → infrastructure 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.
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.