Apache-2.0 GitHub ↗

sherpa

Guides for building and shipping real software with a coding agent.

pluginharness 0.1.1 licenseApache-2.0 skills5 forClaude Code
install
>/plugin marketplace add brij-coda/sherpacopy
>/plugin install harness@sherpacopy

##harness

Most people struggling with a coding agent are not struggling with the model. They are struggling because nothing in the loop can tell the difference between done and claimed done.

harness closes that gap. The agent has to prove its own checks actually work before it trusts them, and it cannot ship to production without asking you first. It came out of shipping several products with an agent, and every rule in it was learned by something going wrong first.

Things you have probably said out loud

If you cannot read the diff yourself, you are relying entirely on the agent being straight with you about what it did. These are the moments where that breaks.

“It said it was done, and it wasn't.” The agent has to open what it made and look at it, not just run the tests and report green. No test catches an output that is wrong in a way you would spot in one second.
“It deployed and nothing actually changed.” Usually a cached build, or a setting that needed a rebuild rather than a redeploy. It now confirms the deploy really landed instead of trusting the dashboard.
“It quietly did less than I asked.” Cutting scope is your call and not the agent's. If part of the work got dropped it has to tell you which part and why, rather than handing back something smaller and calling it finished.
“It changed production without asking me.” It cannot merge without you giving an explicit go and naming the version. An approval you gave for one thing does not carry over to a bigger thing that arrived while you were answering.
“It keeps asking me for another password or key.” Every account, key and login the project needs gets worked out before any code is written and asked for in one message, instead of surfacing one at a time over four days.
“The tests were green and the thing was obviously broken.” Green tests have sat happily alongside a PDF with overlapping labels, a report that contradicted itself, and a settings screen whose switches saved and did nothing. So once per phase it has to look at the real thing.
“It keeps making the same mistake.” Anything that costs more than ten minutes gets written into the project's own rules in that same session, so the next mistake is at least a new one.

What it adds

Five skills, and they load when the work matches rather than all at once.

prda brief arrives Seven artefacts before any code. Invariants, tenancy, auth, providers, skills, surfaces and open questions. The first four cannot be retrofitted.
phasea build phase starts A fixed order. Migration, data layer, service, route, surface, then gates, and it ends green and committed.
gatea check is written Prove the gate can fail before you trust it. Then verify by reading the output, and not only by running tests.
shipa production release Never merge without an explicit go and a stated version. Migration before code. Confirm the deploy actually landed.
diagnosesomething is inexplicable Symptom → cause, for the failures that look like successes.

The idea in one line

You don't know a check works until you have seen it fail.

Four separate checks in the source project shipped green while checking nothing. One compiled zero files, one walked only an entrypoint's imports, one silently stopped comparing because it never stripped ANSI codes, and one matched a renamed export and passed with an empty list. Each of them was believed for weeks. So the first thing the gate skill tells you to do is plant the exact error the gate exists to catch and watch it fail.

The same goes for a fix. Do not call it done because you applied it. Re-run the check, and when it comes back empty then it is done.

##The working skeleton

The rules are only half of it. HARNESS.md also carries a project skeleton that runs, and one command writes the whole thing. It is generated from a tree that passed both gates and every gate-proof, so it is the code that actually worked rather than a description of it.

one command
$bash scaffold.sh . && ./bootstrap.sh --name acme --domain acme.com
wrote 58 files · placeholders substituted · lockfiles in place
58files written
2gates, both proven
0hand-built boilerplate

backend

src/auth.ts
src/data/tenant-scope.ts
src/data/index.ts
src/services/agent-runtime.ts
src/db/schema.ts
src/routes/auth · google · tenants
migrations/001 · 002
vercel/handler.ts

the gates

scripts/prove-gates.sh
scripts/typecheck.py
scripts/scope-check.py
scripts/typecheck-baseline.txt
frontend/scripts/typecheck.mjs
scripts/migrate.ts
e2e/tests/smoke.spec.ts

frontend & shared

src/pages/Home · Login · Settings
src/components/Pit.tsx
src/components/GoogleSignInButton.tsx
src/lib/api.ts
shared/types/auth · tenant · agent-run
shared/version.ts
CLAUDE.md

The marked files are the ones that cannot be retrofitted later. Tenancy and provenance touch every table written after them, and the agent loop decides what a skill is even allowed to do.

The phase order it expects

0
Skeleton
your auth flow works, deployed
1
Substrate
tenancy, provenance, scope gate proven to fail
2
Intake
a real input parses, honestly
3
Reference
first invariant in a constraint
4
Judgement
one model call, where it is needed
5
Output
the artifact, deterministic
6
Instrument
the measure of whether it works

Phase 1 is the one people skip and the only one that cannot be added later. Phase 6 is the one people cut, and then nobody can say whether the thing works.

##Gates that prove themselves

The skeleton ships with a script that plants the exact error each gate exists to catch and confirms every one goes red. Run it when you write a gate, and again after you touch one.

deno task prove-gates
── proving the gates fail ──────────────────────────
type gate, on a file nothing imports ✓ failed, as it must
…and it refuses to baseline it ✓ failed, as it must
scope gate, tenant table outside data/ ✓ failed, as it must
scope gate, on a renamed export ✓ failed, as it must
frontend gate, real component error ✓ failed, as it must
✅ all 5 gates fail on the error they exist to catch

If one of them passes, the script says ✗ PASSED — the gate is decoration and tells you to fix it before you trust a green build.


HARNESS.md

The plugin ships with HARNESS.md, which is the full source document the skills are derived from. It is long and that is deliberate, because the skills are the rules and HARNESS.md is why, with the failure behind each one.

On the stack

HARNESS.md commits to a specific stack and that is deliberate, because every trap in it is mapped for that exact combination, which is what makes a runbook worth anything.

The protocol does not depend on it. The seven artefacts, the phase order, proving gates, the ship discipline and the symptom table all work anywhere. Read the stack sections as a worked example of what a mature rule set looks like once somebody has paid for it, and not as a requirement.

Make it yours

The rules here are ones somebody else earned. You will respect the ones you earn yourself far more, so the most important habit in the whole document is also the smallest one.

Anything that cost more than ten minutes goes into your standing rules in the same session.

Every trap in HARNESS.md was learned twice, because it was not written down the first time.


##Contributing

The most useful thing you can send is something that looked like it worked and didn't.

Every rule here was learned by something going wrong first, and a rule with no failure behind it is just a preference, which is what people delete when they are in a hurry. So symptom → cause entries are the contributions that make this better.

There is an issue template with three fields, which are the symptom, the cause, and how you found it. The third one matters most, because how you found it is reusable even when the specific bug is not.

##License

Apache-2.0. Permissive, so use it, fork it, and adapt it commercially. Keep the attribution, and if you modify and redistribute it then say what you changed.