* One-time-per-process check that seals any pre-boundary prefix left in * chat.jsonl. Newly written boundaries rotate eagerly at write time; this * lazily migrates files produced before rotation existed (or by crashes * between boundary write and rotation).
(workspaceId: string)
| 1022 | * between boundary write and rotation). |
| 1023 | */ |
| 1024 | private async ensureSealedHistoryRotated(workspaceId: string): Promise<void> { |
| 1025 | if (this.sealedRotationChecked.has(workspaceId)) { |
| 1026 | return; |
| 1027 | } |
| 1028 | this.sealedRotationChecked.add(workspaceId); |
| 1029 | |
| 1030 | try { |
| 1031 | // Cheap unlocked probe first so the common no-op case takes no lock. |
| 1032 | const offset = await this.findLastBoundaryByteOffset(this.getChatHistoryPath(workspaceId)); |
| 1033 | if (offset === null || offset === 0) { |
| 1034 | return; |
| 1035 | } |
| 1036 | await this.fileLocks.withLock(workspaceId, () => |
| 1037 | this.rotateSealedHistoryUnlocked(workspaceId) |
| 1038 | ); |
| 1039 | } catch (error) { |
| 1040 | // Rotation is an optimization — reads remain correct on unrotated files. |
| 1041 | log.warn("Failed to rotate sealed chat history", { |
| 1042 | workspaceId, |
| 1043 | error: getErrorMessage(error), |
| 1044 | }); |
| 1045 | } |
| 1046 | } |
| 1047 | |
| 1048 | /** |
| 1049 | * Move the sealed prefix of chat.jsonl (everything before the latest durable |
no test coverage detected