fix: keep supervisor reviews running until completion

Remove elapsed execution-budget pauses from extraction and navigation so long reviews no longer require repeated manual continuation. Remove the pause-duration setting and update activity copy and design documentation. Preserve explicit pause, saved batches, model timeouts and concurrency limits.

Validation: recorded 13 focused tests, typecheck and targeted ESLint passed; staged diff check passed. Tests were not rerun for this commit.

Release note: 监督回顾现在持续分批处理至完成,不再每隔固定时长自动暂停;仍可主动暂停并从已保存进度继续。
This commit is contained in:
mesalogo
2026-09-26 11:02:30 +08:00
parent e8d93b5bb6
commit e6ac0734de
13 changed files with 56 additions and 33 deletions
+17 -4
View File
@@ -86,18 +86,31 @@ it('reopens saved batches after failure, resumes exact Unicode offsets and only
expect(f.summarize).toHaveBeenCalledTimes(calls)
})
it('soft budget pauses without checkpointing and freezes configuration across continuation', async () => {
it('continues extraction and navigation beyond the saved execution budget', async () => {
const f = await fixture([['x'.repeat(2500)]], { concurrency: 1, executionSeconds: 30 })
const clock = vi.spyOn(Date, 'now').mockReturnValue(time)
f.summarize.mockImplementationOnce(async () => { clock.mockReturnValue(time + 31000); return empty })
const result = await f.service().run(request)
expect(result.status).toBe('completed')
expect(result.coverage).toMatchObject({ batches: 3, remainingSources: 0, complete: true })
expect(f.summarize).toHaveBeenCalledTimes(5)
expect(f.db.supervisionReviewStore().batches(result.runId!, 100).flatMap(row => row.evidence).map(row => row.content.length)).toEqual([1000, 1000, 500])
clock.mockRestore()
})
it('still pauses on user request and resumes saved batches without changing batch settings', async () => {
const f = await fixture([['x'.repeat(2500)]], { concurrency: 1 })
const service = f.service()
f.summarize.mockImplementationOnce(async () => empty).mockImplementationOnce(async () => {
service.pause(f.db.listSupervisionActivity()[0]!.id)
return empty
})
const result = await service.run(request)
expect(result.status).toBe('paused')
expect(result.coverage).toMatchObject({ batches: 1, remainingSources: 1, complete: false })
f.config.batchCharacters = 16000
const resumed = await f.service().resume(result.runId!)
expect(resumed.status).toBe('completed')
expect((await f.service().resume(result.runId!)).status).toBe('completed')
expect(f.db.supervisionReviewStore().batches(result.runId!, 100).flatMap(row => row.evidence).map(row => row.content.length)).toEqual([1000, 1000, 500])
clock.mockRestore()
})
it('rejects changed source versions and rolls back offsets when batch persistence fails', async () => {