Here is my global CLAUDE.md, it has only three purposes:

  • use timeouts
  • no hacks
  • route easier tasks to cheap sub-agents

When using fable, it has proven itself to be excellent at slashing costs using the sub-agents routing.


# Global rules (apply to every session)

## Command timeouts & fast diagnostics
- ALWAYS wrap a command that can hang or block in a timeout guard, and **start at `timeout 3s`**. Only start higher when there's a real, specific reason (e.g. an ssh round-trip plus remote work), and expand from 3s as needed. Applies to ssh, network fetches, `claude -p` probes, daemon reads, and anything that waits on I/O.
- Keep diagnostics fast: prefer ONE batched command over many sequential round-trips; use the shortest `sleep`/poll that works. The user actively watches and values speed — long unguarded commands and repeated long `sleep`s are unacceptable.

## Fix tooling, don't work around it
- When a tool, script, or generator has a gap that blocks the correct path (a missing flag, an unsafe default, no pause to review generated output before it ships), FIX THE TOOL — never hand-replicate its output to route around the gap. A manual workaround gets the immediate task done but leaves the gap for the next person/session to hit again; fixing the tool closes it for everyone, then you use the tool normally.
- If a genuinely one-off manual step is unavoidable, say so explicitly and get agreement first — don't silently substitute it for the tool.

## Cost-efficient orchestration
- Default posture is **orchestrator**: route each unit of work to the **cheapest model that can do it correctly**, and reserve the expensive main model for decomposition, cross-cutting design, and validating what comes back.
- **Criticality overrides cost.** Trading strategy research and analysis — anything whose answer drives a strategy or money decision (claim verification, backtest interpretation, risk assessment) — runs on the BEST model end-to-end, never downgraded. Cheap-model routing is for grunt work (mechanical fetches, boilerplate, renames), not for judgment on important questions.
- Decompose a task into modular, isolated sub-tasks. Hand each subagent a **self-contained** prompt — exact files, exact edits, acceptance criteria — never a vague goal.
- Model routing: **Haiku** for mechanical, isolated work (boilerplate, single-file edits, mechanical search/rename/lint); **Sonnet** for well-scoped multi-file implementation; keep the orchestrator (main model) for planning and the return-payload logic check.
- Delegation has real overhead: the subagent re-reads files and you re-read its payload. Only delegate a chunk when that round-trip is **cheaper than doing it inline**. Do trivial one-shot steps yourself (a lint, a one-line edit, a quick grep). **Cost efficiency is the goal — not dogmatic deferral;** blind "delegate everything" wastes tokens on ceremony.
- Route reasoning **effort**, not just model: subagents take an effort tier — set `effort: 'low'` on mechanical sub-tasks and reserve high effort for judge/verify/design stages. Cheaper even on the same model.
- **Workflows inherit the expensive session model silently.** Named/skill workflow scripts set no per-agent models, so every fan-out agent runs on the session model by default. Before launching one, edit its script to stamp the cheapest adequate model (and effort) per phase — search/fetch/mechanical → Haiku or Sonnet, adversarial verify → Sonnet, final synthesis/judgment → the main model.
- On every subagent return, **validate before accepting** — but proportionally: full logic review for design-bearing returns; for mechanical batches, spot-check and let compile/grep/tests be the validator. Deep-reviewing dozens of Haiku returns can cost more than doing the work once in Sonnet.

I was happy with Google Domains, but like everything good that they do, they killed it. Without asking for confirmation, they pushed the entirety of their DNS registrations to SquareSpace. World class, Google. It forced me to search a bit and discover that even the little guys can get Cloudflare protection, wholesale. Damn I love them.

The domain transfer process takes work, here’s a rundown of tasks:

  • At google domains, turn off autorenewal and unlock your domain
  • At cloudflare domains, add your site, extracting in the existing DNS records; it’s messy but helpful; strip out the bad ones
  • At google domains, under DNS, click the non-obvious “custom DNS servers” material-view “tab” (gross)
    • change all the DNS servers from google to cloudflare (see cloudflare instructions)
    • turn off DNSSEC by removing all records
  • Start the transfer process at cloudflare; it will make you wait until it can actually pull the updated name server changes
  • Once cloudflare sees the name changes, it will allow you to select the “Free” plan and finish setup; but that does not mean the site has been transferred yet
  • On cloudflare, continue the transfer, pasting in a transfer code you copied from google
  • Once you think everything is in place, it still won’t work until you change SSL mode from “Flexible” (WTF is that!) to Full (strict), so it properly uses my Lets Encrypt certificates.
  • Also… EVENTUALLY… you will receive confirmation email from google. Click through that and finally, google and cloudflare will confirm the transfer.

The good news is, even though the process typically requires extension of the renewal by another year (unless the last renewal was very recent), it is an extension (you don’t lose renewal time).

A better Trader has been a work-in-progress project of mine for a very long time. The web UI was done in vanilla javascript, with old school imports, and PHP-style server-generated html, then added jQuery, then bootstrap, then started removing jQuery, then moved towards more-static html with JSON payloads for the data, then pined for better node imports, then then then. You get the point.

I went too long without a rewrite, so I recently became a weekend warrior skeletoning up the next gen web ui. Parts include:

  • Vite due to its blazing hot-loading, tree-shaking, polyfilling goodness
  • React because it’s good enough and gets the job done
  • Bootstrap because I won’t have time to finish the mobile apps for a while

For my UIs, D3 is the most important library there is. So the skeleton is based on responsively displaying a handful of some of Mike Bostock’s greatest hits (imho). This was quite important to me because D3 examples have been somewhat obfuscated when they were migrated to Observables notebooks. The skeleton makes it much easier for me to quickly get working D3 examples by copying Mike’s Observables code into a cozy little container with all the bells and whistles in place.

Let me know what you think of it.

Reddit | Live Demo | GitLab | GitHub | Wiki

Browsers are here to own our desktops. But they will never deliver the absolute horsepower of a natively-coded world-class desktop app or game.

These days, when you try to run one, you will find it is crippled by the browser’s 100 open tabs (admit it, you have that many open…). And lord knows you don’t want to close them all.

I am the user. I am the king. Not the last 20 sites I happened to browse, each of which is allowed to take a huge chunk of our system resources for whatever task they deem important. Once you’ve rabbit-holed down a few holes, you have given your entire system resources to them.

Don’t put up with this. OWN YOUR OWN SYSTEM.

To really take it back when you need to play a game, work in your DAW, or play a 4k video at high frame rate, you need that browser to give up ALL its resources. And in linux, that is super easy.

  • Find the parent browser process pid:
ps ax --forest| grep "[0-9][\_ ]*/usr/lib/firefox/firefox$"
  • “STOP” it. This is the magic that tells linux to just stop serving the parent process and all its children, stripping all CPU allocation from the tasks, without actually closing anything (especially your precious tabs scattered across all your virtual desktops). It’s amazing, it will freeze your browser in its tracks in an instant:
kill -STOP #pid-from-previous-step#
  • Start your powerhouse desktop app and do your thing.
  • When you’re done, you can “CONTINUE” the stopped process, kicking off the CPU to immediately start servicing all that javascript again:
kill -CONT #pid-from-previous-step#

I’ve scripted this up so I can press a media key to “stop” firefox and start up Kodi with beautiful performance. Here’s my javascript “continue” script, which uses my rad-scripts tooling:

#!/usr/bin/env node
import * as rs from 'rad-scripts';
const ffPs = rs.run_command_sync('ps ax --forest| grep "[0-9][\_ ]*/usr/lib/firefox/firefox$"');
const ffProcId = +( ffPs.trim().split(' ')[ 0 ] );
console.log( `Parent firefox pid = ${ffProcId}` );
rs.run_command_sync_to_console(`kill -CONT ${ffProcId}`);

Boost 1.77 is working well with it, and I’ve fully migrated to boost::json, which is working out great. The straw that broke the camel’s back was map.contains(), lolz. I was ready! I feel like I’ve had a hot bath. Nice.