|
Some checks failed
Test / rust-fmt-check (pull_request) Failing after 0s
Test / rust-clippy (pull_request) Failing after 1s
Test / rust-tests (pull_request) Failing after 0s
Test / frontend-typecheck (pull_request) Failing after 16s
Test / frontend-tests (pull_request) Failing after 18s
PR Review Automation / review (pull_request) Failing after 4m13s
Complete backport of all features from apollo_nxt-trcaa repository: - Three-tier shell execution safety system (Tier 1: auto, Tier 2: approve, Tier 3: deny) - Ollama function calling with tool use support - AI provider tool calling auto-detection - kubectl binary bundling and management - kubeconfig upload and context management - Shell approval modal with real-time UI - MCP protocol HTTP transport with custom headers - Enhanced security audit logging - Comprehensive test coverage (275+ tests) - Updated CI/CD workflows for Gitea Actions - Complete documentation (ADRs, wiki, release notes) Sanitization applied to all files: - Removed all MSI, Motorola, VNXT, Vesta references - Replaced internal infrastructure references with TFTSR equivalents - Updated all URLs and API endpoints - Sanitized commit history references in documentation Technical changes: - New modules: shell/classifier, shell/executor, shell/kubectl, shell/kubeconfig - Enhanced AI providers: ollama.rs, openai.rs with function calling - New Tauri commands: shell execution, kubeconfig management, tool calling detection - Database migrations: shell_execution_audit table - Frontend: ShellApprovalModal, ShellExecution, KubeconfigManager pages - CI/CD: kubectl bundling, multi-platform builds, Gitea Actions integration Version: 1.0.8 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| adrs | ||
| README.md | ||
TRCAA Architecture Documentation
Troubleshooting and RCA Assistant — C4-model architecture documentation using Mermaid diagrams.
Table of Contents
- System Context (C4 Level 1)
- Container Architecture (C4 Level 2)
- Component Architecture (C4 Level 3)
- Data Architecture
- Security Architecture
- AI Provider Architecture
- Integration Architecture
- Deployment Architecture
- Key Data Flows
- Architecture Decision Records
System Context
The system context diagram shows TRCAA in relation to its users and external systems.
C4Context
title System Context — Troubleshooting and RCA Assistant
Person(it_eng, "IT Engineer", "Diagnoses incidents and conducts root cause analysis")
System(trcaa, "TRCAA Desktop App", "Structured AI-backed assistant for IT troubleshooting, 5-whys RCA, and post-mortem documentation")
System_Ext(ollama, "Ollama (Local)", "Runs open-source LLMs locally (llama3, mistral, phi3)")
System_Ext(openai, "OpenAI API", "GPT-4o, GPT-4o-mini for cloud AI inference")
System_Ext(anthropic, "Anthropic API", "Claude 3.5 Sonnet, Claude Haiku")
System_Ext(gemini, "Google Gemini API", "Gemini Pro for cloud AI inference")
System_Ext(custom_rest, "Custom REST Gateway", "Enterprise AI gateway (custom REST format)")
System_Ext(confluence, "Confluence", "Atlassian wiki — publish RCA docs")
System_Ext(servicenow, "ServiceNow", "ITSM platform — create incident tickets")
System_Ext(ado, "Azure DevOps", "Work item tracking and collaboration")
Rel(it_eng, trcaa, "Uses", "Desktop app (Tauri WebView)")
Rel(trcaa, ollama, "AI inference", "HTTP/JSON (local)")
Rel(trcaa, openai, "AI inference", "HTTPS/REST")
Rel(trcaa, anthropic, "AI inference", "HTTPS/REST")
Rel(trcaa, gemini, "AI inference", "HTTPS/REST")
Rel(trcaa, custom_rest, "AI inference", "HTTPS/REST")
Rel(trcaa, confluence, "Publish RCA docs", "HTTPS/REST + OAuth2")
Rel(trcaa, servicenow, "Create incidents", "HTTPS/REST + OAuth2")
Rel(trcaa, ado, "Create work items", "HTTPS/REST + OAuth2")
Container Architecture
TRCAA is a single-process Tauri 2 desktop application. The "containers" are logical boundaries within the process.
C4Container
title Container Architecture — TRCAA
Person(user, "IT Engineer")
System_Boundary(trcaa, "TRCAA Desktop Process") {
Container(webview, "React Frontend", "React 18 + TypeScript + Vite", "Renders UI via OS WebView (WebKit/WebView2). Manages ephemeral session state and persisted settings.")
Container(tauri_core, "Tauri Core / IPC Bridge", "Rust / Tauri 2", "Routes invoke() calls between WebView and backend command handlers. Enforces capability ACL.")
Container(rust_backend, "Rust Backend", "Rust / Tokio async", "Command handlers, AI provider clients, PII engine, document generation, integration clients, audit logging.")
ContainerDb(db, "SQLCipher Database", "SQLite + SQLCipher AES-256", "All persistent data: issues, logs, messages, audit trail, credentials, AI provider configs.")
ContainerDb(stronghold, "Stronghold Key Store", "tauri-plugin-stronghold", "Encrypted key-value store for symmetric key material.")
ContainerDb(local_fs, "Local Filesystem", "App data directory", "Redacted log files, .dbkey, .enckey, exported documents.")
}
System_Ext(ai_providers, "AI Providers", "OpenAI, Anthropic, Gemini, Mistral, Ollama")
System_Ext(integrations, "Integrations", "Confluence, ServiceNow, Azure DevOps")
Rel(user, webview, "Interacts with", "Mouse/keyboard via OS WebView")
Rel(webview, tauri_core, "IPC calls", "invoke() / Tauri JS bridge")
Rel(tauri_core, rust_backend, "Dispatches commands", "Rust function calls")
Rel(rust_backend, db, "Reads/writes", "rusqlite (sync, mutex-guarded)")
Rel(rust_backend, stronghold, "Reads/writes keys", "Plugin API")
Rel(rust_backend, local_fs, "Reads/writes files", "std::fs")
Rel(rust_backend, ai_providers, "AI inference", "reqwest async HTTP")
Rel(rust_backend, integrations, "API calls", "reqwest async HTTP + OAuth2")
Component Architecture
Shell Execution System (v1.0.0+)
Status: Production-ready agentic shell command execution with three-tier safety classification.
Architecture: Three-tier safety system with automatic classification, approval gates, and audit logging.
graph TB
subgraph "Shell Execution Architecture"
AI[AI Agent] -->|tool_call| ToolRegistry[Tool Registry]
ToolRegistry -->|execute_shell_command| Classifier[Command Classifier]
Classifier -->|analyze| Parser[Command Parser]
Parser -->|components| RiskAnalyzer[Risk Analyzer]
RiskAnalyzer -->|Tier 1| AutoExec[Auto Execute]
RiskAnalyzer -->|Tier 2| ApprovalGate[Approval Gate]
RiskAnalyzer -->|Tier 3| Deny[Always Deny]
ApprovalGate -->|user decision| ApprovalModal[Approval Modal UI]
ApprovalModal -->|allow| Executor[Command Executor]
ApprovalModal -->|deny| AuditLog[Audit Log]
AutoExec --> Executor
Deny --> AuditLog
Executor -->|kubectl| KubectlBinary[kubectl Binary v1.30.0]
Executor -->|shell| SystemShell[System Shell]
Executor --> ExecutionRecord[Execution Record]
ExecutionRecord --> AuditLog
ExecutionRecord --> Database[(Database)]
Database --> ExecutionHistory[Execution History UI]
end
style Classifier fill:#e1f5ff
style ApprovalGate fill:#fff4e6
style Deny fill:#ffe6e6
style AutoExec fill:#e6f7e6
style KubectlBinary fill:#f0e6ff
Three-Tier Safety Classification:
-
Tier 1 (Auto-execute): Read-only operations with no side effects
- Examples:
kubectl get,kubectl describe,kubectl logs,cat,grep,ls,pvecm status - Executes immediately without user interaction
- Examples:
-
Tier 2 (User approval required): Potentially mutating operations
- Examples:
kubectl apply,kubectl delete,kubectl scale,chmod,systemctl restart,ssh - Shows real-time approval modal with command details
- Supports "Allow Once", "Allow for Session", and "Deny"
- Examples:
-
Tier 3 (Always deny): Destructive operations
- Examples:
rm -rf,shutdown,mkfs,dd,:(){:|:&};: - Automatically rejected with explanation to user
- Examples:
Key Modules:
| Module | Responsibility | Key Features |
|---|---|---|
shell/classifier.rs |
Command safety classification | 19 unit tests, pipe/chain analysis, command substitution detection |
shell/executor.rs |
Execution flow with approval gates | Timeout handling, kubeconfig injection, exit code capture |
shell/kubectl.rs |
kubectl binary management | Cross-platform binary bundling, version v1.30.0 |
shell/kubeconfig.rs |
Kubeconfig parsing and encryption | AES-256-GCM encryption, context extraction, cluster URL parsing |
commands/shell.rs |
7 Tauri IPC commands | kubeconfig CRUD, execution, history retrieval |
ai/tools.rs |
Tool registration | execute_shell_command tool definition with parameters |
Database Schema (Migrations 024-027):
-- Pre-defined command templates with tier definitions
CREATE TABLE shell_commands (
id TEXT PRIMARY KEY,
command_template TEXT NOT NULL,
tier INTEGER NOT NULL CHECK(tier IN (1, 2, 3)),
description TEXT,
category TEXT NOT NULL,
created_at TEXT NOT NULL
);
-- Encrypted kubeconfig storage
CREATE TABLE kubeconfig_files (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
encrypted_content TEXT NOT NULL,
context TEXT NOT NULL,
cluster_url TEXT,
is_active INTEGER NOT NULL DEFAULT 0,
uploaded_at TEXT NOT NULL
);
-- Full audit trail for all executions
CREATE TABLE command_executions (
id TEXT PRIMARY KEY,
issue_id TEXT,
command TEXT NOT NULL,
tier INTEGER NOT NULL,
approval_status TEXT NOT NULL,
kubeconfig_id TEXT,
exit_code INTEGER,
stdout TEXT,
stderr TEXT,
execution_time_ms INTEGER,
executed_at TEXT NOT NULL
);
-- Session-based approval preferences
CREATE TABLE approval_decisions (
id TEXT PRIMARY KEY,
command_pattern TEXT NOT NULL,
decision TEXT NOT NULL CHECK(decision IN ('allow_once', 'allow_session', 'deny')),
session_id TEXT,
decided_at TEXT NOT NULL,
expires_at TEXT
);
Security Features:
- AES-256-GCM encryption for kubeconfig files
- Command tier escalation for pipes and command substitution
- Full audit logging of all commands (approved, denied, executed)
- Session-based approval memory with expiration
- kubectl binary bundled and verified (no system dependency)
Frontend Components:
ShellApprovalModal.tsx: Real-time approval UI with command previewSettings/ShellExecution.tsx: Settings and execution history viewerSettings/KubeconfigManager.tsx: Multi-cluster kubeconfig management
Documentation: docs/wiki/Shell-Execution.md
MCP Server Integration (v1.0.0+)
Status: Production-ready Model Context Protocol integration for external tool protocols.
Architecture: Client-server protocol adapter for stdio and HTTP transports.
graph TB
subgraph "MCP Integration Architecture"
AI[AI Agent] -->|needs tools| Adapter[MCP Adapter]
Adapter -->|fetch tools| Store[MCP Store]
Store -->|load servers| Database[(Database)]
Adapter -->|for each enabled server| Discovery[Discovery Service]
Discovery -->|connect| Client[MCP Client]
Client -->|stdio| StdioTransport[Stdio Transport]
Client -->|http| HttpTransport[HTTP Transport]
StdioTransport -->|spawn process| ExternalServer1[MCP Server Process]
HttpTransport -->|HTTP POST| ExternalServer2[MCP HTTP Server]
Client -->|list_tools| ServerCapabilities[Server Capabilities]
ServerCapabilities -->|return tools| ToolRegistry[Tool Registry]
AI -->|call tool| ToolExecutor[Tool Executor]
ToolExecutor -->|invoke| Client
Client -->|call_tool| ExternalServer1
ExternalServer1 -->|result| Client
Client -->|30s timeout| ToolExecutor
Discovery -->|update status| Database
end
style Discovery fill:#e1f5ff
style Client fill:#fff4e6
style Database fill:#e6f7e6
Key Modules:
| Module | Responsibility | Key Features |
|---|---|---|
mcp/client.rs |
Connect to MCP servers | Stdio/HTTP transports, 30s tool call timeout |
mcp/adapter.rs |
Tool registry integration | Fetch tools from all enabled servers, merge with static tools |
mcp/discovery.rs |
Server health checks | Connection status updates, error tracking |
mcp/store.rs |
Database CRUD | Server config, tool/resource persistence |
mcp/models.rs |
Data models | McpServer, McpTool, McpResource types |
mcp/transport/stdio.rs |
Stdio transport | Process spawning, environment variables |
mcp/transport/http.rs |
HTTP transport | Custom headers, auth support |
mcp/commands.rs |
7 Tauri IPC commands | Server CRUD, discovery, tool/resource listing |
Database Schema (Migration 018):
CREATE TABLE mcp_servers (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
url TEXT NOT NULL,
transport_type TEXT NOT NULL CHECK(transport_type IN ('stdio', 'http')),
transport_config TEXT NOT NULL DEFAULT '{}',
auth_type TEXT NOT NULL CHECK(auth_type IN ('none', 'api_key', 'bearer', 'oauth2')),
auth_value TEXT,
enabled INTEGER NOT NULL DEFAULT 1,
last_discovered_at TEXT,
discovery_status TEXT NOT NULL DEFAULT 'pending'
CHECK(discovery_status IN ('pending','connected','unreachable','error')),
discovery_error TEXT,
env_config TEXT,
created_at TEXT NOT NULL,
updated_at TEXT NOT NULL
);
CREATE TABLE mcp_tools (
id TEXT PRIMARY KEY,
server_id TEXT NOT NULL,
name TEXT NOT NULL,
tool_key TEXT NOT NULL,
description TEXT,
parameters TEXT NOT NULL DEFAULT '{}',
FOREIGN KEY(server_id) REFERENCES mcp_servers(id) ON DELETE CASCADE
);
CREATE TABLE mcp_resources (
id TEXT PRIMARY KEY,
server_id TEXT NOT NULL,
uri TEXT NOT NULL,
name TEXT,
description TEXT,
FOREIGN KEY(server_id) REFERENCES mcp_servers(id) ON DELETE CASCADE
);
Tool Calling Flow:
- AI agent requests available tools
- Adapter fetches static tools (
ai/tools.rs::get_available_tools()) - Adapter fetches MCP tools from all enabled servers
- Tools merged and returned to AI agent
- AI agent calls tool by name (e.g.,
server_name.tool_name) - Adapter routes to correct MCP client
- Client invokes tool with 30-second timeout
- Result returned to AI agent
Security:
- Auth credentials stored with AES-256-GCM encryption
- Environment variables isolated per server process
- 30-second hard timeout prevents indefinite hangs
- Server connection status tracked and displayed
Frontend Components:
Settings/MCPServers.tsx: Server configuration and discovery UISettings/MCPTools.tsx: Tool browser and tester
AI Tool Calling & Auto-Detection (v1.0.8+)
Status: Production-ready automatic tool calling support detection.
Architecture: Test-based detection with graceful degradation.
graph TB
subgraph "Tool Calling Detection"
User[User] -->|clicks detect| UI[Auto-Detect Button]
UI -->|invoke| Command[detect_tool_calling_support]
Command -->|create test tool| TestTool[test_tool definition]
Command -->|override config| DetectionConfig[Detection Config]
DetectionConfig -->|max_tokens: 100| Optimization1[Cost Optimization]
DetectionConfig -->|temperature: 0.0| Optimization2[Deterministic]
Command -->|send test call| Provider[AI Provider]
Provider -->|response| Parser[Response Parser]
Parser -->|has tool_calls array?| Decision{Supports Tools?}
Decision -->|yes, contains test_tool| Success[Return true]
Decision -->|no tool_calls| NotSupported[Return false]
Decision -->|503 / tool error| Blocked[Return false]
Decision -->|connection error| Error[Throw error]
Success -->|update UI| Checkbox[Enable Checkbox]
NotSupported -->|update UI| DisableCheckbox[Disable Checkbox]
Blocked -->|update UI| DisableCheckbox
Error -->|display| ErrorMessage[Error Message]
end
style Success fill:#e6f7e6
style NotSupported fill:#fff4e6
style Blocked fill:#ffe6e6
style Error fill:#ffe6e6
Test Tool Definition:
Tool {
name: "test_tool".to_string(),
description: "A test tool that returns 'success'. Call this tool with no arguments.".to_string(),
parameters: ToolParameters {
param_type: "object".to_string(),
properties: HashMap::new(),
required: vec![],
},
}
Detection Criteria:
| Scenario | Result | Action |
|---|---|---|
Provider returns tool_calls array with test_tool |
✅ Supported | Enable checkbox, show success message |
Provider responds without tool_calls |
⚠️ Not supported | Disable checkbox, show warning |
| Gateway returns 503 / "tool" error (e.g., TFTSR GenAI) | ⚠️ Blocked | Disable checkbox, show warning |
| Connection/auth/timeout error | ❌ Error | Show error message, don't change checkbox |
Optimizations:
max_tokens: 100(reduces cost for detection test)temperature: 0.0(deterministic responses)- Error pattern matching for gateway-level blocks
Key Files:
commands/ai.rs::detect_tool_calling_support(): Backend detection logic (5 unit tests)pages/Settings/AIProviders.tsx::handleAutoDetectToolCalling(): Frontend UI (7 unit tests)lib/tauriCommands.ts::detectToolCallingSupportCmd(): TypeScript wrapper
Database: Uses ai_providers.supports_tool_calling column (Migration 028)
Documentation: docs/wiki/AI-Providers.md section "Tool Calling Auto-Detection"
Backend Components
graph TD
subgraph "Tauri IPC Layer"
IPC[IPC Command Router\nlib.rs generate_handler!]
end
subgraph "Command Handlers (commands/)"
CMD_DB[db.rs\nIssue CRUD\nTimeline Events\n5-Whys Entries]
CMD_AI[ai.rs\nChat Message\nLog Analysis\nProvider Test\nTool Calling Detection]
CMD_ANALYSIS[analysis.rs\nLog Upload\nPII Detection\nRedaction Apply]
CMD_DOCS[docs.rs\nRCA Generation\nPostmortem Gen\nDocument Export]
CMD_INTEGRATIONS[integrations.rs\nConfluence\nServiceNow\nAzure DevOps\nOAuth Flow]
CMD_SYSTEM[system.rs\nSettings CRUD\nOllama Mgmt\nAI Provider Mgmt\nAudit Log]
CMD_SHELL[shell.rs\nKubeconfig CRUD\nCommand Execution\nExecution History]
CMD_MCP[mcp/commands.rs\nMCP Server CRUD\nDiscovery\nTool/Resource Listing]
end
subgraph "Domain Services"
AI[AI Layer\nai/provider.rs\nTrait + Factory]
TOOLS[AI Tools\nai/tools.rs\nStatic Tools Registry]
AGENTS[AI Agents\nai/agents.rs\nAgent Registry]
PII[PII Engine\npii/detector.rs\n12 Pattern Detectors]
AUDIT[Audit Logger\naudit/log.rs\nHash-chained entries]
DOCS_GEN[Doc Generator\ndocs/rca.rs\ndocs/postmortem.rs]
SHELL[Shell System\nshell/classifier.rs\nshell/executor.rs\nshell/kubectl.rs]
MCP[MCP Integration\nmcp/client.rs\nmcp/adapter.rs\nmcp/discovery.rs]
end
subgraph "AI Providers (ai/)"
ANTHROPIC[anthropic.rs\nClaude API]
OPENAI[openai.rs\nOpenAI + Custom REST]
OLLAMA[ollama.rs\nLocal Models]
GEMINI[gemini.rs\nGoogle Gemini]
MISTRAL[mistral.rs\nMistral API]
end
subgraph "Integration Clients (integrations/)"
CONFLUENCE[confluence.rs\nconfluence_search.rs]
SERVICENOW[servicenow.rs\nservicenow_search.rs]
AZUREDEVOPS[azuredevops.rs\nazuredevops_search.rs]
AUTH[auth.rs\nAES-256-GCM\nToken Encryption]
WEBVIEW_AUTH[webview_auth.rs\nOAuth WebView\nCallback Server]
end
subgraph "Data Layer (db/)"
MIGRATIONS[migrations.rs\n28 Schema Versions]
MODELS[models.rs\nIssue / LogFile\nAiMessage / Document\nAuditEntry / Credential\nShellCommand / KubeconfigFile\nCommandExecution\nMcpServer / McpTool]
CONNECTION[connection.rs\nSQLCipher Connect\nKey Auto-gen\nPlain→Encrypted Migration]
end
IPC --> CMD_DB
IPC --> CMD_AI
IPC --> CMD_ANALYSIS
IPC --> CMD_DOCS
IPC --> CMD_INTEGRATIONS
IPC --> CMD_SYSTEM
IPC --> CMD_SHELL
IPC --> CMD_MCP
CMD_AI --> AI
CMD_AI --> TOOLS
CMD_ANALYSIS --> PII
CMD_DOCS --> DOCS_GEN
CMD_SHELL --> SHELL
CMD_MCP --> MCP
CMD_INTEGRATIONS --> CONFLUENCE
CMD_INTEGRATIONS --> SERVICENOW
CMD_INTEGRATIONS --> AZUREDEVOPS
CMD_INTEGRATIONS --> AUTH
CMD_INTEGRATIONS --> WEBVIEW_AUTH
AI --> ANTHROPIC
AI --> OPENAI
AI --> OLLAMA
AI --> GEMINI
AI --> MISTRAL
TOOLS --> SHELL
TOOLS --> MCP
MCP --> AGENTS
CMD_DB --> MODELS
CMD_AI --> AUDIT
CMD_ANALYSIS --> AUDIT
CMD_SHELL --> AUDIT
MODELS --> MIGRATIONS
MIGRATIONS --> CONNECTION
style IPC fill:#4a90d9,color:#fff
style AI fill:#7b68ee,color:#fff
style PII fill:#e67e22,color:#fff
style AUDIT fill:#c0392b,color:#fff
Frontend Components
graph TD
subgraph "React Application (src/)"
APP[App.tsx\nSidebar + Router\nTheme Provider]
end
subgraph "Pages (src/pages/)"
DASHBOARD[Dashboard\nStats + Quick Actions]
NEW_ISSUE[NewIssue\nCreate Form]
LOG_UPLOAD[LogUpload\nFile Upload + PII Review]
TRIAGE[Triage\n5-Whys AI Chat]
RESOLUTION[Resolution\nStep Tracking]
RCA[RCA\nDocument Editor]
POSTMORTEM[Postmortem\nDocument Editor]
HISTORY[History\nSearch + Filter]
SETTINGS[Settings\nProviders / Ollama\nIntegrations / Security]
end
subgraph "Components (src/components/)"
CHAT_WIN[ChatWindow\nStreaming Messages]
DOC_EDITOR[DocEditor\nMarkdown Editor]
PII_DIFF[PiiDiffViewer\nSide-by-side Diff]
HW_REPORT[HardwareReport\nSystem Specs]
MODEL_SEL[ModelSelector\nProvider Dropdown]
TRIAGE_PROG[TriageProgress\n5-Whys Steps]
end
subgraph "State (src/stores/)"
SESSION[sessionStore\nEphemeral — NOT persisted\nCurrentIssue / Messages\nPiiSpans / WhyLevel]
SETTINGS_STORE[settingsStore\nPersisted to localStorage\nTheme / ActiveProvider\nPiiPatterns]
HISTORY_STORE[historyStore\nCached issue list\nSearch results]
end
subgraph "IPC Layer (src/lib/)"
IPC[tauriCommands.ts\nTyped invoke() wrappers\nAll Tauri commands]
PROMPTS[domainPrompts.ts\n8 Domain System Prompts]
end
APP --> DASHBOARD
APP --> TRIAGE
APP --> LOG_UPLOAD
APP --> HISTORY
APP --> SETTINGS
TRIAGE --> CHAT_WIN
TRIAGE --> TRIAGE_PROG
LOG_UPLOAD --> PII_DIFF
RCA --> DOC_EDITOR
POSTMORTEM --> DOC_EDITOR
SETTINGS --> HW_REPORT
SETTINGS --> MODEL_SEL
TRIAGE --> SESSION
TRIAGE --> SETTINGS_STORE
HISTORY --> HISTORY_STORE
SETTINGS --> SETTINGS_STORE
CHAT_WIN --> IPC
LOG_UPLOAD --> IPC
RCA --> IPC
SETTINGS --> IPC
IPC --> PROMPTS
style SESSION fill:#e74c3c,color:#fff
style SETTINGS_STORE fill:#27ae60,color:#fff
style IPC fill:#4a90d9,color:#fff
Data Architecture
Database Schema
erDiagram
issues {
TEXT id PK
TEXT title
TEXT description
TEXT severity
TEXT status
TEXT category
TEXT source
TEXT assigned_to
TEXT tags
TEXT created_at
TEXT updated_at
}
log_files {
TEXT id PK
TEXT issue_id FK
TEXT file_name
TEXT content_hash
TEXT mime_type
INTEGER size_bytes
INTEGER redacted
TEXT created_at
}
pii_spans {
TEXT id PK
TEXT log_file_id FK
INTEGER start_offset
INTEGER end_offset
TEXT original_value
TEXT replacement
TEXT pattern_type
INTEGER approved
}
ai_conversations {
TEXT id PK
TEXT issue_id FK
TEXT provider_name
TEXT model_name
TEXT created_at
}
ai_messages {
TEXT id PK
TEXT conversation_id FK
TEXT role
TEXT content
INTEGER token_count
TEXT created_at
}
resolution_steps {
TEXT id PK
TEXT issue_id FK
INTEGER step_order
TEXT question
TEXT answer
TEXT evidence
TEXT created_at
}
documents {
TEXT id PK
TEXT issue_id FK
TEXT doc_type
TEXT title
TEXT content_md
TEXT created_at
TEXT updated_at
}
audit_log {
TEXT id PK
TEXT action
TEXT entity_type
TEXT entity_id
TEXT prev_hash
TEXT entry_hash
TEXT details
TEXT created_at
}
credentials {
TEXT id PK
TEXT service UNIQUE
TEXT token_type
TEXT encrypted_token
TEXT token_hash
TEXT expires_at
TEXT created_at
}
integration_config {
TEXT id PK
TEXT service UNIQUE
TEXT base_url
TEXT username
TEXT project_name
TEXT space_key
INTEGER auto_create
}
ai_providers {
TEXT id PK
TEXT name UNIQUE
TEXT provider_type
TEXT api_url
TEXT encrypted_api_key
TEXT model
TEXT config_json
INTEGER supports_tool_calling
}
issues_fts {
TEXT rowid FK
TEXT title
TEXT description
}
shell_commands {
TEXT id PK
TEXT command_template
INTEGER tier
TEXT description
TEXT category
}
kubeconfig_files {
TEXT id PK
TEXT name
TEXT encrypted_content
TEXT context
TEXT cluster_url
INTEGER is_active
}
command_executions {
TEXT id PK
TEXT issue_id FK
TEXT command
INTEGER tier
TEXT approval_status
TEXT kubeconfig_id FK
INTEGER exit_code
TEXT stdout
TEXT stderr
INTEGER execution_time_ms
TEXT executed_at
}
approval_decisions {
TEXT id PK
TEXT command_pattern
TEXT decision
TEXT session_id
TEXT decided_at
TEXT expires_at
}
mcp_servers {
TEXT id PK
TEXT name
TEXT url
TEXT transport_type
TEXT auth_type
TEXT auth_value
INTEGER enabled
TEXT discovery_status
TEXT env_config
}
mcp_tools {
TEXT id PK
TEXT server_id FK
TEXT name
TEXT tool_key
TEXT description
TEXT parameters
}
mcp_resources {
TEXT id PK
TEXT server_id FK
TEXT uri
TEXT name
TEXT description
}
issues ||--o{ log_files : "has"
issues ||--o{ ai_conversations : "has"
issues ||--o{ resolution_steps : "has"
issues ||--o{ documents : "has"
issues ||--o{ command_executions : "has"
issues ||--|| issues_fts : "indexed by"
log_files ||--o{ pii_spans : "contains"
ai_conversations ||--o{ ai_messages : "contains"
command_executions }o--|| kubeconfig_files : "uses"
mcp_servers ||--o{ mcp_tools : "exposes"
mcp_servers ||--o{ mcp_resources : "exposes"
Data Flow — Issue Triage Lifecycle
sequenceDiagram
participant U as User
participant FE as React Frontend
participant IPC as Tauri IPC
participant BE as Rust Backend
participant PII as PII Engine
participant AI as AI Provider
participant DB as SQLCipher DB
U->>FE: Create new issue
FE->>IPC: create_issue(title, severity)
IPC->>BE: cmd::db::create_issue()
BE->>DB: INSERT INTO issues
DB-->>BE: Issue{id, ...}
BE-->>FE: Issue
U->>FE: Upload log file
FE->>IPC: upload_log_file(issue_id, path)
IPC->>BE: cmd::analysis::upload_log_file()
BE->>BE: Read file, SHA-256 hash
BE->>DB: INSERT INTO log_files
BE->>PII: detect(content)
PII-->>BE: Vec<PiiSpan>
BE->>DB: INSERT INTO pii_spans
BE-->>FE: {log_file, spans}
U->>FE: Approve redactions
FE->>IPC: apply_redactions(log_file_id, span_ids)
IPC->>BE: cmd::analysis::apply_redactions()
BE->>DB: UPDATE pii_spans SET approved=1
BE->>BE: Write .redacted file
BE->>DB: UPDATE log_files SET redacted=1
BE->>DB: INSERT INTO audit_log (hash-chained)
U->>FE: Start AI triage
FE->>IPC: analyze_logs(issue_id, ...)
IPC->>BE: cmd::ai::analyze_logs()
BE->>DB: SELECT redacted log content
BE->>AI: POST /chat/completions (redacted content)
AI-->>BE: {summary, findings, why1, severity}
BE->>DB: INSERT ai_messages
BE-->>FE: AnalysisResult
loop 5-Whys Iteration
U->>FE: Ask "Why?" question
FE->>IPC: chat_message(conversation_id, msg)
IPC->>BE: cmd::ai::chat_message()
BE->>DB: SELECT conversation history
BE->>AI: POST /chat/completions
AI-->>BE: Response with why level detection
BE->>DB: INSERT ai_messages
BE-->>FE: ChatResponse{content, why_level}
FE->>FE: Auto-advance why level (1→5)
end
U->>FE: Generate RCA
FE->>IPC: generate_rca(issue_id)
IPC->>BE: cmd::docs::generate_rca()
BE->>DB: SELECT issue + steps + conversations
BE->>BE: Build markdown template
BE->>DB: INSERT INTO documents
BE-->>FE: Document{content_md}
Security Architecture
Security Layers
graph TB
subgraph "Layer 1: Network Security"
CSP[Content Security Policy\nallow-list of external hosts]
TLS[TLS Enforcement\nreqwest HTTPS only]
CAP[Tauri Capability ACL\nLeast-privilege permissions]
end
subgraph "Layer 2: Data Encryption"
SQLCIPHER[SQLCipher AES-256\nFull database encryption\nPBKDF2-SHA512, 256k iterations]
AES_GCM[AES-256-GCM\nCredential token encryption\nUnique nonce per encrypt]
STRONGHOLD[Tauri Stronghold\nKey derivation + storage\nArgon2 password hashing]
end
subgraph "Layer 3: Key Management"
DB_KEY[.dbkey file\nPer-install random 256-bit key\nMode 0600 — owner only]
ENC_KEY[.enckey file\nPer-install random 256-bit key\nMode 0600 — owner only]
ENV_OVERRIDE[TRCAA_DB_KEY / TRCAA_ENCRYPTION_KEY\nOptional env var override]
end
subgraph "Layer 4: PII Protection"
PII_DETECT[12-Pattern PII Detector\nEmail / IP / Phone / SSN\nTokens / Passwords / MAC]
USER_APPROVE[User Approval Gate\nManual review before AI send]
AUDIT[Hash-chained Audit Log\nprev_hash → entry_hash\nTamper detection]
end
subgraph "Layer 5: Credential Storage"
TOKEN_HASH[Token Hash Storage\nSHA-256 hash in credentials table]
TOKEN_ENC[Token Encrypted Storage\nAES-256-GCM ciphertext]
NO_BROWSER[No Browser Storage\nAPI keys never in localStorage]
end
SQLCIPHER --> DB_KEY
AES_GCM --> ENC_KEY
DB_KEY --> ENV_OVERRIDE
ENC_KEY --> ENV_OVERRIDE
TOKEN_ENC --> AES_GCM
TOKEN_HASH --> AUDIT
style SQLCIPHER fill:#c0392b,color:#fff
style AES_GCM fill:#c0392b,color:#fff
style AUDIT fill:#e67e22,color:#fff
style PII_DETECT fill:#e67e22,color:#fff
style USER_APPROVE fill:#27ae60,color:#fff
Shell Execution Security (v1.0.0+)
Three-tier safety classification protects against accidental or malicious command execution.
flowchart TD
A[AI Agent calls execute_shell_command] --> B[Parse command string]
B --> C{Contains pipes or command substitution?}
C -->|Yes| D[Parse into components]
C -->|No| E[Single command]
D --> F[Classify each component]
E --> F
F --> G{Highest tier?}
G -->|Tier 1| H[Read-only operations]
G -->|Tier 2| I[Mutating operations]
G -->|Tier 3| J[Destructive operations]
H --> K[Execute automatically]
K --> L[Record to command_executions]
L --> M[Return output to AI]
I --> N[Show approval modal to user]
N --> O{User decision?}
O -->|Allow Once| K
O -->|Allow for Session| P[Store approval_decision]
O -->|Deny| Q[Record denial]
P --> K
Q --> R[Return error to AI]
J --> S[Always reject]
S --> Q
L --> T[Audit Log]
Q --> T
style H fill:#e6f7e6
style I fill:#fff4e6
style J fill:#ffe6e6
style S fill:#c0392b,color:#fff
Tier Classification Rules:
| Tier | Safety Level | Examples | Action |
|---|---|---|---|
| Tier 1 | Read-only | kubectl get, cat, grep, ls, pvecm status |
Auto-execute |
| Tier 2 | Mutating | kubectl apply, chmod, systemctl restart, ssh |
User approval |
| Tier 3 | Destructive | rm -rf, shutdown, mkfs, dd, fork bombs |
Always deny |
Escalation Rules:
- Command with pipe (
|) or chain (&&,||,;) → highest tier wins - Command substitution (
`...`or$(...)) → escalate Tier 1 to Tier 2 - Single Tier 3 command in chain → entire command becomes Tier 3
Kubeconfig Encryption:
- All kubeconfig files encrypted with AES-256-GCM before storage
- Decrypted on-demand for kubectl execution
- Encryption key from
TRCAA_ENCRYPTION_KEYenv var or.enckeyfile
Audit Trail:
- All commands logged to
command_executionstable - Includes: command text, tier, approval status, exit code, stdout, stderr, execution time
- Linked to issue_id for incident context
- Session-based approval decisions stored separately with expiration
Authentication Flow — OAuth2 Integration
sequenceDiagram
participant U as User
participant FE as Frontend
participant BE as Rust Backend
participant WV as WebView Window
participant CB as Callback Server\n(warp, port 8765)
participant EXT as External Service\n(Confluence/ADO)
U->>FE: Click "Connect" for integration
FE->>BE: initiate_oauth(service)
BE->>BE: Generate PKCE code_verifier + code_challenge
BE->>CB: Start warp server (localhost:8765)
BE->>WV: Open auth URL in new WebView window
WV->>EXT: GET /oauth/authorize?code_challenge=...
EXT-->>WV: Login page
U->>WV: Enter credentials
WV->>EXT: POST credentials
EXT-->>WV: Redirect to localhost:8765/callback?code=xxx
WV->>CB: GET /callback?code=xxx
CB->>BE: Signal auth code received
BE->>EXT: POST /oauth/token (code + code_verifier)
EXT-->>BE: access_token + refresh_token
BE->>BE: encrypt_token(access_token)
BE->>DB: INSERT credentials (encrypted_token, token_hash)
BE->>DB: INSERT audit_log
BE-->>FE: OAuth complete
FE->>FE: Show "Connected" status
AI Provider Architecture
Provider Trait Pattern
classDiagram
class Provider {
<<trait>>
+name() String
+chat(messages, config) Future~ChatResponse~
+info() ProviderInfo
}
class AnthropicProvider {
-api_key: String
-model: String
+chat(messages, config)
+name() "anthropic"
}
class OpenAiProvider {
-api_url: String
-api_key: String
-model: String
-api_format: ApiFormat
+chat(messages, config)
+name() "openai"
}
class OllamaProvider {
-base_url: String
-model: String
+chat(messages, config)
+name() "ollama"
}
class GeminiProvider {
-api_key: String
-model: String
+chat(messages, config)
+name() "gemini"
}
class MistralProvider {
-api_key: String
-model: String
+chat(messages, config)
+name() "mistral"
}
class ProviderFactory {
+create_provider(config: ProviderConfig) Box~dyn Provider~
}
class ProviderConfig {
+name: String
+provider_type: String
+api_url: String
+api_key: String
+model: String
+max_tokens: Option~u32~
+temperature: Option~f64~
+custom_endpoint_path: Option~String~
+custom_auth_header: Option~String~
+custom_auth_prefix: Option~String~
+api_format: Option~String~
}
Provider <|.. AnthropicProvider
Provider <|.. OpenAiProvider
Provider <|.. OllamaProvider
Provider <|.. GeminiProvider
Provider <|.. MistralProvider
ProviderFactory --> Provider : creates
ProviderFactory --> ProviderConfig : consumes
Tool Calling Flow (Azure DevOps)
sequenceDiagram
participant U as User
participant FE as Frontend
participant BE as Rust Backend
participant AI as AI Provider
participant ADO as Azure DevOps API
U->>FE: Chat message mentioning ADO work item
FE->>BE: chat_message(conversation_id, msg, provider_config)
BE->>BE: Inject get_available_tools() into request
BE->>AI: POST /chat/completions {messages, tools: [add_ado_comment]}
AI-->>BE: {tool_calls: [{function: "add_ado_comment", args: {work_item_id, comment_text}}]}
BE->>BE: Parse tool_calls from response
BE->>BE: Validate tool name matches registered tools
BE->>ADO: PATCH /wit/workitems/{id}?api-version=7.0 (add comment)
ADO-->>BE: 200 OK
BE->>BE: Format tool result message
BE->>AI: POST /chat/completions {messages, tool_result}
AI-->>BE: Final response to user
BE->>DB: INSERT ai_messages (tool call + result)
BE-->>FE: ChatResponse{content}
Integration Architecture
graph LR
subgraph "Integration Layer (integrations/)"
AUTH[auth.rs\nToken Encryption\nOAuth + PKCE\nCookie Extraction]
subgraph "Confluence"
CF[confluence.rs\nPublish Documents\nSpace Management]
CF_SEARCH[confluence_search.rs\nContent Search\nPersistent WebView]
end
subgraph "ServiceNow"
SN[servicenow.rs\nCreate Incidents\nUpdate Records]
SN_SEARCH[servicenow_search.rs\nIncident Search\nKnowledge Base]
end
subgraph "Azure DevOps"
ADO[azuredevops.rs\nWork Items CRUD\nComments (AI tool)]
ADO_SEARCH[azuredevops_search.rs\nWork Item Search\nPersistent WebView]
end
subgraph "Auth Infrastructure"
WV_AUTH[webview_auth.rs\nOAuth WebView\nLogin Flow]
CB_SERVER[callback_server.rs\nwarp HTTP Server\nlocalhost:8765]
NAT_COOKIES[native_cookies*.rs\nPlatform Cookie\nExtraction]
end
end
subgraph "External Services"
CF_EXT[Atlassian Confluence\nhttps://*.atlassian.net]
SN_EXT[ServiceNow\nhttps://*.service-now.com]
ADO_EXT[Azure DevOps\nhttps://dev.azure.com]
end
AUTH --> CF
AUTH --> SN
AUTH --> ADO
WV_AUTH --> CB_SERVER
WV_AUTH --> NAT_COOKIES
CF --> CF_EXT
CF_SEARCH --> CF_EXT
SN --> SN_EXT
SN_SEARCH --> SN_EXT
ADO --> ADO_EXT
ADO_SEARCH --> ADO_EXT
style AUTH fill:#c0392b,color:#fff
Deployment Architecture
CI/CD Pipeline
graph TB
subgraph "Source Control"
GOGS[Gogs / Gitea\ngogs.trcaa.com\nSarman Repository]
end
subgraph "CI/CD Triggers"
PR_TRIGGER[PR Opened/Updated\ntest.yml workflow]
MASTER_TRIGGER[Push to master\nauto-tag.yml workflow]
DOCKER_TRIGGER[.docker/ changes\nbuild-images.yml workflow]
end
subgraph "Test Runner — amd64-docker-runner"
RUSTFMT[1. rustfmt\nFormat Check]
CLIPPY[2. clippy\n-D warnings]
CARGO_TEST[3. cargo test\n64 Rust tests]
TSC[4. tsc --noEmit\nType Check]
VITEST[5. vitest run\n13 JS tests]
end
subgraph "Release Builders (Parallel)"
AMD64[linux/amd64\nDocker: trcaa-linux-amd64\n.deb .rpm .AppImage]
WINDOWS[windows/amd64\nDocker: trcaa-windows-cross\n.exe .msi]
ARM64[linux/arm64\narm64 native runner\n.deb .rpm .AppImage]
MACOS[macOS arm64\nnative macOS runner\n.app .dmg]
end
subgraph "Artifact Storage"
RELEASE[Gitea Release\nv0.x.x tags\nAll platform assets]
REGISTRY[Gitea Container Registry\ngitea.tftsr.com:3000\nCI Docker images]
end
GOGS --> PR_TRIGGER
GOGS --> MASTER_TRIGGER
GOGS --> DOCKER_TRIGGER
PR_TRIGGER --> RUSTFMT
RUSTFMT --> CLIPPY
CLIPPY --> CARGO_TEST
CARGO_TEST --> TSC
TSC --> VITEST
MASTER_TRIGGER --> AMD64
MASTER_TRIGGER --> WINDOWS
MASTER_TRIGGER --> ARM64
MASTER_TRIGGER --> MACOS
AMD64 --> RELEASE
WINDOWS --> RELEASE
ARM64 --> RELEASE
MACOS --> RELEASE
DOCKER_TRIGGER --> REGISTRY
style VITEST fill:#27ae60,color:#fff
style RELEASE fill:#4a90d9,color:#fff
Runtime Architecture (per Platform)
graph TB
subgraph "macOS Runtime"
MAC_PROC[trcaa process\nMach-O arm64 binary]
WEBKIT[WKWebView\nSafari WebKit engine]
MAC_DATA[~/Library/Application Support/trcaa/\n.dbkey mode 0600\n.enckey mode 0600\ntrcaa.db SQLCipher]
MAC_KUBECTL[Bundled kubectl v1.30.0\narm64 binary]
MAC_BUNDLE[Troubleshooting and RCA Assistant.app\n/Applications/]
end
subgraph "Linux Runtime"
LINUX_PROC[trcaa process\nELF amd64/arm64]
WEBKIT2[WebKitGTK WebView\nwebkit2gtk4.1]
LINUX_DATA[~/.local/share/trcaa/\n.dbkey .enckey\ntrcaa.db]
LINUX_KUBECTL[Bundled kubectl v1.30.0\namd64/arm64 binary]
LINUX_PKG[.deb / .rpm / .AppImage]
end
subgraph "Windows Runtime"
WIN_PROC[trcaa.exe\nPE amd64]
WEBVIEW2[Microsoft WebView2\nChromium-based]
WIN_DATA[%APPDATA%\trcaa\\\n.dbkey .enckey\ntrcaa.db]
WIN_KUBECTL[Bundled kubectl.exe v1.30.0\namd64 binary]
WIN_PKG[NSIS .exe / .msi]
end
MAC_BUNDLE --> MAC_PROC
MAC_PROC --> WEBKIT
MAC_PROC --> MAC_DATA
MAC_PROC --> MAC_KUBECTL
LINUX_PKG --> LINUX_PROC
LINUX_PROC --> WEBKIT2
LINUX_PROC --> LINUX_DATA
LINUX_PROC --> LINUX_KUBECTL
WIN_PKG --> WIN_PROC
WIN_PROC --> WEBVIEW2
WIN_PROC --> WIN_DATA
WIN_PROC --> WIN_KUBECTL
Key Data Flows
PII Detection and Redaction
flowchart TD
A[User uploads log file] --> B[Read file contents\nmax 50MB]
B --> C[Compute SHA-256 hash]
C --> D[Store metadata in log_files table]
D --> E[Run PII Detection Engine]
subgraph "PII Engine"
E --> F{12 Pattern Detectors}
F --> G[Email Regex]
F --> H[IPv4/IPv6 Regex]
F --> I[Bearer Token Regex]
F --> J[Password Regex]
F --> K[SSN / Phone / CC]
F --> L[MAC / Hostname]
G & H & I & J & K & L --> M[Collect all spans]
M --> N[Sort by start offset]
N --> O[Remove overlaps\nlongest span wins]
end
O --> P[Store pii_spans in DB\nwith UUID per span]
P --> Q[Return spans to UI]
Q --> R[PiiDiffViewer\nSide-by-side diff]
R --> S{User reviews}
S -->|Approve| T[apply_redactions\nMark spans approved]
S -->|Dismiss| U[Remove from approved set]
T --> V[Write .redacted log file\nreplace spans with placeholders]
V --> W[Update log_files.redacted = 1]
W --> X[Append to audit_log\nhash-chained entry]
X --> Y[Log now safe for AI send]
Encryption Key Lifecycle
flowchart TD
A[App Launch] --> B{TRCAA_DB_KEY env var set?}
B -->|Yes| C[Use env var key]
B -->|No| D{Release build?}
D -->|Debug| E[Use hardcoded dev key]
D -->|Release| F{.dbkey file exists?}
F -->|Yes| G[Load key from .dbkey]
F -->|No| H[Generate 32 random bytes\nhex-encode → 64 char key]
H --> I[Write to .dbkey\nmode 0600]
I --> J[Use generated key]
G --> K{Open database}
C --> K
E --> K
J --> K
K --> L{SQLCipher decrypt success?}
L -->|Yes| M[Run migrations\nDatabase ready]
L -->|No| N{File is plain SQLite?}
N -->|Yes| O[migrate_plain_to_encrypted\nCreate .db.plain-backup\nATTACH + sqlcipher_export]
N -->|No| P[Fatal error\nDatabase corrupt]
O --> M
style H fill:#27ae60,color:#fff
style O fill:#e67e22,color:#fff
style P fill:#c0392b,color:#fff
Architecture Decision Records
See the adrs/ directory for all Architecture Decision Records.
| ADR | Title | Status |
|---|---|---|
| ADR-001 | Tauri as Desktop Framework | Accepted |
| ADR-002 | SQLCipher for Encrypted Storage | Accepted |
| ADR-003 | Provider Trait Pattern for AI Backends | Accepted |
| ADR-004 | Regex + Aho-Corasick for PII Detection | Accepted |
| ADR-005 | Auto-generate Encryption Keys at Runtime | Accepted |
| ADR-006 | Zustand for Frontend State Management | Accepted |
| ADR-007 | Three-Tier Shell Command Safety Classification | Accepted |
| ADR-008 | Model Context Protocol for External Tools | Accepted |
| ADR-009 | Bundle kubectl Binary for Cross-Platform Consistency | Accepted |