Compare commits

...

1 Commits

Author SHA1 Message Date
Aiden Cline f6b9f8ba75 fix(core): preserve compaction after revert 2026-08-10 20:31:58 +00:00
2 changed files with 56 additions and 16 deletions
+21 -16
View File
@@ -769,22 +769,27 @@ const layer = Layer.effect(
{ location: current.location },
)
}),
compact: Effect.fn("Session.compact")(function* (input) {
yield* result.get(input.sessionID)
const inputID = input.id ?? SessionMessage.ID.create()
const admitted = yield* SessionPending.admitCompaction(db, bus, {
id: inputID,
sessionID: input.sessionID,
}).pipe(
Effect.catchDefect((defect) =>
defect instanceof SessionPending.LifecycleConflict
? new CompactionConflictError({ sessionID: input.sessionID, inputID })
: Effect.die(defect),
),
)
yield* execution.wake(input.sessionID)
return admitted
}),
compact: Effect.fn("Session.compact")((input) =>
Effect.uninterruptible(
Effect.gen(function* () {
const session = yield* result.get(input.sessionID)
if (session.revert) yield* SessionRevert.commit(session).pipe(Effect.provideService(Bus.Service, bus))
const inputID = input.id ?? SessionMessage.ID.create()
const admitted = yield* SessionPending.admitCompaction(db, bus, {
id: inputID,
sessionID: input.sessionID,
}).pipe(
Effect.catchDefect((defect) =>
defect instanceof SessionPending.LifecycleConflict
? new CompactionConflictError({ sessionID: input.sessionID, inputID })
: Effect.die(defect),
),
)
yield* execution.wake(input.sessionID)
return admitted
}),
),
),
wait: Effect.fn("Session.wait")(function* (sessionID) {
yield* result.get(sessionID)
yield* execution.awaitIdle(sessionID)
@@ -118,4 +118,39 @@ describe("Session.compact", () => {
expect((yield* session.context(created.id)).find((message) => message.id === first.id)).toBeUndefined()
}),
)
it.effect("commits a staged revert before admitting manual compaction", () =>
Effect.gen(function* () {
requests = []
const session = yield* Session.Service
const bus = yield* Bus.Service
const created = yield* session.create({ location })
const boundary = SessionMessage.ID.create()
yield* bus.publish(SessionEvent.InputAdmitted, {
sessionID: created.id,
inputID: boundary,
input: {
type: "user",
data: { text: "Discard this turn." },
delivery: "steer",
},
})
yield* bus.publish(SessionEvent.InputPromoted, {
sessionID: created.id,
inputID: boundary,
})
yield* bus.publish(SessionEvent.RevertEvent.Staged, {
sessionID: created.id,
revert: { messageID: boundary, files: [] },
})
const compacted = yield* session.compact({ sessionID: created.id })
expect((yield* session.get(created.id)).revert).toBeUndefined()
expect(yield* session.context(created.id)).toEqual([])
expect(yield* SessionPending.compaction((yield* Database.Service).db, created.id)).toMatchObject({
id: compacted.id,
})
}),
)
})