The Context Tracker (tamper_framework/context.py) resolves the third critical bug: knowing which SQL clause a token belongs to. It walks the token stream maintaining clause state (SELECT, FROM, WHERE, and so on) and nesting depth, exposing a context.clause that transformation rules consult. This is what “context-aware” means in this framework, and it is the feature that lets the same operator be treated differently depending on where it appears.

The payoff is visible in the value-encoding rule. In SELECT * FROM users WHERE id>=5, the operator >= must be encoded (it is in WHERE, where the WAF is matching) but the * in the SELECT list must be left alone. A context-blind script cannot make that distinction and must either encode everything (breaking valid parts of the query) or nothing (failing to evade). With clause tracking, a rule declares allowed_clauses=[ClauseType.WHERE] and fires only there. The documented custom-transform example is exactly this pattern: a transform_func(token, context) that checks context.clause == ClauseType.WHERE and acts only inside the WHERE clause. Nesting-depth tracking extends the same idea into subqueries, where clause context has to be maintained per level.