forge-discipline
Use when turning a named behavioral pattern (gem, fresh arXiv finding, matured instinct) into an INSTALLED, self-tested Claude Code hook in one pass. A BEHAVIOR forge, not a tool forge - it forges hooks/tripwires the harness runs deterministically, not MCP tools. Scaffolds the hook, runs a chaos self-test proving it fires and fails open on garbage, then stages it with the one-line install.
- License 许可
- MIT
- 最近更新
- 2026-11-02
- Stars
- ★ 0
- Forks
- 0
01 前言 Front Matter
- name
- forge-discipline
- description
- Use when turning a named behavioral pattern (gem, fresh arXiv finding, matured instinct) into an INSTALLED, self-tested Claude Code hook in one pass. A BEHAVIOR forge, not a tool forge - it forges hooks/tripwires the harness runs deterministically, not MCP tools. Scaffolds the hook, runs a chaos self-test proving it fires and fails open on garbage, then stages it with the one-line install.
02 资源文件 11
- 脚本forge.py24.8 KB
- 脚本selftest_forge.py5.1 KB
- 其他templates/chaos_gate.py.tmpl4.6 KB
- 其他templates/chaos_inject.py.tmpl4.6 KB
- 其他templates/hook_gate.py.tmpl2.1 KB
- 其他templates/hook_inject.py.tmpl5.4 KB
- 其他templates/INSTALL.md.tmpl1.3 KB
- 其他templates/skill_stub.md.tmpl1.1 KB
- 其他templates/test_gate.py.tmpl1.9 KB
- 其他templates/test_inject.py.tmpl3.0 KB
- 其他templates/tripwire.py.tmpl1.2 KB
03 SKILL.md 正文
Discipline-Forge
The durable moat is not which cross-domain analogy you borrow today (those deprecate the moment the field mines the same paper). The moat is owning the pipeline that turns any named behavioral pattern into an installed, self-tested discipline in one pass. This generalizes the instinct→skill evolution one step further: instead of maturing an observed regularity into an advisory skill, it forges an enforced hook that the harness runs deterministically — and refuses to call it "installed" until a fault-injection self-test proves it actually fires.
This forges behaviors (hooks/tripwires). A tool-forge forges tools (things
the model chooses to call). Different artifact, different home: forged behaviors land
in ~/.claude/hooks/... and fold into the dispatcher or settings.json.
SAFETY: review before install (read this first)
forge.py never edits your live settings.json or _dispatch/manifest.json. A
forged discipline is staged in a review queue with its passing self-test and a single
ready-to-apply line. You read it and apply that line by hand. This mirrors the
auto-skill-authoring discipline (the forge proposes; the human installs) and means a
forged hook can never silently start blocking your tools or injecting context.
Every forged hook also fails open (any error → exit 0; a gate never blocks on error)
and ships a kill-switch: an env var FORGE_<NAME>_OFF=1 and a .disabled file.
The pattern spec
A discipline is described by a small spec (CLI flags or a --spec file.json):
| field | meaning |
|---|---|
name |
hyphen-case identity (becomes the hook dir + manifest name) |
event |
sessionstart | stop | pretooluse | posttooluse | userpromptsubmit |
trigger_kind |
how the predicate reads its source: tool | command | prompt | response | field | always |
trigger_regex |
the pattern the source must match to fire (not needed for always) |
fire_example / silent_example |
a value that SHOULD / must NOT match — used to build the chaos test (validated at forge time) |
action |
the inject message (may contain {count}) or the block reason for a gate |
gates |
if set, forge a blocking tripwire (exit-2 path) instead of an inject |
needs_state |
scaffold a state/ledger schema + session-scoped dedup |
has_procedure |
also emit a companion SKILL stub |
The forge validates the exemplars against the regex at generation time: if the fire example does not match (or the silent example does), it refuses to generate — because the chaos test would otherwise be a lie.
The one-pass pipeline (what forge.py does)
-
Scaffold exactly the artifacts the pattern needs:
hook.py— conforms to the dispatcher check-interface:main(argv)reads the payload on stdin and prints onehookSpecificOutputJSON (inject), or writes a reason to stderr and exits 2 (gate).tripwire.py— the pure HALT predicateshould_halt(payload) -> (bool, reason)(only whengates); kept separate so the block decision is unit-testable.state_schema.json— the ledger record schema (only whenneeds_state).SKILL.md— a companion procedure stub (only whenhas_procedure).- Everything fails open (try/except → exit 0).
-
Unit test the predicate (
build_message/should_halt) directly and run it. -
Chaos / GameDay self-test (
chaos_<name>.py) — fault-injects against the REAL hook process to prove three properties; the discipline is not installed until all three hold:- fires on a matching payload,
- stays silent (inject) / allows (gate) on a non-matching payload,
- fails open on garbage stdin and honours the opt-out.
The GameDay lesson: an untested safety net fails exactly when you need it. A gate that crashed-closed would block every command, so "fail open on garbage → exit 0, never 2" is an explicit, proven property.
-
Stage in the review queue
~/.claude/forge-queue/<name>/with the artifacts, the passing self-test (SELFTEST-RESULT.txt), andINSTALL.mdcontaining the one line to apply. Nothing is auto-wired.
How forged hooks compose with the dispatcher / manifest
The forge picks the install target from the event and whether it gates:
- Inject hook on
sessionstart/stop/pre/posttooluse→ folds into~/.claude/hooks/_dispatch/manifest.jsonas one line underevents.<Event>.checks. The dispatcher already runs that file in-process (one spawn per event), so this is the cheap path. The manifest's own description literally says "adding a future check = one manifest line (seeds the later Discipline-Forge)" — this is that forge. - Any gate (exit-2) → a standalone
settings.jsonentry. The dispatcher only ever exits 0 (it is inject-only), so a blocking hook cannot live inside it. userpromptsubmit(any) → a standalonesettings.jsonentry. The dispatcher does not handle that event.
INSTALL.md always prints the exact target and the exact line/object to add.
Where this sits in the instinct → skill path
The continuous-learning / homunculus path observes sessions, writes confidence-scored
instincts (~/.claude/homunculus/instincts/), and evolves the strong ones into
~/.claude/homunculus/evolved/{skills,commands,agents} — all advisory (the model
must choose to read/run them). Discipline-Forge adds a new evolution target at the end
of that path: a matured instinct (or a gem, or an arXiv pattern) → an enforced,
self-tested hook. Advisory knowledge becomes deterministic enforcement, with proof.
Usage
cd skills/forge-discipline
# Inject discipline (Stop): surface uncaptured TODO/FIXME markers. Folds as 1 manifest line.
python forge.py --name todo-surfacer --event stop --trigger-kind response \
--trigger-regex '\b(TODO|FIXME)\b|- \[ \]' \
--fire-example 'TODO wire API; - [ ] ship' --silent-example 'all shipped' \
--action 'You left {count} open TODO/FIXME marker(s) - capture them before they are lost.'
# Gate discipline (PreToolUse): block git push --force. Installs as a settings.json entry.
python forge.py --name no-force-push --event pretooluse --trigger-kind command --gates \
--trigger-regex 'git\s+push\b[^\n]*(--force\b|-f\b)' \
--fire-example 'git push --force origin main' --silent-example 'git push origin main' \
--action 'Tripwire: refusing git push --force (AGENTS.md s9 needs explicit approval). Override: FORGE_NO_FORCE_PUSH_OFF=1.'
# Inspect without staging: add --dry-run
# Full result as JSON: add --json
Then open ~/.claude/forge-queue/<name>/INSTALL.md, review the artifacts and the
passing self-test, and apply the one line if you approve.
Trigger kinds
| kind | source read | typical event |
|---|---|---|
tool |
payload.tool_name |
pre/posttooluse |
command |
payload.tool_input.command (Bash) |
pre/posttooluse |
prompt |
payload.prompt |
userpromptsubmit |
response |
final assistant text from transcript_path |
stop |
field |
any dotted payload path (--trigger-field) |
any |
always |
no predicate — always fires (inject only) | sessionstart/stop |
Files
forge.py— the scaffolder + self-test orchestrator (pure stdlib).templates/— the hook / tripwire / test / chaos / skill-stub / install templates.selftest_forge.py— regression harness: forges every branch combination in--dry-runand asserts each self-tests cleanly and resolves to the right target.
Quality bar
A discipline that "looks wired but is dead" is the failure this skill exists to
prevent. The chaos self-test is the gate: no PASS, no queue entry, no install line.
Run python selftest_forge.py after any change to the engine or templates.
04 同仓库更多 Skills
clarify-requirements
Resolve genuine pre-execution ambiguity by scanning repo context, generating 1-6 grounded options, and asking 1-3 focused questions via AskUserQuestion. NOT for mid-task use (injection risk); NOT when the goal is already unambiguous; use to disambiguate vague prompts before any file edits.
openmm-md
Run FREE, open-source, Windows-native GPU molecular dynamics via the openmm-md MCP (OpenMM + CUDA on the local NVIDIA GPU). Use for protein / protein-ligand MD when you want a free stack or are on Windows without a Schrodinger license. Covers the full workflow (prepare, solvate, minimize, equilibrate, production, analyze, mmgbsa) AND an honest decision guide vs Schrodinger Desmond, including how to run Desmond legitimately on Linux or a cloud GPU with a real license. This is a deliberately LESSER free alternative and does NOT replace the schrodinger MCP tools. Do NOT use it to pick a free tool when a validated FEP+, WaterMap, IFD-MD, or Prime MM-GBSA result is actually required.
visual-review
Take screenshots of web pages and UI using Playwright for visual review and iteration
status
Diagnostic status report — shows metaswarm installation state, project setup, and potential issues
start
Use when starting work on any task, when the user mentions metaswarm, or when the user wants to begin tracked development work
setup
Interactive project setup — detects your project, configures metaswarm, writes project-local files