Posts

How a 70-Year-Old Robot Fixed My Snarky Claude

Image
AI coding assistants are brilliant. They're also overconfident, defensive, and will produce wrong fixes with total certainty while ignoring instructions you already gave them. If you've used one for serious work, you've felt this: you correct it, it explains why it was actually right. You point out it missed something, it does the same thing again. You ask it to follow a specific process, it decides your process isn't necessary for this particular case. And it's not about how you talk to it. I use the Socratic method with my AI. I ask questions, not to be polite, but because I want to see its reasoning without biasing it. "Can you look at this?" not "here's what's wrong." I want to know what it finds on its own. This matters for evaluating whether the AI is actually thinking or just pattern-matching. And it means when I asked default Claude whether it had loaded a skill, that was a Socratic nudge, not an accusation. The model treated it a...

A 3-Level Process for AI Development to Stop Your App From Shifting Under Your Feet When You Change It

Image
You're iterating: you prompt your AI, it writes code, repeat. Things are going well... but then you make a change to one part of your app and something else quietly breaks. A feature you relied on isn't there. A UI element moved. A workflow you never touched now behaves differently. You didn't ask for any of that. If this sounds familiar, you're not alone. It's not a bug: it's because AIs work by telling stories. They make stories that make sense as much as possible, so they fill in missing details automatically. If you don't supply them, the AI generates them. That's what makes AI-assisted coding so productive. But it's also what makes apps unstable across multiple changes. The problem: unanchored code However you work with your AI: vibe coding, specs and code, or whatever, it does its best to make minimal, targeted changes. And for simple, localized updates, that usually works fine. But because of how AI works, it can add  features you didn't a...

Job Tracker: an AI-Powered Job Search Companion for Claude Code

Image
Claude Code can now help you track your job search. Job Tracker is a local-first Frictionless application: paste a job URL and Claude scrapes the details, searches for salary data, and keeps everything organized while you focus on landing the role. And if the app doesn't cover something you need, just ask Claude to add it; the app evolves with you as you use it. The Problem If you've ever job searched, you know the drill:  Copying company, title, and location from every listing into your notes Listings that don't show salary No idea where the company is even headquartered Dozens of applications across different sites "Wait, did I already apply to this company?" Status updates scattered across emails That perfect cover letter... somewhere on your desktop Spreadsheets work, but manually copying data from every listing is tedious. Job boards have trackers, but your data is siloed. And good luck finding salary ranges or company addresses when they're not in the p...

Loop Til It Works Is Great for Some Things

I've been tuning and refining ui-engine . Man, design choices early on dramatically affect the quality, capabilities, and potential responsiveness of a platform, especially if it has a UI. I've been using a lot of UI experience I've acquired since the 80s and tuning this platform is making me pull out some pretty weird heuristics, like "use a debounce," except in certain situations where that actually interferes with responsiveness. And, yep, I just scrutinized what Claude did and it's starting the debounce timer on the first send after processing a batch, so when processing a batch takes a lot of time, debounce will actually make responsiveness worse by adding yet more of a wait on top of that. Bad decision. My friend says Claude's a lazy coder. Claude does the easy thing if you just tell it, "build X". That's pretty much at every level throughout the system. Even a good design ends up with Claude cutting corners when it writes code becaus...

Frictionless

Image
Frictionless: Claude Code-connected apps What if Claude Code could use apps with you collaboratively? Like, you vibe-code or spec-code or just download an app and as you use it, Claude Code can interact with it too and even alter the app as it runs, without losing information and without needing a restart? Make Claude Code part of your apps... This is Frictionless. No difference between development and deployment and Claude can interact with it while it runs. Build Frictionless apps or download them.  Make dashboards for your Claude Code tasks: track progress, use levers and dials to drive from a UI Make prototypes: prototype production apps in a highly productive environment. Once it works, tell Claude to spec out a production app (hint, consider using [mini-spec](https://github.com/zot/mini-spec)). Improve your Claude Code life and your life beyond Claude Code with personalized expense apps, menu planning, or whatever other non-code, non-work things you do with Claude Don't ju...

Mini-spec 2.0: Now with teeth

Three weeks ago I released mini-spec: a ~93-line skill for spec-driven development. The idea was simple—add a design layer between specs and code so you can catch AI hallucinations before they become phantom features. It worked. But there was a problem: nothing enforced the workflow . Claude could skip the requirements phase. It could forget to link requirements to design artifacts. It could mark things implemented that weren’t. The traceability was only as good as the AI’s attention span. GitHub: https://github.com/zot/mini-spec It’s still the same 3-level process but now the enforcement is way better: Level 1: Specs What you want (human-written) Level 2: Design What the AI understood (requirements, CRC cards, sequences) Level 3: Code What got built The design level makes the AI’s interpretation explicit and reviewable before expensive code generation. Reviewing design documents is far cheaper than reviewing code. What’s new in 2.0 The minispec CLI tool – ...

Announcing mini-spec: spec-driven development for Claude in ~93 lines

mini-spec Spec-driven development for Claude in ~93 lines AI hallucinates features you didn't ask for. Sometimes they're great, so good you rely on them. Then you regenerate and they vanish. Mini-spec fixes this. GitHub: https://github.com/zot/mini-spec The three-level approach specs/ What you asked for (human-written) ↓ design/ What the AI understood (reviewable) ↓ src/ What got built (traceable) The middle layer is key . It shows how Claude interprets your specs: what you left out, where the ambiguities are, what you over-specified. Design docs are small and readable compared to code, so you can verify correctness before a single line is written. How it tracks drift design.md serves as the project's status memory. Each design file lists implementation files with checkboxes. When Claude changes code, it unchecks affected artifacts so it knows: A design review is needed Exactly what to look at There's also a "Gaps...
Use claude-crc, Don’t Lose Features to ‘Generous’ Inference 3-Level Spec-Driven Development For Claude The Problem With 2-Level Spec-Driven Development 2-level spec driven development suffers from the same problem as vibe coding – it just takes longer. Which means it bites you after you done a lot more work. I did some hand-rolled, 2-level spec-driven development for an app I’ve been building. By 2-level, I mean you have a collection of spec documents and tell Claude to generate code from it. When you change one set, you tell Claude to check your changes and update the other. It works pretty well as a light-weight alternative to vibe coding. But it’s not a tiny app and I after a while I ran into problems. Claude “generously” inferred things from my specs that weren’t actually in there. I wasn’t as diligent as I should have been with reviewing the generated code – because AI, I suppose. It generates so much code so fast that eventually it becomes easier just to have it auto-approve ...

A VERY lightweight MVC framework for React

I just dropped a new repository on GitHub about this -- just wanted to put a pointer here.

Transactional memory for operational transformation in Leisure

It's been a very long time since my last post but we haven't been idle.  We've been working on Leisure, which grew out of Lazp.  Leisure has become a collaborative, dynamic, polyglot, computing environment, but more about that in future posts.  If you're curious about Leisure, you can find the repository here , although we haven't formally announced it, yet.  It's functional but buggy. For now, here's a short note about how Leisure manages collaborative data manipulation.  Leisure's collaborative documents contain a combination of content, code, and data, all represented by org-format markup in plain text.  Data in Leisure documents resides in markup-delimited regions of text, such as org-mode source blocks containing yaml data and code in a Leisure document can change that data.  This means that, beyond just normal collaboration, Leisure requires an exclusion mechanism so that data can stay consistent when several users access and change it. Curre...

DOMCursor, a tool for filtered DOM tree cursoring

While working on Leisure , I searched for tools to traverse text in DOM trees, but most of the ones I found were fairly limited.  One nice one is Rangy ( https://github.com/timdown/rangy ), which has a TextRange that can traverse by characters and words with rules for skipping over invisible text, collapsing contiguous whitespace, etc. Leisure, however is what you might call an “ultra-rich text” environment and needs more power.   This isn't my announcement of Leisure, by the way -- it's got a bit farther to go for that -- so consider this a teaser :). Leisure documents are orgmode files and the environment has a couple ways to present them, some of which sprinkle controls and views in among the editable text. During the design, I decided to use the contenteditable attribute and use the text in among the sprinkled controls and views as the actual document text, as opposed to emulating document editing, like code mirror does . Over the years, I experimented with different ...

Trying out a Coding Dojo

We had our first Coding Dojo session, today.  I wanted to start a "Programming Dojo" and I found that some people had already been doing that for years , so I decided to use their wisdom :).   Here's a great video, linked from the same site. The guy making this gestures with the camera a lot.  If you get easily motion-sick, maybe you should just listen to it. The idea is to have 2 people pair programming in front of a group, with the group kibitzing.  Techniques are discussed only in the context of code and programming is the path to learning in the coding dojo.  I'm introducing people, here, to functional programming concepts.  Here is the "kata" we used, today: Kata: Person Learning about "selector functions" 1. Write a "person" function, person(name, address, gender):  it returns a "person"; something which can be used to retrieve the values you man not create a new array, object, or string you may use comparis...

Lazp: an untyped, lazy, functional language with support for runtime metaprogramming

So far, the only untyped, lazy language I've found that's being maintained is Lazy Racket .  I've been interested in Lambda Calculus for a while, though, and LISP/Scheme aren't quite what I want (and they're quite a bit larger, too), so I decided to extend the Lambda Calculator  into a standalone language.   Here's the repository .  The goal is to make it native, but for now, it's still in JavaScript, although it will run "standalone" in node.js (and also in browsers).  Here are the language features I'm interested in: lazy , so no side effects, because they can really mess up a lazy language untyped ; Haskell is already there for typed, lazy languages metaprogramming ; the eval function uses ASTs that are LC functions We'll rewrite Lazp's parser and code generators in Lazp, so it's self-hosting I "hand assembled" the AST functions, so they're in Lazp, already This means metaprogramming in Lazp can happen at pa...
I added an intro, a summary, and a few more ideas to the Code Google post .  It needs a better name that doesn't just mean "search" to people and also doesn't include trademarked words :).

Code Google

UPDATE: Added structure and a few more ideas... Intro Have you ever seen someone include a giant open source library in a project, just to access some small part of its functionality? It's very important to have someone else write, debug, and maintain a large part of your code, but when you do this over and over, it can add quite a lot of bloat to an app for comparatively little gain in functionality. This is a huge problem, as I see it, but maybe there is a solution? What about allowing people to integrate only small subsets of modules into their code. I'm calling this idea "code google," for lack of a better term, although it's a LOT more than just search. It involves search, analysis, IDE integration, and social networking, so that library developers can track what parts of their code are actually being used. It's far from trivial to implement, but I think it could be very useful Before our company started, a friend and I wrote a fair-sized ga...

Podcast interview about Death of the Vele

I already blabbed this in a bunch of emails to people, but just in case... Scott Dunphy of New Style interviewed me about Death of the Vele, here . This was the first time I've been interviewed for anything; I was surprised I sounded coherent -- I thought it might come out a lot less cohesive than it did when I listened to it.

Quick update on The Philosopher's Stone

I have changed TPS many times in the past year and a half, but the core idea is still to be a collaborative story telling RPG that feels like a traditional RPG. The latest version of it is called Death of the Vele and the (lame) website is here It has a link to the latest rules. Wow, taking a look at the old rules, I see that I have streamlined the mechanics a LOT since last year. They are simpler, lighter weight, and more intuitive. There are also tools to promote more integrated and structured stories (spotlights, hitting aspects, etc.). Death of the Vele also adds a back story (which you can remove if you don't like, of course). I'm hoping to publish Death of the Vele within the next 12 months. In the mean time, the rules are out there for free, so anyone who wants to can use them. Here is the feature list from the latest copy of the rules: Collaborative, but feels like a traditional RPG Your characters are yours Supports campaign-length stories Game play ...

Applied Lambda Calculus

I made a slide presentation introducing Lambda Calculus and some functional concepts (lazy evaluation, how to represent data, etc.). It also talks about a Lambda Calculator I wrote, which does LC in three ways: compiles into JavaScript interprets through substitution (alpha, beta, and eta) and shows the steps compiles into virtual machine code (and can execute it) The VM still fails on some complex cases, but when I have that working, I want to make it generate native code, using LLVM. I open sourced all this, under the ZLIB license. Oh, I also started on a Lambda Calculus version of space invaders , which is in there, too :) LC is a really nice language. I wasn't able to find a modern, untyped, lazy language. It seems like functional languages have all gone the way of static typing, but I'm hoping it doesn't have to end that way. Looking at what Anders Møller and co. are doing with TAJS at Aarhus University and BRICS gives me hope that some day, the computer will te...

Calculator/spreadsheet tool for Acme

I got Plan9 from User Space and started messing with it in the hopes of getting a nice toolbench going with Acme. Since I wrote Ober , I've been interested in this idea. Now, I'll probably rewrite it in Go. I'm wondering if I can just use named pipes to mimic what Acme does with its 9p interface. Anyway, I wrote a simplified version of the Calc tool I wrote for Ober and I put it, here . The calc tool searches an Acme window for variables and their values and some code at the bottom. Then, it executes the code, sending the variables and values to its stdin. The code is expected to output new values for some of the variables. Calc parses the output and replaces the new values into the window. I'm also including two wrappers that make it easy to write calc scripts in rc or Go, so you can say something like this: Bob's age=30, he is yearsleft=0 years away from retirement (calc). #!/usr/bin/env calcgo yearsleft = 55 - age If you middle-click "calc" in t...

The Philosopher's Stone

I've been searching for the "Philosopher's Stone" of role playing for years -- a role playing system that combines traditional role playing with the collaborative story telling of Universalis. I think the Blood Red Sands system might allow this. By replacing the coins of Universalis with dice, BRS introduces relative differences between traits, an element of risk into contesting for narrative control, and a competitive framework for play. I think this difference can allow it to support traditional role playing better than Universalis. That's how the document for the new game I'm working on starts. I found Ralph Mazza's Blood Red Sands about 5 weeks ago, when I checked out the Ramshead Publishing site, to see if there was anything new going on. Wow, was there ever! Blood Red Sands is a highly stylized, competitive role playing/story telling game about heroes and their ordeals as they strive to confront the evil, despotic Witch King in a blasted land c...