SIGN IN SIGN UP

fix: [ENG-2858] tool-mode dream — code-quality, BM25 query, undo via dream-log

Address findings from /brv-code-quality and the comprehensive e2e test pass:

Code-quality:
- Guard finalizeDreamSession against agent-supplied path traversal via
  isDescendantOf; new skip reason "unsafe-path"
- Drop `as (typeof VALID_KINDS)[number]` cast in brv dream scan kinds
  validation; switch VALID_KINDS to readonly string[]

BM25 query fix:
- Extract findBM25Pairs shared helper from link/merge candidate generators
  (bm25-pair-discovery.ts) so both kinds use one symmetric-pair pipeline
- Change query construction from `title + summary` to `title` only —
  appending the summary made the query so specific that BM25 ranked only
  the source topic itself, so link/merge returned 0 candidates in practice.
  Regression test added in link-candidates.test.ts.

Undo via dream-log:
- Add optional previousTexts: Record<string,string> to PruneOperationSchema
  so tool-mode dream finalize can record content inline without needing
  the archive-service stub-file indirection
- finalizeDreamSession now reads each file before the rename and returns
  previousTexts alongside archived/skipped
- agent-process dream-finalize handler writes a completed DreamLogEntry
  with one PRUNE/ARCHIVE op per archived file, updates DreamState.lastDreamLogId
  + bumps totalDreams (under the existing per-file mutex)
- undoPrune branches: when previousTexts is present it restores the body
  to the original path under contextTreeDir and unlinks the .brv/archive/
  copy; legacy archiveService.restoreEntry path still works for LLM-driven
  prune ops via stubPath
N
Nguyễn Thuận Phát committed
2cb2bf3245400ef8e7823e866d6bbb98bda28b3b
Parent: d8197ef