Most agent skills teach how to build. Aftermath teaches how to stop and recover when something already broke: a test suite goes green → red, the same error recurs, a build or dependency resolution fails, a test is flaky, a merge conflicts, a destructive command looms, or the user says "you broke it".
ASCII banner (terminal)
██ ████ █████ ████ ███ █ █ ██ █████ █ █
█ █ █ █ █ █ █ ██ ██ █ █ █ █ █
████ ███ █ ███ ███ █ █ █ ████ █ ████
█ █ █ █ █ █ █ █ █ █ █ █ █ █
█ █ █ █ ████ █ █ █ █ █ █ █ █ █
stop · revert · recover
After any failure, stop at the first rung that holds:
- Uncommitted / one file / cheap to undo? → Revert now. Do not patch forward.
- Last-known-good exists? → Diff it, isolate one change, revert just that.
- 2nd+ failed attempt at the same fix? → State exact error, state theory, ask.
- Next action irreversible? → Confirm state explicitly. Never assume.
- Filling a gap with a guess? → Say so out loud.
- User just corrected you? → Do not defend. Find the diff. Fix only that.
Honesty under pressure: never hide a break, never silently revert, never invent an unverified root cause.
npx @moah0911/aftermath init # detect stack + write .aftermath/config.json
npx @moah0911/aftermath init --dry-run --json
npx @moah0911/aftermath init --run-tests # also record a baseline (opt-in)Init detects test/build commands, disposable artifacts, and protected paths, then writes
.aftermath/config.json. From then on, rm -rf node_modules or rm -rf dist is allowed
while rm -rf src, .env, .git, and unknown targets stay blocked. It never runs
destructive commands and never enables autoRevert.
Full flags, detection matrix, config schema, and policy reasons: docs/init.md.
{
"version": 1,
"defaultMode": "full",
"autoRevert": false,
"stacks": ["node"],
"packageManager": "npm",
"testCommands": ["npm test"],
"buildCommands": ["npm run build"],
"safePaths": ["node_modules", "dist", "coverage"],
"protectedPaths": [".git", ".env*", "src", "tests", "package.json"],
"destructiveAllowlist": []
}- Destructive commands are blocked at
full/ultra(force push, reset --hard, clean -f, rm -rf, drop, prune, destroy).liteonly flags them.destructiveAllowlisthandles intentional exceptions. - Project-aware path policy: after
aftermath init, filesystem deletes are allowed only when every target is a literal path undersafePathsand outsideprotectedPaths. Unknown, dynamic, absolute-outside, or protected targets stay blocked. Claude Code and Codex use the same policy throughPreToolUse. - Forward edits are frozen while a failure is unresolved. OpenCode blocks
edit/write; Claude Code and Codex block Edit/Write/MultiEdit inPreToolUse. Get a test green, run/aftermath-revert, or drop tolite/off. - Ultra checkpoints (opt-in): snapshot files before edits, mark last-known-good on a green test, restore only matching files on a green→red test. Manual edits become reported conflicts, never overwritten.
- Detection: test failures, repeat-error attempt ledger, flaky alternation, build failure, dependency resolution, merge conflicts, and phrase-level correction signals. Claude Code and Codex receive the same pointers through
PostToolUseandUserPromptSubmit.
| Host | Destructive block | Forward-edit freeze | Failure signals | Checkpoints |
|---|---|---|---|---|
| OpenCode | full/ultra, path-aware | full/ultra | in-process | ultra + autoRevert |
| Claude Code | PreToolUse, path-aware | full/ultra | PostToolUse + UserPromptSubmit | — |
| Codex | PreToolUse, path-aware | full/ultra | PostToolUse + UserPromptSubmit | — |
| Level | Behavior |
|---|---|
lite |
Flags the problem, suggests the revert, lets the user decide. No blocks or auto-revert. |
full |
Default. Stops forward motion, blocks destructive commands and edits after a failure, runs the diff/isolate diagnostic, asks before the next edit. |
ultra |
Same guards as full, plus checkpoint auto-revert when autoRevert: true. Reports what was restored and what conflicted. |
off |
Disabled. |
Switch with /aftermath [lite|full|ultra|off].
Global: ~/.config/aftermath/config.json (or $XDG_CONFIG_HOME/aftermath/config.json).
Project: .aftermath/config.json (written by aftermath init; found by walking up to the nearest .git).
{
"defaultMode": "full",
"autoRevert": true,
"destructiveAllowlist": ["rm -rf ./dist", "git clean -fd"]
}autoRevertdefaults tofalse; it only matters atultra.destructiveAllowlistentries are command substrings; keep them narrow.- Project values override scalars;
destructiveAllowlist,testCommands,buildCommands, andprotectedPathsunion with global values.AFTERMATH_DEFAULT_MODEoverridesdefaultMode. safePaths/protectedPathspower the path-aware destructive policy.
/aftermath [lite|full|ultra|off]— switch intensity or report state/aftermath-status— what changed since last-known-good, plus failure/checkpoint state/aftermath-revert— undo the last change, nothing more/aftermath-audit— scan the diff for scope creep/aftermath-log— append a one-line postmortem toAFTERMATH.log/aftermath-checkpoint status|clear|restore— inspect, clear, or manually restore checkpoints/aftermath-init— initialize the project with destructive-safe paths
| Harness | Install | What you get |
|---|---|---|
| Any skills-compatible agent | npx skills add moah0911/aftermath -g -y |
The eight on-demand skills |
| OpenCode | npm plugin or curl installer | Ladder injection, guards, checkpoints, commands, skills |
| Claude Code | plugin marketplace | SessionStart/UserPromptSubmit/PreToolUse/PostToolUse hooks, commands, skills |
| Codex | codex plugin marketplace add moah0911/aftermath --ref main && codex plugin add aftermath@aftermath |
Shared hooks and skills |
| Checkout / manual | node scripts/install.js |
Host wiring from a clone |
Add the npm package to opencode.json:
{ "plugin": ["@moah0911/aftermath"] }Or install globally with the curl bootstrapper (plugin + commands + skills):
curl -fsSL https://raw.githubusercontent.com/moah0911/aftermath/main/scripts/install.sh \
| bash -s --/plugin marketplace add moah0911/aftermath
/plugin install aftermath@aftermath
codex plugin marketplace add moah0911/aftermath --ref main && codex plugin add aftermath@aftermathThe marketplace must be registered before the plugin is installed. The Aftermath
installer runs both commands automatically when codex is on PATH:
curl -fsSL https://raw.githubusercontent.com/moah0911/aftermath/main/scripts/install.sh \
| bash -s -- --host codexnpx skills add moah0911/aftermath -g -yThis installs the skills only. Hosts with lifecycle hooks get the fuller enforcement;
see docs/agent-portability.md.
git clone https://github.com/moah0911/aftermath
node aftermath/scripts/install.js --project --host all--host opencode|claude|codex|all filters the host steps, --source uses an existing
checkout, --mode lite|full|ultra|off persists a default level, --dry-run prints the
actions, and --uninstall removes the wiring. OpenCode is wired in place; Codex is
installed through its CLI when available; Claude Code prints its two interactive
marketplace prompts.
Manual OpenCode wiring:
{ "plugin": ["./.opencode/plugins/aftermath.mjs"] }After installing, run the project initializer once. It detects stacks/test commands and
writes .aftermath/config.json with destructive-safe paths:
npx @moah0911/aftermath init
# or from a checkout:
node aftermath/scripts/init.jsSee docs/init.md for flags, detection, and policy details. Restart the
host after installing if it does not reload plugins automatically.
AFTERMATH.md # the ladder — always loaded, ~dozen lines
SKILL.md # root skill entry (discovery pointer)
assets/ # logo.png, icon.png, aftermath.txt (via scripts/make-logo.py)
docs/ # init/config and agent-portability references
hooks/ # config, instruction builder, signals, checkpoints, policy, host hooks
skills/ # aftermath + 7 failure-category playbooks
commands/ # portable slash commands (mirrored to .opencode/commands/)
.opencode/plugins/ # server plugin (ladder injection + enforcement + tripwires)
scripts/ # init.js, cli.js, install.js, install.sh, consistency checks
tests/ # node:test suite
npm test # full node:test suite
npm run test:coverage # runtime coverage gate (95% lines / 85% branches / 98% funcs)
npm run check # rule-copy + command sync + version alignmentMIT — see LICENSE.
