Skip to main content

scat Categories

The scat field selects which AST node categories are actively hashed. This is Table I from the CS-MAST spec, reproduced in full.


Structural Categories

These categories select specific Babel node types.

lit — Literals

Babel AST node types: StringLiteral, NumericLiteral, BooleanLiteral, RegExpLiteral, NullLiteral, BigIntLiteral

Includes all static scalar values.

With val modifier: Hash(LiteralType + LiteralValue) — distinct hash per value
Without val: Hash(LiteralType) — all literals of the same type share a hash

// val active: "hello" ≠ "world"
scat: ['lit', 'val']

// val absent: "hello" == "world" (same type StringLiteral)
scat: ['lit']

:::note RegExpLiteral normalization Regex flags are sorted alphabetically before hashing: /foo/gi and /foo/ig produce the same hash. :::


id — Identifiers

Babel AST node types: Identifier, PrivateName, JSXIdentifier

Includes variable names, function names, and property access names.

With name modifier: Hash(NodeType + NodeName) — distinct hash per identifier name
Without name: Hash(NodeType) — all identifiers share one hash

// name active: 'x' ≠ 'y'
scat: ['id', 'name']

// name absent: 'x' == 'y'
scat: ['id']

:::warning Minification id with name is highly volatile under minification — minifiers rename identifiers, producing completely different signatures. Use without name for structure-only matching. :::


op — Operators

Babel AST node types: BinaryExpression, UnaryExpression, UpdateExpression, AssignmentExpression

Captures the specific behavior of operations.

With op_name modifier: operator symbol is included in the hash
Without op_name: only child structure matters

// op_name active: a+b ≠ a-b
scat: ['op', 'op_name']

// op_name absent: a+b == a-b (same structure)
scat: ['op']

Unary/Update operators (prefix vs postfix):

  • Prefix ++x: Hash("++" + argumentHash)
  • Postfix x++: Hash(argumentHash + "++")

decl — Declarations

Babel AST node types: VariableDeclaration, FunctionDeclaration, ClassDeclaration, ImportDeclaration

Retains structural context modifiers.

When active: node type (and for VariableDeclaration, the kind field) is included in the hash. This distinguishes let x = 1 from const x = 1.

When absent: node type is excluded from the hash (reduced form equations 9, 13, 16, 18).

:::info URR Collision Fix The decl category directly fixes the collision observed in the URR system: let x = 1 and const x = 1 now produce different signatures when decl is active. :::


loop — Control Flow / Loops

Babel AST node types: ForStatement, WhileStatement, DoWhileStatement, ForInStatement, ForOfStatement

Isolates block looping patterns.

Formula: Hash(NodeType + sortedActiveChildHashes)

Child hashes are sorted ASCII-ascending by their hex value before concatenation, then only children that are actively hashed (in the configured scat/sinc) are included.


cond — Conditionals

Babel AST node types: IfStatement, SwitchStatement, ConditionalExpression

Groups branching and decision-making patterns.

With val modifier: Hash(Hash(NodeType) + Hash(test) + Hash(consequent))
Without val: Hash(Hash(NodeType) + Hash(consequent))

Note the double-hashing — each component is SHA-256'd individually, then the outer hash is computed over the concatenation of those inner hashes. This is literal per the spec equations 20/21.

For SwitchStatement, test maps to discriminant and consequent to the cases array.


Cross-Cutting Modifiers

These codes do not select node types — they modify how other categories hash their data.

name — Node Name

Adds the name property to identifier hashes (affects the id category).

val — Node Value

Adds the value property to:

  • Literal hashes (affects the lit category)
  • Conditional test hashes (affects the cond category)

op_name — Operator Name

Adds the operator property to operator expression hashes (affects the op category).


sinc — Exact Node Inclusion

sinc lists specific Babel node type names to hash verbatim. The formula used is the same default Merkle propagation: sha256(nodeType + concat(childHashes)).

sinc: ['ReturnStatement', 'ThrowStatement']

Deduplication rule: If a node type named in sinc is already covered by an active scat category, the sinc entry is silently dropped (scat takes precedence).


Summary Table

CodeFormal NameBabel Node TypesModifier
litLiteralsString/Numeric/Boolean/RegExp/Null/BigIntLiteralval
idIdentifiersIdentifier, PrivateName, JSXIdentifiername
opOperatorsBinary/Unary/Update/AssignmentExpressionop_name
declDeclarationsVariableDeclaration, FunctionDeclaration, ClassDeclaration, ImportDeclaration
loopControl FlowFor/While/DoWhile/ForIn/ForOfStatement
condConditionalsIf/SwitchStatement, ConditionalExpressionval
nameNode Name(modifier)
valNode Value(modifier)
op_nameOperator Name(modifier)