claude-dev-env 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/install.mjs CHANGED
@@ -29,7 +29,6 @@ const INSTALL_GROUPS = {
29
29
  description: 'Prompt engineering tools',
30
30
  skills: ['prompt-generator', 'agent-prompt'],
31
31
  includeHookFiles: [
32
- 'blocking/agent-execution-intent-gate.py',
33
32
  'blocking/prompt_workflow_gate_core.py',
34
33
  'blocking/prompt-workflow-stop-guard.py',
35
34
  'HOOK_SPECS_PROMPT_WORKFLOW.md',
@@ -2,21 +2,9 @@
2
2
 
3
3
  Deterministic runtime gates for prompt workflows.
4
4
 
5
- ## Gate: Execution Intent (PreToolUse Task/Agent)
5
+ ## PreToolUse Task/Agent (removed)
6
6
 
7
- - Hook: `hooks/blocking/agent-execution-intent-gate.py`
8
- - Event: `PreToolUse`
9
- - Matcher: `Task|Agent`
10
- - Fail condition:
11
- - Missing structured execution intent contract field:
12
- - `tool_input.execution_intent: explicit|execute|delegate`, or
13
- - `tool_input.execution_intent_explicit: true`, or
14
- - `tool_input.metadata.execution_intent: explicit|execute|delegate`
15
- - Missing required scope anchors in launch payload (always enforced when execution launch is evaluated)
16
- - Compatibility fallback:
17
- - Text markers are only accepted when `PROMPT_WORKFLOW_ALLOW_TEXT_INTENT_FALLBACK=1` is set.
18
- - Fallback usage is logged to stderr.
19
- - Action: `deny` with concrete missing requirement list.
7
+ The former `agent-execution-intent-gate.py` hook is **removed**. Native Agent/Task launches do not carry stable custom metadata; enforcing scope text on every spawn blocked legitimate `/agent-prompt` and refinement delegations. Scope and checklist rules remain enforced by the Stop guard when a prompt-workflow response is detected.
20
8
 
21
9
  ## Gate: Leakage + Checklist + Scope (Stop)
22
10
 
@@ -83,6 +83,8 @@ def _check_checklist_container(assistant_message: str) -> dict | None:
83
83
  )
84
84
 
85
85
  def _check_missing_checklist_rows(assistant_message: str) -> dict | None:
86
+ if not has_checklist_container(assistant_message):
87
+ return None
86
88
  missing_rows = missing_checklist_rows(assistant_message)
87
89
  if not missing_rows:
88
90
  return None
@@ -152,7 +154,6 @@ def _evaluate_workflow_gates(assistant_message: str) -> dict | None:
152
154
  if not is_prompt_workflow_response(assistant_message):
153
155
  return None
154
156
  workflow_gate_checks: tuple[Callable[[str], dict | None], ...] = (
155
- _check_checklist_container,
156
157
  _check_missing_checklist_rows,
157
158
  _check_missing_scope_anchors,
158
159
  _check_missing_context_signals,
@@ -54,14 +54,6 @@ INTERNAL_OBJECT_MARKERS: tuple[str, ...] = (
54
54
  '"audit_output_contract": {',
55
55
  )
56
56
 
57
- EXPLICIT_EXECUTION_MARKERS: tuple[str, ...] = (
58
- "/agent-prompt",
59
- "execution_intent: explicit",
60
- "execution_intent_explicit: true",
61
- "explicit execution intent",
62
- "explicit delegation intent",
63
- )
64
-
65
57
  PROMPT_WORKFLOW_RESPONSE_MARKERS: tuple[str, ...] = (
66
58
  "checklist_results",
67
59
  "overall_status",
@@ -159,36 +151,6 @@ def _contains_any_marker(text: str, markers: Iterable[str]) -> bool:
159
151
  return any(marker.lower() in lower_text for marker in markers)
160
152
 
161
153
 
162
- def has_explicit_execution_intent(text: str) -> bool:
163
- return _contains_any_marker(text, EXPLICIT_EXECUTION_MARKERS)
164
-
165
-
166
- def has_structured_execution_intent(tool_input: object) -> bool:
167
- if not isinstance(tool_input, dict):
168
- return False
169
-
170
- explicit_flag = tool_input.get("execution_intent_explicit")
171
- if isinstance(explicit_flag, bool):
172
- return explicit_flag
173
-
174
- intent_value = tool_input.get("execution_intent")
175
- if isinstance(intent_value, str):
176
- normalized = intent_value.strip().lower()
177
- return normalized in {"explicit", "execute", "delegation", "delegate"}
178
- if isinstance(intent_value, bool):
179
- return intent_value
180
-
181
- metadata = tool_input.get("metadata")
182
- if isinstance(metadata, dict):
183
- metadata_intent = metadata.get("execution_intent")
184
- if isinstance(metadata_intent, str):
185
- return metadata_intent.strip().lower() in {"explicit", "execute", "delegate"}
186
- if isinstance(metadata_intent, bool):
187
- return metadata_intent
188
-
189
- return False
190
-
191
-
192
154
  def has_debug_intent(text: str) -> bool:
193
155
  return _contains_any_marker(text, DEBUG_INTENT_MARKERS)
194
156
 
@@ -20,8 +20,8 @@ def test_context_control_rule_exists_with_required_sections() -> None:
20
20
 
21
21
  def test_hook_spec_exists_with_required_gates() -> None:
22
22
  text = HOOK_SPEC_PATH.read_text(encoding="utf-8")
23
- assert "Execution Intent (PreToolUse Task/Agent)" in text
23
+ assert "PreToolUse Task/Agent (removed)" in text
24
+ assert "agent-execution-intent-gate.py" in text
24
25
  assert "Leakage + Checklist + Scope (Stop)" in text
25
26
  assert "Required Deterministic Checklist Rows" in text
26
- assert "structured execution intent contract" in text
27
27
  assert "Runtime Context-Control Signals" in text
@@ -3,8 +3,6 @@
3
3
  from prompt_workflow_gate_core import (
4
4
  find_ambiguous_scope_terms,
5
5
  has_checklist_container,
6
- has_explicit_execution_intent,
7
- has_structured_execution_intent,
8
6
  has_internal_object_leak,
9
7
  is_prompt_workflow_response,
10
8
  missing_context_control_signals,
@@ -13,18 +11,6 @@ from prompt_workflow_gate_core import (
13
11
  )
14
12
 
15
13
 
16
- def test_execution_intent_marker_detected() -> None:
17
- assert has_explicit_execution_intent("execution_intent: explicit")
18
-
19
-
20
- def test_structured_execution_intent_detected_from_contract_field() -> None:
21
- assert has_structured_execution_intent({"execution_intent": "explicit"})
22
-
23
-
24
- def test_structured_execution_intent_detected_from_boolean_flag() -> None:
25
- assert has_structured_execution_intent({"execution_intent_explicit": True})
26
-
27
-
28
14
  def test_internal_object_leak_detected() -> None:
29
15
  text = '{"pipeline_mode": "internal_section_refinement_with_final_audit"}'
30
16
  assert has_internal_object_leak(text)
@@ -66,7 +66,7 @@ def test_blocks_missing_checklist_rows() -> None:
66
66
  assert response["decision"] == "block"
67
67
  assert "Deterministic checklist rows missing" in response["reason"]
68
68
 
69
- def test_blocks_missing_checklist_container_for_prompt_workflow_output() -> None:
69
+ def test_allows_prompt_workflow_output_without_checklist_container() -> None:
70
70
  payload = {
71
71
  "last_assistant_message": (
72
72
  "overall_status: pass\n"
@@ -80,9 +80,7 @@ def test_blocks_missing_checklist_container_for_prompt_workflow_output() -> None
80
80
  ),
81
81
  }
82
82
  result = _run_hook(payload)
83
- response = json.loads(result.stdout)
84
- assert response["decision"] == "block"
85
- assert "Deterministic checklist container missing" in response["reason"]
83
+ assert result.stdout.strip() == ""
86
84
 
87
85
  def test_blocks_missing_context_control_signals() -> None:
88
86
  payload = {
package/hooks/hooks.json CHANGED
@@ -94,11 +94,6 @@
94
94
  "type": "command",
95
95
  "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/parallel-task-blocker.py",
96
96
  "timeout": 10
97
- },
98
- {
99
- "type": "command",
100
- "command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/blocking/agent-execution-intent-gate.py",
101
- "timeout": 10
102
97
  }
103
98
  ]
104
99
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-dev-env",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Claude Code development standards — rules, hooks, agents, commands, and skills",
5
5
  "type": "module",
6
6
  "bin": {
@@ -68,7 +68,6 @@ Use simplified mode when either condition is true:
68
68
 
69
69
  This mode is triggered when execution input includes `pipeline_mode: internal_section_refinement_with_final_audit` or equivalent execution-ready orchestration metadata.
70
70
  If present, carry forward the scope block (`target_local_roots`, `target_canonical_roots`, `target_file_globs`, `comparison_basis`, `completion_boundary`) so execution remains artifact-bound.
71
- Execution launch payload must include `execution_intent: explicit`.
72
71
 
73
72
  1. Spawn exactly 6 refinement agents, one per section in fixed order:
74
73
  - `role`
@@ -194,7 +193,7 @@ Section-refinement orchestration is done only when all are true:
194
193
  - Gather context before crafting -- do not send an agent in blind
195
194
  - Start only after explicit user execution intent; keep prompt authoring/refinement in `/prompt-generator`
196
195
  - Default to `section_refinement_with_final_audit` orchestration for execution tasks unless user requests simplified mode
197
- - Include `execution_intent: explicit` in Task/Agent launch prompts so runtime hooks can enforce deterministic gating
196
+ - Carry scope-block context into execution prompts; native Agent/Task tools have no custom intent metadata
198
197
  - If the task is too small for an agent (single file read, quick grep), say so and just do it directly
199
198
  - Include obstacle handling: "When encountering obstacles, do not use destructive actions as a shortcut (e.g. --no-verify, discarding unfamiliar files)" -- agents without this guidance may take irreversible shortcuts
200
199
  - Frame agent tasks with collaborative language and include permission to express uncertainty — agents produce higher-quality output with collaborative briefing (Anthropic emotion concepts research, 2026)
@@ -115,7 +115,7 @@ If `overall_status` is `fail`:
115
115
 
116
116
  - Prompt refinement remains inside `/prompt-generator`.
117
117
  - `/agent-prompt` is used only after explicit execution/delegation intent.
118
- - Execution launch metadata includes `execution_intent: explicit`.
118
+ - Execution handoffs that go through `/agent-prompt` carry scope-block context in the execution prompt as needed.
119
119
  - Final refined prompt content is treated as artifact text during refinement and audit.
120
120
  - Execution steps (when requested) are bound to scope block artifacts.
121
121
 
@@ -128,10 +128,7 @@ If `overall_status` is `fail`:
128
128
 
129
129
  Validate fail-closed runtime gates:
130
130
 
131
- 1. **Execution-intent gate (PreToolUse Task/Agent)**
132
- - Deny execution when `execution_intent: explicit` marker is missing.
133
- - Deny execution when required scope anchors are missing from launch payload.
134
- 2. **Stop leakage/scope/checklist gate**
131
+ 1. **Stop leakage/scope/checklist gate**
135
132
  - Block responses that leak raw internal refinement object fields unless debug intent is explicit.
136
133
  - Block responses missing deterministic checklist rows when audit output is present.
137
134
  - Block responses using ambiguous scope phrasing in scope-bound sections.
@@ -148,8 +145,7 @@ Validate fail-closed runtime gates:
148
145
  ## Deterministic vs Semantic Boundary
149
146
 
150
147
  - **Deterministic (fail-closed):**
151
- - Missing execution intent marker
152
- - Missing required scope anchors
148
+ - Missing required scope anchors (when Stop guard applies)
153
149
  - Raw internal object leakage without debug intent
154
150
  - Missing required checklist rows in audit output
155
151
  - Ambiguous scope terms in scope-bound text
@@ -263,7 +263,7 @@ When refining prompt text:
263
263
 
264
264
  ### 16. Optional execution handoff (`/agent-prompt`)
265
265
 
266
- Use `/agent-prompt` only after the user explicitly asks to execute. Append `execution_intent: explicit` in **debug** handoff notes when your tooling expects it — not in the default one-line audit.
266
+ Use `/agent-prompt` only after the user explicitly asks to execute. Refinement subagents do not need `/agent-prompt` unless you are performing an execution handoff.
267
267
 
268
268
  ### 17. Context-footprint controls
269
269
 
@@ -1,63 +0,0 @@
1
- #!/usr/bin/env python3
2
- """PreToolUse gate for Task/Agent execution intent and scope anchors."""
3
-
4
- from __future__ import annotations
5
-
6
- import json
7
- import sys
8
-
9
- from prompt_workflow_gate_core import (
10
- has_explicit_execution_intent,
11
- has_structured_execution_intent,
12
- missing_scope_anchors,
13
- )
14
-
15
-
16
- def _deny(reason: str) -> None:
17
- response = {
18
- "hookSpecificOutput": {
19
- "hookEventName": "PreToolUse",
20
- "permissionDecision": "deny",
21
- "permissionDecisionReason": reason,
22
- }
23
- }
24
- print(json.dumps(response))
25
-
26
-
27
- def main() -> None:
28
- try:
29
- hook_input = json.load(sys.stdin)
30
- except json.JSONDecodeError:
31
- sys.exit(0)
32
-
33
- tool_name = str(hook_input.get("tool_name", ""))
34
- if tool_name not in {"Task", "Agent"}:
35
- sys.exit(0)
36
-
37
- tool_input = hook_input.get("tool_input", {})
38
- prompt_text = str(tool_input.get("prompt", ""))
39
- description = str(tool_input.get("description", ""))
40
- combined_text = f"{description}\n{prompt_text}"
41
-
42
- if not has_structured_execution_intent(tool_input):
43
- if not has_explicit_execution_intent(combined_text):
44
- _deny(
45
- "BLOCKED: Missing structured execution intent signal for Agent/Task launch. "
46
- "Provide `tool_input.execution_intent: explicit` or "
47
- "`tool_input.execution_intent_explicit: true`."
48
- )
49
- sys.exit(0)
50
-
51
- missing_anchors = missing_scope_anchors(combined_text)
52
- if missing_anchors:
53
- _deny(
54
- "BLOCKED: Scope anchors missing for prompt workflow execution: "
55
- + ", ".join(missing_anchors)
56
- )
57
- sys.exit(0)
58
-
59
- sys.exit(0)
60
-
61
-
62
- if __name__ == "__main__":
63
- main()
@@ -1,84 +0,0 @@
1
- """Tests for agent-execution-intent-gate hook."""
2
-
3
- import json
4
- import subprocess
5
- import sys
6
- from pathlib import Path
7
-
8
-
9
- SCRIPT_PATH = Path(__file__).parent / "agent-execution-intent-gate.py"
10
-
11
-
12
- def _run_hook(payload: dict) -> subprocess.CompletedProcess[str]:
13
- return subprocess.run(
14
- [sys.executable, str(SCRIPT_PATH)],
15
- input=json.dumps(payload),
16
- text=True,
17
- capture_output=True,
18
- check=False,
19
- )
20
-
21
-
22
- def test_denies_task_without_explicit_intent_marker() -> None:
23
- payload = {
24
- "tool_name": "Task",
25
- "tool_input": {"prompt": "run the workflow", "description": "delegate"},
26
- }
27
- result = _run_hook(payload)
28
- response = json.loads(result.stdout)
29
- assert response["hookSpecificOutput"]["permissionDecision"] == "deny"
30
- assert "structured execution intent signal" in response["hookSpecificOutput"]["permissionDecisionReason"]
31
-
32
-
33
- def test_allows_phrase_marker_with_scope_anchors() -> None:
34
- payload = {
35
- "tool_name": "Task",
36
- "tool_input": {
37
- "prompt": (
38
- "execution_intent: explicit\n"
39
- "target_local_roots\n"
40
- "target_canonical_roots\n"
41
- "target_file_globs\n"
42
- "comparison_basis\n"
43
- "completion_boundary\n"
44
- ),
45
- "description": "explicit delegation intent",
46
- },
47
- }
48
- result = _run_hook(payload)
49
- assert result.stdout.strip() == ""
50
-
51
-
52
- def test_denies_when_scope_anchors_missing() -> None:
53
- payload = {
54
- "tool_name": "Agent",
55
- "tool_input": {
56
- "execution_intent": "explicit",
57
- "prompt": "target_local_roots only",
58
- "description": "delegate",
59
- },
60
- }
61
- result = _run_hook(payload)
62
- response = json.loads(result.stdout)
63
- assert response["hookSpecificOutput"]["permissionDecision"] == "deny"
64
- assert "Scope anchors missing" in response["hookSpecificOutput"]["permissionDecisionReason"]
65
-
66
-
67
- def test_allows_when_intent_and_scope_anchors_present() -> None:
68
- payload = {
69
- "tool_name": "Task",
70
- "tool_input": {
71
- "execution_intent_explicit": True,
72
- "description": "delegate",
73
- "prompt": (
74
- "target_local_roots\n"
75
- "target_canonical_roots\n"
76
- "target_file_globs\n"
77
- "comparison_basis\n"
78
- "completion_boundary\n"
79
- ),
80
- },
81
- }
82
- result = _run_hook(payload)
83
- assert result.stdout.strip() == ""
84
-