fix(context): render the stage role prompt as the system prompt (#416)
The role prompt was an L1/USER entry, so PromptRenderer emitted it as a user turn behind the intent, decision journal, repo map and docs catalog, outranked by the pinned schemaInstruction it contradicts. It is now L0/SYSTEM and folds into the leading system message, and it sits directly after systemPrompt in assembly so it heads the system block rather than trailing schemaEntries. Extracted buildAgentPromptEntry so both the promptInline and prompt-path branches build the entry one way. Guard test mutation-verified. #416's finding 1 was wrong: the role prompt was never evictable. "agentPrompt" is already in REQUIRED_SOURCE_TYPES, and DefaultContextPackBuilder exempts REQUIRED entries from pruning at any layer. Layer was never the pinning mechanism here; message placement was the whole defect. Also pins groundingFeedback and recoveryTicket, the two feedback types that were neither REQUIRED nor in neverDropSourceTypes. The recovery stage exists only because of its ticket, so pruning the ticket left it nothing to repair. Not done: reconciling the pinned schemaInstruction ("respond with JSON only") against the role prompt's emit_artifact instruction, and live verification across analyst/architect/role_pipeline.toml. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import com.correx.core.events.types.StageId
|
||||
import com.correx.core.events.types.TransitionId
|
||||
import com.correx.core.events.events.RepoKnowledgeHit
|
||||
import com.correx.core.kernel.orchestration.buildAgentInstructionsEntry
|
||||
import com.correx.core.kernel.orchestration.buildAgentPromptEntry
|
||||
import com.correx.core.kernel.orchestration.buildArtifactKindVocabularyEntry
|
||||
import com.correx.core.kernel.orchestration.buildProjectProfileEntry
|
||||
import com.correx.core.kernel.orchestration.buildRelevantFilesEntry
|
||||
@@ -194,6 +195,19 @@ class ContextFeedbackTest {
|
||||
assertEquals("projectProfile", entry.sourceType)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `stage role prompt renders as the system prompt, not a user turn`() {
|
||||
// #416: as L1/USER this arrived as a user message behind the intent, journal, repo map and docs
|
||||
// catalog, outranked by the pinned schemaInstruction that contradicts it. Live session fced377e:
|
||||
// discovery never acknowledged its role and drifted into implementation.
|
||||
val entry = buildAgentPromptEntry("You discover. You do not implement.", StageId("discovery"), 7)
|
||||
assertEquals(ContextLayer.L0, entry.layer)
|
||||
assertEquals(EntryRole.SYSTEM, entry.role)
|
||||
assertEquals("agentPrompt", entry.sourceType)
|
||||
assertEquals("discovery", entry.sourceId)
|
||||
assertEquals("You discover. You do not implement.", entry.content)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `agent instructions render as single L0 entry`() {
|
||||
val entry = buildAgentInstructionsEntry(
|
||||
|
||||
Reference in New Issue
Block a user