Commit Graph

258 Commits

Author SHA1 Message Date
OG T
0aaf6a276b feat(api,web): Phase 6.5 DecisionManager with dual-engine fallback
Backend:
- Add DecisionManager with state machine (INIT→ANALYZING→READY→EXECUTING)
- Implement Expert System rules engine (100% local, never fails)
- Dual-engine: LLM (primary) + Expert System (fallback)
- Auto-generate decision_token for each incident
- 30-second timeout guarantee

Frontend:
- Use decision.state to unlock [Y/n] buttons
- Display AI action suggestion in card
- Show source indicator [AI] or [EXP]
- Generate proposal on-demand if needed

Fixes: UI locked with hourglass when LLM times out

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 13:19:55 +08:00
OG T
eee4ab9b36 feat(api): Phase 6.6 implement k8s execution engine with subprocess
ActionExecutor enhancements:
- Add execute_kubectl_command() using asyncio.create_subprocess_shell
- Security: Only kubectl commands allowed, forbidden patterns blocked
- Shadow Mode: Simulate execution without actual kubectl calls
- Capture stdout/stderr with PIPE, handle timeout gracefully

New execute_approved_proposal() function:
- Background task entry point for approved proposals
- Read approval from Redis/DB, verify status='approved'
- Extract kubectl_command from metadata
- Execute via execute_kubectl_command()
- Update status to 'executed' or 'failed' with execution_log

Security guardrails:
- Forbid delete namespace/ns, rm -rf, drop database
- Forbid batch deletion patterns
- 60 second default timeout

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 12:46:47 +08:00
OG T
de5796522f fix(api): fix optimization_suggestions dict access in proposal generation
The optimization_suggestions field is list[dict], not list[object].
Use .get() to access dict keys instead of attribute access.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 01:40:00 +08:00
OG T
141df533cc feat(api): Phase 6.4 LLM-based proposal generation with cache
- Add _call_with_cache wrapper in OpenClaw (Redis-based LLM cache)
- Add generate_incident_proposal method for incident analysis
- Integrate ProposalService with OpenClaw LLM
- Fallback to template-based proposals if LLM fails
- Include LLM metadata (provider, confidence, cache status) in proposals

憲法條款: 必須使用快取保護算力資源,嚴禁無快取裸奔調用

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 01:33:46 +08:00
OG T
e4bd030882 fix(api): use INTERVAL syntax to avoid ClickHouse Decimal overflow
The toDateTime64(nanoseconds, 9) caused Decimal overflow.
Switched to simpler `now() - INTERVAL X MINUTE` syntax.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 00:57:45 +08:00
OG T
7f2adab78b fix(api): query correct SigNoz traces table (v3 not v2)
The SignOz trace data is stored in distributed_signoz_index_v3,
not v2. This fixes GlobalPulse showing all zeros.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 00:50:15 +08:00
OG T
b00f318450 fix(api): correct OTEL gRPC endpoint format and SignOz query table
Root cause analysis:
1. OTEL gRPC endpoint had http:// prefix which is invalid for gRPC
2. SignOz query was targeting wrong table (signoz_metrics.distributed_samples_v4)
3. Should query signoz_traces.distributed_signoz_index_v2 for trace data

Fixes:
- Remove http:// prefix from OTEL_EXPORTER_OTLP_ENDPOINT (gRPC needs host:port)
- Update SignOz client to query traces table instead of metrics table
- Fix timestamp format (nanoseconds for DateTime64(9))
- statusCode: 0=Unset, 1=Ok, 2=Error

This should enable OTEL traces to reach SigNoz and GlobalPulse to show real metrics.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-23 00:41:51 +08:00
OG T
196d269b92 feat: add all application source code
- apps/api: FastAPI backend with Dockerfile
- apps/web: Next.js frontend with Dockerfile
- apps/sensor: Signal collection agent
- packages: shared packages

Co-Authored-By: Claude <noreply@anthropic.com>
2026-03-22 18:57:44 +08:00