grudge

The Book of Grudges — cross-session bug graveyard. Every fixed bug is recorded as a structured "grudge"; before touching code, skills query the grudgebook for the files in scope and surface past regressions as forced "DO NOT REPEAT" context. Read mode (pre-flight) and write mode (on bug resolution / fix(*) PR). Machine-local, per-repo, never committed. Triggers on /grudge, "check grudges", "record a grudge", "any past bugs here", "regression oracle", "bug graveyard".

10 stars

Best use case

grudge is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

The Book of Grudges — cross-session bug graveyard. Every fixed bug is recorded as a structured "grudge"; before touching code, skills query the grudgebook for the files in scope and surface past regressions as forced "DO NOT REPEAT" context. Read mode (pre-flight) and write mode (on bug resolution / fix(*) PR). Machine-local, per-repo, never committed. Triggers on /grudge, "check grudges", "record a grudge", "any past bugs here", "regression oracle", "bug graveyard".

Teams using grudge should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/grudge/SKILL.md --create-dirs "https://raw.githubusercontent.com/raddue/crucible/main/skills/grudge/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/grudge/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How grudge Compares

Feature / AgentgrudgeStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

The Book of Grudges — cross-session bug graveyard. Every fixed bug is recorded as a structured "grudge"; before touching code, skills query the grudgebook for the files in scope and surface past regressions as forced "DO NOT REPEAT" context. Read mode (pre-flight) and write mode (on bug resolution / fix(*) PR). Machine-local, per-repo, never committed. Triggers on /grudge, "check grudges", "record a grudge", "any past bugs here", "regression oracle", "bug graveyard".

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Grudge — the Book of Grudges (#271)

> Named for the dwarven Dammaz Kron: every wrong is written down and **never
> forgotten until it is settled.** A fixed bug becomes a grudge the toolchain
> holds against the files that caused it — and refuses to let happen again.

Stock Claude Code has no memory across sessions, so the same class of bug
re-ships. The grudgebook closes the loop: **write-on-resolution** +
**read-on-preflight**. Spec: `docs/plans/2026-06-01-regression-oracle-design.md`.

## Where grudges live (read this first)

The grudgebook is **machine-local and per-repo**, NEVER inside a git tree:

```
$CRUCIBLE_GRUDGE_DIR  (or ~/.claude/crucible/grudge)
  /<repo>/grudges/<hash>.md
```

Grudges carry private file paths + repro detail and crucible is PUBLIC, so the
live store must stay outside any repo (mirrors the calibration ledger central
store, PR #326). `scripts/grudge_append.py` **refuses** to write into the current
repo's tree. The committed `.crucible/grudge/grudges/*.md` are **synthetic
fixtures only**. Isolation is by `repo_root` (git toplevel realpath), so two
checkouts that share a basename never bleed into each other.

## Resolving the helpers (cwd-independent)

A gating skill runs with an arbitrary cwd, so locate the scripts by absolute path
from the plugin root (same convention as `shared/ledger-append.md`):

```
# plugin layout is invariant: <plugin_root>/skills/<name>/ and <plugin_root>/scripts/
plugin_root="$(realpath "<this-skill-base-dir>/../..")"
query="$plugin_root/scripts/grudge_query.py"
append="$plugin_root/scripts/grudge_append.py"
# If unresolved: emit a one-line stderr warning and SKIP. The grudgebook is
# advisory; a missing query/record must NEVER block or fail the host skill.
```

## Read mode (pre-flight — "what grudges do we hold here?")

Before writing/reviewing code, pass the in-scope files (absolute, `./`-prefixed,
or repo-relative — all normalized) to the query helper and inject any output into
your working context as a hard constraint:

```
python3 "$query" path/to/file1 path/to/file2 [--with-signatures] [--limit N]
```

- Path match is always on. Add `--with-signatures` when you already have file
  contents in hand (it greps `anti_pattern_signature` regexes against file bodies).
- Non-empty output = grudges held against these files. Treat each `☠` line as
  **DO NOT REPEAT** — do not re-introduce that bug.
- Maintenance: `--stats` (how many grudges held / recently written — spot
  starvation) and `--cull` (strike settled grudges whose files are all gone).
- A stderr line `grudge: scanned=… matched=… skipped_stale=…` always prints so a
  silent/empty grudgebook is visible.

## Write mode (record a grudge — on bug resolution / fix(*) PR)

When a bug is confirmed fixed, record it (best-effort; a failed record logs to
stderr and never fails the host skill):

```
python3 "$append" \
  --symptom "one-line observable failure" \
  --root-cause "one-line underlying cause" \
  --files "src/a.py,src/b.py" \
  --signature "optional regex or literal snippet that fingerprints the bug" \
  --commit "<fixing sha>" \
  --repro "minimal repro steps" \
  --why "why this kept happening"
```

## Grudge schema

```markdown
---
schema: 1
hash: <sha256(repo_root|sorted-normalized(files_touched)|discriminator)[:12]>
repo: <basename>            # cosmetic dir name
repo_root: <abs realpath>   # isolation key; reads filter on this
fixed_in_commit: <sha>      # recorded, NOT part of the key
symptom: <one-line>         # dedupe discriminator when no signature
root_cause: <one-line>
files_touched: ["repo/rel/path", ...]
anti_pattern_signature: "<regex or literal snippet>"   # optional
date_fixed: YYYY-MM-DD
---
## Repro
<steps>
## Why this kept happening
<expanded root cause>
```

**Dedupe:** key excludes `fixed_in_commit` (one bug can be fixed in many commits);
`discriminator = anti_pattern_signature` when non-empty else `symptom`. Same key →
overwrite (last write wins). A grudge with neither files nor a discriminator is
rejected.

## Consumers (where the wiring lives)

- **Pre-flight (read):** `build` (Phase 2, post-design/pre-implementation),
  `quality-gate` (round-1 dispatch), `debugging` (opening phase).
- **Write:** `debugging` (resolution phase), `merge-pr` (on `fix(*)` PRs).

## Non-goals (v1)

No semantic search (glob + regex only); no cross-**user** shared grudgebook
(sanitized community grudges — v1.1 candidate); no `settings.json` hook.

Related Skills

We are still matching the closest adjacent skills for this page. In the meantime, continue through the full directory.