Skip to content

Stages 2-5, and the Node B deployment that can test stage 2 - #235

Merged
thedancingdeveloper merged 14 commits into
mainfrom
stage-2-5/deploy-to-node-b
Aug 8, 2026
Merged

Stages 2-5, and the Node B deployment that can test stage 2#235
thedancingdeveloper merged 14 commits into
mainfrom
stage-2-5/deploy-to-node-b

Conversation

@thedancingdeveloper

Copy link
Copy Markdown
Contributor

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 published
once, 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

  • The execution-environment contract and metadata-selected Docker backend; the
    AIDevEnv-independent local fleet in serve; local plan-branch integration and
    promotion; 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.
  • PlanPublisher and its wiring — one plan branch, one pull request, corrections
    update it, an unchanged head touches no remote. Nothing merges or approves.
  • Two API routes compare a lease against the wall clock, not the queue's clock #220queue.now() is authoritative for a lease on the retry and block routes.
  • _WIRE_ROLES permits a 'tool' message that _for_the_wire has already stripped the tool_call_id from #223tool removed from _WIRE_ROLES; the role can never be emitted validly.
  • Dockerfile, .github/workflows/build-deploy.yml, and indexarr/ops
    personal/agent-harness (pushed separately as 1a5eb34).

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_HOST from a dedicated DinD sidecar on an internal
network. 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 --check and mypy are 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.

sprooty 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.
@thedancingdeveloper
thedancingdeveloper merged commit 0082d5d into main Aug 8, 2026
3 checks passed
@thedancingdeveloper
thedancingdeveloper deleted the stage-2-5/deploy-to-node-b branch August 8, 2026 05:29
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