Semantic functions

The shipped semantic vocabulary, =/! sugar, arities, return types, and current limits.

Semantic operators are registered as jq functions, so gojq parses them inside ordinary jq constructs. ajq adds only the =~ and !~ surface sugar before parsing.

Function vocabulary

FunctionFormKindReturnsExecution status
sem_matchsem_match(value; "spec")predicatebooleanShipped
sem_classifysem_classify(value; "a"; "b"; …)bounded valueone label from the given labelsShipped
sem_extractsem_extract(value; "what")unbounded valuestringLimited: supported only in gated/interleaved fallback contexts
sem_scoresem_score(value; "spec")unbounded valuenumberLimited: supported in sort_by(...) three-phase placeholder mode and in gated/interleaved fallback contexts
sem_normsem_norm(value; "canonicalization spec")unbounded valuestringLimited: supported in group_by(...) three-phase placeholder mode and in gated/interleaved fallback contexts
sem_redactsem_redact(value; "redaction spec")unbounded valuestringLimited: supported only in gated/interleaved fallback contexts

The spec is a literal string in the query. Stream data is structurally fenced by the selected backend’s output constraints.

Kinds

KindMeaning
PredicateReturns true or false; typically used in select or if.
Bounded valueReturns one of a finite set declared at the call site.
Unbounded valueReturns a string or number with no finite output set. These shapes need bounded executor contexts or interleaved fallback; unsupported forms fail loudly.

Variadic implicit .

Every operator accepts both an explicit value and an implicit one. When the value argument is omitted, it defaults to .:

sem_match(.field; "spec")   # explicit value
sem_match("spec")           # value defaults to .

The implicit form is what makes raw-line mode ergonomic.

The =~ and !~ sugar

SurfaceDesugars to
X =~ "spec"sem_match(X; "spec")
X !~ "spec"`sem_match(X; “spec”)

The desugaring is performed by a jq-aware lexer, not a regular expression.

.users[] | select(.feedback =~ "angry/frustrated") | .id
# ≡
.users[] | select(sem_match(.feedback; "angry/frustrated")) | .id

Return-type discipline

Each semantic operator has a fixed output type: boolean, enum label, string, or number. Backends constrain model output with GBNF grammar or provider structured-output/schema features, so downstream jq receives a value of the expected shape when execution succeeds.

For sem_classify, the enum is exactly the label arguments at the call site:

sem_classify(.text; "billing"; "bug"; "feature")

That expression returns one of "billing", "bug", or "feature".

Scenario matrix

ScenarioInvocationStatus
Fuzzy filterselect(.msg =~ "auth failure")Shipped
Raw-line fuzzy filterselect(. =~ "stack trace") with -RShipped
Routing / labeling{route: sem_classify(.text; "billing"; "bug"; "feature")}Shipped
Semantic sort keysort_by(sem_score(.review; "positivity"))Limited, supported three-phase placeholder mode
Semantic grouping keygroup_by(sem_norm(.company; "canonical name"))Limited, supported three-phase placeholder mode
Gated semantic scoreselect(sem_score(.review; "positivity") > 0.8)Limited, uses interleaved fallback
Gated typed extractionselect(sem_extract(.raw; "years") != "")Limited, uses interleaved fallback
Gated semantic redactionselect(sem_redact(.notes; "PII") != .notes)Limited, uses interleaved fallback

sem_score and sem_norm are not general-purpose enrichment operators in 0.0.1. Use sem_score as a sort_by(...) key and sem_norm as a group_by(...) key when you want the three-phase executor. sem_extract and sem_redact have no supported three-phase context; use them only in a gated control-flow context. When an unbounded value result is used to prune control flow, such as a score comparison inside select or if, ajq may choose an interleaved fallback instead of the harvest/resolve/execute path. That fallback is bounded by the same backend, cache, and --max-calls controls, but its call count is not available as a three-phase harvest estimate.

Current grammar scope

There is no custom jq grammar. @classify(...)-style @ forms and infix transform operators such as ~> do not parse in gojq and are not shipped. Use the function-core forms above.