Skip to content

Commit 0a8a970

Browse files
docs(#323): label PreToolUse/PostToolUse as unregistered since v2.0.0
ADR-006 removed the UserPromptSubmit/PreToolUse/PostToolUse registrations in v2.0.0 (executed 2026-08-04, commit 2e371f6) and deliberately kept the source files. The code side is consistent with that -- ~/.claude/settings.json registers Stop only, and scripts/settings-config.json now lists Stop only. The docs were not. CLAUDE.md's directory layout called hooks/ "Claude Code hook scripts (PreToolUse, PostToolUse, Stop)" and labelled pre-tool-enforcer.py a "hook entry point"; the components table listed all three scripts as one "Tool enforcement + session maintenance" capability. POLICIES-AND-SCRIPTS-FLOW.md put a green check on PreToolUse. POLICY-CHAIN-FLOWCHART.md documented the full check sequence as the live chain, including a table of flag files "read by pre-tool-enforcer.py" that nothing reads. This already cost a downstream error, which is why it is worth an issue rather than a quiet cleanup: an APPROVED harness control policy in youtube-monetization-tool routed its merge-gate remediation to "a PreToolUse deny-pattern in hooks/pre-tool-enforcer.py" (that repo's GH #211). It named a real file, in a real repo, documented as a real hook, and would have produced a merge gate that looked closed and was open. The remediation for "a control that reads as enforcement and enforces nothing" was itself an instance of it. Labelled rather than deleted. The flowchart documents real mechanism and is the right starting point if the decision is ever revisited; deleting it would trade one wrong impression for a missing one. Added a blockquote status notice at the top of that file and at Section 4, since a reader arriving by search lands mid-document. New CLAUDE.md section "Hook status -- read before routing any enforcement need to a hook" records the verification, the downstream incident, and the fact that the capability does exist and is not a hook: Claude Code's native permissions.deny in settings.json is a settings rule, so using it reinstates nothing ADR-006 removed. Docs only -- no code, no registrations, no settings touched. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XL4ogDiGNFK7AyuoaEcey4
1 parent 7ab343c commit 0a8a970

3 files changed

Lines changed: 64 additions & 17 deletions

File tree

‎CLAUDE.md‎

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,12 +130,12 @@ Level 2: SDLC Execution Core (9 active steps: Steps 0-8)
130130

131131
```
132132
/
133-
+-- hooks/ # Claude Code hook scripts (PreToolUse, PostToolUse, Stop)
134-
| +-- pre-tool-enforcer.py # PreToolUse hook entry point (shim -> pre_tool_enforcer/)
135-
| +-- post-tool-tracker.py # PostToolUse hook entry point (shim -> post_tool_tracker/)
136-
| +-- stop-notifier.py # Stop hook entry point (shim -> stop_notifier/)
137-
| +-- pre_tool_enforcer/ # PreToolUse hook package (canonical)
138-
| +-- post_tool_tracker/ # PostToolUse hook package (canonical)
133+
+-- hooks/ # Hook scripts. ONLY Stop is registered (ADR-006, v2.0.0)
134+
| +-- pre-tool-enforcer.py # UNREGISTERED since v2.0.0 -- retained, never invoked
135+
| +-- post-tool-tracker.py # UNREGISTERED since v2.0.0 -- retained, never invoked
136+
| +-- stop-notifier.py # Stop hook entry point (shim -> stop_notifier/) -- THE ONLY LIVE HOOK
137+
| +-- pre_tool_enforcer/ # UNREGISTERED since v2.0.0 -- retained, never invoked
138+
| +-- post_tool_tracker/ # UNREGISTERED since v2.0.0 -- retained, never invoked
139139
| +-- stop_notifier/ # Stop hook package (canonical)
140140
| +-- ide_paths.py # Path constants (imported by hook packages)
141141
| +-- project_session.py # Session utilities (imported by hook packages)
@@ -204,7 +204,8 @@ unversioned: if that machine is lost, so are they.
204204
| Standards (non-numbered) | ~/.claude/rules/ (the only copy; no repo docs/standards/) + langgraph_engine/standards/ (selector + library_adapter) | Standards policies (.md files, no pipeline nodes) -- always-on, loaded from disk; retired from the level count since it has never had pipeline nodes |
205205
| Level 2 | langgraph_engine/sdlc_pipeline/subgraph.py | SDLC Execution Core -- 9-step active execution (Steps 0-8) -- ACTIVE (nodes in sdlc_pipeline/nodes/) |
206206
| Pre-Analysis Node | langgraph_engine/sdlc_pipeline/subgraph.py | orchestration_pre_analysis_node: CallGraph scan at Step 0; template fast-path detection |
207-
| Hooks | hooks/pre-tool-enforcer.py, post-tool-tracker.py, stop-notifier.py | Tool enforcement + session maintenance |
207+
| Hooks (live) | hooks/stop-notifier.py | Session maintenance. **The only registered hook since v2.0.0** |
208+
| Hooks (retained, inactive) | hooks/pre-tool-enforcer.py, post-tool-tracker.py | **NOT registered.** ADR-006 removed the `PreToolUse`/`PostToolUse`/`UserPromptSubmit` registrations in v2.0.0 (commit `2e371f6`, 2026-08-04) and deliberately kept the source. These scripts never run. Do not route an enforcement need to them -- see the note under "Hook status" below |
208209
| Call Graph Builder | langgraph_engine/call_graph_builder.py | AST-based FQN call stack (compat shim -> parsers/) |
209210
| Call Graph Analyzer | langgraph_engine/call_graph_analyzer.py | Pipeline impact analysis (Steps 0/4/5) |
210211
| UML Generators | langgraph_engine/uml_generators.py | Compat shim -> diagrams/DiagramFactory |
@@ -229,6 +230,33 @@ unversioned: if that machine is lost, so are they.
229230
| Pin Requirements | scripts/pin_requirements.py | Generates requirements.pinned.txt + requirements.bounds.txt |
230231
| PromptGen Caller | langgraph_engine/sdlc_pipeline/architecture/prompt_gen_expert_caller.py | Step 1 Phase 1: assembles the orchestration prompt from the master template (no LLM call) |
231232

233+
### Hook status -- read before routing any enforcement need to a hook
234+
235+
<!-- Added 2026-09-15 | GH #323 | Cause: docs across this repo still described PreToolUse as live -->
236+
237+
**`Stop` is the only registered hook.** ADR-006 (`docs/architecture/ADR-006-hook-free-execution.md`,
238+
executed 2026-08-04, commit `2e371f6`) removed the `UserPromptSubmit`, `PreToolUse` and
239+
`PostToolUse` **registrations** in v2.0.0 while deliberately retaining the source files. Verified
240+
2026-09-15: `~/.claude/settings.json` registers `Stop` only, and `scripts/settings-config.json`
241+
now lists `Stop` only.
242+
243+
`hooks/pre-tool-enforcer.py` and `hooks/post-tool-tracker.py` **cannot fire.** Neither can anything
244+
under `hooks/pre_tool_enforcer/` or `hooks/post_tool_tracker/`.
245+
246+
This is not a theoretical warning. It has already cost a downstream error: an APPROVED harness
247+
control policy in a sibling repo routed a merge-gate fix to *"a PreToolUse deny-pattern in
248+
`hooks/pre-tool-enforcer.py`"* — a control that reads as enforcement and enforces nothing, filed as
249+
`techdeveloper-org/youtube-monetization-tool#211`. The remediation for that failure class was itself
250+
an instance of it, one level up.
251+
252+
**The pre-tool deny capability does exist, and it is not a hook.** Claude Code's native
253+
`permissions.deny` in `settings.json` refuses matching tool calls before execution. It is a settings
254+
rule, so using it reinstates nothing ADR-006 removed and does not reopen a settled decision.
255+
256+
Descriptions of the removed hooks elsewhere in `docs/architecture/` are retained as accurate
257+
*history* — `POLICY-CHAIN-FLOWCHART.md` in particular documents real mechanism and would be the
258+
starting point if the decision were ever revisited. They are labelled, not deleted.
259+
232260
### MCP Servers (13 servers, 295 tools) -- All Extracted to Separate Repos
233261

234262
All 13 MCP servers have been extracted to individual private repos under

‎docs/architecture/POLICIES-AND-SCRIPTS-FLOW.md‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -427,11 +427,11 @@ LEVEL 3 (EXECUTION):
427427
└─ Failure Prevention: 8 scripts ✅
428428
Total: 66 scripts, 11 steps
429429
430-
HOOKS:
431-
├─ UserPromptSubmit: 3-level-flow + github_issue_manager ✅
432-
├─ PreToolUse: pre-tool-enforcer (5 enforcement levels) ✅
433-
├─ PostToolUse: post-tool-tracker (6 tracking levels) ✅
434-
└─ Stop: stop-notifier ✅
430+
HOOKS: (status corrected 2026-09-15, GH #323 -- only Stop is registered)
431+
├─ UserPromptSubmit: 3-level-flow + github_issue_manager [UNREGISTERED v2.0.0]
432+
├─ PreToolUse: pre-tool-enforcer (5 enforcement levels) [UNREGISTERED v2.0.0]
433+
├─ PostToolUse: post-tool-tracker (6 tracking levels) [UNREGISTERED v2.0.0]
434+
└─ Stop: stop-notifier ✅ [LIVE]
435435
436436
OVERALL: 45 POLICIES + 74+ SCRIPTS = FULLY INTEGRATED 3-LEVEL SYSTEM ✅
437437
```

‎docs/architecture/POLICY-CHAIN-FLOWCHART.md‎

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,28 @@
88

99
## Overview
1010

11+
> ## ⚠ THREE OF THE FOUR HOOKS BELOW NO LONGER RUN
12+
>
13+
> **Status corrected 2026-09-15 (GH #323).** ADR-006 removed the `UserPromptSubmit`,
14+
> `PreToolUse` and `PostToolUse` **registrations** in v2.0.0 (executed 2026-08-04,
15+
> commit `2e371f6`), keeping the source files deliberately. **`Stop` is the only
16+
> registered hook.**
17+
>
18+
> Everything below is accurate as a record of how those hooks worked and is retained
19+
> for exactly that reason — it documents real mechanism and is the starting point if
20+
> the decision is ever revisited. **It is not a description of the running system.**
21+
> Do not route an enforcement need to `pre-tool-enforcer.py`; it cannot fire. The
22+
> pre-tool deny capability that does exist is Claude Code's native `permissions.deny`
23+
> in `settings.json`, which is a settings rule rather than a hook. See
24+
> `CLAUDE.md` → "Hook status" and `ADR-006-hook-free-execution.md`.
25+
1126
This document shows the complete flow of policy execution across all 4 hooks and 3 levels of the Claude Workflow Engine system. Every subprocess call, flag read/write, and data flow is visualized using Mermaid flowcharts.
1227

13-
**The 4 Hooks (Execution Order):**
14-
1. `UserPromptSubmit` → clear-session-handler.py + 3-level-flow.py (Level -1/1/2/3)
15-
2. `PreToolUse` → pre-tool-enforcer.py (Level 3.6/3.7)
16-
3. `PostToolUse` → post-tool-tracker.py (Level 3.9)
17-
4. `Stop` → stop-notifier.py (Level 3.10)
28+
**The 4 Hooks (Execution Order) — as designed in v1.x; see the status notice above:**
29+
1. `UserPromptSubmit` → clear-session-handler.py + 3-level-flow.py (Level -1/1/2/3) **[UNREGISTERED since v2.0.0]**
30+
2. `PreToolUse` → pre-tool-enforcer.py (Level 3.6/3.7) **[UNREGISTERED since v2.0.0]**
31+
3. `PostToolUse` → post-tool-tracker.py (Level 3.9) **[UNREGISTERED since v2.0.0]**
32+
4. `Stop` → stop-notifier.py (Level 3.10) **[LIVE — the only registered hook]**
1833

1934
---
2035

@@ -235,6 +250,10 @@ flowchart TD
235250

236251
## Section 4: pre-tool-enforcer.py Check Sequence
237252

253+
> **This sequence does not execute.** `PreToolUse` was unregistered in v2.0.0 (ADR-006);
254+
> the script is retained but never invoked. Read this as design history, not as a control
255+
> that runs. See the status notice at the top of this file. (GH #323)
256+
238257
```mermaid
239258
flowchart TD
240259
START["🔍 pre-tool-enforcer.py Starts<br/>(Before each tool execution)"]

0 commit comments

Comments
 (0)