Use when a builder wonders what plumb-line would do for their codebase or which part to adopt, or when, mid-task, they are building with a stand-in: stubbing a service that is not built yet, falling back to cached or last-known values when a source fails, filling a field with generated or sample data, mixing fixture, cached or LLM-produced data with real data. It answers yes, and: add it, and here is how to keep track of it (a label or marker, or plumb-line's provenance primitive where it fit...
Installs into .claude/skills of the current project.
Are you the author of Plumb Line Adopt?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/slopstopper-plumb-line-adopt)
---
name: plumb-line-adopt
description: "Use when a builder wonders what plumb-line would do for their codebase or which part to adopt, or when, mid-task, they are building with a stand-in: stubbing a service that is not built yet, falling back to cached or last-known values when a source fails, filling a field with generated or sample data, mixing fixture, cached or LLM-produced data with real data. It answers yes, and: add it, and here is how to keep track of it (a label or marker, or plumb-line's provenance primitive where it fits). Inspects the repo and routes to the right skills and primitive integration. Read-only: recommends and hands off, never edits or installs."
---
# Adopt plumb-line — which part, on what
REQUIRED READING FIRST: `reference/fit-map.md` (plugin root). If this file
cannot be read, stop immediately and report: "Cannot route: `reference/fit-map.md`
is missing or unreadable. Do not recommend from memory — the fit map is the
source of truth for what the primitives are for." Read
`reference/portable-principles.md` only if the conversation needs the
principles named; the fit map is sufficient for routing.
This skill is a concierge for the whole toolkit — the four sibling skills
AND the run-time primitives. Its job is the question the docs cannot answer
for a specific repo: *"what would I use this on, here?"* It recommends only.
It never edits files, installs anything, or scaffolds code; every action
belongs to the skill it hands off to, or, for a stand-in met mid-task, to
the agent or builder doing the task.
## 1. Look — a lightweight, read-only scan
Scan the repository for **routing signals only** (this is not an audit —
do not read whole files; filenames, imports, and greps suffice):
- HTTP ingestion: `requests` / `httpx` / `fetch` / `axios` whose results
feed computation; caching or retry-with-cache logic.
- Dataframes: `pandas` / `numpy` imports; `fixtures/`, `sample_data/`,
or demo CSVs loadable by production-adjacent code.
- LLM or agent surface: LLM SDK calls; fallback/canned-response branches;
agent-generated artifacts consumed downstream.
- Fakery near production paths: mock flags, `USE_MOCK`-style toggles,
stub data on non-test paths.
- Existing adoption: `plumb-line-provenance` already imported; a ruleset
file (`AGENTS.md` / `CLAUDE.md`) declaring layers; installed hooks.
**State your denominator.** Say in one line what the scan covered (e.g.
"scanned imports and top-level layout; did not read function bodies") —
a routing recommendation must not imply deeper knowledge than the scan had.
## 2. Ask — at most three questions
Fill only the gaps scanning cannot see. Good questions: what the builder
is actually worried about; whether the mock/fixture data ever reaches
users or stored outputs; whether they want enforcement or just visibility.
Skip any question the scan already answered. If no builder is present to
answer, route from the scan alone and say so.
## 3. Route — both surfaces, explicitly
Always answer both halves, in plain language, assuming no prior reading:
**Skills surface (applies to every repo).** Recommend which of the four to
run and in what order, with one line each on what it produces:
- `plumb-line-method` — first if the builder wants the reasoning; teaches
the discipline in minutes.
- `plumb-line-audit` — the zero-setup first taste: reviews the diff or
repo and reports; needs nothing installed.
- `plumb-line-bootstrap` — when they want the discipline wired in
(ruleset, hooks, boundary checks).
- `plumb-line-remediate` — only after an audit report exists.
**Primitives surface (fit-mapped).** Match the scan + answers against the
fit map's profiles and say which profile matched and *why, citing what was
seen* ("you call OpenAI with a static fallback in `llm/client.py` —
profile 1"). Before showing code, give a one-minute mechanics primer in
plain words — builders hesitate when the envelope feels opaque: `mark`
wraps a value with metadata at the point it enters; `derive` runs the
builder's own function on the plain values and combines the metadata by
law (taint ORs and cannot be cleared, confidence takes the weakest);
`metaOf`/`meta_of` reads it back; `auditMeta`/`audit_meta` checks the
envelope is consistent; `guard` stops a value at an output point: by
default one that is unmarked, malformed, flagged by the audit or tainted
by mock, and one below a source or confidence floor when the output sets
one. Say plainly what this bounds: the library never
computes or modifies a value, so a labeling mistake misdescribes data
but cannot corrupt it, and a forgotten `mark` fails visibly rather than
silently (the fit map's "Worried about using it wrong?" section is the
source). Then show the profile's smallest useful integration
**adapted to the builder's actual code**: their filenames, their variable
names, the right language, and the right adapter (`taggedFetch` /
`tag_requests` / `PlumbDataFrame` / plain `mark`+`derive`) for their
stack. Show the pattern as a suggestion in conversation — never apply it.
**Non-fit is a first-class outcome.** If the repo matches the fit map's
anti-profile, say plainly: "you do not need the primitives" — then still
give the skills-surface answer, and name what future change would revisit
the verdict (the fit map's anti-profile section closes the same way). Do
not soften the no; a wrong-fit adoption costs the builder more than an
honest walk-away.
**Defuse the greenfield misconception.** Builders commonly assume
provenance must be adopted at a project's start and hesitate on an
existing codebase. When that worry appears — or when the repo is clearly
mature — say what the fit map's "Mid-project is the normal case" section
says: envelopes attach at boundaries, the smallest integration is a few
lines at one call site, nothing is retrofitted, and repo-wide enforcement
is a separate, opt-in, later decision.
**Mixed or uncertain fit is stated as such.** If signals are ambiguous,
say what would settle it, with the builder's own code as the test — never
present a guessed fit as a match.
## The routing report is contracted (routing-format: v1)
The audit and remediate siblings emit versioned, checker-validated shapes;
this skill's routing recommendation is a public output and carries one too
(#269, P7 — Contracted outputs, applied to our own output). A brief mid-task
answer (see **Surfacing mid-task**) is not a routing recommendation and
carries no header, but any fit it claims still cites what was seen. The contract is deliberately light —
conversational prose stays conversational; five elements are pinned:
```
routing-format: v1
scope: <the repository routed>
date: <YYYY-MM-DD>
denominator: <the Step-1 coverage line — what the scan covered and did not>
## Skills surface
<the Step-3 answer: which skills, in what order, one line each>
## Primitives surface
fit: <profile N | anti-profile | no fit | mixed | uncertain> — cited: <what was seen>
<the mechanics primer and adapted integration, or the honest walk-away>
handoff: <the one offered next step> | none (<reason>)
```
The `fit:` verdict comes from that vocabulary only, **always followed by a
dash and `cited:`** (`— cited: <what was seen>`; em-dash, en-dash, or hyphen
all validate) — a guessed fit presented as a match is exactly what Step 3
forbids, and the citation's presence is what the checker pins mechanically.
Validate before emitting, the same earned-verdict rule as the audit skill:
run the checker that ships in this plugin
(`python3 <plugin root>/scripts/check_report_format.py <report>`) and
fix violations before printing, then close the report with one of these two
literal lines, below `handoff:`:
```
format-validation: scripts/check_report_format.py v<N> — clean
format-validation: not run (checker unavailable in this repo)
```
`<N>` is the checker version the checker prints on its first line (`check_report_format v<N> — ...`); copy it, so a stored "clean" says which rule set it was earned under. The checker judges every `format-validation:` line: an unfilled `v<N>`, a stamp newer than the checker, or a line in any other form (a different dash, trailing text, a list bullet) is rejected; an unstamped clean line passes with a "checker version unrecorded" note. The `— clean` form may only follow an actual execution on the exact text
being emitted; anything that prevents running it is the `not run (<reason>)`
case, reason stated in the line. The key is `format-validation:`, never a
second `routing-format:` line — a duplicate header key makes the report
ambiguous and the checker rejects it.
**The message is the text the checker passed.** Write the report to a
temp file, run the checker on that file, then print the file's text as your
message, unchanged: nothing above the header (no summary, heading or
preamble), and no edit between the check and the message. If you change
anything after the check, however small, re-run the checker on the changed
text before printing it. Anything else you want to say (a summary, step 4's offer) goes
below the report, after its last line. A `— clean` stamp is true only of
the exact text it was run on: two 2026-09-30 eval audits delivered a
message that opens with a prose summary above the header, one whose body
also fails, under a `— clean` stamp, and the checker names both stamps as
not earned (#581).
## 4. Hand off — invoke on yes, never apply
End with ONE short offer naming the next step. When the builder accepts,
invoke that skill directly (via the host's skill mechanism) rather than
telling them to go run it:
- Wire it in → `plumb-line-bootstrap`. When the builder's hesitation is
"I don't want to set this up wrong," say what bootstrap's opt-in
scaffold actually does: it wires `mark`/`derive` at the call sites the
builder names, teaches the pattern at the first site rather than
carpeting the codebase, and finishes with a test asserting the key
output audits clean, wired into the pre-commit gate — the builder is
not hand-assembling from a README.
- See what a review finds first → `plumb-line-audit`.
- Understand the method first → `plumb-line-method`.
If the builder declines, or none is present: stop after the routing
report. This skill's output is a recommendation; leaving with only the
recommendation is a valid ending.
## Surfacing mid-task
This skill may fire while the builder is doing something else — writing a
fallback branch, loading a fixture into a pipeline. In that case: be
brief; where a fit-map profile matches, point at it and show the one-line
integration for the code on screen; and offer to continue or get out of
the way. Do not run the full scan-and-interview over an interruption; the
full routing is for when the builder asks for it. A brief mid-task answer
is not a routing report, so it does not carry the `routing-format` header;
if it names a fit-map profile, cite what you saw that matches it.
This skill still edits nothing: it tells the agent doing the task, or the
builder, how to keep the stand-in tracked, and they make the edit.
The answer to building with a stand-in is yes, and: a stub for a service
that is not built yet, a fallback to cached or last-known values, generated
or sample data filling a field. Add it, and here is how to keep track of it.
The lightest tracking that fits is enough while the stand-in stays out of
outputs: a label on the value or the screen ("sample", "generated", a "last
updated" marker on stale data), a flag on the row, the stub named as a stub.
Where it would reach an output (exported, aggregated or displayed as a
result), it is kept out unless the builder opts in, and marked there when
they do. Offer the provenance primitive
where the stand-in flows into other values, so its `mock` or `fallback`
source stays marked in everything derived from it. If the aim is to make
the stand-in pass as real, that is `plumb-line-method`'s moment, not this
one.