symfonic.capabilities.prompting.compiler¶
compiler ¶
The prompt/context compiler: one entry point, one total sequence.
The sequence is fixed โ accept, validate, admit, resolve, gate, order, budget, region, freeze โ and there is exactly one implementation of it. A second pipeline would be the forbidden thing, however reasonable its motivation looked: the moment domain instructions, standing blocks, or hydrated memory each get their own assembler, ordering and cache decisions stop being decidable from one place, and the region boundary is where that failure shows up as a cache that never hits.
S01 (TA8.51) gave that sequence a second door, not a second pipeline.
:func:compile_prompt calls its sources and :func:compile_prompt_async awaits
them; every other step -- _prepare before the read and _finish after it
-- is the same function called with the same arguments from both, so no
ordering, gating, budget or region decision exists twice. The distinction is
the one thing to check when editing this module: a step that moves into either
door rather than into the shared pair is the second pipeline arriving.
Domain instructions are therefore not special-cased. They compile into the
pinned, platform-tier L0 contribution kernel.instructions and travel the
same eight steps as everything else, which is what makes "the system prompt is
in the cached prefix" a property of the pipeline rather than a coincidence.
compile_prompt ¶
Compile one prompt from one request. Reads sources; performs nothing else.
The synchronous door onto the one sequence. A contribution whose source
only offers aread is refused here by name (see
:func:~.sources.resolve_source) rather than dropped.
Source code in src/symfonic/capabilities/prompting/compiler.py
compile_prompt_async
async
¶
The same sequence, with step 4 awaited (S01, TA8.51).
This is not the forbidden second pipeline, and the difference is worth
stating because the module docstring above forbids one by name. A second
pipeline is a second place ordering, gating, budgeting and region planning
are decided; those steps are :func:_prepare and :func:_finish here, and
both doors call the same two functions with the same arguments. What
differs is one line: whether the source read is called or awaited. A
contribution's position in the prompt cannot depend on which door compiled
it, because neither door decides positions.
The alternative -- asyncio.run or a thread hop inside a synchronous
read -- was refused for the reason S01 states: it would block the loop
every turn, trading a missing port for a latency defect.