feat(orchestrator): slice 3 — real Docker launch broker #357

Open
didericis-claude wants to merge 2 commits from orchestrator-slice3 into orchestrator-slice2
Collaborator

Slice 3 of PRD 0070, stacked on #356 (branched off orchestrator-slice2). The first concrete LaunchBroker, proving the orchestrator → backend seam on the cheapest backend.

  • docker_broker.pyDockerBroker runs a container on a verified launch (docker run --detach --name <bottle> --label ... <image_ref>) and removes it on teardown (docker rm --force, idempotent on an already-absent container). The argv is built only from the request's static ids/flags, so nothing free-form reaches docker; provenance + schema verification are inherited from LaunchBroker.submit.
  • __main__.py gains --broker {stub,docker} so the harness can drive real containers.

Scope: launches a single container from image_ref — that's the seam. The full agent + sidecar bundle (networks, mounts, the consolidated sidecar) is a later slice.

Tests: unit (docker mocked) — argv from static fields only, launch/teardown call the right commands, missing-image + docker-failure raise, teardown idempotent on missing, forged token never touches docker; integration (gated on a reachable daemon via skip_unless_docker) — launch creates a real container, teardown removes it. Full suite green (only pre-existing /bin/sleep errors); integration verified locally against real docker.

Merge order: #352#356 → this.

🤖 Generated with Claude Code

Slice 3 of PRD 0070, **stacked on #356** (branched off `orchestrator-slice2`). The first *concrete* `LaunchBroker`, proving the orchestrator → backend seam on the cheapest backend. - **`docker_broker.py`** — `DockerBroker` runs a container on a verified launch (`docker run --detach --name <bottle> --label ... <image_ref>`) and removes it on teardown (`docker rm --force`, **idempotent** on an already-absent container). The argv is built **only from the request's static ids/flags**, so nothing free-form reaches `docker`; provenance + schema verification are inherited from `LaunchBroker.submit`. - **`__main__.py`** gains `--broker {stub,docker}` so the harness can drive real containers. Scope: launches a single container from `image_ref` — that's the seam. The full agent + sidecar bundle (networks, mounts, the consolidated sidecar) is a later slice. **Tests:** unit (docker mocked) — argv from static fields only, launch/teardown call the right commands, missing-image + docker-failure raise, teardown idempotent on missing, forged token never touches docker; integration (gated on a reachable daemon via `skip_unless_docker`) — launch creates a real container, teardown removes it. Full suite green (only pre-existing `/bin/sleep` errors); **integration verified locally against real docker**. Merge order: #352 → #356 → this. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
didericis-claude added 1 commit 2026-07-13 15:02:25 -04:00
feat(orchestrator): slice 3 — real Docker launch broker (#352)
lint / lint (push) Failing after 1m59s
test / unit (pull_request) Successful in 58s
test / integration (pull_request) Successful in 22s
test / coverage (pull_request) Successful in 1m6s
4fb0f64249
The first concrete LaunchBroker, proving the orchestrator -> backend seam
on the cheapest backend (the sidecar bundle is already containers):

  * orchestrator/docker_broker.py — DockerBroker runs a container on a
    verified launch (`docker run --detach --name <bottle> --label ...
    <image_ref>`) and removes it on teardown (`docker rm --force`,
    idempotent on an already-absent container). The argv is built only from
    the request's static ids/flags, so nothing free-form reaches docker;
    provenance/schema verification is inherited from LaunchBroker.submit.
  * __main__.py gains `--broker {stub,docker}` so the harness can drive real
    containers.

Slice 3 launches a single container from image_ref (the seam); the full
agent + sidecar bundle is a later slice.

Tests: unit (docker mocked) — argv from static fields, launch/teardown call
the right commands, missing-image and docker-failure raise, teardown
idempotent on missing, forged token never touches docker; integration
(gated on a reachable daemon) — launch creates a real container, teardown
removes it. Full suite green (only pre-existing /bin/sleep errors);
integration verified locally against real docker.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
didericis added 1 commit 2026-07-13 15:05:58 -04:00
fix(orchestrator): pyright — pass explicit LaunchRequest in the docker integration test (#352)
lint / lint (push) Successful in 1m58s
test / unit (pull_request) Successful in 59s
test / integration (pull_request) Successful in 20s
test / coverage (pull_request) Successful in 1m6s
44e611d14e
The **kw unpacking put str into slot: int|None. Pass explicit
LaunchRequests instead.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WBMWTEtQdJ4W5UrWuLHCck
didericis approved these changes 2026-07-13 15:10:39 -04:00
didericis left a comment
Owner

@didericis-claude Looks good. Move onto the next slice.

@didericis-claude Looks good. Move onto the next slice.
Author
Collaborator

CI fully green on 44e611d — lint (pylint 9.83/10 + pyright-strict), unit, integration, coverage all pass.

The earlier red was a single pyright-strict error: the integration-test helper used **kw: str, which let a str reach LaunchRequest.slot: int | None. Fixed by passing explicit LaunchRequests (44e611d). pylint was already passing — the items it lists are all pre-existing warnings in other files, well above the 8.0 gate.

Slice 3 is ready for review. Stack merge order: #352#356#357.

✅ **CI fully green** on `44e611d` — lint (pylint 9.83/10 + pyright-strict), unit, integration, coverage all pass. The earlier red was a single pyright-strict error: the integration-test helper used `**kw: str`, which let a `str` reach `LaunchRequest.slot: int | None`. Fixed by passing explicit `LaunchRequest`s (`44e611d`). pylint was already passing — the items it lists are all pre-existing warnings in other files, well above the 8.0 gate. Slice 3 is ready for review. Stack merge order: #352 → #356 → #357.
Some checks are pending
lint / lint (push) Successful in 1m58s
test / unit (pull_request) Successful in 59s
test / integration (pull_request) Successful in 20s
test / coverage (pull_request) Successful in 1m6s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin orchestrator-slice3:orchestrator-slice3
git checkout orchestrator-slice3
Sign in to join this conversation.