The contract layer. A consumer can read this folder and learn the whole warm surface without opening an engine: which requests are answerable warm, what shapes come back, what bounds a run, and the one candidate walk every face runs through.
The faces that turn those candidates into bytes, sets, or records live next
door in ../facet/.
answer.zigcarries the answer and budget vocabulary every face shares:QueryError(onlyStaleandOutOfMemory, which is the fail-closed contract), the answer shapes (Result,Lines,MatchRecord), and the cooperative bounds a hosted run carries (CancelToken,RunBudget, and theCeilingwhose clock read is sampled per stride so a wall-clock backstop costs nothing in the hot walk). Re-exported byresident.zig, soresident.MatchRecordandanswer.MatchRecordare one type.request.zigis the eligibility classifier. It accepts the supported argv surface — a bare pattern (→lines),-l/-c,-F,-P/--pcre2(or--engine), the last-wins case family-i/-s/-S,-w,-v,-q,-m N/--max-count N(incl.-m0),-n/-N,-e/--regexp,-A/-B/-Ccontext windows,-g/-tglob and type scoping (including the--docs/--code/--datagenus flags),--rank[=N]on its own narrow surface, and a clean repo-root-relative PATH root or subtree — and declines everything else toerror.Unsupported(cold fallback).Request.effectiveIgnoreCaseis the single smart-case resolution site:-Sfolds viaargs.hasUpperat the compile seam, so clients ship the raw bit and never re-implement the fold.gather.zigis the candidate walk all four faces share: compile the request through the shared search core, prune through the same three-stage stack cold prunes by (the conjunctive cover plan, then the crest sieve over the mirror's per-doc ρ(d), then the path filter — see below), then visit the surviving base docs plus the sieved overlay under one budget and ceiling — with the per-match existence stat applied on every path the watcher has not proven clean, so a delete racing the walk→report window is never reported.keep.zigis the answer keep: rendered stdout and exit code held against a corpus change epoch, for the questions no index can make cheap. Everything above answers a query faster; this one declines to answer it twice. The daemon never computes here — a client computes cold and offers the result, and the keep only compares epochs and evicts by LRU against a byte ceiling, so a store that cannot recompute cannot recompute wrongly. See the face package'ssrc/surface/cli/reprise.zigfor the caller's half.
request_test.zig sits beside its subject.
A Ceiling overrun declines the query (freshness_unprovable → the
certified cold path); a RunBudget trip is a clean partial stop that
keeps whatever was gathered.
One is the daemon's liveness backstop, the other a hosted caller's cooperative halt, and conflating them would either abandon good results or serve an answer the session cannot vouch for.
gather.candidateIds is the resident twin of cold's read-elision oracle
(../../cold/quarry/elide.zig), and it asks
the same questions in the same order — cheap-and-strong first:
- The index, asked the strongest question the pattern forces: the
conjunctive cover plan, else the flat OR of the sound prefilter literals.
That is cold's
askIndexprecedence including its fall-through — a plan the postings cannot witness declines to the weaker question rather than to an empty answer. - The crest sieve over the mirror's per-doc crest vectors, which prunes
the one class the trigram index concedes outright: a literal-free class
repetition like
[0-9a-f]{8}forces no trigram at all, so before this the session read 100% of the corpus for it. - The path filter, last because it is the only stage that touches strings.
Each is a necessary condition on matching, so dropping any one can only widen the candidate set — never drop a match.
The sieve then rides Candidates into the overlay, which no index tier can
speak for: those docs changed since the build, which is exactly what the
postings no longer describe. It is the one stage where warm prunes something
cold cannot. Cold's vectors are persisted, so its oracle must refuse any file
whose timestamps fail to prove it unchanged — and having read such a file it may
as well search it. A resident overlay entry is different: mirror.readDocOwned
already holds and scans those bytes, so ρ(d) costs one more pass over a body
already in hand (32 B/entry) and then amortizes over every later query.
Read that as a consistency property, not a speed one. The overlay is bounded by construction — it holds the mutation set since the last build, and a divergence large enough to matter makes the session reload or decline rather than accumulate — so the scan it saves is a modest number of documents, measured below the noise floor of process spawn plus the freshness walk. What the stage buys is that both halves of one walk now decide what deserves reading by the same rule.
Both AST-derived prunings come off ONE parse
(../../../kernel/query/prefilter.zig's
winnow, which cold's Writ also calls), and both stand down where they
would be unsound: a caseless pattern keeps its case-variant filter, and a
-F literal or a PCRE2 body arrives with a null source, which is the
standing "do not re-parse" certificate.
<prefix>NO_COVER / <prefix>NO_CREST stand one half down each. They are
read in the daemon's environment, not the client's, since that is where
the pruning is derived — which is what lets one binary A/B the wired path
against itself (the face package's
bench/conformance/gates/parity/warm_parity.sh runs two daemons on two
sockets for exactly this reason). The .index lens reports the tier that
answered and how much each stage admitted, in the same grammar cold uses,
and it rides the diag frame back to the client's stderr.
request.zig is the single argv authority: the face package's CLI client,
auto-spawn, and warm hints all reach it through this library's
session.request export.
Python's session.warm_eligible field predicate is the one cross-language
projection mechanically parity-tested against the built classifier — the
suite lives in the face package's
bindings/python/tests/test_classify_parity.py, driven through the warm
trace lens (<prefix>TRACE=warm) [eligible]/[ineligible] verdict, so the
two cannot drift unnoticed. The Rust binding carries its own warm_eligible
beside the daemon client (bindings/rust/src/runtime/session.rs), kept in
step with classify by comment rather than by the same mechanical proof.