Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 82 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@

> Automate your entire software development lifecycle — from task to merged PR — using Claude AI.

[![Version](https://img.shields.io/badge/Version-1.20.3-blue)](CHANGELOG.md)
[![Version](https://img.shields.io/badge/Version-2.1.0-blue)](CHANGELOG.md)
[![Python](https://img.shields.io/badge/Python-3.10%2B-green)](https://python.org)
[![PyPI](https://img.shields.io/badge/PyPI-claude--workflow--engine-orange)](https://pypi.org/project/claude-workflow-engine/)
[![CI](https://github.com/techdeveloper-org/claude-workflow-engine/actions/workflows/ci.yml/badge.svg)](https://github.com/techdeveloper-org/claude-workflow-engine/actions/workflows/ci.yml)
[![License](https://img.shields.io/badge/License-MIT-yellow)](LICENSE)
[![Tests](https://img.shields.io/badge/Tests-102%20files%20·%205%20integration-brightgreen)](tests/)
Expand All @@ -23,13 +22,13 @@ Most AI coding tools generate code and stop there. This engine does what a full
| **Core Generation** | | | | |
| Code generation | Yes | Yes | Yes | Yes |
| Unit test generation (Python/Java/TS/Kotlin) | Yes | — | Partial | — |
| Documentation update (Step 13) | Yes | — | — | — |
| Documentation update (Step 7) | Yes | — | — | — |
| **Planning & Analysis** | | | | |
| Task analysis + complexity scoring [1-25] | Yes | — | — | Partial |
| Call graph impact analysis (pre-change) | Yes | — | — | — |
| Breaking change detection (graph diff) | Yes | — | — | — |
| Multi-language call graph (Python/Java/TS/Kotlin) | Yes | — | — | — |
| Template fast-path (bypass Step 0, ~0s planning) | Yes | — | — | — |
| Template fast-path (skips Step 1 planning, ~0s) | Yes | — | — | — |
| **GitHub / Jira SDLC** | | | | |
| GitHub issue creation | Yes | — | — | — |
| Dual issue tracking (GitHub + Jira) | Yes | — | — | — |
Expand Down Expand Up @@ -71,11 +70,9 @@ Most AI coding tools generate code and stop there. This engine does what a full

### Install

```bash
# From PyPI (recommended)
pip install claude-workflow-engine
Not published to PyPI. Install from source:

# From source
```bash
git clone https://github.com/techdeveloper-org/claude-workflow-engine
cd claude-workflow-engine
pip install -r requirements.txt
Expand All @@ -85,19 +82,45 @@ cp .env.example .env

### Run

Since v2.0.0 the pipeline does **not** start on its own. It runs only when a caller
explicitly declares which of six commands it stands in for, and it refuses otherwise.
There is no environment variable that disables this and no opt-out flag — the reasoning
is in `scripts/pipeline_invocation.py`.

**The supported route is the plugin.** Its commands declare the invocation for you:

```
/claude-workflow-engine:plan Steps 0-1 — analyse and decompose, change nothing
/claude-workflow-engine:implement Steps 2-4 — issue, branch, code
/claude-workflow-engine:review Steps 5-6 — PR, automated review, close the issue
/claude-workflow-engine:document Step 7 — docs and diagrams
/claude-workflow-engine:release Step 8 — telemetry and summary
/claude-workflow-engine:run-pipeline Steps 0-8 — all of it, in order
```

MCP-backed capabilities stay unreachable until you run
`/claude-workflow-engine:register-mcp` once.

**Direct CLI** — for a container entry point or a manual run, declare the command
yourself with `--invoked-by=`:

```bash
# Hook Mode (default) — runs analysis + creates GitHub issue + branch
python scripts/3-level-flow.py --message "Fix the login timeout bug"
# Hook Mode (default) — analysis, GitHub issue, branch
python scripts/3-level-flow.py --invoked-by=implement --message "Fix the login timeout bug"

# Full Mode — runs all 8 active steps end-to-end (implements + PR + closes issue)
CLAUDE_HOOK_MODE=0 python scripts/3-level-flow.py --message "Fix the login timeout bug"
# Full Mode — all 9 active steps end-to-end (implements + PR + closes issue)
CLAUDE_HOOK_MODE=0 python scripts/3-level-flow.py --invoked-by=run-pipeline \
--message "Fix the login timeout bug"

# Template Fast-Path — skip Step 0 planning entirely
python scripts/3-level-flow.py \
# Template Fast-Path — Step 0 detects the template and skips Step 1 planning
python scripts/3-level-flow.py --invoked-by=run-pipeline \
--message "Add document Q&A feature" \
--orchestration-template=orchestration_template.example.json
```

Omitting `--invoked-by=` prints `[REFUSED]` and exits 0 without running anything. A
misspelled command name exits 2, so a typo costs an error rather than a silent no-op.

### What happens when you run it

```mermaid
Expand Down Expand Up @@ -318,78 +341,55 @@ Pre-fill a JSON orchestration template once, and every subsequent run skips Step
python scripts/3-level-flow.py \
--message "add document Q&A feature" \
--orchestration-template=orchestration_template.example.json
# Planning time: ~0s (template loaded, Step 0 bypassed)
# Planning time: ~0s (Step 0 detects the template and skips Step 1)
```

See `orchestration_template.example.json` for the full field reference.

---

## Hook System

> Interactive version of this section + the pipeline diagram above: [Pipeline & Hook Architecture](https://claude.ai/code/artifact/6045b61f-00e5-411d-a2a6-d62b267ba29c)
## Hooks — what happened to them

Claude Code exposes 9 hook events. This project registers **4 of them** in `~/.claude/settings.json`. The table below was produced by tracing every registered entry point down to which internal policy modules actually execute, not by reading the prose docs — `docs/policies/hook-system-policy.md` has drifted from the real wiring (see Findings below).
**v2.0.0 deleted the enforcement hooks.** `PreToolUse`, `PostToolUse` and
`UserPromptSubmit` are no longer registered in the user-scope `settings.json`; the
`hooks` object holds exactly `Stop` and `Notification`, and those two were proved
unchanged by comparing canonical-JSON digests rather than merely checking they were
still present.

### Registration Status
If you are looking for the previous version of this section — a nine-row registration
table, a per-policy breakdown and four findings about dead abstractions — it described
that deleted architecture and has been removed rather than corrected. `git log` has it.

| Event | Registered | Entry Point | Wired Policies |
|---|:---:|---|---|
| `UserPromptSubmit` | Yes | `scripts/3-level-flow.py` | Runs the full 3-level pipeline; also the only entry point driving `src/mcp/session_hooks.py` |
| `PreToolUse` | Yes | `hooks/pre-tool-enforcer.py` → `pre_tool_enforcer/core.py` | 12 / 13 loaded policies wired (1 dead — see Findings) |
| `PostToolUse` | Yes | `hooks/post-tool-tracker.py` → `post_tool_tracker/core.py` | 6 / 6 wired |
| `Stop` | Yes | `hooks/stop-notifier.py` → `stop_notifier/core.py` | `voice.py` + `post_impl.py` fully wired |
| `SessionStart` | **No** | — | — |
| `SessionEnd` | **No** | — | — |
| `SubagentStop` | **No** | — | — |
| `PreCompact` | **No** | — | — |
| `Notification` | **No** | — | — |
### What replaced them

```mermaid
flowchart TD
subgraph REG["Registered — settings.json"]
direction TB
UPS["UserPromptSubmit\n→ scripts/3-level-flow.py"]
PRE["PreToolUse\n→ hooks/pre-tool-enforcer.py"]
POST["PostToolUse\n→ hooks/post-tool-tracker.py"]
STOP["Stop\n→ hooks/stop-notifier.py"]
end

UPS --> PIPE["Full 3-level LangGraph pipeline\n+ session_hooks.py bridge"]
PRE --> PREP["pre_tool_enforcer/core.py\n12/13 policies wired · 1 dead\nPolicyRegistry loaded, never used"]
POST --> POSTP["post_tool_tracker/core.py\n6/6 policies wired"]
STOP --> STOPP["stop_notifier/core.py\nvoice.py + post_impl.py wired\n+ session save/archive/prune\n(SessionEnd-shaped work)"]

subgraph MISS["Never registered — no entry, no orphaned code"]
direction LR
SS["SessionStart"] ~~~ SE["SessionEnd"] ~~~ SA["SubagentStop"] ~~~ PC["PreCompact"] ~~~ NT["Notification"]
end

style REG fill:#dcfce7,stroke:#16a34a
style MISS fill:#fee2e2,stroke:#dc2626
style PREP fill:#fef3c7,stroke:#d97706
```

### PreToolUse — full policy breakdown
| Was | Is now |
|---|---|
| `UserPromptSubmit` started the pipeline on every prompt | Nothing starts it implicitly. A caller declares one of six commands (see [Run](#run)) or it refuses |
| `PreToolUse` blocked unsafe pushes | An MCP-side push gate, plus ADR-020's three-layer control: prevention on the path the plugin owns, detection on the manual-edit path that has no interception point |
| `PostToolUse` tracked progress | MCP tools, called explicitly |

`pre_tool_enforcer/core.py` loads all 13 files under `hooks/pre_tool_enforcer/policies/`:
The ordering mattered: the replacement push gate was registered and proved reachable by
completing a real `tools/call` **before** `PreToolUse` was deleted. Removing the hook
while its replacement existed only in the repository would have left a machine with no
push gate at all.

| Policy | Status |
|---|---|
| `checkpoint.py`, `task_breakdown.py`, `skill_selection.py`, `context_read.py`, `level1_sync.py`, `python_unicode.py`, `bash_commands.py`, `grep_opt.py`, `read_opt.py`, `agent_persona.py` | Wired — blocking (`_BLOCKING_POLICIES`, core.py:470-481) |
| `skill_context.py`, `failure_kb.py` | Wired — non-blocking hints (core.py:543-549, 562-568) |
| `write_edit.py` | **Loaded, never called** — see Findings #2 |
### The code is still here, and is not wired

### PostToolUse — full policy breakdown
`hooks/` still contains `pre_tool_enforcer/`, `post_tool_tracker/` and `stop_notifier/`.
None of it is registered. Treat it as reference material, not as behaviour you are
getting — nothing in the plugin or in `scripts/3-level-flow.py` reaches it.

All 6 files under `hooks/post_tool_tracker/policies/` are loaded and invoked: `uncommitted_push.py`, `post_merge_update.py`, `task_tracking.py`, `phase_complexity.py`, `task_breakdown_clear.py`, `skill_selection_clear.py`.
### The plugin ships zero hooks, deliberately

### Findings
Plugin hooks merge into a flat, session-wide pipeline with no per-plugin label, so a
user cannot disable one plugin's hook without disabling everyone's. Shipping one would
give you less control than you have now. This is ADR-010, and a CI job
(`Plugin conformance (ADR-010 / ADR-019 CRITICAL)`) fails the build if a `hooks/`
directory or a `hooks.json` ever appears under the plugin root.

1. **`PolicyRegistry` is a dead abstraction.** `hooks/pre_tool_enforcer/registry.py` defines a `PolicyRegistry` class meant to register and run policies generically. `core.py:182` imports it, but nothing in the repo ever instantiates it — `core.py` hand-builds its own `_BLOCKING_POLICIES` list instead. Either wire real policies through it or delete it.
2. **`write_edit.py` never executes.** Loaded and wrapped at `core.py:216` / `367-369`, but no call site in `main()` reaches it — and its own body is a stub that always returns `False`. A second, non-stub-looking copy also sits unused directly in the `pre-tool-enforcer.py` shim (lines 204-222), likewise never called. Two dead implementations of the same check.
3. **No dedicated `SessionEnd` hook.** `stop_notifier/core.py` runs session archiving, pruning, and preference tracking on every `Stop` event — work a real `SessionEnd` hook would own instead. Since `Stop` fires on every response (not just session close), this logic runs far more often than necessary.
4. **`docs/policies/hook-system-policy.md` no longer matches the implementation.** It describes a `script-chain-executor.py` dispatcher and a `hook-downloader.py` sync-from-repo model — neither file exists in the repo anymore. Its example `settings.json` snippets point at `~/.claude/scripts/...py`, while the real registration points directly into this repo's `hooks/...py`. Its policy counts ("8" PreToolUse checks, "6" PostToolUse functions) use a different taxonomy than the actual files and only coincidentally match on PostToolUse.
The consequence is worth stating plainly: **nothing is enforced in a session where you
do not invoke a command.** That is the intended trade-off of the hook-free design, not
a regression.

---

Expand Down Expand Up @@ -538,7 +538,7 @@ All options are set via environment variables. Copy `.env.example` and fill in:
| Variable | Default | Description |
|---|---|---|
| `ENABLE_JIRA` | `0` | Dual GitHub+Jira issue tracking |
| `ENABLE_JENKINS` | `0` | Jenkins build validation in Step 11 |
| `ENABLE_JENKINS` | `0` | Jenkins build validation in Step 5 |
| `ENABLE_SONARQUBE` | `0` | SonarQube scan after implementation |
| `ENABLE_FIGMA` | `0` | Figma design-to-code pipeline |
| `ENABLE_CI` | `false` | GitHub Actions CI pipeline |
Expand Down Expand Up @@ -570,18 +570,18 @@ All integrations follow the same create → update → close lifecycle pattern w
```
Step 8: CREATE Jira issue created, cross-linked to GitHub Issue
Step 9: BRANCH Branch named from Jira key (feature/proj-123)
Step 10: UPDATE Transition → "In Progress", add start comment
Step 11: LINK PR linked in Jira, transition → "In Review"
Step 12: CLOSE Transition → "Done", add implementation summary
Step 4: UPDATE Transition → "In Progress", add start comment
Step 5: LINK PR linked in Jira, transition → "In Review"
Step 6: CLOSE Transition → "Done", add implementation summary
```

### Figma (`ENABLE_FIGMA=1`)

```
Step 0: EXTRACT Components + design tokens extracted into orchestration prompt
Step 10: COMMENT "Implementation started" with component list
Step 11: REVIEW Design fidelity checklist in code review
Step 12: COMMENT "Implementation complete" with PR link
Step 1: EXTRACT Components + design tokens extracted into orchestration prompt
Step 4: COMMENT "Implementation started" with component list
Step 5: REVIEW Design fidelity checklist in code review
Step 6: COMMENT "Implementation complete" with PR link
```

---
Expand Down Expand Up @@ -674,7 +674,7 @@ Numbers from the project's internal version history. All measurements taken on a
| v1.13.0 | 9 | ~2 (subprocess) | ~30s | Removed Steps 1, 3, 4, 5, 6, 7 |
| v1.14.0 | 8 | 2 (subprocess) | ~15s | Step 0 = template fill + orchestrator (claude CLI) |
| v1.16.0 | 8 | 2 (subprocess) | ~15s | Level 2 purged — standards read from policies/ directly |
| **current** | **8** | **2** | **~15s** | Template fast-path: **~0s** (Step 0 bypassed entirely) |
| **current** | **9** | **2** | **~15s** | Template fast-path: **~0s** (Step 1 skipped entirely) |

**Planning overhead reduced by 80%** (75s → 15s) across 4 versions without any loss of output quality.

Expand All @@ -687,7 +687,7 @@ Numbers from the project's internal version history. All measurements taken on a
| AST navigation | Skip irrelevant functions/classes in large files | 40-60% |
| Smart read | Read only the slice the agent needs (not whole file) | 20-40% |
| Context dedup | Deduplicate repeated state / schema definitions | 10-20% |
| **Combined** | Applied across all 8 active steps | **60-85%** |
| **Combined** | Applied across all 9 active steps | **60-85%** |

### Call Graph Intelligence

Expand All @@ -696,7 +696,7 @@ The AST-based call graph (578 classes, 3,985 methods across Python, Java, TypeSc
| Capability | Without Call Graph | With Call Graph |
|------------|:-----------------:|:---------------:|
| Impact scope before change | Manual review | Automatic: `hot_nodes`, `danger_zones`, `affected_methods` |
| Breaking change detection | File diff only | Method-level graph diff (before/after Step 10) |
| Breaking change detection | File diff only | Method-level graph diff (before/after Step 4) |
| Complexity scoring | Heuristic (1-10) | `combined_complexity_score` [1-25] = heuristic × 0.3 + graph × 0.7 |
| Multi-language support | Python only | Python (AST) + Java, TypeScript, Kotlin (regex) |

Expand Down Expand Up @@ -842,4 +842,4 @@ Key rules:

---

**Version:** 2.1.0 | **Last Updated:** 2026-08-07
**Version:** 2.1.0 | **Last Updated:** 2026-08-08
Loading