Skip to content
Back to skills

Bootstrap

ASecurity

Sets up house in a repo for the first time, proposing a house.json manifest, vendored rules, and a CLAUDE.md skeleton, dry run by default; in an adopted repo, turns modules on and walks their at-adoption checklist, or removes the adoption. Use for "bootstrap house", "adopt house here", "enable the security module", or "uninstall house from this repo".

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 19, 2026
developmentgonodegitdatabasesecurity

Works with

  • terminal
  • cli

Security analysis

A100/100

Scanned October 4, 2026

npx -y skills add dubbl-a/house-rules --skill bootstrap --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Bootstrap?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Bootstrap
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dubbl-a-bootstrap/badge)](https://www.skillsdirectory.com/skills/dubbl-a-bootstrap)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: bootstrap
description: Sets up house in a repo for the first time, proposing a house.json manifest, vendored rules, and a CLAUDE.md skeleton, dry run by default; in an adopted repo, turns modules on and walks their at-adoption checklist, or removes the adoption. Use for "bootstrap house", "adopt house here", "enable the security module", or "uninstall house from this repo".
disable-model-invocation: true
---

# Bootstrap

Bootstrap turns an unmanaged repo into a house consumer. It probes the repo, proposes a
`house.json`, and on `--apply` writes the vendored rules, templates, and a CLAUDE.md skeleton.
It never edits an existing CLAUDE.md and it never runs twice over the same manifest.
It writes only the house half of CLAUDE.md, as a separate skeleton file, and leaves the
codebase-derived half to the harness's own init command, which generates a starting CLAUDE.md or
suggests improvements to the one already there.

This skill has side effects on disk, so it never fires on its own. Run it only when asked.

## Default path

1. Dry run: probe the repo and print the proposed `house.json`. Write nothing.
2. Show the proposal to the person running the skill and wait for them to say apply it.
3. Apply: write `house.json`, then render the rules, templates, and skeleton.
4. Print the wiring block below so the person can paste it into `package.json`, CI, and their
   terminal.

Do not skip step 2. A proposal the person never saw is not a proposal, it is a surprise.

## Refuse when a manifest exists

Before probing anything, check whether `house.json` already exists at the repo root.

If it exists, refuse. Print that the repo already has a manifest and point to `/house-rules:sync`
instead. This holds in dry run too: bootstrap never drafts a second proposal over a first one,
even one nobody applied yet. A repo gets exactly one bootstrap. The exceptions are a request to
turn modules on or off, or to uninstall, which take the modes below and never re-propose the manifest.

## Enable modules in an adopted repo

When the person asks to turn on one or more modules in a repo that already has `house.json`, run
the plan first, for every module named, in one run:

```
node ${CLAUDE_PLUGIN_ROOT}/scripts/house enable <module...> --repo <path>
```

It writes nothing. It prints the `house.json` change, the files render would write, the paths
each module's slots resolve to here (a default path matching nothing is dropped), the
at-adoption checklist, and the load cost, including any path pushed over the co-load ceiling.
Show all of it and wait for the person to say apply it. On approval, run the same command with
`--apply`: it writes `house.json`, renders once, and runs `.house/check.mjs`. Report the
checker's summary as printed, findings included.

Then walk the checklist one step at a time. Each step is a repository or account setting no
checker can read, so ask the person whether it is done, and help with the step when it is not.
When the person says a step is done, record it:

```
node ${CLAUDE_PLUGIN_ROOT}/scripts/house confirm <module> <step-id> --repo <path>
```

It writes the step id and today's date beside the module's entry in `house.json`, and keeps the
first date if the step was already confirmed. It refuses while `.house/check.mjs` is not this
plugin's copy, since an older checker fails CI on the record: run `/house-rules:sync` first. Do not confirm a step on the person's behalf. A
step left open is fine: `house doctor` lists every step of an enabled module not yet confirmed.

## Disable modules in an adopted repo

When the person asks to turn modules off, run the plan first, for every module named, in one run:

```
node ${CLAUDE_PLUGIN_ROOT}/scripts/house disable <module...> --repo <path>
```

It writes nothing. It prints the `house.json` change (only `enabled`; config and confirmations
stay), the managed files render would remove, the scaffolds left in place, what stops for each
module, and the load each path sheds. Show all of it and wait for the person to say apply it; on
approval, re-run with `--apply` and report the checker's summary as printed. A module that is on
by default needs `--why "<reason>"`, recorded as a dated deviation: ask the person for the reason
and pass their words, never one of your own. A hand-edited managed file is refused by name: leave
resolving it to the person. Do this on a branch and open a pull request. The branch guard reads
the github module's switch from `house.json` at HEAD, so once turning github off is committed, on
whichever branch is checked out, it stops refusing commits, pushes and history commands on a
protected branch and stops advising to arm the floor; it still refuses a `core.hooksPath` change,
a write or removal under `.githooks/`, and `--no-verify`, and the remote's branch protection is
what still stops a push to a protected branch. If `--apply` is denied by a
permission check, do not retry or route around it; give the person the exact command and the
directory to run it from. The plan names a `git config --unset` the person runs themselves: the
guard refuses it to a session, and leaving the setting in place is harmless.

## Uninstall from an adopted repo

When the person asks to remove house from a repo, do it on a branch and open a pull request.
Run the plan first:

```
node ${CLAUDE_PLUGIN_ROOT}/scripts/house uninstall --repo <path>
```

It writes nothing. It lists the managed files and the git-hook floor it removes, the `AGENTS.md`
block it takes out, `house.json` last (with its deviation count and the `git show` that brings it
back), the directories that end empty, what it does to `core.hooksPath` at each scope, everything
it leaves (scaffolds, files not managed, and each line still calling the checker), what stops, and
what the branch guard and session start do afterwards. Show all of it and wait for the person to
say apply it; on approval, run the same command with `--apply`. If the person wants to keep
`house.json`, pass `--keep-config`: the guard then keeps enforcing its `branchPolicy` and session
start keeps reporting the floor missing, as the plan says. A `house.json` that is not in HEAD, or
differs from it, is not recoverable from git as it is, so `--apply` needs `--keep-config` or
`--discard-untracked-config`: ask which, never choose for them. A hand-edited managed file is
refused by name and nothing is deleted: leave resolving it to the person. With `.house/lock.json`
missing or unreadable nothing proves which files render wrote, so uninstall deletes nothing and
lists them: offer `house render --apply` to rebuild the lock, then uninstall again. If the apply is denied by a permission check, do not retry or route
around it: tell the person that a blocked action can be retried with manual approval from
`/permissions`, and give them the exact command and the directory to run it in. A rerun finishes a
run that stopped part way, with or without `house.json`.

Until the removal is committed, HEAD still has `house.json`, so the guard keeps enforcing it in
this session; its refusals advise arming the floor or rendering, which would re-adopt, so do not
follow them. Then walk the leftovers with the person, one group at a time: each checker caller
listed (remove it in the same pull request, or CI fails once the checker is gone), and each
scaffold and file not managed (theirs to keep or delete). In a linked worktree the plan names the
command to run in the main checkout for `core.hooksPath`.

## Probe the repo

Run the CLI in dry run to gather what the proposal needs:

```
node ${CLAUDE_PLUGIN_ROOT}/scripts/house init --repo <path>
```

The probe reads, and does not write:

- Stack: presence of `package.json`, its scripts, and any framework config file at the root.
- Default branch: `git symbolic-ref refs/remotes/origin/HEAD`, falling back to the current branch.
- Top-level directories, to guess which optional modules apply (`db/` suggests `database`,
  a deploy config suggests `deployment`, and so on).
- Whether `.claude/rules/` or a branch-guard hook already exists, so the proposal can say what
  bootstrap would add versus what the repo already has.
- Whether the repo's current docs scanning already excludes an archive tier, to seed
  `scanArchive` from observed behavior rather than a guess.
- Whether `git check-ignore` says any house write destination (`.claude/rules/house/`, `.house/`)
  is ignored. The checker walks `git ls-files`, so an ignored rule file is invisible to it and
  the first run prints a zero it never earned. The probe warns and names the fix: ignore only
  `.claude/settings.local.json`, never `.claude/` or `.house/`.

## Propose house.json

Every module the probe cannot rule out goes into the proposal as `"detect"`, not `true` or
`false`. `"detect"` means the repo decides at render time, not the skill guessing on its behalf.
Core modules (`docs`, `engineering`, `github`, `claude-code`) are always on. Print the full
proposed `house.json` body, not a summary, so the person reviewing it can read every field
before anything is written.

## Apply: write the manifest, the rules, and the skeleton

Only after the person says to apply:

```
node ${CLAUDE_PLUGIN_ROOT}/scripts/house init --repo <path> --apply
node ${CLAUDE_PLUGIN_ROOT}/scripts/house render --repo <path> --apply
```

`init --apply` writes `house.json`. `render --apply` writes the vendored rule files, the
templates, `.house/check.mjs`, `.house/lock.json`, `.house/INDEX.md`, and one more file:

- If the repo has a CLAUDE.md, write `CLAUDE.md.house-skeleton` beside it. Do not open the
  existing CLAUDE.md and do not write into it.
- If the repo has no CLAUDE.md, still write `CLAUDE.md.house-skeleton`, not `CLAUDE.md` itself.
  Bootstrap never originates the repo's root file. A person merges the skeleton in by hand.

Either way, an existing CLAUDE.md is byte-identical before and after every bootstrap run. That
is the control this skill is held to: diff it before you apply, diff it again after, and if
anything moved, stop and say so instead of reporting success.

The skeleton is offered once per repo: `render` records it in `.house/lock.json` under
`scaffolds`, so once it has been merged into CLAUDE.md and deleted, no later render writes it
back. `render --apply --scaffold` is the way to ask for it again.

Ensure the repo's `.gitignore` contains `.claude/worktrees/` and `.superpowers/`, appending
whichever line is missing. Tool scratch that shows up in `git status` is one `git add -A` from
being committed.

## Print the wiring

After a successful apply, print this block verbatim so it is copy-pasteable into a plain
terminal. Fill in nothing; the person adapts it to their `package.json` and workflow file.

```
Add to package.json scripts:
  "check:docs": "node .house/check.mjs --only=drift,todo"
  "check:house": "node .house/check.mjs"

Add a CI step that runs:
  node .house/check.mjs

Install the plugin once per machine:
  claude plugin marketplace add dubbl-a/house-rules
  claude plugin install house-rules@house-rules --scope user

Arm the git hooks once per clone (render --apply and every session start also do this):
  git config core.hooksPath "$(pwd)/.githooks"
```

`core.hooksPath` lives in `.git/config`, which no clone and no PR carries, so the vendored
`.githooks/` tree is inert in a fresh checkout until something sets it. `render --apply` and the
plugin's SessionStart hook both arm it; the line above is for a clone that has neither. Neither
they nor the person should overwrite a `core.hooksPath` another tool already owns.

If the repo has no `.claude/settings.local.json`, say so in the printed output. That file is
where a per-repo opt-out of a house module or hook would live, and its absence means the repo
is running on defaults only.

## After bootstrap

Tell the person what is not yet done: the skeleton still needs merging into CLAUDE.md by hand
and then deleting (it will not be written again),
the wiring block still needs pasting in, and `node .house/check.mjs` is worth a local run before
the first commit so the repo starts from a clean gate rather than an inherited failure. Stage the
rendered files by path first (`house.json .house/ .claude/rules/house/`, plus `scripts/house/`
only when render listed a file there, since git refuses a pathspec that matches nothing): until
they are staged the manifest family warns `[untracked]` per file, and a wholesale `.claude/` or
`.house/` ignore is a `[gitignored]` finding, because a file git cannot see is one no family
checks. None of that is this skill's job to do for them; bootstrap stops at render.

## Don't

- Don't write `house.json` or any rendered file during the dry run. Dry run only prints.
- Don't overwrite or append to an existing CLAUDE.md, ever, under any flag.
- Don't re-propose over a repo that already has `house.json`. Send it to `/house-rules:sync`,
  or to `house enable` when the ask is to turn modules on.
- Don't guess a module on or off when the probe is ambiguous. Propose `"detect"` and let the
  repo decide.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.