Changelog¶
For the full commit history, see github.com/ZunoSmartLabs/zsl-superpowers/commits/main. This page summarises the user-facing changes per plugin version.
2.2.0¶
Every PRD now opens with a high-level architecture diagram in ASCII.
/to-prd gained a new first section — Architecture Overview — above the
Problem Statement. After sketching the major modules (existing process step 2),
the skill now draws them as a labelled ASCII box-and-arrow map of the major
components and the external systems they talk to, fenced in a plain ``` block so
it survives copy/paste into the issue tracker. It's a map, not a wiring diagram:
the dozen-or-so boxes that orient a reader, with per-module internals left to the
Implementation Decisions section. No migration steps — existing PRDs are
unaffected; only newly generated ones carry the diagram.
2.1.0¶
Sharpen the /commit skill in two ways.
Model-invocable. /commit no longer carries disable-model-invocation: true,
so it can fire on a task match as well as on an explicit /commit — and, more
importantly, orchestrators that already delegate to it (commit-push-pr,
tdd-parallel) can now compose it legitimately. Under the taxonomy's composition
rule (a user-invoked skill may call a model-invoked one, never another
orchestrator) that delegation was previously a latent violation; this resolves it.
Opinionated branch routing. On PR-ship-style repos, /commit now decides
where a commit lands instead of refusing on main:
- a commit whose files are all documentation (
docs/**, narrative*.md) or under.scratch/commits straight tomain; - a commit that touches code — source, scripts, a
SKILL.md, or a sync/build manifest (plugin.json,marketplace.json,mkdocs.yml,Makefile) — is moved onto a feature branch the skill creates itself, then commits there; - a mixed docs+code commit counts as code and goes to the branch whole.
Upgrading from 2.0¶
/commitcan now auto-fire when Claude judges the task calls for committing — it is no longer summon-only. If you relied on it never triggering on its own, invoke it only explicitly and review the staged set as before.- On
main,/commitno longer refuses code changes — it silently creates a feature branch and commits there. Documentation and.scratch/changes still land directly onmain. The branch name follows the usual prefix convention.
2.0.0¶
Adopt a lightweight User-invoked / Model-invoked skill taxonomy, use it to
deduplicate shared guidance into composable skills, add three new user-invoked
skills to the loop, and remove/rename three commands. Net skill inventory:
32 skills (six added, write-a-skill renamed, two removed). The split is
documented in the invocation model and recorded in
ADR 0001.
The taxonomy¶
Every skill is now either user-invoked (only runs when typed — the
orchestrators, flagged disable-model-invocation: true) or model-invoked
(can also auto-fire when the task fits). The rule: a user-invoked skill may invoke
model-invoked skills, but never another user-invoked skill. Model-invoked-only
skills get a lighter sync treatment (registered in plugin.json + a "Shared /
model-invoked" doc subsection, omitted from the decision tree and command lists) —
a sixth lane in the CLAUDE.md skill-sync contract.
Six new skills¶
Three model-invoked skills extract guidance that used to be duplicated inline and drift across skills:
codebase-design— the deep-module design language (module / interface / depth / seam / adapter, the deletion test, the one-adapter-hypothetical / two-adapters-real refinement, interface-for-testability, "design it twice"). Composed byimprove-codebase-architectureandtdd, which no longer carry their own copies.domain-modeling— theCONTEXT.mdUbiquitous Language format, the ADR format, and the bundled Domain-Driven Design book-rules. Composed bygrill-with-docsandimprove-codebase-architecture.grilling— the design-tree interview protocol (status markers, example tree, reprint rules, status-lifecycle diagram). Composed bygrill-meandgrill-with-docs, now thin composers over it.
Three user-invoked skills join the loop:
decision-mapping(Plan) — turn a loose, multi-session idea into a sequenced map of decisions + ticket-sized slices under.scratch/decision-maps/before it becomes a PRD; composesgrilling/domain-modeling/prototype, hands off toto-prd. Local and interactive (not AFK-wired).teach-me-the-codebase— on-the-fly conversational tutor for an unfamiliar repo; readsCONTEXT.md/ADRs/CLAUDE.md/code and teaches the domain, architecture, and conventions. Zero persisted artefacts; hands doc gaps togrill-with-docs; optionalmd-to-htmlcheat-sheet on demand.ask-zsl— a thin interactive router that points you at the right skill mid-session, deferring each skill's description to its own page. Paired with the "Which skill do I want?" decision tree.
Removals and renames¶
write-a-skill→writing-great-skills. The old process skill is replaced by a principles + vocabulary reference (SKILL.md+GLOSSARY.md). The description-length deterministic gate (check-description-length.py+ its tests) travels with it; themake lint/make testtargets are repointed.cavemanremoved. The ultra-compressed reply mode is gone from every surface.zoom-outremoved. The higher-level-framing skill is gone from every surface.
Upgrading from 1.4¶
These are breaking command changes — three public slash commands changed:
/cavemanis gone. It no longer resolves. There's no replacement; drop it from any scripts, aliases, or muscle memory./zoom-outis gone. It no longer resolves. For higher-level framing of unfamiliar code, reach for/teach-me-the-codebase(interactive onboarding) or/improve-codebase-architecture(architectural deepening) instead./write-a-skillis now/writing-great-skills. Same deterministic description-length gate, new name and a sharper principles/vocabulary framing. Update any references; the old command no longer resolves.
No data migration is needed — these are command surfaces, not stored state. After updating, restart Claude Code so the new skill inventory loads.
1.5.0¶
Dropped the acceptance: automatable tag from PRD user stories¶
Since 1.4.0 every PRD user story carried both an acceptance:
automatable tag and at least one AC<n>: acceptance criterion. With
the manual-attestation lane already removed from the pipeline, the tag
had exactly one legal value — automatable — on every story. A field
that can only ever hold one value carries no signal: the AC<n>:
criterion is what makes a story expressible as a test, and /zsl:to-prd
already refuses to draft a story that has no automatable criterion. The
tag was ceremony, re-described in lockstep prose across five skills and
the docs, with nothing reading its value.
/zsl:to-prd no longer writes the tag. The pipeline invariant is now
simply every in-scope story carries at least one AC<n>: acceptance
criterion — /zsl:tdd-parallel's pre-flight (1d),
/zsl:verify-coverage's pre-flight, and /zsl:triage's PRD check all
key off criterion presence instead of the tag. The semantic guard ("is
this story automatable?") stays exactly where it was load-bearing:
/zsl:to-prd's refuse-to-draft gate at authoring time. /zsl:to-issues
no longer propagates the tag into slice bodies (it still carries the
AC<n>: criteria verbatim).
Upgrading from 1.4¶
No action needed. Existing PRDs that still carry acceptance: automatable
lines continue to pass every gate — a leftover tag is now simply ignored,
not rejected. Every story that was valid under 1.4 (tag + AC<n>:)
remains valid under 1.5 (AC<n>: alone), so no PRD needs re-authoring.
Legacy observable: sub-bullets still count as one acceptance criterion,
unchanged.
/zsl:setup-zsl-superpowers project-board fixes + a hybrid tracker¶
A batch of fixes and one new capability for /zsl:setup-zsl-superpowers,
all surfaced while wiring a real board onto a local-markdown repo:
- Fixed a broken Section E mutation. The "replace Status options"
step passed a
projectIdargument that the current GitHub GraphQL schema rejects (UpdateProjectV2FieldInput doesn't accept argument 'projectId'), so creating a fresh board's canonical columns failed mid-setup. The mutation now usesfieldId+singleSelectOptionsonly, and is bundled as a tested deterministic-gate script (set-status-options.sh) whose test asserts theprojectIdregression can't return. - New "Hybrid (local markdown + GitHub mirror)" issue tracker. A
Projects v2 board can only track GitHub-native objects, so plain
local-markdown issues can't appear on one. The hybrid keeps
.scratch/as the source of truth and mirrors each issue to a thin linked GitHub issue purely so it lands on the board. Newissue-tracker-hybrid.mdseed;/zsl:triageand/zsl:tddresolve the mirror issue number from the.scratch/file'sgithub:frontmatter before any board update. - Surfaced the tracker ↔ board coupling. Sections A and E now state outright that a board needs a GitHub-native tracker, and that a local-markdown user who wants a board should pick the hybrid rather than have Section E silently skipped.
- Pull-request reference guard.
/zsl:to-issuesand/zsl:triagenow confirm before acting when a bare number resolves to a PR (GitHub shares one number space), instead of trying to slice or triage a shipped release PR.
Upgrading from 1.4¶
No action needed. Existing setups are unaffected; the fixes apply the
next time you run /zsl:setup-zsl-superpowers or its board sync.
1.4.0¶
PRD user stories split into value-level stories + AC acceptance criteria¶
PRDs written by /zsl:to-prd used to pin each user story to a single
observable: sub-bullet — a concrete, technical, public-interface
assertion. In practice that collapsed two altitudes into one line: the
"stories" read like fine-grained acceptance criteria and leaked
implementation detail (endpoints, status codes, state names), because a
story could only carry one observable, so any capability needing
several assertions got fractured into several "stories."
/zsl:to-prd now writes user stories at value altitude — who, what
capability, why, with no technical detail in the story line — and pushes
every testable assertion down into one or more acceptance criteria
(AC1:, AC2:, …) beneath it. A story keeps its acceptance:
automatable tag and now carries at least one AC<n>: criterion. The
acceptance criteria are the contract /zsl:verify-coverage's Tier B
generates tests against — so a story can hold as many concrete
assertions as it needs without being split, and the story line itself
reads like a story again.
The change runs the length of the pipeline, which reads these sub-bullets as a lockstep contract:
/zsl:to-prddrafts the two-level shape and refuses any story with no automatable acceptance criterion./zsl:to-issuespropagates the parent story'sacceptance:tag andAC<n>:criteria into each slice's## User stories coveredverbatim./zsl:verify-coveragegates onacceptance: automatable+ at least oneAC<n>:criterion, and Tier B generates tests from the story's acceptance criteria (a story is covered when every criterion has a passing, non-vacuous test)./zsl:tdd-parallelpre-flight 1d and/zsl:triageenforce the same gate before handing work to an agent.
Upgrading from 1.3¶
In-flight PRDs authored before this release carry observable:
sub-bullets, not AC<n>: criteria. They keep working: every gate and
the Tier B test-generation hint accept a legacy observable: line as a
single acceptance criterion, so nothing breaks on upgrade. To get the
cleaner two-level shape on an existing PRD, hand-convert each
observable: line into one or more AC<n>: bullets, or re-run
/zsl:to-prd over the original conversation. New PRDs get the AC
shape automatically.
1.3.1¶
/triage: wrap local-markdown comments at 100 chars to satisfy markdownlint¶
/triage wrote its triage notes and disclaimer comments into the local-markdown
tracker as single long lines. Repos that lint their committed markdown with
markdownlint-cli2 enforce MD013 (line-length), so every triage note failed
make lint and needed manual reflowing before it could be committed.
/triage now hard-wraps every comment and triage note it writes to a local-markdown
tracker at ≤100 characters per line — prose only; markdown tables and fenced code
blocks are left intact, since MD013 exempts them and wrapping would break their
rendering. The rule lives in issue-tracker-local.md (next to the ## Comments
convention) with a pointer from the triage skill's disclaimer instruction. Local
markdown only — GitHub Issues, ClickUp, and other non-markdown trackers have no
MD013 and are unaffected.
1.3.0¶
local-markdown tracker: archive folders renamed done/ → _done/¶
The local-markdown issue tracker's two archive folders are renamed so they sort to the top of their parent directory instead of getting lost among the active feature dirs:
- Closed issues now archive to
.scratch/<NNN>-<feature-slug>/issues/_done/(wasissues/done/). - Closed features now archive to
.scratch/_done/<YYYYMMDD>-<NNN>-<feature-slug>/(was.scratch/done/).
Under the default locale (the one macOS Finder and the shell use), the leading
_ sorts ahead of digit-prefixed feature dirs, so the archive sits at the top
where it's easy to find. All skills that git mv into, exclude, or glob the
archive (/zsl:tdd, /zsl:human-itl, /setup-zsl-superpowers backfill, the
feature-number resolver) move in lockstep. Purely a folder-name change — nothing
is deleted, and feature/issue numbering is untouched.
Upgrading from 1.2.x¶
Existing repos still have their archives under the old done/ names; the new
globs won't find them until you rename. The easiest path is to re-run
/zsl:setup-zsl-superpowers — its Section 5
now detects legacy done/ archive folders and offers to git mv them to
_done/ (step 5a, ahead of the existing feature-number backfill). Prefer to do
it by hand? One-time migration, run from the repo root:
# closed features: .scratch/done/ -> .scratch/_done/
[ -d .scratch/done ] && git mv .scratch/done .scratch/_done
# closed issues in every feature (active + archived): issues/done/ -> issues/_done/
for d in $(find .scratch -type d -path '*/issues/done' 2>/dev/null); do
git mv "$d" "${d%/done}/_done"
done
Commit the renames. If you skip this, closed work stays readable on disk but
/zsl:tdd's no-arg discovery and the archive lookups will treat the old done/
folders as if they were active issues.
1.2.1¶
remote-agents loop: fix sourceless routines + guided remote setup¶
- Fix:
/afk-fanoutnow sets the target repo on every scheduled routine. The step-5RemoteTriggercreate body was missingjob_config.ccr.session_context.sources, so each routine fired with no repo to clone and the worker (/afk-worker→/tdd-parallel) had nothing to operate on — the overnight loop was broken for any repo./afk-fanoutnow derives the repo'sorigin(normalized tohttps://github.com/<owner>/<repo>) and emitssession_context.sources. Placement was verified by live API probe:sourcesinsidesession_contextround-trips; a copy at theccrlevel is rejected HTTP 400.outcomesis left unset (it auto-populates as a run output, not a scheduler input). - Added a deterministic-gate script (
resolve-origin-url.sh) that normalizes the origin and fails loudly on a missing/garbled remote, so a sourceless routine can never be scheduled. - Docs fix: environments are repo-agnostic. Corrected the "per-repo Claude
Code environment" language across
/afk-fanout,/setup-zsl-superpowersSection F, and theremote-env.mdseed. One generic environment (e.g. "Full Network + GH + Telegram") is reused across all projects; the repo is selected per-routine viasources. /setup-zsl-superpowersSection F is now a guided walkthrough. Field-by-field UI form (Name / Network / env-vars / setup script) with copy-pasteable values, the previously-missinggh auth setup-gitgit-auth prerequisite, fully-walked Telegram bot + chat-id discovery, automatic env-id discovery viaRemoteTrigger, and a per-repo runtime-cloud-credentials caveat. Theremote-env.mdseed is now a complete operator reference.
Upgrading¶
Any overnight routines scheduled by /afk-fanout before this fix were created
without sources and could not clone a repo — they either failed at run time or
produced nothing. Re-run /afk-fanout to reschedule under the fixed create body.
Leftover disabled/spent triggers from the old runs are cosmetic; clear them in the
claude.ai UI when convenient.
1.1.0¶
Replaces four secretly-deterministic skill steps — places a SKILL.md asked
the model to compute something with exactly one correct answer — with small
bundled scripts, each behind a deterministic gate in its SKILL.md with the
original prose preserved as an explicit fallback. The model copies the script's
output instead of re-deriving it by hand, so the rare hand-derivation slip (a
mis-rounded duration, a silently-truncated description, a missed detached HEAD,
a mis-serialized ledger row) can't happen. Purely additive: if a script can't be
located the gate prints an unresolved line and the skill falls back to the
same prose it always used, so nothing breaks if you're on an older install.
What got scripted¶
/zsl:timesheet— the digest script now emits a per-projectduration_label(4.5h, not a hand-rounded4h) and a pre-renderedwindow_header/window_phrase(correct timezone +last 1 hourpluralization). The final timesheet copies them verbatim. Also fixes the old./scripts/digest_sessions.pyinvocation, which only resolved from the plugin's own checkout, to a path resolver that works from any repo./zsl:tdd-parallel— a sharedzsl-preflight.shvalidator runs the mechanical pre-flight gates (clean tree, HEAD not detached, requireddocs/agents/*.mdexist,.worktrees/gitignored). The "ship-style says PR-style" content read stays model-driven./zsl:write-a-skill— acheck-description-length.pygate counts the hard 1024-char description cap instead of eyeballing it (an over-cap description is silently truncated, dropping itsUse when …trigger). (The skill was renamed to/zsl:writing-great-skillsin 2.0.0.)/zsl:afk-fanout— awrite-afk-entry.shserializer owns the initialafk-runsledger entry + manifest row to the exact schema shared with/zsl:afk-workerand/zsl:morning-review, so the three can't drift.
Under the hood¶
Scripts bundle inside each skill's own scripts/ dir and ride to every
environment (local plugin install, other repos, remote /afk-worker clones) on
the existing distribution — no provisioning or hook change was required. make
test now runs the new scripts' tests (pytest + shell runners). See the
"Deterministic-gate scripts" contract in CLAUDE.md.
afk-fanout: native one-off scheduling¶
Separately, /zsl:afk-fanout now schedules each
overnight worker as a native one-off routine (run_once_at) instead of a
pinned recurring cron that had to be disabled after it fired. Two consequences:
- One-off runs are exempt from the per-day routine cap. A night of workers no longer spends your daily routine quota (Pro 5 / Max 15 / Team 25) — only the overnight window and the per-5h token throttle (the fixed 2h slot spacing) bound how many PRDs you can queue. The old "routine-count budget" overflow rule is gone.
- Routines auto-disable after they fire (
ended_reason: run_once_fired), so there's no disable-after-fire step and no fired-trigger sweep. Spent triggers stay listed as disabled; delete them in the claude.ai UI when convenient (cosmetic —RemoteTriggerhas no delete action).
No migration needed: any routine scheduled by 1.0.0 has already fired and
disabled itself. /zsl:morning-review is unchanged.
1.0.0¶
The 1.0 release adds an overnight remote-agent path alongside the
existing interactive loop, built on the change that makes it possible:
/zsl:tdd-parallel partial runs. The new
path is a three-skill loop —
/zsl:afk-fanout (evening scheduler),
/zsl:afk-worker (per-PRD remote executor), and
/zsl:morning-review (morning walk-through)
— that fans work out to one dedicated remote claude.ai session per PRD so
several /zsl:tdd-parallel runs can happen overnight without contending
on a shared checkout.
This release also reverses 0.10's hard refusal on open [HITL] slices,
teaches /zsl:verify-coverage to tell a deferred story from a real
gap, and makes /zsl:to-issues' ## User stories covered section
mandatory — all three serve the partial-run model. Not purely
additive: the partial-run carve and the deferred state change how
interactive /zsl:tdd-parallel and /zsl:verify-coverage behave even
if you never touch the remote path (see Upgrading from 0.11).
/zsl:tdd-parallel: partial runs replace the open-[HITL] refusal (the big change)¶
0.10 made /zsl:tdd-parallel hard-refuse at pre-flight if any open
[HITL] slice existed anywhere in the parent's sub-tree. That blanket
rule was stronger than the invariant it protected. The real invariant is
no human gate fires after invocation — and that's preserved by a
weaker, graph-aware rule:
Run only slices whose transitive
Blocked byclosure contains no open[HITL]slice. Defer every open[HITL]slice and everything transitively downstream of it.
Because every selected slice's entire blocker closure is HITL-free, no
selected slice can become human-gated mid-run — the invariant holds just
as firmly, without throwing away the work that doesn't depend on the
gate. When anything is deferred, the run is partial: it ships the
runnable slices in a [partial] PR whose body omits `Closes
(so the PRD stays *open*) and carries a## Deferred` section¶
(so the PRD stays *open*) and carries a## Deferred` section¶naming the gating [HITL] issue(s), the deferred slices, and the
deferred user stories, plus a re-entry recipe. Clear the gate via
/zsl:human-itl <parent>, re-run /zsl:tdd-parallel <parent>, and the
now-closed [HITL] slice satisfies its downstream via the existing
satisfied_oob path — the second run (now a full run) closes the parent.
No partial-specific state is persisted between runs.
This carve is always on — there is no flag. A PRD with zero open
[HITL] slices is byte-for-byte the old behaviour: full fanout, closes
the parent, no [partial] marker. Pre-flight 1d now refuses only when
no slice is runnable (everything is deferred behind an open [HITL]
or still in triage), and scopes the automatable-story gate to the
stories the runnable slices cover — stories covered only by deferred
slices are checked on the later run that makes them in-scope. The
zero-progress halt (3a) is correspondingly narrowed: an open [HITL]
blocker now causes a partial-complete, never a halt.
/zsl:tdd-parallel: --on-review-failure halt|continue flag¶
A new flag controls what happens when step 4a's
/zsl:code-review --auto applies findings but lint/tests then fail and
the review commit is reverted. Default halt preserves today's
interactive contract (surface in RCA, leave the user to inspect). New
continue mode proceeds to step 4b — the PRD branch is already at its
pre-review state, all slices are individually green via their per-slice
/zsl:tdd cycles, so the integration is shippable; the attempted
findings (count, severity, file:line refs, the reverted commit sha)
ride into the PR body as a ## ⚠️ Integration review failed section for
the morning reviewer to re-run /zsl:code-review against by hand.
/zsl:afk-worker always passes continue.
/zsl:tdd-parallel: feature-prefixed worktree names in .scratch/ mode¶
Slice worktrees and branches in local-markdown trackers now include the
parent feature number: .worktrees/<feat>-<slice>-<slug>/ and
tdd/<feat>-<slice>-<slug> instead of the <slice>-<slug> forms. This
keeps slice worktrees unambiguous if /zsl:tdd-parallel is ever run
against more than one PRD in the same checkout, since .scratch/ slice
numbers are per-feature scoped (every feature has its own 01, 02, …).
Pre-flight 1b's stale-worktree sweep parses the same conditional pattern.
Overnight this can't arise — /zsl:afk-worker gives each PRD its own
clone — but the prefix keeps single-checkout multi-PRD use safe too.
GitHub/GitLab mode is unchanged — issue numbers are globally unique there.
/zsl:tdd-parallel: callable from a routine prompt¶
/zsl:tdd-parallel no longer carries disable-model-invocation: true
in its frontmatter, so /zsl:afk-worker can drive it from a scheduled
remote session's prompt. Other automatic invocation paths should still
be avoided — the skill is expensive (multi-hour wall-clock, many
sub-agents) and not appropriate for incidental chaining.
/zsl:afk-worker is the one well-defined caller path.
/zsl:verify-coverage: the deferred story state¶
/zsl:verify-coverage gains a fifth story
state, deferred, to support partial runs. A story claimed only
by still-open slices (none shipped — typically the covering slice is
gated behind an open [HITL] that /zsl:tdd-parallel deferred) is not a
gap: the work to cover it hasn't landed yet. It's distinct from both
gap (a hole to fix now) and out-of-scope (a permanent exclusion) —
a temporary not-yet. Deferred stories are never driven through
Tier B and never filed as gaps; doing so would manufacture a
spurious gap that re-files every round and never converges.
To compute this, step 2 now inverts the ## User stories covered map for
both shipped and open slices, keeping the two separate so a story
claimed only by open slices reads as deferred rather than a real hole
(no claiming slice at all). The derivation is always on — a function
of tracker state, not a flag; when every slice is shipped, no story is
deferred and the run is identical to before. A new deferred=<n> count
joins the matrix and the receipt (plus a deferred-stories: line), and
the terminal block reports it separately so /zsl:tdd-parallel's step 4b
can read gap=0 deferred>0 as its partial-complete signal — proceed to
the [partial] PR, don't loop. --no-generate and --no-file both
respect deferral (it takes precedence over unverified, and deferred
stories are never filed in any mode).
/zsl:to-issues: ## User stories covered is now mandatory¶
The ## User stories covered section on every PRD-derived slice (only a
freeform plan with no user stories may omit it) is now explicitly
mandatory, because it's load-bearing in two places that read it back
from the issue body, not the quiz: /zsl:verify-coverage's Tier A
story→slice map, and /zsl:tdd-parallel partial runs, which use it to
tell a deferred story from a real gap. A slicing run that silently drops
the section breaks partial-run coverage scoping — deferred stories get
misclassified as gaps and spuriously re-fanned-out. Legacy slices that
predate the section still fall back to /zsl:verify-coverage's
lower-confidence inference, but new slices must carry it.
verify-after: field in agent briefs¶
triage/AGENT-BRIEF.md
gains a verify-after: ci | local-run | staging line on every brief.
The field tells the post-PR pipeline how the slice's integration PR
should be validated before merge:
ci— CI signals are sufficient; diff skim + merge. Default for pure business-logic slices that don't touch system boundaries.local-run— needsgh pr checkout+/verifyagainst the local dev env. Use for slices touching external APIs, auth, payments, migrations.staging— needs a staging deploy + smoke test. Reserved for slices where local dev can't faithfully simulate the deployed environment.
Set by /zsl:triage when moving a slice to ready-for-agent, surfaced
by /zsl:afk-fanout as each PRD's verify-after mix at selection, and
consumed by /zsl:morning-review to prioritise the morning walk-through.
Default to ci; only escalate when there's a concrete reason —
over-tagging defeats the point of unattended runs.
New skill: /zsl:afk-fanout¶
/zsl:afk-fanout is an interactive
local-session scheduler, not a cron job. Run it yourself in the
evening: it shows the queue of tracking PRDs with open
ready-for-agent children — including each PRD's verify-after mix —
and you pick which to run overnight and in what order. It then schedules
one one-shot remote routine per PRD, a fixed 2h apart, each
firing a fresh remote session that runs /zsl:afk-worker <num>.
The 2h spacing is a deliberate throttle: claude.ai usage is capped per rolling 5-hour window and one worker session is a heavy consumer, so spacing keeps each window under the cap. It is never compressed. A separate, harder ceiling also applies — claude.ai caps routines per day (Pro 5 / Max 15 / Team & Enterprise 25 as of 2026-05; confirm current values), and each scheduled worker is one routine drawn from the same subscription budget as interactive sessions. Selections that overflow either limit are reported for you to schedule the next evening.
A light scheduled claim on each picked PRD stops a second
/zsl:afk-fanout run the same evening from double-booking it. The skill
never runs /zsl:tdd-parallel itself — it only enumerates, claims, and
schedules — and refuses at pre-flight unless the repo has a configured
remote-agent environment (see /zsl:setup-zsl-superpowers below).
New skill: /zsl:afk-worker¶
/zsl:afk-worker is the per-PRD remote
executor each scheduled routine fires. It runs unattended in its own
remote session — own clone, own working tree, own branch — so PRDs never
contend on a shared checkout. Running one /zsl:tdd-parallel per remote
session is the whole reason fan-out happens at the session level rather
than inside one orchestrator.
A worker flips the PRD's claim to in-progress, runs
/zsl:tdd-parallel <num> --on-review-failure=continue --max 2, and opens
one integration PR. Because it owns its clone — where local .scratch/
writes never auto-sync home — successes ride home in the integration PR,
and everything without a PR (the claim flip, any halt's needs-info
move + RCA) is recorded instead as a per-PRD entry on the shared
afk-runs git branch (an orphan ledger branch; one entry per PRD so
concurrent workers never conflict), which /zsl:morning-review
reconciles back into .scratch/. On halt:
- Clean-tree halts (3a zero-progress, 3d agent failure) — record the
attributable slices as
needs-infowith the/zsl:tdd-parallelRCA, and set the PRD parent back totrackingto re-queue once re-triaged. - Dirty-tree halts (3e unresolvable merge conflict) — leave the clone untouched for inspection, RCA on the PRD parent. Because the session is isolated, a stuck PRD can't affect any other PRD's worker.
- Integration review failure (4a) is never a halt here — the worker
always passes
--on-review-failure=continue, so it becomes a PR-body warning instead.
Each worker also fires a best-effort Telegram heads-up when it
finishes a PRD (a plain HTTPS call to the Bot API, no MCP connector) if
AFK_TELEGRAM_BOT_TOKEN / AFK_TELEGRAM_CHAT_ID are set in the remote
environment. It carries no load-bearing data — the afk-runs ledger is
the record — so a missing or failing notification never affects a run.
/zsl:afk-worker is invoked by the routine, not by hand.
New skill: /zsl:morning-review¶
/zsl:morning-review is the consumer side of
the overnight path. It first reconciles the afk-runs ledger branch
back into the canonical .scratch/ tracker — replaying the claim flips
and halt RCAs that ran in isolated worker clones and can't reach main
any other way — across every un-reconciled run, not just last night
(so a skipped morning isn't lost). Then it reads /zsl:afk-fanout's
scheduling manifest and walks you through the artifacts in priority
order:
- PRs flagged
## ⚠️ Integration review failed— re-run/zsl:code-reviewagainst the PR branch locally before merge. - PRs containing slices with
verify-after: staging— staging deploy + smoke test (manual, project-specific). - PRs containing slices with
verify-after: local-run—gh pr checkout+/verifyagainst your local dev env. - Scheduled-but-no-result PRDs — a worker that never produced output (throttled by the token cap, never fired, or stuck on a 3e dirty tree). The manifest cross-check surfaces these so they aren't silently lost; re-schedule or inspect the routine session.
- Halted slices in
needs-info— re-triage decisions (back toready-for-agent, reformulate the brief, orwontfix). - PRs where every slice is
verify-after: ci— diff skim, merge. - PRs with red CI — surfaced separately; investigate via the checks tab.
The skill does not auto-merge and does not deploy. Manual-deploy projects stay manual-deploy. It sequences attention; the human does the work and the merge clicks.
/zsl:setup-zsl-superpowers: optional remote-agent environment¶
/zsl:setup-zsl-superpowers gains an
optional Section F — Remote agent environment that writes
docs/agents/remote-env.md. It records the claude.ai Claude Code
environment id the overnight loop schedules sessions into, installs
the remote-skills SessionStart hook (see below) so the skills
resolve in the fresh remote session, and confirms the remote has push
access for the afk-runs ledger branch, and optionally records the
names (never values) of the AFK_TELEGRAM_* secrets for the Telegram
heads-up. /zsl:afk-fanout refuses at pre-flight until this file exists;
the rest of the loop is unaffected if you skip it.
/zsl:setup-zsl-superpowers: remote-skills hook replaces "install the plugin in the environment"¶
Earlier 1.0 drafts told you to install the zsl plugin into the claude.ai
environment so /zsl:afk-worker would resolve when a routine fired.
There is no such per-environment lever — plugin availability isn't an
environment setting, and a scheduled routine starts in a fresh remote
session with no plugins installed. Section F now provisions the skills
the correct way: it writes .claude/hooks/zsl-remote-skills.sh and merges
a SessionStart entry into the repo's .claude/settings.json. The hook
fires only when CLAUDE_CODE_REMOTE=true (a no-op in your local
sessions, where the plugin is installed), clones zsl-superpowers, and
symlinks its skills — including the remote-agents bucket where
/zsl:afk-worker lives — into ~/.claude/skills/. /zsl:afk-fanout's
pre-flight now checks for this hook instead of an environment-level plugin
install.
Upgrading from 0.11¶
The remote path is opt-in, but two changes affect interactive
/zsl:tdd-parallel and /zsl:verify-coverage even if you never use it:
-
/zsl:tdd-parallelno longer refuses on open[HITL]slices. Where 0.10 hard-refused at pre-flight, it now runs the slices whose blocker closure is HITL-free, defers the rest, and opens a[partial]PR that leaves the parent PRD open. It refuses only when no slice is runnable. If you relied on the blanket refusal as a signal to clear[HITL]first, you'll now get a partial PR instead — clear the gate via/zsl:human-itl <parent>and re-run to land the remainder. A PRD with no open[HITL]slices is unchanged. -
/zsl:verify-coveragenow classifies some storiesdeferred. A story covered only by a still-open slice reports asdeferred(with the blocking slice as evidence) instead of being driven through Tier B and filed as a gap. This is always on. If you had automation parsing the matrix counts, note the newdeferred=<n>field and thedeferred-stories:receipt line. -
/zsl:tdd-parallelworktree naming changed in.scratch/mode. Old.worktrees/<slice>-<slug>/directories from prior runs won't match the new<feat>-<slice>-<slug>sweep pattern and are left untouched (harmless). To clean up,rm -rf .worktrees/once before your next run — the next invocation recreates what it needs. -
Existing agent briefs without
verify-after:still work./zsl:morning-reviewtreats a missing field asci. To get the risk-aware walk-through, re-triage existingready-for-agentslices and add the field; new briefs written by/zsl:triagecarry it automatically.
To stand up the overnight path itself:
- Run
/zsl:setup-zsl-superpowersand answer Section F to writedocs/agents/remote-env.mdwith your claude.ai environment id (and, optionally, the Telegram secret names). The same section installs the remote-skillsSessionStarthook (.claude/hooks/zsl-remote-skills.sh) so the skills resolve in the remote session — there's no plugin to install into the environment. Confirm the remote can push theafk-runsbranch. - In the evening, run
/zsl:afk-fanoutin a local session. Pick the PRDs to run overnight; it schedules one remote routine per PRD, a fixed 2h apart, each running/zsl:afk-worker. - Each routine clones a fresh checkout and runs one PRD. Successes come
home as integration PRs; claim flips and halt RCAs come home on the
shared
afk-runsledger branch (/zsl:afk-fanoutalso writes its scheduling manifest there). - The morning after, run
/zsl:morning-reviewto reconcile the ledger and walk the resulting PRs, halted slices, and any PRD that produced no result.
0.11.0¶
Eight engineering skills now bundle decision-pressure rules distilled
from classic software-engineering books, sourced from
ciembor/agent-rules-books
by Maciej Ciemborowicz (MIT, pinned to v0.5):
/zsl:tdd← Refactoring + Working Effectively with Legacy Code (nano)/zsl:improve-codebase-architecture← A Philosophy of Software Design + Clean Architecture/zsl:diagnose← Release It!/zsl:grill-with-docs← Domain-Driven Design Distilled + Implementing DDD/zsl:to-prd← Domain-Driven Design Distilled/zsl:code-review← Clean Code + Refactoring/zsl:verify-coverage← Working Effectively with Legacy Code/zsl:prototype← The Pragmatic Programmer
Rules are inline-appended to each SKILL.md between
<!-- BEGIN bundled-book-rules --> / <!-- END bundled-book-rules -->
markers and re-rendered by scripts/sync_book_rules.py from the
vendored snapshot in vendor/agent-rules-books/.
The behaviour is always-on (no opt-out); a repo can override via
project-level CLAUDE.md if a specific rule set is wrong for that
codebase.
Two new Makefile targets support the maintenance loop:
make check-upstream-books— diff the vendored snapshot against the latest upstream tag (hand-pick adoption; we do not auto-track).make sync-books— re-render theBEGIN/ENDfences fromvendor/agent-rules-books/after a vendor bump.
Vocabulary alignment in /zsl:improve-codebase-architecture¶
The skill's LANGUAGE.md was restructured to ground its vocabulary
in the bundled APoSD and Clean Architecture rules. boundary,
layer, port, cognitive load, change amplification,
hidden dependencies, and temporal coupling are now canonical
terms (citing their source book). Our own additions — seam,
depth-as-leverage, leverage, locality — are kept with
explicit explanations of how they relate to the books' framing
(notably: a boundary is a particular kind of seam; depth-as-leverage
is preferred over Ousterhout's depth-as-ratio because the ratio
rewards padding the implementation). HTML-REPORT.md's strict
glossary rules and SKILL.md's inline glossary updated to match.
Supporting-file alignment in /zsl:grill-with-docs¶
CONTEXT-FORMAT.md now names CONTEXT.md as the Bounded Context's
Ubiquitous Language (citing DDD Distilled) and lists DDD's nine
context-relationship types — Partnership, Shared Kernel, Customer/
Supplier, Conformist, Anticorruption Layer, Open Host Service,
Published Language, Separate Ways, contained Big Ball of Mud — so
CONTEXT-MAP.md relationships can be tagged with type names instead
of described ad-hoc. The example map shows the tagging: (Published
Language) for event integrations, (Shared Kernel) for shared types.
ADR-FORMAT.md's What qualifies list now includes subdomain
classification (Core/Supporting/Generic), Aggregate consistency
boundaries, and an enriched Integration patterns bullet that names
the DDD relationship types as concrete ADR subjects.
Supporting-file alignment in /zsl:tdd¶
refactoring.md was rewritten as a scannable trigger checklist aligned
with Fowler's Refactoring nano vocabulary (three-strike duplication,
decompose conditionals before reaching for polymorphism, separate
cleanup from behavior, never rewrite when a smaller move would do).
mocking.md gained a Legacy code: internal seams are sometimes
necessary section naming Feathers' moves — Sprout, Wrap,
Parameterize/Inject, Extract & override — and the two guardrails
(narrowest useful seam; don't leave test-only seams permanent).
tests.md gained two sections: Greenfield vs legacy code in TDD
(defines both terms, citing Feathers' "code without trustworthy tests"
criterion — legacy is about test trust, not age) and
Characterization tests for legacy code (worked example: pin
existing ugly behavior → write the bug-fix test → fix → delete the
characterization test once it goes red).
Upgrading from 0.10¶
No action needed. The bundled rules add bias to existing skills but do
not change command surfaces or invocation contracts. If a bundled rule
set conflicts with house style in your repo, add an override in your
project's CLAUDE.md (e.g. "ignore the Clean Architecture layering
rules in /zsl:improve-codebase-architecture for this codebase; we
use a feature-folder layout intentionally").
0.10.0¶
The headline change is a full-auto PRD pipeline:
/zsl:tdd-parallel now runs from invocation
to a pushed integration PR with no human gates in the happy path —
including auto-chaining /zsl:verify-coverage and auto-fixing any
gaps it finds. The supporting design moves all human-judgement gates
upstream of /zsl:tdd-parallel so the auto-loop has a well-formed
input contract to operate against. Also: a new
/zsl:commit-push-pr one-shot ship skill,
a new code-review deep-dive, Mermaid diagrams across
several existing skills, and a docs nav reorg around the lifecycle
phases.
Full-auto pipeline (the big change)¶
/zsl:tdd-parallelauto-chains/zsl:verify-coverage --autoat step 4b (instead of halting and asking you to run it). If verify-coverage files any gap issues, they land asready-for-agentdirectly and the orchestrator re-enters fanout to fix them — the loop iterates untilgap=0or a circuit breaker fires. Three circuit breakers cap the loop:--max-coverage-rounds(default 3) caps total iterations; per-story retry limit (2) catches the same story bouncing back as a gap; a no-progress check catches round-to-round stagnation. On all three breakers the orchestrator halts with a structured RCA — read the residual matrix in the latest coverage receipt and decide whether to fix by hand.- New pre-flight 1d in
/zsl:tdd-parallel. Refuses to start if the parent PRD has any user story missing tags (or tagged anything other thanautomatable), or any open[HITL]sub-issue. Both gates ensure the auto-loop has no human-judgement work to bump into mid-run — clear[HITL]via/zsl:human-itlfirst; fix tag issues via/zsl:to-prdor a hand-edit. - Step 4c delegates the defensive commit to
/zsl:committhen inlines push + structured PR (preserving the wave-ordered## Slices integratedandCloses #Ntemplate) + project-board bulk-move. The PR body grows an## Auto-fixed coverage gapssection when the loop ran multiple rounds. /zsl:to-prdnow refuses non-automatable user stories. Every story must carryacceptance: automatableandobservable: <description>sub-bullets — theobservable:line is the contract Tier B generates a test against. Visual/UX/external-system stories cannot be expressed as a public-interface assertion and so are refused: reframe (e.g. "feels welcoming" → "first-render Lighthouse score ≥ 90"), split into a separate PRD that goes through a manual path, or drop./zsl:to-issuespropagates parent PRD tags into each slice body verbatim. Each slice's## User stories coveredsection carries the parent story'sacceptance:/observable:lines, so agents and/zsl:verify-coverageTier B see the testable contract without re-fetching the PRD./zsl:triagevalidates PRD tags before advancing toready-for-agent. Triaging a PRD or any of its children checks every story foracceptance: automatable+observable:and refuses on missing/invalid tags with the offending story numbers./zsl:verify-coveragesimplified and orchestrator-friendly:- HITL human-attestation lane removed. With
/zsl:to-prdrefusing non-automatable stories upstream, there are no manual stories to route. The wholemanual-attestationvalue has been eliminated from the design. --autoflag added. Skips the matrix-confirmation user prompt and files gap issues asready-for-agent(instead ofneeds-triage) so the orchestrator can fanout the remediation directly. The human review surface moves to/zsl:triage(for false-positive gaps, no different from any other triage-able item).- Classification step removed at runtime. Reads
acceptance:tags written by/zsl:to-prdinstead of LLM-judging AFK-testable vs HITL-verifiable per run. disable-model-invocation: trueremoved. The skill is now chainable by orchestrators (specifically/zsl:tdd-parallelstep 4b). Direct user invocation is still supported for auditing PRDs that shipped via a different path.- Receipt format adds an
invocation: auto | manualfield for audit clarity ("when did this story start failing?").
- HITL human-attestation lane removed. With
New skill¶
/zsl:commit-push-pr. One-shot ship for a feature branch: pre-flight refuses on the default branch, delegates the commit to/zsl:commit, thengit push -u origin, thengh pr create. Same safety rails as the underlying skills — explicit file lists, no Claude attribution, no--force, no--no-verify. Handles the existing-PR / auto-PR-workflow fallback. Use when you want to wrap up an interactive session in one keystroke;/zsl:tdd-parallelinlines its own push + PR step rather than calling this (it needs the structured integration-PR template that the general-purpose skill doesn't produce).
New documentation¶
- Code review deep-dive. Design rationale for
/zsl:code-review's six-lens parallel scan (clean-code, CLAUDE.md compliance, git history, prior PR comments, inline comments, spec alignment) and 0–100 confidence model. Joins tdd-parallel.md as the second top-level deep-dive. - mkdocs nav reorganized around lifecycle phases. "How it fits together" (overview / workflow / phases / state machine / branching) → "Deep dives" (tdd-parallel, code-review) → "Skills" grouped by Plan / Break down / Build / Verify / Ship / Cross-cutting / Off-loop rather than the old engineering/productivity/misc buckets. Easier to find a skill by when you use it.
Visual polish¶
Mermaid diagrams added to five existing SKILL.md files for behavioural flows that read better as pictures than prose:
/zsl:commit— session-vs-other-origin classification flow with the safety-rail kill list./zsl:improve-codebase-architecture— decision flow for when to render the HTML report vs stay conversational./zsl:tdd— step graph for the red-green-refactor cycle with the review/ship branches./zsl:grill-me— node status lifecycle (unresolved → grilling → resolved) within the design tree./zsl:handoff— end-to-end flow from current session through redaction to next session.
Plus a setup config-fanout diagram in setup.md showing which
config files each skill consumes, and small docs touch-ups: an
/zsl:handoff vs /clear FAQ entry, a /zsl:handoff row in the
quick-lookup table on the docs home, and a local-markdown closure
note in the branching pattern docs.
Upgrading from 0.9¶
A few breaking-ish points worth checking before you re-invoke
/zsl:tdd-parallel:
- PRDs need
acceptance:+observable:tags on every user story. PRDs written under 0.9 don't carry these. Re-run/zsl:to-prdon the originating conversation, or hand-edit the PRD body to add the sub-bullets per/zsl:to-prd's template./zsl:triagerefuses to advance children of an untagged PRD toready-for-agent, and/zsl:tdd-parallelrefuses to start against one. - Non-automatable stories must be split out. The HITL
human-attestation lane in
/zsl:verify-coverageis gone, and/zsl:to-prdrefuses to write a story it can't reduce to a public-interface assertion. Visual/UX/external-system work needs its own PRD that goes through a manual path (not this pipeline). Reframing is usually possible — e.g. "looks welcoming" → "Lighthouse first-render score ≥ 90" — and what's left over is a smaller, more focused manual scope. - Clear all
[HITL]slices before/zsl:tdd-parallel. Prior versions silently skipped them and you re-ran the fanout after/zsl:human-itl. 0.10 hard-refuses on any open[HITL]at pre-flight — the rule simplifies the auto-loop's invariants ("no human-judgement work mid-run") but means you can no longer interleave the two skills mid-flight. /zsl:verify-coverage'sdisable-model-invocationis gone. This was a guard against orchestrator self-rubber-stamping; the new design moves that concern to the circuit breakers in/zsl:tdd-parallel4b instead. If you had any local automation that depended on the skill being un-chainable, that assumption no longer holds.- Direct
/zsl:verify-coverageinvocation still works for auditing PRDs whose slices shipped via another path. It defaults to the interactive mode (matrix confirmation, files gaps asneeds-triage). Use--autoonly when chaining from an orchestrator.
0.9.0¶
A focused release that ports three high-leverage additions from
upstream mattpocock/skills,
adds a sixth lens to /code-review, and aligns one skill with the
structured <what-to-do> / <supporting-info> SKILL.md pattern.
No breaking changes.
- New skill:
/zsl:handoff. Compacts the current conversation into a handoff document so a fresh agent (or session) can continue cleanly without re-deriving context. Saves to the OS temp directory ($TMPDIRon macOS/Linux,%TEMP%on Windows) with a dated slug. Redacts API keys, tokens, JWTs, signed URLs, internal hostnames, and.env-derived values before writing. References existing artifacts (PRDs, ADRs, issue bodies, commits) by path/line/URL rather than duplicating them. Includes a Suggested skills for next session section that names specific/zsl:<skill>calls in order. Accepts an argument-hint so the doc can be tailored when the user knows what the next session will focus on. Filling the long-standing gap around session end //clear/ cross-agent handoff. /zsl:code-reviewgrows a sixth lens: Spec alignment. The existing five lenses (clean-code, CLAUDE.md compliance, git history, prior PR comments, inline comments) all read the diff and the surrounding repo. None of them asked "did this faithfully implement what the spec asked for?" — the new Spec lens does. It looks up the originating PRD/issue (via commit-message references → user argument → matching path underdocs/,specs/, or.scratch/) and reports missing requirements, scope creep, and wrong-implementation findings with the relevant spec line quoted. Returns "no spec available" and skips itself if nothing is found. Inspired by upstream's two-axis/reviewskill; merged as one more lens in our existing parallel scan rather than a separate skill./zsl:improve-codebase-architecturegains an HTML report output. Architectural review's value is in the seeing — markdown bullets undersell deepening opportunities. The newHTML-REPORT.mdscaffold renders candidates as a single self-contained HTML file in the OS temp dir, mixing Mermaid graphs (dependencies, call flow, sequences) with hand-built SVG diagrams (mass diagrams, cross-sections, call-graph collapse) for editorial weight Mermaid alone can't carry. Tailwind + Mermaid both come from CDNs; no build tooling. Strict glossary enforcement: prose must use theLANGUAGE.mdterms (module, interface, depth, seam, adapter, leverage, locality) exactly — never "component", "API", "boundary". An optional new step 4 in the SKILL.md; conversational presentation in step 2 stays primary./zsl:grill-meadopts the<what-to-do>/<supporting-info>SKILL.md pattern (matching/zsl:grill-with-docs, which already uses it). No behavioural change — same content, sectioned so the model can find "what to do right now" vs "design-tree format reference" without re-skimming. Not migrated:/zsl:tdd,/zsl:tdd-parallel,/zsl:triage,/zsl:code-review, and other skills with explicit numbered phases. The structured sections would clutter docs whose body IS the workflow; the pattern is for skills with a "here's the action; here's the reference" shape.
Upgrading from 0.8: standard refresh —
/plugin marketplace update zsl-superpowers then restart Claude
Code. Nothing breaking; nothing to migrate. /zsl:handoff is
available immediately; /zsl:code-review automatically picks up the
Spec lens; /zsl:improve-codebase-architecture runs unchanged but
will now offer an HTML report when it would land better than a
numbered list.
0.8.0¶
- Code review becomes a first-class part of the loop.
/zsl:code-reviewwas rewritten as a more rigorous, less noisy review pass with three structural changes: - Clean-code lens. Opens with Uncle Bob framing — simple, correct,
minimal; single responsibility; small functions with names that
don't lie; no dead code; no premature abstraction. Eight concrete
"always flag" standards (incl. behavior changes without test
changes, modified
.env*files, comments that explain what the code does instead of why). - Parallel multi-lens scan. Five concurrent sub-agents handle distinct concerns — CLAUDE.md compliance, shallow bug scan, git history/blame, prior PR comments on the same files, inline code comments — instead of one head doing everything sequentially. Findings are deduplicated, then scored 0–100; anything below 60 is dropped before you ever see it, reducing the noise the approval gate has to filter. The git-blame and prior-PR-comment lenses in particular catch "this looks wrong but it's pre-existing" and "we already debated this exact thing on PR #142" — blind spots the previous single-pass review couldn't see.
--autoflag for autonomous use. Drops the approval gate, applies findings ≥80 as a single revertible commit (subjectreview: <summary>), reports 60–79 findings in the return summary for the orchestrator to surface, runs lint+tests post-fix and self-reverts on failure. Designed for AFK contexts — the interactive approval gate stays default and remains the differentiator versus the built-in/review.
A genericisation pass also removed Sentry / coverage / SQL / Supabase-specific heuristics that didn't belong in a portable skill. The remaining "Before suggesting changes" section keeps three universal principles (match existing conventions, trust enforcement layers, don't push abstraction prematurely). Net effect: file is 47% shorter and applies to any project.
-
/zsl:tddnow auto-triggers a review between Refactor (step 4) and Ship (step 6, renumbered) as new step 5. Interactive mode runs/code-reviewwith the approval gate (fixes commit via/commit, same discipline as ship); AFK mode (--no-ship) runs/code-review --auto, with deferred 60–79 findings riding out in the return summary under a Deferred review findings section. A newreviewedheartbeat phase fires after the review pass so the parent orchestrator sees progress. Catches what the author missed without leaving the loop. The Refactor checklist also gained a Delete aggressively discipline — every refactor pass should remove dead code, unused imports, debug statements, commented-out blocks, and comments that explain what instead of why (TDD that only adds is half-done). -
/zsl:tdd-parallelnow runs an integration code review before the coverage gate. New step 4a fires/code-review --autoagainst the merged PRD tip and rides any cross-slice fixes (duplicate helpers, drift between slices, redundant imports after merge) into the same integration PR. The per-slice review inside each/tddinvocation can't see across slices; this pass can. Old subsections 4a/4b shifted to 4b/4c, and a new Integration review failure halt path joins the other four —/code-review --autoreverts its own commit on lint/test failure and the orchestrator surfaces it in RCA with the reverted commit sha for inspection. The sub-agent prompt template also got a Lean slices reinforcement pointing at/tdd's deletion discipline, so bloated slices don't compound into a bloated integration PR. -
/zsl:grill-meand/zsl:grill-with-docsnow print a design tree at the start of every session and reprint it whenever the shape or status changes (node resolved, new branch discovered, focus moved, scope shifted). Status markers[ ] / [→] / [✓]show where you are in the decision space — pacing and progress become visible at a glance instead of being implicit in the running dialogue. -
/zsl:commitis now fully autonomous. Invoking/commitno longer pauses for a "Shall I proceed?" approval prompt — the invocation itself is the approval, and all session changes land in one logical commit by default. The skill still classifies dirty files into session changes (modified via this conversation's tool calls) versus other-origin (files dirty before the session started, or modified outside the conversation) and confirms only the other-origin bucket before including or excluding it. Safety rails are unchanged: still nevergit add -A, still refuses to stage.env*/*credentials*/*.pemand other obvious secret patterns, still no Claude attribution lines, still creates a fresh commit (never--amend) after a pre-commit hook failure. This composes cleanly with/zsl:tdd's default-on review (Section 1 above) — the user approves fixes once at the review gate;/committhen lands them without a second prompt. -
Local-markdown tracker convention: features now carry a number prefix, archives carry a date prefix. Active features live at
.scratch/<NNN>-<feature-slug>/(was.scratch/<feature-slug>/), where<NNN>is a 3-digit feature number assigned at creation — auto-incremented from the highest existing number across active + archived. Archived features live at.scratch/done/<YYYYMMDD>-<NNN>-<feature-slug>/(was.scratch/done/<feature-slug>/), with the close date stamped before the feature number sols .scratch/done/shows close order while the number stays embedded for lookup. Net effect: features can be addressed by number alone —/zsl:triage 23,/zsl:to-issues 45, or any other skill that accepts a feature reference resolves via glob (.scratch/023-*/for active,.scratch/done/*-023-*/for archived). No more typing the slug, no more guessing what the directory was called./zsl:tdd's feature-level closegit mvnow stamps both the date and the embedded number; the number itself is permanent across the active→archive transition. Numbers and dates are unique enough on their own that lookups never have to disambiguate.
Upgrading from 0.7: standard refresh — /plugin marketplace update zsl-superpowers
then restart Claude Code. Two things worth knowing:
- Local-markdown trackers only: existing features either lack the
number prefix (active and archive) or lack the date prefix (archive
only), and won't pick up the new lookup semantics or chronological
archive sort without a one-time rename. Re-run
/zsl:setup-zsl-superpowers— it now detects unprefixed and partially-prefixed features (new step 5) and offers a single unified backfill that assigns the missing numbers in date order (fromgit log --diff-filter=A) and stamps any missing archive dates, all in one commit. Confirmation is required before anygit mvruns; the maintainer can edit dates, override numbers, or skip specific entries. Existing numbered features keep their numbers; new assignments start frommax(existing) + 1. Alternatively, rename by hand — but the unified backfill is much easier to keep consistent. GitHub, GitLab, and "Other" trackers are unaffected. /zsl:tdd's interactive flow is slightly longer because step 5 (Review) is now default-on. The review pass is the differentiator versus running/zsl:code-reviewmanually after — it stays in the slice's commit graph and gates Ship. If you want fast iteration on a trivial slice, the--autopath runs unattended; otherwise the approval gate stays in force and you decide which findings to fix./zsl:commitno longer asks "Shall I proceed?" Previously the skill drafted a commit plan and waited for confirmation; now it commits directly after classifying the dirty tree. If you relied on the prompt to catch an unintended file, the other-origin confirmation (files dirty before this session) still fires and the safety rails (nogit add -A, refuse to stage.env*, credentials, large binaries) still hold. If you want a dry run, rungit status/git diffyourself before invoking/commit.
0.7.0¶
- New skill:
/zsl:verify-coverage. Closes the loop's missing half. Until now the only post-implementation completeness signal was structural — the tracker auto-closes a PRD when its last child closes — but "all slices shipped" is not "all user stories covered"; they diverge exactly when slicing drops or misframes a story./verify-coverage <PRD>takes the PRD's## User Storiesas an acceptance oracle (never as/tddimplementation context) and proves each story against the implemented code via tests, not prose or code-search judgement: Tier A maps a story to an existing passing behavioral test; Tier B generates a test for stories with none, proves it non-vacuous by mutation (it must go RED when the code path is perturbed), then runs it; a HITL lane routes visual / UX / external-system stories to human attestation. Genuine gaps are quarantined as skipped tests (referencing the gap issue) and auto-filed asneeds-triagesub-issues of the PRD, so they re-enter the loop through/zsl:triage→/zsl:tdd-parallel. The coverage matrix is a review surface that ends in a user decision — never a silent auto-gate. Run it between a/zsl:tdd-parallelfanout and merging the integration PR so gaps close in the same cycle.disable-model-invocation— user-invoked only. /zsl:to-issuesnow persists the story→slice mapping. Previously the "User stories covered" mapping was only spoken in the step-4 quiz and then lost; each published issue now carries a## User stories coveredsection in its body. This is what/zsl:verify-coverage's Tier A reads back as its oracle — without it, coverage would be re-derived from scratch every run./zsl:tdd-parallelnow enforces a coverage gate (new step 4a) before opening the integration PR. After the fanout integrates, it refuses to push until a valid/zsl:verify-coveragereceipt exists for the integrated tip —mode: fullandverified-shaequal to the PRD branch HEAD. Missing,--no-generatepartial, or stale → the run blocks (a checkpoint, not a restart): invoke/zsl:verify-coverage <parent>in the still-open session, then continue; replyskipfor a new coverage-gate-declined halt that leaves the merged branch unpushed for you to PR by hand. It is an execution gate, not an outcome gate — open gaps still pass; only skipping the check is blocked./zsl:verify-coveragewrites the receipt as a PRD comment (GitHub/GitLab) or.scratch/<feature>/verify-coverage-receipt.md(local-markdown) on every completed run. (Supersedes the soft nudge that briefly shipped in this release's drafts — the gate is the shipped behavior.)
Upgrading from 0.6: standard refresh — /plugin marketplace update zsl-superpowers
then restart Claude Code. One thing worth knowing:
- Slice issues created by
/zsl:to-issuesbefore this release have no## User stories coveredsection./zsl:verify-coveragestill works against them — it falls back to inferring the story→slice map from each slice's## What to buildplus its merged diff — but warns that the map is inferred and lower-confidence for those slices. New issues cut after upgrading carry the section and get the exact map. No action required; re-slicing old PRDs is optional and only sharpens Tier A.
0.6.0¶
- New skill:
/zsl:human-itl. The serial, human-present counterpart to/zsl:tdd-parallel: it walks you through the[HITL]slices the fanout skips — the manual actions a coding agent physically can't perform (third-party console clicks, credential rotation, external sign-off, a hand-run migration) — records each as an audit-trail comment, marks them done so the dependent[AFK]slices unblock, then stops with the hint to re-run/zsl:tdd-parallel. It never writes code (that's/zsl:tdd) and never chains the fanout for you. - Narrowed the
[HITL]definition./zsl:to-issuespreviously called a slice HITL if it needed "human interaction, such as an architectural decision or a design review." That conflated two things. A[HITL]slice is now strictly a manual action an agent can't perform. Architectural decisions and design reviews are not HITL slices — they're resolved upstream in/zsl:grill-with-docs - an ADR before issues are cut, so slices fall out maximally AFK. A
[HITL]slice that's really a decision in disguise is a process leak, and/zsl:human-itlhard-refuses it with a pointer back to grilling. /zsl:tdd-parallel's "Skipped — HITL" guidance no longer tells you to run/zsl:tdd <num>(you don't red-green-refactor a manual action). It now points at/zsl:human-itl <parent>, after which you re-run the fanout./zsl:tdd-parallelnow resumes correctly after a/zsl:human-itlround-trip. Previously its "is this blocker satisfied?" check only recognised slice branches it merged during the current run, so an[AFK]sliceBlocked bya[HITL]slice would zero-progress halt again on re-run even though/zsl:human-itlhad finished the blocker (it was closed/done, never a merged branch) — and the RCA would mislabel the finished blocker asunresolvable. The unblocked rule now also counts a blocker that is closed/done within the parent's sub-tree (sub-tree-scoped, so an unrelated closed issue can't spuriously satisfy a dependency). This also fixes the quieter cousin: a blocker shipped by a prior independent/zsl:tddis now recognised too.
Upgrading from 0.5: standard refresh — /plugin marketplace update zsl-superpowers
then restart Claude Code. One thing worth knowing:
- The
[HITL]definition is narrower. Any existing open issue titled[HITL] … — Decide …/… — Pick …/… — Review …is now considered mislabeled: it's a decision, not a manual action. Resolve those with/zsl:grill-with-docs(capture the outcome as an ADR), then relabel the slice and its dependents[AFK]so/zsl:tdd-parallelwill pick them up. Genuine manual-action[HITL]slices need no change — just clear them with/zsl:human-itlinstead of/zsl:tddfrom now on.
0.5.0¶
/zsl:tddnow closes local-markdown sub-tasks itself on ship: it flips theStatus:line toshippedand runsgit mv .scratch/<feature>/issues/<NN>-<slug>.mdinto the feature'sissues/done/folder, both in the same commit as the slice's code so the close is atomic with the work that earned it. GitHub/GitLab path unchanged (still relies onCloses #<n>for tracker-side closure).- When that close empties the feature's open
issues/,/zsl:tddprompts to archive the feature withgit mv .scratch/<feature> .scratch/done/<feature>. Never automatic — gives you a chance to spin up a follow-up issue first. /zsl:tddinvoked with no argument now works on local-markdown trackers: it scans.scratch/, resolves each open issue's## Blocked byagainst theissues/done/archive, and presents the unblocked issues as a numbered picker (with "pending future waves" and "features archived but not closed" buckets shown for context). Auto-discovery for GitHub/GitLab is out of scope — use/zsl:triagefor that.- Removed:
git-guardrails-claude-code. Claude Code's harness already hard-blocks pushes to default branches and asks before other destructive ops, so the hook's closed pattern list was redundant where it overlapped and risked false confidence where it didn't (rm -rf,dropdb, etc. were never covered). Theblock-dangerous-git.shscript is preserved in git history if anyone wants to revive it standalone. - Releases are now automated. A push to
mainthat bumps the plugin version triggers.github/workflows/release.yml, which validates the changelog entry exists and the two version JSONs agree, then creates av<version>GitHub Release with the changelog section as its body. CI enforcement for the rules captured inCLAUDE.md. This entry is the workflow's first execution —v0.5.0will appear on GitHub Releases the moment the bumping commit lands onmain.
Upgrading from 0.4.x: standard refresh — /plugin marketplace update zsl-superpowers
then restart Claude Code. Two things worth knowing:
- If you ran
/zsl:git-guardrails-claude-codepreviously, its PreToolUse hook lives in your.claude/settings.json(and theblock-dangerous-git.shscript under.claude/hooks/), not in the plugin. The update won't remove them. Leave them if you want the extra protection, or delete thehooksblock from your settings and the script file by hand. - On local-markdown trackers,
/zsl:tddnow closes sub-tasks itself — flippingStatus:toshippedandgit mv-ing the issue file intoissues/done/as part of the slice commit. If you'd been doing this manually after each slice, you can stop. The contract for the local-markdown tracker (where issues live, archive folder layout) is unchanged; only the tool that maintains it has more automation.
0.4.1¶
- Polished skill descriptions and the README intro for the marketplace listing.
- Documented the plugin/marketplace version-sync requirement in
CLAUDE.md.
0.4.0¶
- New skill:
timesheet. Reads recent Claude Code session histories from~/.claude/projects/and synthesises copy/paste-ready timesheet bullets, grouped by project. - The skill ships as LLM synthesis (not deterministic templating) so the output reads like notes you'd actually paste into standup.
0.3.x¶
- New skill:
prototype. Builds a throwaway prototype to flush out a design before committing — routes between a runnable terminal app for state/business-logic questions and several radically different UI variations for design questions. - Auto-resolve merge conflicts in
/zsl:tdd-parallel: the orchestrator now attempts a clean, lint+test-passing merge before halting, and only halts on genuine semantic conflicts. - Made the project-board update mandatory in
/zsl:tdd-parallel(was previously best-effort) — the integration PR opens with the parent and every merged sub-issue moved to "In review." - Reworked
/zsl:tdd-parallelto a single integration PR per fanout (was previously one PR per slice). See the deep-dive for why. - Renamed the plugin to
zsl-superpowers(waszsl-skills). - PRDs published by
/zsl:to-prdnow land withready-for-agentinstead ofneeds-triage— saves a triage round-trip on PRDs you authored yourself. - Documented the
done/archive convention for the local-markdown issue tracker: closed issues move to.scratch/<feature>/issues/done/, closed features move to.scratch/done/<feature>/. Nothing is deleted.
0.2.x and earlier¶
- Converted from a standalone repo to a Claude Code plugin (
zsl) installable from a local clone, then from the GitHub-shorthand marketplace path. - Added
marketplace.jsonso the repo can register itself as a marketplace. - New
trackingstate for container/parent issues — the parent doesn't carry a state on its own children's behalf. - Synced triage labels and the
tddlifecycle to GitHub Projects v2Statusfield, behind the optionaldocs/agents/project-board.mdmapping. - Added the
[AFK]/[HITL]slice prefix and the wave-letter format (<wave><letter>) to slice titles so dependency graphs read at a glance. - Auto-clean residue and sync
mainin/zsl:tdd-parallelpre-flight. - New skill:
zoom-outfor higher-level context on unfamiliar code. (Removed in 2.0.0.)