My Current Linting Setup for RiskPlus

Published on: 6/14/2026 Category: AI, Development

RiskPlus has a longer history, but the current version came from a full rewrite a little over a year ago. I used Cursor with Sonnet 3.7 to save time and money, rebuilding work that had previously taken a team of three people in about six weeks.

I have written about that rewrite separately, so this is not the full story. The relevant part here is the constraint: the rewrite happened under real time pressure, with much rougher agentic coding tools than we have today.

So the early setup was, frankly, pretty cowboy-ish. No serious linting setup. No properly enforced type checking. The priority was to ship.

This year we finally had enough breathing room to fix that.

For the Flask backend, I am now very happy with Ruff and ty. The first step was not to clean up everything in one massive pass. Instead, I introduced a migration mode based on the Boy Scout rule: if you touch a file, you leave it cleaner than you found it.

Before every commit, a check would run. If Ruff found issues in the changed files, the agent had to fix them before committing. At first, this used a deliberately small rule set. I left out heavier checks like cognitive complexity.

That worked. But it also had an obvious downside.

Agents would sometimes get pulled into large central files. A small change would trigger lint cleanup, which would trigger more cleanup, and suddenly a tiny feature produced a huge diff. Technically correct, but not always pleasant to review.

Recently, after finishing a larger migration, we had a few quieter days. I used that window to do the real cleanup. Over one weekend, I ran two long Codex /goal sessions, roughly 20 hours each, to fix the remaining backend linting and type-checking issues. I reviewed the changes and checked for regressions afterwards.

That worked surprisingly well.

The frontend is a bit more complicated, but the approach was similar: first a commit-level linting mode, then a focused cleanup pass. There I currently use tsgo, oxlint, oxfmt, svelte-check-rs, and oxsvelte. The Rust ports are especially interesting because the performance is excellent.

Internally, we also use Sonar. More than half of the Sonar issues were cleaned up during this push.

I am still looking for better best practices here. Our stack is somewhat unusual: Flask plus Svelte is not exactly the most common path. But for us, it works.

My main takeaway: good linting and type checking do not just help humans. They also help coding agents. Codex works much better when the codebase gives it clear rails. The output is more consistent, the review surface is smaller, and the code quality is noticeably better.

There is still more to improve. But for a small team, this already made a real difference.