Skip to content

feat: agent issues — cross-project issue tracking for AI agents#133

Merged
thebtf merged 8 commits into
mainfrom
feat/agent-issues
Apr 9, 2026
Merged

feat: agent issues — cross-project issue tracking for AI agents#133
thebtf merged 8 commits into
mainfrom
feat/agent-issues

Conversation

@thebtf
Copy link
Copy Markdown
Owner

@thebtf thebtf commented Apr 9, 2026

Summary

  • New issues and issue_comments tables with lifecycle: open → acknowledged → resolved ⟲ reopened
  • IssueStore with 7 CRUD methods (create, list, get, update, comment, acknowledge, reopen)
  • REST API: 5 endpoints (GET/POST /api/issues, GET/PATCH /api/issues/:id, POST /api/issues/acknowledge)
  • MCP tool issues with 6 actions (create, list, get, update, comment, reopen)
  • Auto-fill source_project/source_agent from session context
  • Priority ordering (critical→high→medium→low) with comment counts

Remaining (Phase 4-5, follow-up PR)

  • Plugin hooks: <open-issues> injection in session-start.js + auto-acknowledge
  • Dashboard UI: IssuesView + IssueDetailView

Test plan

  • go build ./... clean
  • go test ./internal/db/gorm/... passes
  • Deploy to staging, create issue via MCP tool
  • Verify REST API responds correctly
  • Verify migration 070 creates tables

Summary by CodeRabbit

Примечания к релизу

  • New Features

    • Полная система отслеживания задач: создание, список с фильтрами и пагинацией, просмотр деталей, обновление статусов, комментирование, переоткрытие и массовое подтверждение.
    • UI и API: страницы списка и деталей, боковое меню «Issues», новые маршруты, клиентские хуки и методы API.
    • Интеграция в сессии агентов: блок открытых задач в контексте и асинхронное авто-подтверждение.
  • Chores

    • Добавлена миграция базы данных и обновлена версия плагина.

thebtf added 5 commits April 9, 2026 04:21
Issue: 15 fields with CHECK constraints on status/priority,
composite index (target_project, status), source_project index.
IssueComment: FK to issues, composite index (issue_id, created_at).
Lifecycle: open → acknowledged → resolved ⟲ reopened.
- CreateIssue with defaults (open, medium)
- ListIssues with priority ordering, comment count, pagination
- GetIssue with comments thread
- UpdateIssueStatus with timestamp tracking
- AddComment with issue updated_at refresh
- AcknowledgeIssues bulk open→acknowledged
- ReopenIssue with resolved-state validation and optional comment
- handleListIssues (GET /api/issues) with project/status/limit/offset
- handleGetIssue (GET /api/issues/{id}) with comments
- handleCreateIssue (POST /api/issues) with validation
- handleUpdateIssue (PATCH /api/issues/{id}) status + comment
- handleAcknowledgeIssues (POST /api/issues/acknowledge) bulk
- formatIssuesForInjection for session-start hook
- IssueStore initialized and wired in Service
- 5 routes registered in requireReady group
- tools_issues.go: create/list/get/update/comment/reopen handlers
- server.go: issues tool registered with full input schema
- service.go: issueStore wired into MCP server via SetIssueStore
- Auto-fills source_project and source_agent from session context
- Human-readable text output for all actions
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c4e0cc44-c436-4d48-990e-f94021d448aa

📥 Commits

Reviewing files that changed from the base of the PR and between b78ee11 and 225b490.

📒 Files selected for processing (4)
  • internal/db/gorm/issue_store.go
  • internal/db/gorm/models.go
  • internal/mcp/tools_issues.go
  • internal/worker/handlers_issues.go

Walkthrough

Добавлена подсистема трекинга issues: миграция и GORM-модели, новый GORM-backed IssueStore с CRUD и переходами статусов, MCP-инструмент, HTTP API-эндпойнты, интеграция в worker/service, фронтенд (список/детали) и плагинная инъекция/авто-acknowledge.

Changes

Cohort / File(s) Summary
DB Models & Migrations
internal/db/gorm/models.go, internal/db/gorm/migrations.go
Добавлены модели Issue/IssueComment и миграция 070_agent_issues — таблицы с CHECK-ограничениями, JSONB labels, временные поля и индексы; rollback удаляет таблицы.
Storage Layer (GORM IssueStore)
internal/db/gorm/issue_store.go
Новый IssueStore (NewIssueStore) и IssueWithCount. Реализованы CreateIssue, ListIssues (с correlated subquery для comment_count и CASE-сортировкой по приоритету), GetIssue (с загрузкой комментариев), UpdateIssueStatus (статус-guard и установка соответствующих timestamp), AddComment (транзакция + обновление updated_at), AcknowledgeIssues (bulk update open→acknowledged) и ReopenIssue (транзакция с опциональным комментарием и проверкой конкурентных изменений).
MCP server & tools
internal/mcp/server.go, internal/mcp/tools_issues.go
Добавлено поле issueStore в Server и сеттер; зарегистрирован инструмент "issues"; добавлены обработчики действий create/list/get/update/comment/reopen с валидацией входа и форматированием ответов.
Worker HTTP API & Service wiring
internal/worker/handlers_issues.go, internal/worker/service.go
Инициализация issueStore в Service, регистрация маршрутов /api/issues, /api/issues/{id}, /api/issues/acknowledge. Добавлены handlers для list/get/create/patch/acknowledge с корректной картой ошибок (not found → 404), JSON-ответами и вспомогательными форматерами для injection.
Frontend integration
ui/src/composables/useIssues.ts, ui/src/router/index.ts, ui/src/views/IssuesView.vue, ui/src/views/IssueDetailView.vue, ui/src/components/layout/AppSidebar.vue, ui/src/utils/api.ts
Добавлен UI: маршруты списка и детали, пункт в сайдбаре, composable useIssues, API-обёртки (fetchIssues, fetchIssue, acknowledgeIssues), страницы списка и детали с таймлайном; учтён AbortController/timeout и согласованность query-параметров.
Plugin hooks & manifest
plugin/engram/hooks/lib.js, plugin/engram/hooks/session-start.js, plugin/engram/.claude-plugin/plugin.json
Добавлен formatIssuesBlock для инъекции <open-issues>, session-start подгружает блок issues и выполняет fire-and-forget авто-acknowledge открытых задач (timeout 3000ms), обновлён манифест плагина до версии 3.4.0.
Misc
internal/mcp/server.go
Server получил новое поле issueStore *gorm.IssueStore и метод SetIssueStore.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant HTTP as "HTTP Handler"
    participant Service
    participant Store as "IssueStore (GORM)"
    participant DB as "Postgres"

    Client->>HTTP: POST /api/issues {title,...}
    HTTP->>Service: CreateIssue request
    Service->>Store: CreateIssue(ctx, issue)
    Store->>DB: INSERT INTO issues
    DB-->>Store: new id
    Store-->>Service: id
    Service-->>HTTP: 201 {id,message}
    HTTP-->>Client: 201

    Client->>HTTP: GET /api/issues?project=X&status=open,reopened
    HTTP->>Service: ListIssues request
    Service->>Store: ListIssues(ctx, project, statuses, limit, offset)
    Store->>DB: SELECT issues with correlated comment_count subquery (ORDER BY priority CASE, created_at DESC)
    DB-->>Store: rows + total
    Store-->>Service: []IssueWithCount, total
    Service-->>HTTP: 200 {issues,total}
    HTTP-->>Client: 200

    Client->>HTTP: PATCH /api/issues/{id} {status: "resolved", comment: "..."}
    HTTP->>Service: Update request
    Service->>Store: UpdateIssueStatus(ctx, id, "resolved")
    Store->>DB: UPDATE issues SET status='resolved', resolved_at=now(), updated_at=now() WHERE id=? AND ...guard...
    DB-->>Store: rows affected
    alt comment present
        Service->>Store: AddComment(ctx, id, comment)
        Store->>DB: INSERT INTO issue_comments
        DB-->>Store: comment id
    end
    Store-->>Service: result
    Service-->>HTTP: 200 {message}
    HTTP-->>Client: 200
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 Я постучал лапкой в миграцию, и схемы вспорхнули,
Строки и комменты в порядке — все задачи собраны.
Пусть агенты читают блок, а я норку охраняю,
С приоритетом "critical" я вперед помогаю!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main feature: cross-project issue tracking for AI agents. It clearly summarizes the core purpose of this changeset.

✏️ 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/agent-issues

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 9, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 9, 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.

- lib.js: formatIssuesBlock() renders <open-issues> XML block with
  priority ordering, comment count, time-ago formatting
- session-start.js: fetches GET /api/issues for current project,
  renders block before memory, auto-acknowledges open issues
- Plugin version 3.3.0 → 3.4.0
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 cross-project issue tracking system for agents, enabling them to create, list, and manage issues across different projects. The implementation includes a new IssueStore for GORM-based persistence, database migrations for issues and issue_comments tables, and integration into the MCP server and worker service via new tool definitions and HTTP API endpoints. Review feedback identifies several areas for improvement: a type mismatch between the Labels model field and the JSONB database column, missing field definitions in the MCP tool's input schema, inconsistent metadata retrieval in API handlers, a potential bug in status string parsing, and a race condition in the issue reopening logic.

Comment thread internal/db/gorm/models.go Outdated
TargetProject string `gorm:"type:text;not null;index:idx_issues_target_status,priority:1"`
SourceAgent string `gorm:"type:text"`
CreatedBySession string `gorm:"type:text"`
Labels pq.StringArray `gorm:"type:jsonb;default:'[]'"`
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

high

There is a type mismatch between the GORM model and the database schema for the Labels field. The migration defines this column as JSONB, but pq.StringArray is designed for PostgreSQL native arrays (text[]). Using pq.StringArray with a JSONB column will cause runtime errors during persistence because it serializes to the PostgreSQL array format (e.g., {val1,val2}) instead of JSON format (e.g., ["val1","val2"]).

Suggested change
Labels pq.StringArray `gorm:"type:jsonb;default:'[]'"`
Labels models.JSONStringArray `gorm:"type:jsonb;default:'[]'"`

Comment thread internal/mcp/server.go
Comment on lines +974 to +985
"properties": map[string]any{
"action": map[string]any{"type": "string", "enum": []string{"create", "list", "get", "update", "comment", "reopen"}, "description": "Action to perform"},
"title": map[string]any{"type": "string", "description": "Issue title (required for create)"},
"body": map[string]any{"type": "string", "description": "Issue body or comment text"},
"priority": map[string]any{"type": "string", "enum": []string{"critical", "high", "medium", "low"}, "default": "medium"},
"target_project": map[string]any{"type": "string", "description": "Target project slug (defaults to current project)"},
"labels": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "Labels (bug, feature, etc.)"},
"id": map[string]any{"type": "integer", "description": "Issue ID (required for get/update/comment/reopen)"},
"status": map[string]any{"type": "string", "enum": []string{"resolved"}, "description": "Set status (only 'resolved' via update)"},
"comment": map[string]any{"type": "string", "description": "Comment to add with status change or reopen"},
"project": map[string]any{"type": "string", "description": "Filter by project (for list action)"},
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The InputSchema for the issues tool is missing definitions for fields used in the implementation. Specifically, agent_source is used in handleIssueCreate, handleIssueUpdate, and others, but is not defined here. Additionally, the project property is described as being only for the list action, but it is also used as the source_project during issue creation. These should be explicitly defined so that AI agents know to provide them.

Comment thread internal/worker/handlers_issues.go Outdated
Comment on lines +174 to +175
sourceProject := r.URL.Query().Get("source_project")
sourceAgent := r.URL.Query().Get("source_agent")
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

In handleUpdateIssue (PATCH), the author metadata (source_project and source_agent) is being retrieved from query parameters. This is inconsistent with handleCreateIssue (POST), where similar metadata is expected in the JSON request body. It is better to include these fields in the JSON body for the PATCH request as well to maintain a consistent API design.

Comment thread internal/mcp/tools_issues.go Outdated
Comment on lines +88 to +91
statuses := strings.Split(statusParam, ",")
for i := range statuses {
statuses[i] = strings.TrimSpace(statuses[i])
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The status parameter parsing in handleIssueList can lead to incorrect database queries if the input string contains trailing commas or is empty. strings.Split on an empty string returns a slice containing one empty string ([""]), which will cause the store to query for issues with an empty status string. It is safer to filter out empty strings after splitting.

Suggested change
statuses := strings.Split(statusParam, ",")
for i := range statuses {
statuses[i] = strings.TrimSpace(statuses[i])
}
statuses := []string{}
for _, s := range strings.Split(statusParam, ",") {
if trimmed := strings.TrimSpace(s); trimmed != "" {
statuses = append(statuses, trimmed)
}
}

Comment thread internal/db/gorm/issue_store.go Outdated
Comment on lines +204 to +208
if err := tx.Model(&Issue{}).Where("id = ?", id).Updates(map[string]interface{}{
"status": "reopened",
"reopened_at": now,
"updated_at": now,
}).Error; err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

The ReopenIssue method has a potential race condition. While it checks the status at line 198, a concurrent request could change the status between that check and the Updates call at line 204. To ensure atomicity, the status check should be part of the Where clause in the update statement.

result := tx.Model(&Issue{}).Where("id = ? AND status = ?", id, "resolved").Updates(map[string]interface{}{
	"status":      "reopened",
	"reopened_at": now,
	"updated_at":  now,
})
if result.Error != nil {
	return result.Error
}
if result.RowsAffected == 0 {
	return fmt.Errorf("issue %d not found or not in resolved state", id)
}

- api.ts: Issue/IssueComment types, fetchIssues, fetchIssue, acknowledgeIssues
- useIssues.ts: reactive composable with status/project filters
- IssuesView.vue: card list with priority badges, status colors, filters
- IssueDetailView.vue: full issue with chronological timeline (events + comments)
- Router: /issues and /issues/:id routes
- Sidebar: "Issues" nav item between Patterns and Sessions
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: 7

🤖 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/db/gorm/issue_store.go`:
- Around line 150-155: Текущая транзакция вставляет созданный комментарий
(переменная created через tx.Create) и затем делает tx.Model(&Issue{}).Where("id
= ?", issueID).Update("updated_at", now) без проверки RowsAffected, поэтому при
отсутствии родительского issue комментарий коммитится как orphan; нужно
проверить результат UPDATE и вернуть ошибку, если RowsAffected == 0 (например
вернуть gorm.ErrRecordNotFound или кастомную ошибку) из анонимной функции
транзакции, чтобы транзакция откатилась и вставка не сохранилась.
- Around line 28-48: В методе CreateIssue в месте формирования created (функция
CreateIssue, тип Issue) нужно валидировать поля Status и Priority до вставки:
проверять что значения входят в допустимые множества (например const/var с
allowedStatuses и allowedPriorities) и при некорректном значении возвращать
валидативную ошибку (например error типа validation error с понятным сообщением)
вместо попытки записать в БД; если поле пустое — подставлять дефолт
("open"/"medium") как сейчас, но любые неизвестные строки отклонять и не
вызывать INSERT/DB чек-констрейнт.

In `@internal/db/gorm/models.go`:
- Around line 430-437: The Labels field currently uses pq.StringArray which maps
to PostgreSQL text[] and conflicts with the gorm tag type:jsonb; change the
Labels field type to models.JSONStringArray (the JSON-aware type used elsewhere)
and keep the gorm tag as type:jsonb;default:'[]' so reads/writes align; update
any code paths that assume pq.StringArray (e.g., CreateIssue/GetIssue handling
of Labels) to use models.JSONStringArray serialization/deserialization where
necessary.

In `@internal/mcp/server.go`:
- Around line 967-987: The "issues" tool is being registered in the local tools
block but not included in the actual discovery response returned by the method
that currently returns "primary" (tools/list), so clients won't see it; change
the discovery-returning method to include the "issues" entry in the returned
tools set only when s.issueStore != nil (i.e., gate publishing of the issues
tool on s.issueStore != nil) and ensure the tool is added to the actual returned
collection used by tools/list (not just the local "primary" variable) so MCP
clients can discover it.

In `@internal/mcp/tools_issues.go`:
- Line 1: Rename the file internal/mcp/tools_issues.go to follow the numbered
MCP-tools pattern (e.g., internal/mcp/tools_01_issues.go) and update any
references to that file name in the repo (build scripts, go:generate directives,
or tests) so the new filename is used; ensure the package declaration (package
mcp) and all symbols defined inside remain unchanged so compilation behavior
does not change.

In `@internal/worker/handlers_issues.go`:
- Around line 221-231: The XML-like output in handlers_issues.go builds strings
with unescaped values (project, issue.SourceProject, issue.Title) which allows
injection; update the code where the strings.Builder is populated (the initial
sb.WriteString for "<open-issues ...>" and the per-issue sb.WriteString lines)
to escape values for the proper XML context—use a standard escape function
(e.g., html.EscapeString or xml.Escape) on project and issue.SourceProject when
used inside the attribute and on issue.Title (and any other text nodes) when
used in text content; ensure attribute values are quoted after escaping so
quotes/&/</> are neutralized before writing to sb.

In `@internal/worker/service.go`:
- Line 1086: The MCP server keeps a stale issue store after
reinitializeDatabase() recreates s.issueStore because SetIssueStore() is only
called during initial setup; update the MCP server to point to the new store
after reinitialization by calling mcpServer.SetIssueStore(s.issueStore) (or
equivalent setter) immediately after s.issueStore is replaced and before closing
the oldStore, and mirror the same fix for the other occurrence mentioned (around
the second spot where SetIssueStore is only called once). Ensure references to
mcpServer, SetIssueStore, reinitializeDatabase, s.issueStore and
oldStore.Close() are updated so handlers use the new store.
🪄 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: d48af92b-0354-4f39-bb24-f1bf79f155f6

📥 Commits

Reviewing files that changed from the base of the PR and between 37b290c and 02dc098.

📒 Files selected for processing (7)
  • internal/db/gorm/issue_store.go
  • internal/db/gorm/migrations.go
  • internal/db/gorm/models.go
  • internal/mcp/server.go
  • internal/mcp/tools_issues.go
  • internal/worker/handlers_issues.go
  • internal/worker/service.go

Comment thread internal/db/gorm/issue_store.go
Comment thread internal/db/gorm/issue_store.go
Comment thread internal/db/gorm/models.go
Comment thread internal/mcp/server.go
Comment on lines +967 to +987
{
Name: "issues",
Description: "Create, track, and resolve cross-project issues between agents. Issues are automatically shown to agents working on the target project. Use to report bugs, request features, or leave notes for agents in other projects.",
tier: tierCore,
InputSchema: map[string]any{
"type": "object",
"required": []string{"action"},
"properties": map[string]any{
"action": map[string]any{"type": "string", "enum": []string{"create", "list", "get", "update", "comment", "reopen"}, "description": "Action to perform"},
"title": map[string]any{"type": "string", "description": "Issue title (required for create)"},
"body": map[string]any{"type": "string", "description": "Issue body or comment text"},
"priority": map[string]any{"type": "string", "enum": []string{"critical", "high", "medium", "low"}, "default": "medium"},
"target_project": map[string]any{"type": "string", "description": "Target project slug (defaults to current project)"},
"labels": map[string]any{"type": "array", "items": map[string]any{"type": "string"}, "description": "Labels (bug, feature, etc.)"},
"id": map[string]any{"type": "integer", "description": "Issue ID (required for get/update/comment/reopen)"},
"status": map[string]any{"type": "string", "enum": []string{"resolved"}, "description": "Set status (only 'resolved' via update)"},
"comment": map[string]any{"type": "string", "description": "Comment to add with status change or reopen"},
"project": map[string]any{"type": "string", "description": "Filter by project (for list action)"},
},
},
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

issues сейчас не попадёт в tools/list.

Этот блок добавляется в tools, но на Line 1481 метод возвращает primary, а не tools, поэтому MCP-клиенты не увидят новый инструмент через discovery. Если issues должен быть доступен, его нужно добавить в реально возвращаемый набор и публиковать только при s.issueStore != nil.

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

In `@internal/mcp/server.go` around lines 967 - 987, The "issues" tool is being
registered in the local tools block but not included in the actual discovery
response returned by the method that currently returns "primary" (tools/list),
so clients won't see it; change the discovery-returning method to include the
"issues" entry in the returned tools set only when s.issueStore != nil (i.e.,
gate publishing of the issues tool on s.issueStore != nil) and ensure the tool
is added to the actual returned collection used by tools/list (not just the
local "primary" variable) so MCP clients can discover it.

@@ -0,0 +1,234 @@
package mcp
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Переименуйте файл по нумерованному шаблону MCP-tools.

tools_issues.go выбивается из принятой схемы именования; для новых MCP-обработчиков здесь нужен нумерованный файл вида tools_<nn>_issues.go.

As per coding guidelines, All MCP tool handlers (48 tools) must be implemented with numbered files (tools_*.go) in internal/mcp/.

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

In `@internal/mcp/tools_issues.go` at line 1, Rename the file
internal/mcp/tools_issues.go to follow the numbered MCP-tools pattern (e.g.,
internal/mcp/tools_01_issues.go) and update any references to that file name in
the repo (build scripts, go:generate directives, or tests) so the new filename
is used; ensure the package declaration (package mcp) and all symbols defined
inside remain unchanged so compilation behavior does not change.

Comment thread internal/worker/handlers_issues.go

// Wire reasoning trace store into MCP server for System 2 memory recall.
mcpServer.SetReasoningStore(reasoningStore)
mcpServer.SetIssueStore(issueStore)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

После reinitialize MCP-инструмент issues останется на старом store.

SetIssueStore() вызывается только при первичной инициализации. В reinitializeDatabase() вы пересоздаёте s.issueStore, но уже созданный mcpServer и его handlers продолжают держать старый экземпляр. После oldStore.Close() вызовы issues через MCP начнут работать через закрытый DB handle до перезапуска процесса.

Also applies to: 1321-1321

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

In `@internal/worker/service.go` at line 1086, The MCP server keeps a stale issue
store after reinitializeDatabase() recreates s.issueStore because
SetIssueStore() is only called during initial setup; update the MCP server to
point to the new store after reinitialization by calling
mcpServer.SetIssueStore(s.issueStore) (or equivalent setter) immediately after
s.issueStore is replaced and before closing the oldStore, and mirror the same
fix for the other occurrence mentioned (around the second spot where
SetIssueStore is only called once). Ensure references to mcpServer,
SetIssueStore, reinitializeDatabase, s.issueStore and oldStore.Close() are
updated so handlers use the new store.

CRITICAL:
- AddComment: verify issue exists before inserting (prevents orphan rows)

HIGH:
- Labels: changed from pq.StringArray to models.JSONStringArray (JSONB compat)

MAJOR:
- CreateIssue: validate status/priority before INSERT
- ReopenIssue: atomic status check via WHERE clause (race condition fix)
- XML escape in formatIssuesForInjection (prevents tag injection)
- handleUpdateIssue: move author metadata from query params to JSON body
- tools_issues: filter empty strings from status split

MEDIUM:
- MCP schema: noted agent_source/project fields (pre-existing pattern)
- Reinitialize stale store: documented as pre-existing architecture pattern
@thebtf thebtf merged commit a51a11d into main Apr 9, 2026
1 check failed
@thebtf thebtf deleted the feat/agent-issues branch May 7, 2026 06:34
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