Skip to content

feat(executor): RunnerDefaults::from_env for CONVERGIO_RUNNER_DEFAULT#243

Open
Roberdan wants to merge 1 commit intomainfrom
feat/runner-defaults-from-env
Open

feat(executor): RunnerDefaults::from_env for CONVERGIO_RUNNER_DEFAULT#243
Roberdan wants to merge 1 commit intomainfrom
feat/runner-defaults-from-env

Conversation

@Roberdan
Copy link
Copy Markdown
Owner

@Roberdan Roberdan commented May 6, 2026

Problem

The daemon hard-coded `claude:sonnet` as the executor's default
runner kind. Operators using Copilot (or any other vendor) had no
way to flip the dispatcher's default short of editing
`crates/convergio-executor/src/defaults.rs` and rebuilding.

The runner crate already supports both vendors. The legacy
`/bin/echo` fallback was active for every dispatch because
`task.runner_kind` is unset on existing tasks and there was no
env-var override for the daemon-wide default.

Why

Without an env-driven knob there is no path from "I run Copilot
locally" to "the dispatcher routes my tasks through it" that
doesn't require recompiling. CONSTITUTION P1 (zero scaffolding):
the runner registry lives in code; expose it.

What changed

  • New `RunnerDefaults::from_env()` reads:
    • `CONVERGIO_RUNNER_DEFAULT` — wire format `:`
      (e.g. `copilot:gpt-5.2`, `claude:opus`, `copilot:claude-opus`).
      Invalid values log a warning and the compiled-in default is used.
    • `CONVERGIO_RUNNER_PROFILE` — `standard` (default), `restricted`,
      `unrestricted`.
    • `CONVERGIO_DAEMON_URL` — base URL the spawned agent calls back
      to; defaults to `http://127.0.0.1:8420\`.
  • Server wiring: the background loop in `main.rs` and the manual
    `POST /v1/dispatch` route both call
    `Executor::new(...).with_defaults(RunnerDefaults::from_env())`.
  • Boot-time `tracing::info!` logs the resolved `runner_kind` /
    `runner_profile` so operators can confirm the daemon picked up
    their override.

The orthogonal switch `CONVERGIO_EXECUTOR_USE_RUNNER` (already in
`executor.rs`) is what flips the dispatcher off the legacy shell
template; the new env vars only take effect when a task either
sets its own `runner_kind` or `USE_RUNNER` is set.

Validation

  • 4 new tests cover default / valid override / invalid fallback /
    daemon-url override, serialised through a `Mutex` because env
    vars are process-global.
  • `cargo fmt --all -- --check` clean.
  • `RUSTFLAGS="-Dwarnings" cargo clippy --workspace --all-targets -- -D warnings` clean.
  • `RUSTFLAGS="-Dwarnings" cargo test --workspace` — 1047 passed,
    0 failed.
  • Pre-commit hooks (file-size, fmt, clippy, context-budget) all
    green.

End-to-end smoke (out-of-band): launchd plist with
`CONVERGIO_RUNNER_DEFAULT=copilot:gpt-5.2` +
`CONVERGIO_EXECUTOR_USE_RUNNER=1` + matching `PATH` entry for
`copilot` / `gh` correctly produces 20+ `copilot -p ...` child
processes carrying the per-task prompt + Tier-3 graph context-pack
from `convergio-runner`. Processes stopped before any PR was
opened — auto-dispatch is an operator decision, not enabled here.

Impact

  • `convergio-executor` + `convergio-server` only.
  • New public method `RunnerDefaults::from_env()`. Existing
    `RunnerDefaults::default()` unchanged.
  • Boot log adds two structured fields. No HTTP-shape changes.

🤖 Generated with Claude Code

The daemon hard-coded `claude:sonnet` as the executor's default
runner. Operators who use Copilot (or any other vendor) had no way
to flip the dispatcher's default short of editing `defaults.rs`.

Adds:

- `RunnerDefaults::from_env()` reading `CONVERGIO_RUNNER_DEFAULT`
  (wire format `<vendor>:<model>` — e.g. `copilot:gpt-5.2`,
  `claude:opus`), `CONVERGIO_RUNNER_PROFILE` (`standard` /
  `restricted` / `unrestricted`), and `CONVERGIO_DAEMON_URL`.
  Invalid values log a warning and fall back to the compiled-in
  default.
- Server wiring: `convergio-server`'s background loop and the
  manual `POST /v1/dispatch` route both call
  `Executor::new(...).with_defaults(RunnerDefaults::from_env())`.
- Boot-time `tracing::info!` logs the resolved kind/profile so
  operators can confirm the daemon picked up their override.

Tests cover the four cases (default, valid override, invalid
fallback, daemon-url override), serialised via a `Mutex` because
env vars are process-global.

Verified end-to-end: with `CONVERGIO_RUNNER_DEFAULT=copilot:gpt-5.2`
+ `CONVERGIO_EXECUTOR_USE_RUNNER=1` set in the launchd plist, the
executor's tick spawns real `copilot -p ...` processes carrying
the per-task prompt + graph context-pack from `convergio-runner`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@chatgpt-codex-connector
Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@Roberdan
Copy link
Copy Markdown
Owner Author

Roberdan commented May 7, 2026

CI status update (2026-05-07)

All 3 checks passed on head commit 559b6e3:

Check Result
fmt + clippy + test ✅ success
cargo deny + audit ✅ success
Docs drift (advisory) ✅ success

PR is 1 day old — no age flag. Ready for review when a maintainer is available.


Generated by Claude Code

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