Feature: Expose thinking-block prefill to hooks/skills for enforcing protocol compliance

Resolved 💬 2 comments Opened Apr 11, 2026 by gWcyWoo Closed May 23, 2026

Summary

Allow PreToolUse hooks (and optionally skill metadata) to return a thinking_prefix string that gets prepended to the assistant's next thinking block as an assistant prefill on the following API call. This leverages the existing assistant-prefill primitive in the Anthropic API to move skill-protocol compliance from the message layer (where rules are advisory and drift under attention dynamics) to the reasoning layer (where they shape the very next token deterministically).

Problem

I've spent ~397 hours across 237 sessions building a skill-based workflow system on top of Claude Code (understand → write-tests → code pipelines, my-explore dispatchers, self-check author-side review rules, tool.md tool-selection references). Per my /insights report, my top work area by session count is skill & workflow engineering (16 sessions) — not because I enjoy meta-work, but because skill-protocol compliance keeps failing in a specific, reproducible way:

  • Claude reads a skill's rules, can cite them back, and still calls tools in violation of them (e.g., extract_code with a bare file path when the skill explicitly requires file#symbol or file:line anchors).
  • Fabricated thinking steps — Claude prints what the protocol expects to see instead of actually performing the reasoning. I've caught this repeatedly and had to force honest self-critique rather than accept surface-level output.
  • /insights friction clusters in wrong_approach (37) + misunderstood_request (23) — exactly the failure modes this proposal targets.
  • Iterative skill tightening (adding NEVER restrictions, reducing SKILL.md to a pure dispatcher, writing detailed tool-selection references) only marginally reduces drift, because interventions stay at the message level. The model sees the rule, then decides whether its next-token-routing attention actually passes through it at the decision instant. That routing is not under user control.

Existing mitigations all hit structural walls:

| Mechanism | Limit |
|---|---|
| System prompts / <system-reminder> tags | Compete with thousands of context tokens; drift is inherent to attention dynamics |
| PreToolUse (block-only) | Rejects bad calls but doesn't change the reasoning that produced them — the model retries, often with the same mistake |
| Subagent tool whitelists | Control availability, not correct usage of allowed tools |
| Post-hoc review (self-check, external reviewer agents) | Catches errors after the fact; doubles token cost; cannot prevent |

Proposal

Add a thinking_prefix return field to hook output. When a PreToolUse (or a new TurnStart) hook returns it, the harness includes it as an assistant prefill on the next API call, so Claude's next thinking block begins with the injected content and generation continues from there.

Sketch:

// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [{
      "matcher": "mcp__probe__extract_code",
      "hooks": [{
        "type": "command",
        "command": "node scripts/verify-anchor.js",
        "inject_thinking": true
      }]
    }]
  }
}

The hook script returns JSON:

{
  "thinking_prefix": "About to call extract_code with files=[\"src/foo.ts\"]. Per tool.md: the files entry must contain '#' (symbol) or ':' (line). Checking: 'src/foo.ts' contains neither. Therefore: ABORT this call and re-plan with a valid anchor.",
  "block": false
}

The harness then injects thinking_prefix as an assistant prefill on the next API call. Claude's next generation starts from this reasoning state — not after deciding whether to consider it.

Why this works when message-level prompts don't

The failure mode isn't "doesn't know the rule." It's "the rule is in context but the reasoning path didn't route through it at the decision instant." Prefilled thinking bypasses the routing problem by making the rule the literal starting state of the reasoning. The next token is generated from the rule, not after evaluating whether to apply it.

This primitive already exists in the Anthropic API. Assistant-role messages with partial content ("assistant prefill") are a stable, documented feature widely used for output shaping. Claude Code simply doesn't expose it to hook authors today. The request is a Claude Code surface-level addition, not a model-capability research item. Implementation cost is low relative to impact.

Alternatives considered

  1. Stronger prompts / system reminders — tried extensively over 16 dedicated skill-engineering sessions; drift persists.
  2. Subagent tool whitelists — already in use (e.g., removing Bash/Edit/Write from exploration subagents via physical tool removal). Controls availability, not correctness of usage.
  3. Post-hoc review agents — doubles cost, catches errors too late, cannot prevent.
  4. Hook-based tool-call rejection — forces retries but does nothing to change the reasoning that produced the bad call, so the retry often repeats the error.

None address the root cause: reasoning at the decision instant is not currently under user control.

Impact

Users investing in skill-based workflows build methodology that currently rests on the hope that the model self-applies it. My /insights footprint: 1,371 markdown files authoring specs/skills/rules, 16 dedicated skill-engineering sessions in one month, 397 total hours across 237 sessions, friction concentrated in wrong_approach + misunderstood_request — the exact failure modes this proposal targets.

Exposing thinking prefill would convert existing methodology from advisory to enforced — every existing skill file becomes immediately more reliable, no rewriting required, because skills already encode the rules; they just need a channel to inject them at the right layer.

Scope

  • Minimal: add thinking_prefix return field to PreToolUse hook output schema; harness forwards as assistant prefill on the next API call. Enforce a length cap (e.g. 512 tokens) to prevent runaway prefills.
  • Extended: SKILL.md frontmatter can declare static or templated thinking prefixes per skill stage.
  • Long-term: expose thinking prefill as a first-class primitive in the Agent SDK so third-party harnesses can use it.

Failure modes / caveats

  • Loose prefixes can be gamed. A vague "consider the rule" prefix lets the model write "✓ considered" without actually considering. Effective prefixes must be mechanical and terminalcurrent value = A, rule = B, therefore next action = C — leaving only the next concrete step to generate. This is a prompt-craft constraint on hook authors, not an architectural issue.
  • Requires the hook to know the current skill stage. Easier for linear dispatcher-style skills (understand → my-explore → code) than for free exploration. A stage-tracking helper would benefit this.
  • Prefill counts against context budget. Prefixes should be short; harness should enforce a cap.
  • Not a substitute for tool whitelists or blocking hooks. This is a complementary mechanism. The ideal enforcement stack uses all three (whitelist + block + thinking prefill) at different layers.

Why this isn't a one-user niche

Among Claude Code users who invest in skill-based workflows, message-layer approaches appear to be hitting a wall simultaneously. The public ecosystem of skill collections (dispatcher patterns, pre-flight checklists, NEVER-clause restrictions, tool-selection references) all show the same shape: they encode rules carefully, then lose enforcement at the decision instant. The next unit of progress for this user segment requires a new enforcement layer, and assistant prefill is the lowest-cost candidate because the underlying API primitive is already built.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗