Remix.run Logo
aka-rider 3 days ago

>feed the same input to the old Go app and the new Rust then diff the outputs.

Yes, I completely forgot to mention, this is exactly my case. Rune is a TUI editor, so I feeded the same terminal sequences to the old and new apps.

It didn't translate 1:1 (I ported core editor first, there were side panels, and different chrome elements) so I instructed LLM to use ttyd (tty -> browser render), Fable then could open both apps with playwright, make and compare screenshots.

To rephrase, one critical component is to establish a feedback loop for the model. This new generation of models: Opus 5, Fable, GLM-5.2, even Qwen3.8-27B can self-correct, provided they know whether they are progressing or not.

A month ago, especially smaller model would fall into a rabbit hole it dug for itself and would never recover. This generation can sometimes run tens of hours without losing track.

I still wouldn't trust a model after 70% context window, but the progress is noticeable.

coder-pm 3 days ago | parent [-]

The ttyd and playwright is a clever differential way, personally I’m doing the same when it’s about to compare the views (or fix something related to rendering). Good job on that!

A TUI editor’s real output is the bytes stored on disk, while rendering can look identical the saved files might diverge (encoding, line endings, trailing new lines etc). Did you manage to diff that?

Totally agree on the overnight roadmap runs I have the same experience here. The agents have to know how to self-correct and if it’s progressing, otherwise it’s failing!

aka-rider 3 days ago | parent [-]

>files might diverge

The way rune works with files minimizes chances of silent corruption. I keep original byte blobs immutable, separately there is a journal (kinda WAL) of positional deltas (inserts and deletes).

So I only need to validate that blob + deltas = snapshot.

Disk IO is encapsulated through VFS, and writes are atomics (write to a temp file, then rename).

Separate virtual rendering buffer is built on top of that. Rune, like Obsidian, renders markdown preview inline, so the same chunk could be rendered as "Header" as well as `## Header` when under the cursor.

All of that makes it quite easy to work with text. The core function is to translate offset in a byte array to line and column and back, which is pure math and relatively easy to test.

Another trick that helped a lot is to use sqlite extensively: blobs, deltas, vfs, redo and undo history graph are all sqlite tables.

I noticed that LLMs make stupid decisions when it comes to data structures, but they understand CRUD and SQL, so I turned all Rune's internals into dumb CRUD.

coder-pm 3 days ago | parent [-]

Nice trick with the structures, good for agent legibility! I will try it out on the right occasion:)