Super Bootstrap — Development Pipeline for Any Repo
Set up (or sync) the development pipeline in a project. Installs harness — workflow rules, doc-sync gate, skeleton docs, the core plugin pin — in one scaffold session. The doc-sync gate at every later commit grows the skeleton docs over time, so there's no deferred deep-scan stage.
Designed for a solo developer working across multiple Claude Code sessions and cloud Claude Code.
Phase 1: Quick Scan (lightweight, parallel reads)
Gather just enough to scaffold — skim manifests for stack/version, note structure shape, stop.
Check contributor count (git shortlog -sn --all | head -5). If >1 active contributor, surface as info — don't block:
"FYI: detected multiple contributors. The pipeline's CLAUDE.md assumes solo dev (simple branching, no PRs for self-review). You can edit those sections after bootstrap if your team's workflow differs."
Sampling Discipline (applies to all source-file reads)
Throughout this skill — Phase 1 detection, anywhere Claude reads source files — paraphrase structure into committed docs; never paste raw file contents. Skip files whose names suggest secrets (e.g. .env*, *.key, *.pem, id_*, *credential*, *secret*, .npmrc, .netrc, *.p12 / *.pfx, *.keystore, kubeconfig — illustrative, judge by name).
When skipping, surface to user: ⊘ skipped <path> (likely secret).
Reason: reading alone isn't the breach — Claude's context isn't shared. The breach is quoting raw content into auto-committed docs (techstack.md, overview.md): a gitignored secret becomes permanent in git history. Defense lives in the write step. The illustrative list seeds pattern recognition for the skip step; new secret-bearing patterns are judged by name, not table lookup.
Manifest Detection
Detect language/runtime by manifest files at repo root (e.g. package.json, tsconfig.json, pyproject.toml / requirements.txt, Cargo.toml, go.mod, Gemfile, pom.xml / build.gradle, composer.json, pubspec.yaml, CMakeLists.txt / Makefile, *.csproj / *.sln — illustrative, not exhaustive). Don't read fully — skim each for runtime/version, top-level deps, scripts/build commands. Cover unlisted stacks (Bun, Deno, Zig, Elixir, Gleam, etc.) by analogy from the manifest's contents.
Code presence. A manifest, or any source file (e.g. .js / .ts / .py / .go / .rs / .sh — scripts included; illustrative, judge by analogy), sets code present. Neither → docs-only repo: the code-touch pair — CLAUDE.md § Coding Principles and CODING_STANDARDS.md — is not applicable, the way monorepo-only sections are on a single-package repo (§ Pipeline-owned): the drift walk skips both and the receipt's covered omits them. A re-run that finds code raises both as ⊕ new (§ 2b, § 2a). A pair an earlier bootstrap placed on a docs-only repo stays as the consumer left it — the walk carries no removal path.
Quick Structure
lsroot directory- Check for:
docs/,README.md,CLAUDE.md,.claude/, monorepo indicators - Note existing doc structure (don't read docs deeply yet)
Monorepo detection
Check the repo root for a workspace manifest — the marker that one root hosts multiple packages (e.g. pnpm-workspace.yaml, turbo.json, nx.json, lerna.json, a package.json carrying a "workspaces" field, Cargo.toml with a [workspace] table — illustrative, judge by analogy). Present → set monorepo tier.
On monorepo tier, enumerate packages from the workspace globs (apps/*, packages/*, etc. — read the actual globs from the manifest, don't assume the layout). Each resolved directory with its own manifest is a package; record { name, path, role, build command } per package for the Phase 2b techstack.md § Packages table rows (§ 2b) and the CLAUDE.md monorepo block.
Rule-signal detection (below) then fans out per package instead of scanning root-only: the frontend-component-dir signal is checked inside each package, and a fired signal seeds its rule file with a package-scoped path glob (apps/*/src/components/**) rather than a root glob (src/components/**). One path-scoped rule carries the whole boundary — no nested CLAUDE.md needed.
No workspace manifest → single-package repo; skip, everything stays root-scoped.
Existing CLAUDE.md
If it exists, read it. The pipeline may already be partially or fully present — note what's already there. Also note legacy-skeleton blocks (Coding Standards code-block walls, framework-specific patterns under pipeline-owned headings, large Project Structure trees) — these become migration candidates in Phase 2b. Default route for enforcement-shaped content (imperatives, "must / never / always") is .claude/rules/<scope>.md; only browsable reference goes to docs/techstack.md grown sections. See Phase 2b migration table.
Rule-signal detection
Phase 1 also flags which .claude/rules/*.md files Phase 2b should seed. Signals (illustrative — judge by analogy):
- Frontend component dir detected (e.g.
src/components/,src/pages/,app/,components/) + framework manifest (React / Vue / Svelte / Angular / Solid) → seedrules/<framework>.mdfromassets/rules-frontend-skeleton.md. - Chrome MV3 manifest (
manifest.jsonwith"manifest_version": 3+service_workerfield) ORsrc/background/dir → seedrules/mv3.mdfromassets/rules-mv3-skeleton.md. - Migrations dir (
migrations/,db/migrate/,prisma/migrations/) → flagrules/migrations.mdfor body-fill via doc-sync (machinery-only seed at scaffold). - Tests dir with non-trivial structure (
tests/,__tests__/,*.test.*patterns) → flagrules/tests.mdfor body-fill via doc-sync.
On monorepo tier (§ Monorepo detection), each signal is evaluated per package, not root-only, and a fired signal's seeded glob is package-scoped (apps/*/src/components/**) so one rule file spans every package that shares the pattern.
ECC-first seed source for language-scoped rules. Before scaffolding from local assets/rules-*-skeleton.md, check ECC (gh api repos/affaan-m/everything-claude-code/contents/rules) for a matching language/framework rule. If ECC ships one, propose seeding from ECC (with attribution comment + license note) — defer to specialists. Local skeletons are the fallback. Cross-cutting / project-specific rules (e.g. MV3, custom service-worker patterns) stay on local skeletons.
Adjacent stacks (Bun + Next, Deno + Fresh, Tauri + React, etc.) infer by analogy. Unknown stacks → skip rule-seeding for that signal; user can add later.
Output of Phase 1: A mental model of "what kind of project is this" — stack name, structure shape, maturity level, which rule files to seed in Phase 2b, which legacy CLAUDE.md sections need migration. NOT a deep analysis.
Greenfield (no seed docs)
The generic runway runs on greenfield. If Phase 1 detects a docs-only repo (§ Code presence — no manifests + no source files) whose docs/overview.md / docs/techstack.md are also missing, scaffold normally and write overview.md / techstack.md as empty skeletons in Phase 2b. The entry /super-bootstrap seeds GAP cards against those empty skeletons and surfaces the gate.
When docs/overview.md + docs/techstack.md already carry substantive content, manifest facts and existing content feed the Phase 2b skeletons normally.
Rot signals (harnessed-but-stale)
Catches "harness installed but carries renamed-away literals" — re-run is the right entry, flag before Phase 2b churns through migrations.
Trigger: any pipeline-owned file (CLAUDE.md, docs/overview.md, docs/techstack.md, .claude/bootstrap.md, .claude/rules/*.md) contains a literal listed as old in assets/rename-map.md. Whole-token match; one hit is enough.
When the trigger fires, surface ONCE up front (single message, not a redirect — re-run is the correct entry point):
Renamed-away literals detected in pipeline-owned files.
Phase 2b will propose migrations alongside the normal drift check.
Affected files: {list of files where rot was observed}.
Continue? (y / dry-run report only)
If user answers dry-run, walk Phases 1–2b without writing — render the sync report (per-section listing + rename-map migration rows) inline without persisting .claude/bootstrap-sync-report.md, then exit. Otherwise proceed normally; Phase 2b's rot scan (see § 2b) handles the actual migrations.
Output of Phase 1 (rot lane): record rot_hits[] so Phase 2b can re-use the scan instead of grepping twice.
Version-staleness signal (harnessed-but-stale)
Rot signals catch renamed literals; they miss template drift that shifted structure without renaming a token. The runway receipt closes that gap.
Read .claude/super-bootstrap-runway.json in the target repo (the runway coverage receipt — shape { "version": "x.y.z", "covered": [...], "declined": [...], "placed": { ... } }; covered lists the sections the last sync read-and-compared, declined a subset of covered the user declined to update at that version — divergence accepted, not pending; placed maps each file asset's destination path to the sha256 of the file as this pipeline placed it, so a later sync can tell a lagging copy from a consumer-edited one). Compare its version to the running plugin's own version — read version from the plugin's .claude-plugin/plugin.json, located at the plugin root two directory levels above this skill's base directory (skills/harness-bootstrap/ → skills/ → plugin root). That is the version currently installing/syncing.
- Marker stale (older) or absent → set
version_stale, consumed by Phase 2b to enforce the full drift check (see § 2b). Surface ONCE up front:- Stale:
runway stamped v{old} < plugin v{new} — full drift re-check enforced. - Absent:
runway carries no version stamp — full drift re-check enforced.
- Stale:
- Marker matches plugin version → judge the receipt: enumerate the pipeline-owned sections applicable to this repo (§ Pipeline-owned, honoring the tier conditionals — monorepo, scale module, code presence) and set-difference against
covered. A legacy version-only stamp carries nocovered— its coverage is unknown, so every applicable section counts as uncovered.- Difference empty → normal path.
- Difference non-empty → set
version_stalewith the gap list. Surface ONCE up front:runway stamped v{cur} but coverage gaps: {list} — full drift re-check enforced.
Detection only — Phase 1 reads the receipt and stops; it does not act on the flag or alter its own scan. Phase 2c overwrites the receipt later, after sync completes.
Output of Phase 1 (version lane): record version_stale (plus the old/new version strings, and the coverage-gap list when that was the trigger) for Phase 2b to consume.
Fact-staleness signal (detected facts vs last run)
The version lane asks whether the receipt is old. This lane asks whether the facts it was written against still hold. The receipt records what the last sync saw: covered omits CLAUDE.md § Coding Principles and CODING_STANDARDS.md on a docs-only run (§ Code presence), so a covered list carrying neither says the last sync ran against a repo with no code.
Set facts_stale when both hold:
- the receipt exists, its
coveredis present and non-empty, andcoveredcarries neitherCLAUDE.md § Coding PrinciplesnorCODING_STANDARDS.md - this run's § Code presence reads code present
Every other state leaves it unset: no receipt (fresh install — the facts seed this run), a legacy version-only stamp with no covered (coverage unknown, nothing to compare against), a docs-only repo still docs-only, or a repo whose last run already saw code.
Bound. The receipt records no manifest identity, so this delta keys on the code-presence transition alone. A manifest that changed, moved, or was added beside an existing one on a repo the last run already read as code-present raises nothing here.
Detected here, materialized at § 2b: the flag rides the sync report, not context. When set, § 2b's enumeration appends one facts: row to .claude/bootstrap-sync-report.md — facts: stale — last sync docs-only, code present now · manifest {file} · runtime {runtime + version} · framework {framework, or "none"} — beside the rot rows, and Phase 3 prints its advisory from that row alone (§ Phase 3). The receipt shape and the § 2c set-difference are unchanged: the row is a print source, not a coverage claim.
Output of Phase 1 (facts lane): record facts_stale, and with it the facts this run detected — manifest file name, runtime, framework (§ Manifest Detection) — for § 2b to write as the facts: row.
The runway scaffolds with no product Q&A. Drift on existing files is resolved inline per-section at Phase 2b.
Phase 2: Scaffold / Sync
Walk each pipeline artifact in order: folders → pipeline docs → sync report + commit. Same flow on fresh and re-run repos — fresh just sees "all new" at every step.
Per-artifact rule (applied uniformly in 2a / 2b):
- Missing → write from template / curate fresh
- Exists, matches template → skip (
✓ current) - Exists, drifted from template → show diff, get approval per change, then write
- Exists, pipeline-owned section absent →
⊕ new— show the template section, get approval, insert - Project-owned content → never touch, even on drift
Registration rule (2a / 2a-scale / 2b plantings, 2b-adopt deletions): a durable artifact this run places for the first time or deletes earns its own sync-report row — status ⊕ new for a planting, ⊘ removed for a deletion:
registration: {artifact} → {surfaces, or none}
{surfaces} names the consumer-authored surfaces that enumerate the artifact's class — a table or list carrying one entry per member (a glob that already covers the artifact needs no edit and is not a surface; a curated shortlist of a few files is not an enumeration). Grep each of four places for the artifact's path and for its parent directory string (docs/, .claude/skills/), and name every place whose hit is such a list:
.claude/rules/*.mdpaths:frontmatter entries that name paths literally- root
README.md— any table or list namingdocs/paths docs/**/README.mdanddocs/overview.md§ Module Index.claude/rules/*.mdbodies — any table or list namingdocs/paths (ownership / routing);CLAUDE.md's pipeline-owned sections are the plugin's own registration and stay out of this search
The row resolves updated once every named surface is edited, before § 2c runs, in the same commit — or none, earned only when all four greps return nothing. An unresolved row halts § 2c like a drifted one. The 2a-hooks and 2a-drain steps sit outside this rule, scripts included: the .claude/settings.json and .gitignore entries those steps already write are their registration.
Pipeline-owned (subject to drift check):
- CLAUDE.md sections: Development Workflow, Dispatch, Doc Sync, Coding Principles (code present only — Phase 1 § Code presence), Edit Discipline, Context Hygiene, Finding Triage, Rules, Git Notes, Planning, Monorepo (monorepo tier only — the conditional cross-package build block)
docs/techstack.mdskeleton sections: Runtime, Framework, Key Dependencies, Build & Distribution (seed-once — mechanics at § 2b; stale facts route to the Phase 3 advisory, § Fact-staleness signal), Edit Discipline (fixed prose — body drift-checked against the template), Packages (monorepo tier only — the § header + column shape; table rows are consumer-grown, project-owned)docs/overview.mdskeleton sections: Problem, User, Current Statedocs/decisions.mdscope header (the blockquote +## Closed Forksheading)CODING_STANDARDS.mdpreamble + section headings (code present only; drift checked againstassets/coding-standards-skeleton.md)docs/work/README.md,docs/work/TEMPLATE.mdAGENTS.md(foreign-executor contract — always placed; whole shipped body drift-checked againstassets/agents-md-skeleton.md).claude/rules/index.md(rule-authoring guide).claude/rules/<seeded>.mdskeleton bodies (drift checked againstassets/rules-*-skeleton.md).claude/settings.jsoncore plugin pin (enabledPlugins,extraKnownMarketplaces) — drift-checked for presence alone (§ 2a).claude/bootstrap.md(seeded plan — carries user checkbox state, so § 2b's special case governs re-run; the next session consumes it, its own Task 3 deletes it).claude/super-bootstrap-runway.json(runway coverage receipt{ version, covered, declined, placed }— presence + content checked, not diffed section-by-section; read at Phase 1, written at 2c —covered/declinedfrom the sync-report rows,placedfrom the file assets the ensure-infra procedures copied or verified current; durable marker, no cleaner — persists for the life of the harness)- Scale module — checked only when installed (detected by
docs/parked.mdpresence):docs/parked.md+docs/test-queue.mdheader/shape sections,docs/outward/README.md+docs/outward/TEMPLATE.md(whole files, the waydocs/work/README.md/docs/work/TEMPLATE.mdare),.claude/rules/venue-map.mdskeleton body (drift-checked againstassets/scale/rules-venue-map-skeleton.md— whole body, prose included), thedocs/work/README.mdfact-fields marker block (<!-- scale-module: fact fields -->…<!-- /scale-module -->), the CLAUDE.md § Rulesvenue-map.mdbullet block (drift-checked againstassets/claude-md-skeleton.md§ Rules)
Project-owned (never touched):
- CLAUDE.md: Tech Stack one-line (seed-once, same classification as the
docs/techstack.mdfact sections above — filled from Phase 1 detection facts when the runway first writes CLAUDE.md, consumer-edited from then on; no re-run rewrites it), Commands, any user-added custom sections docs/techstack.mdgrown sections: Architecture Rules, Coding Patternsdocs/overview.mdgrown sections: Module Index, Data Flow, Key Boundariesdocs/decisions.md§ Closed Forks table rows (consumer-filled history)CODING_STANDARDS.mdsection content (consumer-authored by hand when a convention settles — the file sits outside the doc-sync surface)AGENTS.mdgrown content (additions appended below the shipped sections).claude/rules/<rule>.mdgrown sections (additions the user/doc-sync added below the skeleton scaffold).claude/rules/<rule>.mdfiles the user authored without a matching skeleton (treat as fully project-owned)- Scale-module container content —
docs/parked.md## Entries+## Sweep logcontent,docs/test-queue.md## Pending/## Failed (re-queued for fix)rows, thedocs/outward/OUT-###.mdentry files (consumer-filled, like card content; only the skeleton headers/shape stay pipeline-owned) - Other settings in
.claude/settings.jsonoutside the plugin-pin keys
2a: Folders & core plugin pin
Folders + the core plugin pin don't drift — only two states: missing or present, because the skeleton's /super-bootstrap:* doors and the committed commit-channel.sh dangle without that pin.
Migrate before creating — docs/superpowers/ → docs/work/. Repos bootstrapped
before the rename hold their temporal specs and plans under docs/superpowers/. Creating
docs/work/ beside it would strand that work: every scan below — /super-bootstrap:todo,
drain, the classify pass — reads the new path only, so the old tree goes invisible
while still sitting in the repo. When docs/superpowers/ exists, git mv it to
docs/work/ first, then continue. If both exist, move the old tree's contents in
directory by directory and leave anything that would overwrite a file already at the
destination — report those paths rather than resolving them.
Always created (fixed macro):
docs/
decisions.md ← closed forks / rejected directions (history dimension — always scaffolded, starts empty)
specs/ ← feature specs, one .md per feature (empty + .gitkeep; files seeded by Task 1 of bootstrap-plan)
work/
README.md ← work-unit workspace header: contract, categories, ID high-water line
TEMPLATE.md ← copy-to-create card template
.claude/
rules/ ← path-scoped rules, full-body fires on file match
index.md ← rule-authoring guide (path-scoped — loads when editing rules)
For each: create if missing, skip if present. Add .gitkeep in empty folders. If docs/ or .claude/ already exists, nest alongside. Report status per directory.
Code present only (Phase 1 § Code presence — scaffold rule below):
CODING_STANDARDS.md ← repo binding conventions (headings-only scaffold; sections hand-recorded as conventions settle)
There is no docs/specs/ index file — the folder + filename convention IS the catalog. Spec files are seeded by Task 1 of the bootstrap plan, each opening with # {Feature Name} and a one-paragraph intro.
docs/specs/ is always scaffolded (empty folder + .gitkeep), matching overview.md / techstack.md / decisions.md. Spec files are seeded only when source-code features exist to document (Task 1 of the bootstrap plan) — the empty folder carries no speculative content.
docs/decisions.md is always scaffolded — copy assets/decisions-skeleton.md to docs/decisions.md if missing (no substitutions). Starts empty (header + ## Closed Forks table). Its scope header is pipeline-owned (drift-checked); the table rows are project-owned (never touched).
Copy assets/work-readme-skeleton.md to docs/work/README.md if missing (no substitutions). Copy assets/work-template-skeleton.md to docs/work/TEMPLATE.md if missing (no substitutions).
AGENTS.md is always scaffolded — copy assets/agents-md-skeleton.md to the repo root if missing (no substitutions). No code-presence gate: the build contract it carries binds a docs-only repo the same way. Its whole shipped body is pipeline-owned (drift-checked); anything the consumer appends below it is project-owned (never touched).
CODING_STANDARDS.md is scaffolded when code is present (Phase 1 § Code presence) — copy assets/coding-standards-skeleton.md to the repo root if missing (no substitutions); a docs-only repo takes no file, and a later re-run that finds code raises it as ⊕ new. Starts headings-only; its preamble states the fill contract and the three-way routing (binding + ambient here, binding + path-scoped → .claude/rules/<scope>.md, descriptive → docs/techstack.md § Coding Patterns). Preamble + headings pipeline-owned (drift-checked); section content project-owned, hand-recorded when a review or commit settles a convention — the file sits outside the doc-sync surface.
.claude/rules/ machinery is always scaffolded (zero-cost when empty). index.md is seeded from assets/rules-index-skeleton.md. Individual rule bodies fill in Phase 2b based on Phase 1 signal detection.
Core plugin pin (pre-resolve). The harness CLAUDE.md skeleton names one plugin by its own wiring:
super-bootstrap— the skeleton routes every door through/super-bootstrap:*, and the committedcommit-channel.shdeny text routes workers to/super-bootstrap:commit. All of it must resolve from the project pin alone on any boundary where the authoring device's user-scope settings don't apply (fresh clone, second machine, cloud session) — the committed hook fires there regardless of plugin state.
It is a core dep, not an adaptive pick — pinned here at 2a so tier-2 curation (/super-bootstrap:resolve-plugins, run later by /super-bootstrap) layers adaptive picks on a guaranteed base. Dangling-rule risk: if CLAUDE.md names a skill that isn't installed, the trigger rule misfires silently. Pin first.
Keep every pipeline-owned surface free of foreign-plugin command names — the skeleton's route rows name disciplines, not skill entries. A process harness a repo adds on its own then stays a settings edit: no doc change, no dangling-rule risk.
Ensure .claude/settings.json contains:
{
"enabledPlugins": {
"super-bootstrap@super-bootstrap": true
},
"extraKnownMarketplaces": {
"super-bootstrap": {
"source": { "source": "github", "repo": "RockyHong/super-bootstrap" }
}
}
}
- File missing → create with this minimal shape.
- Key already present → skip (
✓ pinned), whatever its value. - Core-pin key absent → merge it in.
- Other
.claude/settings.jsoncontent → never touched.
The core pin lives outside the official marketplace, so its extraKnownMarketplaces entry is required for cloud / fresh-machine resolution. Tier-2 curation (/super-bootstrap:resolve-plugins) reads it as locked — never proposes drop, never re-prompts the user. Adaptive picks (stack-matched skills / MCPs / hooks) layer on top when curation runs.
2a-hooks: Harness hooks (default-on)
Three hook assets ship as frozen files and install unconditionally — no
opt-in confirm, unlike drain's worktree infra (§2a-drain below); all are
safe-by-default (rationale + full procedure:
assets/hooks-ensure-infra.md).
| # | Asset | Fires on | Effect |
|---|---|---|---|
| 1 | commit-channel (PreToolUse) |
Bash(git *) and PowerShell(git *) — one hook element per command tool, each a bare-command pre-filter; the script narrows to real git commit |
Deny raw git commit from worker subagents — deny text routes the worker back to /super-bootstrap:commit; main session and separate-process workers pass. The commit door runs mechanics and the doc-sync judgment gateway-inline, runs a bundled link-integrity check every commit, and dispatches a cold doc-sync-scan only past the scope ceiling — no separate gate hook |
| 2 | consult-check-sessionstart (SessionStart) |
startup|resume|clear|compact |
Derives the compact docs/** catalog into the gitignored .claude/.consult-catalog cache, once per session boundary |
| 3 | consult-check-check (UserPromptSubmit) |
every prompt | Injects the catalog + a forced YES/NO-per-doc relevance evaluation — the read boundary's activation layer: the right project docs get read at the prompt moment (pure cache read; installs as a pair with #2) |
Execute the procedure in assets/hooks-ensure-infra.md — copies the scripts to .claude/hooks/ and merges each settings snippet into .claude/settings.json (hooks.PreToolUse[]: commit-channel; hooks.SessionStart[] + hooks.UserPromptSubmit[]: the consult-check pair). Content-aware (copy-on-drift — a drifted script the consumer never touched is re-placed from the asset silently, so an upstream fix reaches existing repos, while a consumer-edited one stops for an overwrite/keep pick; settings snippets replace in place; mechanism in assets/hooks-ensure-infra.md § Idempotency), silent when already current; stage the placed files with the Phase 2c commit. Same asset-copy + guarded-merge mechanism as drain's read-hook.json (../drain/assets/ensure-infra.md step 3) — one pattern, reused here rather than re-derived.
2a-drain: Drain infra (opt-in)
/super-bootstrap:drain (parallel-worktree auto-drain) needs three committed infra pieces. Most active-dev repos use drain; skill / plugin / docs-only repos usually don't. Ask once:
Install
/super-bootstrap:drainworktree infra? — worktree settings template +PreToolUse(Read)guard +.claude/worktrees/gitignore. Most dev repos: yes. Skill / plugin / docs repos: skip (drain self-installs on first use anyway). Install now? (y / skip)
On y: execute the procedure in ../drain/assets/ensure-infra.md — the same idempotent three-piece install drain self-runs on first invocation. One install home; harness-bootstrap delegates to it, never carries its own copy. Stage the placed files with the Phase 2c commit.
On skip: nothing placed; drain's own §Pre-flight step 0 installs on first /super-bootstrap:drain.
2a-scale: Scale module (opt-in, earn-gated)
The scale module adds work-substrate-adjacent runway — a parked-items artifact, a manual-verification queue, an outward folder (one thread file per item the author or an outside party moves, the repo owning only the result tail), and a phase→venue map — for repos whose card set has outgrown simple scanning. Earn-gated: offer only when a signal shows the repo has grown into it, silent skip otherwise (no prompt spam on small repos).
Signals — any one arms the offer:
- Card files (
{BUG|DEBT|GAP}-###.md) indocs/work/≥ 10. - Drain worktree infra installed (
.claude/worktrees/gitignore present — the module's venue map feeds drain's dispatch-vs-wall filter). - User asked for it.
None hold → skip silently, place nothing. A later re-run re-offers once a signal fires.
Split before placing — docs/outward.md → docs/outward/. Repos that took the scale module before the folder shape hold every outward item as an ### OUT-### chunk in one flat file. Placing docs/outward/ beside it strands those entries: /super-bootstrap:log's dedup and the mover gate read the folder, and the board only carries the flat file on a legacy branch that draws a # note: every render. When docs/outward.md exists, run the split first, then continue with this step's placements:
python3 ${CLAUDE_PLUGIN_ROOT}/skills/harness-bootstrap/assets/scale/split-outward.py <repo root> ${CLAUDE_PLUGIN_ROOT}/skills/harness-bootstrap/assets/scale/outward-readme-skeleton.md
Deterministic, no per-item judgment: it writes docs/outward/README.md from the skeleton with the flat file's high-water ID carried onto the high-water line, one docs/outward/OUT-###.md per ### OUT-### chunk — the H1 plus the chunk's whole body, field lines and any blocks an author had already appended, verbatim except that every relative link target gains one ../ (the entry now sits a directory deeper; http(s), mailto:, #anchor and absolute / targets stay as written) — and deletes the flat file last. It refuses (exit 2, nothing written) when any target file — docs/outward/README.md or an OUT-###.md it would create — already exists: the two shapes then coexist, so stop and surface the flat file's entry list beside the folder's for the user to reconcile; never treat exit 2 as a converted repo. A repo with no docs/outward.md is already on the folder shape and the placements below resolve ✓ current. The split moves a durable artifact, so it earns § Registration rule rows the same way a planting does — every consumer surface naming the flat path re-points to docs/outward/README.md, CLAUDE.md § Planning's bracket line included (pipeline-owned; § 2b's drift check carries that one).
When armed, ask once:
Install the scale module? —
docs/parked.md(deferred items with named triggers) +docs/test-queue.md(manual-verification queue) +docs/outward/(outward threads — next move + waiting-on party, one file per item) +.claude/rules/venue-map.md(phase → run-location map, feeds/super-bootstrap:todo+/super-bootstrap:drain) + card fact-field guidance. Install now? (y / skip)
On y, place the six assets/scale/ skeletons per Phase 2's per-artifact rule (all copy verbatim — no substitutions):
parked-skeleton.md→docs/parked.mdtest-queue-skeleton.md→docs/test-queue.mdoutward-readme-skeleton.md→docs/outward/README.mdoutward-template-skeleton.md→docs/outward/TEMPLATE.mdrules-venue-map-skeleton.md→.claude/rules/venue-map.mdcard-fact-fields.md→ insert its marker-delimited block (<!-- scale-module: fact fields -->…<!-- /scale-module -->) intodocs/work/README.mddirectly above the## Thread contractheading. Markers already present → the block is placed; § 2b's drift check judges its content against the asset (§ Pipeline-owned), so a re-run updates a stale block there, on approval.
Stage the placed files with the Phase 2c commit.
On skip: nothing placed; a re-run re-offers while a signal holds.
2b: Pipeline docs
Walk each pipeline doc and apply the per-artifact rule. Sources:
| Asset | Destination | Notes |
|---|---|---|
assets/claude-md-skeleton.md |
CLAUDE.md (project root) |
Includes Rules summary section — fill bullets from seeded rule files |
assets/techstack-skeleton.md |
docs/techstack.md |
Grown sections absorb migrated CLAUDE.md state-dimension content (Architecture Rules: still-binding decisions; Coding Patterns: examples) |
assets/overview-skeleton.md |
docs/overview.md |
<!-- harness-meta --> block at top: seed external-tools: as a YAML list defaulting to [github]. Read by /super-bootstrap:resolve-plugins (tier-2 curation) as the external-tools source. Update manually or via the entry skill when the tool list changes. Treat as pipeline-owned for drift checks. |
assets/decisions-skeleton.md |
docs/decisions.md |
Always — scope header pipeline-owned (drift-checked), ## Closed Forks table rows project-owned |
assets/work-readme-skeleton.md |
docs/work/README.md |
Always — categories, thread contract, ID high-water line |
assets/work-template-skeleton.md |
docs/work/TEMPLATE.md |
Always — copy-to-create card template |
assets/coding-standards-skeleton.md |
CODING_STANDARDS.md (project root) |
Code present only (Phase 1 § Code presence) — preamble + headings pipeline-owned (drift-checked), section content consumer-authored by hand (outside the doc-sync surface) |
assets/agents-md-skeleton.md |
AGENTS.md (project root) |
Always — foreign-executor contract; shipped body pipeline-owned (drift-checked), consumer additions below it project-owned |
assets/bootstrap-plan.md |
.claude/bootstrap.md |
|
assets/rules-index-skeleton.md |
.claude/rules/index.md |
Always — machinery |
assets/rules-frontend-skeleton.md |
.claude/rules/<framework>.md |
Only if frontend signal fired in Phase 1 |
assets/rules-mv3-skeleton.md |
.claude/rules/mv3.md |
Only if MV3 signal fired in Phase 1 |
On greenfield (no manifest, no source files), overview.md / techstack.md write as unfilled skeletons — manifest-derived facts fill only when code is present. The empty skeleton is intentional: it is the unsolved-product state the entry /super-bootstrap detects to seed GAP cards.
Per-doc handling:
- Missing → fill placeholders, write.
- Exists, drifted in pipeline-owned section → diff that section vs template, present to user, get approval per section, write approved.
- Exists, pipeline-owned section absent →
⊕ newrow: render the template section at Block 2, get approval, insert at the skeleton-defined position relative to the surviving sections. - Exists, seed-once section (
docs/techstack.md§ Runtime / Framework / Key Dependencies / Build & Distribution — § Pipeline-owned) → compare shape only: heading present and in its skeleton position →✓ current, whatever facts the body carries. Heading missing →⊕ newper the bullet above, inserted with this run's detected facts filled in where code is present (the template's placeholder body on a docs-only repo) — that insertion is the section's first fill. The body is never diffed against the template here: a filled body and a still-unfilled placeholder both read✓ current, and facts that went stale route to the Phase 3 stale-facts advisory (§ Phase 3), never to a write in this walk. - CLAUDE.md § Rules, scale module installed → the skeleton's shipped
venue-map.mdbullet block is this section's only template-fixed content — the remaining bullets mirror the repo's own seeded rules and stay project-owned. Novenue-map.mdbullet in the section →⊕ new, append the shipped block verbatim as the last bullet of the bullet list, one blank line above it. Bullet present → compare its fires-on list and key-point lines to the shipped block (the lead line keeps the section's own bullet form and any repo-local marker): same →✓ matches; differs →⚠ drifted, show the diff, write on approval. .claude/settings.jsoncore plugin pin → key present →✓ pinned; key absent →⊕ new, resolvinginsertedwith no prompt (§ 2a).- Exists, current → mark
✓ current. Still show the per-section comparison briefly (one-line per pipeline-owned section:[Runtime] ✓ matches,[Framework] ✓ matches, etc.) — asserting "current" without showing the comparison is a gap. - Project-owned content → never touched, even on drift.
- Legacy / unrecognized format — if existing doc structure doesn't align with template sections (different headings, merged sections, doc was written by an older version of this skill or by hand) → surface as legacy format detected, propose:
(a) rewrite to current skeleton format (preserves grown sections), (b) leave as-is and accept template drift, (c) show full template-vs-current diff. Do not silently skip drift detection because section names don't match — that hides real drift.
Legacy CLAUDE.md migration (re-run on already-installed repos):
Older super-bootstrap skeletons baked content into CLAUDE.md that now belongs in .claude/rules/ (path-scoped), docs/techstack.md grown sections (state reference), or docs/decisions.md (closed history). When Phase 1 flagged legacy blocks in pipeline-owned slots, propose per-section migration BEFORE running the normal drift check on those sections.
Migration patterns (illustrative — judge by content shape, not heading exact-match):
| Legacy CLAUDE.md content | Proposed destination | Reason |
|---|---|---|
| Enforcement rules with clear file-scope (component patterns, Tailwind tokens, async style, framework idioms) | .claude/rules/<scope>.md |
Path-scoped — full body fires when matching file is read. Cold-file alternative would silent-miss enforcement. |
| Closed history — rejected alternatives, roads-not-taken, closed design rationale | docs/decisions.md § Closed Forks |
History dimension — a state doc never holds it (same lane as § Rejected Alternatives retirement below). |
| Still-binding architecture decisions — module boundaries, data-flow direction, layering | docs/techstack.md § Architecture Rules (grown section) |
State — a live constraint, written present-tense, stripped of when/why-decided. |
| Live reference — deep examples, pattern walkthroughs for browsing | docs/techstack.md § Coding Patterns (grown section) |
On-demand reading, not enforcement. Safe to be cold. |
| Imperative coding convention with no clean file glob — binds every code touch (naming, error handling, testing posture) | CODING_STANDARDS.md § matching heading |
Ambient standard — the CLAUDE.md § Coding Principles line is its guaranteed reader at every code touch. |
MV3 / service-worker rules path-bound to src/background/** |
.claude/rules/mv3.md |
Path-scoped |
## Project Structure directory tree |
drop | ls / tree covers it; not load-bearing for any decision |
| Cross-cutting items inside a path-scoped list (storage-key constants, type-centralization across UI ↔ background, message-contract types) | keep in CLAUDE.md (no clean glob — every layer touches them) | Genuinely ambient |
Imperatives route by glob. A "Coding Standards" block named like reference but written as imperatives (must / never / always) is enforcement: a clean file glob → .claude/rules/<scope>.md (default there when the glob is arguable — silent-miss in a cold file costs more than slight rule over-attach); no clean glob, every layer touches it → CODING_STANDARDS.md § matching heading, carried ambient by CLAUDE.md § Coding Principles.
Surface the migration plan as a single proposal. Format below pins shape — one row per legacy block, judged via the migration table above. Destinations: .claude/rules/<scope>.md | CODING_STANDARDS.md § <hea
…(truncated)