0.134.46
Security (C-M-5 — Embedder re-embed pipeline, частичный фикс)
Реализован фундамент для переиндексации эмбеддингов при смене embedder’а
с разной размерностью. Раньше при dimension mismatch SwappableEmbedder.Swap
возвращал 409 без возможности продолжить. Теперь инфраструктура (Store +
Reindexer) готова — админ сможет запустить фоновую переиндексацию, которая
обновит все memory_facts и memory_chunks.
- Миграция
077_reindex_jobs.up.sql— таблицаreindex_jobs(id, kind, old_dim, new_dim, old_model, new_model, status, processed, total, started_at, finished_at, error, created_at) + UNIQUE INDEXuniq_active_reindex_jobгарантирующий только один active job одновременно. internal/store/store.go—ReindexJobstruct + 7 новых методов Store:CreateReindexJob,GetActiveReindexJob,GetReindexJob,UpdateReindexJobProgress,UpdateReindexJobStatus,ListReindexJobs,EnsureVectorDimensions.internal/store/sqlite.go— все 7 методов +UpdateChunkEmbedding+ListChunksNeedingReembed+IndexChunkUpdateVector(HNSW reindex).internal/store/postgres.go— все 7 методов +UpdateChunkEmbedding
ListChunksNeedingReembed(использует существующийvectorToPG).EnsureVectorDimensionsуже существовал.
internal/store/dual.go— passthrough-методы.internal/embeddings/reindex.go—ReindexerсStart(kind),Cancel(), фоновой goroutine, батчами по 100, проверкойctx.Err()на каждой итерации.ErrAlreadyRunningзащищает от дублей.internal/embeddings/reindex_test.go— 3 теста: Start creates job, DoubleStartFails, ProcessesFacts (создаёт факт → reindex → проверяет что mockProvider был вызван).
Planned (admin HTTP endpoints + WS events)
Полная интеграция в cmd/taigaclaw/main.go (swappable + reindexer wiring)
и HTTP endpoint’ы (POST /api/v1/admin/embeddings/reindex,
GET /status, POST /cancel) оставлены на следующий PR — сейчас
инфраструктура (Store + Reindexer) готова и покрыта тестами.
Security (H-S-4, H-S-11 — file ops + IP fingerprint)
internal/server/handler/file.go— добавленsafeRemove(workspaceDir, target): централизованный helper для удаления файлов/папок с защитой от path traversal (isPathInWorkspace), symlink-атак (Lstat Mode), и race-атак через подмену каталога symlink-ом между Lstat и RemoveAll (EvalSymlinks+ повторная проверка). Используется вместо прямогоos.Remove/os.RemoveAllв handler-ах. Учитывает macOS/var→/private/var(workspace и target резолвятся одинаково).internal/server/handler/safe_remove_test.go— 5 тестов: file inside, dir recursive, path outside (отказ), symlink (отказ), non-existent (no-op).- Миграция
076_oauth_ip_fingerprint— колонкаip_fingerprint TEXTвoauth_sessions. NULL по умолчанию (backward-compat). internal/store/store.go—OAuthSession.IPFingerprint stringполе. Документировано поведение: IPv4 = /24, IPv6 = /64.internal/store/{sqlite,postgres}.go—CreateOAuthSession/GetOAuthSessionобновлены для работы сip_fingerprint. PG-версия использует*string/anyдля NULL-семантики.internal/server/handler/auth.go—computeIPFingerprint(r)нормализует IP клиента в /24 (IPv4) или /64 (IPv6). ПриLogin— записывается в новую сессию. ПриAuthorize— сверяется с текущим IP. Несовпадение →slog.Warn+ удаление сессии + 401.internal/server/handler/auth_ipfingerprint_test.go— 3 теста: IPv4 normalization, invalid addr, fingerprintMatches edge-cases.- Поведение: По умолчанию fingerprint выключен (записывается, но проверка отключена). Включение — через
settings.security.ip_fingerprint_enabled(default false, см. задачу ADV-XXX в roadmap). Backward compatible: пустой stored fingerprint → match always.
Security (C-CH-9 — DKIM/SPF placeholder)
internal/email/whitelist.go— добавлены заглушкиVerifyDKIMиVerifySPFс явным TODO-комментарием и планом реализации (go-msgauth/dkim+ DNS-based SPF check). Текущая реализацияMatchWhitelistDual(envelope-from + Return-Path) уже работает, но без криптографической проверки подмены заголовков.internal/email/whitelist_dkim_spf_test.go— тесты для заглушек, чтобы регрессия не вернула «заглушка всегда возвращает true» поведение после замены на реальную проверку.- Контракт зафиксирован: функции принимают
(rawEmail []byte)и(senderIP, envelopeFrom, heloDomain string), возвращают(verified bool, detail string). Это позволит добавитьrequire_dkim/require_spfфлаги вemail_accountsбез breaking changes.
Security (C-SC-9 — authLimiter на /oauth/token)
internal/server/handler/oauth_ratelimit_test.go— регрессионный тестTestOAuthToken_RateLimited: доказывает, что 6-й POST/oauth/tokenс одного IP получает 429 +Retry-After. Подтверждает, чтоauthLimiter(router.go:128) уже защищает весь/oauth/*route, включая/oauth/token.internal/auth/oauth.go— добавлен TODO-комментарий с планом миграции сpasswordgrant на Authorization Code Flow + PKCE (RFC 6749 §1.3.3, draft-ietf-oauth-security-topics §2.4). Per-account lockout остаётся defence-in-depth.
Added (документация)
- ADR-002
docs/adr/2026-06-07-sandbox-argv.md— argv-array без shell-string для sandbox (C-SC-2, выполнено вv0.134.19). - ADR-003
docs/adr/2026-06-07-oauth-refresh-rotation.md— атомарный revoke черезUPDATE ... WHERE revoked_at IS NULL+client_idbinding (C-SC-4, C-H-8, выполнено вv0.134.38+ миграция 072). - ADR-004
docs/adr/2026-06-07-audit-structured.md—resource_type+resource_id+detailsJSON в audit log (H-S-10, выполнено вv0.134.23). - ADR-005
docs/adr/2026-06-07-rag-batched-queries.md— batch Store-методы для RAG:GetFactsByIDs,SearchEntitiesByNames, Jaro-Winkler для KG same_as (H-M-1..H-M-12, выполнено вv0.134.33). - ADR-006
docs/adr/2026-06-07-embedder-dimensions.md— стратегия миграции при смене embedder’а с разными dim: блокирующий check + re-embed pipeline (C-M-5, частичный фикс; полный pipeline — следующий PR). - ADR-007
docs/adr/2026-06-07-updater-key-rotation.md— TLS hardening + Ed25519 подпись манифеста + atomic apply + key rotation plan (C-CH-7, H-CH-10..15, выполнено вv0.134.19/33). - ADR-008
docs/adr/2026-06-07-dual-store-embedding.md— предлагаемый struct embedding refactorDualStore(−1000 строк passthrough, L-ST-2 / L-CS-1, DEFERRED).