From badbd1bd64f768deeec6ea1c7ad2f18526a7c5fb Mon Sep 17 00:00:00 2001 From: Eric Dahl Date: Fri, 15 May 2026 01:40:08 -0400 Subject: [PATCH 1/3] Narrow crush-code activation to explicit invocation only MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Prevent accidental activation from generic phrases like "get to work", "keep going", or "work the issues" — require explicit /crush-code or "run crush-code". Assisted-by: Crush:claude-sonnet-4-5 --- skills/engineering/crush-code/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/skills/engineering/crush-code/SKILL.md b/skills/engineering/crush-code/SKILL.md index fdbdc03..05e6586 100644 --- a/skills/engineering/crush-code/SKILL.md +++ b/skills/engineering/crush-code/SKILL.md @@ -1,6 +1,6 @@ --- name: crush-code -description: Autonomous issue-driven development loop for any repo. Works issues one by one using TDD and caveman mode, opens auto-merge PRs, resolves CI failures and merge conflicts, and pings the user via Telegram only when truly blocked. Use when user says "get to work", "work the issues", "keep going", or invokes /crush-code. +description: Autonomous issue-driven development loop for any repo. Works issues one by one using TDD and caveman mode, opens auto-merge PRs, resolves CI failures and merge conflicts, and pings the user via Telegram only when truly blocked. ONLY activate when user explicitly invokes /crush-code or says "run crush-code" — do NOT activate for generic phrases like "get to work", "keep going", or "work the issues". --- # crush-code From dcb3800cdf975a7d6ab673d45947cc55534dde4a Mon Sep 17 00:00:00 2001 From: Eric Dahl Date: Fri, 15 May 2026 01:42:38 -0400 Subject: [PATCH 2/3] Make Telegram optional with terminal fallback When telegram_send_message is not available, fall back to stdout for status messages and stdin prompts for blocking questions. Assisted-by: Crush:claude-sonnet-4-5 --- skills/engineering/crush-code/SKILL.md | 27 +++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/skills/engineering/crush-code/SKILL.md b/skills/engineering/crush-code/SKILL.md index 05e6586..914aa37 100644 --- a/skills/engineering/crush-code/SKILL.md +++ b/skills/engineering/crush-code/SKILL.md @@ -21,7 +21,7 @@ Before starting, detect how issues are tracked in this repo. Check in order: 2. **GitHub remote** — `git remote -v` contains `github.com` → use `gh issue` CLI. 3. **GitLab remote** — `git remote -v` contains `gitlab.com` → use `glab issue` CLI. 4. **`.scratch/`** directory exists → local markdown issues (see below). -5. **Fallback** — ask via `telegram_ask` "How are issues tracked in this repo?" then follow instructions. +5. **Fallback** — ask via `telegram_ask` (or terminal prompt if Telegram unavailable): "How are issues tracked in this repo?" then follow instructions. ### Local markdown issues (`.scratch/`) @@ -29,14 +29,23 @@ Before starting, detect how issues are tracked in this repo. Check in order: - Read: `cat .scratch//issue.md` - Close: move to `.scratch/done//` or delete +## Telegram detection + +At session start, check whether Telegram is configured by verifying the `telegram_send_message` tool is available in the current session. Set a mental flag `TELEGRAM=yes/no`. + +- **`TELEGRAM=yes`** — use `telegram_send_message` / `telegram_ask` as described below. +- **`TELEGRAM=no`** — replace every Telegram call with plain terminal output: + - `telegram_send_message` → print status line to stdout + - `telegram_ask` → print the question + options to stdout, then **pause and wait for the user to reply in the terminal** before continuing + ## Communication tools | Tool | When | |------|------| -| `telegram_send_message` | Fire-and-forget status (PR opened, CI red, blocked) | -| `telegram_ask` | Block and wait for human input (ambiguous requirement, risky delete, credentials needed) | +| `telegram_send_message` (or stdout) | Fire-and-forget status (PR opened, CI red, blocked) | +| `telegram_ask` (or stdin prompt) | Block and wait for human input (ambiguous requirement, risky delete, credentials needed) | -Telegram only when truly stuck. Prefer autonomous decisions. +Notify only when truly stuck. Prefer autonomous decisions. ## Issue loop @@ -105,7 +114,7 @@ glab mr merge --squash # GitLab Only move to step 1 once all open PRs/MRs are resolved or genuinely blocked. -If blocked: `telegram_ask` "PR blocked: . Options?" with buttons ["Fix it", "Close PR", "Skip for now"] +If blocked: ask (via `telegram_ask` or terminal prompt): "PR blocked: . Options? [Fix it / Close PR / Skip for now]" ### 1. Pick issue @@ -128,7 +137,7 @@ ls .scratch/ | head -1 # pick first open issue dir cat .scratch//issue.md ``` -If none found: `telegram_send_message` "no ready-for-agent issues. triage first?" then stop. +If none found: notify (via `telegram_send_message` or stdout): "no ready-for-agent issues. triage first?" then stop. ### 2. Branch @@ -174,7 +183,7 @@ gh pr merge --auto --squash glab mr create --title "" --description "Closes #" --squash-before-merge ``` -Send: `telegram_send_message` "PR opened for issue # — auto-merge on." +Notify: "PR opened for issue # — auto-merge on." (via `telegram_send_message` or stdout) ### 5. CI watch @@ -183,7 +192,7 @@ Send: `telegram_send_message` "PR opened for issue # — auto-merge on." On failure: - Read logs and fix -- If fix needs human decision: `telegram_ask` with buttons ["Fix it", "Skip", "Close issue"] +- If fix needs human decision: ask (via `telegram_ask` or terminal prompt): "CI failed: . [Fix it / Skip / Close issue]" ### 6. Conflict check @@ -205,7 +214,7 @@ git checkout main && git pull - GitLab: `glab issue close ` - Local: `mv .scratch/ .scratch/done/` -Send: `telegram_send_message` "issue # merged. moving to next." +Notify: "issue # merged. moving to next." (via `telegram_send_message` or stdout) Loop back to step 0. From 226b7d51cecb5d01b8afd7cfc2ea20a2de2be7cc Mon Sep 17 00:00:00 2001 From: Eric Dahl Date: Fri, 15 May 2026 01:46:04 -0400 Subject: [PATCH 3/3] Add smallest-change / deliberate-change discipline to engineering skills Across tdd, diagnose, crush-code, and improve-codebase-architecture: - Only make the smallest change needed - Every change must be traceable to a specific requirement - Do not test or guard against impossible/unreachable states Assisted-by: Crush:claude-sonnet-4-5 --- skills/engineering/crush-code/SKILL.md | 5 +++++ skills/engineering/diagnose/SKILL.md | 2 ++ skills/engineering/improve-codebase-architecture/SKILL.md | 2 ++ skills/engineering/tdd/SKILL.md | 8 ++++++++ 4 files changed, 17 insertions(+) diff --git a/skills/engineering/crush-code/SKILL.md b/skills/engineering/crush-code/SKILL.md index 914aa37..c9578c0 100644 --- a/skills/engineering/crush-code/SKILL.md +++ b/skills/engineering/crush-code/SKILL.md @@ -156,6 +156,11 @@ Slug = title lowercased, spaces→hyphens, max 40 chars. - Run the project's test suite after each phase (check `docs/agents/` or `AGENTS.md` for the correct command) - Run linters/security scanners if configured +**Code discipline (non-negotiable):** +- Make the **smallest change** that satisfies the current requirement — no speculative logic, no extra abstractions +- Every change must be **deliberate**: traceable to a specific test or explicit requirement +- Do **not** test or guard against impossible situations — states the type system or existing invariants already prevent + ### 4. Push + PR ```bash diff --git a/skills/engineering/diagnose/SKILL.md b/skills/engineering/diagnose/SKILL.md index eb43bdd..b14b709 100644 --- a/skills/engineering/diagnose/SKILL.md +++ b/skills/engineering/diagnose/SKILL.md @@ -91,6 +91,8 @@ Tool preference: ## Phase 5 — Fix + regression test +**Fix discipline:** make the smallest change that eliminates the bug. Do not refactor surrounding code, add defensive guards for impossible states, or broaden the fix beyond what the repro requires. One cause → one targeted change. + Write the regression test **before the fix** — but only if there is a **correct seam** for it. A correct seam is one where the test exercises the **real bug pattern** as it occurs at the call site. If the only available seam is too shallow (single-caller test when the bug needs multiple callers, unit test that can't replicate the chain that triggered the bug), a regression test there gives false confidence. diff --git a/skills/engineering/improve-codebase-architecture/SKILL.md b/skills/engineering/improve-codebase-architecture/SKILL.md index 63f0ae3..a338cda 100644 --- a/skills/engineering/improve-codebase-architecture/SKILL.md +++ b/skills/engineering/improve-codebase-architecture/SKILL.md @@ -26,6 +26,8 @@ Key principles (see [LANGUAGE.md](LANGUAGE.md) for the full list): - **Deletion test**: imagine deleting the module. If complexity vanishes, it was a pass-through. If complexity reappears across N callers, it was earning its keep. - **The interface is the test surface.** - **One adapter = hypothetical seam. Two adapters = real seam.** +- **Smallest change first.** Propose the minimal refactor that improves depth or locality — not a full rewrite. Each suggestion should be independently shippable. +- **Deliberate changes only.** Every proposed change must be motivated by observed friction, not theoretical improvement. If you cannot point to the specific pain, skip it. This skill is _informed_ by the project's domain model. The domain language gives names to good seams; ADRs record decisions the skill should not re-litigate. diff --git a/skills/engineering/tdd/SKILL.md b/skills/engineering/tdd/SKILL.md index 2d5923b..27ea0fd 100644 --- a/skills/engineering/tdd/SKILL.md +++ b/skills/engineering/tdd/SKILL.md @@ -107,4 +107,12 @@ After all tests pass, look for [refactor candidates](refactoring.md): [ ] Test would survive internal refactor [ ] Code is minimal for this test [ ] No speculative features added +[ ] No tests for impossible or unreachable states +[ ] Change is the smallest that satisfies the current requirement ``` + +## Code discipline + +- **Smallest change first.** Write only enough code to pass the current test. Do not anticipate future tests or add logic "just in case." +- **Deliberate changes only.** Every line added must be traceable to a specific failing test. If you cannot point to the test that requires a line, delete it. +- **Do not test impossible situations.** Avoid tests for states the system's own invariants or types already prevent. Testing them adds noise, not safety.