Skip to content

Commit 1ce97b5

Browse files
authored
Merge pull request #46 from barkain/fix/restore-delegation-directive
fix: restore delegation directive after f831fd2 regression
2 parents 8ac52d7 + 4c97f69 commit 1ce97b5

9 files changed

Lines changed: 70 additions & 37 deletions

File tree

.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": "2.0.2",
11+
"version": "2.0.3",
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": "2.0.2",
3+
"version": "2.0.3",
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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

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

5+
## [2.0.3] - 2026-04-16
6+
7+
### Fixed
8+
- Restored main-agent delegation after f831fd2 regression: imperative nudge messages from violation #1, orchestrator stub gains work definition + MUST NOT list + self-catch directive, output style reframes main agent as orchestrator (not executor).
9+
510
## [2.0.2] - 2026-04-12
611

712
### Added

CLAUDE.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
66

77
## Delegation Policy (Soft Enforcement)
88

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 hintwarning → strong reminder. The counter resets each turn and zeros when `/workflow-orchestrator:delegate` runs.
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 → imperative STOPimperative STOP (2nd call phrasing) → strong reminder explaining what's being lost. The counter resets each turn and zeros when `/workflow-orchestrator:delegate` runs.
1010

1111
The expected path for any multi-step or work-shaped request is:
1212

@@ -115,10 +115,9 @@ There is no allowlist. `require_delegation.py` tracks per-turn direct work-tool
115115
| Violations | Message | Tokens |
116116
|---|---|---|
117117
| 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 |
118+
| 1 | `STOP. This tool call bypasses delegation. Abandon this step and run: /workflow-orchestrator:delegate <your task>` | ~25 |
119+
| 2 | `STOP. 2nd direct tool call this turn. The main agent does not execute work tools. Run: /workflow-orchestrator:delegate <your task>` | ~28 |
120+
| 3+ | `STOP. N direct tool calls bypassing delegation. You are losing planning, parallelization, and context isolation. Abandon the current plan and run: /workflow-orchestrator:delegate <your task>` | ~55 |
122121

123122
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.
124123

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -193,20 +193,21 @@ and then prompt claude with:
193193
The delegation system uses adaptive nudges instead of hard blocks:
194194

195195
```bash
196-
# Turn 1: Direct tool call (silent)
196+
# 1st direct tool call (imperative STOP)
197197
Read test.py
198+
# stderr: "STOP. This tool call bypasses delegation. Abandon this step and run: /workflow-orchestrator:delegate <your task>"
198199

199-
# Turn 2: Another direct tool call (hint)
200+
# 2nd direct tool call (imperative STOP, 2nd-call phrasing)
200201
Read other.py
201-
# stderr: "delegate?"
202+
# stderr: "STOP. 2nd direct tool call this turn. The main agent does not execute work tools. Run: /workflow-orchestrator:delegate <your task>"
202203

203-
# Turn 3: Third direct tool call (nudge)
204+
# 3rd direct tool call (strong reminder — explains what's being lost)
204205
Edit file.py
205-
# stderr: "nudge: use /workflow-orchestrator:delegate for multi-step work"
206+
# stderr: "STOP. 3 direct tool calls bypassing delegation. You are losing planning, parallelization, and context isolation. Abandon the current plan and run: /workflow-orchestrator:delegate <your task>"
206207

207-
# Turn 4: Fourth direct tool call (warning)
208+
# 4th+ direct tool calls keep the same strong reminder with the updated count
208209
Bash command.sh
209-
# stderr: "WARNING: 3 direct tool calls bypassing delegation. Use /workflow-orchestrator:delegate <task>."
210+
# stderr: "STOP. 4 direct tool calls bypassing delegation. ..."
210211

211212
# Delegation resets the counter (state clean)
212213
/workflow-orchestrator:delegate "Create feature"

hooks/PreToolUse/require_delegation.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,18 +93,19 @@ def message_for(count: int) -> str | None:
9393
if count <= 0:
9494
return None
9595
if count == 1:
96-
return "delegate?"
96+
return (
97+
"STOP. This tool call bypasses delegation. Abandon this step "
98+
"and run: /workflow-orchestrator:delegate <your task>"
99+
)
97100
if count == 2:
98-
return "nudge: use /workflow-orchestrator:delegate for multi-step work"
99-
if count <= 4:
100101
return (
101-
f"WARNING: {count} direct tool calls bypassing delegation. "
102-
"Use /workflow-orchestrator:delegate <task>."
102+
"STOP. 2nd direct tool call this turn. The main agent does not "
103+
"execute work tools. Run: /workflow-orchestrator:delegate <your task>"
103104
)
104105
return (
105-
f"WARNING: {count}+ direct tool calls. The orchestrator plans, "
106-
"parallelizes, and isolates context — direct use loses these benefits. "
107-
"Run /workflow-orchestrator:delegate <task> now."
106+
f"STOP. {count} direct tool calls bypassing delegation. You are "
107+
"losing planning, parallelization, and context isolation. Abandon "
108+
"the current plan and run: /workflow-orchestrator:delegate <your task>"
108109
)
109110

110111

output-styles/technical-adaptive.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ keep-coding-instructions: true
66

77
# Response Format
88

9+
The main agent is an orchestrator, not an executor. Work goes through /workflow-orchestrator:delegate. Responses summarize subagent output — they do not describe tool calls the main agent made directly.
10+
911
## Default Mode: Ultra Concise
1012

1113
- Deliver only what is necessary. No fluff, no preamble, no recap.
1214
- Expert-level brevity — assume the user has deep technical knowledge.
1315
- Direct answers only. No hand-holding.
14-
- After completing an edit, respond with ONE sentence (e.g., "Done. Added timeout to compact_run.py."). The user can read the diff.
16+
- After a delegation completes, respond with ONE sentence summarizing what the subagents did (e.g., "Done. Wave 0 added timeout to compact_run.py."). The user can read the diffs and task log.
1517
- Never restate the user's problem before acting.
1618
- Never reply "You're absolutely right" or similar affirmations — just act.
1719
- Never add time or effort estimates to tasks.

system-prompts/orchestrator_stub.md

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,29 @@ Any user request that requires work — writing code, running tools, multi-step
88
/workflow-orchestrator:delegate <full task description>
99
```
1010

11-
The main agent does not execute work tools directly. Use only: Tasks API, AskUserQuestion, and `/workflow-orchestrator:delegate`. The delegate command loads the full orchestrator (planning, agent assignment, execution waves) on demand.
11+
The main agent does not execute work tools directly. Use only: Tasks API, AskUserQuestion, `/workflow-orchestrator:delegate`, and `/workflow-orchestrator:ask` (read-only questions). The delegate command loads the full orchestrator (planning, agent assignment, execution waves) on demand.
1212

1313
## Exception — continuation after plan approval
1414

1515
If you received a "PLAN ALREADY APPROVED" or "continuing to STAGE 1" continuation message from the Stop hook, **do NOT re-invoke `/workflow-orchestrator:delegate`** and **do NOT call `EnterPlanMode`** again. The orchestrator is already loaded and the plan is already approved — proceed directly to Stage 1 execution by rendering the dependency graph and spawning Wave 0 agents. In this exception path, the `Agent` tool (plus `TaskCreate`/`TaskUpdate`/`TaskGet` for status, and `TeamCreate`/`SendMessage` if running in team mode) is permitted — these are how Wave 0 phases are spawned. The "all work → delegate" rule above does NOT apply during in-flight delegation continuation.
1616

17+
## What counts as "work"
18+
19+
ANY of these = delegate:
20+
- Reading, searching, editing, or writing files (Read, Grep, Glob, Edit, Write, MultiEdit, NotebookEdit)
21+
- Running shell commands (Bash) for anything beyond a single trivial status check
22+
- Investigating the codebase to answer a question that requires file access → use /workflow-orchestrator:ask
23+
- Multi-step tasks, even if each step looks simple in isolation
24+
25+
## What you MUST NOT do
26+
27+
- Do NOT open files with Read to "just check" before deciding — delegate the check
28+
- Do NOT run `grep`/`find`/`ls` via Bash — delegate
29+
- Do NOT make "just a small edit" directly — delegate
30+
- Do NOT chain 2+ tool calls to accomplish one user request — delegate
31+
32+
If you catch yourself about to call Bash/Edit/Write/Read/Glob/Grep/MultiEdit/NotebookEdit, STOP and invoke `/workflow-orchestrator:delegate <task>` instead.
33+
1734
## Team Mode
1835

1936
If `TeamCreate` is in your available tools, agent teams are enabled. When you run `/workflow-orchestrator:delegate`, default to team mode (`TeamCreate` + `Agent(team_name=...)`) for multi-agent work. If `TeamCreate` is not available, the delegate flow falls back to parallel subagents automatically.

tests/test_require_delegation.py

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,46 +110,54 @@ def test_non_work_tools_silent(self, tmp_path: Path, tool: str) -> None:
110110

111111

112112
class TestEscalationLadder:
113-
def test_first_violation_is_short(self, tmp_path: Path) -> None:
113+
def test_first_violation_is_imperative(self, tmp_path: Path) -> None:
114114
_, stderr, _ = _run(_input("Bash"), tmp_path)
115-
assert "delegate?" in stderr # noqa: S101
116-
# Short message — under ~30 chars
117-
assert len(stderr.strip()) < 30 # noqa: S101
115+
# New imperative message must include STOP + the delegate command
116+
assert "STOP" in stderr # noqa: S101
117+
assert "/workflow-orchestrator:delegate" in stderr # noqa: S101
118118

119119
def test_second_violation_is_medium(self, tmp_path: Path) -> None:
120120
_run(_input("Bash"), tmp_path)
121121
_, stderr, _ = _run(_input("Edit"), tmp_path)
122-
assert "nudge" in stderr # noqa: S101
122+
assert "STOP" in stderr # noqa: S101
123123
assert "/workflow-orchestrator:delegate" in stderr # noqa: S101
124+
# Distinct 2nd-call phrasing
125+
assert "2nd direct tool call" in stderr # noqa: S101
124126

125127
def test_third_violation_is_warning(self, tmp_path: Path) -> None:
126128
for tool in ("Bash", "Edit", "Write"):
127129
_run(_input(tool), tmp_path)
128130
_, stderr, _ = _run(_input("Read"), tmp_path)
129-
# 4th call -> "WARNING: 4 direct tool calls"
130-
assert "WARNING" in stderr # noqa: S101
131+
# 4th call -> "STOP. 4 direct tool calls bypassing delegation..."
132+
assert "STOP" in stderr # noqa: S101
131133
assert "4" in stderr # noqa: S101
134+
assert "/workflow-orchestrator:delegate" in stderr # noqa: S101
132135

133136
def test_fifth_plus_is_strong(self, tmp_path: Path) -> None:
134137
for _ in range(5):
135138
_run(_input("Bash"), tmp_path)
136139
_, stderr, _ = _run(_input("Bash"), tmp_path) # 6th call
137-
assert "WARNING" in stderr # noqa: S101
138-
assert "parallelizes" in stderr # noqa: S101
140+
assert "STOP" in stderr # noqa: S101
141+
# The ≥3 message explains what's being lost
142+
assert "losing planning, parallelization, and context isolation" in stderr # noqa: S101
139143
# Long message — over ~100 chars
140144
assert len(stderr.strip()) > 100 # noqa: S101
141145

142146
def test_message_length_grows(self, tmp_path: Path) -> None:
143-
"""Verify token cost (proxied by message length) scales with violations."""
147+
"""Verify escalation adds context (proxied by message length/content)."""
144148
lengths = []
149+
messages = []
145150
for _ in range(6):
146151
_, stderr, _ = _run(_input("Bash"), tmp_path)
147152
lengths.append(len(stderr.strip()))
148-
# Each level should be at least as long as the previous
153+
messages.append(stderr.strip())
154+
# Each level should be at least as long as the previous (monotonic)
149155
for i in range(1, len(lengths)):
150156
assert lengths[i] >= lengths[i - 1] # noqa: S101
151-
# The final message should be substantially longer than the first
152-
assert lengths[-1] > lengths[0] * 5 # noqa: S101
157+
# The final message should be strictly longer than the first
158+
assert lengths[-1] > lengths[0] # noqa: S101
159+
# And must include the "what's being lost" context that proves escalation
160+
assert "losing planning, parallelization, and context isolation" in messages[-1] # noqa: S101
153161

154162

155163
# ---------------------------------------------------------------------------

0 commit comments

Comments
 (0)