Reading time:
How we customised Superpowers without forking it
Layering enterprise conventions onto an agentic development methodology you don’t own

Article written by
Ali Tavakoli
‘Superpowers’ is a plugin that installs a set of process skills: brainstorming, writing plans, test-driven development, verification, and so on. When a request comes in, it routes to whichever skill matches the work. That routing is what we attach to.
We started using Superpowers, but we needed it to do a few things it doesn't do on its own. We wanted it to produce our documentation in our format, traceable to our test IDs, and respecting our library boundaries.
Instead of forking it, we hooked into it. All our customizations live in files we own. Superpowers updates on its own, and we pull those updates in.
Why Superpowers, and not the others?
We could have built this on BMAD-METHOD or GSD. Both are serious projects, and either could have worked. We picked Superpowers for two reasons, and popularity wasn't one of them.
First, it was easier to grasp. You can read it in one sitting and hold the whole lifecycle in your head. That helps because every decision in this article is about where to attach something, and that's hard to do if you don't have a clear picture of what you're attaching to.
Second, it doesn't have strong opinions about architecture. We already had our own: enforced library boundaries, versioned shared code, one canonical example per library type. We needed a methodology that would carry those instead of fighting them.
If you already have an architecture, pick the methodology that brings the least of its own. If you don't, a more opinionated one may suit you better, because it makes decisions you'd otherwise have to make yourself.
Why does layering beat forking?
First, these projects update often. They're all recent and under active development, so their skills and structure keep changing. If you fork one, every edit you make can turn into a merge conflict later. The alternative is to stop pulling updates, but then you're stuck maintaining an old copy of a project that's still moving.
This isn't unique to agentic tooling. It's the normal cost of forking any dependency that's still being worked on.
Second, Superpowers already gives you a way to override its behavior without forking. It sets a clear order of precedence: your instructions come first, then skills, then default behavior. It also tells you to put project-specific conventions in your root instruction file instead of editing its files directly.
So the place to customize is already built in and documented. You don't need a workaround.
Our rule is simple: never modify Superpowers' own files. Everything we customize goes in three places we control: our AGENTS.md, our documentation folder, and our own skills.
Why we layer instead of fork
Superpowers updates independently, so edits to its files are lost. It already ranks user instructions above skills, and routes project conventions to the instruction file. So that file plus our own skills is the sanctioned channel.
Revisit if it stops honouring that precedence, or stops routing project conventions to the instruction file.
We add a note like this to every architectural decision in our workspace. It takes one sentence, and it turns "why is this like this?" into something you can just look up.
Anchor on moments, not names
To insert steps you need attachment points: before this happens, do that. The natural way to write one names the Superpowers skill. “Before writing-plans runs, write our specs.”
But those names belong to someone else, and any release can rename, split, merge, or replace them. So we treat every name we reference as a marker for something more durable, never the thing itself. Two places do this:
An attachment point’s name marks a lifecycle moment. “Before we finish this branch” stays a real moment whatever the skill is called.
Our own routing marks a kind of work, i.e., design work, a defect, or neither. We run one workflow for each, and each attaches our steps at different moments. The work stays that way whatever the skill is called, and the replacing skill’s own description will say so.
Note! Sometimes the kind of work is genuinely ambiguous. “This feature is wrong” can mean we changed our minds (design work) or it never matched its spec (a defect). Rather than letting it fall either way, we ask. The tell: do you already know what the new behaviour should be, or must you first find out why the current behaviour happens?

Then the rule for when a named skill isn’t there:
The thing it marked still governs. Run the step at that moment, and say that you did, and why.
Never silently skip it, and never silently substitute a similar-looking skill. Work done at the wrong moment looks like it worked, which is worse than not running at all.
Check, don’t guess. Which skills exist is observable: the available-skills listing, the plugin cache on disk. So is what each one is for: its own description.
The rule exists because we got it wrong. We anchored our documentation-verification step to Superpowers’ verification-before-completion skill, which sounded like the right home for “check the docs match what shipped”. That skill turned out to be invoked by systematic-debugging, the bug-fixing path. On the feature-building path it never fired. Our step didn’t run for weeks, and nothing reported a problem, because a step that never fires produces no errors.
That also taught us about granularity. We now attach only before or after a whole skill, never before or after a step inside one. A skill-level anchor breaks only if someone renames the skill or stops invoking it, and both are observable. A step-level anchor breaks on a reworded or renumbered step, detectable only by matching prose inside a file you don’t own. Same bug, much harder to find.
Make the layering checkable
Everything above is a set of references: a hook hanging off a skill name, a rule citing another file, a pointer with an anchor in it. Everyone breaks silently, because the sentence still reads correctly afterwards. Review does not catch that, so three things do.
Pin the version, and separately record what you reviewed against. The pin says which commit gets installed; a small baseline file says which commit our workflow was last read against. When those part company, installs still match the pin faithfully, nothing fails, and “reviewed” quietly stops describing what runs. No other signal can see that gap, so it gets its own check.
Run a checker over the prose surfaces. Ours has fifteen rules and takes seconds: a cited hook ID with no matching heading, a dead file path, an anchor no heading yields, a hook anchored to a skill that is not installed, a skill whose registry stub has drifted, one workflow file citing another. Every rule but one guards a failure that actually happened here.
Let the harness remind you. Editing one of these files triggers a pointer to the procedure, finishing the edit runs the checker, and a version change surfaces at session start. None of that decides anything. It just means noticing is not left to memory.
The limit matters, because a green run is easy to over-trust: it means no reference is broken, never that the change is correct. A hook attached to the wrong lifecycle moment passes every rule, as does a gate asking the wrong question, or a rule that contradicts another in plain English. Those need a human, or a scenario run against the changed docs.
Ali Tavakoli

Article written by
Ali Tavakoli



