A film in nine acts · release 0.10.1

Workstation Steward

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.

  • macOS today
  • MIT · open source
  • Nothing changes on its own

I Why

One October

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.

156.800 MHzCH 16 · CALLING
Transmission 1 of 4

A hijacked release

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.

    Each one happened because a tool decided for itself.

    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

    Who stands on the pier

    Four people who feel this first.

    You do not need to be a security specialist. You need to have felt one of these.

    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.

    What you getA registry of your decisions, every project brought to its decision with one yes, and one weekly list of what needs you.

    The consultant on client work

    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.

    What you getA receipt for every change, a backup before it, and releases whose build you can verify.

    The engineer who reads advisories

    You want a gate in front of new releases, a plan before anything runs, and a record after. Not a changelog you discover later.

    What you getA 3-day release-age gate, an exception for the first patched release, and audits that only read.

    The agentic engineer

    You run Ruflo, AQE or Brain across projects. You want them pinned, qualified, and never updating or spending tokens on their own.

    What you getDrift checks, repinning to stable paths, and guards that stay off whatever the tool defaults to.

    Not for you, yet, if

    • you want updates to happen silently in the background. Nothing changes on its own, on purpose: the only thing that runs unasked is a short look that reads and never writes.
    • you want a window to click in. It is a conversation in Claude Code, and eight commands for when you'd rather type.
    • you work on Linux or Windows today. macOS came first; the rest is charted in Act VIII.

    III The gate

    Quarantine

    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.

    Anchorage · holding 0

    Quay · cleared 0

    Harbormaster's office · your call 0

    # 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.

    • One number, everywhereSet once in steward.toml. steward sc release-age changes it there and in the copies mise and Renovate need, and the audit flags any disagreement.
    • The advisory exceptionThe first patched release for a published advisory (GitHub Advisory Database, RustSec, OSV) may skip the gate, with an expiry.
    • Majors are deliberateA major version always waits for your decision. A 0.x minor bump counts as a major.
    • Signed data skips it tooData that is signed by a pinned key, never code, checked against the gated runtime that reads it.
    • See who is waitingsteward 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 comes aboard

    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.

    claude — ~/Development/web

    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.

    One shape for every change

    way back plan · yes · backup · receipt PLAN YES BACKUP CHANGE RECEIPT

    DRY_RUN=1 shows the plan and stops. Say no, and nothing happens at all.

    Receipt workstation-steward

    command
    steward sc upgrade
    yes
    yours, for this run (--yes-to upgrade)
    changed
    gh 2.103.1 → 2.103.2
    backup
    ~/.config/mise/backups/config.toml.20261028-112629
    way back
    steward rollback
    soak
    old gh kept 3 days; prune waits

    The yard · soak

    gh 2.103.1 stays on disk for 3 days. steward sc prune waits them out, then asks.

    day 0 of 3

    Standing orders

    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.

      No Claude open? Type steward

      On 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.

      V The map

      Four berths

      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.

      GitHub · the remote The shipping lanes Fleet · Renovate PRs, one verified PR per repo, checkouts kept level The docks Supply chain · what lands, and when BONDED The bonded warehouse AI tooling · add-on The registry office Projects · add-on

      Supply chain

      The docks

      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

        Every vessel picks its own kit

        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.

        steward — zsh
        Pick a project's tools, then press Plan.

        Retold from a recorded run (docs/assets/steward-projects.svg), adapted to the tools you pick.

        If you used agentic-kit: this is where its best parts went. Drift checks, guards against self-updates and background daemons, and verified installs live on under 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 ledger is yours

        The engine holds none of your data. Your policy is a few plain lines, with defaults you can change.

        The engine

        The npm package. Code only.

        • Knows no paths, no projects, no repos. just leak-check keeps it that way.
        • Every release since 0.1.0 is built and published by the repo's GitHub workflow, never from a laptop, and carries a signed provenance record anyone can check.
        • Installed through mise, it waits out the same release-age gate as every other tool.

        Your instance

        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.
        • Best kept in a private Git repo: a history, Renovate for your toolchain, and a second Mac in minutes.
        • steward config sync keeps this Mac and GitHub level, fast-forward only, with a plan and a yes.
        • Receipts and backups live outside any repo, in ~/.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

        The horizon

        What ships today, lit. What is charted next, in outline.

        macOS Homebrew · mise · App Store apps · trust stores · Docker shipping now · 0.10.1 Linux apt · dnf · zypper · pacman portage · slackpkg · apk · xbps planned · first Windows 11 + WSL winget · Scoop · Chocolatey planned · second NixOS a dated update of the flake planned · third

        Shipping now

        • ✓A pilot in Claude Code: a skill for each area, and /steward:fix to work the list. It speaks first, once, when something needs you, and asks before anything changes.
        • ✓One next step, steward, and one weekly list, steward review, including what the release-age gate holds back and when it clears.
        • ✓Standing orders: every step labelled with who takes it, your [autonomy] level for what runs unattended, and steward fix to work through it.
        • ✓Eight everyday commands, and one yes for each routine job: upgrade, ai fix, projects apply, fleet tidy.
        • ✓The supply chain of a Mac: mise tools and mise itself, global npm tools, Homebrew formulae and casks, apps and their bundled runtimes, the App Store, macOS, trust stores, Docker images, indicators of compromise.
        • ✓The gate, the soak and the way back: a 3-day release-age gate with the advisory exception, old installs kept 3 days, steward rollback.
        • ✓Same-day Node security releases through steward sc node-patch: checksummed, byte-checked, with the previous Node kept.
        • ✓AI tooling add-on: Ruflo, AgentDB, AQE, Brain and RuVector. Drift checks, repinning, and guards that keep self-updates and daemons off.
        • ✓Projects add-on: scan, decide, onboard, reconcile and offboard, with a registry of your decisions.
        • ✓Fleet: Renovate patterns, a repo's bot PRs folded into one verified PR, checkouts brought level after merges.
        • ✓Signed build provenance on every release since 0.1.0, and your config kept in step with its repo by steward config sync.

        IX Start

        Cast off

        Four steps aboard. Then ask the pilot, or type one of eight.

        1. Install through mise

          mise use -g npm:workstation-steward@0.10.1

          mise 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'
        2. Check it

          steward version

          Says which release is running and where your config will live.

        3. Set up

          steward init

          Creates 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.

        4. Take a first look. None of these change anything.

          steward doctor
          steward

          What this machine still needs; then the one next step, and the eight everyday commands under it.

        The eight, for when you'd rather type

        • stewardthe one next step, or that nothing needs you
        • steward reviewweekly: everything waiting on a decision
        • steward fixwork the list under your standing orders
        • steward upgradetools past the gate; shows the plan, asks once
        • steward config syncyour config repo level with GitHub
        • steward projectswhat is new or gone; --apply asks each decision
        • steward rollbackundo the last upgrade or Node patch
        • steward doctorfirst run, or when something seems off

        steward help --all lists the rest, by area. Old names keep working.

        Bring the pilot aboard

        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.

        what needs updating on this Mac?
        Running the read-only checks first.steward sc audit · steward sc plan
        Two things passed the gate: gh 2.103.1 → 2.103.2 and cloudflared 2026.10.5. Python 3.15.2 is 2 days old, so it holds until tomorrow. Postgres 18 is a major, so that is your call. Want me to upgrade the two that are ready? I will show the plan and wait for your yes.
        yes, the two
        Done, with a backup first and a receipt. Way back: steward rollback
        steward skills install

        Run it in your own terminal, not inside a Claude Code session: Claude Code accepts a plugin's command only from a person.

        Check that a release is genuine

        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
        What you are promising yourself

        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.