Skip to content

feat: add static session-start gRPC flow#199

Merged
thebtf merged 3 commits into
mainfrom
feat/us13-session-start-121
Apr 22, 2026
Merged

feat: add static session-start gRPC flow#199
thebtf merged 3 commits into
mainfrom
feat/us13-session-start-121

Conversation

@thebtf
Copy link
Copy Markdown
Owner

@thebtf thebtf commented Apr 22, 2026

Summary

  • add GetSessionStartContext and NegotiateVersion to the Engram gRPC API
  • implement server-side static session-start composition for issues, rules, and memories
  • add HTTP compatibility endpoint for hook migration
  • move plugin session-start to the new static path with local cache fallback per FR-17
  • add tests for gRPC handlers, compatibility endpoint, and hook cache behavior

Scope

Implements US13 / engram#121:

  • session-start inject
  • version negotiation
  • FR-17 client cache

Verification

  • node --test plugin/engram/hooks/session-start.test.js
  • go test ./internal/grpcserver ./internal/worker -count=1
  • go build ./...

Notes

  • keeps the old /api/context/inject endpoint in place for compatibility, but it is no longer the primary session-start path
  • static-only payload by design: issues + behavioral rules + memories, no ranking/LLM filtering

Summary by CodeRabbit

  • Новые возможности

    • Статический API для получения контекста сеанса (проблемы, правила, памяти) с фильтрацией по проекту и лимитами; возвращает сгенерированный timestamp.
    • Механизм согласования версий (MAJOR) клиента и сервера.
    • HTTP-эндпоинты для получения статического контента сеанса.
    • Плагин: файловый персистентный кеш для payload и рендеринг из кэша при ошибках.
  • Tests

    • Добавлены интеграционные и юнит-тесты для новых API, HTTP-обработчиков, согласования версий и логики кэширования.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 60f311b0-c5c8-4d8c-8062-0705b540138d

📥 Commits

Reviewing files that changed from the base of the PR and between 1ac03fa and ab1b34d.

📒 Files selected for processing (1)
  • internal/grpcserver/session_start_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/grpcserver/session_start_test.go

Walkthrough

Добавлены два новых gRPC-эндпоинта (GetSessionStartContext, NegotiateVersion) с реализациями и тестами, HTTP-обёртка для статического контекста сеанса, маршруты в сервисе, плагинная логика кеширования payload и соответствующие тесты, а также обновлён proto-файл с новыми сообщениями.

Changes

Cohort / File(s) Summary
gRPC: session start
internal/grpcserver/session_start.go, internal/grpcserver/session_start_test.go
Добавлен GetSessionStartContext: валидация запроса, применение дефолтов к лимитам, SQL-запросы (issues, memories, behavioral rules), маппинг в protobuf (копирование слайсов, преобразование времён). Тесты покрывают валидацию, happy path и поведение по умолчанию.
gRPC: версия
internal/grpcserver/version_negotiate.go, internal/grpcserver/version_negotiate_test.go
Добавлен NegotiateVersion и parseMajorVersion: парсинг MAJOR из строки версии, правила ошибок и совместимость по равенству MAJOR; тесты на парсер и ветвления совместимости/несовместимости.
HTTP: статический контекст
internal/worker/handlers_context.go, internal/worker/handlers_context_session_start_test.go, internal/worker/service.go
Добавлен HTTP-обработчик GET/POST /api/context/session-start, транслирующий вызов к внутреннему gRPC и конвертирующий protobuf->JSON (RFC3339 для времён, копирование списков). Сервис хранит ссылку на внутренний gRPC-сервер; добавлены маршруты и тесты для happy/error путей.
Protobuf
proto/engram/v1/engram.proto
Добавлены сервисные методы GetSessionStartContext и NegotiateVersion и соответствующие сообщения: запросы/ответы, SessionStartIssue/Rule/Memory с timestamp-полями.
Плагин: утилиты кеша
plugin/engram/hooks/lib.js
Новые экспортируемые функции: определение каталога данных, построение пути кеша для проекта, безопасное чтение/запись JSON (создание директорий, ограниченные права, тихое подавление ошибок).
Плагин: session-start
plugin/engram/hooks/session-start.js, plugin/engram/hooks/session-start.test.js
Переписан поток: fetch статического payload с GET /api/context/session-start, рендер issues/rules/memories, локальный файл-кеш payload; на падении запроса — рендер из кеша со статусом «stale» или баннер «no cache». Упрощено подтверждение открытых issues; тесты покрывают live/cached/error сценарии и запись кеша.

Sequence Diagram(s)

sequenceDiagram
    participant Plugin as Plugin (frontend)
    participant HTTP as HTTP Server
    participant GRPC as Internal gRPC Server
    participant DB as Database

    Plugin->>HTTP: GET /api/context/session-start?project=...
    HTTP->>GRPC: GetSessionStartContext(project, limits)
    GRPC->>DB: SELECT issues WHERE project=? AND status IN (open,ack,reopened) LIMIT issuesLimit
    DB-->>GRPC: rows(issues)
    GRPC->>DB: SELECT memories WHERE project=? LIMIT memoriesLimit
    DB-->>GRPC: rows(memories)
    GRPC->>DB: SELECT rules WHERE project=? OR project IS NULL ORDER BY priority DESC, created_at DESC LIMIT rulesLimit
    DB-->>GRPC: rows(rules)
    GRPC-->>HTTP: {issues, memories, rules, generated_at}
    HTTP-->>Plugin: JSON payload (RFC3339 timestamps)
    Plugin->>Plugin: write cache (on success) / read cache (on failure)
    Plugin->>HTTP: POST /api/issues/acknowledge (ack open issues)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Poem

🐰 Я кролик в норах кода сижу,
Вытаскиваю контекст для старта,
Кеш храню — когда сеть не в помощь,
Версию считаю — майор важней,
Пусть сеанс летит, я рядом — держу!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.03% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add static session-start gRPC flow' accurately and concisely describes the main change: introducing new gRPC functionality for static session-start context composition.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/us13-session-start-121

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.11.4)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


Comment @coderabbitai help to get the list of available commands and usage tips.

@thebtf
Copy link
Copy Markdown
Owner Author

thebtf commented Apr 22, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new static context mechanism for session starts, including gRPC and HTTP endpoints for fetching issues, behavioral rules, and memories. It also implements a major-version negotiation endpoint and refactors the plugin hook to utilize these new services with a local file-based caching layer for improved resilience. Feedback focuses on refining the API design to allow for empty result sets, enforcing server-side limits on behavioral rule queries to prevent resource exhaustion, and securing the local cache files with restricted file permissions.

Comment thread internal/grpcserver/session_start.go
Comment thread internal/grpcserver/session_start.go
Comment thread plugin/engram/hooks/lib.js Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (5)
internal/worker/handlers_context.go (1)

803-814: Рассмотрите добавление маппинга для codes.PermissionDenied и codes.Unauthenticated

Функция grpcCodeToHTTP обрабатывает только InvalidArgument, NotFound и Unavailable. Для полноты API рассмотрите добавление:

  • codes.PermissionDenied403 Forbidden
  • codes.Unauthenticated401 Unauthorized
♻️ Предложенное расширение
 func grpcCodeToHTTP(code codes.Code) int {
 	switch code {
 	case codes.InvalidArgument:
 		return http.StatusBadRequest
 	case codes.NotFound:
 		return http.StatusNotFound
 	case codes.Unavailable:
 		return http.StatusServiceUnavailable
+	case codes.PermissionDenied:
+		return http.StatusForbidden
+	case codes.Unauthenticated:
+		return http.StatusUnauthorized
 	default:
 		return http.StatusInternalServerError
 	}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/worker/handlers_context.go` around lines 803 - 814, Update the
grpcCodeToHTTP function to handle authorization-related gRPC codes: add mappings
for codes.PermissionDenied -> http.StatusForbidden (403) and
codes.Unauthenticated -> http.StatusUnauthorized (401); modify the switch in
grpcCodeToHTTP to include these two cases alongside the existing
InvalidArgument, NotFound, and Unavailable branches so permission/auth failures
return the correct HTTP status codes.
plugin/engram/hooks/session-start.js (1)

158-166: Хелпер buildCachedSessionStartPayload содержит захардкоженную дату

Функция buildCachedSessionStartPayload имеет дефолтное значение generated_at: '2026-04-22T12:00:00Z'. Это выглядит как тестовые данные, "утёкшие" в production-код. Для тестового хелпера лучше использовать более очевидное значение или документировать назначение.

♻️ Предложенное улучшение
 function buildCachedSessionStartPayload(overrides = {}) {
   return {
     issues: [],
     rules: [],
     memories: [],
-    generated_at: '2026-04-22T12:00:00Z',
+    generated_at: new Date().toISOString(), // or document this is a test helper
     ...overrides,
   };
 }

Если это намеренно для тестов, рассмотрите перенос в тестовый файл или добавление JSDoc-комментария.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/engram/hooks/session-start.js` around lines 158 - 166, The helper
buildCachedSessionStartPayload contains a hardcoded generated_at timestamp that
looks like leaked test data; change it to a dynamic default (e.g. generated_at:
new Date().toISOString()) or set generated_at to null/omit it and let
callers/tests inject a stable value, and if the fixed timestamp is intentional
for tests either move this helper into the test suite or add a JSDoc explaining
its purpose and why the static date is required; update references to
buildCachedSessionStartPayload accordingly.
plugin/engram/hooks/lib.js (1)

149-156: writeJSONFile может выбросить исключение при ошибке записи

В отличие от readJSONFile, которая безопасно возвращает null при ошибках, writeJSONFile не обрабатывает исключения от mkdirSync и writeFileSync. Это может привести к неперехваченным исключениям при проблемах с файловой системой (нет прав, диск заполнен и т.д.).

Учитывая, что кеширование — некритичная операция, рассмотрите добавление try-catch для согласованности с паттерном "silent fail" в readJSONFile.

♻️ Предложенное исправление
 function writeJSONFile(filePath, value) {
   if (!filePath) {
     return;
   }
-  const parentDir = path.dirname(filePath);
-  fs.mkdirSync(parentDir, { recursive: true });
-  fs.writeFileSync(filePath, JSON.stringify(value, null, 2), 'utf8');
+  try {
+    const parentDir = path.dirname(filePath);
+    fs.mkdirSync(parentDir, { recursive: true });
+    fs.writeFileSync(filePath, JSON.stringify(value, null, 2), 'utf8');
+  } catch {
+    // Cache write is best-effort; failures are non-critical
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@plugin/engram/hooks/lib.js` around lines 149 - 156, The writeJSONFile
function currently may throw from fs.mkdirSync or fs.writeFileSync; wrap the
body of writeJSONFile in a try-catch so filesystem errors are swallowed
similarly to readJSONFile (i.e., do not throw for cache write failures),
optionally returning a boolean (true on success, false on failure) or undefined
on error; reference the writeJSONFile function and use the same silent-fail
pattern as readJSONFile to keep behavior consistent across the module.
internal/worker/service.go (1)

856-867: Некорректный отступ в группе маршрутов

Блок маршрутов для "Context injection" имеет лишний уровень отступа по сравнению с остальными маршрутами в группе s.requireReady. Это нарушает согласованность форматирования кода.

♻️ Предложенное исправление форматирования
-		// Context injection
-		r.Get("/api/context/count", s.handleContextCount)
-		r.Post("/api/context/inject", s.handleContextInject)
-		r.Get("/api/context/inject", s.handleContextInject) // deprecated — use POST
-		r.Post("/api/context/session-start", s.handleSessionStartContextStatic)
-		r.Get("/api/context/session-start", s.handleSessionStartContextStatic)
-		r.Get("/api/context/search", s.handleSearchByPrompt)
-		r.Post("/api/context/search", s.handleSearchByPrompt)
-		r.Get("/api/context/files", s.handleFileContext)
-		r.Get("/api/context/by-file", s.handleContextByFile)
-		r.Post("/api/memory/triggers", s.handleMemoryTriggers)
-		r.Post("/api/decisions/search", s.handleSearchDecisions)
+		// Context injection
+		r.Get("/api/context/count", s.handleContextCount)
+		r.Post("/api/context/inject", s.handleContextInject)
+		r.Get("/api/context/inject", s.handleContextInject) // deprecated — use POST
+		r.Post("/api/context/session-start", s.handleSessionStartContextStatic)
+		r.Get("/api/context/session-start", s.handleSessionStartContextStatic)
+		r.Get("/api/context/search", s.handleSearchByPrompt)
+		r.Post("/api/context/search", s.handleSearchByPrompt)
+		r.Get("/api/context/files", s.handleFileContext)
+		r.Get("/api/context/by-file", s.handleContextByFile)
+		r.Post("/api/memory/triggers", s.handleMemoryTriggers)
+		r.Post("/api/decisions/search", s.handleSearchDecisions)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/worker/service.go` around lines 856 - 867, The "Context injection"
routes are indented one level deeper than the other routes in the s.requireReady
group; align their indentation with the rest of the s.requireReady route
registrations by removing the extra indentation so the entries like
r.Get("/api/context/count", s.handleContextCount), r.Post("/api/context/inject",
s.handleContextInject), r.Get("/api/context/inject", s.handleContextInject),
r.Post("/api/context/session-start", s.handleSessionStartContextStatic),
r.Get("/api/context/session-start", s.handleSessionStartContextStatic),
r.Get("/api/context/search", s.handleSearchByPrompt),
r.Post("/api/context/search", s.handleSearchByPrompt),
r.Get("/api/context/files", s.handleFileContext), r.Get("/api/context/by-file",
s.handleContextByFile), r.Post("/api/memory/triggers", s.handleMemoryTriggers),
and r.Post("/api/decisions/search", s.handleSearchDecisions) match the same
indentation level as the other route registrations in the s.requireReady block.
internal/grpcserver/session_start_test.go (1)

113-114: Уберите time.Sleep из тестов, чтобы снизить флаки.

На Line 113-114 и 143-144 порядок данных делается через паузы. Надёжнее выставлять created_at детерминированно (через update) или сортировать по явному полю в seed.

Also applies to: 143-144

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/grpcserver/session_start_test.go` around lines 113 - 114, Remove the
brittle time.Sleep calls used to order created memories in session_start_test.go
(around memoryStore.Create calls) and instead create deterministic ordering by
explicitly setting the created_at timestamps on the Memory objects (or updating
them after Create) or by asserting against a sorted order using an explicit
field; update the tests that call memoryStore.Create with models.Memory to
assign deterministic created_at values (or call an UpdateCreatedAt helper)
and/or sort the returned seed list by created_at when asserting, replacing the
Sleep at both the locations referenced.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/grpcserver/session_start_test.go`:
- Around line 25-28: The current test only checks DATABASE_DSN presence but
later runs destructive DELETEs; update the test setup (where dsn is read into
the dsn variable in session_start_test.go, e.g. inside TestSessionStart) to
verify the DSN points to a test database before proceeding: if dsn does not
match an allowed test pattern (for example contains "test", "localhost", a
specific test DB name, or matches a configured TEST_DATABASE_DSN regex) then
call t.Skip with a clear message; additionally explicitly reject known
production/staging hosts/containers (e.g., hostnames like "prod", "production",
or your staging domain) to ensure the destructive cleanup never runs against
non-test DBs.

In `@internal/grpcserver/session_start.go`:
- Around line 54-55: The gRPC responses currently include raw DB/driver errors
via status.Errorf(codes.Internal, "…%v", err) (seen in the three occurrences of
status.Errorf(codes.Internal, ...) around the session-start listing code);
instead remove the %v and return a neutral error string (e.g. "failed to list
session-start issues") and log the detailed err server-side; update each
occurrence (the status.Errorf calls at the three locations) to return a generic
message and call your server logger (e.g. serverLogger.Errorf or log.Printf) to
record the full err and any context before returning the neutral gRPC error.
- Around line 28-45: Добавьте проверку верхнего предела для
req.GetMemoriesLimit() и req.GetIssuesLimit(): объявите константы
maxSessionStartMemoriesLimit и maxSessionStartIssuesLimit, затем после
существующей проверки >=0 (и перед присвоением переменным memoriesLimit и
issuesLimit) либо вернуть status.Error(codes.InvalidArgument, "... must be <=
<max>") при превышении, либо безопасно капировать значение до соответствующего
max (например memoriesLimit = min(int(req.GetMemoriesLimit()),
maxSessionStartMemoriesLimit)); обновите логику использования
defaultSessionStartMemoriesLimit/defaultSessionStartIssuesLimit чтобы применять
их только для нулевого значения. Укажите эти константы и используйте
req.GetMemoriesLimit(), req.GetIssuesLimit(), memoriesLimit, issuesLimit и s.db
в правках.

---

Nitpick comments:
In `@internal/grpcserver/session_start_test.go`:
- Around line 113-114: Remove the brittle time.Sleep calls used to order created
memories in session_start_test.go (around memoryStore.Create calls) and instead
create deterministic ordering by explicitly setting the created_at timestamps on
the Memory objects (or updating them after Create) or by asserting against a
sorted order using an explicit field; update the tests that call
memoryStore.Create with models.Memory to assign deterministic created_at values
(or call an UpdateCreatedAt helper) and/or sort the returned seed list by
created_at when asserting, replacing the Sleep at both the locations referenced.

In `@internal/worker/handlers_context.go`:
- Around line 803-814: Update the grpcCodeToHTTP function to handle
authorization-related gRPC codes: add mappings for codes.PermissionDenied ->
http.StatusForbidden (403) and codes.Unauthenticated -> http.StatusUnauthorized
(401); modify the switch in grpcCodeToHTTP to include these two cases alongside
the existing InvalidArgument, NotFound, and Unavailable branches so
permission/auth failures return the correct HTTP status codes.

In `@internal/worker/service.go`:
- Around line 856-867: The "Context injection" routes are indented one level
deeper than the other routes in the s.requireReady group; align their
indentation with the rest of the s.requireReady route registrations by removing
the extra indentation so the entries like r.Get("/api/context/count",
s.handleContextCount), r.Post("/api/context/inject", s.handleContextInject),
r.Get("/api/context/inject", s.handleContextInject),
r.Post("/api/context/session-start", s.handleSessionStartContextStatic),
r.Get("/api/context/session-start", s.handleSessionStartContextStatic),
r.Get("/api/context/search", s.handleSearchByPrompt),
r.Post("/api/context/search", s.handleSearchByPrompt),
r.Get("/api/context/files", s.handleFileContext), r.Get("/api/context/by-file",
s.handleContextByFile), r.Post("/api/memory/triggers", s.handleMemoryTriggers),
and r.Post("/api/decisions/search", s.handleSearchDecisions) match the same
indentation level as the other route registrations in the s.requireReady block.

In `@plugin/engram/hooks/lib.js`:
- Around line 149-156: The writeJSONFile function currently may throw from
fs.mkdirSync or fs.writeFileSync; wrap the body of writeJSONFile in a try-catch
so filesystem errors are swallowed similarly to readJSONFile (i.e., do not throw
for cache write failures), optionally returning a boolean (true on success,
false on failure) or undefined on error; reference the writeJSONFile function
and use the same silent-fail pattern as readJSONFile to keep behavior consistent
across the module.

In `@plugin/engram/hooks/session-start.js`:
- Around line 158-166: The helper buildCachedSessionStartPayload contains a
hardcoded generated_at timestamp that looks like leaked test data; change it to
a dynamic default (e.g. generated_at: new Date().toISOString()) or set
generated_at to null/omit it and let callers/tests inject a stable value, and if
the fixed timestamp is intentional for tests either move this helper into the
test suite or add a JSDoc explaining its purpose and why the static date is
required; update references to buildCachedSessionStartPayload accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e54fec1b-32d5-4c6b-9659-e9ed35598425

📥 Commits

Reviewing files that changed from the base of the PR and between 69e326d and f763533.

⛔ Files ignored due to path filters (2)
  • proto/engram/v1/engram.pb.go is excluded by !**/*.pb.go
  • proto/engram/v1/engram_grpc.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (11)
  • internal/grpcserver/session_start.go
  • internal/grpcserver/session_start_test.go
  • internal/grpcserver/version_negotiate.go
  • internal/grpcserver/version_negotiate_test.go
  • internal/worker/handlers_context.go
  • internal/worker/handlers_context_session_start_test.go
  • internal/worker/service.go
  • plugin/engram/hooks/lib.js
  • plugin/engram/hooks/session-start.js
  • plugin/engram/hooks/session-start.test.js
  • proto/engram/v1/engram.proto

Comment thread internal/grpcserver/session_start_test.go
Comment thread internal/grpcserver/session_start.go
Comment thread internal/grpcserver/session_start.go Outdated
@thebtf
Copy link
Copy Markdown
Owner Author

thebtf commented Apr 22, 2026

🤖 PR Review MCP State (auto-managed, do not edit)
{
  "version": 2,
  "parentChildren": {},
  "resolvedNitpicks": {
    "coderabbit-nitpick-87633c09-803": {
      "resolvedAt": "2026-04-22T22:25:00.617Z",
      "resolvedBy": "agent"
    },
    "coderabbit-nitpick-cdaeb395-158": {
      "resolvedAt": "2026-04-22T22:25:03.237Z",
      "resolvedBy": "agent"
    },
    "coderabbit-nitpick-936107ef-149": {
      "resolvedAt": "2026-04-22T22:25:06.106Z",
      "resolvedBy": "agent"
    },
    "coderabbit-nitpick-5093434e-856": {
      "resolvedAt": "2026-04-22T22:25:08.915Z",
      "resolvedBy": "agent"
    },
    "coderabbit-nitpick-bd29bda0-113": {
      "resolvedAt": "2026-04-22T22:25:11.380Z",
      "resolvedBy": "agent"
    },
    "coderabbit-nitpick-abc045c8-126": {
      "resolvedAt": "2026-04-22T22:26:27.520Z",
      "resolvedBy": "agent"
    }
  },
  "updatedAt": "2026-04-22T22:26:28.358Z"
}

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
internal/grpcserver/session_start_test.go (1)

126-126: Использование time.Sleep для упорядочивания записей.

Паузы в 5мс для создания различных created_at временных меток работают, но могут быть нестабильными под нагрузкой или при низкой точности временных меток БД. Рекомендуется рассмотреть явную установку временных меток через фикстуры, если тесты станут нестабильными.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/grpcserver/session_start_test.go` at line 126, Вместо ненадёжного
вызова time.Sleep(5 * time.Millisecond) в тесте (строка с time.Sleep) задайте
детерминированные created_at через фикстуры или мок часов: обновите код теста в
session_start_test.go чтобы явно присваивать временные метки нужным записям
(например через helper/fixture setCreatedAt или через внедряемый Clock/Now mock)
или используйте фиктивный clock, который выдвигает время вперёд на ожидаемую
разницу; уберите sleep и убедитесь, что сравнения/сортировка используют эти
явные created_at значения.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@internal/grpcserver/session_start_test.go`:
- Line 126: Вместо ненадёжного вызова time.Sleep(5 * time.Millisecond) в тесте
(строка с time.Sleep) задайте детерминированные created_at через фикстуры или
мок часов: обновите код теста в session_start_test.go чтобы явно присваивать
временные метки нужным записям (например через helper/fixture setCreatedAt или
через внедряемый Clock/Now mock) или используйте фиктивный clock, который
выдвигает время вперёд на ожидаемую разницу; уберите sleep и убедитесь, что
сравнения/сортировка используют эти явные created_at значения.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 09179efd-24a9-4213-89b4-bbfb0745355b

📥 Commits

Reviewing files that changed from the base of the PR and between f763533 and 1ac03fa.

📒 Files selected for processing (6)
  • internal/grpcserver/session_start.go
  • internal/grpcserver/session_start_test.go
  • internal/worker/handlers_context.go
  • internal/worker/service.go
  • plugin/engram/hooks/lib.js
  • plugin/engram/hooks/session-start.js
🚧 Files skipped from review as they are similar to previous changes (3)
  • internal/grpcserver/session_start.go
  • plugin/engram/hooks/lib.js
  • plugin/engram/hooks/session-start.js

@thebtf thebtf merged commit 531a6e5 into main Apr 22, 2026
8 checks passed
@thebtf thebtf deleted the feat/us13-session-start-121 branch April 22, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant