refactor(toolintent): one SessionContext read-model for the gates

Replace the single-purpose sessionReadPaths plumbing with a SessionContext
{reads, writes, activeTask} folded by SessionContextProjection over the session
stream — the read-model every anti-hallucination gate consumes (plane-2 rules via
ToolCallAssessmentInput.session; tool gates via a port, next).

- reads: completions whose recorded capability includes FILE_READ.
- writes: the resolved paths the orchestrator already records on each completion's
  receipt.affectedEntities (FileAffectingTool) — no param-parsing reinvention.
- activeTask: null for now; populated once claim records a session fact.

ReadBeforeWriteRule now reads input.session.reads; ReadFilesProjection is retired.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 20:16:15 +00:00
parent 9b003d02ea
commit 47a109e49f
7 changed files with 89 additions and 86 deletions
@@ -69,7 +69,7 @@ import com.correx.core.events.events.ToolReceipt
import com.correx.core.events.events.ToolRequest
import com.correx.core.events.risk.RiskAction
import com.correx.core.events.risk.RiskSummary
import com.correx.core.toolintent.ReadFilesProjection
import com.correx.core.toolintent.SessionContextProjection
import com.correx.core.toolintent.ToolCallAssessmentInput
import com.correx.core.toolintent.ToolCallAssessor
import com.correx.core.toolintent.WorkspacePolicy
@@ -970,7 +970,7 @@ abstract class SessionOrchestrator(
paramRoles = tool?.paramRoles ?: emptyMap(),
writeManifest = writeManifest,
sessionEgressHosts = sessionEgressHosts,
sessionReadPaths = resolveSessionReadPaths(sessionId),
session = resolveSessionContext(sessionId),
),
)
emit(
@@ -1001,15 +1001,14 @@ abstract class SessionOrchestrator(
}
/**
* Folds this session's file_read tool events through [ReadFilesProjection] into the set of paths
* it has successfully read — the input to [com.correx.core.toolintent.rules.ReadBeforeWriteRule].
* Replay-safe (reads the log, never live state); empty before any read completes.
* Folds this session's tool events through [SessionContextProjection] into the read-model the
* anti-hallucination gates consume (reads, writes, active task). Replay-safe (reads the log,
* never live state); empty before anything has happened.
*/
internal fun resolveSessionReadPaths(sessionId: SessionId): Set<String> {
val projection = ReadFilesProjection(sessionId)
internal fun resolveSessionContext(sessionId: SessionId): com.correx.core.toolintent.SessionContext {
val projection = SessionContextProjection(sessionId)
return eventStore.read(sessionId)
.fold(projection.initial()) { acc, event -> projection.apply(acc, event) }
.readPaths
}
private suspend fun buildSchemaEntries(