Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Config Format

The config format is shared across all five implementations. Same JSON/YAML structure, same semantics.

MatcherConfig

Top-level config for a matcher:

{
  "matchers": [ ... ],
  "on_no_match": { ... }
}
FieldTypeRequiredDescription
matchersarray of FieldMatcherConfigYesField matchers evaluated in order
on_no_matchOnMatchConfigNoFallback when no field matcher matches

FieldMatcherConfig

A single rule: predicate + action:

{
  "predicate": { ... },
  "on_match": { ... }
}
FieldTypeRequiredDescription
predicatePredicateConfigYesCondition to evaluate
on_matchOnMatchConfigYesWhat to do when predicate matches

PredicateConfig

Boolean logic over conditions. Discriminated by type:

single

Extract a value and match it:

{
  "type": "single",
  "input": { "type_url": "xuma.test.v1.StringInput", "config": { "key": "method" } },
  "value_match": { "Exact": "GET" }
}
FieldTypeRequiredDescription
type"single"YesDiscriminator
inputTypedConfigYesData input reference (resolved via registry)
value_matchValueMatchOne ofBuilt-in string match
custom_matchTypedConfigOne ofCustom matcher via registry

Exactly one of value_match or custom_match must be set.

and

All child predicates must match:

{
  "type": "and",
  "predicates": [ { "type": "single", ... }, { "type": "single", ... } ]
}

or

Any child predicate must match:

{
  "type": "or",
  "predicates": [ { "type": "single", ... }, { "type": "single", ... } ]
}

not

Negate a predicate:

{
  "type": "not",
  "predicate": { "type": "single", ... }
}

OnMatchConfig

Either a terminal action or a nested matcher. Discriminated by type:

action

Return a value:

{ "type": "action", "action": "route-get" }

The action field can be any JSON value – string, number, object. The engine doesn’t interpret it.

matcher

Continue evaluation with a nested matcher:

{
  "type": "matcher",
  "matcher": {
    "matchers": [ ... ],
    "on_no_match": { ... }
  }
}

Action XOR matcher – never both. This enforces OnMatch exclusivity from the xDS spec.

TypedConfig

Reference to a registered type:

{ "type_url": "xuma.test.v1.StringInput", "config": { "key": "method" } }
FieldTypeRequiredDescription
type_urlstringYesRegistered type identifier
configobjectNo (defaults to {})Type-specific configuration

The type_url is resolved at load time via the Registry. Unknown type URLs produce an error listing available types.

ValueMatch

Built-in string matchers:

{ "Exact": "hello" }
{ "Prefix": "/api" }
{ "Suffix": ".json" }
{ "Contains": "admin" }
{ "Regex": "^Bearer .+$" }
VariantMatches
ExactExact string equality
PrefixString starts with value
SuffixString ends with value
ContainsString contains value
RegexRE2 regex pattern (linear time)

Type URL Reference

Core (all domains)

Registered by register_core_matchers() in all implementations:

Type URLTypeConfig
xuma.core.v1.StringMatcherInputMatcherStringMatchSpec
xuma.core.v1.BoolMatcherInputMatcher{ "value": true }

Test Domain

Type URLConfigExtracts
xuma.test.v1.StringInput{ "key": "method" }Value for key from test context

HTTP Domain

Type URLConfigExtracts
xuma.http.v1.PathInput{}Request path
xuma.http.v1.MethodInput{}HTTP method
xuma.http.v1.HeaderInput{ "name": "content-type" }Header value by name
xuma.http.v1.QueryParamInput{ "name": "page" }Query parameter by name

Claude Domain

Type URLConfigExtracts
xuma.claude.v1.EventInput{}Hook event name (e.g. PreToolUse)
xuma.claude.v1.ToolNameInput{}Tool name (e.g. Bash)
xuma.claude.v1.ArgumentInput{ "name": "command" }Tool argument by name
xuma.claude.v1.SessionIdInput{}Session ID
xuma.claude.v1.CwdInput{}Working directory
xuma.claude.v1.GitBranchInput{}Git branch

Full Examples

HTTP Route Matching

matchers:
  - predicate:
      type: and
      predicates:
        - type: single
          input: { type_url: "xuma.http.v1.PathInput", config: {} }
          value_match: { Prefix: "/api" }
        - type: single
          input: { type_url: "xuma.http.v1.MethodInput", config: {} }
          value_match: { Exact: "GET" }
    on_match: { type: action, action: "api_read" }

  - predicate:
      type: single
      input: { type_url: "xuma.http.v1.HeaderInput", config: { name: "content-type" } }
      value_match: { Exact: "application/json" }
    on_match: { type: action, action: "json_handler" }

on_no_match: { type: action, action: "not_found" }

Claude Code Hook Policy

matchers:
  - predicate:
      type: and
      predicates:
        - type: single
          input: { type_url: "xuma.claude.v1.EventInput", config: {} }
          value_match: { Exact: "PreToolUse" }
        - type: single
          input: { type_url: "xuma.claude.v1.ToolNameInput", config: {} }
          value_match: { Exact: "Bash" }
        - type: single
          input: { type_url: "xuma.claude.v1.ArgumentInput", config: { name: "command" } }
          value_match: { Contains: "rm -rf" }
    on_match: { type: action, action: "block" }

  - predicate:
      type: single
      input: { type_url: "xuma.claude.v1.EventInput", config: {} }
      value_match: { Exact: "PreToolUse" }
    on_match: { type: action, action: "allow" }

on_no_match: { type: action, action: "allow" }

Test Domain (key-value)

matchers:
  - predicate:
      type: and
      predicates:
        - type: single
          input: { type_url: "xuma.test.v1.StringInput", config: { key: "method" } }
          value_match: { Exact: "GET" }
        - type: single
          input: { type_url: "xuma.test.v1.StringInput", config: { key: "path" } }
          value_match: { Prefix: "/api" }
    on_match: { type: action, action: "api_get" }

  - predicate:
      type: single
      input: { type_url: "xuma.test.v1.StringInput", config: { key: "path" } }
      value_match: { Exact: "/health" }
    on_match: { type: action, action: "health" }

on_no_match: { type: action, action: "not_found" }

Validation Limits

Configs are validated at load time:

LimitValueError
Max nesting depth32 levelsDepthExceeded
Max field matchers per matcher256TooManyFieldMatchers
Max predicates per AND/OR256TooManyPredicates
Max pattern length8192 charsPatternTooLong
Max regex pattern length4096 charsPatternTooLong

If a config loads successfully, the resulting matcher is guaranteed to be structurally valid. Parse, don’t validate.