feat(stage-workingset): durable, replay-safe stage working set (slices 1-4)
Stage agents were spending most of their turn budget re-discovering files already known from prior stages/attempts. Root cause: nothing durable carries acquired knowledge across handoffs and retries. First four slices of the fix: - core:sourcedesc — new dependency-free module: describe(path, bytes) derives comment-free structural navigation metadata (module, bounded symbols, bounded imports, versioned format). Deliberately non-prose: descriptors are derived from agent-writable files and rendered into successor-stage context, so comments/docstrings/literals are excluded to close a prompt-injection channel. CAS post-image hash stays authoritative; descriptor is disposable navigation. - kernel retry-repair state (ContextFeedback): on retry, name the authoritative CAS images of files this stage already wrote so the agent patches them instead of re-reading to rediscover them. - kernel file-written manifest (SessionOrchestratorArtifacts): each produced file surfaced with its authoritative CAS image plus a comment-free structural descriptor (via core:sourcedesc, over recorded CAS bytes — replay-safe). - apps/server RepoMapIndexer: route the injected repo-map descriptor through the comment-free describe(). Previously scraped leading comments, which were embedded into L3 and surfaced verbatim to successor stages — an injection channel from one stage into the next. Structural facts (module + imports + symbols) remain as the retrieval signal. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -4,8 +4,13 @@ import com.correx.core.artifacts.kind.JsonSchema
|
||||
import com.correx.core.artifacts.kind.TypedArtifactSlot
|
||||
import com.correx.core.context.model.ContextLayer
|
||||
import com.correx.core.context.model.EntryRole
|
||||
import com.correx.core.events.events.FileWrittenEvent
|
||||
import com.correx.core.events.events.RefinementIterationEvent
|
||||
import com.correx.core.events.events.RetryAttemptedEvent
|
||||
import com.correx.core.events.events.ToolInvocationRequestedEvent
|
||||
import com.correx.core.events.events.ToolRequest
|
||||
import com.correx.core.events.types.ToolInvocationId
|
||||
import com.correx.core.approvals.Tier
|
||||
import com.correx.core.events.types.ArtifactId
|
||||
import com.correx.core.events.types.SessionId
|
||||
import com.correx.core.events.types.StageId
|
||||
@@ -50,6 +55,43 @@ class ContextFeedbackTest {
|
||||
assertTrue(entry.content.contains("tests failed: NPE in FooTest"), "content: ${entry.content}")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `retry repair state names authoritative CAS images of files this stage already wrote`() {
|
||||
val inv = ToolInvocationId("inv-1")
|
||||
val events = listOf(
|
||||
stored(
|
||||
payload = ToolInvocationRequestedEvent(
|
||||
invocationId = inv, sessionId = SessionId("s"), stageId = StageId("impl"),
|
||||
toolName = "file_write", tier = Tier.T2,
|
||||
request = ToolRequest(
|
||||
invocationId = inv, sessionId = SessionId("s"), stageId = StageId("impl"),
|
||||
toolName = "file_write", parameters = mapOf("path" to "frontend/src/hooks/queries.ts"),
|
||||
),
|
||||
),
|
||||
),
|
||||
stored(
|
||||
payload = FileWrittenEvent(
|
||||
invocationId = inv, sessionId = SessionId("s"), path = "frontend/src/hooks/queries.ts",
|
||||
postImageHash = "cafebabe", preExisted = true, timestampMs = 0,
|
||||
),
|
||||
),
|
||||
stored(
|
||||
payload = RetryAttemptedEvent(
|
||||
SessionId("s"), StageId("impl"), 2, 3,
|
||||
"build gate: queries.ts(39,3): error TS1005: '}' expected", gate = "execution",
|
||||
),
|
||||
),
|
||||
)
|
||||
val entry = buildRetryFeedbackEntry(events, StageId("impl"))!!
|
||||
assertTrue(entry.content.contains("## Retry repair state"), "content: ${entry.content}")
|
||||
assertTrue(entry.content.contains("gate 'execution'"), "content: ${entry.content}")
|
||||
assertTrue(
|
||||
entry.content.contains("frontend/src/hooks/queries.ts — CAS cafebabe"),
|
||||
"content: ${entry.content}",
|
||||
)
|
||||
assertTrue(entry.content.contains("do NOT re-read"), "content: ${entry.content}")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `retry entry for other stage is not returned for queried stage`() {
|
||||
val events = listOf(
|
||||
|
||||
Reference in New Issue
Block a user