TAI BUI
Back to curriculum
BuildPython

Capstone: Ship a Reusable Agent Workbench Pack

The mini-track ends with a directory you can drop into any repo. Eleven lessons of surfaces, compressed into something you `cp -r` so an agent is working reliably the next morning. This is the artifact the curriculum trades on.

TIME: ~75 minutesPREREQUISITES: Phases 14 · 31 to 14 · 41

Learning Objectives

  • Package the seven workbench surfaces into one drop-in directory.
  • Pin the schemas, scripts, and templates so a new repo gets a known-good baseline.
  • Add a single installer script that lays down the pack idempotently.
  • Decide what stays in the pack and what stays out, defending the cut for each.

The Problem

A workbench pack is a versioned directory that holds the seven surfaces (init script, scope contract, state, feedback runner, verification gate, reviewer, and handoff, built in Lessons 34 to 40 and listed in Lesson 41), the schemas, the scripts, and a one-command installer. Without one, the workbench lives in a Google Doc, a chat history, and three half-remembered scripts, and it gets rebuilt every quarter.

You will end this lesson with outputs/agent-workbench-pack/ shipped on disk and a bin/install.sh that drops it into any target repo.

Warm-up0/3
1. Seven workbench surfaces exist as separate scripts, schemas, and docs, and each team copies them by hand into new repos. What goes wrong first?Warm-up
2. A release renames a required field that existing JSON state files already use. Under semantic versioning, which bump does that change need?Warm-up
3. An install script gets run twice on the same repo by accident. What should a well-built installer do?Warm-up
Check: The Problem0/1
1. What is a workbench pack?Define

The Concept

Mermaid diagram

The pack layout

outputs/agent-workbench-pack/
├── AGENTS.md
├── docs/
│   ├── agent-rules.md
│   ├── reliability-policy.md
│   ├── handoff-protocol.md
│   └── reviewer-rubric.md
├── schemas/
│   ├── agent_state.schema.json
│   ├── task_board.schema.json
│   └── scope_contract.schema.json
├── scripts/
│   ├── init_agent.py
│   ├── run_with_feedback.py
│   ├── verify_agent.py
│   └── generate_handoff.py
├── bin/
│   └── install.sh
└── README.md

What stays in, what stays out

In:

  • Surface schemas. They are the contract.
  • The four scripts above. They are the runtime.
  • The four docs. They are the rules and the rubric.

Out:

  • Project-specific tasks. Those belong on the target repo's board, not in the pack.
  • Vendor SDK calls. The pack is framework-agnostic.
  • Onboarding prose. The pack sits next to the team's existing onboarding, not inside it.

The installer

A short bin/install.sh (or bin/install.py) does four things:

  1. Refuses to install over an existing pack without --force.
  2. Copies the pack into the target repo.
  3. Wires up CI if a .github/workflows/ exists.
  4. Prints next steps: fill in the board, set acceptance commands, run the init script.

Versioning

The pack carries a VERSION file. A schema bump, or a script change that requires a migration, bumps the major. A change that only needs the checker re-run bumps the minor. A doc-only change bumps the patch. The target repo's agent_state.json records which pack version it was initialized against.

Check: The Concept0/16
1. What is the installer in a workbench pack?Define
2. What is a pack version?Define
3. What stays OUT of the pack?Define
4. Why are the surface schemas in the pack's In list?Explain
5. Why do vendor SDK calls stay out of the pack?Explain
6. Why does onboarding prose stay out of the pack?Explain
7. What does the installer do when a pack already exists in the target repo, and what else does it wire up?Explain
8. Why does the pack carry a VERSION file?Explain
9. A teammate fixes a typo in docs/reviewer-rubric.md and nothing else changes. Which bump does the pack need?Apply
10. A change to scripts/verify_agent.py means target repos must re-run the checker, but no state files need migrating. Which bump fits?Apply
11. install.sh runs, without --force, in a repo that has a .github/workflows/ directory and no existing pack. What happens?Apply
12. The installer has just finished on a fresh repo. Which set matches the next steps it prints?Apply
13. Counting the pack layout as drawn, how many files sit directly inside docs/ and schemas/ combined?Apply
14. A release renames a field in scope_contract.schema.json but ships with only a minor bump. Repos that upgrade find their existing scope files rejected. What went wrong?Analyze
15. Repos installed from a pack all show a board task named 'migrate billing service', which means nothing to them. What was wrong with the pack?Analyze
16. A team asks you to add calls to one vendor's hosted eval API inside verify_agent.py. Which response keeps the pack's design?Design

Build It

code/main.py assembles the pack into outputs/agent-workbench-pack/ next to the lesson. It seeds the pack with the schemas and scripts from the previous lessons in this mini-track, plus the docs you already wrote.

Run it:

python3 code/main.py

The script copies and pins the surfaces, writes the README, prints the pack tree, and exits zero. Re-running is idempotent.

Check: Build It0/1
1. You run python3 code/main.py twice in a row. What should the second run do?Apply

Production patterns in the wild

A pack is only valuable if it survives forks, updates, and an unfriendly upstream. Four patterns make that work. The layout above is the minimal pack. A full version also ships VERSION, lint_pack.py, and uninstall.sh (Exercises 3 and 4 have you build the last two), and the installer writes .workbench-version into the target repo.

VERSION is the contract, not the marketing. Major bumps require a state migration. Minor bumps require a checker re-run. Patch bumps are doc-only. The installer writes .workbench-version into the target repo on every install, and lint_pack.py refuses to ship if the target's lock disagrees with the pack's VERSION. That is how npm, Cargo, and pyproject.toml survive 10 years of churn. Agents don't change the rules.

One source, every tool. Nx ships a single nx ai-setup that lays down AGENTS.md, CLAUDE.md, .cursor/rules/, .github/copilot-instructions.md, and an MCP server from one config. The pack should do the same. The installer emits the symlinks (ln -s AGENTS.md CLAUDE.md), so a single source of truth fans out to every coding agent. Forking the pack to support one tool over another is a failure mode.

An uninstall.sh that refuses on non-trivial state. Uninstalling must not delete the user's agent_state.json, task_board.json, or outputs/. The uninstaller removes the schemas, scripts, docs, and AGENTS.md (with a --keep-agents-md opt-out), and it refuses to proceed if any state file has uncommitted changes. State belongs to the user; the pack does not own it.

Publish it as a skill. The pack ships as a SkillKit skill: skillkit install agent-workbench-pack lays it down across 32 AI agents from a single source. The pack repo is the source of truth and SkillKit is the distribution channel. Vendor lock-in collapses, and the seven surfaces stay the same.

Check: Production patterns in the wild0/7
1. Why does the installer write .workbench-version into the target repo on every install?Explain
2. How does the pack get one set of rules to every coding agent?Explain
3. Which distribution channel lays the pack down across 32 AI agents from a single source repo?Explain
4. A teammate runs uninstall.sh in a repo where task_board.json has uncommitted edits. What should the uninstaller do?Apply
5. A team forks the pack to keep a hand-edited Claude rules file and a hand-edited Copilot rules file. Months later the two disagree. Which pattern did they skip?Analyze
6. A team uses three coding agents and wants one set of rules to cover all three, updated in one place. Which design fits the pack?Design
7. You maintain the pack for 50 repos and want upgrades to be safe and auditable. Which combination from the lesson fits?Design

Use It

The pack ships three ways:

  • As a directory you drop into a repo. cp -r outputs/agent-workbench-pack /path/to/repo.
  • As a public template repo. Fork and customize, with VERSION controlling drift.
  • As a SkillKit skill. Wired into your agent product so a single command lays it down.

The pack is the recipe. Each install is a serving.

Check: Use It0/3
1. What does it mean for a pack to be a drop-in pack?Define
2. What is a forkable template?Define
3. Besides a SkillKit skill, which two other forms does the lesson name for shipping the pack?Define

Ship It

outputs/skill-workbench-pack.md generates a project-tuned pack: rules sharpened to the team's history, scope globs matched to the repo, and the rubric extended with one domain-specific dimension.

Author's Note

My bet is that a pack gets judged on what it refuses to touch. I treat the out list as the design: tasks stay on the target repo's board, vendor SDK calls stay out, and the uninstaller leaves agent_state.json, task_board.json, and outputs/ alone. State belongs to the user; the pack does not own it, so I'd make the uninstaller refuse before it would ever guess. Keeping vendor SDK calls out is what keeps the pack framework-agnostic. Everything on the out list is a line I'd hold.

Exercises

  1. Decide which optional fifth doc deserves promotion into the canonical pack. Defend the cut.
  2. Rewrite the installer as Python with a --dry-run flag. Compare its ergonomics against bash.
  3. Add a bin/uninstall.sh that safely removes the pack and refuses if state files have non-trivial history. What counts as non-trivial?
  4. Add a lint_pack.py that fails when the pack drifts from VERSION. Wire it into CI for the pack's own repo.
  5. Author the migration runbook from a hand-rolled workbench to this pack. Which order of operations minimizes downtime?

Key Terms

TermWhat people sayWhat it actually means
Workbench pack"The starter kit"A versioned directory carrying all seven surfaces
Installer"Setup script"bin/install.sh that lays the pack down idempotently
Pack version"VERSION"Major bumps for schema/script changes, minor for checker re-runs, patch for doc-only
Drop-in pack"cp -r and go"Pack works without per-repo customization on day one
Forkable template"GitHub template"Public repo that GitHub's "Use this template" can clone from

Further Reading

Code

Ships With