Longtail Forge Update: The Compiler Is Finally Quiet. Good. Now What?
Longtail Forge Update · September 19–October 2, 2026

Two weeks ago I wrote about getting the browser to stop guessing what kind of data it had in its hands. This time I get to write a sentence I have been trying to earn for a while: the TypeScript compiler is finally quiet across Longtail Forge.
Zero diagnostics. Every first-party JavaScript file is inside one of the strict checking programs. No explicit any left as an escape hatch.
That sounds like a finish line.
It is one. Just not the one where I get to declare the software finished, throw the laptop into the air, and start pricing yachts.
The useful change is more specific: a very large class of ambiguity that used to be allowed to accumulate now has nowhere approved to hide. At the same time, the verification system around the code got smaller in some important ways, failed to get smaller in one very measurable way, and picked up a cleaner starting point for future modules.
That last part matters because the next major product work is supposed to be actual product work again. I’d rather start Support Tickets and the next round of public-demo work from a boring, enforceable foundation than drag a pile of “we will clean that up later” behind them.
The short version
- All 1,577 first-party JavaScript files are now owned by one of three full-strict TypeScript programs, with zero diagnostics and zero explicit
any. - The regression estate dropped from 464 discovered programs to 348, and the estimated number of Node processes in a full run fell from 464 to 342 without merging test families that still need isolation.
npm run verify:sliceis now the one normal local verification entry point, and an unrecognized changed file escalates to the full gate instead of quietly escaping coverage.- The cleanup did not hit every numerical target. The
scripts/directory actually grew, mostly because strict checking and coverage policy required more explicit documentation and contracts. That miss is recorded instead of being massaged away. - A new
npm run module:createcommand can generate a strict-clean module starting point, while repository adoption remains a reviewed step instead of magic. - The 0.33.33 branch is closed on
nightly. The active roadmap has moved to 0.33.34, where public-demo analytics, privacy, feedback, and durable interest capture are being planned with nonessential data collection disabled until the boundaries are settled.
Zero TypeScript diagnostics does not mean zero bugs
The branch started with more than 32,000 full-strict diagnostics spread across the server and tests, browser code, and development scripts. That number is ugly enough to be memorable, but it’s also easy to misuse.
A TypeScript diagnostic is not automatically a bug. Sometimes it’s a missing description of something the program already handles correctly. Sometimes it’s a real disagreement between two parts of the application. Sometimes the type checker is telling me, quite reasonably, “You are making a promise here that the runtime has not actually proved.”
The work over this branch was to stop treating those three things as interchangeable.
Longtail Forge is still JavaScript at runtime. I didn’t rename 1,577 files to .ts, add a build pipeline, or make the browser wait for a bundler. The application still starts the same way. What changed is that the JavaScript is now checked under strict TypeScript rules using JSDoc, runtime schemas where the data crosses a trust boundary, and shared declarations where different parts of the application need to agree.
That distinction matters for self-hosting. A development process that only works because I remember which files the checker ignores is not much of a process. The final gate now proves that every first-party JavaScript file belongs to exactly one checked program and that the compiler actually read every file that program claims to own.
Does that make Longtail Forge bug-free? No. If a type checker could do that, the software industry would be a much quieter place.
What it does is remove an entire category of tolerated uncertainty. New type debt is no longer compared against a ledger and accepted because it is “no worse than yesterday.” The temporary debt ledger is gone. Zero is the rule now.
Technical discovery & auditing
The public page doesn’t tell you much about the machinery behind it. Raymond Tec audits inherited and long-running projects to uncover the plugins, integrations, data, dependencies, and old decisions that determine what the next change will really involve.
I wanted fewer tests. I got fewer tests. I did not get the number I wanted.
The other half of this branch was verification cleanup, and this is where the numbers tell a more interesting story.
Longtail Forge had accumulated 464 separately discovered regression programs. Some existed because they protected important behavior. Some existed because a narrow change needed a narrow proof at the time. Some were reading old roadmap or changelog text as evidence that current code was still correct, which is a wonderfully indirect way to test software.
The finished branch has 348 discovered regressions. Static history readers fell from 54 to 7. The estimated number of Node processes in a full regression run fell from 464 to 342. The 409-check permissions harness, which had previously lived outside normal discovery, is now counted as part of the estate it protects.
I had a more aggressive target: roughly 250 to 300 regression entry points and Node processes.
I did not hit it.
The reason is not especially glamorous. A large chunk of the remaining tests use isolated databases, isolated file storage, serial database behavior, or other process boundaries for a reason. Combining them just to make the graph look prettier would trade a numerical win for weaker evidence. That’s exactly the sort of cleanup I do not want.
There was another miss too. I expected the scripts/ directory to get smaller. It grew from 152,785 lines to 187,207.
Now, most of that growth is not 34,000 lines of exciting new machinery. A lot is JSDoc needed for full-strict checking and generated coverage-policy data. The regression owners themselves shrank structurally. Still, “I expected this directory to get smaller and it got 22.5 percent bigger” is not a sentence that improves if I hide it under a nicer metric.
So it stays in the record.
The better result is that the remaining verification has clearer ownership. There is also one normal command now: npm run verify:slice. It figures out what changed, runs the appropriate checks, and escalates to the full gate when a changed path is not understood. An empty selection fails instead of producing a reassuring green check for doing nothing.
That’s the kind of simplification I actually trust: fewer ways to accidentally prove the wrong thing.
Reliable automation
Automation is wonderful until it quietly stops working three Tuesdays ago. Raymond Tec builds integrations with logging, monitoring, and failure handling in mind so the boring work stays automated without becoming mysterious.
The cleanup found real behavior worth fixing
A long typing and verification branch can become dangerously abstract if the only output is a spreadsheet of disappearing diagnostics. Fortunately, the code kept objecting to that idea.
Workbench picked up several corrections while its contracts were being made explicit. A related action now needs a real action ID before its dependencies load. A supplied card route has to be a string. A corrupted cached card registry can recover from the normal bootstrap data instead of taking the surface down. A malformed timer start keeps the time already accumulated without pretending the timer is still running.
Lists produced an even better reminder not to confuse “the branch is green” with “nothing can go wrong.” Two regressions were introduced during the work: at one point the Lists page refused every real list, and at another other pages could no longer open the Lists dialog.
Both were caught and fixed inside the branch. They never became a release.
I like that story more than I would like a claim that the branch never broke anything. Large changes break assumptions. The useful question is whether the process makes those breaks obvious while they are still cheap to fix.
This branch also tightened how the browser isolates old-style scripts, how shared namespace members are published, how DOM lookups prove what kind of element they found, and how Workbench, Lists, Clients/Projects, Tasks, Notes, and Files describe the data they pass around.
You probably will not notice most of that directly. You may notice the absence of a future bug that no longer has a vague boundary to hide behind. That’s a difficult feature to screenshot, but it is still a feature I am happy to ship into the development process.
The next module now starts from a cleaner place
The part of this work I am most interested in now is not the zero. It is what the zero lets me stop doing.
Future module work should not need to rediscover the same public API response shapes, search-index plumbing, manifest defaults, permission composition, or TypeScript setup every time. The branch pulled several of those repeated boundaries into shared helpers and gave Time Tracking a more cohesive way to declare its permissions, events, and integrations.
There is also now a npm run module:create command that generates a strict-clean module starting point.
I’m deliberately calling it a starting point, not a module vending machine.
The generated code still has to be adopted into the repository through a reviewed step. A new module can have the right file structure and still have the wrong permissions, the wrong data model, or a terrible reason for existing. Automation can remove boilerplate. It cannot make the product decision for me.
That’s especially relevant because Support Tickets is the next large module on the roadmap after the public-demo follow-on work. I want Tickets to plug into the same application instead of arriving as a miniature help-desk product that happens to share a login screen. A cleaner module boundary makes that easier without pretending the hard design questions are solved.
The branch also added a dependency-cycle no-growth gate. In plain English, the project now measures the places where groups of files depend on one another in a loop and refuses new cyclic components beyond the reviewed baseline. It’s not pretending the existing graph is perfect. It’s preventing “we will untangle that later” from becoming the default architecture.
That’s the recurring theme here: establish the boring rule before the next interesting feature gives me a reason to ignore it.
Custom application development
Off-the-shelf software is great when your business works the way the software expects. When it doesn’t, Raymond Tec builds focused internal tools, dashboards, portals, plugins, and custom applications around the work that actually needs to happen.
So, what will anybody actually notice?
Today? Not a dramatic new screen.
The visible corrections in Workbench and Lists are useful, but most of this update changes the cost and risk of the next change rather than the interface you see right now.
- New JavaScript cannot quietly sit outside strict checking.
- A change that lands in an unrecognized path gets more verification, not less.
- Tests that still need process or database isolation keep it, even when removing it would make the metrics prettier.
- Future modules start with shared contracts and a strict-clean scaffold instead of rebuilding the same plumbing from memory.
- The measurements now include the misses as well as the wins, which makes them useful for the next cleanup instead of useful for a slide deck.
The larger benefit is confidence with a lower memory tax. I don’t want Longtail Forge to be maintainable only while I can keep the entire architecture in my head. The software is specifically supposed to help people avoid rebuilding context after an interruption. Its own development process should probably aspire to the same standard.
Small custom tools
Custom software doesn’t have to mean a giant multi-year platform. Sometimes a small internal tool that removes one ugly spreadsheet, repeated task, or missing connection is exactly the right amount of software.
Where things stand now
The 0.33.33 Lean Core, Full Strict TypeScript, and Verification Simplification branch is closed on nightly. The main branch hasn’t been promoted to that version yet, so I am not calling this a public release of 0.33.33.
The active development cursor is now 0.33.34: the public-demo analytics, privacy, feedback, and interest-capture follow-on. The important part of that plan is what stays off. Nonessential analytics and interest capture remain disabled until the external data boundaries, consent, retention, logging, and review path are actually decided and documented. Durable mailing-list and feedback data are also supposed to live outside the demo database that gets reset.
After that, Support Tickets remains the next major module in 0.34. It is planned. It is not shipped.
For the moment, I am happy with a less exciting milestone: the compiler is quiet, the verification system knows more clearly what it owns, and the things that did not improve as much as planned are written down where future me cannot conveniently forget them.
That’s not the end of cleanup.
It is a much better place to stop cleaning long enough to build something.
Want the detailed trail? The Longtail Forge Changelog is the place for release-level history, the Roadmap shows what is queued up next, and you can subscribe for future Longtail Forge updates if you would rather have the next summary come to you.
