fix(kernel): llm-emitted artifacts require stored content — close phantom path
emitLlmArtifacts previously emitted ArtifactCreated/Validating/Validated for every llm-emitted slot unconditionally, fabricating "validated" artifacts when the model produced no content. Gate now mirrors the F-015 file_written check: slots with null or blank cached content are skipped with a warn log. Regression test added in NeedsArtifactInjectionTest verifies no artifact events appear for a blank-response stage.
This commit is contained in:
+11
@@ -1158,6 +1158,17 @@ abstract class SessionOrchestrator(
|
||||
stageConfig.produces
|
||||
.filter { it.kind.llmEmitted }
|
||||
.forEach { slot ->
|
||||
// Same rule as the file_written gate (F-015): no stored content means the
|
||||
// model never produced this artifact — do not fabricate a validated one.
|
||||
val cached = artifactContentCache["${sessionId.value}:${slot.name.value}"]
|
||||
if (cached.isNullOrBlank()) {
|
||||
log.warn(
|
||||
"[Orchestrator] stage={} slot={}: no content stored — skipping artifact emission",
|
||||
stageId.value,
|
||||
slot.name.value,
|
||||
)
|
||||
return@forEach
|
||||
}
|
||||
emit(sessionId, ArtifactCreatedEvent(slot.name, sessionId, stageId, schemaVersion = 1))
|
||||
emit(sessionId, ArtifactValidatingEvent(slot.name, sessionId, stageId))
|
||||
emit(sessionId, ArtifactValidatedEvent(slot.name, sessionId, stageId))
|
||||
|
||||
Reference in New Issue
Block a user