0.134.30

Fixed (DEFERRED-задачи §3.2 Agent/Tools, см. docs/audit/backend-2026-06.md §3.2)

  • H-T-8 ApprovalManager.Resolve TOCTOU race — m.mu.RLock() удерживается до захвата pa.mu.Lock(), устраняя окно гонки. RequestApproval success/timeout пути устанавливают pa.done = true под pa.mu. Добавлены 8 тестов с -race.
  • H-T-5 decryptPassword в EmailSendTool/EmailInboxTool — при ошибке secrets.Decrypt логирует через slog.Error и возвращает "" вместо зашифрованного текста.
  • H-T-4 EmailSendTool.attachPathsNewEmailSendTool принимает *FsGuard. При наличии guard путь валидируется через ResolveAndCheckRead() (workspace boundary, blocked devices, symlink protection). RegisterToolsFromPermissions возвращает *FsGuard для проброса.
  • H-T-3 ToolStreamEvent channel — добавлена sendStreamEvent(ctx, ch, evt) с context-aware select { case ch<-evt | case <-ctx.Done() }. Все блокирующие записи в ExecuteStream и web_fetch.go заменены. Producer не зависает при отменённом контексте.
  • H-T-7 memoryToolBase.embedQuery — добавлен helper, устраняющий дублирование embedder.Embed(ctx, []string{query}) в 3 методах MemorySearchTool.
  • H-T-6 memory_search N+1 — добавлены batch-методы GetFactsByIDs/GetChunksByIDs/GetEntitiesByIDs в Store (SQLite + PG + DualStore). Render-циклы переписаны на batch fetch. filterFactsByCategory и batchKGEnrichment используют batch.
  • H-T-1 ExecTool.ExecuteStream дублирует Execute — извлечена общая логика валидации/подготовки в execPrepare(). ~150 строк дублирования устранены. Добавлены 5 регрессионных тестов.

Added

  • Batch Store-методы: GetFactsByIDs, GetChunksByIDs, GetEntitiesByIDs — единый SQL-запрос WHERE id IN (...) вместо N+1.
  • sendStreamEvent(ctx, ch, evt) — helper для context-aware записи в ToolStreamEvent channel.
  • memoryToolBase.embedQuery(ctx, query) — общий helper для embedding запросов.
  • approval_test.go — 8 тестов (basic approve/deny, timeout, concurrent resolve, cleanup).
  • email_send_test.go — 9 тестов (decrypt, FsGuard attach, blocked devices, path traversal).
  • stream_test.go — 3 теста (normal, cancelled context, full channel).
  • exec_test.go — 5 новых тестов (Execute, ExecuteStream, empty command, non-zero exit, cancelled context).

Build / Tests

  • go test ./internal/... -race -count=1 — все тесты проходят.
  • make build-cross — 6 бинарников собираются без ошибок.