Skip to content

Speed up controller Docker rebuilds#344

Merged
skulidropek merged 12 commits into
mainfrom
issue-339
May 23, 2026
Merged

Speed up controller Docker rebuilds#344
skulidropek merged 12 commits into
mainfrom
issue-339

Conversation

@skulidropek
Copy link
Copy Markdown
Member

Summary

  • Split the controller Dockerfile so Skiller/Electron artifacts are cached independently from API source rebuilds.
  • Added controller image revision inspection so browser bootstrap skips docker compose --build when the current image already matches the local revision.
  • Tightened Docker build context and controller revision hashing around generated outputs.

Local measurements

  • API source-only rebuild: 201s before, 5s after.
  • Revision-only rebuild: 3s.
  • Clean cached rebuild after probe removal: 1s.

Verification

  • docker compose -f docker-compose.yml config --quiet
  • docker compose -f docker-compose.api.yml config --quiet
  • docker run --rm --entrypoint bash app-api:latest -lc 'test -f packages/api/dist/src/main.js && test -f third_party/skiller-desktop-skills-manager/out/main/index.js && test -x third_party/skiller-desktop-skills-manager/node_modules/electron/dist/electron && test -f scripts/skiller-apply-docker-git-patches.mjs'\n- rtk bun run --cwd packages/app typecheck\n- rtk bun run --cwd packages/app lint\n- rtk bun run --cwd packages/app test\n- git diff --check\n\nFollow-up to Fix app lint failures and terminal copy regression #342.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c691a978-067c-4371-8741-b48e9f9952c1

📥 Commits

Reviewing files that changed from the base of the PR and between c7ef800 and ed22024.

📒 Files selected for processing (1)
  • packages/app/src/docker-git/browser-frontend.ts
📜 Recent review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/docker-git/browser-frontend.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/docker-git/browser-frontend.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/docker-git/browser-frontend.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/docker-git/browser-frontend.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/docker-git/browser-frontend.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/src/docker-git/browser-frontend.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/docker-git/browser-frontend.ts
🧠 Learnings (1)
📚 Learning: 2026-05-22T21:08:18.083Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In this repo’s docker-git controller compose generation, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` should be treated as standard bash parameter expansion: when `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` is unset, it defaults to the string "1". There is no "-1" mode. The runtime contract enforced by `packages/app/src/docker-git/controller-compose.ts` is: unset / "1" / "true" => output "1"; "0" / "false" => output "0". If review code shows branching/behavior for "-1" or any numeric value other than this 0/1 contract, flag it. Also ensure the Dockerfile ARG `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` stays consistent with default `1`.

Applied to files:

  • packages/app/src/docker-git/browser-frontend.ts
🔇 Additional comments (1)
packages/app/src/docker-git/browser-frontend.ts (1)

178-178: LGTM!


📝 Walkthrough

Summary by CodeRabbit

  • Chores

    • Расширены правила .dockerignore; добавлены/обновлены compose/CI переменные; улучшена логика сборки Docker и передачи ревизий; оптимизирован повторный reuse workspace для e2e; улучшена очистка диска в CI; обновлён запуск браузерного контроллера и npm-скрипты для ускоренной сборки.
  • New Features

    • Режим «build skiller» для ревизий контроллера; чтение/сравнение ревизий образа; новая утилита запуска команд с захватом вывода при ошибках; более устойчивый выбор API URL для браузерного фронтенда.
  • Tests

    • Добавлены property- и интеграционные тесты для ревизий, парсинга меток, аргументов запуска, выбора API и create-flow; обновлены e2e тесты.
  • Bug Fixes

    • Исправлена навигация create-flow, fallback выбора терминальной сессии и утилизация ресурсов; улучшены fallback‑механизмы при инспекции образов.

Walkthrough

PR добавляет режим Skiller и оптимизации сборки/CI, рефакторит чтение image-ревизий через docker compose, вводит правила для решения о пересборке контроллера, правит create-flow path-утилиты и добавляет E2E reuse-пути и улучшения CI.

Changes

Контроллер, ревизии, Skiller и create-flow

Layer / File(s) Summary
Docker ignore и compose конфигурация
.dockerignore, docker-compose.api.yml, docker-compose.yml, packages/app/package.json
Расширены игнор-паттерны, добавлены DOCKER_GIT_CONTROLLER_REV и DOCKER_GIT_CONTROLLER_BUILD_SKILLER в compose/build args; добавлены npm-скрипты для reuse-сборки.
Многостадийная сборка Dockerfile с workspace и Skiller
packages/api/Dockerfile
Введены workspace-deps/workspace-static для кеширования зависимостей и статичных сборок; skiller-build выделен как условная сборка (реальная сборка или генерация заглушек); финальный stage экспортирует флаги/ревизии.
Инспекция имени и ревизии образа
packages/app/src/docker-git/controller-image-revision.ts
Добавлены парсеры вывода docker compose config --images, выбор единственного имени образа и безопасная инспекция label ревизии (io.prover-coder-ai.docker-git.controller-rev) с дифференцированной обработкой ошибок отсутствия образа.
Входы ревизии и парсер метки
packages/app/src/docker-git/controller-revision.ts
docker-compose.api.yml добавлен в tracked inputs; расширены skipped-паттерны директорий/файлов; добавлен parseControllerRevisionLabelOutput (trim + <no value> → null).
Режим сборки Skiller: переменная и парсер
packages/app/src/docker-git/controller-compose.ts, packages/app/src/docker-git/controller-docker.ts
Добавлен controllerBuildSkillerEnvKey, тип ControllerBuildSkillerMode, parseControllerBuildSkillerMode, loader режима; buildSkillerMode включается в controllerRevisionForMode; реэкспорт обновлён.
План compose up и определение необходимости сборки
packages/app/src/docker-git/controller-bootstrap-plan.ts
Добавлены типы ControllerComposeUpPlan/ControllerImageBuildInput; resolveControllerComposeUpArgs() формирует up -d и опционально --build/--force-recreate; shouldBuildControllerImage() решает о rebuild по ревизиям и force-флагу.
Bootstrap контроллера и запуск через compose
packages/app/src/docker-git/controller.ts
Контекст bootstrap расширен currentImageRevision и buildController; loadControllerBootstrapContext инспектирует image-ревизию; запуск использует resolveControllerComposeUpArgs и логирует режим старта (Rebuilding/Recreating).
Тесты контроллера и property-тесты ревизий
packages/app/tests/docker-git/*
Добавлены/обновлены тесты для parseControllerRevisionLabelOutput, shouldBuildControllerImage, resolveControllerComposeUpArgs, parseControllerBuildSkillerMode и property-based тесты computeRevisionFromInputs с in-memory FS; docker-инспекция тестируется с фейковым CommandExecutor.
Утилиты нормализации и разрешения инпутов create-flow
packages/app/src/docker-git/menu-create-inputs.ts
TSDoc и изменения joinPath (удаление пустых сегментов, сохранение /), trimLeftSlash/trimRightSlash, normalizeCreateFlowContext, resolveDefaultOutDir, resolveCreateInputs документированы.
Логика advance/apply create-flow
packages/app/src/docker-git/menu-create-advance.ts
Изменено вычисление nextStep для non-repoUrl шагов (не инкрементировать); обновлены комментарии/инварианты.
Уточнения Web UI компонентов
packages/app/src/web/*, packages/api/src/services/terminal-sessions.ts
Fallback активной сессии на первую, helper для selectedProjectKey, вызов dispose через runOptionalTerminalOperation, уточнение комментария tmux-предиката.

E2E оптимизации: workspace install reuse и диск

Layer / File(s) Summary
GitHub Action: проверка и освобождение диска
.github/actions/free-docker-disk/action.yml
Action получил set -euo pipefail, чтение/валидация порога GiB и DOCKER_GIT_FORCE_FREE_DOCKER_DISK, вычисление доступного места в KiB, ранний exit при достаточном свободном месте и безопасную диагностику docker с timeout 20s.
E2E workflow: переменные окружения для jobs
.github/workflows/check.yml
В e2e job’ы добавлены DOCKER_GIT_CONTROLLER_BUILD_SKILLER=0 и DOCKER_GIT_E2E_REUSE_WORKSPACE_INSTALL=1.
Хелперы e2e скриптов: truthy, длительность, готовность и reuse
scripts/e2e/_lib.sh
Добавлены dg_is_truthy(), dg_log_duration(), dg_workspace_install_ready(); dg_prepare_bun_workspace и dg_build_docker_git_cli получили fast-path reuse при флаге; dg_prepare_docker_git_cli логирует общую длительность.
Скрипт browser-command: условный запуск по reuse флагу
scripts/e2e/browser-command.sh
Добавлена ветка по DOCKER_GIT_E2E_REUSE_WORKSPACE_INSTALL для запуска либо собранного dist-артефакта, либо bun run docker-git, оба варианта запускаются через setsid с логированием.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-339

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 0be7a69
Status: success
Files: 14 (18.79 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/app/src/docker-git/controller.ts (1)

319-320: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Пересчитайте buildController при принудительном рестарте.

На Line 320 вы форсируете только forceRecreateController, но оставляете старое значение buildController, вычисленное для forceRecreateController: false. В результате restartController может сделать --force-recreate без --build и поднять устаревший образ.

Предлагаемый фикс
 export const restartController = (): Effect.Effect<void, ControllerBootstrapError, ControllerRuntime> =>
   Effect.gen(function*(_) {
@@
     const bootstrapContext = yield* _(loadControllerBootstrapContext())
-    yield* _(startAndRememberController({ ...bootstrapContext, forceRecreateController: true }))
+    const forceRecreateController = true
+    const buildController = shouldBuildControllerImage({
+      currentControllerRevision: bootstrapContext.currentControllerRevision,
+      currentImageRevision: bootstrapContext.currentImageRevision,
+      forceRecreateController,
+      localControllerRevision: bootstrapContext.localControllerRevision
+    })
+    yield* _(startAndRememberController({ ...bootstrapContext, forceRecreateController, buildController }))
   })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/controller.ts` around lines 319 - 320, The
bootstrapContext's buildController flag is computed for forceRecreateController:
false and isn't updated when you call startAndRememberController with
forceRecreateController: true, so restart may run with --force-recreate but
without --build; to fix, recompute or reload the bootstrap context with
forceRecreateController: true (i.e. call loadControllerBootstrapContext or
otherwise recalc the buildController decision) before calling
startAndRememberController so that the buildController value in the object
passed to startAndRememberController matches forceRecreateController: true
(update the code around loadControllerBootstrapContext, bootstrapContext, and
the startAndRememberController call).
packages/app/src/web/panel-project-details.tsx (1)

139-162: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Добавьте fallback на project.projectKey для загрузки live-сессий.

Сейчас ключ берётся только из selectedProjectSummary; при временном undefined блок live-сессий остаётся пустым, даже когда project уже доступен в панели.

💡 Предлагаемый фикс
-  const selectedProjectKey = selectedProjectSummary?.projectKey ?? null
+  const selectedProjectKey = selectedProjectSummary?.projectKey ?? project?.projectKey ?? null
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/web/panel-project-details.tsx` around lines 139 - 162, The
live-sessions key is only taken from selectedProjectSummary (selectedProjectKey)
so when that summary is temporarily undefined the
ProjectTerminalSessionsForProject receives null and shows nothing even if
project is available; change the computation of selectedProjectKey to fall back
to project.projectKey (use selectedProjectSummary?.projectKey ??
project?.projectKey ?? null) and pass that to the
ProjectTerminalSessionsForProject prop so live sessions load when project is
present.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/api/src/services/terminal-sessions.ts`:
- Around line 768-791: The WHY comment is misleading:
tmuxRightClickForwardPredicate actually returns false in copy/view mode when
mouse_any_flag is absent (since it evaluates pane_in_mode AND 0), so right-click
events are not forwarded in that case; update the WHY text above the constant
tmuxRightClickForwardPredicate to clearly state that mouse-aware apps receive
events when mouse_any_flag is set, but in copy/view mode events are suppressed
unless mouse_any_flag is present (or otherwise clarify the intended behavior if
the predicate should be changed instead).

In `@packages/app/src/docker-git/menu-create-advance.ts`:
- Around line 260-267: The function resolveNextCreateFlowStep incorrectly
returns currentStepIndex + 1 for non-"repoUrl" steps even though the applied
step is removed from the nextSteps list, causing the flow to skip the next
entry; change the logic to compute the next index relative to the
filtered/active nextSteps instead of blindly adding one — e.g., find the
position of currentStep within the current nextSteps array (or compute the next
index as the same index after removal) and return that index (use the CreateStep
type and firstCreateSettingsStepIndex as before); apply the same fix to the
other similar block handling nextSteps (the code around
resolveNextCreateFlowStep usage referenced in the comment).

In `@packages/app/src/docker-git/menu-create-inputs.ts`:
- Around line 34-40: The TSDoc for the function that "Normalizes legacy cwd
input into the create-flow context record" and the other functions in this
module are missing required contract tags; update each function's TSDoc
(including the cwd-normalizer, the two functions around lines 58–69, the block
at 87–93, and the block at 104–125) to include `@param` for every argument,
`@returns` describing the return shape, `@pure` true, `@effect` listing external deps,
a mathematical `@invariant` mapping (e.g., "string input maps to { cwd: input }"),
`@precondition` and `@postcondition` describing required input state and guaranteed
output state, `@throws` Never when the function never throws, and `@complexity` with
the proper O-notation; keep the existing short description and ensure tags names
and formats match the repository standard.
- Around line 22-32: The joinPath function drops a root "/" because parts of
length 1 equal to "/" are filtered out and become empty, making absolute paths
relative; update joinPath (and its filtering logic) so it preserves a standalone
"/" as the leading part: change the filter to not remove "/" (e.g., allow part
=== "/"), and in the mapping for index === 0 explicitly detect part === "/" and
return "/" unmodified (otherwise use trimRightSlash(part)); keep existing
trimLeftSlash/trimRightSlash usage for non-root parts so other segments are
normalized.

In `@packages/app/src/web/app-ready-terminal-tabs.tsx`:
- Around line 40-43: Фикс: текущий fallback для выбора активной сессии
использует sessions.at(-1) (последняя сессия), а UI ожидает fallback на первую
сессию, поэтому при невалидном activeSessionId кнопка "+ New" открывает терминал
для неправильного проекта; замените fallback в выражении, где вычисляется active
(используется sessions.find, terminalSessionId и activeSessionId), чтобы вместо
sessions.at(-1) использовать первую сессию (например sessions[0] или аналогичный
доступ к первому элементу), и убедитесь, что возвращаемый объект по-прежнему
берёт projectId/projectKey из active (active.browserProjectId /
active.browserProjectKey).

In `@packages/app/src/web/terminal-panel-cleanup-runtime.ts`:
- Around line 26-28: В методе cleanupTerminalResources обёрнуть каждый вызов
disposable.dispose() из args.lifecycle.inlineImageDisposables в отдельный
try/catch, чтобы исключение в одном disposable не прерывало дальнейшую очистку
(socket/runtime/remove* и т.д.); в catch логировать ошибку (через существующий
логгер или console.error) и продолжать цикл, чтобы все disposable пытались
освободиться и оставшиеся шаги очистки всегда выполнялись.

---

Outside diff comments:
In `@packages/app/src/docker-git/controller.ts`:
- Around line 319-320: The bootstrapContext's buildController flag is computed
for forceRecreateController: false and isn't updated when you call
startAndRememberController with forceRecreateController: true, so restart may
run with --force-recreate but without --build; to fix, recompute or reload the
bootstrap context with forceRecreateController: true (i.e. call
loadControllerBootstrapContext or otherwise recalc the buildController decision)
before calling startAndRememberController so that the buildController value in
the object passed to startAndRememberController matches forceRecreateController:
true (update the code around loadControllerBootstrapContext, bootstrapContext,
and the startAndRememberController call).

In `@packages/app/src/web/panel-project-details.tsx`:
- Around line 139-162: The live-sessions key is only taken from
selectedProjectSummary (selectedProjectKey) so when that summary is temporarily
undefined the ProjectTerminalSessionsForProject receives null and shows nothing
even if project is available; change the computation of selectedProjectKey to
fall back to project.projectKey (use selectedProjectSummary?.projectKey ??
project?.projectKey ?? null) and pass that to the
ProjectTerminalSessionsForProject prop so live sessions load when project is
present.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c9aad1b0-a1e3-4e7e-b655-21dca75ca522

📥 Commits

Reviewing files that changed from the base of the PR and between 525ed8b and 0be7a69.

📒 Files selected for processing (63)
  • .dockerignore
  • docker-compose.api.yml
  • packages/api/Dockerfile
  • packages/api/src/services/terminal-sessions.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/app-ready-terminal-screen.tsx
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • scripts/e2e/browser-command.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (Browser command)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • scripts/e2e/browser-command.sh
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • scripts/e2e/browser-command.sh
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • scripts/e2e/browser-command.sh
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • docker-compose.api.yml
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/docker-git/menu-create-errors.ts
  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • scripts/e2e/browser-command.sh
  • packages/app/src/web/terminal-panel-optional-operation.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-command-parse.ts
  • packages/app/src/web/panel-content-types.ts
  • packages/app/src/web/panel-terminal-types.ts
  • packages/app/src/docker-git/menu-create-step-apply.ts
  • packages/app/src/web/app-ready-terminal-types.ts
  • packages/app/src/web/actions-project-menu-commands.ts
  • packages/app/src/web/app-ready-terminal-task-manager.tsx
  • packages/app/src/docker-git/menu-create-labels.ts
  • packages/app/src/web/app-ready-main-panel-labels.ts
  • packages/app/src/web/app-ready-ssh-link-terminal.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/src/docker-git/menu-create-draft.ts
  • packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts
  • docker-compose.api.yml
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/menu-create-steps.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/panel-content.tsx
  • packages/app/src/web/panel-terminal-header.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-flow-types.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/src/web/panel-content-renderers.tsx
  • packages/app/src/docker-git/menu-create-choices.ts
  • packages/app/src/web/app-ready-project-picker-screen.tsx
  • packages/app/src/web/panel-project-terminal-sessions.tsx
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/web/panel-terminal-mobile-controls.tsx
  • packages/app/src/web/app-ready-project-action-bar.tsx
  • packages/api/Dockerfile
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/panel-create-select.tsx
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-navigation.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-inline-images-runtime.ts
  • packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/web/terminal-copy-selection-drag.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/web/actions-projects.ts
  • packages/app/src/web/app-ready-ssh-link-core.ts
  • packages/app/src/web/panel-terminal-styles.ts
  • packages/app/src/web/app-ready-ssh-link-hook.ts
  • packages/app/src/web/app-ready-main-panels.tsx
  • packages/app/src/docker-git/menu-create-shared.ts
  • packages/app/src/web/panel-terminal.tsx
  • packages/app/src/web/app-ready-terminal-pane.tsx
  • packages/app/src/web/terminal-panel-runtime-core.ts
  • packages/app/src/web/terminal-copy-interaction.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
  • packages/app/src/web/actions-project-terminal.ts
  • packages/app/src/web/app-ready-terminal-screen.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts
  • packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts
  • packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts
  • packages/api/tests/terminal-sessions.test.ts
  • packages/app/tests/docker-git/terminal-copy-interaction.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/actions-projects.test.ts
**/{Dockerfile*,docker-compose*.{yml,yaml},.dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce unsafe Docker configuration such as privileged containers, broad host mounts, unbounded Docker socket access, or unnecessary write permissions

Files:

  • .dockerignore
  • docker-compose.api.yml
  • packages/api/Dockerfile
docker-compose*.yml

📄 CodeRabbit inference engine (README.md)

docker-compose*.yml: Per-project containers should ship with a default CPU limit of 30% and RAM limit of 30% (resolved against the host), overridable via --cpu / --ram flags or per-project docker-git.json
GPU mode should default to 'none' for non-GPU projects; GPU is enabled only explicitly via --gpu all or saved 'gpu': 'all' in docker-git.json

Files:

  • docker-compose.api.yml
docker-compose.api.yml

📄 CodeRabbit inference engine (README.md)

Controller container (docker-git-api) should be capped with default CPU/RAM at 90% of host resources with memory swap defaulting to twice the resolved RAM limit, overridable via CLI flags or environment variables

Files:

  • docker-compose.api.yml
packages/api/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

API layer should work only with LIB and serve as the intermediary between APP and LIB

Files:

  • packages/api/tests/terminal-sessions.test.ts
  • packages/api/src/services/terminal-sessions.ts
🧠 Learnings (1)
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.

Applied to files:

  • packages/api/src/services/terminal-sessions.ts
🪛 Checkov (3.2.529)
packages/api/Dockerfile

[low] 1-135: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-135: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Hadolint (2.14.0)
packages/api/Dockerfile

[info] 89-89: Multiple consecutive RUN instructions. Consider consolidation.

(DL3059)

🪛 Trivy (0.69.3)
packages/api/Dockerfile

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)


[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)

🔇 Additional comments (54)
packages/api/src/services/terminal-sessions.ts (3)

813-853: LGTM!

Also applies to: 878-907


931-934: LGTM!


1153-1153: LGTM!

packages/api/tests/terminal-sessions.test.ts (1)

257-306: LGTM!

.dockerignore (1)

2-18: LGTM!

docker-compose.api.yml (1)

7-12: LGTM!

packages/api/Dockerfile (1)

55-129: LGTM!

packages/app/src/docker-git/controller-image-revision.ts (1)

35-130: LGTM!

packages/app/src/docker-git/controller-revision.ts (1)

10-37: LGTM!

Also applies to: 118-145

packages/app/src/docker-git/controller-bootstrap-plan.ts (1)

1-76: LGTM!

packages/app/tests/docker-git/controller.test.ts (1)

116-122: LGTM!

Also applies to: 131-179, 195-219

scripts/e2e/browser-command.sh (1)

119-120: LGTM!

packages/app/src/web/terminal-copy-selection-drag.ts (1)

1-203: LGTM!

packages/app/tests/docker-git/fixtures/terminal-copy-interaction.ts (1)

24-25: LGTM!

Also applies to: 40-40, 54-54, 78-85, 89-94, 120-120, 147-163, 229-235, 285-286, 297-297

packages/app/tests/docker-git/terminal-copy-interaction.test.ts (1)

41-41: LGTM!

Also applies to: 217-218

packages/app/tests/docker-git/terminal-copy-right-click-interaction.test.ts (1)

1-230: LGTM!

packages/app/src/docker-git/menu-create-step-apply.ts (1)

10-15: LGTM!

Also applies to: 17-40, 42-53, 55-69, 71-102

packages/app/src/docker-git/menu-create-draft.ts (1)

4-28: LGTM!

packages/app/src/docker-git/menu-create-shared.ts (1)

1-30: LGTM!

packages/app/src/web/panel-create-select.tsx (1)

20-37: LGTM!

Also applies to: 100-123, 125-139, 140-176, 178-214

packages/app/src/web/panel-project-terminal-sessions.tsx (1)

10-20: LGTM!

Also applies to: 22-38, 40-59, 60-97, 99-138, 140-164, 166-221

packages/app/tests/docker-git/menu-create-shared.test.ts (1)

13-13: LGTM!

Also applies to: 92-105, 188-200, 258-277, 279-315

packages/app/src/web/app-ready-ssh-link-core.ts (1)

17-97: LGTM!

Also applies to: 123-157, 158-176, 204-267, 292-296, 322-335

packages/app/src/web/app-ready-ssh-link-hook.ts (1)

8-35: LGTM!

Also applies to: 66-140, 163-270, 272-337

packages/app/src/web/app-ready-ssh-link-terminal.ts (1)

31-63: LGTM!

Also applies to: 88-104, 130-143, 170-184

packages/app/src/web/actions-project-menu-commands.ts (1)

12-33: LGTM!

Also applies to: 34-98, 100-140

packages/app/src/web/actions-project-terminal.ts (1)

31-82: LGTM!

Also applies to: 94-149, 151-279, 307-323, 352-373

packages/app/src/web/actions-projects.ts (1)

4-28: LGTM!

Also applies to: 103-139

packages/app/src/web/app-ready-main-panel-labels.ts (1)

3-46: LGTM!

packages/app/src/web/app-ready-project-action-bar.tsx (1)

21-27: LGTM!

Also applies to: 34-125, 127-163

packages/app/src/web/app-ready-main-panels.tsx (1)

5-12: LGTM!

packages/app/src/web/app-ready-project-picker-screen.tsx (1)

1-222: LGTM!

packages/app/src/web/panel-content-types.ts (1)

1-37: LGTM!

packages/app/src/web/panel-content.tsx (1)

3-14: LGTM!

packages/app/tests/docker-git/actions-project-terminal-lifecycle.test.ts (1)

1-287: LGTM!

packages/app/tests/docker-git/actions-project-terminal-test-fixtures.ts (1)

1-54: LGTM!

packages/app/tests/docker-git/actions-projects.test.ts (1)

5-8: LGTM!

Also applies to: 22-23, 45-45

packages/app/tests/docker-git/app-ready-ssh-link-hook.test.ts (1)

63-66: LGTM!

packages/app/src/web/panel-terminal-header.tsx (1)

1-189: LGTM!

packages/app/src/web/panel-terminal-styles.ts (1)

1-219: LGTM!

packages/app/src/web/panel-terminal-types.ts (1)

1-22: LGTM!

packages/app/src/web/panel-content-renderers.tsx (1)

1-152: LGTM!

packages/app/src/web/panel-terminal-mobile-controls.tsx (1)

1-178: LGTM!

packages/app/src/web/panel-terminal.tsx (1)

3-310: LGTM!

packages/app/src/web/terminal-copy-interaction.ts (1)

1-242: LGTM!

packages/app/src/web/terminal-panel-cleanup-runtime.ts (1)

1-25: LGTM!

Also applies to: 29-43

packages/app/src/web/terminal-panel-inline-images-runtime.ts (1)

1-299: LGTM!

packages/app/src/web/terminal-panel-optional-operation.ts (1)

1-21: LGTM!

packages/app/src/web/terminal-panel-runtime-core.ts (1)

1-1: LGTM!

Also applies to: 5-7, 22-23, 99-103

packages/app/src/web/app-ready-terminal-screen.tsx (1)

1-2: LGTM!

Also applies to: 4-7, 22-24, 26-112, 122-134

packages/app/src/web/app-ready-terminal-pane.tsx (1)

1-238: LGTM!

packages/app/src/web/app-ready-terminal-task-manager.tsx (1)

1-69: LGTM!

packages/app/src/web/app-ready-terminal-types.ts (1)

1-63: LGTM!

packages/app/src/web/app-ready-terminal-tabs.tsx (1)

55-63: ⚡ Quick win

Доступность вкладок по клавиатуре: претензия не подтверждается — Box при onClick рендерит нативную кнопку.

TerminalTab и NewTerminalButton используют <Box onClick={...}>, а в packages/app/src/web/elements.tsx такой Box создаёт элемент <button type="button">, поэтому таб-навигация и активация Enter/Space по клавиатуре работают. Если нужна именно семантика “вкладок” (role tablist/tab и стрелочная навигация), это следует добавить отдельно.

			> Likely an incorrect or invalid review comment.

Comment thread packages/api/src/services/terminal-sessions.ts
Comment thread packages/app/src/docker-git/menu-create-advance.ts
Comment thread packages/app/src/docker-git/menu-create-inputs.ts
Comment thread packages/app/src/docker-git/menu-create-inputs.ts
Comment thread packages/app/src/web/app-ready-terminal-tabs.tsx Outdated
Comment thread packages/app/src/web/terminal-panel-cleanup-runtime.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: be0a9b4
Status: success
Files: 14 (19.54 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/api/Dockerfile (1)

137-157: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Финальный образ запускается от root-пользователя.

В controller-final нет USER, значит рантайм остаётся root. Для контроллера это повышает impact при компрометации процесса. Рекомендуется добавить непривилегированного пользователя в финальном слое и запускать CMD от него (с необходимой настройкой прав на рабочие директории/сокеты).

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/api/Dockerfile` around lines 137 - 157, The final image runs as root
because the controller-final stage lacks a USER; add a non‑root user (e.g.,
create a user/group and home) in the controller-final stage and switch to it
with USER before the CMD so the process launched by CMD
["bash","packages/api/scripts/start-controller.sh"] runs unprivileged; also
chown/chmod any required runtime paths (workspace/ directories, socket paths
like /var/run/docker.sock if the service must access Docker, and
packages/api/scripts/start-controller.sh) to that user so the controller has
necessary permissions at runtime.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/docker-git/controller-compose.ts`:
- Around line 34-40: The parser parseControllerBuildSkillerMode currently only
accepts "0"/"1"/"false"/"true" and returns null otherwise; update it to
explicitly accept the "-1" string (trimmed) and return "-1" so the compose
default is supported, and ensure any validator that calls
parseControllerBuildSkillerMode (and the function controllerRevisionForMode)
treat "-1" as a valid mode (or normalize "-1" to the intended normalized value
in one place before computing revisions/build args) to avoid
ControllerBootstrapError and revision drift; update all related usages
(including the validator logic referenced around the parse and
controllerRevisionForMode) to handle the "-1" branch consistently.

In `@packages/app/tests/docker-git/controller.test.ts`:
- Around line 211-235: The test currently uses the real NodeContext.layer
(FileSystem.FileSystem and Path.Path) making it integration-y; replace
NodeContext.layer with mocked Effect layers for FileSystem and Path that
implement the methods used (makeTempDirectoryScoped, makeDirectory,
writeFileString, join, etc.), drive the same scenario (create a temp rootDir,
create "src/tracked.ts", write ignored entries from
ignoredControllerRevisionEntries including the ".git" special case) using those
mocks, then call computeRevisionFromInputs(rootDir, ["src"]) before and after
and assert equality; keep references to computeRevisionFromInputs and
ignoredControllerRevisionEntries so the invariant check is unchanged and remove
any dependency on NodeContext.layer in the test.

---

Outside diff comments:
In `@packages/api/Dockerfile`:
- Around line 137-157: The final image runs as root because the controller-final
stage lacks a USER; add a non‑root user (e.g., create a user/group and home) in
the controller-final stage and switch to it with USER before the CMD so the
process launched by CMD ["bash","packages/api/scripts/start-controller.sh"] runs
unprivileged; also chown/chmod any required runtime paths (workspace/
directories, socket paths like /var/run/docker.sock if the service must access
Docker, and packages/api/scripts/start-controller.sh) to that user so the
controller has necessary permissions at runtime.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 73508010-5f56-46dd-bfb7-f9a7473e8ebc

📥 Commits

Reviewing files that changed from the base of the PR and between 0be7a69 and be0a9b4.

📒 Files selected for processing (12)
  • .dockerignore
  • .github/workflows/check.yml
  • docker-compose.api.yml
  • docker-compose.yml
  • packages/api/Dockerfile
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (13)
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • docker-compose.yml
  • docker-compose.api.yml
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/controller-compose.ts
**/{Dockerfile*,docker-compose*.{yml,yaml},.dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce unsafe Docker configuration such as privileged containers, broad host mounts, unbounded Docker socket access, or unnecessary write permissions

Files:

  • docker-compose.yml
  • docker-compose.api.yml
  • .dockerignore
  • packages/api/Dockerfile
docker-compose*.yml

📄 CodeRabbit inference engine (README.md)

docker-compose*.yml: Per-project containers should ship with a default CPU limit of 30% and RAM limit of 30% (resolved against the host), overridable via --cpu / --ram flags or per-project docker-git.json
GPU mode should default to 'none' for non-GPU projects; GPU is enabled only explicitly via --gpu all or saved 'gpu': 'all' in docker-git.json

Files:

  • docker-compose.yml
  • docker-compose.api.yml
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • docker-compose.yml
  • docker-compose.api.yml
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/api/Dockerfile
**/.github/workflows/*.{yml,yaml}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce unsafe GitHub Actions configuration such as unsafe pull_request_target, or unnecessary write permissions

Files:

  • .github/workflows/check.yml
docker-compose.api.yml

📄 CodeRabbit inference engine (README.md)

Controller container (docker-git-api) should be capped with default CPU/RAM at 90% of host resources with memory swap defaulting to twice the resolved RAM limit, overridable via CLI flags or environment variables

Files:

  • docker-compose.api.yml
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/controller-compose.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/controller-compose.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/controller-compose.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/controller-compose.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/controller-compose.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/controller.test.ts
🪛 Checkov (3.2.529)
packages/api/Dockerfile

[low] 1-157: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-157: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Hadolint (2.14.0)
packages/api/Dockerfile

[info] 89-89: Multiple consecutive RUN instructions. Consider consolidation.

(DL3059)


[warning] 105-105: Use WORKDIR to switch to a directory

(DL3003)

🪛 Trivy (0.69.3)
packages/api/Dockerfile

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)


[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)


[warning] 105-135: 'RUN cd ...' to change directory

RUN should not be used to change directory: 'if [ "$DOCKER_GIT_CONTROLLER_BUILD_SKILLER" = "1" ]; then test -f third_party/skiller-desktop-skills-manager/package.json && cd third_party/skiller-desktop-skills-manager && for attempt in 1 2 3 4 5; do if bun install --frozen-lockfile --silent; then break; fi; if [ "$attempt" = "5" ]; then echo "skiller bun install failed after retries" >&2; exit 1; fi; echo "skiller bun install attempt ${attempt} failed; retrying..." &gt;&amp;2; rm -rf /root/.bun/install/cache node_modules; sleep $((attempt * 2)); done && bun run build && touch out/.docker-git-browser-folder-picker.patch && mkdir -p out/preload && ln -sf index.mjs out/preload/index.js; else cd third_party/skiller-desktop-skills-manager && mkdir -p node_modules/electron/dist out/main out/renderer out/preload && printf '%s\n' '#!/usr/bin/env sh' 'echo "Skiller is not bundled in this controller image." >&2' 'exit 1' > node_modules/electron/dist/electron && chmod +x node_modules/electron/dist/electron && printf '%s\n' 'throw new Error("Skiller is not bundled in this controller image.")' > out/main/index.js && printf '%s\n' '<!doctype html><title>Skiller unavailable</title>' > out/renderer/index.html && printf '%s\n' 'export {}' > out/preload/index.mjs && touch out/.docker-git-browser-folder-picker.patch && ln -sf index.mjs out/preload/index.js; fi'. Use 'WORKDIR' statement instead.

Rule: DS-0013

Learn more

(IaC/Dockerfile)

🔇 Additional comments (10)
docker-compose.yml (1)

8-8: LGTM!

.github/workflows/check.yml (1)

156-157: LGTM!

Also applies to: 175-176, 194-195, 213-214, 232-233, 251-252

docker-compose.api.yml (1)

7-8: LGTM!

Also applies to: 13-13

packages/app/src/docker-git/controller-revision.ts (1)

10-10: LGTM!

Also applies to: 20-22, 25-36, 118-145

packages/app/src/docker-git/controller-bootstrap-plan.ts (1)

1-77: LGTM!

packages/app/src/docker-git/controller-docker.ts (1)

24-30: LGTM!

.dockerignore (1)

2-18: LGTM!

packages/app/src/docker-git/controller-image-revision.ts (1)

1-131: LGTM!

packages/app/src/docker-git/controller.ts (1)

3-3: LGTM!

Also applies to: 17-17, 147-149, 165-165, 169-183, 222-231, 238-243

packages/app/tests/docker-git/controller.test.ts (1)

120-125: LGTM!

Also applies to: 135-209

Comment on lines +34 to +40
export const parseControllerBuildSkillerMode = (raw?: string): ControllerBuildSkillerMode | null => {
const trimmed = raw?.trim() ?? ""
if (trimmed.length === 0 || trimmed === "1" || trimmed === "true") {
return "1"
}
return trimmed === "0" || trimmed === "false" ? "0" : null
}
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Режим -1 для DOCKER_GIT_CONTROLLER_BUILD_SKILLER не поддержан, хотя он заявлен как дефолт в compose-спеке.

Сейчас парсер и валидатор принимают только 0/1/false/true, а дефолт в controllerRevisionForMode"1". При значении -1 (из конфигурации compose по документации) получите ControllerBootstrapError и потенциальный рассинхрон ревизии с фактически собранным образом. Нужно явно поддержать -1 (или нормализовать его в одном месте до вычисления ревизии и build-аргументов).

As per coding guidelines, "**/*: ... Сверь изменения с исходным ТЗ/спекой ... Флагай любой уход от спеки, недокументированное изменение поведения ..."

Also applies to: 45-46, 61-72

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/controller-compose.ts` around lines 34 - 40, The
parser parseControllerBuildSkillerMode currently only accepts
"0"/"1"/"false"/"true" and returns null otherwise; update it to explicitly
accept the "-1" string (trimmed) and return "-1" so the compose default is
supported, and ensure any validator that calls parseControllerBuildSkillerMode
(and the function controllerRevisionForMode) treat "-1" as a valid mode (or
normalize "-1" to the intended normalized value in one place before computing
revisions/build args) to avoid ControllerBootstrapError and revision drift;
update all related usages (including the validator logic referenced around the
parse and controllerRevisionForMode) to handle the "-1" branch consistently.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I checked this against the current compose/Dockerfile defaults and did not change the parser. ${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1} is shell-style parameter expansion whose default value is 1, not a -1 mode. The Dockerfile also declares ARG DOCKER_GIT_CONTROLLER_BUILD_SKILLER=1, and the supported runtime contract remains unset/1/true or 0/false. Adding -1 would create a new undocumented mode rather than aligning with the current spec.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@skulidropek, вы правы — я неверно интерпретировал ${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1} как литеральное значение -1, тогда как это стандартный bash-синтаксис подстановки параметра с дефолтом "1". Парсер корректно покрывает весь заявленный контракт: unset/"1"/"true""1", "0"/"false""0". Замечание снимаю.


✏️ Learnings added
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In the docker-git project, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` in compose files is standard bash parameter expansion with default value `"1"` (not a literal "-1" mode). The supported runtime contract for `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` in `packages/app/src/docker-git/controller-compose.ts` is: unset/`"1"`/`"true"` → `"1"`, `"0"`/`"false"` → `"0"`. There is no `-1` mode. The Dockerfile also declares `ARG DOCKER_GIT_CONTROLLER_BUILD_SKILLER=1`.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@skulidropek
Copy link
Copy Markdown
Member Author

CI/CD check for e2e on be0a9b4 is green.

Measured e2e check durations:

  • E2E (Browser command): 3m55s (previous fresh run failed at 9m55s while still building Skiller; old green PR was ~4m32s)
  • E2E (OpenCode): 6m12s
  • E2E (Login context): 5m56s
  • E2E (Runtime volumes + SSH): 6m30s
  • E2E (Clone auto-open SSH): 6m15s
  • E2E (Local package CLI): 39s
  • E2E (Clone cache): 10m58s total; its Free Docker disk step alone took ~4m54s, while Clone cache reuse was ~5m17s.

The browser e2e path is fixed and faster now because CI sets DOCKER_GIT_CONTROLLER_BUILD_SKILLER=0, so controller images used by browser/runtime e2e skip the Skiller Electron build. Production/local default remains 1 and still bundles Skiller.

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 32748c9
Status: success
Files: 15 (24.68 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@scripts/e2e/_lib.sh`:
- Around line 158-165: The dg_workspace_install_ready function assumes a fixed
workspace layout and specific package-manager-installed binaries (checks in
dg_workspace_install_ready for $repo_root/node_modules and the .bin paths for
packages/app, packages/lib, packages/docker-git-session-sync); add an inline
comment above dg_workspace_install_ready that documents these structural
assumptions (which packages and binaries are expected and that changes in
package names, locations, or package manager could break the check), and modify
the function to emit diagnostic output when a check fails that prints which
specific path or binary was missing so callers can see why it returned false
(include the exact checked paths in the message).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 17406e25-3c76-415d-af27-5aa6b533eb4d

📥 Commits

Reviewing files that changed from the base of the PR and between be0a9b4 and 32748c9.

📒 Files selected for processing (5)
  • .github/actions/free-docker-disk/action.yml
  • .github/workflows/check.yml
  • packages/app/package.json
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/package.json
  • scripts/e2e/browser-command.sh
  • scripts/e2e/_lib.sh
**/{package*.json,requirements*.txt,setup.py,setup.cfg,Pipfile,Pipfile.lock,pyproject.toml,pom.xml,build.gradle,Gemfile,Gemfile.lock,go.mod,go.sum,composer.json,Cargo.toml,Cargo.lock}

📄 CodeRabbit inference engine (Custom checks)

Fail if dependency or package-manager changes materially increase supply-chain risk without justification

Files:

  • packages/app/package.json
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/package.json
  • scripts/e2e/browser-command.sh
  • scripts/e2e/_lib.sh
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • scripts/e2e/browser-command.sh
  • scripts/e2e/_lib.sh
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • scripts/e2e/browser-command.sh
  • scripts/e2e/_lib.sh
**/.github/workflows/*.{yml,yaml}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce unsafe GitHub Actions configuration such as unsafe pull_request_target, or unnecessary write permissions

Files:

  • .github/workflows/check.yml
🔇 Additional comments (12)
packages/app/package.json (1)

30-31: LGTM!

scripts/e2e/browser-command.sh (2)

119-119: LGTM!


143-147: LGTM!

.github/actions/free-docker-disk/action.yml (2)

10-53: LGTM!


32-33: ⚡ Quick win

Укрепить парсинг и защиту вокруг df перед вычислением available_kib

  • available_kib="$(df -Pk / | awk 'NR == 2 { print $4 }')" привязан к конкретной структуре вывода df (вторая строка и 4-й столбец); добавьте валидацию результата (непустое и числовое значение) и понятный fallback при несоответствии.
  • В этой среде df отсутствует (df: command not found), поэтому стоит добавить проверку наличия команды (command -v df) и обработку ошибки, чтобы экшен не падал неожиданно.
.github/workflows/check.yml (1)

156-158: LGTM!

Also applies to: 176-178, 196-198, 216-218, 236-238, 256-258

scripts/e2e/_lib.sh (6)

27-27: LGTM!


138-147: LGTM!


149-156: LGTM!


463-479: LGTM!


481-501: LGTM!


503-513: LGTM!

Comment thread scripts/e2e/_lib.sh
@skulidropek
Copy link
Copy Markdown
Member Author

CI/e2e optimization update for commit 32748c9:

Implemented the planned fast paths:

  • .github/actions/free-docker-disk now skips cleanup when / already has at least 40GiB free, with DOCKER_GIT_FORCE_FREE_DOCKER_DISK for forced cleanup.
  • Docker e2e jobs set DOCKER_GIT_E2E_REUSE_WORKSPACE_INSTALL=1 and reuse the workspace bun install from the setup step.
  • Docker e2e CLI prep now uses the new build:docker-git:reuse-install package script, so it avoids rerunning the root install while still building session-sync/lib/app dist.
  • Added timing logs around workspace install/build/prepare.

Verification:

  • Local: shell syntax checks, frozen install, rtk bun run --cwd packages/app typecheck, rtk bun run --cwd packages/app build:docker-git:reuse-install, git diff --check.
  • GitHub checks: all green, including CodeRabbit.
  • Log proof from CI: Free Docker disk skipped immediately (/ has at least 40GiB available), e2e: reusing existing Bun workspace install, docker-git CLI build completed in 5s.

Measured Check workflow delta vs previous green run (be0a9b4 -> 32748c9):

  • Browser command: 3m55s -> 2m37s (-1m18s)
  • OpenCode: 6m12s -> 5m31s (-41s)
  • Runtime volumes + SSH: 6m30s -> 5m51s (-39s)
  • Clone auto-open SSH: 6m15s -> 5m53s (-22s)
  • Login context: 5m56s -> 5m44s (-12s)
  • Clone cache: 10m58s -> 11m07s (+9s total; scenario runtime dominates, but CLI prep still uses the 5s fast path)

This keeps Local package CLI unchanged by design, so local-package coverage still exercises the normal package script path.

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: c8e9714
Status: success
Files: 17 (26.93 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

Addressed the valid CodeRabbit findings in c8e9714:

  • fixed create-flow advancement so applying cpuLimit continues to ramLimit instead of skipping a remaining step;
  • preserved root / in create-flow outDir joining and expanded the required TSDoc contracts;
  • aligned terminal + New fallback with the active terminal fallback;
  • made terminal inline-image disposable cleanup best-effort so one throwing disposable does not abort socket/runtime cleanup;
  • recomputed controller buildController when restartController() forces recreation;
  • added the live-session projectKey fallback from loaded project details;
  • replaced the controller revision generated-path test with mocked FileSystem plus Path.layer;
  • documented and diagnosed the e2e workspace install reuse assumptions;
  • hardened free-docker-disk df parsing;
  • clarified the tmux right-click predicate comment.

Validated locally:

  • bash -n scripts/e2e/_lib.sh
  • git diff --check
  • free-docker-disk fast path and invalid-threshold path
  • rtk bun --cwd packages/app vitest run tests/docker-git/menu-create-shared.test.ts tests/docker-git/controller.test.ts tests/docker-git/terminal-panel-runtime-core.test.ts
  • rtk bun run --cwd packages/app typecheck
  • rtk bun run --cwd packages/app lint
  • rtk bun run --cwd packages/app test
  • rtk bun run --cwd packages/api typecheck
  • rtk bun run --cwd packages/api lint
  • rtk bun run --cwd packages/api test

Two comments were intentionally not converted into code changes:

  • DOCKER_GIT_CONTROLLER_BUILD_SKILLER=-1: ${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1} means default value 1, not a -1 mode; I replied inline.
  • Final API image non-root user: current controller-final starts managed dockerd in isolated/privileged mode and writes /var/lib/docker, /var/run/docker.sock, and /var/log/docker-git. A simple USER switch would likely break controller e2e. This should be a separate rootless/split-runtime design task, not a small review fix.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/tests/docker-git/controller.test.ts`:
- Around line 276-301: Replace the fixed example check in the test
it.effect("ignores generated paths when computing controller revisions") with a
property-based test using fast-check: use fc.property to generate random
tracked.ts content (e.g., fc.string()) and randomized choices/subsets of
ignoredControllerRevisionEntries (and optional generated file contents), then
inside the property body create the memory fs, write tracked.ts with the
generated content, compute before = computeRevisionFromInputs(rootDir, ["src"]),
apply only the generated/ignored entries (creating directories/files as in the
diff) and compute after = computeRevisionFromInputs(rootDir, ["src"]) and assert
expect(after).toBe(before); keep references to computeRevisionFromInputs and
ignoredControllerRevisionEntries so the test semantics remain identical but now
validated over many random cases.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 0e36bb6b-3210-48a3-a96a-79f24cf7b855

📥 Commits

Reviewing files that changed from the base of the PR and between 32748c9 and c8e9714.

📒 Files selected for processing (11)
  • .github/actions/free-docker-disk/action.yml
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • scripts/e2e/_lib.sh
📜 Review details
🧰 Additional context used
📓 Path-based instructions (10)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/controller.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/tests/docker-git/controller.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/controller.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/tests/docker-git/controller.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/controller.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • scripts/e2e/_lib.sh
  • packages/app/tests/docker-git/controller.test.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/controller.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • scripts/e2e/_lib.sh
  • packages/app/tests/docker-git/controller.test.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/controller.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • scripts/e2e/_lib.sh
  • packages/app/tests/docker-git/controller.test.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/tests/docker-git/controller.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/src/docker-git/controller.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • scripts/e2e/_lib.sh
  • packages/app/tests/docker-git/controller.test.ts
packages/api/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

API layer should work only with LIB and serve as the intermediary between APP and LIB

Files:

  • packages/api/src/services/terminal-sessions.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/tests/docker-git/controller.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/tests/docker-git/controller.test.ts
🧠 Learnings (2)
📚 Learning: 2026-05-22T21:08:18.083Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In this repo’s docker-git controller compose generation, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` should be treated as standard bash parameter expansion: when `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` is unset, it defaults to the string "1". There is no "-1" mode. The runtime contract enforced by `packages/app/src/docker-git/controller-compose.ts` is: unset / "1" / "true" => output "1"; "0" / "false" => output "0". If review code shows branching/behavior for "-1" or any numeric value other than this 0/1 contract, flag it. Also ensure the Dockerfile ARG `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` stays consistent with default `1`.

Applied to files:

  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/docker-git/menu-create-advance.ts
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.

Applied to files:

  • packages/api/src/services/terminal-sessions.ts
🔇 Additional comments (11)
.github/actions/free-docker-disk/action.yml (1)

12-16: LGTM!

Also applies to: 36-44, 64-67

packages/app/src/web/terminal-panel-cleanup-runtime.ts (1)

26-31: LGTM!

packages/app/src/docker-git/controller.ts (1)

319-327: LGTM!

packages/api/src/services/terminal-sessions.ts (1)

768-777: LGTM!

packages/app/src/web/app-ready-terminal-tabs.tsx (1)

36-43: LGTM!

packages/app/tests/docker-git/menu-create-shared.test.ts (1)

153-163: LGTM!

Also applies to: 200-212

packages/app/src/web/panel-project-details.tsx (1)

127-145: LGTM!

packages/app/src/docker-git/menu-create-inputs.ts (1)

6-19: LGTM!

Also applies to: 28-40, 50-82, 88-98, 116-149, 170-213

packages/app/src/docker-git/menu-create-advance.ts (1)

260-267: LGTM!

Also applies to: 280-289

scripts/e2e/_lib.sh (1)

158-185: LGTM!

packages/app/tests/docker-git/controller.test.ts (1)

4-4: LGTM!

Also applies to: 38-102

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: aee90d7
Status: success
Files: 20 (28.42 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/app/tests/docker-git/controller.test.ts (1)

24-25: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте TSDoc документацию к вспомогательным функциям

Функции joinIp и makeHttpUrl не имеют TSDoc документации, что нарушает требования coding guidelines для TypeScript функций.

📝 Предлагаемая документация
+/**
+ * Joins IP octets into a dotted-quad string.
+ * `@param` octets - The four IP address octets
+ * `@returns` Dotted-quad IP address string (e.g., "127.0.0.1")
+ * `@pure` true
+ * `@complexity` O(n) time where n = octets.length
+ */
 const joinIp = (...octets: ReadonlyArray<string>): string => octets.join(".")
+
+/**
+ * Constructs an HTTP URL from host and port.
+ * `@param` host - The hostname or IP address
+ * `@param` port - The port number as string
+ * `@returns` HTTP URL string (e.g., "http://localhost:3334")
+ * `@pure` true
+ * `@complexity` O(1) time
+ */
 const makeHttpUrl = (host: string, port: string): string => ["ht", "tp://", host, ":", port].join("")

Как указано в coding guidelines: "TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/tests/docker-git/controller.test.ts` around lines 24 - 25, Add
comprehensive TSDoc comments to the helper functions joinIp and makeHttpUrl:
document each parameter and return type, mark the function as `@pure`, list any
`@effect` dependencies (none for these pure helpers), include an `@invariant`
describing the mathematical property (e.g., joinIp produces a dotted-quad
string), state `@precondition` (e.g., octets contains only decimal 0-255 strings;
host/port are non-empty), state `@postcondition` (e.g., resulting string is a
valid HTTP URL or IP dotted-quad), and add a `@complexity` annotation (O(n) where
n is number of octets or length of input); keep descriptions concise and match
coding guidelines for TypeScript TSDoc.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/tests/docker-git/controller.test.ts`:
- Around line 287-322: The test only verifies that ignored/generated paths do
not change the controller revision but lacks the positive invariant that changes
to tracked files must change the revision; add a second property-based assertion
(or extend the existing fc.asyncProperty) that generates two different
trackedContents values and asserts computeRevisionFromInputs(rootDir, ["src"])
returns different revisions when tracked.ts is written with trackedContentsA vs
trackedContentsB, using the same Effect-based setup (FileSystem.FileSystem,
Path.Path, createMemoryFileSystemLayer, and calls to computeRevisionFromInputs)
and ensuring trackedContentsA !== trackedContentsB before asserting the
revisions differ.
- Line 112: The test currently calls fc.assert(property, { numRuns: 25 }) which
sets numRuns far below fast-check's default and reduces confidence in the
invariant; either increase numRuns to a higher value (e.g., 50–100) in the
fc.assert call to improve coverage, or if 25 is a deliberate CI performance
tradeoff, add an inline comment next to the fc.assert call explaining why
numRuns is limited; reference the fc.assert invocation and the numRuns option in
your change.
- Around line 305-312: The test treats ".git" as a file while other
ignoredEntries are created as directories; either make ".git" a directory to
match real repo semantics by using fs.makeDirectory(path.join(sourceDir,
".git"), { recursive: true }) and placing generatedContents into a generated.txt
inside it (matching the existing branch that calls fs.makeDirectory and
fs.writeFileString), or if the file-case is an intentional edge-case, add a
clarifying comment above the conditional explaining that the test intentionally
exercises ignoring ".git" when it is a file; update the block that references
ignoredEntries, sourceDir, generatedContents, fs.writeFileString and
fs.makeDirectory accordingly.
- Around line 109-113: Update the function assertControllerRevisionProperty to
include full TSDoc and rename the generic parameter from Ts to a clearer name
like PropertyArgs: add a doc summary, `@param` describing the property param
(fc.IAsyncProperty<PropertyArgs>), `@returns` describing the Effect promise return
type, add `@pure`, an `@effect` listing dependencies (e.g., Effect.tryPromise,
fc.assert), `@invariant` (mathematical invariant), `@precondition`, `@postcondition`,
and `@complexity` (Big-O) entries per coding guidelines; also update the generic
declaration and all usages inside the function signature from <Ts> to
<PropertyArgs> to keep names consistent.

---

Outside diff comments:
In `@packages/app/tests/docker-git/controller.test.ts`:
- Around line 24-25: Add comprehensive TSDoc comments to the helper functions
joinIp and makeHttpUrl: document each parameter and return type, mark the
function as `@pure`, list any `@effect` dependencies (none for these pure helpers),
include an `@invariant` describing the mathematical property (e.g., joinIp
produces a dotted-quad string), state `@precondition` (e.g., octets contains only
decimal 0-255 strings; host/port are non-empty), state `@postcondition` (e.g.,
resulting string is a valid HTTP URL or IP dotted-quad), and add a `@complexity`
annotation (O(n) where n is number of octets or length of input); keep
descriptions concise and match coding guidelines for TypeScript TSDoc.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3f399b19-599f-4095-8dcb-b64d695a338e

📥 Commits

Reviewing files that changed from the base of the PR and between c8e9714 and aee90d7.

📒 Files selected for processing (1)
  • packages/app/tests/docker-git/controller.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/tests/docker-git/controller.test.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/tests/docker-git/controller.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/tests/docker-git/controller.test.ts

Comment on lines +109 to +113
const assertControllerRevisionProperty = <Ts>(property: fc.IAsyncProperty<Ts>) =>
Effect.tryPromise({
catch: (cause) => cause,
try: () => fc.assert(property, { numRuns: 25 })
})
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте TSDoc документацию и улучшите имя generic-параметра

Функция assertControllerRevisionProperty не имеет TSDoc документации, что нарушает требования coding guidelines. Согласно guidelines, все TypeScript-функции должны включать comprehensive TSDoc с параметрами, return types, @pure маркером, @effect зависимостями, @invariant, @precondition, @postcondition и @complexity.

Также generic-параметр <Ts> неясен — лучше использовать более описательное имя, например <PropertyArgs>.

📝 Предлагаемая документация
+/**
+ * Wraps a fast-check async property assertion in an Effect for integration with Effect-based tests.
+ * 
+ * `@param` property - The fast-check async property to assert
+ * `@returns` Effect that succeeds if the property holds across all test runs, fails otherwise
+ * 
+ * `@pure` false (runs property-based test executions)
+ * `@effect` None (self-contained test runner)
+ * `@complexity` O(n) time where n = numRuns (currently 25)
+ */
-const assertControllerRevisionProperty = <Ts>(property: fc.IAsyncProperty<Ts>) =>
+const assertControllerRevisionProperty = <PropertyArgs>(property: fc.IAsyncProperty<PropertyArgs>) =>
   Effect.tryPromise({
     catch: (cause) => cause,
     try: () => fc.assert(property, { numRuns: 25 })
   })

Как указано в coding guidelines: "TypeScript functions must include comprehensive TSDoc with parameters, return types, @pure marker, @effect dependencies, @invariant (mathematical), @precondition, @postcondition, and @complexity O-notation."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/tests/docker-git/controller.test.ts` around lines 109 - 113,
Update the function assertControllerRevisionProperty to include full TSDoc and
rename the generic parameter from Ts to a clearer name like PropertyArgs: add a
doc summary, `@param` describing the property param
(fc.IAsyncProperty<PropertyArgs>), `@returns` describing the Effect promise return
type, add `@pure`, an `@effect` listing dependencies (e.g., Effect.tryPromise,
fc.assert), `@invariant` (mathematical invariant), `@precondition`, `@postcondition`,
and `@complexity` (Big-O) entries per coding guidelines; also update the generic
declaration and all usages inside the function signature from <Ts> to
<PropertyArgs> to keep names consistent.

Comment thread packages/app/tests/docker-git/controller.test.ts Outdated
Comment on lines +287 to +322
it.effect("ignores generated paths when computing controller revisions", () =>
assertControllerRevisionProperty(
fc.asyncProperty(
revisionFileContentsArbitrary,
ignoredControllerRevisionEntrySubsetArbitrary,
revisionFileContentsArbitrary,
(trackedContents, ignoredEntries, generatedContents) =>
Effect.runPromise(
Effect.gen(function*(_) {
const fs = yield* _(FileSystem.FileSystem)
const path = yield* _(Path.Path)
const rootDir = "/memory"
const sourceDir = path.join(rootDir, "src")
yield* _(fs.makeDirectory(sourceDir, { recursive: true }))
yield* _(fs.writeFileString(path.join(sourceDir, "tracked.ts"), trackedContents))

const before = yield* _(computeRevisionFromInputs(rootDir, ["src"]))

for (const entry of ignoredEntries) {
if (entry === ".git") {
yield* _(fs.writeFileString(path.join(sourceDir, entry), generatedContents))
continue
}
yield* _(fs.makeDirectory(path.join(sourceDir, entry), { recursive: true }))
yield* _(fs.writeFileString(path.join(sourceDir, entry, "generated.txt"), generatedContents))
}

const after = yield* _(computeRevisionFromInputs(rootDir, ["src"]))
expect(after).toBe(before)
}).pipe(
Effect.provide(createMemoryFileSystemLayer()),
Effect.provide(Path.layer)
)
)
)
))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial | ⚡ Quick win

Дополните инвариант проверкой позитивного случая

Property-based тест проверяет только негативный инвариант: добавление игнорируемых файлов НЕ меняет revision. Однако отсутствует проверка позитивного инварианта: изменение tracked файлов ДОЛЖНО менять revision.

Без позитивной проверки тест может давать ложное ощущение безопасности — например, если computeRevisionFromInputs всегда возвращает константу, текущий тест пройдёт успешно.

Рекомендуется добавить второй property-based тест или расширить текущий для проверки:

∀ trackedContents₁ ≠ trackedContents₂: 
  computeRevisionFromInputs(tracked.ts = trackedContents₁) ≠ 
  computeRevisionFromInputs(tracked.ts = trackedContents₂)

Как указано в coding guidelines: "Property-based tests (fast-check) must verify mathematical invariants."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/tests/docker-git/controller.test.ts` around lines 287 - 322, The
test only verifies that ignored/generated paths do not change the controller
revision but lacks the positive invariant that changes to tracked files must
change the revision; add a second property-based assertion (or extend the
existing fc.asyncProperty) that generates two different trackedContents values
and asserts computeRevisionFromInputs(rootDir, ["src"]) returns different
revisions when tracked.ts is written with trackedContentsA vs trackedContentsB,
using the same Effect-based setup (FileSystem.FileSystem, Path.Path,
createMemoryFileSystemLayer, and calls to computeRevisionFromInputs) and
ensuring trackedContentsA !== trackedContentsB before asserting the revisions
differ.

Comment on lines +305 to +312
for (const entry of ignoredEntries) {
if (entry === ".git") {
yield* _(fs.writeFileString(path.join(sourceDir, entry), generatedContents))
continue
}
yield* _(fs.makeDirectory(path.join(sourceDir, entry), { recursive: true }))
yield* _(fs.writeFileString(path.join(sourceDir, entry, "generated.txt"), generatedContents))
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Уточните семантику обработки .git как файла

В тесте .git записывается как файл (строка 307), в то время как все остальные игнорируемые записи создаются как директории (строки 310-311). В реальных репозиториях .git всегда является директорией.

Если это намеренная проверка edge-case (игнорирование .git независимо от типа), рекомендуется добавить комментарий, объясняющий это решение. В противном случае рассмотрите создание .git как директории для согласованности с реальным поведением.

🔧 Предлагаемое исправление для согласованности
               for (const entry of ignoredEntries) {
-                if (entry === ".git") {
-                  yield* _(fs.writeFileString(path.join(sourceDir, entry), generatedContents))
-                  continue
-                }
                 yield* _(fs.makeDirectory(path.join(sourceDir, entry), { recursive: true }))
                 yield* _(fs.writeFileString(path.join(sourceDir, entry, "generated.txt"), generatedContents))
               }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/tests/docker-git/controller.test.ts` around lines 305 - 312, The
test treats ".git" as a file while other ignoredEntries are created as
directories; either make ".git" a directory to match real repo semantics by
using fs.makeDirectory(path.join(sourceDir, ".git"), { recursive: true }) and
placing generatedContents into a generated.txt inside it (matching the existing
branch that calls fs.makeDirectory and fs.writeFileString), or if the file-case
is an intentional edge-case, add a clarifying comment above the conditional
explaining that the test intentionally exercises ignoring ".git" when it is a
file; update the block that references ignoredEntries, sourceDir,
generatedContents, fs.writeFileString and fs.makeDirectory accordingly.

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 5c497a6
Status: success
Files: 20 (28.83 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/tests/docker-git/controller-revision.test.ts`:
- Around line 69-90: The in-memory mock FileSystem is too permissive: update
readDirectory, readFileString and stat to enforce real- FS behavior by first
resolving normalizeMemoryPath(path) and checking entries.get(...) exists and has
the correct _tag; specifically, make readDirectory verify the entry exists and
entry._tag === "Directory" (otherwise throw or return an error indicating
missing/not-a-directory), make readFileString only succeed for entries with _tag
=== "File" (otherwise error), and make stat fail when the path is missing
(instead of returning a Directory); use the same entries map and
memoryFileInfo/matching error types so computeRevisionFromInputs/hashTree (which
call fs.exists before stat/readFileString) observe missing-path semantics
consistent with makeDirectory-created parents.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a06783d7-b764-4946-96dc-ba65c4a56172

📥 Commits

Reviewing files that changed from the base of the PR and between aee90d7 and 5c497a6.

📒 Files selected for processing (2)
  • packages/app/tests/docker-git/controller-revision.test.ts
  • packages/app/tests/docker-git/controller.test.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
🔇 Additional comments (2)
packages/app/tests/docker-git/controller.test.ts (1)

2-2: LGTM!

Also applies to: 21-50

packages/app/tests/docker-git/controller-revision.test.ts (1)

1-68: LGTM!

Also applies to: 91-206

Comment thread packages/app/tests/docker-git/controller-revision.test.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: bee9e00
Status: success
Files: 20 (29.56 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

Addressed the latest CodeRabbit follow-up comments.

Added in bee9e00:

  • tightened the in-memory FileSystem mock in controller-revision.test.ts so readDirectory, readFileString, and stat now fail on missing paths or wrong entry types instead of silently returning success;
  • kept the controller revision properties covered with a stricter mock that matches real filesystem semantics.

Local verification:

  • rtk bun --cwd packages/app vitest run tests/docker-git/controller-revision.test.ts
  • rtk bun run --cwd packages/app lint:tests
  • rtk bun run --cwd packages/app test
  • git diff --check

GitHub verification on bee9e0046a652f9a733e1f881d320aaba0979d9e:

  • Check green (26313907795), including Browser command e2e at 2m32s;
  • Final Build green (26313908915);
  • Checking Dependencies green (26313910135);
  • Snapshot green (26313911228);
  • CodeRabbit is pass and marked the last comment addressed in bee9e00.

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 4b079bb
Status: success
Files: 20 (30.10 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@skulidropek
Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

✅ Actions performed

Full review triggered.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/app/src/docker-git/menu-create-inputs.ts (1)

6-83: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Добавьте обязательные функциональные маркеры комментариев для helper-функций.

В этом модуле для trimLeftSlash, trimRightSlash, joinPath и resolveProjectsRoot есть TSDoc, но отсутствуют обязательные блоки CHANGE/WHY/QUOTE(ТЗ)/REF/SOURCE/FORMAT THEOREM/PURITY/EFFECT/INVARIANT/COMPLEXITY, которые уже используются у других функций файла.

As per coding guidelines "Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY."

Also applies to: 116-134

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/menu-create-inputs.ts` around lines 6 - 83, Add
the missing mandatory functional comment markers to the helper functions
trimLeftSlash, trimRightSlash, joinPath and resolveProjectsRoot: include CHANGE,
WHY, QUOTE(ТЗ) or "n/a", REF, SOURCE or "n/a", FORMAT THEOREM, PURITY (mark as
CORE or SHELL), and for SHELL functions add an EFFECT signature, plus explicit
INVARIANT and COMPLEXITY lines consistent with the existing style in the file;
keep the descriptions short and factual and place them in the TSDoc header above
each function.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/actions/free-docker-disk/action.yml:
- Around line 27-34: The case statement checking
DOCKER_GIT_FORCE_FREE_DOCKER_DISK currently treats mixed-case values like "TrUe"
as falsy; normalize the input before the case so matching is truly
case-insensitive (e.g., convert the variable force_cleanup to lowercase) and
then run the existing case on the normalized value, leaving the branches that
set force_cleanup_enabled unchanged; update references to force_cleanup in that
block (the case "$force_cleanup" in ... esac) to use the normalized variable so
1/true/yes/on in any letter case are recognized.

In `@packages/app/src/docker-git/controller-image-revision.ts`:
- Around line 75-87: В результате вызова runDockerCapture(...) код сейчас берёт
первый непустой результат через firstNonEmptyLine(output); добавь проверку
детерминизма: распарсь output в список непустых строк, если length !== 1 —
логируй/выбрасывай ошибку с полным списком образов (и контекстом, что ожидался
ровно один) или альтернативно фильтруй строки по сервису "api" перед возвратом;
внеси изменения рядом с вызовом firstNonEmptyLine и в логике, использующей
composeFilesForMode(...) / runDockerCapture(...), чтобы гарантировать, что
возвращаемый образ однозначен для контроллера.

In `@packages/app/tests/docker-git/menu-create-shared.test.ts`:
- Around line 153-163: Convert the two point tests into property-based tests
using fast-check: write an fc.property that for arbitrary relevant cwd values
(or a small string arb) when calling advanceCreateFlow({ cwd, projectsRoot: "/"
}, createInitialFlowView(featureCreateRepoUrl)) and wrapping with
expectCreateContinueView the returned view has the absolute outDir invariant
(i.e. view.values.outDir is the expected absolute path for root projectsRoot);
and write another fc.property that for arbitrary step sequences /
remaining-steps generated, applying advanceCreateFlow and inspecting the
returned view ensures view.index points to the next remaining step (no skipped
steps). Use fc.property (no async/await) and the existing helpers
expectCreateContinueView, advanceCreateFlow, createInitialFlowView and
featureCreateRepoUrl to implement the assertions; adhere to the repo testing
utilities (Effect test utilities) when needed.

---

Outside diff comments:
In `@packages/app/src/docker-git/menu-create-inputs.ts`:
- Around line 6-83: Add the missing mandatory functional comment markers to the
helper functions trimLeftSlash, trimRightSlash, joinPath and
resolveProjectsRoot: include CHANGE, WHY, QUOTE(ТЗ) or "n/a", REF, SOURCE or
"n/a", FORMAT THEOREM, PURITY (mark as CORE or SHELL), and for SHELL functions
add an EFFECT signature, plus explicit INVARIANT and COMPLEXITY lines consistent
with the existing style in the file; keep the descriptions short and factual and
place them in the TSDoc header above each function.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4c67cdfe-de68-43bc-a57e-1fd5b5c1fdf8

📥 Commits

Reviewing files that changed from the base of the PR and between 525ed8b and 4b079bb.

📒 Files selected for processing (24)
  • .dockerignore
  • .github/actions/free-docker-disk/action.yml
  • .github/workflows/check.yml
  • docker-compose.api.yml
  • docker-compose.yml
  • packages/api/Dockerfile
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/package.json
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
📜 Review details
🧰 Additional context used
📓 Path-based instructions (15)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • scripts/e2e/browser-command.sh
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • scripts/e2e/_lib.sh
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • scripts/e2e/browser-command.sh
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • scripts/e2e/_lib.sh
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/package.json
  • scripts/e2e/browser-command.sh
  • docker-compose.yml
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • docker-compose.api.yml
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • scripts/e2e/_lib.sh
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/web/app-ready-terminal-tabs.tsx
  • packages/app/src/web/panel-project-details.tsx
  • packages/app/package.json
  • scripts/e2e/browser-command.sh
  • docker-compose.yml
  • packages/app/src/web/terminal-panel-cleanup-runtime.ts
  • packages/api/src/services/terminal-sessions.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • docker-compose.api.yml
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • scripts/e2e/_lib.sh
  • packages/api/Dockerfile
  • packages/app/tests/docker-git/controller.test.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/{package*.json,requirements*.txt,setup.py,setup.cfg,Pipfile,Pipfile.lock,pyproject.toml,pom.xml,build.gradle,Gemfile,Gemfile.lock,go.mod,go.sum,composer.json,Cargo.toml,Cargo.lock}

📄 CodeRabbit inference engine (Custom checks)

Fail if dependency or package-manager changes materially increase supply-chain risk without justification

Files:

  • packages/app/package.json
**/{Dockerfile*,docker-compose*.{yml,yaml},.dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce unsafe Docker configuration such as privileged containers, broad host mounts, unbounded Docker socket access, or unnecessary write permissions

Files:

  • .dockerignore
  • docker-compose.yml
  • docker-compose.api.yml
  • packages/api/Dockerfile
docker-compose*.yml

📄 CodeRabbit inference engine (README.md)

docker-compose*.yml: Per-project containers should ship with a default CPU limit of 30% and RAM limit of 30% (resolved against the host), overridable via --cpu / --ram flags or per-project docker-git.json
GPU mode should default to 'none' for non-GPU projects; GPU is enabled only explicitly via --gpu all or saved 'gpu': 'all' in docker-git.json

Files:

  • docker-compose.yml
  • docker-compose.api.yml
packages/api/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

API layer should work only with LIB and serve as the intermediary between APP and LIB

Files:

  • packages/api/src/services/terminal-sessions.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • packages/app/tests/docker-git/controller.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/tests/docker-git/controller-revision.test.ts
  • packages/app/tests/docker-git/controller.test.ts
docker-compose.api.yml

📄 CodeRabbit inference engine (README.md)

Controller container (docker-git-api) should be capped with default CPU/RAM at 90% of host resources with memory swap defaulting to twice the resolved RAM limit, overridable via CLI flags or environment variables

Files:

  • docker-compose.api.yml
**/.github/workflows/*.{yml,yaml}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce unsafe GitHub Actions configuration such as unsafe pull_request_target, or unnecessary write permissions

Files:

  • .github/workflows/check.yml
🧠 Learnings (2)
📚 Learning: 2026-05-18T07:43:38.131Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 313
File: packages/api/src/services/panel-cloudflare-tunnel.ts:123-135
Timestamp: 2026-05-18T07:43:38.131Z
Learning: In this repo’s ProverCoderAI/docker-git architecture, it is intentional for service modules under packages/api/src/services/ to call Node.js APIs directly (e.g., fs, child_process, fetch). Do not treat direct Node API usage in these service modules as a dependency-injection (DI) violation. This codebase provides the NodeContext at the program boundary (entry point) rather than injecting Context.Tag/Layer services into individual service modules; reviewers should only flag DI/context issues if the expected boundary setup is missing.

Applied to files:

  • packages/api/src/services/terminal-sessions.ts
📚 Learning: 2026-05-22T21:08:18.083Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In this repo’s docker-git controller compose generation, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` should be treated as standard bash parameter expansion: when `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` is unset, it defaults to the string "1". There is no "-1" mode. The runtime contract enforced by `packages/app/src/docker-git/controller-compose.ts` is: unset / "1" / "true" => output "1"; "0" / "false" => output "0". If review code shows branching/behavior for "-1" or any numeric value other than this 0/1 contract, flag it. Also ensure the Dockerfile ARG `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` stays consistent with default `1`.

Applied to files:

  • packages/app/src/docker-git/controller-docker.ts
  • packages/app/src/docker-git/menu-create-advance.ts
  • packages/app/src/docker-git/controller.ts
  • packages/app/src/docker-git/controller-bootstrap-plan.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/controller-compose.ts
  • packages/app/src/docker-git/controller-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
🪛 Checkov (3.2.529)
packages/api/Dockerfile

[low] 1-157: Ensure that HEALTHCHECK instructions have been added to container images

(CKV_DOCKER_2)


[low] 1-157: Ensure that a user for the container has been created

(CKV_DOCKER_3)

🪛 Hadolint (2.14.0)
packages/api/Dockerfile

[info] 89-89: Multiple consecutive RUN instructions. Consider consolidation.

(DL3059)


[warning] 105-105: Use WORKDIR to switch to a directory

(DL3003)

🪛 Trivy (0.69.3)
packages/api/Dockerfile

[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)


[error] 1-1: Image user should not be 'root'

Specify at least 1 USER command in Dockerfile with non-root user as argument

Rule: DS-0002

Learn more

(IaC/Dockerfile)


[info] 1-1: No HEALTHCHECK defined

Add HEALTHCHECK instruction in your Dockerfile

Rule: DS-0026

Learn more

(IaC/Dockerfile)


[warning] 105-135: 'RUN cd ...' to change directory

RUN should not be used to change directory: 'if [ "$DOCKER_GIT_CONTROLLER_BUILD_SKILLER" = "1" ]; then test -f third_party/skiller-desktop-skills-manager/package.json && cd third_party/skiller-desktop-skills-manager && for attempt in 1 2 3 4 5; do if bun install --frozen-lockfile --silent; then break; fi; if [ "$attempt" = "5" ]; then echo "skiller bun install failed after retries" >&2; exit 1; fi; echo "skiller bun install attempt ${attempt} failed; retrying..." &gt;&amp;2; rm -rf /root/.bun/install/cache node_modules; sleep $((attempt * 2)); done && bun run build && touch out/.docker-git-browser-folder-picker.patch && mkdir -p out/preload && ln -sf index.mjs out/preload/index.js; else cd third_party/skiller-desktop-skills-manager && mkdir -p node_modules/electron/dist out/main out/renderer out/preload && printf '%s\n' '#!/usr/bin/env sh' 'echo "Skiller is not bundled in this controller image." >&2' 'exit 1' > node_modules/electron/dist/electron && chmod +x node_modules/electron/dist/electron && printf '%s\n' 'throw new Error("Skiller is not bundled in this controller image.")' > out/main/index.js && printf '%s\n' '<!doctype html><title>Skiller unavailable</title>' > out/renderer/index.html && printf '%s\n' 'export {}' > out/preload/index.mjs && touch out/.docker-git-browser-folder-picker.patch && ln -sf index.mjs out/preload/index.js; fi'. Use 'WORKDIR' statement instead.

Rule: DS-0013

Learn more

(IaC/Dockerfile)

🔇 Additional comments (21)
packages/api/src/services/terminal-sessions.ts (1)

769-773: LGTM!

packages/app/src/web/app-ready-terminal-tabs.tsx (1)

40-40: LGTM!

packages/app/src/web/panel-project-details.tsx (1)

127-130: LGTM!

Also applies to: 144-144

packages/app/src/web/terminal-panel-cleanup-runtime.ts (1)

27-29: LGTM!

packages/app/src/docker-git/menu-create-advance.ts (1)

266-266: LGTM!

Also applies to: 281-282, 288-288

.dockerignore (1)

2-4: LGTM!

Also applies to: 8-18

docker-compose.api.yml (1)

7-8: LGTM!

Also applies to: 13-13

docker-compose.yml (1)

8-8: LGTM!

packages/app/package.json (1)

30-31: LGTM!

packages/api/Dockerfile (1)

1-1: LGTM!

Also applies to: 55-62, 66-71, 81-89, 91-98, 100-136, 137-151

.github/actions/free-docker-disk/action.yml (1)

10-25: LGTM!

Also applies to: 36-53, 64-67

.github/workflows/check.yml (1)

156-158: LGTM!

Also applies to: 176-178, 196-198, 216-218, 236-238, 256-258

scripts/e2e/_lib.sh (1)

27-27: LGTM!

Also applies to: 138-185, 483-533

scripts/e2e/browser-command.sh (1)

143-147: LGTM!

packages/app/src/docker-git/controller-bootstrap-plan.ts (1)

1-77: LGTM!

packages/app/src/docker-git/controller.ts (1)

3-3: LGTM!

Also applies to: 17-17, 147-148, 165-165, 169-170, 176-183, 222-231, 238-239, 242-242, 320-327

packages/app/tests/docker-git/controller.test.ts (1)

3-3: LGTM!

Also applies to: 5-13, 21-50, 132-137, 147-182, 183-195, 205-215, 216-220

packages/app/tests/docker-git/controller-revision.test.ts (1)

1-279: LGTM!

packages/app/src/docker-git/controller-revision.ts (1)

10-22: LGTM!

Also applies to: 25-37, 118-145

packages/app/src/docker-git/controller-compose.ts (1)

11-15: LGTM!

Also applies to: 34-46, 61-72, 126-126, 140-143, 157-163, 175-177

packages/app/src/docker-git/controller-docker.ts (1)

24-30: LGTM!

Comment thread .github/actions/free-docker-disk/action.yml Outdated
Comment thread packages/app/src/docker-git/controller-image-revision.ts Outdated
Comment thread packages/app/tests/docker-git/menu-create-shared.test.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 834b994
Status: success
Files: 21 (36.95 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/app/src/docker-git/controller-image-revision.ts (1)

190-202: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Сделайте инспекцию ревизии best-effort вместо фатального отказа.

Сейчас при ошибке резолва image (например, неоднозначный вывод compose) путь на Line 190 может вернуть ControllerBootstrapError и сорвать bootstrap. Для этой оптимизации безопаснее деградировать в null и перейти к обычному build-пути.

Предлагаемое минимальное исправление
 export const inspectControllerImageRevision = (): Effect.Effect<
   string | null,
   ControllerBootstrapError,
   ControllerRuntime
 > =>
   inspectControllerComposeImageName().pipe(
+    Effect.orElseSucceed((): string | null => null),
     Effect.flatMap((imageName) =>
       imageName === null
         ? Effect.succeed<string | null>(null)
         : runDockerCapture(
           ["image", "inspect", "-f", inspectControllerRevisionLabelTemplate, imageName],
           `Failed to inspect image revision for ${imageName}`
         ).pipe(
           Effect.map((output) => parseControllerRevisionLabelOutput(output)),
           Effect.orElseSucceed((): string | null => null)
         )
     )
   )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/controller-image-revision.ts` around lines 190 -
202, The inspectControllerComposeImageName() call should be best-effort too —
catch failures there and return null so the bootstrap can fall back to build;
wrap or handle errors from inspectControllerComposeImageName() (not just the
runDockerCapture call) and map any error to a successful null value. Concretely,
ensure the pipeline starting with inspectControllerComposeImageName() uses
Effect.orElseSucceed(() => null) (or an equivalent error-to-null recovery)
before or around the subsequent Effect.flatMap, so failures in
inspectControllerComposeImageName, runDockerCapture, or
parseControllerRevisionLabelOutput all degrade to null instead of throwing a
ControllerBootstrapError.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/app/src/docker-git/controller-image-revision.ts`:
- Around line 190-202: The inspectControllerComposeImageName() call should be
best-effort too — catch failures there and return null so the bootstrap can fall
back to build; wrap or handle errors from inspectControllerComposeImageName()
(not just the runDockerCapture call) and map any error to a successful null
value. Concretely, ensure the pipeline starting with
inspectControllerComposeImageName() uses Effect.orElseSucceed(() => null) (or an
equivalent error-to-null recovery) before or around the subsequent
Effect.flatMap, so failures in inspectControllerComposeImageName,
runDockerCapture, or parseControllerRevisionLabelOutput all degrade to null
instead of throwing a ControllerBootstrapError.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1eb5bb9d-2a37-45da-92fd-1a3585616d51

📥 Commits

Reviewing files that changed from the base of the PR and between 4b079bb and 834b994.

📒 Files selected for processing (5)
  • .github/actions/free-docker-disk/action.yml
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/tests/docker-git/create-flow-test-helpers.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
🧠 Learnings (1)
📚 Learning: 2026-05-22T21:08:18.083Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In this repo’s docker-git controller compose generation, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` should be treated as standard bash parameter expansion: when `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` is unset, it defaults to the string "1". There is no "-1" mode. The runtime contract enforced by `packages/app/src/docker-git/controller-compose.ts` is: unset / "1" / "true" => output "1"; "0" / "false" => output "0". If review code shows branching/behavior for "-1" or any numeric value other than this 0/1 contract, flag it. Also ensure the Dockerfile ARG `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` stays consistent with default `1`.

Applied to files:

  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/src/docker-git/menu-create-inputs.ts
🔇 Additional comments (5)
packages/app/tests/docker-git/create-flow-test-helpers.ts (1)

42-69: LGTM!

packages/app/tests/docker-git/menu-create-shared-properties.test.ts (1)

1-174: LGTM!

.github/actions/free-docker-disk/action.yml (1)

20-30: LGTM!

packages/app/src/docker-git/controller-image-revision.ts (1)

11-115: LGTM!

packages/app/src/docker-git/menu-create-inputs.ts (1)

84-113: LGTM!

Also applies to: 160-173

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: e635acd
Status: success
Files: 21 (37.99 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/docker-git/controller-image-revision.ts`:
- Line 191: The current use of Effect.orElseSucceed((): string | null => null)
inside inspectControllerImageRevision suppresses any ControllerBootstrapError
coming from inspectControllerComposeImageName (e.g., docker/compose failures);
remove that global orElseSucceed so errors from
inspectControllerComposeImageName flow to the error channel, and instead apply a
targeted recovery to return null only where absence/ambiguity is expected
(inside resolveSingleControllerImageName). Concretely: stop swallowing errors in
inspectControllerImageRevision, move the null-recovery into
resolveSingleControllerImageName (or wrap only the call-site that intends to
treat “no image found” as null) and preserve propagation of docker/compose
errors from inspectControllerComposeImageName.

In `@packages/app/tests/docker-git/controller-image-revision.test.ts`:
- Around line 101-118: Add a property-based test around
inspectControllerImageRevision that asserts it returns null whenever the number
of non-empty lines (after trim+filter implemented by nonEmptyLines) is either 0
or greater than 1: use fast-check to generate stdout strings composed of N
non-empty lines where N ∈ {0} ∪ {n | n > 1} (e.g., arrayOf(nonEmptyString())
with length 0 or minLength 2), join with "\n", and feed that stdout via the
commandExecutorLayer stub used in the existing test; for each generated stdout
run inspectControllerImageRevision (providing FileSystem.layerNoop and
Path.layer as in the current test) and assert the result is null. Ensure the
property wires into the same docker --images branch in commandExecutorLayer so
the produced stdout is used by the implementation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 3c1c0ef1-459d-4725-a959-7250c390797d

📥 Commits

Reviewing files that changed from the base of the PR and between 834b994 and e635acd.

📒 Files selected for processing (2)
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/tests/docker-git/controller-image-revision.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: Lint
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
🧠 Learnings (1)
📚 Learning: 2026-05-22T21:08:18.083Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In this repo’s docker-git controller compose generation, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` should be treated as standard bash parameter expansion: when `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` is unset, it defaults to the string "1". There is no "-1" mode. The runtime contract enforced by `packages/app/src/docker-git/controller-compose.ts` is: unset / "1" / "true" => output "1"; "0" / "false" => output "0". If review code shows branching/behavior for "-1" or any numeric value other than this 0/1 contract, flag it. Also ensure the Dockerfile ARG `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` stays consistent with default `1`.

Applied to files:

  • packages/app/src/docker-git/controller-image-revision.ts

Comment thread packages/app/src/docker-git/controller-image-revision.ts Outdated
Comment thread packages/app/tests/docker-git/controller-image-revision.test.ts Outdated
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 40b718a
Status: success
Files: 21 (38.33 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/app/src/docker-git/controller-image-revision.ts (1)

145-155: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Не скрывайте все ошибки docker image inspect в null

На Line 154 Effect.orElseSucceed(() => null) глушит любые ControllerBootstrapError из runDockerCapture(...), включая диагностически важные ошибки Docker daemon/socket. Это ломает прозрачность причин bootstrap-сбоя.

Предлагаемое минимальное исправление
 export const inspectControllerImageRevision = (): Effect.Effect<
   string | null,
   ControllerBootstrapError,
   ControllerRuntime
 > =>
   inspectControllerComposeImageName().pipe(
     Effect.flatMap((imageName) =>
       imageName === null
         ? Effect.succeed<string | null>(null)
         : runDockerCapture(
           ["image", "inspect", "-f", inspectControllerRevisionLabelTemplate, imageName],
           `Failed to inspect image revision for ${imageName}`
         ).pipe(
-          Effect.map((output) => parseControllerRevisionLabelOutput(output)),
-          Effect.orElseSucceed((): string | null => null)
+          Effect.map((output) => parseControllerRevisionLabelOutput(output))
         )
     )
   )

As per coding guidelines (README.md): "remediation must distinguish (1) Docker daemon unreachable, (2) socket permission, (3) controller not running; and the CLI should guide accordingly."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/app/src/docker-git/controller-image-revision.ts` around lines 145 -
155, The current pipeline in inspectControllerComposeImageName ->
runDockerCapture -> parseControllerRevisionLabelOutput swallows all errors with
Effect.orElseSucceed(() => null), hiding important ControllerBootstrapError
details; change the error handling so that runDockerCapture errors are inspected
and only convert the "image not found / no label" case to null, while rethrowing
or returning a failure for Docker daemon/socket/permission errors so they
surface to the CLI. Concretely, replace Effect.orElseSucceed(() => null) with an
Effect.catch or Effect.catchAll that matches on the error from runDockerCapture
(ControllerBootstrapError or its discriminants) and returns null only for the
specific “label missing / image absent” condition, otherwise rethrow or wrap the
error (and ensure the error message is preserved when propagated) so CLI can
distinguish daemon unreachable, socket permission, and controller-not-running
scenarios; reference functions: inspectControllerComposeImageName,
runDockerCapture, parseControllerRevisionLabelOutput.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/app/src/docker-git/controller-image-revision.ts`:
- Around line 145-155: The current pipeline in inspectControllerComposeImageName
-> runDockerCapture -> parseControllerRevisionLabelOutput swallows all errors
with Effect.orElseSucceed(() => null), hiding important ControllerBootstrapError
details; change the error handling so that runDockerCapture errors are inspected
and only convert the "image not found / no label" case to null, while rethrowing
or returning a failure for Docker daemon/socket/permission errors so they
surface to the CLI. Concretely, replace Effect.orElseSucceed(() => null) with an
Effect.catch or Effect.catchAll that matches on the error from runDockerCapture
(ControllerBootstrapError or its discriminants) and returns null only for the
specific “label missing / image absent” condition, otherwise rethrow or wrap the
error (and ensure the error message is preserved when propagated) so CLI can
distinguish daemon unreachable, socket permission, and controller-not-running
scenarios; reference functions: inspectControllerComposeImageName,
runDockerCapture, parseControllerRevisionLabelOutput.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 8d39cd94-1019-40a1-a0fc-a47abb8525a9

📥 Commits

Reviewing files that changed from the base of the PR and between e635acd and 40b718a.

📒 Files selected for processing (2)
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/tests/docker-git/controller-image-revision.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Clone auto-open SSH)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: Lint
  • GitHub Check: E2E (Clone cache)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/tests/docker-git/controller-image-revision.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
🧠 Learnings (1)
📚 Learning: 2026-05-22T21:08:18.083Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In this repo’s docker-git controller compose generation, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` should be treated as standard bash parameter expansion: when `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` is unset, it defaults to the string "1". There is no "-1" mode. The runtime contract enforced by `packages/app/src/docker-git/controller-compose.ts` is: unset / "1" / "true" => output "1"; "0" / "false" => output "0". If review code shows branching/behavior for "-1" or any numeric value other than this 0/1 contract, flag it. Also ensure the Dockerfile ARG `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` stays consistent with default `1`.

Applied to files:

  • packages/app/src/docker-git/controller-image-revision.ts
🔇 Additional comments (2)
packages/app/tests/docker-git/controller-image-revision.test.ts (1)

10-10: LGTM!

Also applies to: 25-33, 110-161

packages/app/src/docker-git/controller-image-revision.ts (1)

46-70: LGTM!

Also applies to: 75-115, 124-139

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 6f68395
Status: success
Files: 22 (39.89 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 22, 2026

AI Session Backup

Commit: 789a128
Status: success
Files: 22 (40.00 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 23, 2026

AI Session Backup

Commit: c7ef800
Status: success
Files: 23 (41.91 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/app/src/docker-git/browser-frontend.ts`:
- Around line 176-179: In the explicit-URL branch of resolveApiBaseUrl (where
resolveExplicitApiBaseUrl() is called), return the explicitApiBaseUrl variable
instead of selectedApiBaseUrl so the function doesn't implicitly depend on
resolveApiBaseUrl internals; update the branch that currently does "if
(explicitApiBaseUrl !== undefined) { return Effect.succeed(selectedApiBaseUrl)
}" to return Effect.succeed(explicitApiBaseUrl) and keep the rest of
resolveApiBaseUrl/selectedApiBaseUrl logic unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a7464bdf-ec98-4ee2-a168-9f6827dc44a8

📥 Commits

Reviewing files that changed from the base of the PR and between 789a128 and c7ef800.

📒 Files selected for processing (5)
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/src/docker-git/controller-image-revision.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout of 900000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
  • GitHub Check: E2E (Login context)
  • GitHub Check: E2E (Runtime volumes + SSH)
  • GitHub Check: E2E (Clone cache)
  • GitHub Check: E2E (OpenCode)
  • GitHub Check: Lint
  • GitHub Check: E2E (Clone auto-open SSH)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Implement Functional Core, Imperative Shell (FCIS) pattern: CORE layer contains only pure functions with immutable data and mathematical operations; SHELL layer isolates all effects (IO, network, database). Strict dependency direction: SHELL → CORE (never reverse).
Never use any, unknown, eslint-disable, ts-ignore, or as type assertions (except in rigorously justified cases with documentation). Always use exhaustive union type analysis through .exhaustive() pattern matching.
All external dependencies must be wrapped through typed interfaces and injected via Effect-TS Layer pattern. Never call external services directly from CORE functions.
Use monadic composition with Effect-TS for all effects: Effect<Success, Error, Requirements>. Compose effects through pipe() and Effect.flatMap(). Implement dependency injection via Layer pattern. Handle errors without try/catch blocks.
All functions must be pure in the CORE layer: no side effects (logging, console output, IO operations, mutations). Separate all side effects into the SHELL layer.
Use exhaustive pattern matching with Effect.Match instead of switch statements. Example: Match.value(item).pipe(Match.when(...), Match.exhaustive).
Document all functions with comprehensive TSDoc including: @pure (true/false), @effect (required services), @invariant (mathematical invariants), @precondition, @postcondition, @complexity (time and space), @throws Never (errors must be typed in Effect).
Use functional comment markers for code clarity: CHANGE (brief description), WHY (mathematical/architectural justification), QUOTE(ТЗ) (requirement citation), REF (RTM or message ID), SOURCE (external source with quote), FORMAT THEOREM (∀x ∈ Domain: P(x) → Q(f(x))), PURITY (CORE|SHELL), EFFECT (Effect type signature), INVARIANT (mathematical invariant), COMPLEXITY (time/space).
Define all external service dependencies as Context.Tag classes with fully typed methods returning Effect types. Example: `class Da...

Files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: Forbidden constructs in CORE code: any, eslint-disable, ts-ignore, async/await, raw Promise chains (then/catch), Promise.all, try/catch for logic control, console.*, switch statements (use Match with .exhaustive() instead)
All functions must use Effect-TS for composing effects: Effect<Success, Error, Requirements>. No direct async/await, Promise chains, or try/catch in product logic.
Functional comments must include: CHANGE, WHY, QUOTE(ТЗ) or n/a, REF, SOURCE or n/a, FORMAT THEOREM, PURITY (CORE|SHELL), EFFECT signature for SHELL functions, INVARIANT, and COMPLEXITY.
All data mutations must use immutable patterns (ReadonlyArray, readonly properties, Object.freeze); mutation in SHELL only when absolutely necessary and documented.

Files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{sh,bash,py,js,ts,jsx,tsx,go,java,rb,php}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce command injection or unsafe shell/process execution with user-controlled input

Files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files introduce path traversal or writes outside intended project/container state directories

Files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}

📄 CodeRabbit inference engine (Custom checks)

Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output

Files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (README.md)

App layer (APP) should work only with API and not have direct access to LIB layer

Files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Ты строгий ревьюер SPEC DRIVEN DEVELOPMENT.

Перед выводами изучи README.md, другие *.md файлы, linked issues,
PR description, PR comments/discussion и релевантную кодовую базу.

Сверь изменения с исходным ТЗ/спекой и обсуждением. Флагай любой уход
от спеки, недокументированное изменение поведения, отсутствие тестов
для заявленного поведения и security-риск. Если спека не видна,
попроси автора добавить ее в issue или PR description.

Проверь решение с точки зрения формальной верификации: какие инварианты,
предусловия и постусловия можно доказать математически, а где доказуемость
слабая. Оцени решение с точки зрения теории игр: устойчивы ли стимулы,
нет ли выгодного обхода правил, и какое решение было бы сильнее.

Files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
  • packages/app/src/docker-git/controller-image-revision.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Implement property-based testing using fast-check for mathematical properties and invariants. Example: fc.property(fc.array(messageArbitrary), (messages) => isChronologicallySorted(sortMessagesByTimestamp(messages))).
Mock external dependencies in unit tests using Effect's testing utilities. Run tests without Effect runtime for speed. Example: Effect.provide(MockService), Effect.runPromise.

Files:

  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Property-based tests (fast-check) must verify mathematical invariants; unit tests must use Effect test utilities without async/await.

Files:

  • packages/app/tests/docker-git/menu-create-shared-properties.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/menu-create-shared.test.ts
🧠 Learnings (1)
📚 Learning: 2026-05-22T21:08:18.083Z
Learnt from: skulidropek
Repo: ProverCoderAI/docker-git PR: 344
File: packages/app/src/docker-git/controller-compose.ts:34-40
Timestamp: 2026-05-22T21:08:18.083Z
Learning: In this repo’s docker-git controller compose generation, `${DOCKER_GIT_CONTROLLER_BUILD_SKILLER:-1}` should be treated as standard bash parameter expansion: when `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` is unset, it defaults to the string "1". There is no "-1" mode. The runtime contract enforced by `packages/app/src/docker-git/controller-compose.ts` is: unset / "1" / "true" => output "1"; "0" / "false" => output "0". If review code shows branching/behavior for "-1" or any numeric value other than this 0/1 contract, flag it. Also ensure the Dockerfile ARG `DOCKER_GIT_CONTROLLER_BUILD_SKILLER` stays consistent with default `1`.

Applied to files:

  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/src/docker-git/controller-image-revision.ts
🔇 Additional comments (4)
packages/app/tests/docker-git/menu-create-shared-properties.test.ts (1)

5-7: LGTM!

packages/app/tests/docker-git/browser-frontend.test.ts (1)

9-41: LGTM!

Also applies to: 83-86, 124-132, 174-217

packages/app/tests/docker-git/menu-create-shared.test.ts (1)

21-25: LGTM!

Also applies to: 156-170, 209-223

packages/app/src/docker-git/controller-image-revision.ts (1)

182-186: LGTM!

Comment thread packages/app/src/docker-git/browser-frontend.ts
@skulidropek
Copy link
Copy Markdown
Member Author

skulidropek commented May 23, 2026

AI Session Backup

Commit: ed22024
Status: success
Files: 23 (42.07 MB)
Links: README | Manifest

git status

On branch issue-339
Your branch is up to date with 'origin/issue-339'.

nothing to commit, working tree clean

@skulidropek
Copy link
Copy Markdown
Member Author

Follow-up update on the CodeRabbit/e2e fixes:

  • Fixed the browser frontend API target selection so host browser runtime prefers the reachable configured host URL after controller bootstrap, while preserving explicit DOCKER_GIT_API_URL exactly. This keeps runtime-state and web proxy config on the externally reachable endpoint instead of leaking a Docker bridge URL.
  • Converted the create-flow root projectsRoot and next-step invariants to fast-check property coverage where CodeRabbit flagged the example-only tests.
  • Addressed the final CodeRabbit follow-up by returning explicitApiBaseUrl directly in the explicit branch.

Local verification on final changes:

  • rtk bun --cwd packages/app vitest run tests/docker-git/browser-frontend.test.ts tests/docker-git/menu-create-shared.test.ts tests/docker-git/menu-create-shared-properties.test.ts tests/docker-git/controller-image-revision.test.ts
  • rtk bun run --cwd packages/app lint:effect
  • rtk bun run --cwd packages/app typecheck
  • rtk bun run --cwd packages/app lint
  • rtk bun run --cwd packages/app lint:tests
  • rtk bun run --cwd packages/app test
  • git diff --check

GitHub checks are green on ed22024, including CodeRabbit and E2E (Browser command) at 2m39s.

@skulidropek skulidropek merged commit c18b20c into main May 23, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant