pub fn build_prompt(
lesson: &Lesson,
submission: &Submission,
results: &ExecResults,
) -> PromptExpand description
Build the LLM feedback prompt for a graded submission.
Pure (§2.1): it reads only the borrowed domain values and performs no IO, env
read, or network call, so identical inputs always render byte-identically. The
layout is a fixed structure — the task, the lesson’s success_criteria when
present and non-blank (ADR-0020), a single fenced copy of the submission,
a captured-output section, and a check-results section (one line per outcome,
labeled with its lesson.checks entry by index) — not the lesson’s
llm_evaluation_prompt template (ADR-0006). results.outcomes is expected 1:1
with lesson.checks (the shape run_checks produces); the rendering never
silently drops a verdict if they desync (see render_checks). Every
interpolated value is neutralized, so the fences and labels each appear
exactly once even when the submission forges them: injected text can never be
read as code or as a verdict.