2026-09-11, save the date folks. That's when all companies selling products with digital elements in the EU have to have a reporting pipeline for actively exploited vulnerabilities and severe incidents.
First sensible take I've seen in this thread. People especially seem to forget the consequences of #1: The company where everyone is working 0.5 days a week will almost certainly get outcompeted, very quickly, by the company where everyone is working 5 days a week. In fact company #2 can probably precompute company #1 even if they have much lower quality staff on average.
In fact, most 2 digit numbers not divisible by 2, 3, or 5 are prime. [1] The only one that's likely to ruin your day is 7 * 13 == 91, but that's self-defeating because after you think about it long enough 91 falls victim to [2].
`sops` and `age` are about as barebones as you can get if you want to have something to check into a repo, I suppose. Most CI/CD runners have secret storage you can use to make this a nonissue as well.
The codebase was small enough that I handed it over to DeepSeek v4 Flash in Pi to skim through for any risky business, and I didn't find anything concerning. Nice work.
Since the OP stated they used DeepSeek V4 Flash for generating a lot of the code, I decided to check whether there were any outdated dependencies. In my experience, with Rust projects, if you do not instruct models (even Claude 4.7 Opus) to use `cargo add` instead of manually editing the Cargo.toml, you will almost certainly get out-of-date dependencies added to your project.
Manually checking the dependencies used by this project, I was pleased to see they are all the latest version. That doesn't mean there are no issues lurking in transitive dependencies, of course.
As for getting an LLM to review the code, I think we can get all opinionated very fast. For instance, when I was eyeballing the code, some of the enum methods converting to/from strings made me think "this could've been a single #[derive] with strum." That would make the code in provider.rs a lot more concise, at the cost of importing one crate (with no dependencies!)
Lastly, for fun, I decided to get DeepSeek V4 Pro (with Max thinking) to "audit" the codebase. The output mentioned no obvious signs of hidden telemetry, but it did note that the project sets the panic handler to "abort", which I have strong opinions on... Presumably the OP wanted to avoid linking against libunwind to save a few kilobytes of binary size, but now you have a binary that immediately aborts and doesn't give the user a stacktrace of what just crashed. I would rather have a ~50 KiB larger binary if it means getting useful debug info during a panic. Additionally, if there are async tasks that panic, they can't be recovered to display a generic error message; instead the whole process just aborts.
1. I had experience not only with wrong versions selected by the agents, but also weird crates (ex. choosing a crate with 10 github stars when a more complete and more supported one was available), reason why now I always choose the dependencies and then I let the agent work.
2. Yes, some of the provider code could be made using macros, I am just lazy... But thanks for the tip! I will save it for later.
3. No telemetry, and it can be checked thanks to the fact that there are no HTTP calls outside of the MCP implementation (via rmcp) and LLM connectors (via rig)
4. Yes, i set panic handler to 'abort', thinking that I would've get a nice size decrease: i yet have to experience a panic on this project, but I will revert it to default behavior if the binary size saving is really so small
5. While it is async, the entire project runs on one thread (as expressed in the main.rs with ```#[tokio::main(flavor = "current_thread")]```), as it allows for a nice ~8MB memory saving (so, 50% off) and no real performance loss, being such a simple tool.
---
P.S. Just switched back to default settings for panic handler
Hidden telemetry was my big concern, yes; the abort thing wasn't caught as a security thing by DeepSeek V4 Flash but it was mentioned by Claude 4.7 Opus (I wanted to compare and contrast here), and Flash brought it up later when I asked it about performance tuning.
`cargo add` tip is very helpful, I had a hunch this happened in my own Rust project and I think you just filled in the missing piece for me there.
To me panic=abort is much safer security as it means you’re unlikely to enter weird states due to incorrectly handled unwinding. The only attack vector is a DOS attack which is a short term thing that’s easily rectified.
Thanks! Funny enough, a good chunk of the coding was done by Deepseek v4 Flash, while I hand-wrote a couple of the TUI logic, as deepseek kept failing on certain cursor-moving logic, and I fully managed the memory optimization process (as you can read on another comment I left, it both a set of compiler optimizations and usage of certain Rust crates in order to leverage more efficient data structures).
Haskell would be my vote, and Rust too, actually, both because of their very strong type systems. The type system lets you very quickly figure out what something is before you figure out what something does, and it turns out that separating those two concerns as hard as those two languages do often results in doing the whole one-two punch faster.
Haskell does not qualify for a large training set, though. (Nor for readability in my opinion)
I think I have never seen haskell software made wih LLM's but well, aside from university, I have not seen Haskell code at all.
(Also Haskell purists I would associate with people who avoid LLM's)
I would rather go with Rust given these choices.
But I have good results with typescript (or javascript for simpler things). Really large set of examples. Tools optimized for it, agents debugging in the browser works allmost out of the box.
And well, a elaborate typesystem.
I give up rust because it’s not functional enough. There aren’t many things Claude can prove about a table viewer, and Haskell fits very well, and have enough libraries. Claude is pretty good at Haskell. I barely write Haskell before but I do know monad.
I used Claude to generate Haskell and it works really well. Claude struggles sometimes with respecting abstraction boundaries, but Haskell enforces parts of those boundaries in its type system better than a lot of other languages (if a module can’t do IO, for example).
Works well, in my experience. Sometimes the agent does weird stuff that you have to rewrite, but I get the sense that this happens in any language.
Maybe Haskell’s training set is not large enough, but it seems to work despite the smaller training set.
In the window of Haskell-like and highly readable, I’d throw OCaml and F# out as strong candidates.
In practice your code can be cleaner than Python, deeply flexible naming capabilities including full sentences with backticking, efficient and powerful discriminated unions and types enable near-English domains, the type system keeps you honest and provides exhaustiveness guarantees, domain modules of applied functions are obvious and locally coherent domain grammars, and there is potent DSL support to create mini-grammars for legibility and expressiveness.
I used to write python by hand to reason then type it up in C#. F# is just as easy with a pen, but far more powerful and with a powerful type system and aggressive compiler. OCaml and F# are also highly token efficient languages, beating Python across the board for agentic work.
I’d add perl (similar runtime semantics as python, but at least sigils give you some hint of developer intent. If you see &@%$$ck() in perl, you know you’re in for a ride).
I’d also add, C, C++, Rust, Java, Swift, Typescript, Ruby, Lisp, Make, Awk and Sed.
I've "written" a lot of rust via LLMs, and the rust tooling and features give a lot of useful guard rails to LLMs that produce pretty good code overall, certainly compared to the python I've seen it crank out. Clippy and fmt alone often cause the LLM to hit a snag and realize it's mistake and take a better approach. It's quite a powerful combo IME
There are many languages with similarly strong type systems - Scala, Kotlin, OCaml, etc (and nowadays, even Java). A GC may also be an advantage in that the LLMs may get it right in less tries.
Apparently the structure itself has a bit of a history. The word 'rediscovery' tipped me off to go to Wikipedia myself and read up more about this.
First Blumer et al., 1983 came up with a "DAWG", but reading the abstract [1] I was left a little confused as to how exactly we get from 'here is how we store all substrings of a string in O(|string|) space, with "is this a substring [yn]" recognition in O(|substring|) time' to the modern DAFSA, as cool and useful as that is. Come to think of it I bet I could use that in some LeetCode problems.
But the structure we actually think of as a DAWG or DAFSA (or FST, I guess, thanks to this Rust crate) is in the paper "The World’s Fastest Scrabble Program". That worked but you had to construct a whole trie first, then compact it down, so build time was a memory hog. Then Dr. Daciuk of 3city sharpened the blade in 2000 by proving that this was as good as it gets in the unsorted case, but on a sorted set you could build the DAFSA incrementally, because an increasingly large part of the graph you were building was already optimized.
And then from there BurntSushi got involved with the implementation and the rest is history.
reply