claudeers.
// Claude Plugins

ballast

Turns working with Claude Code into a system that finishes goals: what you teach, verify, and solve once stays in use — session after session.

Install with your AI

Paste into Claude Code, Cursor, or any agent — it reads the repo and wires the tool into your project.

Install and set up ballast (claude-plugin project) into my current project.
Found on https://claudeers.com/ballast
Repo: https://github.com/svy04/ballast
Homepage/docs: —
Detected install method: claude-plugin → /plugin install ballast@svy04/ballast
Category: plugins. Platforms: cli, api.
Read the repo's README for exact setup and env vars, then install it and wire it into my project.

Claudeers Health Verdict:
unknown; community-verified: false. Confirm the source before running anything.
// or install directly (claude-plugin)

Unverified / not recently updated — review before pasting a run-this config.

/plugin marketplace add svy04/ballast
/plugin install ballast@svy04/ballast
// or clone
git clone https://github.com/svy04/ballast

// compatibility

Platformscli, api
Operating systems
AI compatibilityclaude
LicenseMIT
Pricingopen-source
LanguageJavaScript

ballast

한국어 문서 →

ballast — a ship that holds steady because of the weight riding low in its hull

ballast is a Claude Code plugin that turns working with Claude into a system that finishes goals. It mobilizes what you already hold, keeps what the work verifies, reuses every solved path, and calls nothing done until a check passes — session after session.

  • Zero dependencies, zero network — one script, imports only fs/os/path; it reads local files and prints. ballast itself sends nothing anywhere (the optional verifier/researcher commands are local CLIs you configure)
  • Two commands to install — the plugin marketplace, nothing else
  • One hook + eleven skills — only the hook is code-enforced, and the docs label which is which
  • Checks stand before mistakes — deliverables rehearse against a zero-context reader before shipping, and research collected by a second model arrives hearsay, never as fact
  • Ships empty — the hook stays silent until rules enter your catalog; Quick start is how they get there
  • Hook verified on 5 cases — keyword inject, silence on no match, block, legacy input fields, broken catalog stays harmless; run node hooks/scripts/verify-hook.mjs in a clone of this repo to re-check
  • MIT — the whole mechanism is readable in an afternoon

Install · Why · What changes · Pieces · One goal · Quick start · Philosophy · Maintenance

What that looks like in a session — you set a rule once, weeks ago, after the second broken lockfile:

> add a setup script — npm install and we're done

[ballast] Standing rules that apply to this request:
- Use pnpm here: This repo uses pnpm. npm install has broken the
  lockfile twice; write scripts and commands with pnpm.

Claude: Using pnpm — your rule says npm broke the lockfile twice.
The setup script runs pnpm install.

The [ballast] block is the guaranteed part: "npm" matched your rule, so its full text arrived with this message. The reply follows what Claude was handed, not what it remembered.

Install

/plugin marketplace add svy04/ballast
/plugin install ballast@ballast

The hook runs on the node (≥ 18) already on your PATH. Everything else is markdown. (The install id reads plugin@marketplace — both happen to be named ballast here.)

Using Codex instead? No marketplace there — a short manual setup (clone + one AGENTS.md block + the example catalog) carries the eleven skills over: docs/CODEX.md. Only the hook stays Claude Code-specific, so on Codex everything is convention.

Why ballast

In the fix column, code means a script enforces it whether Claude cooperates or not; convention means markdown instructions Claude follows.

ProblemWhat you seeThe fix
CLAUDE.md is read once; long sessions driftThe same correction, every sessionrules hook (code) — matching rules delivered with each message
Decisions live in old chatsSettled questions relitigated, or quietly rewrittendecision ledger (convention) — append-only; change by supersede
Plausible statements harden into factsConfident answers on unverified claimsverify gate (convention) — every claim labeled; confirmed is earned
Copy describes the roadmap, not the product"We do X" about missing featuresproof standard (convention) — external claims only from a truth file
"Done" means Claude said soDeclared success, quiet failuregoal (convention) — done means a check passed
Deliverables fail on first contact with their readerStalls and misreadings surface after shippingrehearsal (convention) — a zero-context reader executes it before it ships
Research and judgment travel as oneA second model's fluent summary lands as factresearcher (convention) — collection delegated, judgment never; findings arrive hearsay

A truth file is a record of what the product verifiably does, with evidence attached; a passed check is a file that exists, a test that runs, an output actually inspected.

Only one row is code-enforced. The six conventions hold exactly as well as Claude follows them — which means they can drift like any prompt.

ballast does not pretend otherwise. Its route from convention to enforcement is pin: when a convention slips, you correct it once, pin writes the correction into the rule catalog, and the hook delivers it from then on.

The pieces also chain across a goal's whole life — the hook is the only code in this chain; everything else is convention:

  • Prepare — goal mobilizes what the project already holds, then scans the terrain; with a researcher configured, the collecting itself can be delegated
  • Accumulate — knowledge-base and the decision ledger keep what the work verifies; rehearsal is how a deliverable earns its passed check
  • Reuse — the rules hook, pin, and skill-forge put it back into later sessions
  • Return — checkpoint makes picking the goal back up a thirty-second read
flowchart TD
    G["a goal arrives — /ballast:goal"] --> M{"mobilize:<br/>already held in rules,<br/>knowledge, skills?"}
    M -- "held → using it is mandatory" --> W["the work"]
    M -- "gap → learn first" --> L["terrain scan → top-down skeleton →<br/>bottom-up leaves, each verified"]
    L -. "collection delegated<br/>(optional) — returns hearsay" .-> X["researcher"] -.-> L
    L --> V["verify gate — refute first,<br/>a second model may argue back"] --> K[("memory/knowledge/<br/>labeled, sourced")]
    K --> W
    W -- "you correct Claude once" --> P["pin"] --> R[("rule catalog")]
    R -- "hook delivers on every<br/>matching message" --> W
    W -- "a solved path recurs" --> S["skill-forge →<br/>a skill file"] --> W
    W -- "pause" --> C[("CHECKPOINT.md")] -- "30-second return" --> W
    W --> RH["rehearsal — a zero-context<br/>reader executes it"] --> D["done = a check passed"]

What changes

BeforeAfter
The same correction, repeated every weekpin writes it once; it arrives with every matching message
Standing rules cost context, relevant or notOnly matching rules delivered — max 12 rules / ~6,000 chars
Prompts you'd rather have stopped go throughaction: "block" refuses them, showing your rule as the reason
Memory resets with every sessionmemory/ persists: index, ledger, open questions, session log
The goal's skeleton evaporates with the sessionmemory/goal/<slug>.md keeps the tree, its gaps, and the next leaf

The delivery cap is fixed in the hook source. Blocking is a guardrail, not a sandbox — the hook is fail-open (see Quick start).

The pieces

PieceKindRole
rules hookcode — script on every promptDelivers each matching rule's full text with the message, up to the cap; block rules stop the prompt instead
decision-ledgerconvention — markdown skillAppend-only DECISIONS.md; changed minds get supersede links, never silent edits
verify-gateconvention — markdown skillResearch and model knowledge stay drafts until refuted-and-survived, sourced, and labeled
knowledge-baseconvention — markdown skillGate-passed findings land in memory/knowledge/; every new question reads there before researching
researcherconvention — markdown skillCollection delegated to a configured second CLI, judgment never — findings arrive hearsay and must still pass the gate
proof-standardconvention — markdown skillNo external claim without evidence in a truth file; copy may not blur code states
brain-initconvention — markdown skillScaffolds memory: index, ledger, open questions, session log, product truth; appends a session-start block to CLAUDE.md (on Codex, AGENTS.md)
goalconvention — markdown skillMobilizes what you already hold, maps the field, splits the goal top-down into a pyramid of atomic pieces — no overlaps, no gaps — and fills them bottom-up, each verified before it bears weight
rehearsalconvention — markdown skillA zero-context reader executes the deliverable before it ships; the stall log becomes the done-check's evidence
checkpointconvention — markdown skillCHECKPOINT.md keeps a thirty-second return point; HANDOFF.md carries orders read once, then deleted
pinconvention — writes hook rulesTurns the correction you just made into a permanent rule, in one step
skill-forgeconvention — markdown skillA procedure that recurred and passed its check becomes a skill file; the next run starts from the solved path

verify-gate's labels: confirmed / observed / assumed / hearsay / unknown. proof-standard tracks code in four states — implemented, wired, operational, verified.

Every skill is callable as /ballast:<name>; most also fire on their own cue — each skill file's description says when.

One goal, start to finish

  1. /ballast:goal build the pricing page — mobilize finds a pricing rule already in the catalog and brand facts in memory/knowledge/. Both get used, not rediscovered.
  2. One branch is a gap — checkout copy conventions. That branch starts with a terrain scan (a configured researcher can do the collecting; everything it returns arrives hearsay), then the goal gets cut top-down into a pyramid of atomic pieces and the gaps get learned bottom-up — what survives the verify gate lands in memory/knowledge/, labeled and sourced. The skeleton itself lives in memory/goal/pricing-page.md, so tomorrow's session starts from the same tree.
  3. Mid-work you correct Claude once: "prices include VAT." pin writes it to the catalog; the hook delivers it with every pricing message after that.
  4. "Page is live, form tested" is a claim — a zero-context reader walks the page cold (rehearsal), and the stall-free round is the passed check that lets the goal be called done.
  5. You stop for the day. checkpoint writes the thirty-second return point; tomorrow starts at next first action, not at "where were we".
  6. Next quarter's pricing page starts from the solved path — skill-forge kept the procedure as a skill.

One correction, one verified fact, one solved procedure — each outlives its session. That is the whole plugin.

Quick start

First session

  1. Smoke-test in 60 seconds. Create <project>/.claude/ballast.rules.json from the example catalog (rules/ballast.rules.example.json — installed from the marketplace? ask Claude to copy it from the ballast plugin, or paste the JSON under Write the catalog by hand). Then send any message containing "generate": a [ballast] block above the reply means the hook is live.
  2. Pin your first rule. Correct Claude about anything once — a correction is the pin skill's cue: Claude drafts the rule entry, shows it to you, and writes it to the catalog on your OK. If no draft appears, call /ballast:pin directly.
  3. /ballast:brain-init scaffolds the memory files in your project — and appends a session-start block to your CLAUDE.md, so expect that file to change.
  4. /ballast:goal <something big> runs the full pipeline — in an unfamiliar field it maps what's argued, what's settled, and where beginners get burned before producing a single answer.

Before any rule exists, your message arrives alone. With the example catalog from step 0 in place, "generate" trips its cost-gate rule and the message arrives like this:

> generate 40 images for the launch batch

[ballast] Standing rules that apply to this request:
- Estimate before spending: Anything that spends money or credits:
  present an estimate and get explicit approval BEFORE executing.
  No exceptions for small amounts — the habit is the point.

Write the catalog by hand

Rules live in <project>/.claude/ballast.rules.json and ~/.claude/ballast.rules.json (project wins on duplicate id). The version/rules wrapper is required — a file holding a bare rule object loads as zero rules, silently:

{
  "version": 1,
  "rules": [
    {
      "id": "cost-gate",
      "title": "Estimate before spending",
      "when": { "keywords": ["generate", "credits"], "patterns": ["\\bbatch\\b"] },
      "action": "inject",
      "body": "Anything that spends money or credits: present an estimate and get explicit approval BEFORE executing. No exceptions for small amounts — the habit is the point."
    }
  ]
}
  • keywords — case-insensitive substring match; the string must appear verbatim in the message, so add keywords in the language you chat in. Short keywords match inside longer words — npm also fires on pnpm
  • patterns — regex match
  • always: true — fires on every message; keep to 1–2 rules
  • action: "block" — stops the prompt and shows body as the reason
  • BALLAST_DISABLE=1 — turns the hook off (set env vars in the environment you launch Claude Code from)
  • BALLAST_DEBUG=1 — prints load failures and bad patterns to stderr; the hook otherwise swallows them

Start from rules/ballast.rules.example.json, or let pin write entries for you.

Know the limits

Two design choices to keep in mind:

  • Fail-silent — a broken catalog, a bad regex, or an internal error never breaks your session.
  • Fail-open — if the hook cannot run at all (node missing from PATH, catalog unreadable), block rules do not fire either. Treat blocks as a guardrail, not a sandbox.

Fail-open has no error screen — the only symptom is a missing [ballast] block on a message that should match. Check that node --version prints 18+ (install Node if it doesn't), restart Claude Code if the plugin was installed this session, then rerun with BALLAST_DEBUG=1 for the specific failure.

To put a second model on verification duty, create <project>/.claude/ballast.verifier.json — the whole file is { "command": "your-verifier-cli --check" } (example).

Point command at any CLI that will argue against a claim — the verify-gate skill runs it with the claim as the final argument and weighs the refutation before labeling anything confirmed. Without the file — or when the command fails, said once — the gate still runs on primary sources alone, labeled (self-gated).

To delegate collection the same way, create <project>/.claude/ballast.researcher.json — same shape, { "command": "your-researcher-cli --search" } (example); the researcher skill runs it with the question as the final argument.

Collection is delegated, judgment is not: findings arrive hearsay and must still pass the gate. Without the file Claude collects as before, and a command that fails gets said once.

Before your first push from any Claude-operated repo, walk docs/PUBLISH-CHECKLIST.md — these workspaces accumulate secrets in files you stopped looking at.

Philosophy

ballast assumes that when work with Claude goes wrong, the usual cause is memory or overconfidence, not capability. So rules live in files and arrive with the message that needs them.

Decisions live in a ledger that cannot be quietly rewritten. Claims carry labels until they earn confirmed.

The pieces share one arrangement: the check stands before the mistake — rules arrive before the reply, mobilize runs before the work, rehearsal runs before the reader ever sees the deliverable. That order came from months of fixing accidents after they shipped — the same months the disclosure below files under hearsay; ballast is built to close the room they happened in.

By those labels, this README owes you two disclosures:

  • The track record is hearsay. ballast exists because one person with no development background runs an entire job through Claude Code and must be able to trust the results. But those months of daily use happened in a private company workspace, and this public repo dates from August 2026 — no history here opens.
  • The novelty claim is unknown. Injecting context on prompt submit is a documented Claude Code hook pattern, and append-only records long predate software. "We have not seen the whole loop elsewhere" is the most ballast can say.

What you can check is the mechanism: the hook, the eleven skills, and the rule format are all in this repo, readable in an afternoon. If you know prior art for the loop, open an issue and we'll link it.

Maintenance

Version history lives in CHANGELOG.md — each release records what changed and what was corrected. Ask anything in an issue; answers that belonged in this README get written into it.

Pull requests start at CONTRIBUTING.md — the short version: the hook stays zero-dependency and fail-silent, and docs must match behavior.


MIT

// faq

What is ballast?

Turns working with Claude Code into a system that finishes goals: what you teach, verify, and solve once stays in use — session after session.. It is open-source on GitHub.

Is ballast free to use?

ballast is open-source under the MIT license, so it is free to use.

What category does ballast belong to?

ballast is listed under plugins in the Claudeers registry of Claude-compatible tools.

1 views
17 stars
unclaimed
updated 7 days ago

// embed badge

ballast on Claudeers
[![Claudeers](https://claudeers.com/api/badge/ballast.svg)](https://claudeers.com/ballast)

// retro hit counter

ballast hit counter
[![Hits](https://claudeers.com/api/counter/ballast.svg)](https://claudeers.com/ballast)

// reviews

// guestbook

0/500

// related in Claude Plugins

🔓

A single CLAUDE.md file to improve Claude Code behavior, derived from Andrej Karpathy's observations on LLM coding pitfalls.

// pluginsmultica-ai/203,096[ claude ]
🔓

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explainin…

// pluginsanthropics/Python141,574[ claude ]
🔓

"CLI-Anything: Making ALL Software Agent-Native" -- CLI-Hub: https://clianything.cc/

// pluginsHKUDS/Python47,363Apache-2.0[ claude ]
🔓

financial-services — a Claude ecosystem project on GitHub.

// pluginsanthropics/Python34,276Apache-2.0[ claude ]
→ see how ballast connects across the ecosystem