Skip to content
Development
Skill

/plumb-line-bootstrap

Use when setting up a project with the plumb-line discipline — interviews the builder to find their source-truth layer and layering, generates a domain-neutral ruleset, and installs parameterized enforcement (boundary check, test gate, pre-commit gate, branch guard) for the

From plugin
plumb-line
45 skills
Install
$ npx -y skills add slopstopper/plumb-line --skill plumb-line-bootstrap --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/plumb-line-bootstrap

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when setting up a project with the plumb-line discipline — interviews the builder to find their source-truth layer and layering, generates a domain-neutral ruleset, and installs parameterized enforcement (boundary check, test gate, pre-commit gate, branch guard) for the

SKILL.md

plumb-line-bootstrap.SKILL.md
name: plumb-line-bootstrap
description: Use when setting up a project with the plumb-line discipline — interviews the builder to find their source-truth layer and layering, generates a domain-neutral ruleset, and installs parameterized enforcement (boundary check, test gate, pre-commit gate, branch guard) for the project's language. Ships no default layers and invents no answers.

Bootstrap a project with plumb-line

Part of the five-skill flow: find your fit with `plumb-line-adopt`, learn the discipline with `plumb-line-method`, set the project up here, review changes with `plumb-line-audit`, and apply findings with `plumb-line-remediate`.

REQUIRED READING FIRST: `reference/portable-principles.md` and `adapters/adapter-contract.md` (plugin root). If either file cannot be read, stop immediately and report which file is missing. Do not proceed from memory.

Two entries: full bootstrap vs. declaration-only (mid-audit)

This skill has two entry modes. **Full bootstrap** — the builder asked for setup — runs every step below. **Declaration-only** — `plumb-line-audit` invoked this skill because the project declares no architecture and the audit needs that context before proceeding — runs a deliberately two-minute detour:

  • Ask ONLY interview questions 1–3 (layers + direction; source-truth layer;

composition root). The audit needs the declaration, not the ceremony.

  • Write the ruleset from those answers (Step 3), marking every section the

interview did not reach as `planned` — an un-asked question must not read as an answered one.

  • Skip Step 4, Step 4b, and Step 6's audit offer entirely: no enforcement

install, no primitive offer, nothing added to the project beyond the ruleset file. Those belong to a full bootstrap run — name it as the follow-up in the report's TODOs.

  • Emit the Step 5 report header with one extra line — `entry: declaration-only`

— then return the baton: the calling audit resumes with the freshly declared architecture (do not start a second audit).

The honesty constraint applies in both modes: if the builder cannot name a source-truth layer, stop and say so — in declaration-only mode that answer goes back to the audit, which then proceeds calibrated with the gap on record.

Step 1 — Detect language, pick the adapter

  • Look for `package.json` -> JS adapter (`adapters/js`).
  • Look for `pyproject.toml` / `setup.py` / `requirements.txt` -> Python adapter (`adapters/python`).
  • If both or neither, ASK the builder which to use. Never guess silently.

Step 2 — Interview (one question at a time)

Ask the find-your-version prompts from the principles, in this order (ask one, wait for the answer, then proceed). Do NOT supply defaults; these answers are the builder's, not yours:

1. Layers, top to bottom, and the one-way direction. 2. The source-truth layer, and what must never leak into it. 3. The one allowed exception (composition root), if any. 4. What flows downstream (gets provenance + confidence). 5. Where non-real (mock/fallback/cached) data is used. 6. Which constants encode judgment calls (priors to lift to config). 7. Public output shapes that need a versioned contract. 8. For each key output, the inputs needed to reproduce it. 9. Which derived outputs to freeze as a golden baseline. 10. The phrasing for a valid null result in this domain.

HONESTY CONSTRAINT: if the builder cannot name a source-truth layer, stop and say so — that absence is the finding. Do not fabricate one.

Step 3 — Generate the ruleset

Fill `reference/ruleset-template.md` placeholders with the answers; write it to the target repo as `AGENTS.md` (or append if one exists — never overwrite silently).

Step 4 — Install enforcement (from the chosen adapter)

  • Copy the boundary config template, replacing layer placeholders with the

builder's layers/direction. (JS: eslint zones; Python: import-linter layers.)

  • Copy the two guard hook scripts (branch guard + pre-commit gate) into the

target repo's `.claude/guards/` (or hooks dir).

  • Wire the pre-commit gate to the adapter's declared test command.
  • Tell the builder exactly what was written and how to enable the hooks.
  • **Verify, don't assume.** After installing, plant a deliberate upward import

and confirm the boundary check errors; pipe a code path to the branch guard on the protected branch and confirm it blocks. An installed-but-inert guard is the failure mode to rule out.

JS boundary zones — get the direction right (easy to invert silently)

In `import/no-restricted-paths`, each zone reads: **`target` = the layer doing the importing; `from` = the layer it must NOT import.** To forbid the bottom layer importing upward, list one entry per forbidden (lower imports higher) pair:

zones: [
  {
    target: "./src/data",
    from: "./src/ui",
    message: "data must not import from ui",
  },
  {
    target: "./src/data",
    from: "./src/services",
    message: "data must not import from services",
  },
  {
    target: "./src/data",
    from: "./src/engine",
    message: "data must not import from engine",
  },
  // ...repeat for services (must not import ui), engine (must not import ui/services), etc.
];

A reversed `{ target: "./src/ui", from: "./src/data" }` forbids the _opposite_ (ui importing data) and leaves the real upward leak unguarded — and nothing errors, so the mistake is invisible. This is why the verify step above matters.

ESLint v9 uses flat config (`eslint.config.mjs`); the template is a `.cjs` fragment. Load it from the flat config (import the fragment and spread its `rules`) rather than expecting a legacy `.eslintrc` to be read.

Branch-guard allowlist forms

The docs allowlist matches an entry in exactly three forms — no other globbing:

  • exact file: `README.md`
  • directory (trailing slash): `docs/` — everything under it
  • extension glob: `*.md` — that extension at any depth

Empty entries are rejected. (Earlier versions matched files exactly only; a bare `*.md` silentl

Read more
Ships withplumb-line

Stop uncertain data becoming confident-looking results. plumb-line carries provenance, confidence and mock-taint with values through JavaScript and Python, and its review-time checks and GitHub Action catch uncertainty laundered into a claim in AI-assisted code.

Get the whole plugin
Stats
4
Stars
0
Forks
Active
Maintenance
Python
Language
Apache-2.0
License
2d ago
Last commit
2mo ago
Created

Repo: slopstopper/plumb-line

Other skills on plumb-line.