From 4521228e7360e022d8f8b690d358dd4f864b1c9b Mon Sep 17 00:00:00 2001 From: Piyush Makhija Date: Sat, 8 Aug 2026 07:01:02 +0530 Subject: [PATCH] docs: correct the README's four load-bearing false claims Every defect below was verified by running something, not by reading. THE INSTALL INSTRUCTION DOES NOT WORK. `pip install claude-workflow-engine` was the first command in Quick Start and was marked "(recommended)". The package is not on PyPI: https://pypi.org/pypi/claude-workflow-engine/json returns 404. The badge above it linked to the same 404. Both are gone; source install is now the only route, stated as such. EVERY RUN COMMAND WAS BROKEN. v2.0.0 made `--invoked-by=` mandatory, and none of the three documented commands carried it. Running the first one as printed produces four `[REFUSED]` lines and exits 0 having done nothing -- confirmed by executing it. The commands now carry the flag, and the plugin route is documented first, because it is the supported one and the README did not mention the plugin at ALL: zero occurrences of the word in 845 lines, for the mechanism the refusal message itself calls "the supported route". THE HOOK SYSTEM SECTION DESCRIBED A DELETED ARCHITECTURE. 68 lines: a nine-row registration table, per-policy breakdowns, four findings. v2.0.0 deleted `PreToolUse`, `PostToolUse` and `UserPromptSubmit`; the section listed all three as registered, and listed `Notification` as NOT registered when it is one of the two that survive. Four of nine rows inverted. Being well-researched made it worse than a vague section would have been -- it reads as authoritative. Replaced rather than patched, with what is actually true: which hooks remain, what replaced each deleted one, that `hooks/` still holds the unwired code, that the plugin ships zero hooks by ADR-010 with a CI job enforcing it, and the consequence stated plainly -- nothing is enforced in a session where no command is invoked. STEP NUMBERS PREDATED THE RENAME. References to Steps 10, 11, 12 and 13, which have not existed since the Level/Step rename collapsed old 8-14 into 2-8. Mapped 10->4, 11->5, 12->6, 13->7 against CLAUDE.md's canonical list. "8 active steps" appeared twice while the same file said "9 active steps" and "Steps 0-8" -- 0 through 8 is nine. The template fast-path was described as bypassing Step 0; it is Step 0 that detects the template and skips Step 1. The version badge read 1.20.3. sync-version.py rewrites the `**Version:**` footer but not the badge, so it had been drifting since 1.20.3 while the footer tracked every release. Now 2.1.0. Verified: the two documented `--invoked-by` values pass the real authorize() gate and the flagless form still refuses; 57 documentation tests; all six CI gates; CRLF count identical before and after (845 both), so the 81/81 diff is content and not a line-ending flip. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 164 +++++++++++++++++++++++++++--------------------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/README.md b/README.md index 93827cce..981c5514 100644 --- a/README.md +++ b/README.md @@ -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/) @@ -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 | — | — | — | @@ -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 @@ -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 @@ -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. --- @@ -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 | @@ -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 ``` --- @@ -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. @@ -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 @@ -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) | @@ -842,4 +842,4 @@ Key rules: --- -**Version:** 2.1.0 | **Last Updated:** 2026-08-07 +**Version:** 2.1.0 | **Last Updated:** 2026-08-08