Mario Alexandre  ·  March 26, 2026  ·  auto-scatter prompt-hook sinc-llm

The Catch-22 That Almost Broke My Auto-Scatter System

This one hurt. I spent two days stuck in a loop. The auto-scatter hook is the tool I built to make every prompt better. It started breaking the prompts I used to fix it.

It was intercepting itself.

How It Started

The scatter hook was live and working. Every raw prompt going through Claude Code was intercepted. It was broken into sinc JSON and sent back as structured context. The token exchange rate was already dropping. Things looked good.

Then I saw a problem. The hook handled very short prompts badly. It guessed too much about context. It made CONSTRAINTS bands that were too tight. I wanted to fix that.

So I opened Claude Code and typed: "Fix the scatter hook. It is being too aggressive with CONSTRAINTS inference on short prompts."

The hook intercepted this prompt. Decomposed it. Produced a structured interpretation. That interpretation — shaped by the exact bug I was trying to fix — told the main model that the task was something slightly different from what I'd asked. The model made a change. The wrong change. The hook was now more broken.

I tried again. I typed: "Actually revert that. Now the hook is not inferring any CONSTRAINTS at all for one-word prompts."

The hook intercepted that prompt too. It was still broken. It gave the model a wrong picture. The model made another bad change.

I was stuck in a loop. Every fix attempt passed through the broken hook first. The model never got my real message.

The Deeper Problem

A self-referential trap happens when a system processes its own input. It is a known problem. I had not thought about it for the scatter hook. When I built it, it seemed safe. I told myself: the hook processes prompts, not the code that defines it. That was true. But I was using Claude Code to change that code, and Claude Code sends everything through the hook first.

My first fix was a special escape character. I would start a prompt with "!!" to tell the hook to skip it. That was a bad idea. I had to remember the escape every time. I kept forgetting. When I forgot, I was back in the loop.

The Real Fix

The real fix was to change the pass-through rule. No more magic escape character. The new rule is based on structure. If the input is already valid sinc JSON (it has the formula field, the T field, and the fragments array), the hook lets it through without scattering.

sinc-LLM — pass-through detection
x(t) = Σ x(nT) · sinc((t - nT) / T)
def is_sinc_json(text: str) -> bool:
    try:
        obj = json.loads(text.strip())
        return (
            "formula" in obj and
            "T" in obj and
            "fragments" in isinstance(obj.get("fragments"), list)
        )
    except:
        return False

Now, when I need to talk to the model about the hook itself, I write sinc JSON by hand. I build the 6 bands myself. I set CONSTRAINTS to say "do not modify the scatter_server.py CONSTRAINTS inference logic". Then I send that raw JSON. The hook sees the input is already structured. It passes it through. The model gets exactly what I wrote.

What This Revealed About System Design

Hitting this catch-22 early was actually useful. It made me build a real escape mechanism. I could not just assume the hook would always be safe. Any interceptor that touches all traffic needs a way to bypass itself. Without that, you cannot fix it when it breaks, not without outside tools.

The sinc JSON pass-through rule gave me a second benefit too: sub-agent communication. When one agent hands a task to another, it can write a fully structured sinc JSON prompt. The receiving agent's hook sees the structure and does not scatter it again. This experience added "MUST NOT double-scatter" as a formal rule in my system documentation.

Two days of pain. One clean structural fix. The hook has been stable ever since.

// Production AI Engineering

Build AI systems that hold up in production.

sinc-LLM designs, audits, and stabilises production AI infrastructure: from vendor evaluation and cost accountability to incident controls and MCP architecture.

See what we do →