← 2.1.16 Test inconclusive · runtime-test

Combo Test: Hook-Triggered Task Creation — runtime test

Hands-on runtime battle-test of Combo Test: Hook-Triggered Task Creation. Result: INCONCLUSIVE.

Hooks can create tasks by writing JSON to the task directory, enabling external automation to inject work into the Claude Code runtime—but ID collisions and JSON escaping require careful handling.

How It Works

A hook receives session_id via JSON stdin and writes task definitions to ~/.claude/tasks/{session_id}/{id}.json. TaskList scans this directory and picks up externally-created tasks, making it possible for automation scripts, agents, or CI systems to inject work without calling TaskCreate directly. The mechanism integrates into the runtime's task discovery pipeline with no special registration.

What the Test Found

The test created task-creator-hook.sh and confirmed the core claim: writing valid JSON to the task directory creates discoverable tasks. Hook invocation successfully passed session_id through stdin, and TaskList recognized the resulting task files. However, three critical limitations emerged during execution:

ID collision: The hook created task 27, but TaskCreate later assigned the same ID, overwriting the hook's task without warning. No built-in sequence coordination exists between hook-based ID assignment and the TaskCreate allocator.

JSON escaping failure: Nested quotes in metadata caused parsing failures. Manual JSON construction is error-prone; jq or a serialization library is needed.

Silent malformation: Invalid JSON was silently ignored by TaskList with no logging, making debugging difficult.

Recommended Pattern

Use high ID ranges (1000+) or UUIDs like hook-$(date +%s) to avoid collision with TaskCreate's sequence. For complex metadata, use jq or a JSON library rather than string interpolation to ensure valid output.

Why It Matters

Hook-based task creation enables decoupled automation: CI systems, event handlers, or orchestration scripts can queue work without implementing TaskCreate. The pattern is functionally validated, but production use requires explicit ID coordination and serialization discipline to avoid data loss.

Primary source
⎘ 2.1.16/tests/combo-05-hook-task-creation/TEST-RESULTS.mdverbatim from the corpus

Combo Test: Hook-Triggered Task Creation

Hypothesis

Hooks can create tasks by writing JSON to the task directory.

Test Setup

Created task-creator-hook.sh that:

  1. Reads session_id from JSON stdin
  2. Writes task JSON to ~/.claude/tasks/{session_id}/{id}.json

Results

Status: ✅ VALIDATED with caveats

What Works

  • Hooks receive session_id via JSON stdin (confirmed)
  • Writing valid JSON to task directory creates tasks
  • TaskList picks up externally-created tasks

What Doesn't Work

  • ID collision: Hook created task #27, TaskCreate also used #27 → overwrite
  • JSON escaping: Nested quotes in metadata caused parsing failure
  • No validation: Malformed JSON silently ignored by TaskList

Critical Finding: ID Collision

# Hook creates task 27
echo '{"id": "27", ...}' > ~/.claude/tasks/{session}/27.json

# Later, TaskCreate also assigns ID 27
TaskCreate(subject="foo")  # Overwrites hook task!

Recommended Pattern for Hooks

# Use high IDs (1000+) or UUIDs to avoid collision
TASK_ID="hook-$(date +%s)"  # or UUID

# Be careful with JSON escaping
# Use jq for complex metadata

Test Evidence

$ cat /tmp/task-creator-hook.log
Hook triggered at Thu Jan 22 23:52:36 PST 2026
Session ID: 4130c084-17b1-495b-b137-8c0b6cec9c8a
Created task 27 in /Users/ryanhunter/.claude/tasks/...

Task appeared in TaskList after fixing JSON formatting.

Evidence & receipt
◇ ed25519 receipt
idtest_c95dae56fbc5c9fcd56f2f1c
alged25519
pubkey9b87705613b1e2fd064d57fa75a6b679d2856ceafad6b1daa8f982493871b6dd
sig4e975348e575795750765e94d436168cc627da4ce1571b64f7c5e7400ad48d7445922031eef7412eb646fd174f193f75b16c4ccee80866b57ae07e2be768b502

Signed with an ed25519 key held off the repo. Anyone can verify against the published public key; nobody without the secret key can forge it. Click verify: it recomputes the signature in your browser. The signature proves integrity and authorship of this exact content — not a third-party timestamp or that the underlying claim is objectively true. signedAt is when the @f3/attest pipeline ran, not when the work happened; the evidence refs carry the source dates.

Connected