{"id":45779622,"url":"https://github.com/alexsjones/sympozium","last_synced_at":"2026-03-15T20:21:34.555Z","repository":{"id":340122920,"uuid":"1164625104","full_name":"AlexsJones/sympozium","owner":"AlexsJones","description":"Run a fleet of AI agents on Kubernetes. Administer your cluster agentically","archived":false,"fork":false,"pushed_at":"2026-02-27T20:13:34.000Z","size":10435,"stargazers_count":87,"open_issues_count":5,"forks_count":17,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-28T14:58:32.411Z","etag":null,"topics":["agentic","agentic-ai","kubeclaw","openclaw"],"latest_commit_sha":null,"homepage":"https://sympozium.ai/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlexsJones.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":"docs/roadmap.md","authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-02-23T09:53:24.000Z","updated_at":"2026-02-28T13:15:12.000Z","dependencies_parsed_at":"2026-02-27T11:06:11.774Z","dependency_job_id":null,"html_url":"https://github.com/AlexsJones/sympozium","commit_stats":null,"previous_names":["alexsjones/k8sclaw","alexsjones/sympozium"],"tags_count":67,"template":false,"template_full_name":null,"purl":"pkg:github/AlexsJones/sympozium","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexsJones%2Fsympozium","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexsJones%2Fsympozium/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexsJones%2Fsympozium/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexsJones%2Fsympozium/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlexsJones","download_url":"https://codeload.github.com/AlexsJones/sympozium/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlexsJones%2Fsympozium/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29969700,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T12:56:10.327Z","status":"ssl_error","status_checked_at":"2026-03-01T12:55:24.744Z","response_time":124,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agentic","agentic-ai","kubeclaw","openclaw"],"created_at":"2026-02-26T10:59:13.828Z","updated_at":"2026-03-01T13:00:43.608Z","avatar_url":"https://github.com/AlexsJones.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"header.png\" alt=\"sympozium icon\" width=\"800px;\"\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n \n  \u003cem\u003e\n  Every agent is an ephemeral Pod.\u003cbr\u003eEvery policy is a CRD. Every execution is a Job.\u003cbr\u003e\n  Orchestrate multi-agent workflows \u003cb\u003eand\u003c/b\u003e let agents diagnose, scale, and remediate your infrastructure.\u003cbr\u003e\n  Multi-tenant. Horizontally scalable. Safe by design.\u003c/em\u003e\u003cbr\u003e\u003cbr\u003e\n  From the creator of \u003ca href=\"https://github.com/k8sgpt-ai/k8sgpt\"\u003ek8sgpt\u003c/a\u003e and \u003ca href=\"https://github.com/AlexsJones/llmfit\"\u003ellmfit\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003e\n  This project is under active development. API's will change, things will be break. Be brave.\n  \u003cb /\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/AlexsJones/sympozium/actions\"\u003e\u003cimg src=\"https://github.com/AlexsJones/sympozium/actions/workflows/build.yaml/badge.svg\" alt=\"Build\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/AlexsJones/sympozium/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/AlexsJones/sympozium\" alt=\"Release\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-Apache%202.0-blue\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"demo.gif\" alt=\"Sympozium TUI demo\" width=\"800px;\"\u003e\n\u003c/p\u003e\n\n---\n### Quick Install (macOS / Linux)\n\n**Homebrew:**\n```bash\nbrew tap AlexsJones/sympozium\nbrew install sympozium\n```\n\n**Shell installer:**\n```bash\ncurl -fsSL https://deploy.sympozium.ai/install.sh | sh\n```\n\nThen deploy to your cluster and activate your first agents:\n\n```bash\nsympozium install          # deploys CRDs, controllers, and built-in PersonaPacks\nsympozium                  # launch the TUI — go to Personas tab, press Enter to onboard\n```\n\nSympozium ships with **PersonaPacks** — pre-configured bundles of agents that you activate with a few keypresses. No YAML required. See [PersonaPacks](#personapacks) below.\n\n📖 **New here?** See the [Getting Started guide](docs/getting-started.md) — install, deploy, onboard your first agent, and learn the TUI and CLI commands.\n\n### Advanced: Helm Chart\n\nFor production and GitOps workflows, you can deploy the control plane separately using Helm and install the CLI independently.\n\n#### Control Plane\n\n**Prerequisites:** [cert-manager](https://cert-manager.io/) (for webhook TLS):\n```bash\nkubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.17.1/cert-manager.yaml\n```\n\nDeploy the Sympozium control plane:\n```bash\nhelm install sympozium ./charts/sympozium\n```\n\nSee [`charts/sympozium/values.yaml`](charts/sympozium/values.yaml) for configuration options (replicas, resources, external NATS, network policies, etc.).\n\n#### CLI\n\nInstall the CLI on your local machine to connect to the cluster:\n\n```bash\nbrew tap AlexsJones/sympozium \u0026\u0026 brew install sympozium\n# or\ncurl -fsSL https://deploy.sympozium.ai/install.sh | sh\n```\n\n## Why Sympozium?\n\nSympozium serves **two powerful use cases** on one Kubernetes-native platform:\n\n1. **Orchestrate fleets of AI agents** — customer support, code review, data pipelines, or any domain-specific workflow. Each agent gets its own pod, RBAC, and network policy with proper tenant isolation.\n2. **Administer the cluster itself agentically** — point agents inward to diagnose failures, scale deployments, triage alerts, and remediate issues, all with Kubernetes-native isolation, RBAC, and audit trails.\n\nAgentic frameworks like OpenClaw pioneered rich agent orchestration — sub-agent registries, tool pipelines, channel integrations, and sandbox execution. But they run as **in-process monoliths** with file-based state, single-instance locks, and tightly coupled plugin systems.\n\nSympozium takes the same agentic control model and rebuilds it on Kubernetes primitives:\n\n### Isolated Skill Sidecars — a game-changer\n\nMost agent frameworks dump every tool into one shared process. One bad `kubectl delete` and your whole agent environment is toast. Sympozium does this completely differently:\n\n**Every skill runs in its own sidecar container** — a separate, isolated process injected into the agent pod at runtime. Use skills to give agents cluster-admin capabilities (`kubectl`, `helm`, scaling) or domain-specific tools — each with ephemeral least-privilege RBAC that's garbage-collected when the run finishes. Toggle a skill on, and the controller automatically:\n\n- Injects a dedicated sidecar container with only the binaries that skill needs (`kubectl`, `helm`, `terraform`, etc.)\n- Provisions **ephemeral, least-privilege RBAC** scoped to that single agent run — no standing permissions, no god-roles\n- Shares a `/workspace` volume so the agent can coordinate with the sidecar\n- **Garbage-collects everything** when the run finishes — containers, roles, bindings, all gone\n\nThis means you can give an agent full `kubectl` access for a troubleshooting run without worrying about leftover permissions. Skills are declared as CRDs, toggled per-instance in the TUI with a single keypress, and their containers are built and shipped alongside the rest of Sympozium. No plugins to install, no runtime to configure — just Kubernetes-native isolation that scales.\n\n\u003e _\"Give the agent tools, not trust.\"_ — Whether it's orchestrating a fleet or administering the cluster, skills get exactly the permissions they declare, for exactly as long as the run lasts, and not a second longer.\n\n### How it compares\n\n| Concern | OpenClaw (in-process) | Sympozium (Kubernetes-native) |\n|---------|----------------------|----------------------------|\n| **Agent execution** | Shared memory, single process | Ephemeral **Pod** per invocation (K8s Job) |\n| **Orchestration** | In-process registry + lane queue | **CRD-based** registry with controller reconciliation |\n| **Sandbox isolation** | Long-lived Docker sidecar | Pod **SecurityContext** + PodSecurity admission |\n| **IPC** | In-process EventEmitter | Filesystem sidecar + **NATS JetStream** |\n| **Tool/feature gating** | 7-layer in-process pipeline | **Admission webhooks** + `SympoziumPolicy` CRD |\n| **Persistent memory** | Files on disk (`~/.openclaw/`) | **ConfigMap** per instance, controller-managed |\n| **Scheduled tasks** | Cron jobs / external scripts | **SympoziumSchedule CRD** with cron controller |\n| **State** | SQLite + flat files | **etcd** (CRDs) + PostgreSQL + object storage |\n| **Multi-tenancy** | Single-instance file lock | **Namespaced CRDs**, RBAC, NetworkPolicy |\n| **Scaling** | Vertical only | **Horizontal** — stateless control plane, HPA |\n| **Channel connections** | In-process per channel | Dedicated **Deployment** per channel type |\n| **Observability** | Application logs | `kubectl logs`, events, conditions, **k9s-style TUI** |\n\nThe result: every concept that OpenClaw manages in application code, Sympozium expresses as a Kubernetes resource — then adds the ability to point agents at the cluster itself. Declarative, reconcilable, observable, and scalable.\n\n---\n\n### Deploy to Your Cluster\n\n```bash\nsympozium install          # CRDs, controllers, webhook, NATS, RBAC, network policies\nsympozium onboard          # interactive setup wizard — instance, provider, channel\nsympozium                  # launch the interactive TUI (default command)\nsympozium uninstall        # clean removal\n```\n\n## Architecture\n\n```mermaid\ngraph TB\n    subgraph K8S[\"Kubernetes Cluster\"]\n        direction TB\n\n        subgraph CP[\"Control Plane\"]\n            CM[\"Controller Manager\u003cbr/\u003e\u003csmall\u003eSympoziumInstance · AgentRun · PersonaPack\u003cbr/\u003eSympoziumPolicy · SkillPack · SympoziumSchedule\u003c/small\u003e\"]\n            API[\"API Server\u003cbr/\u003e\u003csmall\u003eHTTP + WebSocket\u003c/small\u003e\"]\n            WH[\"Admission Webhook\u003cbr/\u003e\u003csmall\u003ePolicy enforcement\u003c/small\u003e\"]\n            NATS[(\"NATS JetStream\u003cbr/\u003e\u003csmall\u003eEvent bus\u003c/small\u003e\")]\n            CM --- NATS\n            API --- NATS\n            WH -.- CM\n        end\n\n        subgraph SCHED[\"Scheduled Tasks\"]\n            CS[\"SympoziumSchedule Controller\u003cbr/\u003e\u003csmall\u003eCron-based reconciler\u003c/small\u003e\"]\n            SROUTER[\"Schedule Router\u003cbr/\u003e\u003csmall\u003eNATS → SympoziumSchedule CRD\u003c/small\u003e\"]\n            CS -- \"creates AgentRuns\u003cbr/\u003eon schedule\" --\u003e CM\n            SROUTER -- \"creates / updates\u003cbr/\u003eSympoziumSchedule CRDs\" --\u003e CS\n        end\n\n        subgraph CH[\"Channel Pods  ·  one Deployment per type\"]\n            TG[\"Telegram\"]\n            SL[\"Slack\"]\n            DC[\"Discord\"]\n            WA[\"WhatsApp\"]\n        end\n\n        subgraph AP[\"Agent Pod  ·  ephemeral K8s Job\"]\n            direction LR\n            A1[\"Agent Container\u003cbr/\u003e\u003csmall\u003eLLM provider agnostic\u003c/small\u003e\"]\n            IPC[\"IPC Bridge\u003cbr/\u003e\u003csmall\u003efsnotify → NATS\u003c/small\u003e\"]\n            SB[\"Sandbox\u003cbr/\u003e\u003csmall\u003eoptional sidecar\u003c/small\u003e\"]\n            SKS[\"Skill Sidecars\u003cbr/\u003e\u003csmall\u003ekubectl, helm, etc.\u003cbr/\u003eauto-RBAC\u003c/small\u003e\"]\n            A1 -. \"/ipc volume\" .- IPC\n            A1 -. optional .- SB\n            A1 -. \"/workspace\" .- SKS\n        end\n\n        subgraph SEC[\"Skill RBAC  ·  ephemeral, least-privilege\"]\n            SR[\"Role + RoleBinding\u003cbr/\u003e\u003csmall\u003enamespace-scoped\u003cbr/\u003eownerRef → AgentRun\u003c/small\u003e\"]\n            SCR[\"ClusterRole + Binding\u003cbr/\u003e\u003csmall\u003ecluster-scoped\u003cbr/\u003elabel-based cleanup\u003c/small\u003e\"]\n        end\n\n        SKS -- \"uses\" --\u003e SR\n        SKS -- \"uses\" --\u003e SCR\n        CM -- \"creates / deletes\" --\u003e SEC\n\n        subgraph MEM[\"Persistent Memory\"]\n            MCM[(\"ConfigMap\u003cbr/\u003e\u003csmall\u003e\u0026lt;instance\u0026gt;-memory\u003c/small\u003e\")]\n            A1 -- \"reads /memory\u003cbr/\u003eMEMORY.md\" --\u003e MCM\n            CM -- \"extracts \u0026 patches\u003cbr/\u003ememory markers\" --\u003e MCM\n        end\n\n        subgraph DATA[\"Data Layer\"]\n            ETCD[(\"etcd\u003cbr/\u003e\u003csmall\u003eCRDs, state\u003c/small\u003e\")]\n            PG[(\"PostgreSQL\u003cbr/\u003e\u003csmall\u003esessions, history\u003c/small\u003e\")]\n            SK[(\"SkillPack ConfigMaps\u003cbr/\u003e\u003csmall\u003emounted at /skills\u003c/small\u003e\")]\n        end\n\n        TG \u0026 SL \u0026 DC \u0026 WA -- \"messages\" --\u003e NATS\n        NATS -- \"tasks\" --\u003e IPC\n        IPC -- \"channel msgs\u003cbr/\u003eschedule requests\" --\u003e NATS\n        NATS -- \"schedule.upsert\" --\u003e SROUTER\n    end\n\n    USER([\"User / Chat Client\"]) -- \"Telegram · Slack\u003cbr/\u003eDiscord · WhatsApp\" --\u003e CH\n    ADMIN([\"Operator / SRE\"]) -- \"sympozium TUI\u003cbr/\u003ekubectl · k9s\" --\u003e CP\n\n    style K8S fill:#0d1117,stroke:#30363d,color:#c9d1d9\n    style CP fill:#1a1a2e,stroke:#e94560,color:#fff\n    style SCHED fill:#1a1a2e,stroke:#f5a623,color:#fff\n    style CH fill:#16213e,stroke:#0f3460,color:#fff\n    style AP fill:#0f3460,stroke:#53354a,color:#fff\n    style MEM fill:#1c2333,stroke:#7c3aed,color:#fff\n    style SEC fill:#1c2333,stroke:#238636,color:#fff\n    style DATA fill:#161b22,stroke:#30363d,color:#c9d1d9\n    style NATS fill:#e94560,stroke:#fff,color:#fff\n    style USER fill:#238636,stroke:#fff,color:#fff\n    style ADMIN fill:#1f6feb,stroke:#fff,color:#fff\n```\n\n### How It Works\n\n1. **A message arrives** via a channel pod (Telegram, Slack, etc.) and is published to the NATS event bus.\n2. **The controller creates an AgentRun CR**, which reconciles into an ephemeral K8s Job — an agent container + IPC bridge sidecar + optional sandbox + skill sidecars (with auto-provisioned RBAC).\n3. **The agent container** calls the configured LLM provider (OpenAI, Anthropic, Azure, Ollama, or any OpenAI-compatible endpoint), with skills mounted as files, persistent memory injected from a ConfigMap, and tool sidecars providing runtime capabilities like `kubectl`.\n4. **Results flow back** through the IPC bridge → NATS → channel pod → user. The controller extracts structured results and memory updates from pod logs.\n5. **Everything is a Kubernetes resource** — instances, runs, policies, skills, and schedules are all CRDs. Lifecycle is managed by controllers. Access is gated by admission webhooks. Network isolation is enforced by NetworkPolicy. The TUI gives you k9s-style visibility into the entire system.\n\n---\n\n### Built-in Agent Tools\n\nEvery agent pod has these tools available out of the box (no skill sidecar required for native tools):\n\n| Tool | Type | Description |\n|------|------|-------------|\n| `execute_command` | IPC (sidecar) | Execute shell commands (`kubectl`, `bash`, `curl`, `jq`, etc.) in the skill sidecar container. Timeout-configurable, working directory support. |\n| `read_file` | Native | Read file contents from the pod filesystem (`/workspace`, `/skills`, `/tmp`, `/ipc`). Truncated at 100 KB. |\n| `write_file` | Native | Create or overwrite files under `/workspace` or `/tmp`. Auto-creates parent directories. |\n| `list_directory` | Native | List directory contents with type, size, and name. |\n| `fetch_url` | Native | Fetch web pages or API endpoints. HTML is converted to readable plain text; JSON returned as-is. Supports custom headers, configurable max chars (default 50k). |\n| `send_channel_message` | IPC (bridge) | Send a message through a connected channel (WhatsApp, Telegram, Discord, Slack). Routes via IPC bridge → NATS → channel pod. |\n\n\u003e **Native** tools run directly in the agent container. **IPC** tools communicate with sidecars or the IPC bridge via the shared `/ipc` volume. See the **[Tool Authoring Guide](docs/writing-tools.md)** for how to add your own.\n\n### Built-in Skills (SkillPacks)\n\nSkills are mounted as files into agent pods and optionally inject sidecar containers with runtime tools. Toggle skills per-instance in the TUI with `s` → `Space`.\n\n| SkillPack | Category | Sidecar | Description | Status |\n|-----------|----------|---------|-------------|--------|\n| `k8s-ops` | Kubernetes | ✅ `kubectl`, `curl`, `jq` | Cluster inspection, workload management, troubleshooting, scaling. Full admin RBAC auto-provisioned per run. | **Stable** |\n| `incident-response` | SRE | ✅ | Structured incident triage — gather context, diagnose root cause, suggest remediation. | **Alpha** |\n| `code-review` | Development | — | Code review guidelines and best practices for pull request analysis. | **Alpha** |\n\n### Channels\n\nChannels connect Sympozium to external messaging platforms. Each channel runs as a dedicated Kubernetes Deployment. Messages flow through NATS JetStream and are routed to AgentRuns by the channel router.\n\n| Channel | Protocol | Self-chat | Status |\n|---------|----------|-----------|--------|\n| **WhatsApp** | WhatsApp Web (multidevice) via `whatsmeow` | ✅ Owner can message themselves to interact with agents | **Stable** |\n| **Telegram** | Bot API (`tgbotapi`) | ✅ Owner can message themselves to interact with agents | **Stable** |\n| **Discord** | Gateway WebSocket (`discordgo`) | — | **Alpha** |\n| **Slack** | Socket Mode (`slack-go`) | — | **Alpha** |\n\n\u003e **Stable** — tested and actively used. **Alpha** — implemented but not yet production-tested.\n\n---\n\n## Custom Resources\n\nSympozium models every agentic concept as a Kubernetes Custom Resource:\n\n| CRD | Kubernetes Analogy | Purpose |\n|-----|--------------------|---------|\n| `SympoziumInstance` | Namespace / Tenant | Per-user gateway — channels, provider config, memory settings, skill bindings |\n| `AgentRun` | Job | Single agent execution — task, model, result capture, memory extraction |\n| `SympoziumPolicy` | NetworkPolicy | Feature and tool gating — what an agent can and cannot do |\n| `SkillPack` | ConfigMap | Portable skill bundles — kubectl, Helm, or custom tools — mounted into agent pods as files, with optional sidecar containers for cluster ops |\n| `SympoziumSchedule` | CronJob | Recurring tasks — heartbeats, sweeps, scheduled runs with cron expressions |\n| `PersonaPack` | Helm Chart / Operator Bundle | Pre-configured agent bundles — activating a pack stamps out instances, schedules, and memory for each persona |\n\n### PersonaPacks\n\nPersonaPacks are the **recommended way to get started** with Sympozium. A PersonaPack is a CRD that bundles multiple pre-configured agent personas — each with a system prompt, skills, tool policy, schedule, and memory seeds. Activating a pack is a single action: the PersonaPack controller stamps out all the Kubernetes resources automatically.\n\n**Why PersonaPacks?**\n\nWithout PersonaPacks, setting up even one agent requires creating a Secret, SympoziumInstance, SympoziumSchedule, and memory ConfigMap by hand. PersonaPacks collapse that into: pick a pack → enter your API key → done.\n\n**How it works:**\n\n```\nPersonaPack \"platform-team\" (3 personas)\n  │\n  ├── Activate via TUI (Enter on pack → wizard → API key → confirm)\n  │\n  └── Controller stamps out:\n      ├── Secret: platform-team-openai-key\n      ├── SympoziumInstance: platform-team-security-guardian\n      │   ├── SympoziumSchedule: ...security-guardian-schedule (every 30m)\n      │   └── ConfigMap: ...security-guardian-memory (seeded)\n      ├── SympoziumInstance: platform-team-sre-watchdog\n      │   ├── SympoziumSchedule: ...sre-watchdog-schedule (every 5m)\n      │   └── ConfigMap: ...sre-watchdog-memory (seeded)\n      └── SympoziumInstance: platform-team-platform-engineer\n          ├── SympoziumSchedule: ...platform-engineer-schedule (weekdays 9am)\n          └── ConfigMap: ...platform-engineer-memory (seeded)\n```\n\nAll generated resources have `ownerReferences` pointing back to the PersonaPack — delete the pack and everything gets garbage-collected.\n\n**Built-in packs:**\n\n| Pack | Category | Agents | Description |\n|------|----------|--------|-------------|\n| `platform-team` | Platform | Security Guardian, SRE Watchdog, Platform Engineer | Core platform engineering — security audits, cluster health, manifest review |\n| `devops-essentials` | DevOps | Incident Responder, Cost Analyzer | DevOps workflows — incident triage, resource right-sizing |\n\n**Activating a pack in the TUI:**\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"personas.gif\" alt=\"PersonaPack activation in the TUI\" width=\"800px;\"\u003e\n\u003c/p\u003e\n\n1. Launch `sympozium` — the TUI opens on the **Personas** tab (view 1)\n2. Select a pack and press **Enter** to start the onboarding wizard\n3. Choose your AI provider and paste an API key\n4. Optionally bind channels (Telegram, Slack, Discord, WhatsApp)\n5. Confirm — the controller creates all instances within seconds\n\n**Activating via kubectl:**\n\n```yaml\n# 1. Create the provider secret\nkubectl create secret generic my-pack-openai-key \\\n  --from-literal=OPENAI_API_KEY=sk-...\n\n# 2. Patch the PersonaPack with authRefs to trigger activation\nkubectl patch personapack platform-team --type=merge -p '{\n  \"spec\": {\n    \"authRefs\": [{\"provider\": \"openai\", \"secret\": \"my-pack-openai-key\"}]\n  }\n}'\n```\n\nThe controller detects the `authRefs` change and reconciles — creating SympoziumInstances, Schedules, and memory ConfigMaps for each persona.\n\n**Writing your own PersonaPack:**\n\n```yaml\napiVersion: sympozium.ai/v1alpha1\nkind: PersonaPack\nmetadata:\n  name: my-team\nspec:\n  description: \"My custom agent team\"\n  category: custom\n  version: \"1.0.0\"\n  personas:\n    - name: my-agent\n      displayName: \"My Agent\"\n      systemPrompt: |\n        You are a helpful assistant that monitors the cluster.\n      skills:\n        - k8s-ops\n      toolPolicy:\n        allow: [read_file, list_directory, execute_command, fetch_url]\n      schedule:\n        type: heartbeat\n        interval: \"1h\"\n        task: \"Check cluster health and report any issues.\"\n      memory:\n        enabled: true\n        seeds:\n          - \"Track recurring issues for trend analysis\"\n```\n\nApply it with `kubectl apply -f my-team.yaml`, then activate through the TUI.\n\n### Skill Sidecars\n\nSkillPacks can declare a **sidecar container** that is dynamically injected into the agent pod when the skill is active. The controller automatically creates scoped RBAC:\n\n```\nSympoziumInstance has skills: [k8s-ops]\n  → AgentRun created\n    → Controller resolves SkillPack \"k8s-ops\"\n      → Finds sidecar: { image: skill-k8s-ops, rbac: [...] }\n      → Injects sidecar container into pod\n      → Creates Role + RoleBinding (namespace-scoped)\n      → Creates ClusterRole + ClusterRoleBinding (cluster-wide access)\n    → Pod runs with kubectl + RBAC available\n    → On completion/deletion: all skill RBAC cleaned up\n```\n\nThe `k8s-ops` built-in skill is the first proof of concept — it provides a sidecar with `kubectl`, `curl`, and `jq` with full admin access to workload resources (pods, deployments, services, etc.) and cluster-wide read access to nodes, namespaces, and more. See the **[Skill Authoring Guide](docs/writing-skills.md)** for a full walkthrough of building your own skills. To enable a skill, toggle it on your instance:\n\n```\n# In the TUI: press 's' on an instance → Space to toggle k8s-ops\n# Or via kubectl:\nkubectl patch sympoziuminstance \u003cname\u003e --type=merge -p '{\"spec\":{\"skills\":[{\"skillPackRef\":\"k8s-ops\"}]}}'\n```\n\n### Security\n\nSympozium enforces defence-in-depth at every layer — from network isolation to per-run RBAC:\n\n| Layer | Mechanism | Scope |\n|-------|-----------|-------|\n| **Network** | `NetworkPolicy` deny-all egress on agent pods | Only the IPC bridge can reach NATS; agents cannot reach the internet or other pods |\n| **Pod sandbox** | `SecurityContext` — `runAsNonRoot`, UID 1000, read-only root filesystem | Every agent and sidecar container runs with least privilege |\n| **Admission control** | `SympoziumPolicy` admission webhook | Feature and tool gates enforced before the pod is created |\n| **Skill RBAC** | Ephemeral `Role`/`ClusterRole` per AgentRun | Each skill declares exactly the API permissions it needs — the controller auto-provisions them at run start and revokes them on completion |\n| **RBAC lifecycle** | `ownerReference` (namespace) + label-based cleanup (cluster) | Namespace RBAC is garbage-collected by Kubernetes. Cluster RBAC is cleaned up by the controller on AgentRun completion and deletion. |\n| **Controller privilege** | `cluster-admin` binding | The controller needs `cluster-admin` to create arbitrary RBAC rules declared by SkillPacks (Kubernetes prevents RBAC escalation otherwise) |\n| **Multi-tenancy** | Namespaced CRDs + Kubernetes RBAC | Instances, runs, and policies are namespace-scoped; standard K8s RBAC controls who can create them |\n\nThe skill sidecar RBAC model deserves special attention: permissions are **created on-demand** when an AgentRun starts, scoped to exactly the APIs the skill needs, and **deleted when the run finishes**. There is no standing god-role — each run gets its own short-lived credentials. This is the Kubernetes-native equivalent of temporary IAM session credentials.\n\n### Persistent Memory\n\nEach `SympoziumInstance` can enable **persistent memory** — a ConfigMap (`\u003cinstance\u003e-memory`) containing `MEMORY.md` that is:\n- Mounted read-only into every agent pod at `/memory/MEMORY.md`\n- Prepended as context so the agent knows what it has learned\n- Updated after each run — the controller extracts memory markers from pod logs and patches the ConfigMap\n\nThis gives agents **continuity across runs** without external databases or file systems. Memory lives in etcd alongside all other cluster state.\n\n### Scheduled Tasks (Heartbeats)\n\n`SympoziumSchedule` resources define cron-based recurring agent runs — perfect for automated cluster health checks, overnight alert reviews, resource right-sizing sweeps, or any domain-specific task:\n\n```yaml\napiVersion: sympozium.ai/v1alpha1\nkind: SympoziumSchedule\nmetadata:\n  name: daily-standup\nspec:\n  instanceRef: alice\n  schedule: \"0 9 * * *\"        # every day at 9am\n  type: heartbeat\n  task: \"Review overnight alerts and summarize status\"\n  includeMemory: true           # inject persistent memory\n  concurrencyPolicy: Forbid     # skip if previous run still active\n```\n\nConcurrency policies (`Forbid`, `Allow`, `Replace`) work like `CronJob.spec.concurrencyPolicy` — a natural extension of Kubernetes semantics.\n\n## Interactive TUI\n\nRunning `sympozium` with no arguments launches a **k9s-style interactive terminal UI** for full cluster-wide agentic management.\n\n### Views\n\n| Key | View | Description |\n|-----|------|-------------|\n| `1` | Personas | PersonaPack list — press Enter to activate a pack and create agents |\n| `2` | Instances | SympoziumInstance list with status, channels, memory config |\n| `3` | Runs | AgentRun list with phase, duration, result preview |\n| `4` | Policies | SympoziumPolicy list with feature gates |\n| `5` | Skills | SkillPack list with file counts |\n| `6` | Channels | Channel pod status (Telegram, Slack, Discord, WhatsApp) |\n| `7` | Schedules | SympoziumSchedule list with cron, type, phase, run count |\n| `8` | Pods | All sympozium pods with status and restarts |\n\n### Keybindings\n\n| Key | Action |\n|-----|--------|\n| `l` | View logs for the selected resource |\n| `d` | Describe the selected resource (kubectl describe) |\n| `x` | Delete the selected resource (with confirmation) |\n| `Enter` | View details / select row |\n| `Tab` | Cycle between views |\n| `Esc` | Go back / close panel |\n| `?` | Toggle help |\n\n### Slash Commands\n\n| Command | Description |\n|---------|-------------|\n| `/run \u003ctask\u003e` | Create and submit an AgentRun |\n| `/schedule \u003cinstance\u003e \u003ccron\u003e \u003ctask\u003e` | Create a SympoziumSchedule |\n| `/memory \u003cinstance\u003e` | View persistent memory for an instance |\n| `/personas` | Switch to PersonaPacks view |\n| `/instances` `/runs` `/channels` `/schedules` | Switch views |\n| `/delete \u003ctype\u003e \u003cname\u003e` | Delete a resource with confirmation |\n\n## Getting Started\n\n### 1. Install the CLI\n\n```bash\ncurl -fsSL https://deploy.sympozium.ai/install.sh | sh\n```\n\nDetects your OS and architecture, downloads the latest release binary, and installs to `/usr/local/bin` (or `~/.local/bin`).\n\n### 2. Deploy to your cluster\n\n```bash\nsympozium install\n```\n\nApplies CRDs, RBAC, controller manager, API server, admission webhook, NATS event bus, cert-manager (if not present), and network policies to your current kubectl context.\n\n```bash\nsympozium install --version v0.0.13   # specific version\n```\n\n### 3. Activate a PersonaPack (recommended)\n\nLaunch the TUI and activate one of the built-in PersonaPacks:\n\n```bash\nsympozium\n```\n\nThe TUI opens on the **Personas** tab. Press **Enter** on a pack (e.g. `platform-team`) to start the onboarding wizard:\n\n1. Choose your AI provider (OpenAI, Anthropic, Azure, Ollama, or custom)\n2. Paste your API key\n3. Pick a model\n4. Optionally bind messaging channels\n5. Confirm — the controller creates all agent instances automatically\n\nWithin seconds you'll have multiple purpose-built agents running on schedules, each with their own skills, memory, and tool policies.\n\n### Alternative: Manual onboard (single instance)\n\nIf you prefer to create a single instance manually:\n\n```bash\nsympozium onboard\n```\n\nThe wizard walks you through five steps:\n\n```\n  ╔═══════════════════════════════════════════╗\n  ║         Sympozium · Onboarding Wizard       ║\n  ╚═══════════════════════════════════════════╝\n\n  Step 1/5 — Cluster check\n  Step 2/5 — Name your SympoziumInstance\n  Step 3/5 — Choose your AI provider\n  Step 4/5 — Connect a channel (optional)\n  Step 5/5 — Apply default policy\n```\n\n**Step 3** supports any GenAI provider:\n\n| Provider | Base URL | API Key |\n|----------|----------|---------|\n| OpenAI | (default) | `OPENAI_API_KEY` |\n| Anthropic | (default) | `ANTHROPIC_API_KEY` |\n| Azure OpenAI | your endpoint | `AZURE_OPENAI_API_KEY` |\n| Ollama | `http://ollama:11434/v1` | none |\n| Any OpenAI-compatible | custom URL | custom |\n\n### 4. Launch Sympozium\n\n```bash\nsympozium\n```\n\nThe interactive TUI gives you full visibility — browse instances, runs, schedules, and channels; view logs and describe output inline; submit agent runs with `/run \u003ctask\u003e`; check memory with `/memory \u003cinstance\u003e`.\n\n```bash\nsympozium instances list                              # list instances\nsympozium runs list                                   # list agent runs\nsympozium features enable browser-automation \\\n  --policy default-policy                           # enable a feature gate\n```\n\n### 5. Remove Sympozium\n\n```bash\nsympozium uninstall\n```\n\n## Project Structure\n\n```\nsympozium/\n├── api/v1alpha1/           # CRD type definitions (SympoziumInstance, AgentRun, SympoziumPolicy, SkillPack, SympoziumSchedule, PersonaPack)\n├── cmd/                    # Binary entry points\n│   ├── agent-runner/       # LLM agent runner (runs inside agent pods)\n│   ├── controller/         # Controller manager (reconciles all CRDs)\n│   ├── apiserver/          # HTTP + WebSocket API server\n│   ├── ipc-bridge/         # IPC bridge sidecar (fsnotify → NATS)\n│   ├── webhook/            # Admission webhook (policy enforcement)\n│   └── sympozium/            # CLI + interactive TUI\n├── internal/               # Internal packages\n│   ├── controller/         # Kubernetes controllers (6 reconcilers incl. PersonaPack)\n│   ├── orchestrator/       # Agent pod builder \u0026 spawner\n│   ├── apiserver/          # API server handlers\n│   ├── eventbus/           # NATS JetStream event bus\n│   ├── ipc/                # IPC bridge (fsnotify + NATS)\n│   ├── webhook/            # Policy enforcement webhooks\n│   ├── session/            # Session persistence (PostgreSQL)\n│   └── channel/            # Channel base types\n├── channels/               # Channel pod implementations (Telegram, Slack, Discord, WhatsApp)\n├── images/                 # Dockerfiles for all components\n├── config/                 # Kubernetes manifests\n│   ├── crd/bases/          # CRD YAML definitions\n│   ├── manager/            # Controller deployment\n│   ├── rbac/               # ClusterRole, bindings\n│   ├── webhook/            # Webhook configuration\n│   ├── network/            # NetworkPolicy for agent isolation\n│   ├── nats/               # NATS JetStream deployment\n│   ├── cert/               # TLS certificate resources\n│   ├── personas/           # Built-in PersonaPack definitions\n│   ├── skills/             # Built-in SkillPack definitions\n│   ├── policies/           # Default SympoziumPolicy presets\n│   └── samples/            # Example CRs\n├── migrations/             # PostgreSQL schema migrations\n├── docs/                   # Design documentation\n├── Makefile\n└── README.md\n```\n\n## Key Design Decisions\n\n| Decision | Kubernetes Primitive | Rationale |\n|----------|---------------------|-----------|\n| **One Pod per agent run** | Job | Blast-radius isolation, resource limits, automatic cleanup — each agent is as ephemeral as a CronJob pod |\n| **Filesystem IPC** | emptyDir volume | Agent writes to `/ipc/`, bridge sidecar watches via fsnotify and publishes to NATS — language-agnostic, zero dependencies in agent container |\n| **NATS JetStream** | StatefulSet | Durable pub/sub with replay — channels and control plane communicate without direct coupling |\n| **NetworkPolicy isolation** | NetworkPolicy | Agent pods get deny-all egress; only the IPC bridge connects to the event bus — agents cannot reach the internet or other pods |\n| **Policy-as-CRD** | Admission Webhook | `SympoziumPolicy` resources gate tools, sandboxes, and features — enforced at admission time, not at runtime |\n| **Memory-as-ConfigMap** | ConfigMap | Persistent agent memory lives in etcd — no external database, no file system, fully declarative and backed up with cluster state |\n| **Schedule-as-CRD** | CronJob analogy | `SympoziumSchedule` resources define recurring tasks with cron expressions — the controller creates AgentRuns, not the user |\n| **Skills-as-ConfigMap** | ConfigMap volume | SkillPacks generate ConfigMaps mounted into agent pods — portable, versionable, namespace-scoped |\n| **Skill sidecars with auto-RBAC** | Role / ClusterRole | SkillPacks can declare sidecar containers with RBAC rules — the controller injects the container and provisions ephemeral, least-privilege RBAC per run |\n| **PersonaPacks** | Operator Bundle | Pre-configured agent bundles — the controller stamps out SympoziumInstances, Schedules, and memory ConfigMaps. Activating a pack is a single TUI action |\n\n## Configuration\n\n| Variable | Component | Description |\n|----------|-----------|-------------|\n| `EVENT_BUS_URL` | All | NATS server URL |\n| `DATABASE_URL` | API Server | PostgreSQL connection string |\n| `INSTANCE_NAME` | Channels | Owning SympoziumInstance name |\n| `MEMORY_ENABLED` | Agent Runner | Whether persistent memory is active |\n| `TELEGRAM_BOT_TOKEN` | Telegram | Bot API token |\n| `SLACK_BOT_TOKEN` | Slack | Bot OAuth token |\n| `DISCORD_BOT_TOKEN` | Discord | Bot token |\n| `WHATSAPP_ACCESS_TOKEN` | WhatsApp | Cloud API access token |\n\n## Development\n\n```bash\nmake test        # run tests (46 passing)\nmake lint        # run linter\nmake manifests   # generate CRD manifests\nmake run         # run controller locally (needs kubeconfig)\n```\n\n## License\n\nApache License 2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexsjones%2Fsympozium","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexsjones%2Fsympozium","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexsjones%2Fsympozium/lists"}