Skip to content

Commit f831fd2

Browse files
authored
feat: soft-enforcement delegation, simplified team mode, lean injection
Soft enforcement replaces hard-blocking delegation: - require_delegation.py emits per-turn escalating stderr nudges instead of exit-2 blocks - Tracks only the 8 stable work primitives (Bash/Edit/Write/Read/Glob/Grep/MultiEdit/NotebookEdit) - New Claude Code tools never trigger nudges — no allowlist maintenance - Counter resets per turn, zeros on /workflow-orchestrator:delegate, subagents immune Simplified team-mode selection: - Deleted team_mode_score scoring table - One rule: TeamCreate available → team mode, else subagent Team-mode persistent teammate fix: - Teammate Agent(team_name=...) calls must NOT use run_in_background: true - Background tasks exit on completion and are not persistent swarm members Lean SessionStart injection (~6.6K token savings): - 3 hooks consolidated into inject_all.py - Stub orchestrator on startup, full logic loaded on-demand by /delegate - Output style loaded natively from plugin.json Validation hooks downgraded to advisory-only. Removed orphaned system-prompts/workflow_orchestrator.md and commands/bypass.md. README walkthrough refreshed with team-mode demo. Closes #41
1 parent a1424cf commit f831fd2

41 files changed

Lines changed: 1244 additions & 2781 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.claude-plugin/marketplace.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"name": "workflow-orchestrator",
99
"source": "./",
1010
"description": "Delegation system with workflow orchestration, specialized agents, and parallel execution for Claude Code",
11-
"version": "1.16.0",
11+
"version": "1.18.0",
1212
"author": {
1313
"name": "Nadav Barkai"
1414
},

.claude-plugin/plugin.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "workflow-orchestrator",
3-
"version": "1.16.0",
3+
"version": "1.18.0",
44
"description": "Delegation system with workflow orchestration, specialized agents, and parallel execution for Claude Code",
55
"author": {
66
"name": "Nadav Barkai"

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,33 @@
22

33
All notable changes to this project will be documented in this file.
44

5+
## [1.18.0] - 2026-04-08
6+
7+
### Changed
8+
- **Soft enforcement replaces hard blocking**: `hooks/PreToolUse/require_delegation.py` no longer blocks tool calls. It emits per-turn escalating stderr nudges (silent → `delegate?``nudge: ...``WARNING: ...` → strong reminder) based on `.claude/state/delegation_violations.json`. The counter resets each turn and zeros when `/workflow-orchestrator:delegate` runs. Subagents are immune.
9+
- **Stable work-tool surface**: Only the 8 stable primitives (`Bash`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `MultiEdit`, `NotebookEdit`) are tracked. New Claude Code tools never trigger nudges — no more allowlist maintenance as Anthropic ships new tools.
10+
- **One-rule team mode selection**: Deleted the `team_mode_score` scoring table from `commands/delegate.md`. New rule — if `TeamCreate` is in the available tools, `execution_mode: "team"`; otherwise `"subagent"`. No scoring, no exceptions.
11+
- **Advisory-only validation hooks**: `validate_task_graph_compliance.py` and `validate_task_graph_depth.py` are now advisory (stderr hints, never block). `python_posttooluse_hook.py` (Ruff/Pyright) is the only remaining hard-blocking hook.
12+
13+
### Fixed
14+
- **Team-mode persistent teammates**: Teammate `Agent(team_name=...)` calls must NOT use `run_in_background: true`. Background Agent tasks exit on completion and are not persistent swarm members, leaving the tmux session empty. Subagent-mode spawns still use `run_in_background: true`.
15+
16+
### Removed
17+
- **`commands/bypass.md`**: No longer needed under soft enforcement.
18+
- **`system-prompts/workflow_orchestrator.md`**: Orphaned file (no Python loaded it). The full orchestrator logic lives inline in `commands/delegate.md` and is loaded on-demand by the slash command.
19+
20+
### Documentation
21+
- **README walkthrough**: Replaced legacy 5-screenshot subagent flow with 4 team-mode screenshots (plan mode → dependency graph → tmux swarm → completion). New 4× speed demo gif (`assets/workflow-demo.gif`).
22+
- **Refreshed**: `README.md`, `CLAUDE.md`, `docs/hook-debugging.md`, `docs/ARCHITECTURE_QUICK_REFERENCE.md`, `docs/environment-variables.md`, `docs/plan-explore-parallel-processing.md`, `docs/validation-schema.md`.
23+
24+
## [1.17.0] - 2026-04-06
25+
26+
### Changed
27+
- **SessionStart hooks consolidated**: Combined `inject_workflow_orchestrator.py`, `inject-output-style.py`, `inject_token_efficiency.py` into single `inject_all.py` — reads stdin once, outputs merged additionalContext (~0.7s faster startup)
28+
- **Statusline version from stdin**: Reads `version` field from stdin JSON instead of spawning `claude --version` subprocess (920ms → 0ms per render)
29+
- **Statusline context from stdin**: Reads `context_window` from stdin JSON instead of parsing JSONL files (~1s faster per render)
30+
- **Cached version fallback**: Falls back to cached `claude --version` with 1-hour TTL when stdin unavailable
31+
532
## [1.16.0] - 2026-04-06
633

734
### Fixed

CLAUDE.md

Lines changed: 37 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,28 +4,17 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
44

55
---
66

7-
## Critical: Delegation Policy
7+
## Delegation Policy (Soft Enforcement)
88

9-
**MANDATORY IMMEDIATE DELEGATION ON TOOL BLOCK**
9+
The framework nudges via stderr when the main agent uses work-doing tools (`Bash`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `MultiEdit`, `NotebookEdit`) directly. **Nudges never block.** They escalate by per-turn violation count: silent → short hint → warning → strong reminder. The counter resets each turn and zeros when `/workflow-orchestrator:delegate` runs.
1010

11-
When ANY tool is blocked by the delegation policy hook:
12-
13-
1. **DO NOT try alternative approaches** - just delegate immediately
14-
2. **IMMEDIATELY use `/workflow-orchestrator:delegate <task>`** on first tool block
15-
3. **The entire user request must be delegated**, not just the blocked tool
16-
17-
### Recognition Pattern
11+
The expected path for any multi-step or work-shaped request is:
1812

1913
```
20-
Error: PreToolUse:* hook error: [...] Tool blocked by delegation policy
21-
Tool: <ToolName>
22-
23-
STOP: Do NOT try alternative tools.
24-
REQUIRED: Use /workflow-orchestrator:delegate command immediately:
25-
/workflow-orchestrator:delegate <full task description>
14+
/workflow-orchestrator:delegate <task description>
2615
```
2716

28-
First tool block = immediate delegation. Don't try alternatives, don't explain — just delegate.
17+
Subagents are immune (they're executing a delegation). New tools added by Claude Code never trigger nudges — only the 8 stable work primitives are tracked.
2918

3019
---
3120

@@ -62,7 +51,6 @@ CI workflow exists (`.github/workflows/ci.yml`) but tests are currently disabled
6251
```bash
6352
/workflow-orchestrator:delegate <task> # Plan and execute task via native plan mode
6453
/workflow-orchestrator:ask <question> # Read-only question answering (forked context)
65-
/workflow-orchestrator:bypass # Toggle delegation enforcement on/off (persists until toggled)
6654
/workflow-orchestrator:add-statusline # Enable workflow status display
6755
```
6856

@@ -78,7 +66,7 @@ In plugin mode, all commands and agent names use the `workflow-orchestrator:` pr
7866

7967
### Execution Flow
8068

81-
**Token overhead:** Conditional injection (stub ~200 tokens on startup, full ~11K tokens on first delegation) + per-agent delegation (~350 tokens)
69+
**Token overhead:** Conditional injection (stub ~200 tokens on startup, full ~7.5K tokens on first delegation, optional token-efficient guide ~1.9K) + per-agent delegation (~350 tokens)
8270

8371
```
8472
User prompt
@@ -111,37 +99,36 @@ User prompt
11199

112100
| Event | Scripts | Purpose |
113101
|-------|---------|---------|
114-
| **PreToolUse** (`*`, `Bash`) | `validate_task_graph_compliance.py`, `require_delegation.py`, `token_rewrite_hook.py` (Bash only) | Validate Agent/Task invocations against active task graph; block non-allowed tools (compressed error messages); rewrite Bash commands for token efficiency (cd && pattern, eslint, next, tsc) |
115-
| **PostToolUse** | `python_posttooluse_hook.py` (Edit/Write/MultiEdit), `remind_skill_continuation.py` (ExitPlanMode\|Skill\|SlashCommand), `validate_task_graph_depth.py` + `remind_todo_after_task.py` (Agent/Task) | Python validation (Ruff, Pyright, security), workflow continuation state (triggers on ExitPlanMode for plan mode flows), depth-3 enforcement, task reminders |
116-
| **UserPromptSubmit** | `clear-delegation-sessions.py` | Clear delegation state, record turn start timestamp, clear team state (`team_mode_active`, `team_config.json`), rotate logs |
117-
| **SessionStart** (`startup\|resume\|clear\|compact`) | `inject_workflow_orchestrator.py`, `inject-output-style.py`, `inject_token_efficiency.py` | Inject conditional orchestrator (stub on startup, full on /workflow-orchestrator:delegate), output style, token efficiency guidance |
102+
| **PreToolUse** (`*`, `Bash`) | `validate_task_graph_compliance.py` (advisory), `require_delegation.py` (adaptive nudge), `token_rewrite_hook.py` (Bash only) | Hint on out-of-order Agent/Task spawns; emit per-turn escalating delegation nudge (silent → strong); rewrite Bash for token-efficient output |
103+
| **PostToolUse** | `python_posttooluse_hook.py` (Edit/Write/MultiEdit, **blocking**), `remind_skill_continuation.py` (ExitPlanMode\|Skill\|SlashCommand), `validate_task_graph_depth.py` (advisory) + `remind_todo_after_task.py` (Agent/Task) | Python validation (Ruff, Pyright, security — only hard-blocking hook); workflow continuation + zero violations counter on `/workflow-orchestrator:delegate`; depth hint; task reminders |
104+
| **UserPromptSubmit** | `clear-delegation-sessions.py` | Reset per-turn state (timestamp, violations counter), clear team state, rotate logs |
105+
| **SessionStart** (`startup\|resume\|clear\|compact`) | `inject_all.py` | Consolidated injection (orchestrator stub + token efficiency). Output style is loaded natively from plugin.json's `outputStyles` field |
118106
| **SubagentStop** (`*`) | `remind_todo_update.py` (async), `trigger_verification.py` | Remind to update tasks, suggest verification |
119-
| **Stop** | `python_stop_hook.py` | Turn duration, workflow continuation (block stop + inject "continue"), quality analysis |
107+
| **Stop** | `python_stop_hook.py` | Turn duration, workflow continuation, quality analysis |
120108

121109
Hook config source of truth: `hooks/plugin-hooks.json` (not settings.json). All hooks are Python for cross-platform compatibility (Windows/macOS/Linux).
122110

123-
### Tool Allowlist
111+
### Soft Enforcement (Adaptive Nudges)
124112

125-
Main agent can only use: `AskUserQuestion`, `TaskCreate`, `TaskUpdate`, `TaskList`, `TaskGet`, `Skill`, `SlashCommand`, `Agent`, `Task`, `SubagentTask`, `AgentTask`, `EnterPlanMode`, `ExitPlanMode`, `ToolSearch`, `CronCreate`, `CronDelete`, `CronList`
113+
There is no allowlist. `require_delegation.py` tracks per-turn direct work-tool calls and writes a stderr message that escalates by count:
126114

127-
Special cases:
128-
- `Write` tool allowed for temp/scratchpad paths only (`/tmp/`, `/private/tmp/`, `/var/folders/`)
129-
- `TaskOutput` is **prohibited** (context exhaustion: ~20K tokens per agent)
130-
- `TaskList` polling loops are **prohibited** (use completion notifications instead)
115+
| Violations | Message | Tokens |
116+
|---|---|---|
117+
| 0 | (silent) | 0 |
118+
| 1 | `delegate?` | ~2 |
119+
| 2 | `nudge: use /workflow-orchestrator:delegate for multi-step work` | ~12 |
120+
| 3–4 | `WARNING: N direct tool calls bypassing delegation. Use /workflow-orchestrator:delegate <task>.` | ~25 |
121+
| 5+ | Strong reminder explaining what's being lost | ~55 |
131122

132-
**Agent Teams tools** (conditional, requires `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1`):
133-
- Explicit: `TeamCreate`, `SendMessage`
134-
- Teammates are spawned via `Agent` tool with `team_name` parameter (Agent is already in the main allowlist)
135-
- Pattern match: Any tool name containing `"team"` or `"teammate"` (case-insensitive) as safety net
123+
Tracked tools (the only ones that count as violations): `Bash`, `Edit`, `Write`, `Read`, `Glob`, `Grep`, `MultiEdit`, `NotebookEdit`. These 8 stable primitives are the only ones monitored. New Claude Code tools never trigger nudges.
136124

137-
### Bypass Mechanisms
125+
The counter:
126+
- Resets each turn (`UserPromptSubmit`)
127+
- Zeros when `/workflow-orchestrator:delegate` runs (slate clean — model chose the right path)
128+
- Is bypassed entirely for subagents (they're executing a delegation; `CLAUDE_PARENT_SESSION_ID` / `CLAUDE_AGENT_ID` set)
129+
- Is bypassed when `.claude/state/delegation_active` exists (delegation already in progress)
138130

139-
| Mechanism | How | Scope |
140-
|-----------|-----|-------|
141-
| Env var | `DELEGATION_HOOK_DISABLE=1` | Session-wide |
142-
| `/workflow-orchestrator:bypass` command | Creates `.claude/state/delegation_disabled` | Persists until toggled |
143-
| Subagent auto-bypass | `CLAUDE_PARENT_SESSION_ID` set | Automatic for subagents |
144-
| Delegation active flag | `.claude/state/delegation_active` created on Skill/Agent/Task use | Per-delegation |
131+
The only hook that still hard-blocks is `python_posttooluse_hook.py` (Ruff/Pyright on edited Python files — stable surface, fix-forward UX).
145132

146133
**Note:** The `task-planner` and `breadth-reader` skills have been removed. Planning and orchestration are provided by native plan mode (EnterPlanMode/ExitPlanMode). Read-only breadth tasks are handled by spawning parallel Explore agents or the codebase-context-analyzer directly.
147134

@@ -174,21 +161,17 @@ Two team workflow patterns:
174161
- **Team mode (simple):** Single AGENT TEAM phase with `phase_type: "team"` and `teammates` array -- used for multi-perspective exploration (e.g., "explore from different angles")
175162
- **Team mode (complex):** Multiple individual phases across waves, all executed as teammates via `Agent(team_name=...)` -- used for collaborative implementation (e.g., "implement project, tasks should be collaborative"). The plan has `execution_mode: "team"` at the top level; no individual phase needs `phase_type: "team"`
176163

177-
**Mode selection** is based on TeamCreate tool availability (detected during plan mode):
178-
- **If TeamCreate tool is available** (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is set): Calculate `team_mode_score` to determine whether to use team mode or subagent mode
179-
- Phase count >8: +2, Tier 3 complexity: +2, cross-phase data flow: +3
180-
- Review-fix cycles: +3, iterative refinement: +2, user keyword "collaborate"/"team": +5
181-
- Breadth task: -5, phase count <=3: -3
182-
- Default to team mode (score not calculated, absent, or > -3); use subagent mode only when score <= -3
183-
- **If TeamCreate tool is not available** (env var not set): Always use subagent mode (≥2 subtasks mandatory)
164+
**Mode selection** is based on ONE RULE (detected during plan mode):
165+
- **If TeamCreate tool is available** (CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 is set): `execution_mode: "team"`
166+
- **If TeamCreate tool is not available** (env var not set): `execution_mode: "subagent"` (≥2 subtasks mandatory)
184167

185168
**When team mode is active:**
186169
- `validate_task_graph_compliance.py` hook is bypassed (team handles dependencies)
187170
- Agent Teams tools are added to the allowlist (TeamCreate, SendMessage; teammates via Agent with team_name param)
188171
- Agents use conditional COMMUNICATION MODE (teammate messaging vs `DONE|{path}`)
189172
- State files: `.claude/state/team_mode_active`, `.claude/state/team_config.json`
190173

191-
Agent selection uses keyword matching (≥2 matches threshold, highest count wins). Falls back to general-purpose if 0-1 matches. See `system-prompts/workflow_orchestrator.md` for keyword lists.
174+
Agent selection uses keyword matching (≥2 matches threshold, highest count wins). Falls back to general-purpose if 0-1 matches. See `commands/delegate.md` (Available Specialized Agents section) for keyword lists.
192175

193176
Agent config format: YAML frontmatter (`name`, `description`, optional `tools`/`model`/`color`) + markdown system prompt body. All agents enforce `DONE|{output_file}` return format. Custom agent instructions include:
194177
- Return format must be exactly `DONE|{output_file_path}` (no summaries or explanations)
@@ -199,9 +182,8 @@ Agent config format: YAML frontmatter (`name`, `description`, optional `tools`/`
199182

200183
| File | Purpose | Lifecycle |
201184
|------|---------|-----------|
202-
| `.claude/state/delegated_sessions.txt` | Session registry | Cleared per user prompt |
203-
| `.claude/state/delegation_active` | Subagent session flag | Per-delegation |
204-
| `.claude/state/delegation_disabled` | Bypass flag | Until `/bypass` toggle |
185+
| `.claude/state/delegation_violations.json` | Per-turn nudge counter (`{violations, delegations, turn_id}`) | Reset per user prompt; zeroed on `/workflow-orchestrator:delegate` |
186+
| `.claude/state/delegation_active` | Active-delegation flag (suppresses nudges) | Per-delegation |
205187
| `.claude/state/active_delegations.json` | Parallel wave tracking | Per-workflow |
206188
| `.claude/state/active_task_graph.json` | Task graph for validation | Per-workflow |
207189
| `.claude/state/workflow_continuation_needed.json` | Signal stop hook to auto-continue | Per-plan-mode exit (ExitPlanMode) |
@@ -233,7 +215,6 @@ Agent config format: YAML frontmatter (`name`, `description`, optional `tools`/`
233215

234216
| Variable | Default | Purpose |
235217
|----------|---------|---------|
236-
| `DELEGATION_HOOK_DISABLE` | `0` | Emergency bypass (`1` to disable enforcement) |
237218
| `DEBUG_DELEGATION_HOOK` | `0` | Enable hook debug logging to `/tmp/delegation_hook_debug.log` |
238219
| `CLAUDE_MAX_CONCURRENT` | `8` | Max parallel agents per batch |
239220
| `CHECK_RUFF` | `1` | Skip Ruff validation (`0` to disable) |
@@ -284,12 +265,12 @@ tail -f /tmp/delegation_hook_debug.log
284265

285266
**Check delegation state:**
286267
```bash
287-
cat .claude/state/delegated_sessions.txt
288-
cat .claude/state/delegation_disabled # bypass active?
268+
cat .claude/state/delegation_violations.json # current per-turn nudge counter
269+
ls .claude/state/delegation_active 2>/dev/null # delegation in progress?
289270
```
290271

291272
**Multi-step not detected:**
292-
Ensure SessionStart hooks are installed (inject_workflow_orchestrator.py) so that workflow_orchestrator.md is injected and native plan mode (EnterPlanMode/ExitPlanMode) is available. Use connectors in prompts: "and then", "with", "including".
273+
Ensure the SessionStart hook is installed (`hooks/SessionStart/inject_all.py`) so `orchestrator_stub.md` is injected and the main agent knows to route multi-step work through `/workflow-orchestrator:delegate`. Use connectors in prompts: "and then", "with", "including".
293274

294275
**TeamCreate blocked:**
295276
```bash
@@ -299,7 +280,7 @@ export CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1
299280
The PreToolUse hook blocks all team tools (`TeamCreate`, `SendMessage`, pattern `*team*`/`*teammate*`) unless this env var is set. The hook auto-creates `.claude/state/team_mode_active` when the env var is "1" and a team tool is invoked.
300281

301282
**Team mode not activating despite keywords:**
302-
Team mode is activated by tool availability detection during plan mode. Ensure `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set before running a workflow that should use team mode. The planning phase evaluates `team_mode_score` based on task complexity and characteristics. Without the env var, plan mode always selects `"subagent"` mode (with ≥2 subtasks mandatory).
283+
Team mode is activated by tool availability detection during plan mode. Ensure `CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1` is set before running a workflow that should use team mode. The planning phase checks if `TeamCreate` tool is available. If the env var is not set, `TeamCreate` is blocked by PreToolUse hook, so plan mode always selects `"subagent"` mode (with ≥2 subtasks mandatory).
303284

304285
**Team state files stale after crash:**
305286
```bash

0 commit comments

Comments
 (0)