Living doc — state dimension only (what the stack is now). Skeleton sections (Runtime / Framework / Key Dependencies / Build & Distribution — seed-once: seeded at scaffold from detected facts, hand-edited from then on; a
harness-bootstrapre-run checks their shape only and never rewrites the facts. Edit Discipline, fixed prose). Grown sections (Architecture Rules / Coding Patterns) start empty and grow via doc-sync — every commit that touches a relevant area triggers a sync proposal, admitted per § Doc Sync. Rejected stack directions are history, not state →docs/decisions.md, never a section here. SeeCLAUDE.mdDoc Sync.
No build step, no runtime dependency. The product is markdown: skills are SKILL.md files with YAML frontmatter, agents and shared fragments are markdown, loaded directly by Claude Code's plugin loader. Python 3 is an optional runtime one skill asset invokes for zero-dispatch mechanical extraction (help's menu); it degrades to a manual scan when python3 is absent.
Claude Code plugin architecture. A root .claude-plugin/marketplace.json declares the self-hosted marketplace; plugins/super-bootstrap/.claude-plugin/plugin.json declares the plugin. Layout: plugins/super-bootstrap/{skills,agents,shared}. plugin.json declares no skills array, so the loader discovers skills/*/ itself and every folder ships — an explicit array is an allowlist, and any folder left out of it never loads, with no error. The source field in marketplace.json (./plugins/super-bootstrap) is the install boundary — only that subtree ships to installers; repo-root files (this doc, CLAUDE.md, the docs/work/ cards) are dev-workspace-only and never reach a user's project.
- super-bootstrap (self-pin) — core pin: the scaffolded CLAUDE.md routes every door through
/super-bootstrap:*and the committedcommit-channel.shnames/super-bootstrap:commit, so the project pin must resolve them on a local boundary without the authoring device's user-scope settings (fresh clone, second machine — the pin's marketplace registers once the workspace is trusted). A cloud session never shows the trust dialog and loads no repo-declared plugin, so there the plugin comes from the environment's setup script instead: README § Cloud sessions. - No process harness is a dependency, and none is pinned. The scaffolded CLAUDE.md's route rows name disciplines, not process-harness skill entries, so any process harness (superpowers or another) is an ordinary
/super-bootstrap:resolve-pluginscandidate the user may take or drop. Rationale + cut map:docs/specs/harness-architecture.md. - Discovery sources for
/super-bootstrap:resolve-plugins— what each source is and the role it plays in the set: README § Sources. The pool the door issues live queries against isresolve-plugins/SKILL.md§ Phase 2.
No build. Distribution is git + Claude Code marketplace:
/plugin marketplace add rockyhong/super-bootstrap
/plugin install super-bootstrap@super-bootstrap
Versioned via the /release skill. plugin.json is the single version source — Claude Code resolves a plugin's version from plugin.json first, so marketplace.json carries no version; /release bumps plugin.json and re-syncs the marketplace plugins[0].description mirror from plugin.json, then commits + tags. Published by pushing to github.com/RockyHong/super-bootstrap; installs with autoUpdate pull the new version.
Grows via doc-sync as patterns crystallize. Module boundaries, data flow direction, dependency philosophy, layering rules.
- Dispatch-shell + typed-agent split — skills with bounded-judgment verbs route through a dispatch shell + typed agent pair; monolithic skill bodies don't own execution judgment. →
skill-authoring.md - Frozen-asset versioning — shipped assets are placed by mechanical copy/merge at release time and never regenerated, eliminating inter-repo drift. →
ensure-infra.md - Plugin-owned hook lane — a hook whose input is the installed plugin itself (
plugins/super-bootstrap/hooks/, commands anchored on${CLAUDE_PLUGIN_ROOT}) runs from the plugin tree and updates with it; never placed, so it carries no receipt row and no drift check. →overview.md§ Key Boundaries - Skeleton/dogfood sync direction — two lanes by SSOT side — dogfood prose edits carry their shipped-skeleton counterpart in the edit's closure, frozen-asset edits carry the placed dogfood copy; skeletons must be self-contained (no dogfood-only wiring). →
repo-boundary.md - Gateway-inline vs dispatched lanes — closure-judged (not diff-size-judged): build phases dispatch to clean subagents; transcription applies inline; parallel within a phase only; writer run mode keyed on path overlap. →
CLAUDE.md§ Dispatch
Grows via doc-sync as patterns crystallize — descriptive reference: how this code is actually written, read on demand, safe to be cold. Import style, class-vs-function bias, type usage, recurring idioms. A convention that binds — imperative, obeyed at every code touch — is recorded in
CODING_STANDARDS.md.
Two edit-tool failure families: bulk replace corrupting on common identifiers (preference order + checklist below), and edits issued against stale file state (§ Stale-state edits).
Edit replace_all: true is naive whole-file string replace — no AST, no scope, no token boundaries. Running on common identifiers silently corrupts unrelated code (state → swipe rewrites SwipeState to SwipeSwipe, import paths, comments, CSS selectors). The trap is invisible until the next type-check.
Preference order:
- Per-occurrence Edit with unique surrounding context — enumerate call sites first (LSP
findReferenceswhere a server is configured, Grep otherwise); each Edit'sold_stringincludes enough context to be unique to that call. sed/ scripted bulk replace — only when term is 8+ chars and unique to the domain (Conversation,MerchandiseInventory). Always case-preserving pair:s/OldName/NewName/g; s/oldName/newName/g; s/OLD_NAME/NEW_NAME/g. Run build/test cycle immediately.Edit replace_all: true— only on unique long string literals (URLs, full sentences, hash IDs). Never on identifiers <8 chars. Never on common English words.
Pre-flight checklist (any bulk replace):
- Grep the exact term. Look at count + sample matches.
- If hits >5 OR length <8 OR common English word → switch to options 1–3.
- Scan sample matches for false positives (substrings inside other identifiers, string literals, CSS classes overlapping HTML tags, comments).
- Any doubt → per-occurrence Edit. Caution token cost ≪ silent-corruption debug cost.
Banned terms for replace_all (always per-occurrence):
state, name, data, value, item, key, id, type, props, node, text, link, error, result, body, head, main, time, path, file, index, count, child, style, class, tag, event, target, source, from, to, next, prev, init, done.
Stale-state edits — Read before first Edit, re-Read after mutation:
An Edit failing "File has not been read yet" or "File has been modified since read" is a state-tracking failure, not a content failure — retrying the same Edit against the same stale state cannot succeed. Read first; on those errors, re-Read:
- Read before the first Edit of a file each session —
Writealways requires a prior Read;Edit's guard is relaxed for newer models (CC 2.1.208+) but reading first remains the discipline — an unread edit is a blind edit. - Re-Read after either error class above before the next Edit of that file.
- Re-Read after any save that lands behind your read-tracker — formatter hook, linter-on-commit (prettier / lint-staged repos mutate on every commit), and any file-writing subagent that returned (a skill may have dispatched it): it wrote in its own context, invisible to yours. Prevention half — sequencing the writer dispatch itself — in
dispatch-run-mode.md. git diffoutput is not a Read — after reviewing another agent's edits via diff, Read the file itself before editing it.- Two consecutive same-file Edit failures = mandatory re-Read, no exceptions — the loop is unwinnable without fresh state.
When a replace_all slips through:
git difffirst — see damage scope.- If uncommitted,
git checkoutthe file and redo with the right tool. - If committed, fix as a NEW commit (preserves mistake in history).
- Run type-check / lint / test — usually points straight at corruption.
Always run build/test after bulk operations.