From 8ec672ae0791c1f484912971cd1f1436ce6f720f Mon Sep 17 00:00:00 2001 From: logikonline Date: Wed, 11 Feb 2026 23:38:54 -0500 Subject: [PATCH] Create note-1770870661601-657f3az5c.json --- .notes/note-1770870661601-657f3az5c.json | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .notes/note-1770870661601-657f3az5c.json diff --git a/.notes/note-1770870661601-657f3az5c.json b/.notes/note-1770870661601-657f3az5c.json new file mode 100644 index 0000000..ba809b3 --- /dev/null +++ b/.notes/note-1770870661601-657f3az5c.json @@ -0,0 +1,8 @@ +{ + "id": "note-1770870661601-657f3az5c", + "title": "Plan - Implement", + "content": " GitCaddy Server-Side AI Integration Architecture\n\n Context\n\n GitCaddy server needs AI capabilities for automated repo operations: answering issues, reviewing\n PRs/workflows, inspecting code, performing small bug fixes, and escalating to staff. The system must\n support configuration at system, org, and repo levels, and enable both light AI operations and\n advanced agentic work (Claude Code headless).\n\n What Already Exists\n Component: gitcaddy-server\n Location: Plugin system, repo units, notifier, queues, Actions runners\n Status: Production\n ────────────────────────────────────────\n Component: gitcaddy-vault\n Location: Compile-time merge plugin (blank import + init())\n Status: Production\n ────────────────────────────────────────\n Component: gitcaddy-ai\n Location: .NET 9 gRPC service + Go client + proto definitions\n Status: Built, needs integration\n ────────────────────────────────────────\n Component: MarketAlly.AIPlugin\n Location: C# AI provider abstraction (Claude, OpenAI, Gemini)\n Status: Production\n ---\n Confirmed Architecture Decisions\n Decision: AI runtime\n Choice: Keep .NET gRPC sidecar\n Rationale: Already built, shares MarketAlly.AIPlugin with desktop, no rewrite\n ────────────────────────────────────────\n Decision: API key management\n Choice: Server passes per-request\n Rationale: Server resolves config cascade, AI service is stateless\n ────────────────────────────────────────\n Decision: Bot identity\n Choice: Dedicated system bot user\n Rationale: Clear attribution, loop prevention\n ────────────────────────────────────────\n Decision: Plugin framework\n Choice: gRPC protocol for server extensions\n Rationale: Language-agnostic, platform-independent, clean contract\n ────────────────────────────────────────\n Decision: Advanced agent work\n Choice: Leverage Actions runners\n Rationale: Reuse existing sandboxing, queuing, resource management\n ────────────────────────────────────────\n Decision: AI routing\n Choice: Server decides light vs heavy\n Rationale: Simple ops → gRPC AI service, complex ops → Actions runner with Claude Code\n ---\n Two Extension Mechanisms\n\n ┌──────────────────────────────────────────────────────────────┐\n │ gitcaddy-server (Go) │\n │ │\n │ ┌─────────────┐ ┌────────────────────────────────────┐ │\n │ │ Core Modules │ │ AI Integration Layer │ │\n │ │ (compiled) │ │ │ │\n │ │ • Vault │ │ Event → evaluate → route to: │ │\n │ └─────────────┘ │ ├─ Tier 1 (gRPC AI service) │ │\n │ │ └─ Tier 2 (Actions runner) │ │\n │ ┌─────────────────────────────────────────────────────┐ │ │\n │ │ gRPC Plugin Manager │ │ │\n │ │ • Plugin discovery & lifecycle │ │ │\n │ │ • Event routing to interested plugins │ │ │\n │ │ • API route proxying │ │ │\n │ └──────────────┬──────────────────────────────────────┘ │ │\n └─────────────────┼────────────────────────────────────────────┘\n │ gRPC\n ┌─────────┼──────────┐\n ┌────▼───┐ ┌──▼─────┐ ┌▼────────┐\n │ AI Svc │ │ Future │ │ Future │\n │ (.NET) │ │ Plugin │ │ Plugin │\n └────────┘ └─────────┘ └─────────┘\n\n Actions Runners (existing infrastructure):\n ┌──────────────────────────────────┐\n │ Runner with Claude Code installed │ ← Tier 2 advanced agent work\n │ • Clones repo │\n │ • Runs Claude Code headless │\n │ • Creates branches, PRs │\n │ • Sandboxed, resource-limited │\n └──────────────────────────────────┘\n\n Tier 1: gRPC AI Service (Light Operations)\n\n - Request/response pattern, completes in seconds\n - PR review comments, issue triage/labels, issue responses\n - Workflow inspection, code explanation, doc generation\n - Uses existing gitcaddy-ai .NET service via Go gRPC client\n\n Tier 2: Actions Runner (Advanced Agent Work)\n\n - Long-running agent sessions, minutes to hours\n - Full repo checkout, code modification, testing\n - Claude Code headless running autonomously\n - Creates branches, submits PRs, iterates on feedback\n - Sandboxed execution with resource limits\n - Server triggers via a built-in workflow template\n\n Routing Logic\n\n Event arrives (issue created, PR opened, etc.)\n │\n ▼\n AI Notifier checks repo config\n │\n ├─ Is AI unit enabled for this repo? No → skip\n │\n ├─ Is this operation enabled? No → skip\n │\n ├─ Rate limit check → exceeded → skip + log\n │\n ├─ Is this a Tier 1 operation? (review, triage, respond)\n │ └─ Queue → gRPC call to AI service → post result\n │\n └─ Is this a Tier 2 operation? (bug fix, code change)\n └─ Queue → Trigger Actions workflow → Claude Code runner\n └─ Runner does work → creates PR → notifies staff\n\n ---\n gRPC Plugin Protocol\n\n Plugin Contract (proto definition)\n\n // gitcaddy_plugin.proto — the contract all gRPC plugins implement\n\n service GitCaddyPlugin {\n // Lifecycle\n rpc Initialize(PluginInitRequest) returns (PluginInitResponse);\n rpc Shutdown(google.protobuf.Empty) returns (PluginStatus);\n rpc HealthCheck(google.protobuf.Empty) returns (PluginStatus);\n\n // Discovery\n rpc GetManifest(google.protobuf.Empty) returns (PluginManifest);\n\n // Event handling\n rpc OnEvent(PluginEvent) returns (PluginEventResponse);\n\n // HTTP route proxying (optional — for plugins that serve API routes)\n rpc HandleHTTPRequest(HTTPRequest) returns (HTTPResponse);\n }\n\n message PluginManifest {\n string name = 1;\n string version = 2;\n string description = 3;\n repeated string subscribed_events = 4; // [\"issue.created\", \"pull_request.opened\"]\n repeated PluginRoute routes = 5; // API routes this plugin serves\n repeated string required_permissions = 6; // [\"read:code\", \"write:issues\"]\n string license_tier = 7; // \"solo\", \"pro\", \"team\", \"enterprise\"\n }\n\n Plugin Manager (modules/plugins/manager.go)\n\n New addition to the existing plugin system:\n - Discovers plugin binaries in configured directory\n - Launches plugin processes on server startup\n - Establishes gRPC connections\n - Routes events to plugins based on subscribed_events\n - Proxies HTTP requests to plugin-served routes\n - Health monitoring and auto-restart\n - Graceful shutdown\n\n Plugin Configuration in app.ini\n\n [plugins]\n ENABLED = true\n PATH = APP_DATA_PATH/plugins ; directory for plugin binaries\n SCAN_INTERVAL = 60 ; seconds between plugin discovery scans\n\n [plugins.gitcaddy-ai]\n ENABLED = true\n ; For managed plugins (server launches the binary):\n BINARY = gitcaddy-ai ; binary name in plugins directory\n ARGS = --port 0 ; auto-assign port\n ; For external plugins (already running):\n ; ADDRESS = localhost:5051 ; connect to existing service\n\n ---\n Server Integration Components\n\n Existing v2 AI Infrastructure (already built)\n\n The v2 API at routers/api/v2/ already provides AI context endpoints for tools:\n Endpoint: POST /api/v2/ai/repo/summary\n File: ai_context.go:98\n Purpose: Rich repo info for AI (structure, languages, hints)\n ────────────────────────────────────────\n Endpoint: POST /api/v2/ai/repo/navigation\n File: ai_context.go:284\n Purpose: Directory tree, important paths, file types\n ────────────────────────────────────────\n Endpoint: POST /api/v2/ai/issue/context\n File: ai_context.go:388\n Purpose: Issue details, comments, code refs, complexity hints\n ────────────────────────────────────────\n Endpoint: POST /api/v2/mcp\n File: mcp.go\n Purpose: MCP protocol for AI tool integration\n ────────────────────────────────────────\n Endpoint: GET /api/v2/operations/{id}/progress\n File: operations.go\n Purpose: SSE operation progress tracking\n These provide context to AI. What we're adding is AI operations by the server.\n\n New Files in gitcaddy-server\n\n gitcaddy-server/\n ├── models/ai/\n │ ├── settings.go # Org-level AI configuration model\n │ └── operation_log.go # AI operation audit log model\n ├── modules/setting/ai.go # System-level [ai] config from app.ini\n ├── modules/plugins/\n │ ├── manager.go # gRPC plugin lifecycle manager (NEW)\n │ └── protocol.go # Plugin proto client helpers (NEW)\n ├── services/ai/\n │ ├── client.go # Wraps gRPC client with config cascade\n │ ├── notifier.go # Event → AI operation routing\n │ ├── queue.go # Async operation queue\n │ ├── operations.go # Operation definitions & handlers\n │ ├── escalation.go # Staff escalation logic\n │ └── agent.go # Tier 2 Actions workflow trigger\n ├── routers/api/v2/ai_operations.go # Repo-scoped AI operations API (v2)\n ├── routers/api/v2/ai_settings.go # AI settings API (v2)\n └── routers/web/repo/ai.go # Web UI settings page\n\n Modified Files\n\n models/unit/unit.go # Add TypeAI = 11\n models/repo/repo_unit.go # Add AIConfig struct\n routers/init.go # Initialize AI service + plugin manager\n routers/api/v2/api.go # Register new AI routes in existing v2 router\n routers/web/web.go # Register AI web routes\n modules/setting/setting.go # Load AI settings\n\n ---\n 1. System-Level Configuration (modules/setting/ai.go)\n\n New [ai] section in app.ini:\n\n [ai]\n ENABLED = true\n ; Default provider/model (fallback when org doesn't configure)\n DEFAULT_PROVIDER = claude\n DEFAULT_MODEL = claude-sonnet-4-20250514\n ; System API keys (used when org/repo doesn't provide their own)\n CLAUDE_API_KEY = sk-ant-...\n OPENAI_API_KEY = sk-...\n GEMINI_API_KEY = ...\n ; Rate limiting\n MAX_OPERATIONS_PER_HOUR = 100 ; per repo\n MAX_TOKENS_PER_OPERATION = 8192\n ; Feature gates (admin controls what's available)\n ALLOW_AUTO_RESPOND = true\n ALLOW_AUTO_REVIEW = true\n ALLOW_AGENT_MODE = false ; Tier 2 — admin must explicitly enable\n ; Bot user\n BOT_USER_NAME = gitcaddy-ai ; system bot user for AI comments/reviews\n\n ---\n 2. Repo Unit Type\n\n Add TypeAI = 11 to models/unit/unit.go.\n\n AIConfig in models/repo/repo_unit.go:\n\n type AIConfig struct {\n // Tier 1: Light AI operations\n AutoRespondToIssues bool `json:\"auto_respond_issues\"`\n AutoReviewPRs bool `json:\"auto_review_prs\"`\n AutoInspectWorkflows bool `json:\"auto_inspect_workflows\"`\n AutoTriageIssues bool `json:\"auto_triage_issues\"`\n\n // Tier 2: Advanced agent operations\n AgentModeEnabled bool `json:\"agent_mode_enabled\"`\n AgentTriggerLabels []string `json:\"agent_trigger_labels\"` // e.g., [\"ai-fix\"]\n AgentMaxRunMinutes int `json:\"agent_max_run_minutes\"` // default 30\n\n // Escalation\n EscalateToStaff bool `json:\"escalate_to_staff\"`\n EscalationLabel string `json:\"escalation_label\"` // e.g., \"needs-human\"\n EscalationAssignTeam string `json:\"escalation_assign_team\"`\n\n // Provider overrides (empty = inherit from org → system)\n PreferredProvider string `json:\"preferred_provider\"`\n PreferredModel string `json:\"preferred_model\"`\n\n // Custom instructions\n SystemInstructions string `json:\"system_instructions\"`\n ReviewInstructions string `json:\"review_instructions\"`\n IssueInstructions string `json:\"issue_instructions\"`\n }\n\n ---\n 3. Org-Level AI Settings (models/ai/settings.go)\n\n type OrgAISettings struct {\n ID int64 `xorm:\"pk autoincr\"`\n OrgID int64 `xorm:\"UNIQUE NOT NULL INDEX\"`\n Provider string `xorm:\"NOT NULL DEFAULT ''\"`\n Model string `xorm:\"NOT NULL DEFAULT ''\"`\n APIKeyEncrypted string `xorm:\"TEXT\"` // encrypted at rest\n MaxOpsPerHour int `xorm:\"NOT NULL DEFAULT 0\"` // 0 = system default\n AllowedOps string `xorm:\"TEXT\"` // JSON array\n AgentModeAllowed bool `xorm:\"NOT NULL DEFAULT 0\"`\n CreatedUnix timeutil.TimeStamp `xorm:\"INDEX CREATED\"`\n UpdatedUnix timeutil.TimeStamp `xorm:\"INDEX UPDATED\"`\n }\n\n Configuration Resolution (most specific wins):\n Repo AIConfig.PreferredProvider → if empty:\n OrgAISettings.Provider → if empty:\n setting.AI.DefaultProvider → \"claude\"\n Same cascade for model and API key.\n\n ---\n 4. AI Operation Audit Log (models/ai/operation_log.go)\n\n type OperationLog struct {\n ID int64 `xorm:\"pk autoincr\"`\n RepoID int64 `xorm:\"INDEX NOT NULL\"`\n Operation string `xorm:\"NOT NULL\"` // \"code-review\", \"issue-response\",\n etc.\n Tier int `xorm:\"NOT NULL\"` // 1 or 2\n TriggerEvent string `xorm:\"NOT NULL\"` // \"issue.created\"\n TriggerUserID int64 `xorm:\"INDEX\"`\n TargetID int64 `xorm:\"INDEX\"` // issue/PR ID\n TargetType string // \"issue\", \"pull\", \"commit\"\n Provider string // which AI provider was used\n Model string // which model\n InputTokens int\n OutputTokens int\n Status string `xorm:\"NOT NULL\"` // \"success\", \"failed\", \"escalated\"\n ResultCommentID int64 // comment/review ID created\n ActionRunID int64 // for Tier 2, the Actions run ID\n ErrorMessage string `xorm:\"TEXT\"`\n DurationMs int64\n CreatedUnix timeutil.TimeStamp `xorm:\"INDEX CREATED\"`\n }\n\n ---\n 5. AI Notifier (services/ai/notifier.go)\n\n Registers with notify_service, listens for events, routes to Tier 1 or Tier 2:\n\n func init() {\n notify_service.RegisterNotifier(NewAINotifier())\n }\n\n type aiNotifier struct {\n notify_service.NullNotifier\n }\n\n Event → Operation Mapping:\n Notifier Method: NewIssue()\n Condition: auto_respond_issues\n Tier: 1\n Operation: issue-response + issue-triage\n ────────────────────────────────────────\n Notifier Method: CreateIssueComment()\n Condition: Comment mentions bot or asks question\n Tier: 1\n Operation: issue-response\n ────────────────────────────────────────\n Notifier Method: NewPullRequest()\n Condition: auto_review_prs\n Tier: 1\n Operation: code-review\n ────────────────────────────────────────\n Notifier Method: PullRequestSynchronized()\n Condition: auto_review_prs\n Tier: 1\n Operation: code-review (re-review)\n ────────────────────────────────────────\n Notifier Method: PushCommits()\n Condition: auto_inspect_workflows + has workflow files\n Tier: 1\n Operation: workflow-inspect\n ────────────────────────────────────────\n Notifier Method: IssueChangeLabels()\n Condition: Label matches agent_trigger_labels\n Tier: 2\n Operation: agent-fix\n Loop prevention: Skip all events where the doer is the AI bot user.\n\n ---\n 6. Queue & Async Processing (services/ai/queue.go)\n\n var aiOperationQueue *queue.WorkerPoolQueue[*AIOperationRequest]\n\n func InitQueue(ctx context.Context) {\n aiOperationQueue = queue.CreateUniqueQueue(ctx, \"ai_operations\", handleAIOperation)\n }\n\n Worker handler for Tier 1:\n 1. Load repo + org settings, resolve provider/model/key cascade\n 2. Build gRPC request with resolved config\n 3. Call gitcaddy-ai service (ReviewPullRequest, GenerateIssueResponse, etc.)\n 4. Process response → create comment/review via existing services\n 5. Check confidence → escalate if needed\n 6. Log to operation_log table\n\n Worker handler for Tier 2:\n 1. Load repo + org settings\n 2. Generate a workflow YAML for Claude Code headless run\n 3. Trigger via services/actions.DispatchActionWorkflow()\n 4. Log the action run ID to operation_log for tracking\n\n ---\n 7. Tier 2: Claude Code Agent via Actions (services/ai/agent.go)\n\n When a Tier 2 operation is triggered, the server generates and dispatches an Actions workflow:\n\n # Auto-generated workflow for AI agent task\n name: AI Agent - Fix Issue #{issue_number}\n on: workflow_dispatch\n jobs:\n ai-fix:\n runs-on: [ai-runner] # label for runners with Claude Code\n timeout-minutes: 30\n steps:\n - uses: actions/checkout@v4\n with:\n fetch-depth: 0\n - name: Run Claude Code\n env:\n ANTHROPIC_API_KEY: ${{ secrets.AI_API_KEY }}\n CLAUDE_MODEL: ${{ inputs.model }}\n run: |\n claude --headless \\\n --system-prompt \"$SYSTEM_PROMPT\" \\\n --prompt \"Investigate and fix issue #${ISSUE_NUMBER}: ${ISSUE_TITLE}\\n\\n${ISSUE_BODY}\" \\\n --allowedTools \"Edit,Read,Bash,Grep,Glob\" \\\n --max-turns 50\n - name: Create PR\n if: success()\n run: |\n git checkout -b ai/fix-issue-${ISSUE_NUMBER}\n git add -A\n git commit -m \"fix: address issue #${ISSUE_NUMBER}\"\n git push origin ai/fix-issue-${ISSUE_NUMBER}\n # Create PR via API\n\n The server:\n - Generates this workflow dynamically based on the operation\n - Injects repo-specific system instructions from AIConfig\n - Sets the API key from the resolved config cascade\n - Tracks the run ID for status monitoring\n - Posts updates on the issue as the agent works\n\n Runner Requirements:\n - Runners labeled ai-runner must have Claude Code CLI installed\n - Standard Actions runner infrastructure handles scheduling, sandboxing, logs\n\n ---\n 8. Escalation (services/ai/escalation.go)\n\n When AI determines it can't handle something (Tier 1: low confidence response, Tier 2: agent fails):\n\n 1. Add the configured escalation label (e.g., needs-human-review)\n 2. Post a comment as the bot user:\n \"I've analyzed this but believe a team member should review. Here's what I found: [summary]\"\n 3. If escalation_assign_team is set, assign to a team member\n 4. Log as \"escalated\" in operation_log\n\n ---\n 9. API Endpoints (v2)\n\n All new endpoints in routers/api/v2/. Builds on existing v2 patterns (idempotency, structured errors,\n operations tracking).\n\n Repo-scoped (/api/v2/repos/{owner}/{repo}/ai/)\n\n New file: routers/api/v2/ai_operations.go\n ┌────────┬──────────────────┬────────────┬──────────────────────────────────────────────────┐\n │ Method │ Path │ Auth │ Description │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ GET │ /settings │ repo read │ Get repo AI settings │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ PUT │ /settings │ repo admin │ Update repo AI settings │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ GET │ /operations │ repo read │ List AI operation log (paginated) │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ GET │ /operations/{id} │ repo read │ Get operation detail + result │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ POST │ /review/{pull} │ repo write │ Manually trigger PR review (Tier 1) │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ POST │ /respond/{issue} │ repo write │ Manually trigger issue response (Tier 1) │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ POST │ /triage/{issue} │ repo write │ Manually trigger issue triage (Tier 1) │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ POST │ /explain │ repo read │ Explain code (body: file path + range) (Tier 1) │\n ├────────┼──────────────────┼────────────┼──────────────────────────────────────────────────┤\n │ POST │ /fix/{issue} │ repo write │ Trigger agent fix (Tier 2, returns operation ID) │\n └────────┴──────────────────┴────────────┴──────────────────────────────────────────────────┘\n Tier 2 operations return an operation ID that can be tracked via existing GET\n /api/v2/operations/{id}/progress SSE endpoint.\n\n Org-scoped (/api/v2/orgs/{org}/ai/)\n\n New file: routers/api/v2/ai_settings.go\n ┌────────┬───────────┬───────────┬───────────────────────────────────────────────┐\n │ Method │ Path │ Auth │ Description │\n ├────────┼───────────┼───────────┼───────────────────────────────────────────────┤\n │ GET │ /settings │ org admin │ Get org AI settings │\n ├────────┼───────────┼───────────┼───────────────────────────────────────────────┤\n │ PUT │ /settings │ org admin │ Update org AI settings (provider, model, key) │\n └────────┴───────────┴───────────┴───────────────────────────────────────────────┘\n Admin (/api/v2/admin/ai/)\n ┌────────┬─────────────┬────────────┬──────────────────────────────────┐\n │ Method │ Path │ Auth │ Description │\n ├────────┼─────────────┼────────────┼──────────────────────────────────┤\n │ GET │ /status │ site admin │ AI service health + global stats │\n ├────────┼─────────────┼────────────┼──────────────────────────────────┤\n │ GET │ /operations │ site admin │ Global operation log │\n └────────┴─────────────┴────────────┴──────────────────────────────────┘\n Route Registration in routers/api/v2/api.go\n\n Added inside the existing Routes() function:\n // AI operations - repo-scoped\n m.Group(\"/repos/{owner}/{repo}/ai\", func() {\n m.Get(\"/settings\", GetRepoAISettings)\n m.Put(\"/settings\", reqToken(), web.Bind(api.UpdateAISettingsOption{}), UpdateRepoAISettings)\n m.Get(\"/operations\", ListAIOperations)\n m.Get(\"/operations/{id}\", GetAIOperation)\n m.Post(\"/review/{pull}\", reqToken(), TriggerAIReview)\n m.Post(\"/respond/{issue}\", reqToken(), TriggerAIRespond)\n m.Post(\"/triage/{issue}\", reqToken(), TriggerAITriage)\n m.Post(\"/explain\", reqToken(), web.Bind(api.AIExplainRequest{}), TriggerAIExplain)\n m.Post(\"/fix/{issue}\", reqToken(), TriggerAIFix)\n }, repoAssignment())\n\n // AI settings - org-scoped\n m.Group(\"/orgs/{org}/ai\", func() {\n m.Get(\"/settings\", GetOrgAISettings)\n m.Put(\"/settings\", web.Bind(api.UpdateOrgAISettingsOption{}), UpdateOrgAISettings)\n }, reqToken())\n\n // AI admin\n m.Group(\"/admin/ai\", func() {\n m.Get(\"/status\", GetAIServiceStatus)\n m.Get(\"/operations\", ListAllAIOperations)\n }, reqToken(), reqSiteAdmin())\n\n The existing v2 /ai/ context endpoints (repo/summary, repo/navigation, issue/context) remain as-is —\n they provide context TO AI tools. The new repo-scoped endpoints are AI operations BY the server.\n\n ---\n 10. Security\n\n - API keys: Encrypted at rest using setting.SecretKey, same as existing secrets\n - Bot user: Dedicated system user (gitcaddy-ai), created on first init\n - Loop prevention: AI notifier skips events from bot user\n - Rate limiting: Per-repo ops/hour, configurable at system/org level\n - Permissions: Manual triggers require repo write; settings require admin\n - Admin gates: System admin can globally disable risky features (agent mode, auto-respond)\n - Audit trail: Every operation logged with provider, tokens, result, duration\n - Tier 2 sandboxing: Runs in Actions runner containers with standard isolation\n\n ---\n 11. Proto Enhancement for gitcaddy-ai\n\n The existing proto needs a ProviderConfig message added to support per-request provider resolution:\n\n message ProviderConfig {\n string provider = 1; // \"claude\", \"openai\", \"gemini\"\n string model = 2; // model ID\n string api_key = 3; // resolved API key (encrypted in transit via TLS)\n int32 max_tokens = 4;\n double temperature = 5;\n }\n\n // Added to each existing request message:\n message ReviewPullRequestRequest {\n ProviderConfig provider_config = 10; // NEW\n // ... existing fields ...\n }\n\n ---\n Implementation Order\n\n Phase 1: Foundation\n\n 1. modules/setting/ai.go — System config loading from [ai] section in app.ini\n 2. models/ai/settings.go + operation_log.go — Database models + migrations\n 3. models/unit/unit.go — Add TypeAI = 11 unit type\n 4. models/repo/repo_unit.go — Add AIConfig struct with FromDB()/ToDB()\n 5. Bot user creation in routers/init.go server startup\n\n Phase 2: Tier 1 Integration\n\n 6. Proto update in gitcaddy-ai — Add ProviderConfig message to requests\n 7. services/ai/client.go — gRPC client wrapper with config cascade resolution\n 8. services/ai/queue.go — ai_operations queue via queue.CreateUniqueQueue()\n 9. services/ai/operations.go — Tier 1 operation handlers mapping to gRPC methods\n 10. services/ai/notifier.go — Notifier registered with notify_service.RegisterNotifier()\n 11. services/ai/escalation.go — Label + comment + team assignment\n\n Phase 3: v2 API & UI\n\n 12. routers/api/v2/ai_operations.go — Repo-scoped AI operation endpoints\n 13. routers/api/v2/ai_settings.go — Org + admin AI settings endpoints\n 14. routers/api/v2/api.go — Register new routes in existing v2 router\n 15. routers/web/repo/ai.go — Settings UI page\n 16. Leverage existing GET /api/v2/operations/{id}/progress for Tier 2 tracking\n\n Phase 4: Tier 2 Agent Mode\n\n 17. services/ai/agent.go — Actions workflow generation + DispatchActionWorkflow()\n 18. Runner setup documentation (Claude Code installation on ai-runner labeled runners)\n 19. Agent status tracking — updates posted on issues as agent works\n\n Phase 5: Plugin Framework (Future)\n\n 20. modules/plugins/manager.go — gRPC plugin lifecycle manager\n 21. protos/gitcaddy_plugin.proto — Plugin contract definition\n 22. Plugin discovery, launch, health monitoring\n 23. Event routing + HTTP proxying for plugin-served routes\n\n ---\n Verification\n\n - Config: Unit tests for cascade resolution (repo → org → system)\n - Tier 1: Integration test — create issue → notifier fires → operation queued → gRPC called → comment\n posted\n - Tier 2: Integration test — add label → agent workflow triggered → Actions run created\n - Rate limiting: Verify ops/hour limits prevent excessive operations\n - Loop prevention: Bot user events are skipped\n - Escalation: Low confidence → label added + comment posted + team assigned\n - Permissions: All API endpoints enforce correct auth middleware\n - End-to-end: Docker Compose with gitcaddy-server + gitcaddy-ai + runner for full testing", + "createdAt": 1770870661600, + "updatedAt": 1770871100847, + "tags": [] +} \ No newline at end of file