aboutsummaryrefslogtreecommitdiff
path: root/.claude
diff options
context:
space:
mode:
Diffstat (limited to '.claude')
-rw-r--r--.claude/commands/lint-org.md4
-rw-r--r--.claude/commands/refactor.md39
-rw-r--r--.claude/commands/start-work.md21
-rw-r--r--.claude/settings.json1
4 files changed, 56 insertions, 9 deletions
diff --git a/.claude/commands/lint-org.md b/.claude/commands/lint-org.md
index 64ec967..d9719fa 100644
--- a/.claude/commands/lint-org.md
+++ b/.claude/commands/lint-org.md
@@ -60,10 +60,10 @@ Out of scope (refuse, don't try to lint):
3. Invoke the script:
```bash
- emacs --batch -q -l .ai/scripts/lint-org.el FILE
+ emacs --batch -q -l .ai/scripts/lint-org.el --fix FILE
```
- The script applies every mechanical fix, then emits structured stdout. First line is a summary; each subsequent line is a plist describing one issue:
+ `--fix` is required for the writes — the script's default invocation is report-only (a linter reports, it doesn't write). With the flag, the script applies every mechanical fix, then emits structured stdout. First line is a summary; each subsequent line is a plist describing one issue:
```
;; lint-org: file=todo.org mechanical=4 judgment=11
diff --git a/.claude/commands/refactor.md b/.claude/commands/refactor.md
index 08cbdab..97ce366 100644
--- a/.claude/commands/refactor.md
+++ b/.claude/commands/refactor.md
@@ -1,5 +1,5 @@
---
-description: Scan code for refactoring opportunities or perform a targeted refactor. Six modes — `full` (default; complexity + duplication + dead-code scans), `quick` (high-severity findings only), `complexity` (length / nesting / cyclomatic / parameter count / boolean ops with severity bands and techniques like guard clauses, extract method/predicate, parameter object, decompose conditional), `duplication` (clones / logic / constants / patterns / error-handling with extract-function / parameterize / template-method strategies), `dead-code` (imports / exports / branches / feature flags / deps with high/medium/low confidence labels), `rename old new` (codebase-wide symbol rename with reference search, preview gate, atomic commit, post-apply verification). Findings render as `[SEVERITY] Category — File / Metric / Issue / Suggestion` blocks plus a summary table and quick-wins. Structure-only — no feature work mixed in, no auto-apply without confirmation, characterization tests first when coverage is missing, small focused commits. Use for cleanup or wide renames. Do NOT use for behavior changes (`fix:` or `feat:`, not refactor), green-field design (use `/arch-design`), or single-symbol single-file renames (just edit). Companion to `/add-tests` for the characterization-test prereq.
+description: Scan code for refactoring opportunities or perform a targeted refactor. Seven modes — `full` (default; complexity + duplication + dead-code + simplification scans), `quick` (high-severity findings only), `complexity` (length / nesting / cyclomatic / parameter count / boolean ops with severity bands and techniques like guard clauses, extract method/predicate, parameter object, decompose conditional), `duplication` (clones / logic / constants / patterns / error-handling with extract-function / parameterize / template-method strategies), `dead-code` (imports / exports / branches / feature flags / deps with high/medium/low confidence labels), `simplification` (over-defensive guards / needless indirection / convoluted logic / redundant state / legibility rewrites — behavior-preserving clarity and size reduction, distinct from the metric-driven complexity scan), `rename old new` (codebase-wide symbol rename with reference search, preview gate, atomic commit, post-apply verification). Findings render as `[SEVERITY] Category — File / Metric / Issue / Suggestion` blocks plus a summary table and quick-wins. Structure-only — no feature work mixed in, no auto-apply without confirmation, characterization tests first when coverage is missing, small focused commits. Use for cleanup or wide renames. Do NOT use for behavior changes (`fix:` or `feat:`, not refactor), green-field design (use `/arch-design`), or single-symbol single-file renames (just edit). Companion to `/add-tests` for the characterization-test prereq.
argument-hint: "[scope: full|quick|complexity|duplication|dead-code|rename old new]"
---
@@ -9,11 +9,12 @@ Parse `$ARGUMENTS` to determine the operation:
| Argument | Description |
|----------|-------------|
-| `full` (default) | Run all scans: complexity + duplication + dead code |
+| `full` (default) | Run all scans: complexity + duplication + dead code + simplification |
| `quick` | High-severity issues only (critical/high across all scans) |
| `complexity` | Analyze code complexity: nesting, length, parameters, boolean expressions |
| `duplication` | Detect duplicated logic, clone blocks, repeated patterns |
| `dead-code` | Find unused imports, exports, unreachable code, dead feature flags |
+| `simplification` | Find over-complicated code: redundant guards, needless indirection, convoluted logic, redundant state, legibility rewrites |
| `rename old new` | Codebase-wide symbol rename with verification |
If a file or directory path is included in the arguments, scope the scan to that path. Otherwise scan the project source directories (exclude vendored code, node_modules, build output, test fixtures).
@@ -182,6 +183,40 @@ Group findings by category with confidence levels:
---
+## Mode: Simplification
+
+Scan for code that's more complicated than it needs to be — a plainer, smaller, more direct expression of the same behavior. Behavior-preserving like every other mode; this targets clarity and size, not metrics (complexity mode) or repetition (duplication mode).
+
+### What to Check
+
+- **Over-defensive / redundant guards** — existence checks and fallbacks for conditions that can't occur given the actual call sites.
+- **Needless indirection / unearned abstraction** — single-use closures, helpers, or wrappers; a single-use local that could inline (or a repeated expression that should be a local); a parameter always passed the same value; an option or branch never exercised.
+- **Convoluted logic expressible more directly** — a manual loop that's a map/filter/comprehension; a verbose if-chain that's a lookup table; an if/else assigning a value that's a ternary; boolean expressions that simplify; redundant intermediate computations.
+- **Redundant state** — a cache rebuilt every call anyway; two variables tracking the same thing; write-only "dead storage" (assigned, never read); dead flags.
+- **Legibility rewrites** — named locals to expose a decision matrix obscured by indexing or chaining. No structural change, large readability win.
+
+For identical-twin branches and plain deletion of unreachable code, see Mode: Dead Code; for repeated literals → named constant, see Mode: Duplication. Those modes already own that detection.
+
+### Detection Heuristics
+
+- Search for guard clauses and fallbacks (null checks, default branches), then check every call site to see whether the guarded condition can actually occur
+- Search for helpers, closures, and locals referenced exactly once
+- Search for manual index/accumulator loops that build or filter a collection
+- Search for variables assigned but never read, and for values recomputed on every call that never change
+
+### Rules
+
+- Behavior-preserving only.
+- Verify against **all** call sites before deleting a guard, dropping an option, or removing "never read" state — "can't occur" and "never read" are only true relative to every caller. Never remove a guard or fallback that's genuinely reachable.
+- Run the test suite after each change.
+- Present findings before applying.
+
+### Boundary with /simplify
+
+`/refactor simplification` sweeps the whole tree (or a scoped path), presents findings, and applies on confirmation. The built-in `/simplify` works on the current diff and applies its lenses directly. Reach for `/simplify` on a change in flight; reach for `/refactor simplification` to sweep existing code.
+
+---
+
## Mode: Rename
Perform a codebase-wide symbol rename.
diff --git a/.claude/commands/start-work.md b/.claude/commands/start-work.md
index d146622..85ed6b0 100644
--- a/.claude/commands/start-work.md
+++ b/.claude/commands/start-work.md
@@ -1,12 +1,12 @@
---
-description: Pick up a task (Linear ticket, GitHub issue, todo.org task, or a described scope) and take it through Pre-work, Claim, Justify, Approach, Implement, Verify, and Hand-off. Three user-approval gates separate the phases. Pre-work covers eligibility, a fetch-and-reconcile against the base branch, and a source-code check that the problem still exists in the tree. The Justify gate weighs benefits, costs, impact, urgency, effort, alternatives, and ticket quality. The Approach gate covers root cause, risk, refactor prerequisites, test strategy (unit, integration, e2e, pairwise, characterization), migration and backwards-compat, feature flags, commit decomposition, and branch name. Implementation uses TDD (red, green, edge cases); a refactor audit then walks every touched file against a language-agnostic checklist, fixing each finding here or filing it as a ticket, never dropping one. A verify phase exercises the feature end-to-end locally (Playwright against localhost for web, scripted manual test otherwise) before the final gate hands off to the Review-and-Publish flow in commits.md. Use when starting work on a specific task where both "should we" and "how exactly" are worth deliberating. Do NOT use for open-ended bug investigation without a clear target (use debug first), for architectural paradigm exploration (use arch-design), for architectural decision recording (use arch-decide), when the task is trivial and obvious (just do it), or when requirements are still being shaped (use brainstorm).
+description: Pick up a task (Linear ticket, GitHub issue, todo.org task, or a described scope) and take it through Pre-work, Claim, Justify, Approach, Implement, Verify, and Hand-off. Three user-approval gates separate the phases. Pre-work covers eligibility, a fetch-and-reconcile against the base branch, a green-baseline suite run, and a source-code check that the problem still exists in the tree. The Justify gate weighs benefits, costs, impact, urgency, effort, alternatives, and ticket quality. The Approach gate covers root cause, risk, refactor prerequisites, test strategy (unit, integration, e2e, pairwise, characterization), migration and backwards-compat, feature flags, commit decomposition, and branch name. Implementation uses TDD (red, green, edge cases); a refactor audit then walks every touched file against a language-agnostic checklist, fixing each finding here or filing it as a ticket, never dropping one. A verify phase exercises the feature end-to-end locally (Playwright against localhost for web, scripted manual test otherwise) before the final gate hands off to the Review-and-Publish flow in commits.md. Use when starting work on a specific task where both "should we" and "how exactly" are worth deliberating. Do NOT use for open-ended bug investigation without a clear target (use debug first), for architectural paradigm exploration (use arch-design), for architectural decision recording (use arch-decide), when the task is trivial and obvious (just do it), or when requirements are still being shaped (use brainstorm).
---
# /start-work: pick up a task, justify it, plan it, build it
Three review gates separate the phases. The user can redirect or kill the work at each one.
-0. **Pre-work.** Eligibility check, fetch-and-reconcile against the base branch, source-code check that the problem still exists.
+0. **Pre-work.** Eligibility check, fetch-and-reconcile against the base branch, green-baseline suite run, source-code check that the problem still exists.
1. **Claim.** Mark in-progress, assign, label, verify project.
2. **Justify (gate 1).** Benefits, costs, impact, urgency, effort, alternatives, ticket quality. Stop for approval.
3. **Approach (gate 2).** Root cause, risk, tests, migration, flag, commit decomposition. Stop for approval.
@@ -53,7 +53,7 @@ If the reference is ambiguous, ask the user to clarify before proceeding.
## Phase 0: pre-work
-Three checks before claiming the task. All run before any state change — no assignee added, no label written, no status moved. If any of them disqualify the task, the rollback is free.
+Four checks before claiming the task. All run before any state change — no assignee added, no label written, no status moved. If any of them disqualify the task, the rollback is free.
### 0.1 Eligibility
@@ -84,7 +84,18 @@ The branch this task will be cut from must reflect the remote — otherwise the
4. If the current branch is *not* the base branch (e.g. left over from a prior task), surface and ask whether to switch before continuing. Don't auto-switch — the user may want to finish or stash WIP first.
-### 0.3 Existence check (validate the problem is real)
+### 0.3 Green baseline (confirm the tree starts known-good)
+
+Run the project's test suite now, against the reconciled base, so the baseline you build on is actually green (see the Green Baseline section in `verification.md`). This runs after 0.2 — baselining a stale tree is pointless.
+
+- **Green** — proceed to 0.4.
+- **Red** — fix the failure first, or, when it's out of scope or needs a decision, file a tracked task with the diagnosis and carry its name forward as the only tolerated failure for this work. Surface the baseline result either way so "we started from green" is on the record.
+- **No suite** — nothing to baseline. Note it and proceed (your personal/doc projects hit this).
+- **Suite can't run** (no network, missing dep, sandbox limit) — that's the "When You Cannot Verify" case in `verification.md`, not a blocker. Record what you couldn't run, name the risk, and proceed.
+
+This baseline is the green starting point; the intentional red test you write in Phase 4 (TDD) is expected and distinct from a baseline failure.
+
+### 0.4 Existence check (validate the problem is real)
The ticket may describe a problem the code no longer has — fixed independently of the ticket, made obsolete by another change, or never present in the first place. Read the source to confirm the problem exists in the tree as the ticket describes, before justifying or planning the fix.
@@ -337,7 +348,7 @@ Follow `commits.md` exactly. Summary of the flow:
## Anti-patterns
- **Skipping the pre-flight reconcile.** Cutting a new branch from a stale base means the whole task happens on top of yesterday's main. Conflicts surface at PR time instead of at the start; rebases later are noisier than a fetch up front.
-- **Taking the ticket's word that the problem still exists.** Tickets age. Read the source. A `git log --grep` for a fix commit is a hint, not a check — fixes ship under all kinds of commit-message wording, and the buggy behavior may be gone for reasons that never landed in a commit titled "fix." Five minutes of source-read at Phase 0.3 saves an entire Justify-and-Approach cycle on a phantom problem.
+- **Taking the ticket's word that the problem still exists.** Tickets age. Read the source. A `git log --grep` for a fix commit is a hint, not a check — fixes ship under all kinds of commit-message wording, and the buggy behavior may be gone for reasons that never landed in a commit titled "fix." Five minutes of source-read at Phase 0.4 saves an entire Justify-and-Approach cycle on a phantom problem.
- **Skipping the Justify gate.** "This is obviously worth doing" is exactly what the gate exists to verify. If the answer really is obvious, the gate takes thirty seconds.
- **Skipping the Approach gate.** Implementation without a plan is how scope creep happens. It is also how the user loses the chance to redirect.
- **Marking a personal todo task DOING before Phase 2 approval.** Personal claims carry no teammate signal, so they wait until the gate clears — a killed task then needs no rollback. Team-tracker claims (Linear, GitHub) are the exception: they happen in Phase 1 to flag intent, but only after the prior state is recorded so the gate can restore it cleanly.
diff --git a/.claude/settings.json b/.claude/settings.json
index 33ed7e6..6bd53fd 100644
--- a/.claude/settings.json
+++ b/.claude/settings.json
@@ -7,6 +7,7 @@
"permissions": {
"defaultMode": "bypassPermissions"
},
+ "model": "fable",
"hooks": {
"PreToolUse": [
{