Stages 2-5, and the Node B deployment that can test stage 2 - #235
Merged
Conversation
added 14 commits
August 5, 2026 11:03
# Conflicts: # src/agent_harness/api.py # src/agent_harness/schemas.py
The accumulated locally-accepted milestone: the execution-environment contract and its metadata-selected Docker backend, the AIDevEnv-independent local fleet in `serve`, local plan-branch integration and promotion, the normalized remote-review intake contract with its durable deduplication, the notification outbox, and the first-party browser control plane reconciled onto this tree. Landed in this pass: - `github-pr-review`, the first installed review source. Identity is per-endpoint, because reviews and review comments number independently. Disposition is decided by explicit markers and review state, never by a model reading a human's prose -- anything unmarked becomes a hold for a person rather than work an agent guessed at. - `PlanPublisher` and its wiring into the executor factory. One plan branch yields exactly one pull request; a correction updates that same PR; an unchanged plan head touches no remote; a branch this plan does not contain is refused rather than discarded. Nothing merges, approves or marks ready. - #220: `queue.now()` is authoritative for a lease. The retry and block routes compared against the wall clock, silently opting out of the injectable clock that exists so lease behaviour can be tested at all. - #223: `tool` leaves `_WIRE_ROLES`. `_for_the_wire` reduces a message to role and content, so it can never produce the `tool_call_id` that role requires -- the allow-list contradicted the rule the function enforces. And the deployment, which exists for one reason: stage 2's exit needs the live Docker tests to run against a real daemon, and no daemon was reachable. The controller ships as an image with the Docker CLI and no Docker socket; the daemon arrives at runtime through DOCKER_HOST, pointing at a dedicated DinD sidecar on an internal network. The host socket was rejected: it is root-equivalent on the deploy host and would make every agent sandbox a sibling of every production stack there. The live suite deliberately does not run on the publish CI runners. They reach a separate DinD container with no shared volume, so a bind mount from the job workspace resolves to an empty directory on the daemon's side and would prove nothing. Acceptance runs against the deployed stack's own daemon instead. Gates on this tree: 1712 tests pass with one skip (live Docker, no daemon here), ruff check, ruff format --check and mypy all clean. No stage exit is claimed. No real remote has been contacted, no real pull request has been polled, and the live execution boundary remains untested until the deployed stack runs it.
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.
The accumulated locally-accepted milestone (stages 2–5 implementation), plus the
deployment that exists to unblock stage 2's exit.
Why this is one PR
docs/STATUS.md§2.5 says slices are developed and gated locally and publishedonce, in one branch and one pull request, at the milestone. This is that
publication. Everything here has passed the four repository gates locally.
What is in it
AIDevEnv-independent local fleet in
serve; local plan-branch integration andpromotion; normalized remote-review intake with durable deduplication; the
notification outbox; the browser control plane reconciled onto this tree.
github-pr-review— the first installed review source. Per-endpoint identity;disposition from explicit markers and review state, never from a model reading
prose. Unmarked feedback becomes a hold for a person.
PlanPublisherand its wiring — one plan branch, one pull request, correctionsupdate it, an unchanged head touches no remote. Nothing merges or approves.
queue.now()is authoritative for a lease on the retry and block routes.toolremoved from_WIRE_ROLES; the role can never be emitted validly.Dockerfile,.github/workflows/build-deploy.yml, andindexarr/opspersonal/agent-harness(pushed separately as1a5eb34).The deployment, and the one thing that will bite whoever changes it
The controller carries the Docker CLI and no Docker socket; the daemon
arrives through
DOCKER_HOSTfrom a dedicated DinD sidecar on an internalnetwork. The host socket was rejected — root-equivalent on Node B, and it would
make every agent sandbox a sibling of every production stack there.
The worktree volume is mounted at the same path in both containers. A bind
mount is resolved by the daemon that creates the container, not the client that
asks, so a path the daemon does not know is silently replaced by an empty
directory — every agent would get an empty checkout and it would look like a
model defect. This repository already paid for that class of bug once (#216).
The live execution tests deliberately do not run on the publish CI runners:
those reach a separate DinD container with no shared volume, so the same bind
mount would resolve to nothing and the test would prove nothing. Acceptance runs
against the deployed stack's own daemon via Komodo
RunStackService.Gates
1712 tests pass with one skip (the live Docker suite — no daemon on the dev
host, which is the whole reason for this deployment).
ruff check,ruff format --checkandmypyare clean.What is not claimed
No stage exit. No real remote contacted, no real pull request polled, and the
live execution boundary is untested until the deployed stack runs it.