Repository navigation
Description
What
The fleet's placement capability — deciding WHERE a build job runs
across the fleet's GitHub Actions copies and runner providers, and
dispatching it there — currently exists as a reference
implementation in the org fork of the fleet umbrella:
- Spec + frozen client interface:
docs/placement.mdin
developing-today/fleet (branchfleet-place, commit1258ed8;
lands on the fork's main once the fork is added to this app's
installation — see below). - Reference implementation:
tools/fleet-place+ the data registry
tools/fleet-surfaces.jsonin the same repo.
Drew's direction (2026-11-04): this capability belongs in the binary
clients already use — repo-queue — so lane workers and Muse
clients trigger jobs in the appropriate location through one
interface, with sessions that outlive the client (reconnect by
handle). The crates are being refactored in another line of work
today; this issue is the absorption spec so that work inherits the
architecture instead of redesigning it. Do not treat the Python
dispatcher as the destination.
The contract to implement (from placement.md, frozen v1)
repo-queue dispatch --repo developing-today/code \
--command 'nix build .#mcpx' [--ref SHA] \
[--runner auto|github|blacksmith] [--surface ID] \
[--push-nix-cache] [--actions-cache KEY:PATH] \
[--allow-paid-blacksmith MINUTES]
# -> session handle (fp_...), chosen surface, reasoning
repo-queue session status HANDLE # mapped state + run URL
repo-queue session result HANDLE # terminal result
repo-queue session list [--mine]Non-negotiables:
- Registry as data. Surfaces live in
tools/fleet-surfaces.json
(id, kind, owner, repo, workflow, app installation, capacity /
budget posture, eligibility). Adding a location = adding an
entry (+ app installation + a fleet copy). The binary reads the
same registry format; no surface is ever hardcoded. - Adapters per placement kind. github-actions dispatch,
blacksmith (runner variant, org-only, budgeted), codespace
(session handoff, last resort), laptop (recorded handoff) —
each behind eligible/capacity/dispatch/status. A new placement
type = a new adapter + akindvalue; dispatch/session logic
untouched. - App-only dispatch. Every dispatch mints an installation
token for the host repo's owner through the fleet-paperwork
flow (App private key from the sops secrets file). Both
installations (org 174792676, personal 175747567). No user-token
path; a surface the app cannot reach is ineligible, loudly. - Sessions server-side. Handle =
fp_+ 128-bit random.
Record: payload, surface + why, run id/URL, submitter, state,
timestamps. DDL foragent.placement_sessionsis in
placement.md (the Python stopgap is a local JSON store with
identical semantics — migrate records, don't redesign them). - Spill cascade. GitHub-hosted capacity per owner (live
running+queued vs plan cap) → Blacksmith inside its free
3,000 min/mo budget (paid only via explicit per-job allowance or
the registry's paid cap) → Codespaces when Actions is tapped and
the laptop is saturated → otherwise the job stays queued in
repo-queue. Nothing is dropped for lack of a surface. - Caching passthrough. fleet-run jobs may carry per-entry
cache options (nix closure → fleet R2 cache via the existing
signing machinery; actions/cache for non-nix artifacts). The
dispatch command exposes them as flags, unchanged.
Proof state of the reference implementation (2026-11-04)
- Dry-run cascade verified, incl. simulated spill to Blacksmith and
the all-tapped → queued outcome. - Real dispatch as the app: session
fp_5ccf1d4ca63f4ca0939fd909345bd9ad,
run https://github.com/dezren39/fleet/actions/runs/41819899125
(triggering actordeveloping-today[bot]), pin-check job read
back tosucceededvia the session handle.
Blockers that also gate this
- developing-today/fleet is not yet in this app's installation
scope (org-owner grant pending) — the reference branch waits on
it to push. - org-run (this repo) is pre-registered as a surface; when it lands,
flip its registry status and give it therunnerinput for
Blacksmith parity (small follow-up PR, noted in placement.md).
Unassigned on purpose; pick up with the queue refactor.
Acceptance criteria
- fleet placement (dispatch + session commands per docs/placement.md in developing-today/fleet) is absorbed into repo-queue.
- No regression: existing tests/checks for the touched area remain green, and the change lands via PR referencing this issue.
- Evidence (PR link, test/CI output, or verification note) is posted on this issue before it is closed.
Activity
dezren39 commentedon Nov 4, 2026
Intake review
🤖 Agent note · state: filed
Related: epic #5412 and steps #5429-#5433 form one set; #5413 is a sibling absorption task. Native sub-issue attachment per protocol §11 is recommended for the epic if not already done.
Risks: Low for the intake pass itself; implementation risk lives in the issue body.
Suggested approach: Triage through the queue in dependency order, verifying each step's acceptance evidence before closing.
dezren39 commentedon Nov 5, 2026
🤖 Agent note · done (triage)
docs/placement.md, branchfleet-place)Triage findings for issue #5413 (task 10037)
Verified current (2026-11-05, fresh reads): issue #5413 is OPEN, filed 2026-11-04T11:22:49Z, with no hard-stop labels (
held,user/owned,do-not-merge,do-not-auto-edit). The absorption has not happened: the livefleetbinary (0.1.0, checked this triage) registers domains queue / serve / proxy / dispatch / secrets / search / laptop-agent, andfleet queue dispatchanswersunknown command "dispatch"— there are no placementdispatch/sessioncommands in the queue domain, and noagent.placement_sessionsclient surface. The existingdispatchdomain is a different thing (a thin client over pm-stack dispatch, per its own help text) and must not be mistaken for the placement contract indocs/placement.md. No PR or issue implements issue #5413: the only issues referencing it are issue #5942 (fleet-paperwork tests run by no workflow) and issue #5713 (flag handling in the pm-stack dispatch domain) — adjacent, not this absorption.Gates recorded (both already named in the issue body; re-verified as still standing):
dispatch+session status/result/list,fp_handles, registry-as-data, app-only dispatch) is unchanged by that move.fleet-place(commit1258ed8) still waits to land on the fork's main. The repo itself is reachable viagh(verified this triage); the grant is the Drew-owned step, exactly as recorded at filing — it is not a new blocker discovered here.Scoped pickup path (when the gates clear): implement per the frozen v1 contract in
docs/placement.md— registry read fromtools/fleet-surfaces.jsonformat with no hardcoded surfaces, one adapter per placement kind behind eligible/capacity/dispatch/status, installation-token-only dispatch via the fleet-paperwork flow, server-sideagent.placement_sessionsrecords migrated from the Python stopgap's JSON semantics, spill cascade and caching passthrough unchanged — landed via PR referencing this issue, per its acceptance criteria.The issue stays open, labelled triaged + waiting-dependency to mirror gates 1–2. No code change in this triage.