← Back to Projects

leptons1618@anishgiri.dev:~/case-studies/agent-workbench less writeup.md

DevTools2026 August 20, 2026 3 min read

Agent Workbench

Agent skills come from other people's repositories. This one pins every single one to a commit it has actually read.

published
August 20, 2026
read
3 min
stack
5 tools
outcomes
5
media
—

01The Problem

An agent skill is a folder of instructions in somebody else's repository, installed by name. Install it by name twice a month apart and you get two different things, because the name is a moving pointer — and nothing tells you it moved. A skill that quietly changed its instructions is worse than one that broke: the bootstrap succeeds, the environment is different, and the first symptom is an agent behaving oddly on a project three days later.

02The Solution

Every external source is pinned in `manifest/sources.yaml` to the exact commit SHA that was reviewed, next to its repository URL and package id. Installs go through `npx skills add <owner>/<repo>@<sha>`, printed rather than executed silently, so what lands is auditable before it lands. A git fallback copies the same pinned folders into an isolated directory for reading, and nothing in either path writes to an upstream repository.

The thing a version number was supposed to solve

Package managers settled this argument decades ago. You do not depend on “the latest lodash”; you depend on a version, and a lockfile records the exact bytes that version resolved to. Nobody finds this controversial.

Agent skills arrived without any of it. A skill is a folder of markdown in somebody else’s repository, and you install it by name from the default branch. That is a moving pointer, and it moves without telling you — a wording change in an instruction file is a semantic change to how an agent behaves, and it reaches you on the next install with no version bump, no changelog, and no diff you were shown.

The failure mode is the quiet one. An install that breaks is fine; you notice immediately and you fix it. An install that succeeds against different instructions gives you an environment that is subtly not the one you tested, and the first symptom is an agent making a decision you did not expect on a project three days later.

The manifest is the whole idea

manifest/sources.yaml holds one entry per external source, and each entry carries three fields:

  • repository — the GitHub URL it comes from
  • ref — the exact commit SHA that was reviewed for this workbench
  • npx_package — the package id the skills CLI uses

That is provenance in a file, rather than provenance in the shell history of whoever set the machine up. The ref is the load-bearing part: it is not “the version tag they published”, it is the commit somebody actually read. A pin you have not read is a pin against an unknown, which buys reproducibility without buying trust.

Printing the command instead of running it

The install path looks like this:

npx skills add anthropics/skills@f17010c9bb483898c1d9c9f42dde2b3a98889434 \
  --skill doc-coauthoring mcp-builder theme-factory \
  -g -y

The workbench does not execute that for you. npm run print-install:core prints it, and so does python scripts/print_install.py --profile full. You read the SHA, you paste the line.

That looks like a missing feature and it is the opposite. The value of a pin is that a human can see it; a bootstrap script that resolves and runs pins silently has re-created the problem one layer down, because now the moving part is the script. Printing keeps the audit at the surface where somebody will actually look at it.

Profiles exist because not every machine wants every skill — core is the recommended start, frontend and full widen it — and a profile is a named list of pins rather than a different install mechanism.

Two paths, for two different questions

npx skills is the primary path. Skills land in ~/.agents/skills globally, which is where the agent looks, and the CLI handles the fetch.

The git fallback answers a different question: what is actually in this skill? It copies the pinned folders into a directory you choose — a temp path, an isolated audit directory — using the Python module:

python -m workbench --skills-dir "$TMP/awb-skills" install --profile core --method git

Same pins, no global install, nothing to uninstall afterwards. --dry-run goes one step further and validates the manifest without writing anything at all, which is the thing to run after editing a pin and before trusting it.

What it deliberately does not do

It never writes to an upstream skill repository. Not a fork, not a patch, not a local commit. The moment the workbench starts editing a skill it has installed, the SHA in the manifest stops describing what is on the machine, and the pin becomes decoration. If a skill needs changing, that is a change to make upstream or an overlay to keep separately — not a mutation of something a hash is supposed to identify.

It does not try to resolve conflicts between skills. Two skills with overlapping advice are a judgement call about which one you want, and a tool that picked for you would be making that call invisibly.

What it is actually for

The honest framing: this is a lockfile and a review log for a dependency type that does not have either yet. The engineering in it is small — a YAML file, a printer, two install methods, a validator. The part that matters is the discipline it makes cheap, which is knowing exactly which words an agent was given, and being able to prove it six months later.

03Achievements

  1. Skill sources are pinned by commit SHA, so a bootstrap run today and one in six months install byte-identical instructions.
  2. `manifest/sources.yaml` records repository, reviewed ref, and package id for each source — provenance in one file rather than in a shell script's history.
  3. Install profiles (core, frontend, full) print the exact pinned commands, so the operator sees what will run before it runs.
  4. A git-based fallback installs into an isolated directory for auditing, with `--dry-run` to validate the manifest and change nothing.
  5. Cross-platform bootstrap — a Python module and a PowerShell script — with no step that modifies an upstream skill repository.

04Stack

PythonNode.jsShellPowerShellYAML