Adapt to Superpowers + GStack
You are adapting an existing project to the Superpowers + GStack combined workflow. Unlike setup-routing (which is for new/empty projects), this skill preserves everything that already exists and makes only the changes needed for a smooth transition.
Invoke this skill with: /superpowers-gstack:adapt
Dependency check: Before anything else, verify both upstream frameworks are installed. Run:
ls -d ~/.claude/plugins/cache/claude-plugins-official/superpowers/*/ 2>/dev/null | head -1
ls -d ~/.claude/skills/gstack/ 2>/dev/null
If either path is missing, STOP and tell the user:
This plugin is glue for two upstream frameworks. Install them first:
Missing: Superpowers —
/plugin marketplace add claude-plugins-officialthen/plugin install superpowersMissing: GStack —
git clone https://github.com/garrytan/gstack.git ~/.claude/skills/gstack && cd ~/.claude/skills/gstack && ./setupOnly mention the framework(s) that are actually missing. Restart Claude Code after installing, then run
/superpowers-gstack:adaptagain.
Do NOT proceed until both frameworks are present.
Directory check: Verify that Claude Code's working directory is the target project. If the current directory appears to be a different project (e.g., the superpowers-gstack repo itself rather than the user's project), STOP and tell the user:
You're currently in
[cwd]. This skill needs to run from your target project directory. Start a new Claude Code session:cd /path/to/your-project && claudeThen run
/superpowers-gstack:adaptagain.
Version check: The current version is ALWAYS the installed plugin version read from plugin.json (see the marker step) — never a number stated in this file. If the project's CLAUDE.md contains a version marker (<!-- superpowers-gstack: X.Y.Z -->) with an older version, inform the user that routing and session rules will be updated to the current version as part of this adaptation. Projects with an older Model Routing block (v0.1 ### Model Routing with Pi/MLX columns) will have it replaced by the new top-level ## Model Routing (v0.2, Claude-only, domain-aware); projects with none will gain one unless they opt out — surface this clearly so it's not a silent change. Projects on 1.11.1 or earlier will gain three new gstack skill rows (/sync-gbrain, /scrape, /skillify) in the evaluation tables.
Process
Follow these steps in order. Do NOT skip steps.
Step 1: Analyze the project
Read and analyze the following (skip any that don't exist):
- CLAUDE.md — existing instructions, conventions, routing rules
- Package files —
package.json,Package.swift,Cargo.toml,pyproject.toml,go.mod,Gemfile,plugin.json, etc. - Test configuration —
jest.config.*,vitest.config.*,pytest.ini,.swiftpm/,Makefiletest targets, etc. - CI/CD —
.github/workflows/,.gitlab-ci.yml,Jenkinsfile, etc. - Git state — current branch, remotes, branching strategy (check recent branch names)
- Project structure —
lsthe root and key directories to understand the layout - docs/ — existing documentation structure
Summarize what you found to the user. Be concise — focus on what matters for the transition.
Step 2: Identify the project type and stack
Based on Step 1, determine:
- Project type (web app, API, mobile, plugin, library, monorepo, etc.)
- Language(s) and frameworks
- Test framework and how to run tests
- Deploy target (if any)
- QA URL (if browser-testable)
- Whether it's a team or solo project
Present this to the user for confirmation:
Based on my analysis, this is a [type] using [stack]. Tests run with
[command]. [Deployed to X / not deployed]. [Has browser UI at X / No browser UI].Is this correct? Anything to add?
STOP HERE. Do not continue to the next step until the user responds. Do not add "Next steps", suggestions, or any other content after the question. End your message with the question.
Step 3: Evaluate relevant skills
Use the same evaluation tables as setup-routing to determine which Superpowers and GStack skills are relevant. The tables are reproduced here for reference:
Superpowers skills:
| Skill | Consider relevant when... |
|---|---|
/superpowers:brainstorming |
Almost always — skip only for trivial projects |
/superpowers:writing-plans |
Almost always — skip only for single-file changes |
/superpowers:subagent-driven-development |
Projects with 5+ tasks, benefits from parallel TDD |
/superpowers:executing-plans |
Smaller projects (< 5 tasks), or when user wants more control |
/superpowers:systematic-debugging |
Any project with code that can have bugs |
/superpowers:dispatching-parallel-agents |
Projects with clearly independent modules |
/superpowers:using-git-worktrees |
Projects where feature isolation matters |
/superpowers:finishing-a-development-branch |
Projects using feature branches and PRs |
/superpowers:test-driven-development |
Projects with testable code (most projects) |
/superpowers:verification-before-completion |
Complex projects where correctness is critical |
/superpowers:requesting-code-review |
Multi-file changes (runs automatically during SDD, but can be invoked manually) |
/superpowers:receiving-code-review |
After /review or PR feedback requires code changes — structures the response with TDD |
/superpowers:writing-skills |
Only for Claude Code plugin/skill projects |
GStack skills — Phase 1 (Planning):
| Skill | Consider relevant when... |
|---|---|
/office-hours |
New product ideas, features with unclear scope |
/plan-ceo-review |
Projects with strategic decisions or significant scope |
/plan-eng-review |
Projects needing architecture decisions |
/plan-design-review |
Projects with UI/UX components |
/design-consultation |
New projects defining a design system from scratch (creates DESIGN.md) |
/design-shotgun |
When you want multiple design variants to compare before committing |
/plan-devex-review |
Projects with developer-facing surfaces (APIs, CLIs, SDKs, libraries) |
/plan-tune |
Tune plan-skill question preferences (one-time, per-project) |
/autoplan |
When all three plan reviews are relevant — chains them automatically |
GStack skills — Phase 3 (Review & QA):
| Skill | Consider relevant when... |
|---|---|
/review |
Almost always — pre-merge code review |
/qa <url> |
Projects with a browser-accessible UI (include the URL) |
/qa-only <url> |
Same, but report-only (no auto-fixes) |
/cso |
Projects handling auth, user data, payments, or external APIs. For security-critical features, run BEFORE /review |
/design-review |
Projects with visual UI — catches spacing, alignment, inconsistencies |
/design-html |
When you have an approved design and need production HTML/CSS |
/devex-review |
Developer-facing projects — live audit of onboarding flow, docs, CLI help |
/investigate |
Bugs discovered AFTER Phase 2 — in QA, staging, or production. Do NOT use during Phase 2 implementation (use /superpowers:systematic-debugging instead) |
GStack skills — Phase 4 (Ship & Monitor):
| Skill | Consider relevant when... |
|---|---|
/ship |
Projects using git with feature branches and PRs |
/land-and-deploy |
Projects with CI/CD deployment pipelines |
/canary |
Projects with production monitoring needs |
/landing-report |
Read-only PR queue + sibling-workspace dashboard (workspace-aware ship) |
/setup-deploy |
One-time: configure deploy platform (Fly.io, Vercel, Render, etc.) for /land-and-deploy |
/document-release |
Projects with documentation to maintain |
/retro |
Team projects with regular sprint cadence |
/learn |
Long-running projects (> 2 weeks) — saves cross-session learnings |
/setup-gbrain |
Long-running projects wanting cross-session memory (PGLite local or Supabase) |
/sync-gbrain |
Long-running projects with gbrain — keeps the brain current with this repo's code and refreshes CLAUDE.md search guidance |
/health |
Projects with existing linting, type checking, or test suites |
/make-pdf |
Projects needing publication-quality documentation or reports |
GStack skills — Utility:
| Skill | Consider relevant when... |
|---|---|
/careful |
Projects where destructive commands are risky (production DBs, shared infra) |
/freeze |
Monorepos or projects where edits should be restricted TO a specific directory (allow-list, not block-list) |
/unfreeze |
Clear the /freeze boundary mid-session without ending the session |
/guard |
Production / shared-infra work — combines /careful warnings with /freeze directory lock |
/browse |
Projects needing headless browser interaction beyond QA |
/scrape |
Projects pulling data from web pages — prototypes a flow once, codifies it via /skillify |
/skillify |
After a successful /scrape — persists the flow as a permanent browser-skill so future calls run in ~200ms |
/open-gstack-browser |
Projects wanting a visible AI-controlled Chromium with live activity feed |
/pair-agent |
When pairing a remote AI agent with your browser session |
/setup-browser-cookies |
One-time: import cookies for authenticated /qa and /browse testing |
/context-handoff |
Long implementation sessions, projects using SDD, or any multi-step workflow |
/htmlify |
Any project — generates beautiful HTML companions for MD artefacts (design docs, plans, handoffs) so verbose output stays readable. Optional PostToolUse hook auto-fires. |
/context-save |
Save progress and working state |
/context-restore |
Resume where you left off |
/benchmark |
Projects with performance monitoring needs |
/benchmark-models |
Projects comparing AI model performance |
/codex |
Projects needing second opinions or adversarial code review |
/superpowers-gstack:autoimplement |
Multi-phase plans where the user always confirms phase boundaries — chains /review + /pitfall-verification automatically (pitfall auto-chains /codex review + the third lens per tier — no separate codex step). v2.14.0+ adds active pre-flight that reviews the plan body itself before Phase 1 unless the latest plan commit matches the marker regex ^(chore|fix)\(plan\):[[:space:]]*pre-flight([[:space:]]|$) (closes the gap between writing-plans and autoimplement). Refuses on <2 phases, missing per-phase commit steps, dirty tree, main/master branch, or plans touching migrations/secrets/credentials/.env/.ssh. |
/superpowers-gstack:office-hours-track-aware |
All new-project brainstorming — wraps /office-hours with track inference (web vs native), inline platform question, design-doc relocation, htmlify --open, and approve-before-render gate. Intercepts /office-hours — see routing-intercept rules below. |
/superpowers-gstack:swiftui-design-consultation |
Native SwiftUI projects — produces DESIGN.md + Swift Package starter; equivalent to /design-consultation for web. Inlines the platform question (iOS/macOS/both) on first run if .gstack/track is missing. |
/superpowers-gstack:macos-native-review |
macOS apps — pre-implementation HIG-citation-grounded review (vocabulary, controls, keyboard shortcuts, semantic colors, sheets, menu bar, dock, App menu). Run on PRDs/specs/plans before implementation. Phase 0 detects macOS signals; auto-N/A for non-macOS projects. |
/superpowers-gstack:ios-native-review |
iOS / iPadOS apps — pre-implementation HIG-citation-grounded review (vocabulary, touch targets, navigation paradigm, modal presentation, gestures, system surfaces, keyboard, haptics, semantic colors, animation, privileged operations, accessibility, lifecycle). Run on PRDs/specs/plans before implementation. Phase 0 detects iOS signals; auto-N/A for non-iOS projects. |
/superpowers-gstack:quality-review |
After any PRD/spec/plan, before implementation — hunts perceived-quality pitfalls (silent failures, loading/empty states, error recovery, state drift). Complementary to pitfall-verification ("will it work?" vs "will it feel good?"). |
/superpowers-gstack:verify-and-land |
Apple + web projects — after a fix, builds the checked-out branch, launches that exact bundle (not the installed copy), proves which build is on screen, gates on the user seeing the fix, then pushes and offers merge/PR. |
/superpowers-gstack:e2e-route |
Swift projects — pure dispatcher for E2E test requests: reads platform × intent and routes to the right executor (scaffold skills, MCP-live simulator automation, visual review, ios-visual-explore). |
/superpowers-gstack:ios-e2e-scaffold |
iOS SwiftUI apps — one-shot XCUITest scaffolding (TabView/NavigationStack scene-walk, TIER-ranked stubs, iOS-Simulator xcresult runner). Normally reached via /e2e-route. |
/superpowers-gstack:macos-e2e-scaffold |
macOS SwiftUI apps — one-shot XCUITest scaffolding (Scene-walk, TIER-ranked stubs, xcresult runner). Normally reached via /e2e-route. |
/superpowers-gstack:ios-visual-explore |
iOS/iPadOS apps — Tier-2 visual exploration via Gemini computer-use when the accessibility tree is insufficient (layout regressions, visual landmarks). Paid API per run; normally reached via /e2e-route. |
/superpowers-gstack:spec-drift |
Any project with plans in docs/superpowers/plans/ — standalone "does this plan still match the code?" audit: runs /ship Step 8's plan-completion section from disk (hash-pinned) against an explicit plan and base, on any branch, shipped or not. Report + JSON + exit 0/1/2; never edits code. |
Step 4: Identify gaps and plan changes
Compare the current project state against what Superpowers + GStack needs. Check each item:
CLAUDE.md routing:
- Does
## Skill routingsection exist? - Does it include the correct skills for this project?
- Does it have Routing Logic, Rules, and Session Management?
- Does it have a
## Model Routingsection (v0.2+)? If not, this adaptation will add one. - Is there existing content that must be preserved?
Project structure:
- Does
docs/superpowers/exist? (needed for specs and plans) - Is there a feature branch workflow? (needed for
/reviewand/ship) - Is there a remote configured? (needed for
/reviewand/ship)
Potential conflicts:
- Does CLAUDE.md have instructions that contradict the workflow? (e.g., "never use subagents", "don't use TDD")
- Are there existing hooks or workflows that might conflict?
- Is the project on
mainwith no branches? (needs branching strategy)
Present the gap analysis to the user:
Ready for Superpowers + GStack:
- [things that already work]
Needs changes:
- [what needs to be added/modified — be specific]
Potential conflicts:
- [anything that might cause issues]
Shall I proceed with these changes?
STOP HERE. Do not continue to the next step until the user responds. Do not add "Next steps", suggestions, or any other content after the question. End your message with the question.
Step 5: Apply changes
Apply the changes identified in Step 4. Follow these rules strictly:
Snapshot before the first write. Before modifying CLAUDE.md — before any other rule in this step:
mkdir -p .gstack
# Rotate, never overwrite: the second /adapt after a bad first one is exactly the
# recovery case, and overwriting would destroy the only copy of the original.
[ -f .gstack/CLAUDE.md.pre-adapt ] && \
mv .gstack/CLAUDE.md.pre-adapt ".gstack/CLAUDE.md.pre-adapt.$(date +%Y%m%d-%H%M%S)"
cp CLAUDE.md .gstack/CLAUDE.md.pre-adapt
# Keep the snapshots out of git WITHOUT touching the user's tracked .gitignore.
EXCL="$(git rev-parse --git-path info/exclude 2>/dev/null)"
if [ -n "$EXCL" ]; then
mkdir -p "$(dirname "$EXCL")"
grep -qxF '.gstack/CLAUDE.md.pre-adapt*' "$EXCL" 2>/dev/null \
|| echo '.gstack/CLAUDE.md.pre-adapt*' >> "$EXCL"
fi
.gstack/ already holds track, so this introduces no new location. This snapshot is
what Step 6 diffs against and what the user restores from if the run goes wrong. Do
NOT substitute git diff for it: the project may have uncommitted CLAUDE.md changes,
and CLAUDE.md may not be tracked at all. If CLAUDE.md does not exist yet, skip the
copy — there is no prior content to lose — and say so in the Step 6 report.
Three details, each of which was missing and each of which defeats the snapshot on its
own. Rotate rather than overwrite: a user who runs /adapt again after a bad run
would otherwise replace the good original with the bad result — the one scenario the
snapshot exists for. Exclude it via .git/info/exclude (local, so it does not edit
a tracked .gitignore the user owns): a committed stale copy of an instruction file is
read by future agents as if it were current. Name it in the report (Step 6), because
a restore point nobody is told about is not a restore point. If git rev-parse fails
this is not a git repository — skip the exclude silently and carry on; the snapshot
still works.
CLAUDE.md updates:
Read the plugin version from
.claude-plugin/plugin.jsonin the superpowers-gstack plugin directory (check~/.claude/plugins/cache/*/superpowers-gstack/*/plugin.json, use the latest). Add or update the two-line HTML header at the very top of CLAUDE.md — rewrite both lines every run, so the warning stays current without needing a marker of its own:<!-- superpowers-gstack: {version} --> <!-- Sections whose heading carries a gstack-<name>-vN marker are plugin-managed: /adapt replaces each one wholesale on upgrade. Put project-specific findings — the measurement you took, the flag that worked — in your own H2 section with no marker; /adapt leaves those alone. One exception: the headings it manages are reserved even when unmarked (the marked ones in this file, plus Model Routing), because an unmarked copy of one reads as an older emitted section. Prefix your own headings with this project's name and none of them can collide. -->Keep the second line as a single HTML comment with no nested
<!--inside it: HTML comments do not nest, so an inner opener followed by the first-->would end the comment early and render the remainder as visible text.If the file already carries the one-line header that 2.47.0 and earlier wrote (
<!-- superpowers-gstack: X.Y.Z -->alone), replace that line in place with both lines. Do not leave the old line standing above or below the new pair — two version comments in one file is one of them lying, and the reader has no way to tell which.If CLAUDE.md exists: READ it first, then INSERT or UPDATE the
## Skill routingsectionNEVER delete or rewrite existing sections (conventions, tech stack, project-specific rules)
If a
## Skill routingsection already exists: UPDATE its plugin-managed subsections per the per-section case-logic below (cases 1-4 for each marker-section). Do NOT wholesale-replace the entire Skill routing block — that would destroy any user-authored subsections nested inside (e.g. a hand-written### Code reuse disciplinemarkerless heading). The per-section logic handles every plugin-managed subsection individually; anything inside Skill routing that the per-section logic does NOT match must be PRESERVED verbatim, including its position and surrounding whitespace.If no
## Skill routingsection exists: ADD it after the first heading (or at the top if no heading)The routing section follows the same template as
setup-routingStep 6, adapted to this project. Keep the generated content tight — every word is a per-session context tax on the project: routing-table row descriptions ≤ 15 words; decision-tree lines ≤ 10 words; no rationale prose in generated sections (the rules carry the behavior; the why lives in this plugin's docs).Model Routing (v0.2): read the canonical routing table from
~/.claude/plugins/cache/*/superpowers-gstack/*/skills/setup-routing/model-routing.md. Infer this project's domain sensitivity from the project analysis and Step 3 evaluation:Real-time audio / DSP / signal processing, or any lock-free concurrency (incl. Swift audio engines, game-audio) → very high — NB: a plain Swift/SwiftUI CRUD or UI app with none of these signals is medium, not very high
Database migrations / ETL / data-transform, OR security concerns (auth/payments/PII/external APIs) → high
Web/mobile app UI feature work → medium
CLI tools / libraries / format-plumbing / serialization → low
If ambiguous, ask the user one line: "How silently could a subtle bug here compound — very high / high / medium / low?"
First, replace any stale Model Routing block. If the project's existing CLAUDE.md already has a Model Routing section from a prior plugin version — whether a v0.1
### Model Routingsubsection (the one with Pi/MLX/local-model columns) or an older top-level## Model Routing— DELETE that entire section (from its heading through the line before the next heading of equal-or-higher level) before emitting the new one. This is an explicit exception to the "never delete existing sections" rule above: Model Routing is fully plugin-managed, so a stale copy must be replaced, not preserved alongside the new block — otherwise the generated CLAUDE.md carries two contradictory routing tables (old Pi/MLX + new Claude-only). Apply the Attribution check below to it as well —Model Routingcarries no marker, and this is the one place/adaptDELETES rather than replaces, so an unattributable section is gone outright rather than merely overwritten. Sentinel: the body carries a routing table with a model column (the v0.1 Pi/MLX/local-model columns, or aModel/Sensitivitycolumn). If it carries none, the heading is the project's own: leave it untouched, skip emitting the plugin's Model Routing this run, and tell the user to rename their section and re-run/adaptif they want the plugin-managed one.Then emit a top-level
## Model Routingsection (placed after## Skill routingand all its subsections): readblocks/model-routing-section.mdfrom the plugin'sskills/setup-routing/blocks/directory (same path resolution asmodel-routing.mdabove) and emit its content verbatim, substituting{{DOMAIN_SENSITIVITY}}with the inferred value.Fallback: If
model-routing.mdis missing (older cached plugin), warn the user and skip the section entirely.If the user opts out, skip this section entirely and note the choice in the final report
Shared block files. Every "block to insert" below is single-sourced in the plugin at skills/setup-routing/blocks/<name>.md (sibling skill directory — from this skill's base directory: ../setup-routing/blocks/<name>.md; via the cache glob: ~/.claude/plugins/cache/*/superpowers-gstack/*/skills/setup-routing/blocks/). Read the named file and use its content as the verbatim block. Resolve {{...}} placeholders per blocks/PLACEHOLDERS.md before inserting — never let a raw {{...}} token reach the generated CLAUDE.md. If the blocks directory is missing (older plugin cache), warn the user to run /plugin update superpowers-gstack and skip the affected sections.
Record what you emitted. When you write a block into CLAUDE.md, add a SECOND HTML comment on that block's heading line, immediately after the version marker the block file itself carries, with nothing at all between the two:
<!-- gstack-git-hygiene-v9 --><!-- emitted=162 -->
Leave the version marker byte-for-byte as the block wrote it. Provenance is a separate comment precisely so that marker keeps matching for every reader that knows only the bare form: an older plugin cache meeting a file this release wrote finds its marker exactly where it expects it and skips the section as current, instead of reading it as markerless and appending a duplicate. Putting the attribute inside the marker breaks that; putting it on a line of its own adds a line to what the next run counts, and is a line a user tidying their own CLAUDE.md can delete.
This applies to a block whose file carries a version marker, which is what the second
comment attaches to. blocks/model-routing-section.md carries none, so it gets no
provenance: an emitted= with no marker beside it is a number no reader is looking for,
and the growth check never runs on that section — Model Routing is replaced outright.
<N> is wc -l of the block file you just read — every line in the file, counted
before any placeholder substitution and before any heading-level demote. This is the
only fact that makes a later upgrade able to tell growth from a block that simply
changed size, so do not estimate it and do not carry a stale value forward from the
section you replaced. Block files themselves never carry emitted=; a constant baked
into the source would lie the moment the block changed length.
Growth check — applies to every marker-managed section below, in cases 2 and 3. A marker records who created a section, not who has written in it since. Before replacing any section, compare its length against the block's:
TMP="$(mktemp)"
sed -n '<start>,<end>p' CLAUDE.md > "$TMP"
wc -l "$TMP" <path-to-block>.md
You already know <start> and <end> — finding them is how you perform the REPLACE
at all. Read the section from CLAUDE.md, not from the snapshot, and do not
"helpfully" repoint this at .gstack/CLAUDE.md.pre-adapt. <start> and <end> are
line numbers in the LIVE file, and by the time this gate runs Step 5 has already
written above the section — the new header line, the ## Skill routing insert, the
## Model Routing replace. Those same numbers land lower in the snapshot, so the
window slides off the section and past EOF returns nothing. Truncation only ever
shortens, so the ratio only ever falls: the gate goes quiet exactly when it should
fire. Measured on this branch's own fixture (196-line section, 78-line block, true
2.51×): 40 lines inserted above → 2.04× (fires), 90 → 1.40× (silent replace), 200 →
0.00× (silent replace). The section is still unmodified in CLAUDE.md at gate time
and the line numbers came from that same file, so reading it there is the only
self-consistent choice. The snapshot's job is Step 6's whole-file diff, not this.
Then run the diff — always, before deciding. The Volume proxy is read off it, and so is the at-risk list you show the user when the gate fires:
diff "$TMP" <path-to-block>.md
The gate fires when any of the three triggers below holds. Run all three every time — they are checked together, not in precedence order, and the first one to fire is enough.
Provenance (measured, not inferred). — the section's heading line carries a second comment
<!-- emitted=<N> -->after the version marker, and the section is now more than ~20 lines longer than<N>. The plugin wrote exactly<N>lines there, so everything above that came from somewhere else. This is the only one of the three that is a measurement rather than a proxy: a block that grew or shrank between releases moves the ratio, and it cannot move<N>.awk 'NR>=<start> && NR<=<end>' CLAUDE.md | wc -l # what is there nowCount the two sides the way each was counted.
<N>iswc -lof the block file as it shipped; the number above is the section's lines in CLAUDE.md, heading line through the last line before the next heading of equal-or-shallower level. Placeholder substitution and a trailing blank line move the total by a line or two, so the two counts are close rather than equal. The ~20-line threshold exists partly to absorb that; do not tighten it to chase an exact match.Distrust an implausible
<N>. Nothing verifies it — it is a number a past run wrote down. Ignore it, and decide on the other two triggers alone, when either the section is at or below<N>(the plugin cannot have emitted more lines than are there, so the count is wrong), or<N>is more than ~20 lines ABOVE the block file's current length (blocks grow between releases far more often than they shrink, so a<N>well over today's block is a miscount, not history). A<N>well BELOW the block is ordinary — that is just an older, smaller block — and it is fine.Ratio (proxy). — the section is more than 1.5× the block's line count.
Volume (proxy). — more than ~20 of the section's lines carry material the block does not have in any form. Not reworded block prose, which a version bump produces by the dozen; lines whose subject matter is absent from the block entirely.
A section with no emitted= — everything written before 2.49.0 — has only the two
proxies, and they are why provenance exists. Where provenance IS present it adds a
reason to stop; it never removes one. That precedence is deliberate and it is not
symmetric: a trigger that fires when it should not costs one question, and a trigger
that stays quiet when it should not costs the user whatever they had written. An
emitted= that is wrong by a little is the likeliest failure of this whole mechanism,
and letting it silence two working proxies would make this release worse than the one
before it for exactly the sections it was built to protect.
Neither proxy alone is enough, which is why there are two. Ratio scales with the block, so
one threshold buys wildly different exposure: 1.5× of the 162-line git-hygiene.md is
81 losable lines, 1.5× of the 23-line companion-skills.md is 11 — a 7× difference
from the same number. Volume is flat, so it catches the small-block case the ratio
sleeps through.
When the gate fires, do not replace the section silently:
Collect the at-risk lines from the diff you just ran: the
<lines that are not simply a reworded version of block prose. That is the content at risk.Ask the user, naming the section and the number of lines at risk, and offer two outcomes: move that content into a new unmarked H2 section (recommended — give it a heading starting with the project's own name, so it can never collide with a heading the plugin manages, and it survives every future upgrade), or leave this section at its old version and skip its upgrade.
Do not proceed past this gate without an answer. This is a category-3 stop under the Autonomy rules — genuinely ambiguous, with materially different consequences — and the one place in
/adaptwhere silent correctness is worse than asking. A wrong guess here is unrecoverable for the user; the cost of asking is one question.Non-interactive runs — nobody is there to answer. Take the preserving branch without asking: leave the section at its old version, do not replace it, and list it in the report's Deferred (grown past its block, not upgraded): block, naming the section. A stale section is recoverable; a deleted one is not.
Be precise about when this applies. Two
STOP HEREgates sit above Step 5 — the Step 2 stack confirmation and the Step 4 "shall I proceed" — so a bareclaude --print "/adapt"never reaches this gate at all; it stops at the first one. Rule 4 is for a run that got past those gates and then meets a question it cannot put to anyone: a prompt that pre-answered them, an orchestrator running/adaptas one step of something larger, a subagent with no channel back to the user. Do not read it as "--printmeans proceed" — assuming that reachability is exactly what made this branch's first test harness report PASS while proving nothing.
The two proxies are heuristics, and neither establishes authorship — a line count is
not a byline. They are cheap stand-ins for "someone has been writing in here", chosen
because they are computable from what the gate already reads. Provenance is not one of
them: it is a measurement against a number the plugin wrote down, which is why it can
only add a reason to stop and never subtract one. A section at 1.1× is usually a
user fixing a typo in plugin prose; the run that motivated this gate was at 2.7× — a
73-line block against a 198-line section, and the 125-line delta held an
-allowProvisioningUpdates discovery, three lessons about running on a physical
iPhone, and a note on a tool's current status. None of it was recoverable from the
plugin.
The real test is a three-way compare against the block the section was originally
emitted from, which separates project content from plugin drift instead of guessing.
Provenance closes the length half of that as of this release — emitted=<N> is the
originally-emitted length itself, not a ratio against a block that may have grown or
shrunk since. What it still cannot see is a same-length edit: replace ten lines of
plugin prose with ten lines of a user's own and the count never moves. Closing that
needs the emitted block's own content, or a hash of it, recorded in the marker — a
further format change across all nine blocks and both generators. It is deferred until
the first report of a section lost with all three triggers quiet, or the next time a
block shrinks between releases. Deferred alongside it: a volume-neutral fixture — a
section that restates the block's own material more verbosely, so it is more than ~20
lines over <N> while almost none of its lines are absent from the block. The fixture
that exists is both, so the integration test proves the gate fired, not which trigger
fired it; build the neutral one the first time provenance and Volume are suspected of
disagreeing in the field. One residual is known and accepted: the sanity band's ~20 and
the trigger's own ~20 stack, so an <N> overstated by up to ~20 buys roughly 40 lines
of growth in which only Volume — the judgement-call proxy — is still watching.
Attribution check — applies to case 3 of the six sections below that replace on a
missing marker. Three do not need it: Code reuse discipline already preserves,
Session Continuity has its own handoff.md content test, and Track-aware routing
carries a heading this plugin coined, which no project would write by accident.
Case 3 is "heading present, marker absent", and it replaces on the theory that a
markerless copy must be pre-marker plugin legacy. That theory is a guess, and it is
wrong exactly where it costs most: most of these headings are ordinary English that a
project would plausibly write for itself. A hand-written 15-line
Git hygiene & commit cadence holding a team's own conventions is 0.1× its block, so
the Growth check never fires and case 3 replaces it without a word.
So case 3 does not fire on the heading alone. Each rule below names a sentinel — a string only a past emitter would have written into that section. Before replacing:
Sentinel present in the section body → it is emitted content. REPLACE as in case 2, still subject to the Growth check above.
Sentinel absent → you cannot attribute the section to a past emitter. Do NOT replace it. Leave it byte-for-byte intact, insert the plugin block as a separate H2 section immediately below it, and report the outcome in these terms:
<heading>: I cannot attribute this section to a past emitter — it has no version marker and none of the phrases an older/adaptwould have written. I left it exactly as it was and put the current plugin version below it, so nothing of yours was touched. If it is an old plugin section, delete your copy and re-run/adaptand it will upgrade cleanly.Two sections sharing a heading is a state the user has to resolve, so tell them which one is theirs and what resolves it. A report that only says "both now exist" leaves them to work out both.
This is Code reuse discipline's case 3 and Session Continuity's handoff.md test
generalised, and it accepts one failure to avoid a worse one: an old emitted section
that has drifted past its sentinel gets preserved instead of upgraded. A stale section
costs one /adapt run after the user deletes it; a destroyed one costs whatever was
in it.
Insert or upgrade the Autonomy and user interruption section. This section applies to ALL projects (web and native equally — agents over-asking is platform-agnostic). Scan CLAUDE.md for the heading ^#{2,3} Autonomy and user interruption and its version marker <!-- gstack-autonomy-vN -->. Apply the same four-case logic:
- Heading present + marker matches
v2→ skip (idempotent). - Heading present + marker present + different version → REPLACE through next heading of equal-or-shallower level. Preserve original heading level. Run the Growth check above before replacing. If the existing root is H3 (nested under
## Skill routing, as pre-2.34.0 setup-routing emitted), you MUST demote every subsection in the replacement block one level (H3 → H4) so subsections do not sit at the same level as the root — same demote requirement as case 4 below. - Heading present + marker absent (legacy pre-v2.8.0) → REPLACE the same way; one-time silent upgrade adds the current marker. Run the Attribution check above FIRST — replace only if the sentinel is present; if it is absent, preserve the section and insert the block below it — then the Growth check before replacing. Sentinel: the body contains
The only five reasons to stop and askorForbidden phrases. - Heading absent → APPEND the block below as H2 (subsections stay at H3, one level below the root — the REPLACE-through-equal-or-shallower-heading invariant holds). If you instead insert the block under
## Skill routingas H3 to matchsetup-routing's structure, you MUST also demote every H3 subsection in the block to H4. Otherwise the H3 subsections sit at the SAME level as the H3 root, and the next marker upgrade stops at the first subsection and leaves stale content behind — same heading-hierarchy class bug/codex reviewflagged on the v2.12.0 Code reuse section.
The block to insert: read blocks/autonomy.md (see Shared block files above) and insert its content verbatim.
Insert or upgrade the Git hygiene & commit cadence section. This section applies to ALL projects (git is universal). Scan CLAUDE.md for heading ^#{2,3} Git hygiene and its version marker <!-- gstack-git-hygiene-vN -->. Apply the same four-case logic:
- Heading present + marker matches
v9→ skip (idempotent). - Heading present + marker
v1orv2(older emitters — universalist convention rule, autonomy cross-ref missing, stash advice without WIP-branch caveat) OR different version → REPLACE through next heading of equal-or-shallower level. Preserve original heading level. Run the Growth check above before replacing. (The Git hygiene block has H4 subsections; "next heading" alone would stop at the first one and leave old v1 prose behind.) If the existing root is H3 (nested under## Skill routing, as pre-2.34.0 setup-routing emitted), you MUST demote every subsection in the replacement block one level so subsections do not sit at the same level as the root — same demote requirement as case 4 below. - Heading present + marker absent → REPLACE the same way; one-time silent upgrade adds the current marker. Run the Attribution check above FIRST — replace only if the sentinel is present; if it is absent, preserve the section and insert the block below it — then the Growth check before replacing. Sentinel: the body contains
Hygiene rules (NEVER violate)orCommitting is not backing up. - Heading absent → APPEND the block below as H2 (subsections stay at H3, one level below the root — the REPLACE-through-equal-or-shallowe
…(truncated)