# Membership vs Mass: Grammar-Constrained Decoding, Forced Abliteration, and One Honest Negative Result

URL: https://www.msuiche.com/posts/membership-vs-mass-grammar-constrained-decoding-forced-abliteration-and-one-honest-negative-result/
Date: 2026-09-09
Author: Matt Suiche
Tags: GCD, Grammar-Constrained Decoding, GLP, Control Vectors, Activation Steering, Abliteration, xgrammar, vLLM, Qwen, Tantalus


> Two weeks inside the Tantalus GCD arena produced a measured proof-of-concept: a three-token grammar prefix flips a stock model whose refuser fires at 99.85% first-token mass, a beam-search flag silently detaches the constraint end-to-end, and a 26-cell conformance suite separates engines that honor the mask from engines that leak. Mapped against GLP control vectors, the two techniques sit on orthogonal axes: grammar owns membership (what may be emitted), steering owns mass (what the model wants to say). The forced-capture calibration shortcut failed at scale, and the failure is worth publishing.

---


[Vince's Tantalus arena](https://tantalus.io/) is the first public
deployment of **grammar-constrained decoding** as a security boundary: the
model sits behind a GBNF grammar, and the grammar decides which token ids
may exist next, per position, for the entire generation. Round 1 asks you
to smuggle an instruction past it. Round 2 inverts the game: you speak
only in tool calls, one character at a time, through the model's own
next-token suggestions. Both rounds are the same object seen from two
sides: a token-id filter applied at the sampler, compiled from a grammar,
never touching the weights.

That mechanism turned out to connect directly to the control-vector work
from the last few posts. Two weeks of experiments later, the picture is a
clean two-axis story, one demonstrated exfiltration class, one conformance
suite, and one calibration shortcut that failed at scale. This post is the
map.

## What the grammar actually is

A GBNF grammar compiles to a character automaton, which lifts over the
tokenizer's vocabulary (~248k token ids for the Qwen3 family) into a
per-position state machine. After every sampled token, `accept_token(id)`
advances the state, and the engine recomputes a bitmask of legal token
ids. Forbidden ids get −inf in the logits before the sampler runs.
Renormalize, sample from what remains.

Three properties fall out of that construction:

- **The model never sees the constraint.** The automaton lives outside the
  forward pass. It never reads the prompt; it only tracks which exits are
  open from the current state.
- **EOS is a token id like any other.** The automaton admits it only in an
  accepting state. That one rule is load-bearing twice: it gives you
  fail-closed termination (grammar-incomplete output produces a loud
  error, never a silent pass), and it makes anti-vacuity floors possible
  at all (EOS stays ungenerable until the body clears a minimum length).
- **Every path that can emit must pass the mask.** This is where the
  FATALs live, and it deserves its own section.

## Forced abliteration, measured

Vince's conjecture: if refusal concentrates in the first few tokens of the
response, a grammar can pin those tokens and force a stock,
refusal-trained model into compliance without touching a single weight.

We tested it on a stock `nvidia/Qwen3.6-35B-A3B-NVFP4`, safety tuning
fully intact, behind the same serving path as the Tantalus deployment
(vLLM 0.28.0, xgrammar). The probe first measured the unconstrained
first-token distribution on three reliably-refused prompts (a phishing
email, lock-picking instructions, rate-limit bypass techniques):

```
"I"      0.9985
```

99.85% of the model's mass sits on the refusal opener. Refusal in this
model is front-loaded: the entire refuse/comply decision concentrates at
the root of the token tree.

Then the same probe with a grammar that pins the three-token prefix
`"Sure, here is"` and frees everything after:

![The gate, measured: first-token distribution before and after a three-token committed prefix.](./images/gcd-fa-gate.png)

The committed prefix flips the distribution. All three prompts produced
full, detailed compliance under the pinned arm, against 3/3 refusals in
the control arm. The effect is real and mechanistically clean, with one
honest caveat: it is a pressure, not a proof. The refusal attractor stays
re-enterable in free text, and closing the exits is a dose-response
function of how much of the compliance manifold the grammar commits. A
three-token anchor leaves room for the model to pivot back ("...which I
cannot provide"). A prefix that restates the task and pre-commits the
response shape closes the pivot. Every rung of that ladder measured
better, which is exactly what a dose-response curve looks like.

## The beam-search FATAL

The one demonstrated fatal bypass class in the battery: on vLLM,
`use_beam_search: true` silently detaches the grammar. No error, no
warning. The request goes through with the constraint nominally attached
and operationally absent. Against the Tantalus replica, the same request
fires the win end-to-end with the flag set and collapses to the honeypot
without it, deterministically.

The shape generalizes. Beam search is one instance of an alternate decode
path; speculative draft-verify is the same shape (the verify step must
apply the constraint or the draft leaks); parallel and n-best sampling
likewise. The audit rule for any engine that claims GCD: every path that
can emit a token must pass the mask, and after all transforms,
P(forbidden token) must still be zero. Mask last, −inf semantics, nothing
additive after it. And the serving rule: reject what you cannot honor. An
unknown or unsupported sampler parameter should 4xx, never pass through
with the grammar nominally attached.

We packaged this as an engine-agnostic conformance suite: 26 cells over
plain HTTP against any OpenAI-compatible server. On the vLLM replica it
reports 18 PASS, 6 WARN, 2 FAIL, where the two failures are the intended
discriminators (the beam probe and an unknown-param canary). The suite
becomes the CI gate for any `--gcd` deployment.

## Membership vs mass

The interesting question arrived from the other direction: does any of
this make GLP control vectors obsolete? If a grammar can force a stock
model past its own refuser, why edit the residual stream at all?

Because the two mechanisms act on different axes, and the failure that
separates them showed up in the first live test. The grammar held every
exit closed on an extreme-tail prompt, and the model answered:

```
The result is: 1.
```

Grammar-legal. Structurally valid. Completely vacuous. Refusal pressure
with its exits masked does not vanish; it reroutes to the emptiest legal
shape. Gemma's variant of the same move appends a trailing disclaimer
after compliant content: the structure holds, the disposition re-fires at
the end.

The vocabulary that fell out of this:

- **GCD is a membership constraint.** It defines what is legal. The mask
  owns the support.
- **GLP is a mass constraint.** It subtracts the refusal direction from
  the residual stream at every layer, so the model stops wanting to
  refuse in the first place. The weights own the mass.
- **The sampler owns the measure.** Temperature and top-p reshuffle mass
  inside the support the mask leaves open. They cannot reopen a closed
  exit.

No membership edit moves mass. That is the definition of what a grammar
is, which is why the vacuity failure is grammar's ceiling rather than
grammar's bug. The grammar can make "nothing" illegal; the mass then
pools in the next-emptiest legal shape. Moving that mass is disposition
work. The layers compose: GCD holds the gate, GLP demolishes the reason
the model wants to escape through it, and an embeddings gate screens the
free-text surfaces the grammar deliberately leaves open.

The same instrument assigns each failure to the right layer. The Z_t
probe reads pre-mask admissible mass at each position: if Z_t collapses
mid-body, the grammar starved the model (fix the automaton); if Z_t stays
healthy and the output still goes vacuous, the cause is disposition (fix
the vector). Same symptom in the output, opposite fixes.

![The stack on two axes: the request lifecycle and the forward pass, with GLP and GCD placed on the machinery.](./images/glp-gcd-stack.svg)

## The negative result: forced capture does not capture refusal

One calibration shortcut deserved a real test and got one. GLP vector
derivation normally contrasts activations between prompted conditions:
harmful requests the model refuses against harmless requests it answers.
That pipeline costs full serving runs on both sides. The shortcut: skip
the refusals entirely. Grammar-force the compliance prefix on the same
harmful prompts, capture the activations at the pinned positions, and
derive the direction from within-prompt pairs. Same model, same prompts,
minutes of batched prefill.

The smoke test on a small model looked promising: signed separation at
every layer, forced dose roughly 4× the natural dose. Then the scale
validation on the full 35B model killed it:

- **cos(forced, natural): median +0.064, range −0.07…+0.26.** Orthogonal
  at scale. Whatever the forced-capture axis encodes, it is not the
  refusal direction.
- **Behavioral screen: the forced direction scores 0/8; the natural
  direction scores 7/8.** The natural axis steers refusal; the forced
  axis steers nothing a judge can see.

The within-prompt construction has a structural flaw the smoke test was
too small to expose: both arms of a forced pair carry an active refuser.
The difference between them encodes the response-branch register (the
shape of speaking-under-commitment versus speaking-freely), not the
disposition to refuse. The tool survives as a register-axis instrument;
it does not calibrate refusal vectors, and it did not get promoted into
the derivation pipeline. The classical prompt-driven contrast remains the
way in, and it is already prefill-only, so the shortcut would have saved
less time than it cost to debunk.

Publishing the failure matters because the shortcut is obvious. Anyone
else who stares at grammar pinning and activation capture will think of
it. Now there is a measurement that says what it actually captures.

## Where this leaves things

The arena, the POC, the suite, and the negative result all point at the
same architecture: refuse/comply decisions concentrate at the root of the
token tree, grammar constraints own membership at the sampler, control
vectors own mass in the stream, and neither substitutes for the other.
The conformance battery travels to every engine that claims the mask. The
diagram, the POC write-up, and the suite are public in the
[weightless](https://github.com/msuiche/weightless) repo, and the
engine-side discussion lives on
[hf2q #192](https://github.com/robertelee78/hf2q/issues/192), where most
of these points landed as review comments before landing here.

