Skip to content

fix(agent-adapter): default codewith workers to exec, not durable agent start#21

Open
andrei-hasna wants to merge 1 commit into
mainfrom
fix/codewith-worker-exec
Open

fix(agent-adapter): default codewith workers to exec, not durable agent start#21
andrei-hasna wants to merge 1 commit into
mainfrom
fix/codewith-worker-exec

Conversation

@andrei-hasna

Copy link
Copy Markdown
Contributor

Problem (blocker — unblocks ALL codewith drains fleet-wide)

The loops codewith adapter launched every worker via codewith agent start (the durable background daemon). That path is broken two ways on the current fleet:

  1. Silent no-op (codewith bug aaa695d2): the daemon reloads ~1.9MB session history per turn → context_length_exceeded → completes in ~10s with a null message and no work done. Every codewith-provider drain (PR-merge queue, fleet-reliability-drain, DATA-PLATFORM AWS-RDS drains) dispatched workers that did nothing.
  2. Contract break: codewith 0.1.51's agent start no longer accepts --json, so route/task-lifecycle steps failed at triage with step triage failed: codewith agent start exited with code 2 / unexpected argument --json.

codewith exec works fine (it is the documented working delegation path).

Fix

Switch the default codewith execution path to one-shot codewith exec (non-interactive, honors --auth-profile, reaches the network, mirrors the codex adapter):

  • Prompt travels on stdin via codewith exec -, keeping it off argv/ps.
  • workspace-write sandboxes block network egress by default, so gh/git could not reach GitHub (exactly the merge-worker failure recorded in the PR-merge diagnosis: "git fetch … Could not resolve host github.com"). The exec path now adds -c sandbox_workspace_write.network_access=true for workspace-write so model-run gh/git commands complete. danger-full-access is already unrestricted; read-only workers stay egress-off.
  • Preserves --auth-profile, --sandbox, --cd, --add-dir, --model, reasoning effort, --json/--ephemeral/--ignore-rules/--skip-git-repo-check, and worktree handling.

The durable agent start path stays available behind an opt-in codewithMode: "agent" target flag. Existing loops with no flag default to exec and are fixed automatically (no migration/backfill needed).

Codewith remains local-only in both modes (capabilities.remote=false): remote durable readback and remote-exec verification are separate work, so a codewith step on a remote machine fails closed rather than dispatching to an unverified transport.

Verification against codewith 0.1.51 (real CLI)

  • The exec arg vector parses cleanly, streams --json JSONL, and reads the prompt from stdin via -.
  • sandbox_workspace_write.network_access is a recognized config field (--strict-config accepts it; a bogus key is rejected).

Changes

  • src/types.ts: add AgentTarget.codewithMode ("exec" default | "agent").
  • src/lib/agent-adapter.ts: exec-default codewith invocation + opt-in durable branch; codewithUsesDurableAgent/resolveCodewithMode helpers; codewithMode validation; promptChannel: "stdin"; rename UNSAFE_CODEWITH_DURABLE_EXTRA_ARGSRESERVED_CODEWITH_MANAGED_ARGS.
  • src/lib/executor.ts: gate the durable start/read/logs poller on codewithMode="agent"; keep codewith local-only in both modes.
  • README.md / docs/USAGE.md: describe the new default + opt-in agent mode.
  • Tests: new exec-default worker test + remote-exec guard test; existing durable tests opt into codewithMode: "agent".

Checks

  • bun run typecheck ✓ · bun test → 550 pass / 0 fail ✓ · bun run build ✓ · bun run test:boundary
  • Staged secrets scan: clean.

Landing note

This restores the merge pipeline together with the admission-gate fix (49f5670c). Do not self-merge — needs an adversarial reviewer and a separate merger per the delivery contract.

Follow-ups (out of scope, noted for reviewer)

  • Codex workers share the same workspace-write-without-egress default; if codex is also used for network work, it needs the same network_access treatment.
  • Worktree-based workers write git metadata to the main repo's .git/worktrees/<name> (outside the worktree cwd); confirm the sandbox policy or --add-dir/repoRoot covers that for git commit/push.
  • Enabling verified machine-local (remote) codewith exec is a separate change with its own remote test.

…nt start

The loops codewith adapter launched every worker via `codewith agent start`
(the durable background daemon). That daemon reloads large session history per
turn, hits context_length_exceeded, and silently completes with no work, so
every codewith-provider drain (PR-merge queue, fleet-reliability, data-platform)
dispatched workers that did nothing. Codewith 0.1.51 also no longer accepts the
`--json` flag on `agent start`, so route/task-lifecycle steps failed at triage
with "codewith agent start exited with code 2".

Switch the default codewith execution path to one-shot `codewith exec`
(non-interactive, honors --auth-profile, reaches the network, mirrors the codex
adapter). The prompt travels on stdin via `codewith exec -`, keeping it off
argv/ps. workspace-write sandboxes block network egress by default, so enable it
explicitly with `-c sandbox_workspace_write.network_access=true` so model-run
gh/git commands can reach GitHub (verified: the config key is recognized and the
exec arg vector parses and streams JSONL against codewith 0.1.51).

The durable `agent start` path stays available behind an opt-in
`codewithMode: "agent"` target flag; existing loops with no flag default to exec
and are fixed automatically. Codewith remains local-only in both modes (remote
durable readback and remote exec verification are separate work), failing closed
on a remote machine rather than dispatching to an unverified transport.

- add AgentTarget.codewithMode ("exec" default | "agent") with validation
- gate the durable start/read/logs poller on codewithMode="agent"
- add codewithUsesDurableAgent/resolveCodewithMode helpers
- rename UNSAFE_CODEWITH_DURABLE_EXTRA_ARGS -> RESERVED_CODEWITH_MANAGED_ARGS
- update capabilities.promptChannel to stdin; refresh README/USAGE docs
- tests: new exec-default and remote-exec-guard cases; opt existing durable
  tests into codewithMode="agent"
@cursor

cursor Bot commented Jul 4, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@andrei-hasna

Copy link
Copy Markdown
Contributor Author

Worker review result for todos task 0886e268-3fa8-4537-ae55-bea86221c2f5: not safe to merge as-is.

Blockers:

  • GitHub still reports mergeable=CONFLICTING; git merge-tree --write-tree --name-only --messages origin/main origin/pr/21 reports conflicts in README.md, docs/USAGE.md, src/lib/agent-adapter.ts, src/lib/agent-adapter.test.ts, src/lib/executor.ts, src/lib/executor.test.ts, and src/lib/workflow-runner.test.ts.
  • Current main is 0e2a90d and already contains the essential default Codewith exec worker fix. PR head 7d1964d diverges from the same release base rather than stacking on current main.
  • Merging this PR as-is would regress current main by deleting src/lib/route/pr-review.test.ts and removing gh-based PR author derivation in src/lib/route/pr-review.ts, which protects non-author review routing.
  • It would also roll package metadata from 0.4.9 back to 0.4.8 and remove the current changelog entry.
  • Active GitHub identity in the worker is andrei-hasna, which is also the PR author; routing evidence selected non-author reviewer kriptoburak, so this worker cannot supply the required non-author review.

Validation on current main/worktree:

  • Focused tests: bun test src/lib/agent-adapter.test.ts src/lib/executor.test.ts src/lib/workflow-runner.test.ts -> 79 pass.
  • bun run typecheck -> pass.
  • Initial full bun test failed only because the sandbox real HOME was read-only for startup install tests; rerun with isolated writable HOME -> 555 pass.
  • bun run test:boundary -> pass.
  • bun run build -> pass.

Follow-up todo created for the separable question of whether the PR-only codewithMode: "agent" durable-agent opt-in should be rebased/split on top of current main: 0a99f0e2. Until that is resolved, PR #21 should stay unmerged.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant