<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Explanation on ajq — semantic jq</title><link>https://ricardocabral.github.io/ajq/docs/explanation/</link><description>Recent content in Explanation on ajq — semantic jq</description><generator>Hugo</generator><language>en-us</language><atom:link href="https://ricardocabral.github.io/ajq/docs/explanation/index.xml" rel="self" type="application/rss+xml"/><item><title>Split execution</title><link>https://ricardocabral.github.io/ajq/docs/explanation/split-execution/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ricardocabral.github.io/ajq/docs/explanation/split-execution/</guid><description>&lt;h2 id="the-observation"&gt;The observation&lt;/h2&gt;
&lt;p&gt;A real-world &amp;ldquo;AI data&amp;rdquo; query is mostly &lt;em&gt;not&lt;/em&gt; fuzzy. Consider triaging support tickets:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;cat data.json | ajq --backend local &amp;#39;.users[] | select(.feedback =~ &amp;#34;angry/frustrated&amp;#34;) | .id&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └────────┬───────┘ └────────────┬────────────┘ └┬┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; deterministic path semantic predicate proj
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (pure gojq) (LLM, per value) (pure gojq)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Iterating the array, projecting &lt;code&gt;.id&lt;/code&gt;, shaping the output — all of that is exact,
mechanical work that &lt;code&gt;jq&lt;/code&gt; already does perfectly. Only one operator, &lt;code&gt;=~&lt;/code&gt;, needs
judgement. The insight behind ajq is to treat that asymmetry as a first-class execution
strategy: &lt;strong&gt;run the deterministic majority through a real jq engine, and call a model only
for the fuzzy operators, on the smallest possible slices of data.&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>The determinism contract</title><link>https://ricardocabral.github.io/ajq/docs/explanation/determinism/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ricardocabral.github.io/ajq/docs/explanation/determinism/</guid><description>&lt;p&gt;ajq separates deterministic structure from semantic judgement.&lt;/p&gt;
&lt;h2 id="the-contract"&gt;The contract&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;The deterministic pipeline is &lt;strong&gt;byte-reproducible&lt;/strong&gt;. Semantic judgements are
&lt;strong&gt;structurally&lt;/strong&gt; guaranteed, but their values are model- and cache-dependent.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Those are different promises.&lt;/p&gt;
&lt;h3 id="deterministic-parts-are-byte-reproducible"&gt;Deterministic parts are byte-reproducible&lt;/h3&gt;
&lt;p&gt;Every part of a query that is not a semantic operator runs through pure gojq. Given the
same input, it produces the same output bytes. There is no model, no sampling, and no
network in that path.&lt;/p&gt;</description></item><item><title>The three-phase executor</title><link>https://ricardocabral.github.io/ajq/docs/explanation/three-phase-executor/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ricardocabral.github.io/ajq/docs/explanation/three-phase-executor/</guid><description>&lt;p&gt;ajq runs supported semantic queries in three phases. For NDJSON and raw streams, the
unit of work is a bounded window of complete frames rather than the complete stream.&lt;/p&gt;
&lt;h2 id="the-three-phases"&gt;The three phases&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Phase 1 HARVEST pure gojq run; semantic ops in COLLECT mode gather every
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; (op, spec, value) they observe. Permissive returns.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Phase 2 RESOLVE dedup collected values, consult/write the judgement cache,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; and resolve misses through the selected backend.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;Phase 3 EXECUTE pure gojq run; semantic ops in LOOKUP mode return resolved
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; values from cache. Deterministic given those cached values.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Phases 1 and 3 are pure gojq. Phase 2 is the isolated semantic boundary: it deduplicates,
checks cache identity, and calls the backend only for misses.&lt;/p&gt;</description></item><item><title>Architecture</title><link>https://ricardocabral.github.io/ajq/docs/explanation/architecture/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ricardocabral.github.io/ajq/docs/explanation/architecture/</guid><description>&lt;p&gt;ajq is a small pipeline of components.&lt;/p&gt;
&lt;h2 id="data-flow"&gt;Data flow&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;stdin → [Reader/Framer] → [Desugar] → [gojq.Parse] → [Planner] ──→ [Explain]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; │
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; [3-phase Executor]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ gojq (deterministic)
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ Semantic Executor → [Backend iface]
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ mock
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ local daemon
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ ollama
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; ├─ openai / openrouter
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; └─ anthropic cloud
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;[Grammar/Schema builder] → GBNF / json_schema ─────────────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;stdout ← [Assembler / schema-invariance guard]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="the-components"&gt;The components&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Component&lt;/th&gt;
					&lt;th&gt;Responsibility&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Reader / Framer&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Stream framing: single JSON, NDJSON, and raw lines (awk-mode). Supported three-phase semantic input is grouped into complete-frame byte-budgeted windows; pure-jq and interleaved paths remain streaming.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Desugar&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Rewrites &lt;code&gt;=~&lt;/code&gt; / &lt;code&gt;!~&lt;/code&gt; into &lt;code&gt;sem_match&lt;/code&gt; calls with a jq-aware lexer.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Planner&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Exhaustive AST walk that discovers every semantic call site → a &lt;code&gt;Plan&lt;/code&gt; used for &lt;code&gt;--explain&lt;/code&gt;, validation, and cost estimation.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Executor&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Runs the plan in three phases (harvest / resolve / execute), with interleaved fallback for gated unbounded value ops.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Semantic Executor&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Deduplicates judgements, consults the persistent judgement cache when enabled, builds each op&amp;rsquo;s prompt and schema, and records run stats.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Backend&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Pluggable inference. Shipped backends: &lt;code&gt;mock&lt;/code&gt;, &lt;code&gt;local&lt;/code&gt; (llama-server daemon), &lt;code&gt;ollama&lt;/code&gt;, &lt;code&gt;openai&lt;/code&gt;, &lt;code&gt;openrouter&lt;/code&gt;, and &lt;code&gt;anthropic&lt;/code&gt;/&lt;code&gt;--cloud&lt;/code&gt;.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Grammar / schema builder&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Turns an op&amp;rsquo;s return type / enum into a JSON Schema and, for the local engine, GBNF grammar constraints.&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Assembler&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Reassembles the output stream and enforces schema invariance.&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="windowed-semantic-execution"&gt;Windowed semantic execution&lt;/h2&gt;
&lt;p&gt;For supported three-phase semantic queries, the executor retains one complete-frame window
at a time, harvests its semantic judgements, resolves deduplicated cache misses in one
backend batch, then executes frames in source order. The default source-byte budget is
256 KiB and can be overridden with &lt;code&gt;--window-bytes&lt;/code&gt;, &lt;code&gt;AJQ_WINDOW_BYTES&lt;/code&gt;, or
&lt;code&gt;window_bytes&lt;/code&gt; in TOML. A record that exceeds the budget is a valid one-frame oversized
window, so the budget is not a rejection limit. The executor does not retain the complete
stream: it keeps the current window, one lookahead frame, and bounded framing buffers.&lt;/p&gt;</description></item><item><title>Project status</title><link>https://ricardocabral.github.io/ajq/docs/explanation/project-status/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ricardocabral.github.io/ajq/docs/explanation/project-status/</guid><description>&lt;p&gt;ajq has shipped its deterministic jq spine, semantic planning and supported semantic
execution, local inference, bounded-parallel local daemon transport, Phase 3
backend/cloud controls, first-run local asset provisioning, local model management, the
persistent judgement cache, byte-budgeted semantic windows, an explicit low-latency
semantic stream mode, and checksummed release archives with a no-sudo install script.
Further streaming optimizations remain planned. The iterative-harvest experiment is an internal-only no-go prototype, not a shipped mode; default windowed execution is unchanged.&lt;/p&gt;</description></item><item><title>Iterative-harvest prototype evaluation</title><link>https://ricardocabral.github.io/ajq/docs/explanation/iterative-harvest-evaluation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://ricardocabral.github.io/ajq/docs/explanation/iterative-harvest-evaluation/</guid><description>&lt;h2 id="decision-no-go-for-productionization"&gt;Decision: no-go for productionization&lt;/h2&gt;
&lt;p&gt;The iterative-harvest implementation is an internal test and benchmark prototype. It is
&lt;strong&gt;not&lt;/strong&gt; a CLI mode, is not selected by default, and must not be enabled for users.
The existing &lt;code&gt;three-phase-windowed&lt;/code&gt; executor remains the default and unsupported query
shapes continue to use their existing windowed or planner-required interleaved fallback.&lt;/p&gt;
&lt;p&gt;This is a no-go even though the pruning workload clears its judgement-saving target. A
reachable error case found during characterization has different behavior from the current
windowed executor: after an earlier gate rejects a value, a backend result/schema/transport
error for that pruned descendant is dispatched and returned by permissive windowed harvest,
but is intentionally not dispatched by iterative harvest or interleaved execution. That
changes the reachable error, cache, and exit contract. Reducing calls by dispatching the
unreachable descendant would defeat the prototype&amp;rsquo;s purpose. Until a separate design
resolves that semantic/error boundary, the required current-window parity gate is not met.&lt;/p&gt;</description></item></channel></rss>