docs: добавлен анализ GPT-5.4 и Opus 4.6

- agent-handoff-2026-03-10.md — GPT-5.4 code review (lifecycle issues, invocation history gap)
- opus-pragmatic-review-2026-03-10.md — Opus прагматичный review для небольшого провайдера
- Opus: gVisor/LLM validation — overkill для MVP, фокус на быстрые фиксы + ResourceQuota/NetworkPolicy
- Обновлён progress.md с новыми документами
- .gitignore — добавлен test.token
This commit is contained in:
“Naeel”
2026-03-10 08:56:59 +04:00
parent 9d6db0d223
commit 7d6f8d6079
5 changed files with 1349 additions and 1 deletions
+130
View File
@@ -262,3 +262,133 @@ existing.Spec.Template.Annotations["kubectl.kubernetes.io/restartedAt"] = fn.Sta
**Правило проекта:** При использовании `:latest` tag всегда явно проставлять `restartedAt` annotation при обновлении кода.
**Версия:** operator `naeel/sless-operator:v0.1.11`
---
## 2026-03-10 — LLM-валидация кода при upload (pre-build security gate)
**Решение:** Интегрировать вызов облачного LLM в pipeline upload кода. LLM анализирует исходники пользователя **до** отправки в S3 и запуска kaniko. Если код подозрительный — upload отклоняется с HTTP 400 и причиной.
**Причина:**
1. LLM уже развёрнут (или скоро будет) в облаке nubes.ru — его нужно загрузить реальной работой.
2. Dogfooding: облачный провайдер использует собственный сервис ИИ в своём же продукте serverless.
3. Маркетинг: "ваш код проверяется ИИ перед деплоем" — реальная продающая фича.
4. Security: защита от криптомайнеров, ботнетов, DDoS-агентов, port scanners в пользовательских функциях.
**Точка интеграции:** `internal/api/handler/upload.go` — между распаковкой zip и упаковкой tar.gz.
**Pipeline с LLM:**
```
POST /upload (zip)
→ распаковка zip
→ извлечение текстовых файлов (.py, .js, .ts, .json, .sh, .sql ...)
→ POST к облачному LLM API с исходниками + системным промптом
→ safe=true → Dockerfile + tar.gz → S3 → CRD patch (обычный путь)
→ safe=false → HTTP 400 {"error": "code validation failed: <reason>"}
→ LLM error → warning в лог, upload продолжается (soft-fail)
```
**Режим работы: blocking + soft-fail**
- `safe=false` → upload отклоняется (HTTP 400), код не попадает в S3, сборка не начинается.
- LLM недоступен (timeout, 5xx) → upload **пропускается** (soft-fail), логируется warning.
Причина: недоступность LLM не должна ломать весь pipeline деплоя.
**Новый пакет:** `internal/validator/`
**Интерфейс:**
```go
// internal/validator/validator.go
type CodeValidator interface {
// Validate проверяет код функции перед сборкой.
// files — map[filename]content (текстовые файлы из zip).
// Возвращает (true, "") если код safe, (false, reason) если нет.
// При ошибке связи с LLM — возвращает (true, "") + логирует warning (soft-fail).
Validate(ctx context.Context, files map[string]string, runtime string) (safe bool, reason string, err error)
}
```
**LLM-реализация:**
```go
// internal/validator/llm.go
type LLMValidator struct {
endpoint string // URL облачного LLM API (OpenAI-compatible)
apiKey string // токен доступа
timeout time.Duration // default: 15s
log *slog.Logger
}
```
**Конфигурация (env vars):**
| Переменная | Default | Описание |
|------------|---------|----------|
| `LLM_ENABLED` | `false` | Включатель. false → NoopValidator (всегда safe) |
| `LLM_ENDPOINT` | — | URL LLM API, например `https://llm.nubes.ru/v1/chat/completions` |
| `LLM_API_KEY` | — | Bearer-токен для LLM API |
| `LLM_TIMEOUT` | `15s` | Максимальное время ожидания ответа |
`LLM_ENABLED=false` → оператор работает без LLM зависимости. По умолчанию выключено.
**Prompt-стратегия:**
Промпт НЕ хардкодится в Go — выносится в константу с возможностью override через ConfigMap.
```
You are a security reviewer for a serverless cloud platform.
Analyze the following {runtime} code deployed as a cloud function.
Check for:
1. Cryptocurrency mining (crypto hash algorithms, pool connections, stratum protocol)
2. DDoS/botnet behavior (mass outbound HTTP/UDP, connection floods)
3. Port scanning / network reconnaissance
4. Reverse shells, backdoors, C2 communication
5. Attempts to escape container (access host filesystem, /proc, /sys)
6. Obfuscated code designed to hide malicious intent
Files:
{files_content}
Respond ONLY with valid JSON, no other text:
{"safe": true} or {"safe": false, "reason": "brief explanation"}
```
**Что НЕ проверяем через LLM (не его задача):**
- Качество кода, стиль, best practices
- Уязвимости в зависимостях (это Trivy/npm audit, потом)
- Бизнес-логику пользователя
**Ограничения по размеру:**
- Суммарный размер текстовых файлов > 100KB → skip LLM (дорого, context window). Деплой проходит.
- Бинарные файлы (.pyc, .so, node_modules/) → не отправляются в LLM.
- Только расширения: `.py`, `.js`, `.ts`, `.json`, `.yaml`, `.yml`, `.txt`, `.sh`, `.sql`, `.go`.
**Встраивание в upload.go:**
```go
// После распаковки zip, до generateDockerfile
if h.Validator != nil {
files := extractTextFiles(zipData)
safe, reason, err := h.Validator.Validate(r.Context(), files, fn.Spec.Runtime)
if err != nil {
h.Log.Warn("llm validation error (soft-fail)", "err", err)
} else if !safe {
writeJSON(w, http.StatusBadRequest, errResp("code validation failed: "+reason))
return
}
}
```
**Terraform provider:** Получит `status 400: code validation failed: <reason>` — пользователь видит причину в `terraform apply` output.
**Файлы для реализации:**
1. `internal/validator/validator.go` — интерфейс CodeValidator + NoopValidator
2. `internal/validator/llm.go` — LLMValidator с HTTP client к OpenAI-compatible API
3. `internal/validator/extract.go` — extractTextFiles: zip → map[string]string
4. `internal/config/config.go` — добавить LLM_ENABLED, LLM_ENDPOINT, LLM_API_KEY, LLM_TIMEOUT
5. `internal/api/handler/handler.go` — добавить Validator поле
6. `internal/api/handler/upload.go` — вызов Validator между zip и tar.gz
7. `main.go` — wire: if LLM_ENABLED → LLMValidator, else → NoopValidator
**Компромиссы:**
- +5-15 секунд к каждому деплою (зависит от скорости LLM).
- False positives: пользователь получит 400 с причиной, может обратиться в support.
- Soft-fail при недоступности LLM: security degraded, но деплой работает.
- Prompt не идеален: LLM не ловит всё. Это дополнительный слой, не единственный.