symbi 1.16.0

AI-native agent framework for building autonomous, policy-aware agents that can safely collaborate with humans, other agents, and large language models
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
# Modo de Execução Nativa (Sem Docker/Isolamento)

## Outros idiomas


O Symbiont suporta a execução de agentes sem Docker ou isolamento de containers para ambientes de desenvolvimento ou implantações confiáveis onde desempenho máximo e dependências mínimas são desejados.

## Avisos de Segurança

**IMPORTANTE**: O modo de execução nativa ignora todos os controles de segurança baseados em container:

- Sem isolamento de processos
- Sem isolamento de sistema de arquivos
- Sem isolamento de rede
- Sem imposição de limites de recursos
- Acesso direto ao sistema host

> **A feature `native-sandbox` não compila em builds de release.** Ela é protegida por um `compile_error!` sob `not(debug_assertions)`, de modo que um binário de release nunca pode incluir o runner nativo. É um auxílio de desenvolvimento somente para debug.

**USE APENAS PARA**:
- Desenvolvimento local com código confiável
- Ambientes controlados com agentes confiáveis
- Testes e depuração
- Ambientes onde Docker não está disponível

**NAO USE PARA**:
- Ambientes de produção com código não confiável
- Implantações multi-tenant
- Serviços expostos publicamente
- Processamento de entrada de usuários não confiáveis

## Arquitetura

### Hierarquia de Níveis de Sandbox

```
┌─────────────────────────────────────────┐
│ SecurityTier::None (Execução Nativa)    │ ← Sem isolamento
├─────────────────────────────────────────┤
│ SecurityTier::Tier1 (Docker)            │ ← Isolamento de container
├─────────────────────────────────────────┤
│ SecurityTier::Tier2 (gVisor)            │ ← Isolamento aprimorado
├─────────────────────────────────────────┤
│ SecurityTier::Tier3 (Firecracker)       │ ← Isolamento máximo
└─────────────────────────────────────────┘
```

### Fluxo de Execução Nativa

```mermaid
graph LR
    A[Requisição do Agente] --> B{Nível de Segurança?}
    B -->|None| C[Native Process Runner]
    B -->|Tier1+| D[Sandbox Orchestrator]

    C --> E[Execução Direta de Processo]
    E --> F[Sistema Host]

    D --> G[Docker/gVisor/Firecracker]
    G --> H[Ambiente Isolado]
```

## Configuração

### Opção 1: Configuração TOML

```toml
# symbiont.toml

[security]
# Permitir execução nativa (padrão: false)
allow_native_execution = true

# A execução nativa é sua própria seção de nível superior (não aninhada sob [security]).
[native_execution]
enabled = true
default_executable = "python3"
working_directory = "/tmp/symbiont-native"
# Aplicar limites de recursos do SO mesmo em modo nativo
enforce_resource_limits = true
max_memory_mb = 2048              # Option<u64>
max_cpu_seconds = 300             # Option<u64> — tempo de CPU, não contagem de núcleos
max_execution_time_seconds = 300  # timeout de relógio
allowed_executables = ["python3", "node", "bash"]
```

### Exemplo de Configuração Completa

Um `config.toml` completo com execução nativa junto com outras configurações do sistema:

```toml
# config.toml
[api]
port = 8080
host = "127.0.0.1"
timeout_seconds = 30
max_body_size = 10485760

[database]
# Dimensão do vetor de embedding. O LanceDB (backend embarcado padrão) não
# precisa de configuração adicional. O backend é escolhido em tempo de compilação
# via a feature Cargo `vector-lancedb` (padrão) ou `vector-qdrant` — não existe
# chave de configuração `vector_backend`; use a variável de ambiente
# SYMBIONT_VECTOR_BACKEND para alternar em tempo de execução.
vector_dimension = 384

# Usado ao executar com o backend Qdrant (SYMBIONT_VECTOR_BACKEND=qdrant):
# qdrant_url = "http://localhost:6333"
# qdrant_collection = "symbiont"

[logging]
level = "info"
format = "Pretty"
structured = true

[security]
key_provider = { Environment = { var_name = "SYMBIONT_KEY" } }
enable_compression = true
enable_backups = true
enable_safety_checks = true

[storage]
context_path = "./data/context"
git_clone_path = "./data/git"
backup_path = "./data/backups"
max_context_size_mb = 1024

[native_execution]
enabled = true
default_executable = "python3"
working_directory = "/tmp/symbiont-native"
enforce_resource_limits = true
max_memory_mb = 2048
max_cpu_seconds = 300
max_execution_time_seconds = 300
allowed_executables = ["python3", "python", "node", "bash", "sh"]
```

### Campos de NativeExecutionConfig

| Campo | Tipo | Padrão | Descrição |
|-------|------|--------|-----------|
| `enabled` | bool | `false` | Habilitar modo de execução nativa |
| `default_executable` | string | `"bash"` | Interpretador/shell padrão |
| `working_directory` | path | `/tmp/symbiont-native` | Diretório de execução |
| `enforce_resource_limits` | bool | `true` | Aplicar limites no nível do SO |
| `max_memory_mb` | Option<u64> | `Some(2048)` | Limite de memória em MB |
| `max_cpu_seconds` | Option<u64> | `Some(300)` | Limite de tempo de CPU |
| `max_execution_time_seconds` | u64 | `300` | Timeout de relógio |
| `allowed_executables` | Vec<String> | `[bash, python3, etc.]` | Lista de executáveis permitidos |

### Opção 2: Proteções de segurança de runtime (ambiente)

Não existem configurações `SYMBIONT_NATIVE_*` / `SYMBIONT_ALLOW_NATIVE_EXECUTION` /
`SYMBIONT_DEFAULT_SANDBOX_TIER` — a execução nativa é configurada através da
seção de configuração `[native_execution]` acima. As únicas variáveis de
ambiente relacionadas ao modo nativo são as duas proteções de segurança de
runtime, ambas as quais devem ser definidas para realmente executar o runner
nativo (sem isolamento):

```bash
export SYMBI_UNSAFE_NATIVE_SANDBOX=1   # reconhece o runner nativo
export SYMBIONT_ALLOW_UNISOLATED=1     # permite SandboxTier::None
```

### Opção 3: Configuração por Agente

```symbi
metadata {
  version = "1.0.0"
  description = "Local Development Agent"
}

agent native_worker(task: String) -> String {
  capabilities = ["local_filesystem", "network"]

  policy dev_only {
    allow: ["local_filesystem", "network"] if true
  }

  # tier 0 = sem sandbox (execução no host); requer os opt-ins acima
  with sandbox = "none" {
    return process(task);
  }
}
```

## Exemplos de Uso

### Exemplo 1: Modo de Desenvolvimento

```rust
use symbi_runtime::{Config, SecurityTier, SandboxOrchestrator};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Habilitar execução nativa para desenvolvimento
    let mut config = Config::default();
    config.security.allow_native_execution = true;

    let orchestrator = SandboxOrchestrator::new(config)?;

    // Executar código nativamente
    let result = orchestrator.execute_code(
        SecurityTier::None,
        "print('Hello from native execution!')",
        HashMap::new()
    ).await?;

    println!("Output: {}", result.stdout);
    Ok(())
}
```

### Exemplo 2: Compilando e executando com o runner nativo

Não existe uma flag de CLI `--native`. A execução nativa (no host) requer três opt-ins explícitos:

1. **Compile com a feature `native-sandbox` — apenas builds de debug.** A feature não oferece isolamento algum e é protegida por um `compile_error!` em builds de release:

   ```bash
   cargo build --features native-sandbox    # apenas debug; release não compila
   ```

2. **Reconheça ambas as proteções de runtime:**

   ```bash
   export SYMBI_UNSAFE_NATIVE_SANDBOX=1   # reconhece o runner nativo
   export SYMBIONT_ALLOW_UNISOLATED=1     # permite SandboxTier::None em execuções não-dev
   ```

3. **Selecione o tier 0 (sem sandbox) na DSL do agente:**

   ```
   with sandbox = "none" {
       // ...
   }
   ```

   Os limites de recursos (memória/CPU/timeout) vêm do bloco `with` / configuração (veja acima), não de flags de CLI.

Em seguida, execute normalmente:

```bash
symbi run agent.symbi
```

### Exemplo 3: Execução Mista

```rust
// Usar execução nativa para operações locais confiáveis
let local_result = orchestrator.execute_code(
    SecurityTier::None,
    local_code,
    env_vars
).await?;

// Usar Docker para operações externas/não confiáveis
let isolated_result = orchestrator.execute_code(
    SecurityTier::Tier1,
    untrusted_code,
    env_vars
).await?;
```

## Detalhes de Implementação

### Native Process Runner

O runner nativo usa `std::process::Command` com limites de recursos opcionais:

```rust
pub struct NativeRunner {
    config: NativeConfig,
}

impl NativeRunner {
    pub async fn execute(&self, code: &str, env: HashMap<String, String>)
        -> Result<ExecutionResult> {
        // Execução direta de processo
        let mut command = Command::new(&self.config.executable);
        command.current_dir(&self.config.working_dir);
        command.envs(env);

        // Opcional: Aplicar limites de recursos via rlimit (Unix)
        #[cfg(unix)]
        if self.config.enforce_limits {
            self.apply_resource_limits(&mut command)?;
        }

        let output = command.output().await?;

        Ok(ExecutionResult {
            stdout: String::from_utf8_lossy(&output.stdout).to_string(),
            stderr: String::from_utf8_lossy(&output.stderr).to_string(),
            exit_code: output.status.code().unwrap_or(-1),
            success: output.status.success(),
        })
    }
}
```

### Limites de Recursos (Unix)

Em sistemas Unix, a execução nativa ainda pode impor alguns limites:

- **Memória**: Usando `setrlimit(RLIMIT_AS)`
- **Tempo de CPU**: Usando `setrlimit(RLIMIT_CPU)`
- **Contagem de Processos**: Usando `setrlimit(RLIMIT_NPROC)`
- **Tamanho de Arquivo**: Usando `setrlimit(RLIMIT_FSIZE)`

### Suporte de Plataformas

| Plataforma | Execução Nativa | Limites de Recursos |
|------------|----------------|---------------------|
| Linux      | Completo       | rlimit              |
| macOS      | Completo       | Parcial             |
| Windows    | Completo       | Limitado            |

## Migração do Docker

### Passo 1: Atualizar Configuração

```diff
# symbiont.toml
[security]
+ allow_native_execution = true

+ [native_execution]
+ enabled = true
```

Em seguida, selecione o tier 0 (sem sandbox) por agente no DSL:

```
with sandbox = "none" { ... }
```

### Passo 2: Compilar e executar (apenas debug)

```bash
# Não é mais necessário
# docker build -t symbi:latest .
# docker run ...

# A feature native-sandbox é apenas para debug (compile_error! em builds release):
cargo build --features native-sandbox
SYMBI_UNSAFE_NATIVE_SANDBOX=1 SYMBIONT_ALLOW_UNISOLATED=1 \
  ./target/debug/symbi run agent.symbi
```

### Abordagem Híbrida

Use ambos os modos de execução estrategicamente -- nativo para operações locais confiáveis, Docker para código não confiável:

```rust
// Operações locais confiáveis
let local_result = orchestrator.execute_code(
    SecurityTier::None,  // Nativo
    trusted_code,
    env
).await?;

// Operações externas/não confiáveis
let isolated_result = orchestrator.execute_code(
    SecurityTier::Tier1,  // Docker
    external_code,
    env
).await?;
```

### Passo 3: Gerenciar Variáveis de Ambiente

O Docker isolava automaticamente as variáveis de ambiente. Com execução nativa, defina-as explicitamente:

```bash
export AGENT_API_KEY="xxx"
export AGENT_DB_URL="postgresql://..."
export SYMBI_UNSAFE_NATIVE_SANDBOX=1
export SYMBIONT_ALLOW_UNISOLATED=1
symbi run agent.symbi   # o agente deve declarar: with sandbox = "none" { ... }
```

## Comparação de Desempenho

| Modo | Inicialização | Throughput | Memória | Isolamento |
|------|---------------|------------|---------|------------|
| Nativo | ~10ms | 100% | Mínima | Nenhum |
| Docker | ~500ms | ~95% | +128MB | Bom |
| gVisor | ~800ms | ~70% | +256MB | Melhor |
| Firecracker | ~125ms | ~90% | +64MB | Ótimo |

## Solução de Problemas

### Problema: Permissão Negada

```bash
# Solução: Garantir que o diretório de trabalho seja gravável
mkdir -p /tmp/symbiont-native
chmod 755 /tmp/symbiont-native
```

### Problema: Comando Não Encontrado

```bash
# Solução: Garantir que o executável está no PATH ou usar caminho absoluto
export PATH=$PATH:/usr/local/bin
# Ou configurar caminho absoluto
allowed_executables = ["/usr/bin/python3", "/usr/bin/node"]
```

### Problema: Limites de Recursos Não Aplicados

A execução nativa no Windows possui suporte limitado a limites de recursos. Considere:
- Usar Job Objects (específico do Windows)
- Monitorar e encerrar processos descontrolados
- Migrar para execução baseada em container

## Boas Práticas

1. **Apenas para Desenvolvimento**: Use execução nativa primariamente para desenvolvimento
2. **Migração Gradual**: Comece com containers, migre para nativo quando estável
3. **Monitoramento**: Mesmo sem isolamento, monitore o uso de recursos
4. **Listas de Permissão**: Restrinja executáveis e caminhos permitidos
5. **Logging**: Habilite logging de auditoria abrangente
6. **Testes**: Teste com containers antes de implantar nativamente

## Lista de Verificação de Segurança

Antes de habilitar a execução nativa em qualquer ambiente:

- [ ] Todo código de agente é de fontes confiáveis
- [ ] O ambiente está isolado da produção
- [ ] Nenhuma entrada externa de usuário é processada
- [ ] Monitoramento e logging estão habilitados
- [ ] Limites de recursos estão configurados
- [ ] Lista de executáveis permitidos é restritiva
- [ ] Acesso ao sistema de arquivos é limitado
- [ ] A equipe compreende as implicações de segurança

## Documentação Relacionada

- [Modelo de Segurança]security-model.pt.md - Arquitetura completa de segurança
- [Arquitetura de Sandbox]runtime-architecture.pt.md#sandbox-architecture - Níveis de container
- [Guia de Configuração]getting-started.pt.md#configuration - Opções de configuração
- [Diretivas de Segurança DSL]dsl-guide.pt.md#security - Segurança no nível do agente

---

**Lembre-se**: A execução nativa troca segurança por conveniência. Sempre compreenda os riscos e aplique controles apropriados para seu ambiente de implantação.