Self-improving ecosystem engine (engine + corpus + product) for Claude, Cursor, and Codex
One clone. One ./install.sh. Same stack on every machine.
Install · Ecosystem · Skills · Hooks · Provenance
Rework should go down over time. Full charts + snapshot: engine/skills/reflect/baselines/dora-ai-report.md
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"]
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
Bucket inventory and ownership rules: docs/ecosystem.md.
|
|
Short answers ( |
|
Stop-time brevity checks, bug-complaint search discipline, thrash-triggered |
Skills generalized from Invoker, DrafterSkill, and pstack. Invoker-only helpers stay in Invoker. Where each file came from: provenance. |
git clone https://github.com/EdbertChan/catstack.git
cd catstack
./install.shAlready have local copies? ./install.sh --force backs them up, then links.
./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.
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.
| 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>/.
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.shThe 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.
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.
Hourly local scan of Claude / Cursor / Codex transcripts for repeated user pokes, plus DORA-for-agents metrics. Off by default:
./install.sh --with-session-mineDetails: engine/skills/reflect/references/session-mine.md.
- Provenance — where each skill came from, and how to refresh it
- Contributing
CLAUDE.md— personal, cross-project agent instructionsinstall.sh— the one command