diff --git a/doc/errors/log.md b/doc/errors/log.md
index e924a7f..303b221 100644
--- a/doc/errors/log.md
+++ b/doc/errors/log.md
@@ -631,3 +631,127 @@ Attribute runtime value must be one of: ["nodejs20" "python3.11" "go1.21"], got:
### Версии
- Оператор: `naeel/sless-operator:v0.1.13`
- Провайдер: `terra.k8c.ru/naeel/sless v0.1.7`
+
+---
+
+## 2026-03-19 — Баг 4: Хардкодный 30s таймаут в invoke.go → context deadline exceeded
+
+### Симптом
+
+Вызов функции `stress-go-pgstorm` с `duration_sec=30` возвращал:
+```json
+{"error": "function unreachable: ... context deadline exceeded"}
+```
+При этом под был `Running`, логи показывали нормальную работу pgxpool.
+
+### Корневая причина
+
+В `internal/api/handler/invoke.go` (строка 24) был глобальный http.Client:
+```go
+var httpClient = &http.Client{Timeout: 30 * time.Second}
+```
+Функция реально отрабатывала ровно 30 секунд (duration_sec=30) + накладные расходы
+на pgxpool.New() и первый коннект к БД ≈ 1-2 секунды.
+Итого запрос превышал 30s → оператор разрывал соединение раньше чем функция успевала ответить.
+
+### Почему так было написано
+
+При создании invoke.go в марте 2026 таймаут 30s считался "достаточным для холодного
+старта". Длительные функции тогда не планировались. Когда появились batch/stress задачи
+с timeout_sec=600-700 — баг стал критическим.
+
+### Решение
+
+Убрать глобальный `httpClient`. Перед каждым вызовом:
+1. Получить Function CRD из k8s: `h.K8s.Get(ctx, ObjectKey{name, ns}, fn)`
+2. Прочитать `fn.Spec.TimeoutSec`
+3. Создать `http.Client{Timeout: TimeoutSec*time.Second + 5*time.Second}`
+4. Если функция не найдена (Get вернул ошибку) — дефолт 30s
+
+```go
+func invokeHTTPClient(timeoutSec int32) *http.Client {
+ t := time.Duration(timeoutSec)*time.Second + 5*time.Second
+ if timeoutSec <= 0 {
+ t = 30 * time.Second
+ }
+ return &http.Client{Timeout: t}
+}
+```
+
+### Файл
+
+`internal/api/handler/invoke.go` — исправлено в коммите `d7fda15`
+Оператор пересобран: `naeel/sless-operator:v0.1.40`
+
+### Урок
+
+**Никогда не хардкодить таймауты** в прокси-слое. Таймаут всегда должен браться
+из конфигурации вызываемого ресурса. `Function.Spec.TimeoutSec` существует именно для этого.
+
+---
+
+## 2026-03-19 — Баг 5: nginx ingress proxy-read-timeout не задан → 504 Gateway Time-out
+
+### Симптом
+
+После фикса invoke.go (баг 4) — повторный вызов `stress-go-pgstorm` вернул:
+```html
+
504 Gateway Time-out
+504 Gateway Time-out
+
nginx
+```
+curl exit code 5 (не 0), процесс завершился через ~60 секунд после старта запроса.
+
+### Корневая причина
+
+У ingress `sless-operator` не было аннотации `proxy-read-timeout`.
+nginx ingress controller использует дефолт **60 секунд** если аннотация отсутствует.
+
+```yaml
+# Было — аннотаций timeout нет вообще:
+annotations:
+ kubernetes.io/ingress.class: nginx
+ nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
+ nginx.ingress.kubernetes.io/ssl-redirect: "true"
+```
+
+Цепочка: клиент → nginx (60s timeout) → оператор (705s) → функция (600s).
+Nginx оборвал соединение на 60-й секунде, хотя и оператор и функция были живы.
+
+### Диагностика
+
+Проверили аннотации всех ingress в ns sless:
+- `nodered` ingress: `proxy-read-timeout: "3600"` ✅ (кто-то правильно настроил)
+- `sless-funcs-ingress`: нет timeout аннотаций
+- `sless-operator`: нет timeout аннотаций ← **виновник**
+
+### Решение
+
+1. `kubectl annotate` для мгновенного применения:
+```bash
+kubectl annotate ingress sless-operator -n sless \
+ nginx.ingress.kubernetes.io/proxy-read-timeout="900" \
+ nginx.ingress.kubernetes.io/proxy-send-timeout="900" --overwrite
+```
+
+2. Сохранить в манифест `deployments/k8s/operator.yaml`:
+```yaml
+nginx.ingress.kubernetes.io/proxy-read-timeout: "900"
+nginx.ingress.kubernetes.io/proxy-send-timeout: "900"
+```
+
+### Почему 900s
+
+- function timeout_sec = 700 → оператор ждёт 705s
+- nginx должен ждать дольше чем оператор → 900s с запасом
+- Не ставим 3600s как у nodered — избыточно для функций
+
+### Файл
+
+`deployments/k8s/operator.yaml` — обновлено в коммите `d7fda15`
+
+### Урок
+
+При развёртывании нового ingress **всегда явно задавать** `proxy-read-timeout`
+и `proxy-send-timeout`. Nginx дефолт 60s подходит только для быстрых API.
+Для любых операций дольше 30s — обязательны явные таймауты.
diff --git a/doc/progress.md b/doc/progress.md
index d620f14..bb73cf3 100644
--- a/doc/progress.md
+++ b/doc/progress.md
@@ -1,45 +1,66 @@
# Прогресс разработки
-Последнее обновление: 2026-03-19 21:00
+Последнее обновление: 2026-03-19 22:30
---
-## 2026-03-19 — Go runtime v0.1.1: pgx/v5 + stress-go-pgstorm ⏳ В РАБОТЕ
+## 2026-03-19 — Go runtime v0.1.1: pgx/v5 + stress-go-pgstorm ✅ ЗАВЕРШЕНО
### Цель
-Новая функция `stress-go-pgstorm` — Go код со 100 горутинами, которые ~10 минут долбят
-PostgreSQL напрямую через `pgxpool`. Проверяем: Go runtime под нагрузкой, connection pool
-под конкурентными запросами, устойчивость кластера.
+Новая функция `stress-go-pgstorm` — Go код со 100 горутинами, которые 10 минут
+долбят PostgreSQL напрямую через `pgxpool`. Проверяем: Go runtime под нагрузкой,
+connection pool под конкурентными запросами, устойчивость кластера.
+
+**Попутно выявлены и исправлены два системных бага:**
+- Хардкодный таймаут 30s в invoke.go (прокси оператора)
+- Отсутствие proxy-read-timeout на nginx ingress sless-operator
### Задачи
| # | Задача | Статус | Заметки |
|---|--------|--------|---------|
| 1 | `runtimes/go1.23/go.mod` — добавить `pgx/v5 v5.7.2` | ✅ | go mod tidy на remote, go.sum сгенерирован (28 строк) |
-| 2 | `runtimes/go1.23/go.sum` — создан | ✅ | Все indirect deps: pgpassfile, pgservicefile, puddle/v2, crypto, sync, text |
-| 3 | `runtimes/go1.23/Dockerfile` — добавить `go mod download` | ⏳ | |
-| 4 | Собрать `naeel/sless-runtime-go1.23:v0.1.1`, запушить | ⏳ | |
-| 5 | `internal/builder/context.go` — обновить тег `go1.23` → v0.1.1 | ⏳ | |
-| 6 | Пересобрать оператор `v0.1.39`, задеплоить | ⏳ | |
-| 7 | `code/stress-go-pgstorm/handler.go` — горутины + pgxpool | ⏳ | |
-| 8 | `resources.tf` — новая функция + trigger | ⏳ | |
-| 9 | `terraform apply`, тест | ⏳ | |
-| 10 | Коммит | ⏳ | |
+| 2 | `runtimes/go1.23/Dockerfile` — `go mod download` кешируем deps | ✅ | Один stage `golang:1.23-alpine`, COPY go.mod+go.sum перед server.go |
+| 3 | Собрать `naeel/sless-runtime-go1.23:v0.1.1`, запушить | ✅ | docker build + push, sha256 verified |
+| 4 | `internal/builder/context.go` — тег `go1.23` v0.1.0 → v0.1.1 | ✅ | строка `return "naeel/sless-runtime-go1.23:v0.1.1", nil` |
+| 5 | `internal/api/handler/invoke.go` — динамический таймаут | ✅ | Таймаут = Function.Spec.TimeoutSec + 5s (был хардкод 30s) |
+| 6 | Пересобрать и задеплоить оператор `v0.1.40` | ✅ | rodlout complete |
+| 7 | `deployments/k8s/operator.yaml` — nginx proxy-read-timeout=900s | ✅ | kubectl annotate + манифест обновлён |
+| 8 | `code/stress-go-pgstorm/handler.go` — горутины + pgxpool | ✅ | 100 горутин, INSERT/COUNT/MAX, параметры workers/duration_sec/max_delay_ms |
+| 9 | `resources.tf` — новая функция + trigger | ✅ | timeout_sec=700, memory_mb=256, все PG env vars |
+| 10 | terraform apply — 2 ресурса добавлено | ✅ | apply complete: 2 added |
+| 11 | Запуск 10-минутного стресс-теста | ⏳ | Идёт прямо сейчас: workers=100, duration_sec=600, max_delay_ms=300 |
+| 12 | Коммит d7fda15 | ✅ | feat: Go runtime v0.1.1 (pgx/v5)... |
### Архитектура функции stress-go-pgstorm
```
Handle(event) → запускает N горутин (default 100)
каждая горутина в цикле duration_sec (default 600):
- - случайная задержка 0-500ms
+ - случайная задержка 0-300ms (max_delay_ms)
- чередующиеся операции: INSERT / SELECT COUNT / SELECT MAX
- - логирует ошибки, считает ok/err
- финал → {workers, duration_sec, total_ops, ok_ops, err_ops, ops_per_sec}
+ - считает ok/err атомарно через sync/atomic
+ WaitGroup.Wait() → возвращает итог
+ возвращает: {runtime, version, workers, duration_sec, elapsed_sec,
+ total_ops, ok_ops, err_ops, ops_per_sec}
+
pgxpool.New() — connection pool, MaxConns=20
env: PGHOST, PGPORT, PGDATABASE, PGUSER, PGPASSWORD, PGSSLMODE
```
----
+### Цепочка таймаутов (после фиксов)
+
+| Слой | Таймаут | Где задаётся |
+|------|---------|--------------|
+| curl --max-time | 720s | клиент |
+| nginx ingress proxy-read-timeout | 900s | аннотация ingress sless-operator |
+| operator http.Client (invoke.go) | TimeoutSec+5s = 705s | Function.Spec.TimeoutSec=700 |
+| function runtime (Go) | duration_sec = 600s | параметр в JSON body |
+
+### Что было сломано до этой сессии
+
+1. invoke.go: `var httpClient = &http.Client{Timeout: 30 * time.Second}` — хардкод в строке 24
+2. nginx ingress sless-operator: аннотации proxy-read-timeout не было → nginx дефолт 60s → 504
## 2026-03-19 — Tests 3-7: E2E прогон POSTGRES + 8 стресс-функций