Skip to content

fleet step 4 (#5432): the dispatch thin client over pm-stack - #5551

Merged
dezren39 merged 1 commit into
mainfrom
fleet-step4-dispatch
Nov 4, 2026
Merged

dezren39 merged 1 commit into
mainfrom
fleet-step4-dispatch

Conversation

@dezren39

@dezren39 dezren39 commented Nov 4, 2026 •

Copy link
Copy Markdown
Member

Step 4 of the fleet epic (#5412), closing #5432: the dispatch thin client (D6 — client verbs only; pm-stack is not rewritten, rehomed, or re-platformed; the pm-stack diff attributable to this step is zero).

What lands

New crate crates/fleet-dispatch — verbs over pm-dispatch's live HTTP API, discovered from pm-stack/dispatch/src/server.ts (the service has exactly three routes):

verb route notes
fleet dispatch status GET /health unauthenticated by the service's design; prints the health body + the transport used
fleet dispatch launch POST /v1/sessions repo/prompt/title/model/directory/priority/issue/wait
fleet dispatch enqueue POST /v1/tasks + kind (validated against the service's TASK_KINDS), issue-number attach, dedupe-key

Platform rules hold: the domain is registered like every other (full build carries it; fleet-serve/fleet-connect stub it at 69 — the smoke suite asserts all of it); the bearer token resolves by name through fleet-secrets (pm-dispatch.api-token, [dispatch] token_name overrides) and enters exactly one Authorization header per request — never printed, logged, or stored. fleet-config gains the [dispatch] table (url, token_name, port).

Transports (fleet-queue's two-shape pattern): direct http:// from FLEET_DISPATCH_URL / [dispatch] url, or the laptop seat's zero-config loopback probe; otherwise a CONNECT tunnel on the proxy egress via fleet-proxy's tunnel module. The framed session-broker request shape cannot carry this service's auth — it forwards only X-Agent-Token, which pm-dispatch does not accept — so the client opens its own tunnel on the same egress and speaks HTTP over it. Exit codes: 0 ok · 2 usage · 3 transport/credentials · 4 service HTTP error.

Live-API deltas vs the design note (recorded on #5432)

  • The note's rendered state dir ~/.local/state/pm-dispatch/ does not exist — pm-dispatch keeps no client-readable state; per-task status rides the queue domain, not this one.
  • The note named status+launch; the live API also carries the enqueue submission path (POST /v1/tasks), so the verb set is status/launch/enqueue.
  • Of the service's two auth forms, GitHub Actions OIDC is a CI shape a local client cannot mint; the static bearer is the client form.
  • DISPATCH_API_TOKEN had no by-name vault home (it lived only in the laptop's ~/secrets/dispatch.env), so fleet-secrets could not resolve it. Filed in Bitwarden as pm-dispatch.api-token by this step (value verified byte-identical to the service's by hash; never printed) — a vault filing, not a pm-stack change.
  • Duplicate-dedupe returns the pre-existing task (pre_existing: true + warning), not an error — verified live.

Verification

  • cargo test --workspace: 51 passed, 0 failed (fleet-dispatch +6, fleet-config +2 new). cargo fmt --check clean; clippy clean (run with the rustup toolchain first in PATH — the laptop's mixed cargo/clippy provenance otherwise trips E0514 on pre-existing crates too).
  • All six nix packages build; smoke 62 passed, 0 failed, including a new hermetic dispatch section (stub pm-dispatch + stub bws: status, launch, enqueue, HTTP-error→4, bad-kind→2, unresolved-token→3).
  • Live round-trips against the running pm-dispatch (version d94b8954…) from the shipped builds, detailed on fleet step 4: dispatch thin client domain over pm-stack #5432: laptop status/enqueue/duplicate/launch (session replied with the proof marker; proof tasks 9645/9647/9648 all terminal, proof issue fleet step 4 thin-client proof (launch) #5548 closed), sandbox status + enqueue through the tunnel transport.

Autofix with [code]smith
Open in [code]smith · Need help on this PR? Tag @codesmith-bot with what you need.

Summary by CodeRabbit

  • New Features
    • Added dispatch commands for checking service status, launching sessions, and enqueueing supported task types.
    • Added dispatch settings for the service URL, authentication token name, and port. A nonblank environment variable can override the configured URL.
    • Dispatch requests now use the configured transport options and resolve credentials when authentication is required.
  • Documentation
    • Updated the Fleet guide to describe dispatch setup and available commands.

…eue over pm-stack

New crates/fleet-dispatch: verbs over pm-dispatch's live HTTP API only (D6 — pm-stack untouched): status = GET /health, launch = POST /v1/sessions, enqueue = POST /v1/tasks. The bearer token resolves BY NAME through fleet-secrets (pm-dispatch.api-token, filed in the vault by this step — the token previously had no by-name home); it enters one Authorization header per request and is never printed or stored. Transports follow fleet-queue's two-shape pattern: direct http:// (FLEET_DISPATCH_URL / [dispatch] url, or the laptop seat's loopback probe) and, for the sandbox, a CONNECT tunnel on the proxy egress via fleet-proxy's tunnel module — the framed session-broker request shape forwards only X-Agent-Token, which pm-dispatch does not accept, so the client opens its own tunnel on the same egress. Exit codes: 0 ok, 2 usage, 3 transport/credentials, 4 service HTTP error, 69 capability stub (unchanged machinery). fleet-config gains the [dispatch] table (url/token_name/port); the registry names the enqueue verb the live API carries. Smoke gains a hermetic dispatch section (stub pm-dispatch + stub bws): 62 passed, 0 failed; workspace tests 51/51.
@dezren39
dezren39 requested a review from a team as a code owner November 4, 2026 15:22
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-11-04T15:26:26.418331Z 3a21e13 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@coderabbitai

coderabbitai Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Explain Change →

Caution

Review failed

The pull request is closed.

Walkthrough

Fleet adds a dispatch client for pm-dispatch health, session launch, and task enqueue routes. Dispatch configuration, token lookup, transport selection, command validation, CLI routing, and smoke checks are added.

Changes: Dispatch client

Layer / File(s) Summary
Dispatch configuration and crate setup
pkgs/fleet/crates/fleet-config/src/lib.rs, pkgs/fleet/crates/fleet-dispatch/Cargo.toml, pkgs/fleet/Cargo.toml, pkgs/fleet/crates/fleet/Cargo.toml, pkgs/fleet/README.md
fleet-config adds dispatch URL, token-name, and port settings with defaults and environment-variable URL override. The workspace and fleet feature configuration include fleet-dispatch.
Dispatch commands and HTTP client
pkgs/fleet/crates/fleet-dispatch/src/lib.rs
The client implements status, launch, and enqueue. It selects direct or proxy-CONNECT transport, resolves bearer tokens for POST requests, parses HTTP responses, validates arguments, and maps errors to exit codes.
CLI integration and smoke coverage
pkgs/fleet/crates/fleet/src/main.rs, pkgs/fleet/crates/fleet-registry/src/lib.rs, pkgs/fleet/smoke.sh, pkgs/fleet/README.md
The fleet CLI routes dispatch commands to the client when the feature and domain are available. Registry metadata, smoke checks, and README descriptions cover dispatch commands and requests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant FleetCLI
  participant FleetDispatch as fleet_dispatch::run
  participant FleetSecrets as fleet-secrets
  participant PmDispatch as pm-dispatch
  FleetCLI->>FleetDispatch: Run status, launch, or enqueue
  alt status
    FleetDispatch->>PmDispatch: GET /health
  else launch or enqueue
    FleetDispatch->>FleetSecrets: Resolve configured token name
    FleetSecrets-->>FleetDispatch: Bearer token
    FleetDispatch->>PmDispatch: POST /v1/sessions or /v1/tasks with authorization
  end
  PmDispatch-->>FleetDispatch: HTTP response
  FleetDispatch-->>FleetCLI: JSON output and exit code
Loading

Possibly related issues

  • developing-today/code#5432 — The change implements the requested dispatch verbs against the existing pm-dispatch routes.
  • developing-today/code#5412 — The change adds the dispatch domain and its commands to the fleet multicall binary.
  • developing-today/code#5548 — The launch command implements the /v1/sessions request path described for the one-shot launch proof session.
Merge Risk: Moderate · up to 3a21e

Resolve the loopback credential risk before merging. The client also needs corrections for address handling, response validation, and arguments that can silently change or skip requested work. Configuration tests fail when the supported URL override is set.

- [ ] Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@dezren39
dezren39 merged commit 7648547 into main Nov 4, 2026
1 check failed
@dezren39
dezren39 deleted the fleet-step4-dispatch branch November 4, 2026 15:25

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3a21e13f08

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +193 to +196
.next()
.ok_or_else(|| {
transport_err(format!("cannot resolve dispatch address {authority}"))
})?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Try all resolved addresses before failing a direct connection

When FLEET_DISPATCH_URL or [dispatch] url uses http://localhost:4879 on a host resolving localhost to ::1 before 127.0.0.1, this selects only the IPv6 address and exits with a transport error even though pm-dispatch is reachable over IPv4. The service defaults to binding 127.0.0.1 (pm-stack/dispatch/src/config.ts:81), so this affects an otherwise valid configuration. Iterate over the resolved addresses until one connects rather than discarding every address after the first.

Useful? React with 👍 / 👎.

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