Skip to content

perf(ci): run affected checks by module#435

Draft
skulidropek wants to merge 8 commits into
ProverCoderAI:mainfrom
skulidropek:issue-432
Draft

perf(ci): run affected checks by module#435
skulidropek wants to merge 8 commits into
ProverCoderAI:mainfrom
skulidropek:issue-432

Conversation

@skulidropek

@skulidropek skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member

Summary

  • Add a workspace-aware affected-check runner for lint, Effect lint, tests, typecheck, and check.
  • Replace vibecode-linter usage with direct ESLint cache scripts and TypeScript typecheck.
  • Split CI checks into affected module matrices while preserving aggregate required-check job names.
  • Make module lifecycle scripts self-contained for standalone matrix jobs.
  • Add one E2E prepare job that builds prebuilt CLI/web, controller image, and project image artifacts once.
  • Load the controller and project Docker images in each parallel Docker E2E job, then start projects with docker compose up -d reuse mode instead of rebuilding.
  • Preserve runtime workspace context for prebuilt project images by exporting project env into SSH/login shells.

Closes #432

Proof of fix

  • Причина: CI ran fixed full-package check lists and Docker-heavy E2E jobs repeated workspace install/build work. After moving to a prebuilt project image, SSH shells could also keep build-time workspace defaults unless runtime project env was exported into the session.
  • Решение: changed-checks emits affected module matrices; E2E now has one e2e-prepare build/upload stage for CLI/web, controller image, and project image. Fanout jobs download/load those artifacts and use DOCKER_GIT_E2E_PROJECT_IMAGE with compose reuse mode. Prebuilt-image reuse is fail-fast and cannot fall back to --build; entrypoint rewrites runtime project env and Codex resume hints for SSH sessions.
  • Доказательство: GitHub Actions for commit 3d856f4ccc0b5b9ed7eaae7b03db3e81453d9790 completed successfully: Snapshot, Checking Dependencies, Final Build, and Check. Docker-heavy E2E fanout passed with E2E prepare building the project image once, then E2E (Browser command), E2E (OpenCode), E2E (Clone cache), E2E (Login context), E2E (Runtime volumes + SSH), and E2E (Clone auto-open SSH) all green.

Verification

  • bun run --cwd packages/container test -- tests/core/templates.test.ts
  • bun run --cwd packages/container lint
  • bun run --cwd packages/container build
  • bun run --cwd packages/lib test -- tests/usecases/projects-up.test.ts
  • bun run --cwd packages/lib lint
  • bun run --cwd packages/lib build
  • bun run --cwd packages/api test -- tests/projects.test.ts
  • bun run --cwd packages/api lint
  • bun run --cwd packages/api build
  • bun scripts/ci/build-e2e-project-image.ts --dry-run
  • git diff --check
  • GitHub Actions for 3d856f4ccc0b5b9ed7eaae7b03db3e81453d9790: all PR checks completed successfully.

Local limitation: full Docker image build/load timing was verified by GitHub Actions rather than the local workspace.

@coderabbitai

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

PR добавляет планировщик scripts/changed-checks.mjs, запускающий проверки только для затронутых пакетов; рефакторит CI workflow на матричные jobs через этот планировщик; вводит полный prebuilt-пайплайн E2E (сборка Docker-образов, CLI/web prebuilt, dockerComposeUpBuildMode/imageName сквозь домен и compose-шаблоны); заменяет vibecode-linter на прямые вызовы ESLint с кэшированием во всех пакетах.

Changes

Changed-checks planner and CI matrix jobs

Layer / File(s) Summary
Публичные типы планировщика
scripts/changed-checks.d.mts
Объявлены типы операций, пакетов воркспейса, команд, плана (ChangedChecksPlan), аргументов CLI и GithubMatrix.
Ядро планировщика: загрузка пакетов, affected-замыкание, генерация команд
scripts/changed-checks.mjs
Реализованы loadWorkspacePackages, reverseDependencyMap, affectedClosure, топологическая сортировка, planMode, createChangedChecksPlan и вспомогательные генераторы команд.
CLI-раннер планировщика: git diff, матрица, параллельное выполнение
scripts/changed-checks.mjs
changedFilesFromGit, parseChangedChecksArgs, createGithubMatrix, фазовый параллельный раннер runCommands и точка входа runChangedChecksCli.
Тесты планировщика и скрипты корневого package.json
packages/app/tests/docker-git/changed-checks.test.ts, package.json
Тесты режимов skip/all/affected, fails-closed, serial pre-hooks и createGithubMatrix; корневые npm-скрипты переведены на bun scripts/changed-checks.mjs.
CI: job plan-checks и матричные jobs проверок
.github/workflows/check.yml, .github/actions/setup/action.yml
Новый job plan-checks записывает матрицы в GITHUB_OUTPUT; четыре пары *-modules/агрегатор заменяют монолитные jobs; action получает параметр install-dependencies.

E2E prebuilt image pipeline

Layer / File(s) Summary
Контракты домена: imageName, dockerComposeUpBuildMode
packages/container/src/core/domain.ts, packages/lib/src/core/domain.ts, packages/lib/src/shell/config.ts, packages/lib/src/usecases/actions/docker-up.ts
TemplateConfig получает imageName?; CreateCommanddockerComposeUpBuildMode?; DockerUpOptionsbuildMode?.
Compose-шаблон: renderProjectImageSource и runtime project identity
packages/container/src/core/templates/docker-compose.ts, packages/container/src/core/templates-entrypoint/base.ts, packages/container/src/core/templates-entrypoint.ts
renderProjectImageSource выбирает build: . или image: + pull_policy: never; renderEntrypointProjectRuntimeEnv публикует TARGET_DIR/REPO_URL/REPO_REF в /etc/profile.d и SSH env.
Замена __TARGET_DIR__ на $TARGET_DIR в шаблонах агентов
packages/container/src/core/templates-entrypoint/agents-notice.ts, claude-extra-config.ts, gemini.ts, grok.ts, codex-resume-hint.ts
Плейсхолдеры __TARGET_DIR__ заменены на shell-переменную $TARGET_DIR; соответствующие replaceAll удалены из рендереров.
docker-up и projects-up: маршрутизация по buildMode
packages/lib/src/shell/docker-compose.ts, packages/lib/src/usecases/actions/docker-up.ts, packages/lib/src/usecases/projects-up.ts, packages/lib/src/usecases/actions/create-project.ts
runDockerComposeUpByMode ветвится по "reuse"/"build"; runDockerComposeUpRecreate принимает buildMode; projects-up пропускает rebuild-fallback при наличии prebuilt-образа.
API: инъекция E2E project image
packages/api/src/services/projects.ts, docker-compose.yml
withE2eProjectImageForCreate читает DOCKER_GIT_E2E_PROJECT_IMAGE и устанавливает buildMode: "reuse" + config.imageName в команде создания.
Browser frontend: prebuilt-ветка
packages/app/src/docker-git/browser-frontend-prebuilt.ts, browser-frontend-launch.ts, browser-frontend.ts
Новые модули проверяют DOCKER_GIT_E2E_USE_PREBUILT_WEB, валидируют наличие dist-web/index.html и ветвятся между prebuilt и streaming build.
CI: job e2e-prepare и обновлённые E2E runner jobs
.github/workflows/check.yml
e2e-prepare собирает и публикует 3 артефакта; шесть E2E runner jobs загружают артефакты и используют DOCKER_GIT_E2E_USE_PREBUILT_CLI/WEB.
CI helper scripts: build-e2e-project-image, pack-e2e-prebuilt, e2e lib
scripts/ci/build-e2e-project-image.ts, scripts/ci/pack-e2e-prebuilt.mjs, scripts/e2e/_lib.sh, scripts/e2e/browser-command.sh
Скрипты сборки Docker-образа и упаковки prebuilt tgz; _lib.sh добавляет dg_require_prebuilt_docker_git_cli; browser-command.sh расширяет условие OR.
Тесты: buildMode, compose-шаблон, browser prebuilt, API project image
packages/lib/tests/usecases/docker-up-force.test.ts, projects-up.test.ts, packages/container/tests/core/templates.test.ts, packages/app/tests/docker-git/browser-frontend.test.ts, packages/api/tests/projects.test.ts
Покрывают force+reuse режим, no-rebuild при prebuilt failure, imageName в compose, prebuilt web-ветку и API инъекцию образа.

Linter migration: vibecode-linter → ESLint with cache

Layer / File(s) Summary
Замена vibecode-linter на ESLint с кэшем
packages/app/package.json, packages/container/package.json, packages/lib/package.json, packages/terminal/package.json, packages/docker-git-session-sync/package.json, packages/api/package.json, packages/*/linter.config.json, .gitignore, experiments/terminal-query-suppression.md, scripts/npx
Lint-скрипты переключены на eslint --cache*; @ton-ai-core/vibecode-linter удалён; priorityLevels убраны из linter.config.json; .gitignore дополнен паттернами ESLint-кэша.

Sequence Diagram(s)

sequenceDiagram
    participant GH as GitHub Actions
    participant planChecks as plan-checks job
    participant changedChecks as changed-checks.mjs
    participant matrixJob as *-modules matrix job
    participant aggregator as aggregator job

    GH->>planChecks: trigger on push/PR
    planChecks->>changedChecks: node scripts/changed-checks.mjs --matrix
    changedChecks->>changedChecks: git diff → affectedClosure → createChangedChecksPlan
    changedChecks-->>planChecks: GithubMatrix JSON + has_work flags
    planChecks->>GH: write GITHUB_OUTPUT (typecheck_matrix, lint_matrix, ...)
    GH->>matrixJob: spawn N parallel jobs per matrix include
    matrixJob->>matrixJob: bun run --filter <pkg> <script>
    matrixJob-->>aggregator: result (success/failure/cancelled)
    aggregator->>GH: exit 1 on failure/cancelled
Loading
sequenceDiagram
    participant e2ePrepare as e2e-prepare job
    participant buildScript as build-e2e-project-image.ts
    participant packScript as pack-e2e-prebuilt.mjs
    participant artifacts as GitHub Artifacts
    participant e2eRunner as e2e-* runner job
    participant dockerShell as _lib.sh

    e2ePrepare->>buildScript: bun run → writeProjectFiles + docker build
    buildScript-->>e2ePrepare: docker-git-e2e-project image
    e2ePrepare->>e2ePrepare: docker build controller image
    e2ePrepare->>packScript: pack runtime deps + dist → .tgz
    e2ePrepare->>artifacts: upload prebuilt.tgz + controller.tar.gz + project.tar.gz
    artifacts-->>e2eRunner: download all 3 artifacts
    e2eRunner->>e2eRunner: tar xzf prebuilt.tgz
    e2eRunner->>e2eRunner: docker load < *.tar.gz
    e2eRunner->>dockerShell: DOCKER_GIT_E2E_USE_PREBUILT_CLI=1
    dockerShell->>dockerShell: dg_require_prebuilt_docker_git_cli → return 0
    e2eRunner->>e2eRunner: run e2e test script
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
Requirements Alignment ❌ Error PR реализует основные требования (affected-checks runner, ESLint замена, E2E optimize), но игнорирует 9 критических проблем из review comments: path traversal в npx/pack-e2e-prebuilt, отсутствие pr... Устранить критические проблемы: (1) валидировать command_name в npx; (2) добавить fc.property тесты; (3) валидировать --concurrency/--base/--head; (4) абстрагировать process.env через Layer; (5) редактировать userinfo из URL; (6) проверя...
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Security Regression ⚠️ Warning PR introduces 5 high-confidence security regressions: path traversal in scripts/npx (unvalidated command_name), path traversal in pack-e2e-prebuilt.mjs (symlink escaping), credential exposure in ba... Fix scripts/npx command_name validation; add path boundary checks in pack-e2e-prebuilt.mjs; redact credentials in base.ts URLs; add flag value validation in changed-checks.mjs; pin GitHub Actions to commit SHAs and set persist-credential...
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Заголовок четко отражает основное изменение: оптимизация производительности CI путем запуска проверок только для затронутых модулей.
Linked Issues check ✅ Passed PR полностью решает требование issue #432: реализован affected-check runner для lint/test/typecheck, добавлено кэширование ESLint, E2E оптимизирован для переиспользования prebuilt артефактов.
Out of Scope Changes check ✅ Passed Все изменения находятся в области действия: добавлен changed-checks скрипт, обновлены CI workflow и package.json для affected checks, оптимизирована E2E с prebuilt артефактами, заменен vibecode-linter на ESLint cache.
Description check ✅ Passed PR description is comprehensive, covering objectives, verification, and alignment with issue #432.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@skulidropek

Copy link
Copy Markdown
Member Author

Agent Plan Update

Branch: issue-432 at 13e4f66.

1. Plan

Source: codex - Captured: 2026-06-20T09:55:53.033Z

Issue #432: Affected-Only Checks For Tests And Linters

Summary

Key Changes

  • Add scripts/changed-checks.mjs with CLI:
    bun scripts/changed-checks.mjs <lint|lint:effect|test|typecheck|check> [--base <rev>] [--head <rev>] [--all] [--dry-run].
  • Planner behavior:
    • Parse root workspaces and each package manifest.
    • Map packages/<name>/** to the owning package.
    • Compute reverse dependency closure from workspace deps plus package pre* script references.
    • Skip docs-only changes unless they touch tooling/config.
    • Run full checks for root config/tooling changes: package.json, bun.lock, root tsconfig*, .github/**, scripts/**, and runner tests.
  • Execution rules:
    • lint: run existing package lint scripts for affected owning packages, preserving vibecode-linter semantics.
    • lint:effect: run affected package ESLint with --cache --cache-location .cache/eslint/<pkg>/ --cache-strategy content.
    • test: use Vitest related/file filtering for direct package source/test changes; run full affected package tests for config/dependency/global fallback cases.
    • typecheck: run owning packages plus transitive dependents.
    • check: compose affected typecheck, lint, and test.
  • Update .gitignore with .cache/.
  • Update .github/workflows/check.yml so PR jobs pass ${{ github.event.pull_request.base.sha }} and ${{ github.sha }} to the runner; keep full behavior for non-PR events.

Test Plan

  • Add planner unit tests covering docs-only skip, package source change, test-file change, package config change, root lockfile full fallback, unknown path full fallback, missing base fallback, and dependency closure.
  • Add dry-run assertions for exact command plans.
  • Validate locally:
    • bun run lint -- --dry-run --base HEAD~1
    • bun run lint:effect -- --dry-run --base HEAD~1
    • bun run test -- --dry-run --base HEAD~1
    • bun run check:all
  • Final proof run after implementation: bun run lint:all, bun run test:all, bun run typecheck:all.

Assumptions

2. Plan

Source: codex - Captured: 2026-06-20T09:57:02.458Z

Issue #432: Affected Checks Without Vibecode Linter

Summary

  • Decision: temporarily remove vibecode-linter from the main lint/test path.
  • Do not implement a custom linter now. The repo already has rich ESLint configs with the same core rules: complexity, max-lines, max-depth, suggest-members, TypeScript rules, Effect rules.
  • Add one simple changed-check runner that uses existing ESLint, TypeScript, Vitest, and Bun workspace scripts.

Key Changes

  • Replace package lint scripts that call vibecode-linter with direct ESLint commands using cache:
    eslint <paths> --cache --cache-location ../../.cache/eslint/<package>/ --cache-strategy content.
  • Keep lint:effect as a separate Effect-TS compliance gate.
  • Remove @ton-ai-core/vibecode-linter and package linter.config.json files once no scripts reference them.
  • Add .cache/ to .gitignore.
  • Add scripts/changed-checks.mjs:
    • computes changed files from --base/--head, CI PR env, or local git diff;
    • maps files to workspace packages;
    • expands affected packages through reverse workspace dependencies;
    • skips docs-only changes;
    • fails closed to full run for root/tooling/config changes.
  • Root commands become affected-by-default:
    lint, lint:effect, test, typecheck, check.
  • Full commands remain available:
    lint:all, lint:effect:all, test:all, typecheck:all, check:all.

Test Plan

  • Add unit tests for the pure planner: docs-only skip, package source change, test-file change, root config full fallback, package config fallback, dependency closure, unknown path fallback.
  • Add dry-run tests for exact command output.
  • Validate:
    bun run lint -- --dry-run --base HEAD~1
    bun run test -- --dry-run --base HEAD~1
    bun run check:all
  • CI PR jobs use affected checks; push to main and workflow_dispatch keep full checks.

Assumptions

3. Plan

Source: codex - Captured: 2026-06-20T09:58:24.140Z

Codex Plan

Steps

  • in_progress: Audit current scripts, deps, and git state
  • pending: Add changed-checks runner and tests
  • pending: Switch lint scripts from vibecode to ESLint cache
  • pending: Update CI workflow for affected PR checks
  • pending: Run validation and fix failures

4. Plan

Source: codex - Captured: 2026-06-20T10:02:57.164Z

Codex Plan

Steps

  • completed: Audit current scripts, deps, and git state
  • completed: Add changed-checks runner and tests
  • in_progress: Switch lint scripts from vibecode to ESLint cache
  • pending: Update CI workflow for affected PR checks
  • pending: Run validation and fix failures

5. Plan

Source: codex - Captured: 2026-06-20T10:04:05.366Z

Codex Plan

Steps

  • completed: Audit current scripts, deps, and git state
  • completed: Add changed-checks runner and tests
  • completed: Switch lint scripts from vibecode to ESLint cache
  • in_progress: Update CI workflow for affected PR checks
  • pending: Run validation and fix failures

6. Plan

Source: codex - Captured: 2026-06-20T10:04:57.390Z

Codex Plan

Steps

  • completed: Audit current scripts, deps, and git state
  • completed: Add changed-checks runner and tests
  • completed: Switch lint scripts from vibecode to ESLint cache
  • completed: Update CI workflow for affected PR checks
  • in_progress: Run validation and fix failures

7. Plan

Source: codex - Captured: 2026-06-20T10:31:46.394Z

Codex Plan

Steps

  • in_progress: Inspect current runner and CI shape
  • pending: Add module-level parallel execution support
  • pending: Update CI to split affected modules
  • pending: Update planner tests
  • pending: Run validation

8. Plan

Source: codex - Captured: 2026-06-20T10:32:56.757Z

Codex Plan

Steps

  • completed: Inspect current runner and CI shape
  • in_progress: Add module-level parallel execution support
  • pending: Update CI to split affected modules
  • pending: Update planner tests
  • pending: Run validation

9. Plan

Source: codex - Captured: 2026-06-20T10:34:41.234Z

Codex Plan

Steps

  • completed: Inspect current runner and CI shape
  • completed: Add module-level parallel execution support
  • completed: Update CI to split affected modules
  • in_progress: Update planner tests
  • pending: Run validation

10. Plan

Source: codex - Captured: 2026-06-20T10:36:36.290Z

Codex Plan

Steps

  • completed: Inspect current runner and CI shape
  • completed: Add module-level parallel execution support
  • completed: Update CI to split affected modules
  • completed: Update planner tests
  • in_progress: Run validation

11. Plan

Source: codex - Captured: 2026-06-20T10:40:12.189Z

Codex Plan

Steps

  • completed: Inspect current runner and CI shape
  • completed: Add module-level parallel execution support
  • completed: Update CI to split affected modules
  • completed: Update planner tests
  • completed: Run validation

12. Plan

Source: codex - Captured: 2026-06-20T09:53:46.473Z

Issue #432: changed-only lint/test tooling

Findings

  • Root scripts are in package.json: lint, lint:effect, test, typecheck run fixed package lists through bun run --filter; no changed-file logic.
  • CI repeats full package steps in check.yml: lint, test, lint-effect run package-by-package without diff gating.
  • Package tooling: app/terminal/container/lib use vibecode-linter src/; app/terminal also lint tests/ before vitest run; api uses eslint . + vitest run; session-sync has only lint:effect + vitest.
  • Existing changed-file pattern exists only in git hooks: git diff --cached --name-only -z --diff-filter=ACM in pre-commit and pre-commit-secret-guard.sh.
  • No existing lint/test cache implementation found. Cache-related repo code is mostly product/runtime or clone-cache E2E, not tooling. .gitignore also does not ignore .cache/ or .eslintcache.

Recommended Changes

  • Add one central Bun script, e.g. scripts/changed-checks.mjs, as the single source of truth for:
    • computing changed files from --base, CI PR base SHA, or local git diff + untracked files;
    • mapping packages/<name>/** to workspace packages;
    • falling back to full checks when root/tooling config changes (package.json, bun.lock, tsconfig*, eslint*, scripts/**, .github/**).
  • Add root scripts:
    • lint:changed: run vibecode-linter only on changed src/ or tests/ files, grouped by package;
    • lint:effect:changed: run eslint --cache --cache-location .cache/eslint/<pkg>/ --cache-strategy content on changed files, or full package effect lint for config changes;
    • test:changed: run Vitest changed/related tests for affected packages; run full tests for transitive dependent packages when a workspace package source changes;
    • optional check:changed: compose changed lint + effect lint + tests.
  • Add .cache/ or .eslintcache to .gitignore if ESLint cache is stored in-repo.
  • Update CI lint/test/lint-effect jobs to call the changed runner on PRs. Keep full existing commands for push to main unless the issue owner explicitly wants main pushes changed-only too.

Impact Rules

  • Lint only the owning package for changed source/test files.
  • Tests run for the owning package plus transitive dependents from workspace deps: session-sync -> app/lib/api, container -> lib/api, terminal -> app/api, lib -> api, openapi -> app.
  • Docs-only changes skip lint/test unless they touch tooling/config paths.

Test Plan

  • Unit-test the pure path-to-plan mapper: docs-only skip, package source change, test-file change, package config fallback, root config full fallback, dependency-closure cases.
  • Validate manually after implementation with rtk bun run lint:changed -- --base HEAD~1, rtk bun run lint:effect:changed -- --base HEAD~1, and rtk bun run test:changed -- --base HEAD~1.
  • Sources checked for supported flags: Vitest CLI, ESLint CLI, Bun filter.

13. Plan

Source: codex - Captured: 2026-06-20T09:52:54.169Z

Issue #432 Plan

Сейчас Full-Run

  • CI: .github/workflows/check.yml всегда гоняет все пакеты в jobs build, types, lint, test, lint-effect, плюс все Docker/E2E jobs.
  • Дублирующий gate: .github/workflows/checking-dependencies.yml снова делает packages/app build + bun run check:dist-deps-prune.
  • Final gates: .github/workflows/final-build.yml делает bun run build, web smoke и focused vitest на 3 OS; snapshot.yml всегда билдит/пакует packages/app.
  • Локально full-run scripts: bun run build, check, typecheck, lint, lint:effect, test, e2e; внутри пакетов это tsc, vibecode-linter src/, eslint ., vitest run.

Куда Подключать Changed-Only/Cache

  • Добавить один selector/planner для CI/local: вычисляет changed files от PR base, мапит их в affected packages и reverse-dependents, затем запускает существующие package scripts через bun run --filter <pkg> <script>.
  • Подключить selector в root scripts: check:affected, typecheck:affected, lint:affected, lint-effect:affected, test:affected; full scripts оставить как fallback.
  • В check.yml заменить ручные package steps в types/lint/test/lint-effect/build на affected matrix или conditional steps.
  • В .github/actions/setup/action.yml добавить dependency cache для Bun install cache, keyed by OS + Bun version + bun.lock + package manifests.
  • E2E/Docker jobs не делать package-only: включать по path filters для Dockerfile, compose, packages/api, packages/app, packages/container, packages/lib, scripts/e2e, entrypoint.sh, workflows/actions.

Edge Cases

  • Root/global changes must force full run: package.json, bun.lock, bunfig.toml, tsconfig.base.json, shared eslint config, scripts/npx, package manifests, workflows/actions.
  • Dependency graph must include dependents: container -> lib -> api, terminal -> app/api, openapi -> app, session-sync -> app плюс package prebuild/pretest dependencies.
  • workflow_dispatch, push to main, missing merge-base, shallow checkout, rename/delete, or unknown path should fail closed to full run.
  • Package-specific config changes (tsconfig, vitest.config, eslint*.mjs, vite*.ts) affect that package and its dependents.
  • Keep session-sync optional script behavior; selector must skip absent scripts, not fail incorrectly.

Test Plan

  • Unit/golden tests for selector: package-only change, shared config full fallback, root lockfile full fallback, docs-only skip, rename/delete, missing base fallback.
  • Dry-run local cases showing selected commands without running full suite.
  • Compare affected output against current full commands for representative changes.
  • CI proof PRs: docs-only skips heavy jobs; app-only runs app checks; terminal/container changes include dependents; root/package change runs full.
  • Final validation after implementation: full bun run check, bun run lint, bun run test, and targeted E2E/Docker job for changed Docker paths.

SOURCE: n/a

@skulidropek

skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 13e4f66
Status: success
Files: 6 (4.26 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek

Copy link
Copy Markdown
Member Author

Agent Plan Update

Branch: issue-432 at e0e029e.

1. Plan

Source: codex - Captured: 2026-06-20T11:48:23.377Z

План: build-once artifact для E2E

Summary

  • На GitHub-hosted runners нельзя запустить один live-проект в одном job и подключить к нему параллельные jobs: каждый job получает отдельную VM.
  • Поэтому делаем безопасный вариант: один e2e-prepare job собирает E2E payload один раз, загружает artifact, а E2E jobs параллельно скачивают его и запускают тесты без повторного bun install и rebuild.
  • Каждый E2E job по-прежнему поднимает свои Docker-контейнеры локально, чтобы сохранить изоляцию тестов.

Key Changes

  • В .github/workflows/check.yml добавить e2e-prepare:

    • checkout с submodules;
    • обычный setup с bun install;
    • build CLI: bun run --cwd packages/app build:docker-git:reuse-install;
    • build browser frontend для browser E2E;
    • upload artifact docker-git-e2e-prebuilt с packages/app/dist, нужными package dist, manifest-файлами и минимальной runtime-зависимостью node_modules/@gridland/bun.
  • В .github/actions/setup/action.yml добавить input install-dependencies, default true:

    • true: текущее поведение;
    • false: ставит только runtime tooling, но не делает bun install --frozen-lockfile.
  • В scripts/e2e/_lib.sh добавить режим DOCKER_GIT_E2E_USE_PREBUILT_CLI=1:

    • проверяет наличие packages/app/dist/src/docker-git/main.js;
    • пропускает dg_prepare_bun_workspace и dg_build_docker_git_cli;
    • если artifact неполный, падает с понятной ошибкой;
    • локальное поведение без env остается прежним.
  • Для browser E2E добавить DOCKER_GIT_E2E_USE_PREBUILT_WEB=1:

    • если web build уже в artifact, не запускать повторный bun run --cwd packages/app build:web;
    • при отсутствии prebuilt web dist падать явно.
  • Все E2E jobs сделать needs: e2e-prepare:

    • checkout;
    • setup с install-dependencies: false;
    • download artifact;
    • запуск текущих scripts/e2e/*.sh параллельно.

Test Plan

  • Проверить shell scripts: bash -n scripts/e2e/_lib.sh scripts/e2e/*.sh.
  • Проверить сборку artifact payload:
    • bun run --cwd packages/app build:docker-git:reuse-install;
    • build web frontend, если browser E2E его использует.
  • Локальный smoke:
    • DOCKER_GIT_E2E_USE_PREBUILT_CLI=1 bun packages/app/dist/src/docker-git/main.js --help;
    • при доступном Docker прогнать один E2E script в prebuilt-режиме.
  • CI verification:
    • gh run watch --exit-status;
    • ожидаем: e2e-prepare один раз делает install/build, E2E jobs параллельно используют artifact, повторного bun install в E2E jobs нет.

Assumptions

  • Остаемся на GitHub-hosted runners.
  • Не делаем shared live runtime в этом PR, потому что job isolation делает это невозможным без self-hosted runner или внешнего сервиса.
  • Цель v1: убрать повторную установку JS dependencies и повторную сборку проекта для E2E.
  • Имена существующих E2E checks сохраняются, чтобы не ломать required checks.

@skulidropek

skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: e0e029e
Status: success
Files: 6 (5.62 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 0e94cec
Status: success
Files: 7 (7.48 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek

Copy link
Copy Markdown
Member Author

Agent Plan Update

Branch: issue-432 at 22d4c58.

1. Plan

Source: codex - Captured: 2026-06-20T13:13:16.916Z

Ускорение E2E Через Reusable Project Image

Summary

  • Текущие 6-8 минут остаются потому, что controller image уже переиспользуется, но каждый E2E job всё ещё заново строит project container через docker compose up -d --build.
  • Сделать CI-only fast path: e2e-prepare собирает docker-git-e2e-project:latest один раз, fanout jobs только скачивают/docker load и запускают проекты без build.
  • Полностью убрать download/load нельзя: GitHub Actions fanout jobs живут на разных VM без общего Docker daemon.

Key Changes

  • Добавить в TemplateConfig опциональное imageName?: string; публичный API CreateProjectRequest не менять.
  • В renderDockerCompose: по умолчанию оставить build: .; если imageName задан, рендерить image: <imageName> + pull_policy: never и не рендерить build: ..
  • В create path добавить внутренний dockerComposeUpBuildMode?: "build" | "reuse" и прокинуть его до runDockerUpIfNeeded; для force в reuse mode делать cleanup, но запускать docker compose up -d без --build.
  • Через env DOCKER_GIT_E2E_PROJECT_IMAGE=docker-git-e2e-project:latest в API controller включать config.imageName и buildMode: "reuse".
  • Сделать TARGET_DIR runtime-источником истины в managed AGENTS/Claude/Gemini/Grok текстах, чтобы один image корректно работал для issue/pr target dirs.

CI Changes

  • Добавить scripts/ci/build-e2e-project-image.ts: через существующие template/writeProjectFiles собрать generic project Docker context, затем docker build -t docker-git-e2e-project:latest.
  • В e2e-prepare сохранить docker-git-e2e-project-image.tar.gz отдельным artifact.
  • Во всех Docker-heavy E2E jobs скачать/load project image перед тестом и выставить DOCKER_GIT_E2E_PROJECT_IMAGE.
  • В логах fanout jobs ожидать docker compose up -d, без apt/npm/bun/opencode build output.

Test Plan

  • bun run --cwd packages/container test -- tests/core/templates.test.ts
  • bun run --cwd packages/lib test -- tests/usecases/docker-up-force.test.ts tests/shell/config.test.ts
  • bun run --cwd packages/api test -- tests/projects.test.ts
  • bun run --cwd packages/container build && bun run --cwd packages/lib build && bun run --cwd packages/api build
  • После push: проверить PR perf(ci): run affected checks by module #435 через gh pr checks --watch; acceptance: project image строится только в E2E prepare, fanout E2E не выполняет project image rebuild.

2. Plan

Source: codex - Captured: 2026-06-20T13:13:45.535Z

Codex Plan

Steps

  • completed: Inspect create/up/template integration points
  • in_progress: Add reusable project image support in templates/config/create path
  • pending: Add CI project image build/load workflow path
  • pending: Add focused tests for compose rendering and reuse create path
  • pending: Run targeted verification and report outcome

3. Plan

Source: codex - Captured: 2026-06-20T13:19:48.301Z

Codex Plan

Steps

  • completed: Inspect create/up/template integration points
  • completed: Add reusable project image support in templates/config/create path
  • completed: Add CI project image build/load workflow path
  • in_progress: Add focused tests for compose rendering and reuse create path
  • pending: Run targeted verification and report outcome

@skulidropek

skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 22d4c58
Status: success
Files: 7 (9.01 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 1e24564
Status: success
Files: 8 (10.19 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 210d8fb
Status: success
Files: 8 (10.60 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@skulidropek

skulidropek commented Jun 20, 2026

Copy link
Copy Markdown
Member Author

AI Session Backup

Commit: 3d856f4
Status: success
Files: 8 (10.71 MB)
Links: README | Manifest

git status

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

nothing to commit, working tree clean

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🤖 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/workflows/check.yml:
- Around line 124-132: The aggregator checks only verify the MODULE_RESULT but
do not check if the upstream plan-checks job failed. When plan-checks fails,
dependent jobs become skipped rather than failed, causing the aggregators to
incorrectly pass. Add checks for the plan-checks job result in addition to the
MODULE_RESULT comparison in all four aggregator jobs (Check typecheck module
results, Check linter module results, Check test module results, and Check e2e
module results) to ensure they fail if either the upstream plan-checks or the
module job fails or is cancelled.
- Around line 71-73: Pin all external GitHub Actions in the workflow file to
specific commit SHAs instead of version tags (e.g., replace `@v6` with a full
commit hash) to prevent supply-chain attacks. Additionally, add
persist-credentials: false to all actions/checkout steps to disable unnecessary
credential storage in the git config during workflow execution. Apply these
changes to all instances of actions/checkout and other external actions
throughout the file at the specified line ranges including 71-73, 111, 144, 177,
210, 241-243, 282-293, 321-339, 370-388, 419-437, 468-486, 517-535, and 566-584.

In `@packages/app/src/docker-git/browser-frontend-prebuilt.ts`:
- Around line 16-29: Refactor the direct process access calls in
shouldUsePrebuiltBrowserFrontend and ensurePrebuiltBrowserFrontend to use a
Layer-based service instead of calling process.env and process.cwd() directly.
Create a RuntimeConfig Layer that provides getEnv() and getCwd() methods, then
update shouldUsePrebuiltBrowserFrontend to either return an Effect that uses
Effect.gen to access the config service, or make it accept the environment value
as a parameter. For ensurePrebuiltBrowserFrontend, update the runCommandExitCode
call to obtain the cwd through the RuntimeConfig service via Effect.gen rather
than calling process.cwd() directly.

In `@packages/app/tests/docker-git/changed-checks.test.ts`:
- Around line 95-187: The test suite for the "changed-checks planner" describe
block currently uses only example-based tests and lacks property-based invariant
testing. Add property-based tests using fast-check's fc.property to verify three
key invariants: first, that docs-only file changes result in skip mode; second,
that unknown or global root file changes result in all mode; third, that
delete-only changes within a package do not produce skip mode (this should
include a specific reproducing test case for the delete-only diff bug that was
discovered). Ensure each property test documents the root cause and fix as a
comment following the coding guidelines for test files.

In `@packages/container/src/core/templates-entrypoint/base.ts`:
- Around line 66-79: The function renderEntrypointProjectRuntimeEnv is
persisting REPO_URL and FORK_REPO_URL directly to environment files without
removing potentially embedded credentials (like auth tokens in the format
https://token@host). Before writing these URLs to the DOCKER_GIT_PROJECT_PROFILE
file or passing them to docker_git_upsert_ssh_env calls, sanitize them by
removing any userinfo components that may contain sensitive credentials. Ensure
the sanitized versions are used in both the printf statements for the profile
file and the docker_git_upsert_ssh_env function calls for REPO_URL and
FORK_REPO_URL.

In `@packages/container/tests/core/templates.test.ts`:
- Around line 984-995: The test "renders an explicit prebuilt image without a
build section" currently only verifies a single hardcoded case. Replace or
enhance this test to use property-based testing with fast-check to verify the
mathematical invariant for build/image selection: when an imageName is provided
to makeTemplateConfig, the rendered compose output must always contain image and
pull_policy: never while never containing build: .; conversely, when no
imageName is provided, the opposite should hold. This approach will verify the
contract across multiple generated test cases rather than relying on a single
fixed value.

In `@scripts/changed-checks.mjs`:
- Around line 375-387: The flags `--concurrency`, `--base`, and `--head`
currently accept missing or invalid values without validation, causing ambiguous
CLI behavior. For each of these three flag handlers in the argument parsing
section, add validation to check that the next argument exists in the rest array
and is not another flag (does not start with "--"), and throw an explicit error
with the message "Missing value for [flag-name]" if the validation fails. This
validation should happen before assigning the parsed value to ensure required
arguments are always provided.

In `@scripts/ci/pack-e2e-prebuilt.mjs`:
- Around line 23-43: The addExistingPath function resolves paths that may be
symlinks, but does not validate that the resolved path stays within the repoRoot
boundary. This allows paths with `../` to escape the repository and be included
in the tar archive. After resolving the path with resolve(repoRoot, path) and
computing the relative path with toRelativePath, validate that the resolved
absolute path actually starts with repoRoot (after normalization) before adding
it to the paths collection. If the resolved path is outside repoRoot, call fail
to reject it with an appropriate error message about path traversal.

In `@scripts/npx`:
- Line 5: The script has a path traversal vulnerability where the user-supplied
command_name variable is embedded directly into the node_modules/.bin path
without validation, allowing attackers to use sequences like ../ to escape the
intended directory. Add validation to the $command_name variable to ensure it
only contains alphanumeric characters, hyphens, and underscores before it is
used in the path construction on line 41. Reject any input containing forward
slashes, double dots, or other special characters by checking the variable
against a whitelist pattern and exiting early if validation fails.
🪄 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: ec771cfd-8b54-4fe4-8cf3-f4c5f1663902

📥 Commits

Reviewing files that changed from the base of the PR and between f601d55 and 3d856f4.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (49)
  • .github/actions/setup/action.yml
  • .github/workflows/check.yml
  • .gitignore
  • docker-compose.yml
  • experiments/terminal-query-suppression.md
  • package.json
  • packages/api/package.json
  • packages/api/src/services/projects.ts
  • packages/api/tests/projects.test.ts
  • packages/app/linter.config.json
  • packages/app/package.json
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/container/linter.config.json
  • packages/container/package.json
  • packages/container/src/core/domain.ts
  • packages/container/src/core/templates-entrypoint.ts
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/container/tests/core/templates.test.ts
  • packages/docker-git-session-sync/package.json
  • packages/lib/linter.config.json
  • packages/lib/package.json
  • packages/lib/src/core/domain.ts
  • packages/lib/src/shell/config.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/lib/src/usecases/projects-up.ts
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/terminal/linter.config.json
  • packages/terminal/package.json
  • patches/@ton-ai-core__vibecode-linter@1.0.6.patch
  • scripts/changed-checks.d.mts
  • scripts/changed-checks.mjs
  • scripts/ci/build-e2e-project-image.ts
  • scripts/ci/pack-e2e-prebuilt.mjs
  • scripts/e2e/_lib.sh
  • scripts/e2e/browser-command.sh
  • scripts/npx
💤 Files with no reviewable changes (5)
📜 Review details
⏰ Context from checks skipped due to timeout. (6)
  • GitHub Check: Types
  • GitHub Check: Lint (@prover-coder-ai/docker-git lint)
  • GitHub Check: Lint (@prover-coder-ai/docker-git lint:tests)
  • GitHub Check: Test (@prover-coder-ai/docker-git test)
  • GitHub Check: E2E prepare
  • GitHub Check: Final build (windows-latest)
🧰 Additional context used
📓 Path-based instructions (18)
**/*.{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/container/src/core/templates-entrypoint.ts
  • packages/lib/src/core/domain.ts
  • packages/container/src/core/domain.ts
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • scripts/e2e/browser-command.sh
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • scripts/e2e/_lib.sh
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • packages/lib/src/usecases/projects-up.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/container/src/core/templates-entrypoint.ts
  • packages/lib/src/core/domain.ts
  • packages/container/src/core/domain.ts
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • scripts/e2e/browser-command.sh
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • scripts/e2e/_lib.sh
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • packages/lib/src/usecases/projects-up.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/container/src/core/templates-entrypoint.ts
  • packages/lib/src/core/domain.ts
  • docker-compose.yml
  • packages/container/src/core/domain.ts
  • packages/docker-git-session-sync/package.json
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • scripts/e2e/browser-command.sh
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • packages/api/package.json
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/package.json
  • packages/terminal/package.json
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/package.json
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • package.json
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • packages/container/package.json
  • scripts/e2e/_lib.sh
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • packages/lib/src/usecases/projects-up.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: FUNCTIONAL CORE: Write only pure functions with immutable data and mathematical operations in core modules; no side effects, mutations, or external service calls
IMPERATIVE SHELL: Isolate all side effects (IO, network, database, environment/process) in a thin SHELL layer; CORE never calls SHELL, only SHELL → CORE
Never use any type annotation in TypeScript; use unknown only at SHELL boundaries for decoding, never export unknown outside boundary modules
Never use as type assertions in normal code; only permit as in a single 'axiomatic' module (brands, constructors, constants) after which types flow safely without casts
Always use exhaustive pattern matching for union types through .exhaustive() or Match.exhaustive() from effect-ts; never use switch statements or unhandled type branches
Use Effect<Success, Error, Requirements> monad from effect-ts for all effects; compose through pipe() and Effect.flatMap(); never use async/await, raw Promise chains (then/catch), or Promise.all in product code
Interoperate with Promise/exceptions only in SHELL through Effect.try/Effect.tryPromise with typed error mapping; never leave raw exceptions or untyped errors in the domain
Use Effect.acquireRelease + Effect.scoped for resource management with guaranteed finalization; never manage resources with try/finally or manual cleanup
All external services (database, HTTP, environment) must be accessed through Effect-based interfaces and Layer-based dependency injection; never call external APIs directly
Provide comprehensive TSDoc comments with mathematical notation: @pure, @effect, @invariant, @precondition, @postcondition, @complexity, @throws, and CHANGE/WHY/REF/SOURCE/FORMAT THEOREM functional comment markers
No console.*, process direct calls, or untyped environment access in product code; all such operations must be abstracted through Layer-based services in SHELL
Boundary data from external sources (HTTP, database, environment) must be decoded/valida...

Files:

  • packages/container/src/core/templates-entrypoint.ts
  • packages/lib/src/core/domain.ts
  • packages/container/src/core/domain.ts
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • packages/lib/src/usecases/projects-up.ts
**/{browser*,server*,app*,*.ts,*.js}

📄 CodeRabbit inference engine (README.md)

Web version must listen on 0.0.0.0 by default for accessibility across LAN devices

Files:

  • packages/container/src/core/templates-entrypoint.ts
  • packages/lib/src/core/domain.ts
  • packages/container/src/core/domain.ts
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • scripts/e2e/browser-command.sh
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • packages/lib/src/usecases/projects-up.ts
**/{cli*,command*,auto*,*.ts,*.tsx}

📄 CodeRabbit inference engine (README.md)

Implement auto-mode agent selection logic to choose Claude, Codex, Gemini, or Grok randomly from available authorized providers, or allow forced selection with --auto=

Files:

  • packages/container/src/core/templates-entrypoint.ts
  • packages/lib/src/core/domain.ts
  • packages/container/src/core/domain.ts
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • packages/lib/src/usecases/projects-up.ts
**/*

⚙️ CodeRabbit configuration file

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

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

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

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

Files:

  • packages/container/src/core/templates-entrypoint.ts
  • experiments/terminal-query-suppression.md
  • scripts/npx
  • packages/lib/src/core/domain.ts
  • docker-compose.yml
  • packages/container/src/core/domain.ts
  • packages/docker-git-session-sync/package.json
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • scripts/e2e/browser-command.sh
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • scripts/changed-checks.d.mts
  • scripts/ci/pack-e2e-prebuilt.mjs
  • packages/api/package.json
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/package.json
  • packages/terminal/package.json
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/package.json
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • package.json
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • packages/container/package.json
  • scripts/e2e/_lib.sh
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • scripts/changed-checks.mjs
  • packages/lib/src/usecases/projects-up.ts
**

⚙️ CodeRabbit configuration file

**: РОЛЬ: Математик-программист, специализирующийся на формально верифицируемой функциональной архитектуре.

ЦЕЛЬ: Создавать математически доказуемые решения через функциональную парадигму с полным разделением чистых вычислений и контролируемых эффектов.

МОДЕЛЬ РАССУЖДЕНИЯ:

  • Не выдавать “личные мнения”. Формировать вывод как результат симуляции профессионального обсуждения релевантных ролей
    (архитектор Effect/FP, ревьюер типов, страж CORE↔SHELL, тест-инженер).
  • Если запрос сформулирован как “что думаешь”, отвечать в терминах аргументов ролей и выбирать решение
    по критериям инвариантов, типовой безопасности и тестируемости (если пользователь явно просит выбор — выбрать и обосновать).

ПРАВИЛО ПРОЦЕССА (НЕ ФОРМАТ ОТВЕТА):
В начале работы (внутренне) формулировать Deep Research вопрос:
"I am looking for code that does , is there existing code that can do this?"
Далее:

  • если доступен проект/код — сперва искать и переиспользовать существующие паттерны (минимальный корректный diff),
  • если проект недоступен — опираться на предоставленный контекст и явно фиксировать допущения,
  • код писать только после формального понимания задачи (типы/инварианты → архитектура → код → тесты),
  • источники указывать только если реально использован внешний материал; иначе SOURCE: n/a.

ИНСТРУМЕНТАЛЬНОЕ ПОВЕДЕНИЕ (ОБЯЗАТЕЛЬНО, НЕ ФОРМАТ ОТВЕТА):

  • Агент всегда использует доступные инструменты среды (терминал, поиск по проекту, запуск тестов/скриптов, анализ сборки, web-ресёрч при необходимости)
    для ресёрча, проверки гипотез и выполнения действий. Приоритет: проверяемость, воспроизводимость, минимальный риск.
  • Агент не предлагает “гайд” как замену действия. Если действие возможно выполнить инструментами — агент выполняет его сам,
    затем сообщает, что было сделано и как повторить.
  • Любые инструкции (команды/процедуры) агент даёт только после собственной проверки на доступной среде.
    Если проверить невозможно — явно фиксирует ограничение и перечисляе...

Files:

  • packages/container/src/core/templates-entrypoint.ts
  • experiments/terminal-query-suppression.md
  • scripts/npx
  • packages/lib/src/core/domain.ts
  • docker-compose.yml
  • packages/container/src/core/domain.ts
  • packages/docker-git-session-sync/package.json
  • scripts/ci/build-e2e-project-image.ts
  • packages/container/src/core/templates-entrypoint/base.ts
  • packages/lib/src/usecases/actions/create-project.ts
  • packages/api/tests/projects.test.ts
  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • scripts/e2e/browser-command.sh
  • packages/container/src/core/templates-entrypoint/codex-resume-hint.ts
  • packages/lib/src/shell/config.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • scripts/changed-checks.d.mts
  • scripts/ci/pack-e2e-prebuilt.mjs
  • packages/api/package.json
  • packages/api/src/services/projects.ts
  • packages/container/src/core/templates-entrypoint/gemini.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates-entrypoint/grok.ts
  • packages/app/package.json
  • packages/terminal/package.json
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/package.json
  • packages/lib/tests/usecases/docker-up-force.test.ts
  • packages/container/src/core/templates/docker-compose.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • package.json
  • packages/container/src/core/templates-entrypoint/agents-notice.ts
  • packages/container/package.json
  • scripts/e2e/_lib.sh
  • packages/app/src/docker-git/browser-frontend.ts
  • packages/lib/src/usecases/actions/docker-up.ts
  • packages/container/src/core/templates-entrypoint/claude-extra-config.ts
  • scripts/changed-checks.mjs
  • packages/lib/src/usecases/projects-up.ts
**/{setup,install,config,*.sh,*.md}

📄 CodeRabbit inference engine (README.md)

Ensure default projects directory is ~/.docker-git

Files:

  • experiments/terminal-query-suppression.md
  • scripts/e2e/browser-command.sh
  • scripts/e2e/_lib.sh
.gitignore

📄 CodeRabbit inference engine (AGENTS.md)

Ensure .gitignore includes node_modules, dist, build, .env, and other sensitive/build artifacts; version control only source code and configuration templates

Files:

  • .gitignore
**/{.git*,config*,*.sh,docker-compose*}

📄 CodeRabbit inference engine (README.md)

Use git credential helper to automatically select correct token by host for HTTPS clone/push operations

Files:

  • .gitignore
  • docker-compose.yml
  • scripts/e2e/browser-command.sh
  • packages/lib/src/shell/config.ts
  • packages/lib/src/shell/docker-compose.ts
  • packages/container/src/core/templates/docker-compose.ts
  • scripts/e2e/_lib.sh
**/{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
**/{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/docker-git-session-sync/package.json
  • packages/api/package.json
  • packages/app/package.json
  • packages/terminal/package.json
  • packages/lib/package.json
  • package.json
  • packages/container/package.json
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.test.{ts,tsx}: Write property-based tests using fast-check (fc.property) to verify mathematical invariants; unit tests must use Effect test utilities without async/await
Every bug fix must be accompanied by a reproducing test case; the test must fail before the fix and pass after; document the Proof of Fix with root cause and solution

Files:

  • packages/api/tests/projects.test.ts
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/container/tests/core/templates.test.ts
  • packages/lib/tests/usecases/projects-up.test.ts
  • packages/app/tests/docker-git/changed-checks.test.ts
  • packages/lib/tests/usecases/docker-up-force.test.ts
**/{browser*,server*,.env*,*.sh}

📄 CodeRabbit inference engine (README.md)

Allow DOCKER_GIT_WEB_HOST environment variable to restrict web access to 127.0.0.1

Files:

  • packages/app/src/docker-git/browser-frontend-prebuilt.ts
  • scripts/e2e/browser-command.sh
  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • scripts/e2e/_lib.sh
  • packages/app/src/docker-git/browser-frontend.ts
**/{.env*,auth*,config*,setup*}

📄 CodeRabbit inference engine (README.md)

Store authentication tokens in env-file as GIT_AUTH_TOKEN__ / GIT_AUTH_USER__

Files:

  • packages/lib/src/shell/config.ts
package.json

📄 CodeRabbit inference engine (AGENTS.md)

Dependencies must include effect ^3.x and @effect/schema ^0.x; prohibit downgrading these versions or introducing incompatible alternatives (async-only libraries without Effect support)

Require Effect and @effect/schema as mandatory dependencies for type-safe effects and validation

Files:

  • package.json
**/.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 (3)
📚 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-prebuilt.ts
  • packages/app/src/docker-git/browser-frontend-launch.ts
  • packages/app/src/docker-git/browser-frontend.ts
📚 Learning: 2026-06-10T10:21:51.286Z
Learnt from: konard
Repo: ProverCoderAI/docker-git PR: 386
File: packages/app/tests/docker-git/gridland-react-singleton.test.ts:0-0
Timestamp: 2026-06-10T10:21:51.286Z
Learning: In `packages/app/tests/docker-git` tests that inspect the `packages/terminal` workspace (e.g., for React-related versions), remember that `react-dom` is intentionally declared as a `devDependency` in `packages/terminal` (the terminal exports components but does not render to the DOM itself). Therefore, test assertions should not require `react-dom` to appear in `dependencies`; when resolving versions, accept either `dependencies` or `devDependencies` (as `resolveDepVersion` does in `gridland-react-singleton.test.ts`).

Applied to files:

  • packages/app/tests/docker-git/browser-frontend.test.ts
  • packages/app/tests/docker-git/changed-checks.test.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/projects.ts
🪛 zizmor (1.25.2)
.github/workflows/check.yml

[warning] 71-73: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 111-111: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 144-144: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 177-177: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 210-210: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 241-243: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 115-115: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 115-115: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 148-148: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 148-148: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 181-181: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 181-181: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 214-214: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[warning] 214-214: code injection via template expansion (template-injection): may expand into attacker-controllable code

(template-injection)


[error] 71-71: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 111-111: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 144-144: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 177-177: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 210-210: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 241-241: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 282-282: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 287-287: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 293-293: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[warning] 321-323: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 370-372: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 419-421: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 468-470: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 517-519: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[warning] 566-568: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 321-321: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 329-329: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 334-334: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 339-339: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 370-370: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 378-378: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 383-383: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 388-388: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 419-419: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 427-427: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 432-432: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 437-437: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 468-468: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 476-476: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 481-481: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 486-486: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 517-517: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 525-525: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 530-530: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 535-535: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 566-566: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 574-574: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 579-579: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)


[error] 584-584: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🔇 Additional comments (29)
.gitignore (1)

17-19: Проблем не выявлено в этом фрагменте.

packages/app/package.json (1)

27-30: Проблем не выявлено в этом фрагменте.

packages/container/package.json (1)

13-14: Проблем не выявлено в этом фрагменте.

packages/terminal/package.json (1)

14-16: Проблем не выявлено в этом фрагменте.

packages/lib/package.json (1)

15-19: Проблем не выявлено в этом фрагменте.

packages/api/package.json (1)

17-20: Проблем не выявлено в этом фрагменте.

packages/docker-git-session-sync/package.json (1)

15-15: Проблем не выявлено в этом фрагменте.

experiments/terminal-query-suppression.md (1)

100-101: Проблем не выявлено в этом фрагменте.

scripts/changed-checks.d.mts (1)

1-60: LGTM!

package.json (1)

24-25: LGTM!

Also applies to: 51-61

.github/actions/setup/action.yml (1)

12-15: LGTM!

Also applies to: 63-63

scripts/changed-checks.mjs (1)

414-417: Unable to complete verification: The original verification request does not contain an actual review comment to rewrite. Only coding guidelines and architectural standards are provided. Please supply the specific review comment that needs to be verified and rewritten.

packages/container/src/core/domain.ts (1)

81-81: LGTM!

packages/container/src/core/templates/docker-compose.ts (1)

52-59: LGTM!

Also applies to: 127-131, 252-252

packages/container/src/core/templates-entrypoint/codex-resume-hint.ts (1)

15-15: LGTM!

Also applies to: 85-85

packages/container/src/core/templates-entrypoint/agents-notice.ts (1)

14-17: LGTM!

Also applies to: 133-136

packages/container/src/core/templates-entrypoint/claude-extra-config.ts (1)

55-58: LGTM!

Also applies to: 100-101

packages/container/src/core/templates-entrypoint/gemini.ts (1)

309-312: LGTM!

Also applies to: 341-343

packages/container/src/core/templates-entrypoint/grok.ts (1)

297-300: LGTM!

Also applies to: 324-327

packages/app/src/docker-git/browser-frontend-launch.ts (1)

20-37: Дубликат: здесь тот же паттерн прямого process.*, уже отмеченный в packages/app/src/docker-git/browser-frontend-prebuilt.ts как корневая проблема.

Also applies to: 51-51

packages/lib/src/shell/config.ts (1)

90-91: LGTM!

packages/lib/src/core/domain.ts (1)

92-92: LGTM!

packages/lib/src/usecases/actions/docker-up.ts (1)

60-60: LGTM!

Also applies to: 186-217, 262-268

packages/lib/src/shell/docker-compose.ts (1)

119-136: LGTM!

packages/lib/src/usecases/projects-up.ts (1)

53-54: LGTM!

Also applies to: 227-230

packages/lib/src/usecases/actions/create-project.ts (1)

184-185: LGTM!

scripts/ci/build-e2e-project-image.ts (1)

1-47: LGTM!

scripts/e2e/_lib.sh (1)

549-580: LGTM!

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

194-195: LGTM!

Comment on lines +71 to +73
- uses: actions/checkout@v6
with:
fetch-depth: 0

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 | 🟠 Major | ⚡ Quick win

Нужно закрепить внешние actions по commit SHA и отключить persist-credentials в checkout.

Сейчас uses: ...@v6/@v7 остаются плавающими, а checkout по умолчанию сохраняет токен в git-конфиге runner-а. Для workflow с активной работой с артефактами это лишний риск supply-chain/credential hygiene.

As per coding guidelines: "**/.github/workflows/*.{yml,yaml}: Fail if changed files introduce unsafe GitHub Actions configuration such as unsafe pull_request_target, or unnecessary write permissions".

Also applies to: 111-111, 144-144, 177-177, 210-210, 241-243, 282-293, 321-339, 370-388, 419-437, 468-486, 517-535, 566-584

🧰 Tools
🪛 zizmor (1.25.2)

[warning] 71-73: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)


[error] 71-71: unpinned action reference (unpinned-uses): action is not pinned to a hash (required by blanket policy)

(unpinned-uses)

🤖 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 @.github/workflows/check.yml around lines 71 - 73, Pin all external GitHub
Actions in the workflow file to specific commit SHAs instead of version tags
(e.g., replace `@v6` with a full commit hash) to prevent supply-chain attacks.
Additionally, add persist-credentials: false to all actions/checkout steps to
disable unnecessary credential storage in the git config during workflow
execution. Apply these changes to all instances of actions/checkout and other
external actions throughout the file at the specified line ranges including
71-73, 111, 144, 177, 210, 241-243, 282-293, 321-339, 370-388, 419-437, 468-486,
517-535, and 566-584.

Sources: Coding guidelines, Linters/SAST tools

Comment on lines +124 to +132
- name: Check typecheck module results
env:
MODULE_RESULT: ${{ needs.types-modules.result }}
run: |
if [ -f packages/docker-git-session-sync/package.json ]; then
bun run --cwd packages/docker-git-session-sync typecheck
else
echo "packages/docker-git-session-sync is not present; skipping"
if [[ "$MODULE_RESULT" == "failure" || "$MODULE_RESULT" == "cancelled" ]]; then
echo "Typecheck module job result: $MODULE_RESULT" >&2
exit 1
fi
- name: Typecheck (lib)
run: bun run --cwd packages/lib typecheck
- name: Typecheck (api)
run: bun run --cwd packages/api typecheck
echo "Typecheck module job result: $MODULE_RESULT"

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 | 🟠 Major | ⚡ Quick win

Агрегаторы могут дать ложный green при падении plan-checks.

На Line 124-132 (и аналогично Line 157-165, 190-198, 223-231) проверяется только MODULE_RESULT. Если plan-checks завершится failure, модульный job станет skipped, и агрегатор пройдет успешно.

Предлагаемый фикс (паттерн для всех 4 агрегаторов)
       - name: Check typecheck module results
         env:
+          PLAN_RESULT: ${{ needs.plan-checks.result }}
           MODULE_RESULT: ${{ needs.types-modules.result }}
         run: |
+          if [[ "$PLAN_RESULT" == "failure" || "$PLAN_RESULT" == "cancelled" ]]; then
+            echo "Plan-checks job result: $PLAN_RESULT" >&2
+            exit 1
+          fi
           if [[ "$MODULE_RESULT" == "failure" || "$MODULE_RESULT" == "cancelled" ]]; then
             echo "Typecheck module job result: $MODULE_RESULT" >&2
             exit 1
           fi
           echo "Typecheck module job result: $MODULE_RESULT"

Also applies to: 157-165, 190-198, 223-231

🤖 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 @.github/workflows/check.yml around lines 124 - 132, The aggregator checks
only verify the MODULE_RESULT but do not check if the upstream plan-checks job
failed. When plan-checks fails, dependent jobs become skipped rather than
failed, causing the aggregators to incorrectly pass. Add checks for the
plan-checks job result in addition to the MODULE_RESULT comparison in all four
aggregator jobs (Check typecheck module results, Check linter module results,
Check test module results, and Check e2e module results) to ensure they fail if
either the upstream plan-checks or the module job fails or is cancelled.

Comment on lines +16 to +29
export const shouldUsePrebuiltBrowserFrontend = (): boolean =>
isTruthyEnv(process.env["DOCKER_GIT_E2E_USE_PREBUILT_WEB"])

export const ensurePrebuiltBrowserFrontend = (): Effect.Effect<
void,
ControllerBootstrapError | PlatformError,
CommandExecutor.CommandExecutor
> =>
pipe(
runCommandExitCode({
args: ["-c", "test -f packages/app/dist-web/index.html"],
command: "sh",
cwd: process.cwd()
}),

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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Проверка прямых process-вызовов в новых browser frontend модулях
rg -n --type=ts '\bprocess\.(env|cwd)\b' \
  packages/app/src/docker-git/browser-frontend-prebuilt.ts \
  packages/app/src/docker-git/browser-frontend-launch.ts

Repository: ProverCoderAI/docker-git

Length of output: 532


🏁 Script executed:

#!/bin/bash
# Получить содержимое файлов для понимания контекста
echo "=== browser-frontend-prebuilt.ts ==="
cat -n packages/app/src/docker-git/browser-frontend-prebuilt.ts

echo -e "\n=== browser-frontend-launch.ts ==="
cat -n packages/app/src/docker-git/browser-frontend-launch.ts

Repository: ProverCoderAI/docker-git

Length of output: 5666


🏁 Script executed:

#!/bin/bash
# Поиск существующих Layer-based паттернов для Environment/Runtime
rg -A 5 "class.*Env.*extends.*Context\.Tag|class.*Runtime.*extends.*Context\.Tag" \
  packages/lib/src --type=ts | head -50

Repository: ProverCoderAI/docker-git

Length of output: 50


🏁 Script executed:

#!/bin/bash
# Поиск существующих паттернов использования process в SHELL слое
rg -B 2 -A 2 "process\.(env|cwd)" packages/lib/src --type=ts | head -80

Repository: ProverCoderAI/docker-git

Length of output: 6179


🏁 Script executed:

#!/bin/bash
# Проверить структуру проекта: где находится SHELL слой
find packages -name "*shell*" -o -name "*boundary*" -o -name "*layer*" | head -20

Repository: ProverCoderAI/docker-git

Length of output: 445


Абстрагируйте process.env и process.cwd() через Layer-based сервис вместо прямых обращений.

На линиях 17, 28 (файл browser-frontend-prebuilt.ts) и линиях 22, 51 (файл browser-frontend-launch.ts) добавлены прямые обращения к process.env и process.cwd().

Функция shouldUsePrebuiltBrowserFrontend() читает environment синхронно. Функции ensurePrebuiltBrowserFrontend() и runStreaming() — это Effect'ы, которые жёстко зависят от глобального процесса вместо полученной конфигурации.

Согласно архитектурным правилам: no process direct calls, or untyped environment access in product code; all such operations must be abstracted through Layer-based services.

Решение:

  • Создайте RuntimeConfig Layer с методами getEnv() и getCwd()
  • Передайте их как зависимости в Effect.gen() функции вместо прямых обращений к process
  • Для синхронного shouldUsePrebuiltBrowserFrontend() — либо сделайте его Effect, либо передавайте уже прочитанное значение из вызывающего кода
🤖 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/browser-frontend-prebuilt.ts` around lines 16 -
29, Refactor the direct process access calls in shouldUsePrebuiltBrowserFrontend
and ensurePrebuiltBrowserFrontend to use a Layer-based service instead of
calling process.env and process.cwd() directly. Create a RuntimeConfig Layer
that provides getEnv() and getCwd() methods, then update
shouldUsePrebuiltBrowserFrontend to either return an Effect that uses Effect.gen
to access the config service, or make it accept the environment value as a
parameter. For ensurePrebuiltBrowserFrontend, update the runCommandExitCode call
to obtain the cwd through the RuntimeConfig service via Effect.gen rather than
calling process.cwd() directly.

Source: Coding guidelines

Comment on lines +95 to +187
describe("changed-checks planner", () => {
it("skips docs-only changes", () => {
const result = plan("test", ["docs/process.md", "README.md"])

expect(result.mode).toBe("skip")
expect(result.commands).toEqual([])
})

it("fails closed to a full run for root toolchain changes", () => {
const result = plan("test", ["bun.lock"])

expect(result.mode).toBe("all")
expect(result.commands.map((command) => command.packageName)).toEqual([
"@prover-coder-ai/docker-git-container",
"@prover-coder-ai/docker-git-session-sync",
"@effect-template/lib",
"@prover-coder-ai/docker-git-terminal",
"@effect-template/api",
"@prover-coder-ai/docker-git"
])
})

it("runs normal lint only for the owning package", () => {
const result = plan("lint", ["packages/terminal/src/core/output-buffer.ts"])

expect(result.mode).toBe("affected")
expect(result.commands).toEqual([
{
args: ["run", "--filter", "@prover-coder-ai/docker-git-terminal", "lint"],
command: "bun",
packageName: "@prover-coder-ai/docker-git-terminal",
phase: "lint",
serial: false,
scriptName: "lint"
}
])
})

it("adds test lint when a package test file changed", () => {
const result = plan("lint", ["packages/app/tests/docker-git/menu-create.test.ts"])

expect(result.commands.map((command) => command.scriptName)).toEqual(["lint", "lint:tests"])
})

it("expands typecheck to transitive dependents", () => {
const result = plan("typecheck", ["packages/terminal/src/core/output-buffer.ts"])

expect(result.commands.map((command) => command.packageName)).toEqual([
"@prover-coder-ai/docker-git-terminal",
"@effect-template/api",
"@prover-coder-ai/docker-git"
])
})

it("fails closed for unknown root files", () => {
const result = plan("lint:effect", [".editorconfig"])

expect(result.mode).toBe("all")
expect(result.commands.length).toBeGreaterThan(1)
})

it("marks package commands with pre-hooks as serial for local execution", () => {
const result = plan("typecheck", ["packages/app/src/web/api-http.ts"])

expect(result.commands.find((command) => command.packageName === "@prover-coder-ai/docker-git")).toMatchObject({
phase: "typecheck",
serial: true,
scriptName: "typecheck"
})
})

it("builds a GitHub matrix per affected package command", () => {
const result = plan("lint", [
"packages/app/src/web/api-http.ts",
"packages/app/tests/docker-git/api-http.test.ts"
])

expect(createGithubMatrix(result)).toEqual({
include: [
{
label: "@prover-coder-ai/docker-git lint",
packageName: "@prover-coder-ai/docker-git",
script: "lint"
},
{
label: "@prover-coder-ai/docker-git lint:tests",
packageName: "@prover-coder-ai/docker-git",
script: "lint:tests"
}
]
})
})
})

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 | 🟠 Major | ⚡ Quick win

Нужны property-based тесты инвариантов planner (и репродуктор для delete-only diff).

Сейчас suite полностью example-based. Для этого файла добавьте fc.property-проверки инвариантов (например: docs-only ⇒ skip, unknown/global ⇒ all, и delete-only изменение внутри пакета не даёт skip) и зафиксируйте Proof of fix для найденного кейса удаления.

As per coding guidelines: **/*.test.{ts,tsx}: "Write property-based tests using fast-check (fc.property) ..."; и "Every bug fix must be accompanied by a reproducing test case ... document the Proof of Fix with root cause and solution".

🤖 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/changed-checks.test.ts` around lines 95 - 187,
The test suite for the "changed-checks planner" describe block currently uses
only example-based tests and lacks property-based invariant testing. Add
property-based tests using fast-check's fc.property to verify three key
invariants: first, that docs-only file changes result in skip mode; second, that
unknown or global root file changes result in all mode; third, that delete-only
changes within a package do not produce skip mode (this should include a
specific reproducing test case for the delete-only diff bug that was
discovered). Ensure each property test documents the root cause and fix as a
comment following the coding guidelines for test files.

Source: Coding guidelines

Comment on lines +66 to +79
export const renderEntrypointProjectRuntimeEnv = (): string =>
String.raw`# Publish runtime project identity into login and SSH environments.
DOCKER_GIT_PROJECT_PROFILE="/etc/profile.d/docker-git-project.sh"
{
printf "export TARGET_DIR=%q\n" "$TARGET_DIR"
printf "export REPO_URL=%q\n" "$REPO_URL"
printf "export REPO_REF=%q\n" "$REPO_REF"
printf "export FORK_REPO_URL=%q\n" "$FORK_REPO_URL"
} > "$DOCKER_GIT_PROJECT_PROFILE"
chmod 0644 "$DOCKER_GIT_PROJECT_PROFILE"
docker_git_upsert_ssh_env "TARGET_DIR" "$TARGET_DIR"
docker_git_upsert_ssh_env "REPO_URL" "$REPO_URL"
docker_git_upsert_ssh_env "REPO_REF" "$REPO_REF"
docker_git_upsert_ssh_env "FORK_REPO_URL" "$FORK_REPO_URL"`

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 | 🟠 Major | ⚡ Quick win

Не сохраняйте REPO_URL и FORK_REPO_URL в env-файлы без редактирования секретов

На Line 71-73 и Line 77-79 URL записываются «как есть» в /etc/profile.d/docker-git-project.sh и ~/.ssh/environment. Если в URL присутствует userinfo (https://token@host/...), токен персистируется и может утечь.

Вариант исправления
 export const renderEntrypointProjectRuntimeEnv = (): string =>
   String.raw`# Publish runtime project identity into login and SSH environments.
 DOCKER_GIT_PROJECT_PROFILE="/etc/profile.d/docker-git-project.sh"
+docker_git_redact_url_userinfo() {
+  printf "%s" "$1" | sed -E 's#(https?://)[^/@]+@#\1#'
+}
+REPO_URL_SAFE="$(docker_git_redact_url_userinfo "$REPO_URL")"
+FORK_REPO_URL_SAFE="$(docker_git_redact_url_userinfo "$FORK_REPO_URL")"
 {
   printf "export TARGET_DIR=%q\n" "$TARGET_DIR"
-  printf "export REPO_URL=%q\n" "$REPO_URL"
+  printf "export REPO_URL=%q\n" "$REPO_URL_SAFE"
   printf "export REPO_REF=%q\n" "$REPO_REF"
-  printf "export FORK_REPO_URL=%q\n" "$FORK_REPO_URL"
+  printf "export FORK_REPO_URL=%q\n" "$FORK_REPO_URL_SAFE"
 } > "$DOCKER_GIT_PROJECT_PROFILE"
 chmod 0644 "$DOCKER_GIT_PROJECT_PROFILE"
 docker_git_upsert_ssh_env "TARGET_DIR" "$TARGET_DIR"
-docker_git_upsert_ssh_env "REPO_URL" "$REPO_URL"
+docker_git_upsert_ssh_env "REPO_URL" "$REPO_URL_SAFE"
 docker_git_upsert_ssh_env "REPO_REF" "$REPO_REF"
-docker_git_upsert_ssh_env "FORK_REPO_URL" "$FORK_REPO_URL"`
+docker_git_upsert_ssh_env "FORK_REPO_URL" "$FORK_REPO_URL_SAFE"`

As per coding guidelines: **/*.{js,ts,jsx,tsx,py,java,go,rb,php,sh,bash,yml,yaml,json,env*,toml,cfg,config,dockerfile,dockerignore}: “Fail if changed files expose credentials, tokens, private-keys, or PII in source, generated config, logs, or CI output”.

🤖 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/container/src/core/templates-entrypoint/base.ts` around lines 66 -
79, The function renderEntrypointProjectRuntimeEnv is persisting REPO_URL and
FORK_REPO_URL directly to environment files without removing potentially
embedded credentials (like auth tokens in the format https://token@host). Before
writing these URLs to the DOCKER_GIT_PROJECT_PROFILE file or passing them to
docker_git_upsert_ssh_env calls, sanitize them by removing any userinfo
components that may contain sensitive credentials. Ensure the sanitized versions
are used in both the printf statements for the profile file and the
docker_git_upsert_ssh_env function calls for REPO_URL and FORK_REPO_URL.

Source: Coding guidelines

Comment on lines +984 to +995
it("renders an explicit prebuilt image without a build section", () => {
const compose = renderDockerCompose(
makeTemplateConfig({
imageName: "docker-git-e2e-project:latest"
})
)

expect(compose).toContain(" image: 'docker-git-e2e-project:latest'\n")
expect(compose).toContain(" pull_policy: never\n")
expect(compose).not.toContain(" build: .\n")
})

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Проверка, есть ли property-based тесты для этого инварианта в файле
rg -n --type=ts 'fc\.property|renderDockerCompose\(' packages/container/tests/core/templates.test.ts

Repository: ProverCoderAI/docker-git

Length of output: 848


🏁 Script executed:

#!/bin/bash
# Получить контекст вокруг целевого теста line 984-995
sed -n '970,1005p' packages/container/tests/core/templates.test.ts | cat -n

echo "---"

# Получить контекст property-based теста для сравнения паттерна
sed -n '450,480p' packages/container/tests/core/templates.test.ts | cat -n

Repository: ProverCoderAI/docker-git

Length of output: 3890


🏁 Script executed:

#!/bin/bash
# Найти все тесты с imageName в файле
rg -n -A5 -B1 'imageName' packages/container/tests/core/templates.test.ts | head -60

echo "---"

# Проверить структуру generatedTemplateConfigArbitrary
rg -n -A10 'generatedTemplateConfigArbitrary' packages/container/tests/core/templates.test.ts | head -40

Repository: ProverCoderAI/docker-git

Length of output: 2265


🏁 Script executed:

#!/bin/bash
# Проверить регулярное выражение для docker image names
# Docker image names имеют формат: [REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
# Примеры валидных: "myimage:latest", "localhost:5000/myimage:v1.0", "gcr.io/project/image:tag"

# Найти как makeTemplateConfig обрабатывает imageName
rg -n -A15 'makeTemplateConfig.*\{' packages/container/tests/core/templates.test.ts | grep -A15 'imageName' | head -40

echo "---"

# Проверить функцию renderDockerCompose и как она обрабатывает imageName
rg -n -B5 -A20 'const renderDockerCompose' packages/container/tests/core/templates.test.ts | head -50

Repository: ProverCoderAI/docker-git

Length of output: 691


🏁 Script executed:

#!/bin/bash
# Найти импорты и определение renderDockerCompose
rg -n 'renderDockerCompose|makeTemplateConfig' packages/container/tests/core/templates.test.ts | head -10

echo "---"

# Найти где определены эти функции (вероятно в других файлах)
fd -e ts -e js packages/container -type f | xargs rg -l 'export.*renderDockerCompose|export.*makeTemplateConfig' 2>/dev/null | head -5

Repository: ProverCoderAI/docker-git

Length of output: 1004


🏁 Script executed:

#!/bin/bash
# Получить полное определение makeTemplateConfig (line 16-60)
sed -n '1,100p' packages/container/tests/core/templates.test.ts | cat -n

echo "---"

# Найти где определен TemplateConfig
rg -n 'type TemplateConfig|interface TemplateConfig' packages/container --type ts | head -5

Repository: ProverCoderAI/docker-git

Length of output: 5399


🏁 Script executed:

#!/bin/bash
# Получить определение TemplateConfig и defaultTemplateConfig
sed -n '40,100p' packages/container/src/core/domain.ts | cat -n

echo "---"

# Получить полное определение renderDockerCompose
sed -n '1,80p' packages/container/src/core/templates/docker-compose.ts | cat -n

Repository: ProverCoderAI/docker-git

Length of output: 5788


🏁 Script executed:

#!/bin/bash
# Получить больше из renderDockerCompose, найти логику для build vs image
sed -n '80,200p' packages/container/src/core/templates/docker-compose.ts | cat -n

echo "---"

# Найти где обрабатывается imageName в логике рендера
rg -n -B3 -A3 'imageName|build: \.' packages/container/src/core/templates/docker-compose.ts | head -50

Repository: ProverCoderAI/docker-git

Length of output: 6117


Добавьте property-based проверку инварианта выбора build/image.

Сейчас сценарий тестируется на одном фиксированном imageName, что слабо доказывает контракт рендера. Здесь нужен property-based тест для инварианта: при заданном imageName всегда присутствуют image + pull_policy: never и отсутствует build: .; без imageName — наоборот.

Рекомендуемый вариант
+  it("preserves compose image/build invariants for arbitrary prebuilt image names", () => {
+    fc.assert(
+      fc.property(
+        fc.stringMatching(/^[a-z0-9][a-z0-9._/-]{0,60}:[a-zA-Z0-9._-]{1,40}$/),
+        (imageName) => {
+          const compose = renderDockerCompose(makeTemplateConfig({ imageName }))
+          expect(compose).toContain(`    image: '${imageName}'\n`)
+          expect(compose).toContain("    pull_policy: never\n")
+          expect(compose).not.toContain("    build: .\n")
+        }
+      )
+    )
+  })

Per **/*.test.{ts,tsx}: write property-based tests using fast-check to 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/container/tests/core/templates.test.ts` around lines 984 - 995, The
test "renders an explicit prebuilt image without a build section" currently only
verifies a single hardcoded case. Replace or enhance this test to use
property-based testing with fast-check to verify the mathematical invariant for
build/image selection: when an imageName is provided to makeTemplateConfig, the
rendered compose output must always contain image and pull_policy: never while
never containing build: .; conversely, when no imageName is provided, the
opposite should hold. This approach will verify the contract across multiple
generated test cases rather than relying on a single fixed value.

Source: Coding guidelines

Comment on lines +375 to +387
if (arg === "--concurrency") {
parsed.concurrency = Math.max(1, Number.parseInt(rest[index + 1] ?? "4", 10) || 4)
index += 1
continue
}
if (arg === "--base") {
parsed.base = rest[index + 1] ?? ""
index += 1
continue
}
if (arg === "--head") {
parsed.head = rest[index + 1] ?? "HEAD"
index += 1

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

Флаги с обязательным значением принимаются без валидации значения.

Для --concurrency, --base, --head отсутствие значения (или следующий токен-флаг) сейчас тихо принимается, что делает поведение CLI неоднозначным. Лучше явно падать с ошибкой Missing value for ....

Предлагаемое исправление
+  const requireValue = (flagName) => {
+    const value = rest[index + 1]
+    if (value === undefined || value.startsWith("--")) {
+      throw new Error(`Missing value for ${flagName}`)
+    }
+    index += 1
+    return value
+  }
+
   for (let index = 0; index < rest.length; index += 1) {
@@
     if (arg === "--concurrency") {
-      parsed.concurrency = Math.max(1, Number.parseInt(rest[index + 1] ?? "4", 10) || 4)
-      index += 1
+      parsed.concurrency = Math.max(1, Number.parseInt(requireValue("--concurrency"), 10) || 4)
       continue
     }
     if (arg === "--base") {
-      parsed.base = rest[index + 1] ?? ""
-      index += 1
+      parsed.base = requireValue("--base")
       continue
     }
     if (arg === "--head") {
-      parsed.head = rest[index + 1] ?? "HEAD"
-      index += 1
+      parsed.head = requireValue("--head")
       continue
     }
🤖 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 `@scripts/changed-checks.mjs` around lines 375 - 387, The flags
`--concurrency`, `--base`, and `--head` currently accept missing or invalid
values without validation, causing ambiguous CLI behavior. For each of these
three flag handlers in the argument parsing section, add validation to check
that the next argument exists in the rest array and is not another flag (does
not start with "--"), and throw an explicit error with the message "Missing
value for [flag-name]" if the validation fails. This validation should happen
before assigning the parsed value to ensure required arguments are always
provided.

Comment on lines +23 to +43
const toRelativePath = (path) => {
const relativePath = relative(repoRoot, path)
return relativePath.length === 0 ? "." : relativePath
}

const fail = (message) => {
console.error(message)
process.exit(1)
}

const addExistingPath = (path) => {
if (!existsSync(path)) {
fail(`Missing E2E artifact path: ${path}`)
}

const relativePath = toRelativePath(resolve(repoRoot, path))
if (!paths.has(relativePath)) {
paths.add(relativePath)
queue.push(relativePath)
}
}

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 | 🟠 Major | ⚡ Quick win

Ограничьте пакуемые пути пределами repoRoot.

На Line 38-42 relative(repoRoot, realPath) может вернуть ../... для симлинка вне репозитория; затем этот путь уходит в tar -T (Line 119), что позволяет включить внешние файлы в артефакт.

Предлагаемый фикс границы путей
+const ensureInsideRepo = (absolutePath) => {
+  const rel = relative(repoRoot, absolutePath)
+  if (rel === ".." || rel.startsWith(`..${sep}`)) {
+    fail(`Path escapes repository root: ${absolutePath}`)
+  }
+}
+
 const addExistingPath = (path) => {
   if (!existsSync(path)) {
     fail(`Missing E2E artifact path: ${path}`)
   }
 
-  const relativePath = toRelativePath(resolve(repoRoot, path))
+  const absolutePath = resolve(repoRoot, path)
+  ensureInsideRepo(absolutePath)
+  const relativePath = toRelativePath(absolutePath)
   if (!paths.has(relativePath)) {
     paths.add(relativePath)
     queue.push(relativePath)
   }
 }

As per coding guidelines: "**/*.{py,js,ts,jsx,tsx,go,java,rb,php,sh,bash,c,cpp}: Fail if changed files introduce path traversal or writes outside intended project/container state directories".

Also applies to: 55-64, 119-122

🤖 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 `@scripts/ci/pack-e2e-prebuilt.mjs` around lines 23 - 43, The addExistingPath
function resolves paths that may be symlinks, but does not validate that the
resolved path stays within the repoRoot boundary. This allows paths with `../`
to escape the repository and be included in the tar archive. After resolving the
path with resolve(repoRoot, path) and computing the relative path with
toRelativePath, validate that the resolved absolute path actually starts with
repoRoot (after normalization) before adding it to the paths collection. If the
resolved path is outside repoRoot, call fail to reject it with an appropriate
error message about path traversal.

Source: Coding guidelines

Comment thread scripts/npx

# CHANGE: provide a minimal npx shim for Bun-managed workspaces
# WHY: some tools (e.g. vibecode-linter) call `npx tsc` and should resolve the local workspace binary through Bun instead of downloading a similarly named package
# WHY: workspace tools that call `npx tsc` should resolve the local workspace binary through Bun instead of downloading a similarly named package

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 | 🟠 Major | ⚡ Quick win

Документация улучшена; однако скрипт содержит уязвимость path traversal.

Изменение строки 5 корректно уточняет причину: теперь ясно, что шим предназначен для tools типа npx tsc, которые должны резолвить локальные бинарники через Bun вместо загрузки одноимённого пакета.

Однако критический дефект: переменная $command_name (строка 36) получена от пользователя без валидации. На строке 41 она встраивается в путь $search_dir/node_modules/.bin/$command_name. Если передать npx ../../../bin/malicious, конструкция пути станет /pwd/node_modules/.bin/../../../bin/malicious, что позволяет выйти за границы node_modules/.bin/ и выполнить произвольный исполняемый файл из системы.

Проверка -x (строка 42) не решает проблему: она лишь подтверждает, что файл исполняемый, но не ограничивает доступное пространство.

Рекомендация: добавить валидацию, чтобы $command_name содержал только буквы, цифры, дефис и подчёркивание (стандартные имена npm пакетов). Отклонить любые пути с /, .., или другими спецсимволами.

🔒 Предлагаемый фикс: валидировать command_name
 command_name="$1"
 shift
 
+# CHANGE: validate command_name to prevent path traversal
+# WHY: reject commands with path separators, parent refs, or special chars that could escape node_modules/.bin/
+# INVARIANT: ∀ cmd: valid(cmd) → ¬(contains(cmd, '/') ∨ contains(cmd, '..') ∨ contains(cmd, '\'))
+case "$command_name" in
+  */*|*..*|*\\*|*:*)
+    echo "npx shim: invalid command name '$command_name'" >&2
+    exit 2
+    ;;
+esac
+
 search_dir="$PWD"
🤖 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 `@scripts/npx` at line 5, The script has a path traversal vulnerability where
the user-supplied command_name variable is embedded directly into the
node_modules/.bin path without validation, allowing attackers to use sequences
like ../ to escape the intended directory. Add validation to the $command_name
variable to ensure it only contains alphanumeric characters, hyphens, and
underscores before it is used in the path construction on line 41. Reject any
input containing forward slashes, double dots, or other special characters by
checking the variable against a whitelist pattern and exiting early if
validation fails.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant