The builder with too many repos
Dozens of projects under ~/Development, each with its own tool files. You want them consistent, from one place, without visiting each one.
A film in nine acts · release 0.10.1
A harbormaster for everything that lands on your machine, and a pilot when you need one.
Your Mac runs hundreds of tools from many sources, and each one updates on its own schedule. The steward is the one place that decides what is allowed in, and when. With its skills installed, open Claude Code and it tells you, once, what needs you; answer in plain words. Nothing changes without your word, and every change can be undone.
I Why
Four things that happened to real machines, in one month.
Almost nothing on a developer's machine was installed by one tool. Language runtimes, command-line tools, Homebrew, desktop apps, AI coding tools and every project's own dependencies all arrive by their own roads, on their own schedules. Together those roads are your software supply chain.
Some of those arrivals are attacks. Some carry flaws. Nobody sees the whole harbor at once, because nobody is standing where the decisions get made. In October 2026 alone, four kinds of thing came in on the tide. Tune in to channel 16, the frequency ships call on when something is wrong.
A compromised LiteLLM release reached PyPI and Docker Hub, including the latest tag. It was pulled within hours. Every machine that pulled latest in that window got it.
And no one was watching the whole harbor.
The steward is the one place where that decision gets made, and written down. It aims for safe, explained and reversible, not merely newest. Think of it as a package manager for your package managers: one set of plain rules, with sensible defaults, applied to mise, Homebrew, your apps, your AI tools and every project you work on.
II Who
Four people who feel this first.
You do not need to be a security specialist. You need to have felt one of these.
Dozens of projects under ~/Development, each with its own tool files. You want them consistent, from one place, without visiting each one.
You are trusted with other people's code. You need to say what is on your machine, when it got there, and that you can put it back.
You want a gate in front of new releases, a plan before anything runs, and a record after. Not a changelog you discover later.
You run Ruflo, AQE or Brain across projects. You want them pinned, qualified, and never updating or spending tokens on their own.
III The gate
New releases wait at the anchorage. Three days, by default.
In Venice, ships from plague ports waited forty days before anyone came ashore. Quaranta giorni gave us the word quarantine. The steward keeps the idea and shortens the wait.
A new version comes in once it is 3 days old. This is the release-age gate. Most hijacked or broken releases are found and pulled within days, so a short wait lets other people find them first. You set the number once, in steward.toml, and it applies everywhere: mise, Homebrew and Renovate all read the same value.
A ship flying the yellow Q flag is asking to come ashore. Move the gate and watch who gets in.
# steward.toml [policy] min_release_age_days = 3 # mise, Homebrew, Renovate
The ages are real ones from recorded sessions. The steward's own release 0.10.1 shows its true age as you read this, because installed through mise it waits out the same gate as every other tool.
steward.toml. steward sc release-age changes it there and in the copies mise and Renovate need, and the audit flags any disagreement.steward review reads Renovate's Dependency Dashboard: each update held at the anchorage, when it clears in UTC, and the next step. It only reads.IV The pilot
The pilot knows the water. The captain keeps command. Every change goes in the log.
In a busy port, a harbor pilot comes aboard to bring the ship in. Here the pilot is Claude, carrying the steward's skills. It takes soundings whenever it likes, because looking changes nothing. Anything that changes your machine waits for your word, follows one shape (a plan, a backup, a receipt, a way back) and goes in the log. Bring the pilot aboard: the session below retells a recorded one, and it waits for you where the real one does.
Retold from recorded sessions (docs/assets/steward-skills-updates.svg and steward-upgrade.svg), with the line a command has printed since 0.10.1 when it answers with your yes. Do you want to proceed?
is Claude Code's own prompt: the skill runs only read-only commands without asking. Paths are shortened with ~, the way the steward prints them.
DRY_RUN=1 shows the plan and stops. Say no, and nothing happens at all.
gh 2.103.1 stays on disk for 3 days. steward sc prune waits them out, then asks.
day 0 of 3
The engine labels every step with who may take it. How far the pilot goes without asking is yours to set, once, in steward.toml: [autonomy] level. No setting widens what is always yours, and every write still plans, backs up and writes a receipt.
stewardOn its own, steward reads what is already on your disk and names the one next step, with its exact command, or says nothing needs you. A step that stopped midway comes first, in red, with the step that finishes it. In Claude Code the same answer arrives as the pilot's first word: one Steward:
line at the end of its first reply, then quiet; if you left that session before Claude replied, the next one brings it back. A broken or half-finished state shows as a notice instead.
steward fix works the whole list the way the pilot does: it runs what your standing orders allow, asks you for the rest, and hands you what is yours.
steward steward upgrade stopped midway: 1 of 2 part(s) done next: steward upgrade +1 more: steward brief --all # (here you run steward upgrade: it shows the part left, asks once, runs it) steward steward nothing needs you
V The map
A machine has more than one supply chain. Each gets its own berth, its own rules and its own commands.
A toolchain falls behind. An app bundles an old runtime. An AI tool updates itself. A project pins a path that a cleanup removes. Left to one script, these overlap without knowing about each other. Giving each supply chain its own area makes the drift visible and the rules enforceable. Click a berth.
Supply chain
Everything that lands on the machine: mise tools and mise itself, the global npm command-line tools, Homebrew formulae and casks, apps and the runtimes they bundle, the App Store, macOS, trust stores, Docker images, and known signs of compromise.
Decides when a version may come in.
Each berth has one order for its routine, and it shows every part's plan before it asks once: steward upgrade at the docks, steward ai fix at the warehouse, steward projects apply at the registry office, steward fleet tidy in the lanes. Each part keeps its own backup, receipt and way back, and still runs on its own when only one thing is behind.
VI Projects
Configuration lives in each project. Consistent across projects, if you want it.
Most tools that manage AI tooling work at the user level: one global setting for every project you open. The steward does the opposite.
Each project chooses its tools, or none, and the choice is recorded in a registry. Onboarding writes only that project's files, shows every one first, backs up, and never commits anything. The files it creates are listed in .git/info/exclude, so git status stays clean. Tracked files are refused; those changes go through a pull request.
When a new version of a tool is qualified, reconcile brings every project's copies in step. Copies you edited are kept and reported, and --take adopts the new one when you want it. Offboard takes the tools back out of a project that no longer wants them, with the same plan, yes, backup and receipt.
Try it. Choose each project's kit, plan it, then apply.
The plan on the right is the real shape of steward projects onboard: the file, whether it is absent or ignored today, and what would be added. Nothing is written until the apply, and the apply asks. For many projects at once, steward projects --apply asks each new one's decision, and steward projects apply brings every project to its decision with one yes. Or tell the pilot: onboard the new repo with AQE only
.
Retold from a recorded run (docs/assets/steward-projects.svg), adapted to the tools you pick.
steward ai. What changed is where the configuration lives: in the project, under a decision you made and can read back.
VII Your data
The engine holds none of your data. Your policy is a few plain lines, with defaults you can change.
The npm package. Code only.
just leak-check keeps it that way.A folder: ~/.config/workstation-steward
steward.toml and the policy files beside it: where your projects live, the gate, the soak, which add-ons are on.steward config sync keeps this Mac and GitHub level, fast-forward only, with a plan and a yes.~/.local/state/workstation-steward/, mode 0700.Click any value to change it. steward config reports every effective value and where it came from: the engine's default, or your file.
VIII Now and next
What ships today, lit. What is charted next, in outline.
/steward:fix to work the list. It speaks first, once, when something needs you, and asks before anything changes.steward, and one weekly list, steward review, including what the release-age gate holds back and when it clears.[autonomy] level for what runs unattended, and steward fix to work through it.upgrade, ai fix, projects apply, fleet tidy.steward rollback.steward sc node-patch: checksummed, byte-checked, with the previous Node kept.steward config sync.steward sc add <tool>: the whole vetting checklist as one guided command. plannedsteward doctor checking a release's provenance for you, and release notes that say what to run when a version changes behavior. plannedPlanned means written down in docs/lifecycle.md with an order, not a date. Nothing here is lit until it ships.
IX Start
Four steps aboard. Then ask the pilot, or type one of eight.
mise use -g npm:workstation-steward@0.10.1mise then keeps the steward current under the same release-age gate as your other tools. Needs Node 26 or later. 0.10.1 was the current release when this page was made. Plain npm install -g works too, and npx workstation-steward@0.10.1 version lets you look without installing.
Until 27 November 2026, mise asks for an approval because the package is less than 30 days old. Use this form instead:
mise use -g 'npm:workstation-steward[allow_low_downloads=true]@0.10.1'steward versionSays which release is running and where your config will live.
steward initCreates your config from the examples, shows every file it will write, and asks first. Then it walks the rest one question at a time: the AI tooling add-on, the projects add-on and where your projects live, and the Claude Code skills, the pilot.
steward doctorstewardWhat this machine still needs; then the one next step, and the eight everyday commands under it.
stewardthe one next step, or that nothing needs yousteward reviewweekly: everything waiting on a decisionsteward fixwork the list under your standing orderssteward upgradetools past the gate; shows the plan, asks oncesteward config syncyour config repo level with GitHubsteward projectswhat is new or gone; --apply asks each decisionsteward rollbackundo the last upgrade or Node patchsteward doctorfirst run, or when something seems offsteward help --all lists the rest, by area. Old names keep working.
The steward ships as a Claude Code plugin: one skill per area, and /steward:fix to work the list. Open a session and, when something needs you, it says so once. Say what you want in plain words. It runs the read-only commands, explains what they found, and asks before anything changes.
steward skills installRun it in your own terminal, not inside a Claude Code session: Claude Code accepts a plugin's command only from a person.
Every release carries a provenance record. It should name this repository and its release workflow. On npmjs.com a version that has one shows a green check; from a terminal, with jq:
curl -s https://registry.npmjs.org/-/npm/v1/attestations/workstation-steward@0.10.1 |
jq -r '.attestations[] | select(.predicateType | test("slsa"))
| .bundle.dsseEnvelope.payload | @base64d | fromjson
| .predicate.buildDefinition.externalParameters.workflow | "\(.repository) \(.path)"'
# https://github.com/pacphi/workstation-steward .github/workflows/release.yml
No curl … | sh installer exists, on purpose: running a download straight into a shell is what the steward guards against. Nothing changes on its own: the only thing that runs unasked is a short look that reads and never writes, and there are no auto-updates. Anything that writes shows a plan, asks, backs up, writes a receipt and prints its way back. DRY_RUN=1 previews any of them.