feat(autofix): runnable project env (native + docker-compose) with build/test gating#5
Open
pat-lewczuk wants to merge 2 commits into
Open
feat(autofix): runnable project env (native + docker-compose) with build/test gating#5pat-lewczuk wants to merge 2 commits into
pat-lewczuk wants to merge 2 commits into
Conversation
…ild/test gating
Give autofix runs a real install/build/test feedback loop on the checked-out
worktree, so the fix loop iterates against actual build/test output before
opening a PR — and support a per-run docker-compose environment for repos that
need services (db, redis, …) to build or test.
Core:
- New `provision/` module: `RunEnv` interface with `NativeShellEnv` (host shell)
and `DockerComposeEnv` (per-run `compose -p cezar-<run>` project; worktree
bind-mounted; deps persist via the mount; `down -v` on dispose). `createRunEnv`
resolves kind (`auto` detects a compose file; falls back to native when Docker
is absent so the managed cloud path still works) and the compose service.
- New `shell-check` workflow step kind: runs install/build/test via the run's
`RunEnv`, streams output, and gates the run. A gated build/test failure inside
the fix loop fails-retriable, carrying the failure tail back as fix retry
notes; review only runs once build+test pass. No `RunEnv` / unset command ⇒
the step is a no-op, so triage and env-less runs are unchanged.
- autofix workflow: install (before root-cause) + build + test (in the fix
loop) shell-checks; new blackboard fields for the results.
- Orchestrator builds the `RunEnv` from `autofix.projectEnv`, threads it through
the engine on both the autofix and ci-followup paths, and disposes it.
- Config: `autofix.projectEnv` (kind / install / build / test / compose
{file,service,workdir} / envVars / gateOn{Install,Build,Test}).
GUI:
- Settings → Configuration gains a "Project environment" section; persisted to
`workspaces.config.autofix.projectEnv` and deep-merged in loadWorkspaceConfig.
Compose-based runs require a Docker daemon ⇒ self-hosted runner only; the runner
already caps parallelism via `--concurrency` (default 1) and per-run worktrees +
unique compose project names make >1 safe.
Tests: provision unit tests (detect/native/factory) + engine shell-check tests
(pass, gated-failure-loops-to-fix, loop-exhausted-fails, ungated, no-env).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Boot the project's dev server once after install so the agent can probe the
running application while diagnosing and verifying its fix.
Core:
- `RunEnv` gains `startDevServer()` → `DevServerHandle { url, ready, stop }`,
plus a `waitForHttp` readiness probe. `NativeShellEnv` spawns the command
detached and SIGTERMs the process group on stop/dispose; `DockerComposeEnv`
publishes the container port to an ephemeral host port via the override file,
`up -d`s the service, and resolves the mapped host port with `compose port`
(`parseHostPort`). Both are torn down by `dispose()`.
- New `dev-server` workflow step kind: boots the server, records the URL on the
run, and (informational by default) keeps going if it's slow to come up;
`gate: true` fails the run if it never responds. No env / disabled ⇒ no-op.
- The engine threads the dev-server URL to later agent steps: appends the URL to
the step prompt and adds `curl` to the bash allowlist, so the agent can read
the live app over its existing Bash tool (backend-agnostic "read-url" — a
bespoke custom tool would need a per-backend MCP server).
- autofix workflow runs `dev-server` after install, before root-cause; new
`devServerUrl` blackboard field.
- Config: `autofix.projectEnv.devServer { enabled, command, port, readyPath,
readyTimeoutSec }`.
GUI: dev-server fields in the Settings → Project environment section; persisted
to `workspaces.config` and deep-merged in loadWorkspaceConfig.
Deferred: headless screenshots (needs a browser dep) — left for a follow-up.
Tests: real NativeShellEnv boot/probe/teardown against a throwaway Node server;
engine dev-server scenarios (URL+curl injection ordering, unconfigured no-op,
ungated boot failure). 162 core tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Gives autofix runs a real install → build → test feedback loop on the checked-out worktree, so the fix loop iterates against actual build/test output before opening a PR — and adds a per-run Docker Compose environment for repos that need services (db, redis, …) to build or test.
Both live paths (
@cezar/runnerand the cloud dispatcher) funnel throughAutofixOrchestrator.processIssueViaEngine, so the newRunEnvis wired in there once and works for both.What's in it
Core — new
provision/module (one interface, two impls)RunEnvinterface:install()/build()/test()/run()/dispose().NativeShellEnv— host shell in the worktree.DockerComposeEnv— per-runcompose -p cezar-<runId>project (isolated network/volumes), worktree bind-mounted into the app service, deps persist back through the mount,down -v --remove-orphanson dispose. Override file is written outside the worktree so autosave /git add -Acan't catch it;--project-directorykeeps the base file's build contexts resolving.createRunEnv— auto-detects the compose file (overridable path), resolves the app service when unset, and falls back to native when Docker is absent (so the managed cloud path still works).Core — workflow engine
shell-checkstep kind. A gated build/test failure inside the fix loop fails-retriable→ loops back tofixcarrying the failure tail as retry notes;reviewonly runs once build+test pass. NoRunEnv/ an unset command ⇒ the step is a no-op, so triage and env-less runs are byte-identical to before.install(before root-cause) +build+test(in the fix loop), plus blackboard fields for the results.RunEnvfromautofix.projectEnv, threads it through the engine on both the autofix and ci-followup paths, and disposes it.Config + GUI
autofix.projectEnv(kind / install / build / test / compose{file,service,workdir}/ envVars /gateOn{Install,Build,Test}).workspaces.config.autofix.projectEnv(no migration) and deep-merged inloadWorkspaceConfig.Notes
--concurrency(default 1); per-run worktrees + unique compose project names make >1 safe.read-urlagent tool are intentionally deferred to a follow-up (Phase 3).Test plan
yarn typecheck— all workspaces cleanyarn build— all workspaces incl. Next.jsyarn workspace @cezar/core run test— 157 pass (incl. new provision unit tests + 5 engine shell-check scenarios: pass / gated-failure-loops-to-fix / loop-exhausted-fails / ungated / no-env)projectEnv(native + compose) on a real workspace and watch the cockpit show install/build/test steps🤖 Generated with Claude Code