Skip to content

Repository files navigation

catstack

Self-improving ecosystem engine (engine + corpus + product) for Claude, Cursor, and Codex

CI Agents Skills Hooks

One clone. One ./install.sh. Same stack on every machine.

Install · Ecosystem · Skills · Hooks · Provenance

catstack — Claude, Cursor, Codex

Agent DORA (personal)

Rework should go down over time. Full charts + snapshot: engine/skills/reflect/baselines/dora-ai-report.md

Rework 7d trend — lower is better

Ecosystem

One clone. Three buckets. Mine → apply → PR → install. Details: docs/ecosystem.md.

flowchart TB
  transcripts[Transcripts] --> engine
  subgraph engine [engine]
    hooks[hooks]
    reflect[reflect_session-mine]
    author[create-skill_draft-pr_make-pr]
    automate[automate-me]
    gates[scripts_CI_always-on]
  end
  subgraph corpus [corpus]
    principles[principle_skills]
    personal[cat-mode]
    mined[other_mined_SKILL_edits]
  end
  subgraph product [product]
    portable[diu_land-stack_visual-proof_etc]
  end
  reflect -->|Accepted_skill_prose| corpus
  reflect -->|hook_over_prose| hooks
  automate -->|handle-mode| personal
  install["./install.sh"] --> engine
  install --> corpus
  install --> product
  install --> home["~/.claude_cursor_codex"]
Loading

Engine loop

What drives improvement: thrash/stop hooks, /reflect, or opt-in session-mine mine transcripts; Accepted opens a worktree + PR (never merge); you land it; ./install.sh refreshes live agents.

flowchart LR
  agents[Live_agents] --> transcripts[Transcripts]
  transcripts --> triggers[hooks_reflect_session-mine]
  triggers --> mine[reflect_synthesize]
  mine -->|Accepted| worktree[catstack_worktree_PR]
  mine -->|working_style| automate[automate-me]
  worktree --> human[Human_lands_PR]
  human --> install["./install.sh"]
  install --> agents
Loading

Bucket inventory and ownership rules: docs/ecosystem.md.

What you get

One install

./install.sh symlinks skills, hooks, slash commands, and always-on rules into Claude, Cursor, and Codex. Safe to rerun. Edit here, git pull on another machine, every symlink updates. At the end of each run it removes any link into catstack that the run did not create, so renamed or deleted hooks and skills do not linger.

Always-on rules

Short answers (diu), evidence before "it works" claims (CLAUDE.md), and PR drafting that actually uses the skill (draft-pr) — not a generic gh pr create recipe.

Hooks that catch drift

Stop-time brevity checks, bug-complaint search discipline, thrash-triggered reflect, live-demo freeze, restart-risk checks. Fail-open. Per-agent, because each harness has different stop-time power.

Portable, not project-locked

Skills generalized from Invoker, DrafterSkill, and pstack. Invoker-only helpers stay in Invoker. Where each file came from: provenance.

Install

git clone https://github.com/EdbertChan/catstack.git
cd catstack
./install.sh

Already have local copies? ./install.sh --force backs them up, then links.

Engine-only mode

./install.sh --engine-only links only the engine: reflect, automate-me, create-skill, draft-pr, make-pr, thrash-reflect-automate, every engine hook, the always-on rules, plus the four gates the engine cites (diu, visual-proof, split-scope, narrow-the-scope). It prunes every other corpus and product symlink from the three harness skill folders and points ~/.claude/CLAUDE.md at engine/CLAUDE.core.md, so the mined rules in corpus/CLAUDE.learned.md are not loaded. A plain ./install.sh restores everything.

Corpus stays in git and keeps refilling as reflect and automate-me run, so a newer model can regenerate the principles from scratch while you keep working.

Claude-only skills (automate-me, cat-mode, narrow-the-scope) skip Cursor and Codex on purpose.

Skills

Each skill is a SKILL.md package under engine/skills/, corpus/skills/, or product/skills/ (install flattens to ~/.*/skills/<name>).

Skill What it does
diu Short answers by default. Lead with the outcome.
draft-pr Draft or update a PR with a real schema, not a generic template.
create-skill Author/install skills for Claude, Cursor, and Codex — never one harness.
split-scope Shape diffs so each PR is one reviewable unit.
land-stack Land a stacked PR by SHA, never by branch name.
reflect Mine a transcript for durable learnings. Accepted items open a catstack worktree + PR (never merge); working-style routes to automate-me.
automate-me Turn working-style findings into a personal <handle>-mode skill. Claude-only.
visual-proof Real before/after captures. No stale screenshots.
loop-generator Interview, then write a babysit/watch/retry loop with real safety rules.
show-me-your-work Leftover decision trail so unattended work is reviewable.
narrow-the-scope Stop mid-session when retries aren't making progress. Claude-only.
cat-mode Edbert's personal conventions. Claude-only.
principle-* Narrow engineering rules, cherry-picked from pstack after backtesting against real sessions.

Full sourcing notes, including what was left out and why: docs/provenance.md.

Hooks

Hook When it fires
diu-stop End of turn: did the answer skip the brevity rule?
bug-complaint-leak Bug-complaint prompts: search class, not just local grep.
reflect-on-thrash Thrash detected: defer reflect until the session ends. Do not steal the current turn. Off unless CATSTACK_REFLECT_ENFORCEMENT=1 (see below).
restart-risk-check Thin-evidence "just restart it" claims.
demo-freeze Live demo window: don't edit the thing being filmed.
frustration-watchdog User-frustration signals.
restated-constraint User repeats a must/never/don't they already gave: apply it, don't re-acknowledge it.
named-verb-guard User said test/repro/run/show/delete/revert/stop, or asked for proof twice, and the reply has no evidence: the model judges the request and flags it on a later turn.
wait-needs-wakeup Waiting on CI, a queue, a subagent, or a job: schedule a wakeup and name a clock-time ETA. Blocks foreground poll loops and ETA-less "will report" replies.
hedge-runs-prove-it "I think" / "probably" / "should work" / a retired bare UNVERIFIED: about code with nothing run this turn: verify now, or tag the claim and name the blocker.
new-file-callout A new untracked file at the repo root or under scripts/: the reply must name it and say why.
agent-relay-attribution Advisory: facts relayed from a subagent's report must say so or be re-verified.
scratchpad-collision Two agents writing the same scratchpad file within ten minutes: use a uniquely named file.
ui-input-guard Synthetic keystrokes, clicks, or screen recording aimed at the user's own session: blocked unless a hands-off window is open, the screen is unlocked, and the user is idle.
handoff-needs-smoke-test A reply hands the user a script (! bash <path>) this session never ran: run it, or name why the run cannot happen here.
hook-freshness Advisory: the catstack checkout behind ~/.claude/hooks is off main or behind origin/main, so merged hook fixes are not live on this machine.
auto-pr catstack itself changed: tell the agent to open a PR, no request needed.
cat-mode-default Every investigation or execution prompt, and every subagent prompt sent through the Agent tool: apply cat-mode without typing /cat-mode. Off unless CATSTACK_CAT_MODE_DEFAULT=on (env or .env; see engine/hooks/cat-mode-default/README.md).
plan-discipline Not installed yet (needs Agent mode): block product .py writes after a declined SwitchMode; require "How we test" on new-module plans; no eval numbers without a verifying run; warn on semantic plan-churn. Spec: engine/hooks/plan-discipline/README.md.

Details live in each hook's README under engine/hooks/<name>/.

Reflect enforcement (opt-in)

Four hooks and one always-on rule push you toward /reflect and automate-me. All of them are off unless CATSTACK_REFLECT_ENFORCEMENT is on:

What Read when What it does when on
scope-lock hook every tool call after a second scope correction, stops every tool until you type /reflect and automate-me
reflect-on-thrash hook end of session asks for a reflect at the end of a thrashy session
wrong-check-reflect hook end of turn queues a judge on a retraction-shaped reply
verdict-flip-watch hook after a check runs notes a verifier that passed and then failed
"same complaint type twice: invoke automate-me" rule ./install.sh installs the rule for Claude, Cursor and Codex
echo 'CATSTACK_REFLECT_ENFORCEMENT=1' >> ~/.catstack.env
./install.sh

The hooks see a change on their next run. The rule changes only when ./install.sh runs again, and a run with the flag off removes the rule an earlier run installed. The environment, $CATSTACK_ENV_FILE, the repo's .env and ~/.catstack.env are read in that order. frustration-watchdog is not in this class -- it enforces the live-demo "end the wait" rule and never mentions reflect. Details: engine/hooks/_flags/README.md.

Flags

Every flag is off unless set. "Env and files" is the lookup above; "env only" is the process environment alone.

Flag Read from Effect
CATSTACK_REFLECT_ENFORCEMENT=1 env and files the reflect hooks and rule above
CATSTACK_CAT_MODE_DEFAULT=off|decide|on env and files off: cat-mode runs only when typed as /cat-mode. decide: ./install.sh installs cat-mode so the model may pick it on its own (re-run install after changing to or from it). on: cat-mode-default applies cat-mode to every prompt and every subagent prompt. 1 means on, 0 means off.
CATSTACK_HOOK_FRESHNESS=off|local|fetch env only hook-freshness mode: off (or 0) silences it; local, the default, counts against the last-fetched origin/main; fetch runs a short git fetch first
CATSTACK_SKILL_USAGE_LOG=1 env only skill-usage-log records each Skill tool call
CATSTACK_LLM_JUDGE_RUNNERS env only a JSON list of [name, argv] pairs that replaces the background judge's model runners
CATSTACK_DORA_GIT_ROOTS, CATSTACK_DORA_GH_REPOS, CATSTACK_DORA_DEPLOY_GIT_ONLY env only session-mine DORA inputs: colon-separated git roots, comma-separated owner/name repos, and 1 to skip GitHub search and take merged PRs from local git only

Path variables, env only, move where a hook or test keeps state: CATSTACK_HOOK_METRICS_DIR, CATSTACK_LLM_JUDGE_STATE_DIR, CATSTACK_TAG_LEDGER_DIR, CATSTACK_SKILL_USAGE_LOG_STATE_DIR, CATSTACK_HOOKS_REPO, CATSTACK_REFLECT_RULE_FILE, and the other CATSTACK_*_STATE_DIR variables.

Session mine (opt-in)

Hourly local scan of Claude / Cursor / Codex transcripts for repeated user pokes, plus DORA-for-agents metrics. Off by default:

./install.sh --with-session-mine

Details: engine/skills/reflect/references/session-mine.md.

Docs

About

Personal Claude, Cursor, and Codex skills — one install, one source of truth

Topics

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages