Repository navigation
Description
Design: fleet dispatch-test — explicit-dispatch CI over fleet runner capacity
Status: design of record + MVP built same day (2026-11-06). Direction: Drew, 2026-11-06 11:28 CST.
Supersedes the trigger request in #5663 (closed as superseded): no GitHub Actions
triggers are enabled anywhere — this mechanism is explicit workflow_dispatch only,
consistent with the standing no-auto-CI policy (2026-11-04 ruling, PR #5501). Label:
GitHub Pro / runners program.
Problem
Fleet CI capacity is spread across several GitHub scopes (personal + two orgs), each
with its own hosted-runner concurrency. Load is wildly uneven: measured 2026-11-06
~11:31 CST (in-progress / queued runs): developing-today/code 45 / 244,
developing-today-forks/opencode 7 / 11, developing-today-forks/openchamber 4 / 17,
dezren39/darwin-nix 1 / 1, dezren39/hatch 0 / 0. There is no single place to ask
"where is a runner free right now?" and no generic way to run a build+test on the
emptiest scope with results written back reliably.
The subcommand
New domain in the fleet multicall binary (pkgs/fleet, epic #5412 family):
fleet dispatch-test, verbs scan, submit, status.
Capacity scan
For each scope repo, in configured order:
GET /repos/{r}/actions/runs?status=in_progress— for each run,
GET /repos/{r}/actions/runs/{run_id}/jobsand count jobs with status
in_progressorqueued.GET /repos/{r}/actions/runs?status=queued— each queued run counts as 1 active
unit (a not-yet-started run exposes no jobs; this is the documented
approximation).- Workflow presence:
GET /repos/{r}/actions/workflows— the scope is eligible
only if an active workflow file namedfleet-dispatch-test.ymlexists there.
Eligible = active jobs < threshold AND workflow present. First eligible scope
wins. Threshold is a tunable: --threshold flag / [dispatch-test] threshold
config, default 40 (Drew's tentative figure). Scopes default to
developing-today/code, developing-today-forks/opencode,
developing-today-forks/openchamber, dezren39/darwin-nix, dezren39/hatch
(config-overridable). At the measurement above, code fails the threshold test
outright and hatch is the first scope that is both under threshold and
workflow-equipped — the scan demonstrates both rules on real data.
Auth: a GitHub token resolved by name through fleet-secrets
(default github.ghcr-classic-pat — classic PAT, scopes include repo +
workflow, verified live 2026-11-06; covers every scope above because the
fleet operates as dezren39 in all of them). Follow-up: move to
developing.today-fleet App installation tokens for least-privilege per scope.
Job store: Turso (MVP choice)
Chosen: a dedicated Turso database fleet-dispatch-jobs (created 2026-11-06),
one table:
jobs(id TEXT PRIMARY KEY, created_at TEXT NOT NULL, name TEXT,
target_repo TEXT, target_ref TEXT, script TEXT NOT NULL,
status TEXT NOT NULL, run_id INTEGER, run_url TEXT,
exit_code INTEGER, output_tail TEXT, updated_at TEXT NOT NULL)Why Turso over a CF Worker queue endpoint for the MVP: the fleet already runs on
Turso everywhere (brokers, atlas, ledgers), the HTTP pipeline API
(POST /v2/pipeline) is callable identically from the laptop binary (ureq) and
from a runner step (curl + jq), there is no new service to deploy or keep alive,
and a dedicated database keeps the blast radius at one table. A CF Worker
front-end remains the right hardening step if runner-side access ever needs
rate-limiting or payload validation — the store schema does not change.
Status flow: queued → dispatched → running → succeeded | failed | error.
Token: turso.fleet-dispatch-jobs-token (BWS; also the pilot repo's
DISPATCH_TURSO_TOKEN Actions secret; DB URL is the repo variable
DISPATCH_TURSO_URL).
Job patterns
(2) ID-input — built first (MVP). fleet dispatch-test submit generates an
internal id (dt-<millis base36>-<4 hex>), stores the payload (script, ref,
name) under that id, scans, records the chosen scope on the row, then dispatches
the pilot workflow with the single input job_id. The workflow fetches its job
by id, marks it running (with run id + URL), executes the script, and in an
if: always() step writes back the terminal status, exit code, and the output
tail (last 6000 bytes) — so status lands even on failure, and a crashed or
timed-out run leaves the row in running where status shows it honestly
instead of pretending success. A job can be re-dispatched by id (fresh run row
fields overwrite); retry is roughly idempotent because the payload is immutable
and keyed by the id.
(1) No-inputs pull — designed, not built. A generic workflow dispatched with
no inputs boots, claims the newest queued row (single UPDATE … WHERE id = (SELECT … ORDER BY created_at DESC LIMIT 1) RETURNING shape), executes it, and
writes back exactly as in pattern (2). This is the better shape for bulk work
(no per-job dispatch call, runners pull when free); it lands as a second
workflow mode once pattern (2) has soaked. The store and write-back contract
are already compatible.
Pilot workflow
dezren39/hatch (chosen: zero active runs at measurement time, PAT-owned, no
real CI to disturb) carries .github/workflows/fleet-dispatch-test.yml:
workflow_dispatch with required input job_id, permissions: contents: read,
30-minute timeout, steps fetch → checkout(job ref) → execute → write-back
(always) → upload job-output.log artifact (14-day retention). The workflow
must live on the repo's default branch for dispatch to see it (GitHub rule).
Artifact quotas + return paths
(Research numbers posted as a comment on this issue: per-account artifact
storage GB, cache GB, retention defaults/min/max, private-repo minutes,
concurrency — dezren39 GitHub Pro personal, developing-today org,
developing-today-forks org, with sources.)
Return-path evaluation:
- GitHub Actions artifacts (default). Zero new infra; the output log rides
the run. Limits: per-account storage pools are small on personal/org plans
(see research comment) and retention is capped; fine for logs and small
outputs, wrong for build products. - R2 via a Cloudflare Worker (fallback, when artifacts don't fit). The
fleet already operates Workers + R2 patterns (webhook-gateway, hatch
workers); a presigned-upload Worker endpoint lets a runner stream large
outputs to R2 with no GitHub storage pressure. Build only when a real job
outgrows (1). - Tunnel straight to the laptop (last resort). The lab tunnel
(lab.security.cab) proves the path exists, but runner→laptop transfers
couple CI results to home-network availability; use only for outputs that
must never leave fleet hardware.
Recommendation: (1) by default, (2) when size/retention demands, (3) only on
a stated privacy need. The store's output_tail covers the common case
without any artifact at all.
MVP scope (this build)
fleet dispatch-testdomain: scan / submit / status, threshold tunable,
config in[dispatch-test], tokens by name. (PR + merge link below.)- Turso store as above; pilot workflow in
dezren39/hatch. - One end-to-end proof: a real submitted smoke job (checkout ref, print
environment, exit 0) with scan choice, run URL, and final stored status
recorded on this issue. - Out of scope for the MVP: pattern (1), App-token auth, R2 return path,
installing the new binary fleet-wide (rides the normal fleet build/deploy
path), any change to runner strategy beyond this dispatch mechanism.
Risks / notes
workflow_dispatchrequires the workflow on the default branch of each
participating repo — adding scopes later is a one-file PR per repo.- Runner-side store token is full-access to this one small database by
design; rotation =turso db tokens invalidate fleet-dispatch-jobs+
re-mint + BWS + repo secret update. - The queued-runs-as-1 approximation can undercount a queued multi-job
matrix run; acceptable for a capacity heuristic, revisited if it misleads.
Acceptance criteria
fleet dispatch-test scanreports per-scope in-progress/queued load and workflow eligibility for the five configured scopes, honoring the threshold flag/config (default 40).submitruns a build+test job on the first eligible scope via explicitworkflow_dispatchonly — no automatic GitHub Actions triggers are enabled anywhere.statusreports the dispatched run's state and result from the Turso job store (fleet-dispatch-jobs), including run URL and exit code.- The design's MVP scope is either landed or split into tracked implementation issues linked from this issue; no part of the design sits silently.
Activity
developing-today commentedon Nov 6, 2026
CODE-2002
dezren39 commentedon Nov 6, 2026
Research: GitHub Actions artifact quotas, retention, concurrency (2026-11-06)
All numbers from GitHub Docs / the official
actions/upload-artifactREADME, crawled2026-11-06. Sources: [BILL] https://docs.github.com/en/billing/concepts/product-billing/github-actions ·
[LIM] https://docs.github.com/en/actions/reference/limits ·
[RET] https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository ·
[DISP] https://docs.github.com/en/actions/how-tos/manage-workflow-runs/manually-run-a-workflow ·
[UP] https://github.com/actions/upload-artifact
Billing-model note: current docs express included compute in USD — Free $12/mo, Pro
$18/mo, Team $18/mo, Enterprise Cloud $300/mo. At the standard Linux 2-core rate of
$0.006/min those equal 2,000 / 3,000 / 3,000 / 50,000 Linux minutes [BILL].
dezren39 — personal, GitHub Pro
developing-today — org (plan not publicly disclosed; both rows)
developing-today-forks — org
Identical published numbers to developing-today in both plan rows.
Fleet aggregate concurrency: 40 + 2×20 = 80 (orgs on Free) or 40 + 2×60 = 160
(orgs on Team) — concurrency is per account/plan, not per repo [LIM]. (Note: the
default scan threshold of 40 in this design equals the entire Pro account's
concurrency cap — a scope-level heuristic, revisited once real dispatch data
exists.)
Rules common to all accounts
public repos 1–90 days, private/internal 1–400 days, new artifacts only.
upload-artifactretention-dayshonors the repo setting's max [RET][UP].size cap; the binding constraint is the account storage pool.
workflow_dispatch: max 25 inputs, max payload 65,535 chars; workflowfile must be on the default branch; write access required. No special billing
treatment — a dispatch run bills like any run to the repo owner [DISP][BILL].
storage pool — no authoritative page found says so. Do not design on public-repo
artifacts being free/unmetered.
Support can raise concurrency but cannot raise storage limits.
What this means for the return path
Included artifact space is small and account-wide (1 GB Pro / 0.5–2 GB per org,
shared with Packages), billed by GB-Hour at 90-day default retention — a fleet
returning ~1 GB/day at default retention accrues ~90 GB-months. Artifacts are
therefore the right default only for small, short-lived outputs (the pilot uses
retention-days: 14for a single log file;retention-days: 1+ promptdownload/delete is the pattern for anything routine). Bulk or long-retention
results belong on the R2-via-Worker path (§ return-path evaluation in the issue
body). The store's
output_tailcovers the common case with no artifact at all.dezren39 commentedon Nov 6, 2026
MVP progress (2026-11-06): store + pilot workflow live, loop proven manually
Store: Turso database
fleet-dispatch-jobscreated;jobstable per the designschema. Token vaulted in BWS as
turso.fleet-dispatch-jobs-token(name only) and seton the pilot repo as the
DISPATCH_TURSO_TOKENsecret; DB URL is theDISPATCH_TURSO_URLrepo variable.Pilot workflow:
dezren39/hatchcarries.github/workflows/fleet-dispatch-test.ymlon its default branch (state: active) — PRs dezren39/hatch#5 (initial) and
dezren39/hatch#6 (fix below), merge commits
7c71f768/bc163211.Manual end-to-end proof (job row inserted directly, workflow dispatched with the
id — the same path
fleet dispatch-test submitdrives): jobdt-manual-smoke-1,run https://github.com/dezren39/hatch/actions/runs/42263780711 — success. Final
stored row:
status=succeeded, exit_code=0, run_id=42263780711,output_tailholdsthe executed script's real output (echo marker,
uname -a,git rev-parse HEAD=bc163211). Output artifactdispatch-job-dt-manual-smoke-1(345 bytes, 14-dayretention) uploaded. The failed first attempt's row was reset and re-dispatched by
the same id — retry-by-id works as designed.
Finding worth keeping (bit us live): Turso's
/v2/pipelineAPI requiresinteger argument values encoded as JSON strings (
{"type":"integer", "value":"42263780711"}). A raw JSON number fails the entire request with atop-level
{"error":"JSON parse error: invalid type: integer …, expected a borrowed string"}— no partial results. First smoke run (42263402318) hit exactly this onrun_idand the fetch step misread it as "job not found"; fixed in hatch#6 (stringintegers + surface the store response on fetch failure), and the same rule is being
applied in the Rust subcommand.
Remaining: the
fleet dispatch-testsubcommand PR (pkgs/fleet) and the fullsubmit→scan→dispatch→status proof through the binary.
dezren39 commentedon Nov 6, 2026
MVP complete: end-to-end proof through the binary (2026-11-06)
Subcommand merged: PR #6589, merge commit
0819afd0fc5a987b1602ab880f204908a2183f08— new
fleet-dispatch-testcrate + registry/config/bin wiring, all insidepkgs/fleet(+1269 lines). 11/11 crate tests pass (including the Tursointeger-as-string rule and pipeline error-shape handling); registry/config/bin
test suites pass; live
scansmoke on the merged code:(
codeis over the 40 threshold on its own; three scopes are under threshold butcarry no dispatch workflow yet; hatch is the first scope passing both tests.)
End-to-end run:
fleet dispatch-test submit --name "e2e proof 2026-11-06"produced:
{"job_id": "dt-mw5a91oz-b27b", "repo": "dezren39/hatch", "active_at_scan": 0, "threshold": 40, "status": "dispatched"}Run: https://github.com/dezren39/hatch/actions/runs/42267204516 — and
fleet dispatch-test status dt-mw5a91oz-b27breads back the final stored record:status=succeeded, exit_code=0,output_tailcontaining the job script's realoutput (
dispatch-test-e2e-proof, runneruname -a,git rev-parse HEAD=bc163211). Submitted 18:03:14Z, terminal status stored by 18:03:36Z.Deliberately not done in the MVP (per design): pattern (1) no-inputs pull,
App installation-token auth, R2 return path, fleet-wide install of the new
binary (rides the normal fleet build/deploy path — the proof ran the worktree
build of the merged code), and adding the workflow to further scopes (one-file
PR per repo when wanted).
Process note: both merges in this build (hatch#5/#6, code#6589) went through the
REST merge endpoint because the user token's GraphQL pool was secondary-rate
-limited at merge time; all merges verified by readback.
dezren39 commentedon Nov 6, 2026
Correction of record — Drew, 2026-11-06 11:30–11:32 CST (delivered while this was being built; the build lane was unreachable for steering, so it lands now):
The MVP above proves the dispatch mechanics — capacity scan, ~40 threshold, Turso job store, ID-input jobs, status/output write-back,
workflow_dispatchonly — and those carry over. But the execution model differs from the design Drew specified in three defining ways:Phase 2 = rework the execution model to 1–3 on top of the proven mechanics. First deliverables: identify the fleet repo (the dezren39 repo whose
.gitmodulescontains the other repos) and map its fork network / copies.dezren39 commentedon Nov 6, 2026
Phase 2 — Step 0: fleet repo identified + fork network mapped
Fleet repo:
dezren39/fleet— the dezren39 repo whose.gitmodulesholds the other repos as submodules. Verified viagh api repos/dezren39/<repo>/contents/.gitmodulesacross the candidate set:dezren39/fleet✔ — submodules:code(developing-today/code),opencode+openchamber(developing-today-forks/*),nix(dezren39/darwin-nix),hatch,hatch-personal,cairn,zettel,dezren39-zettel,org-readme,zulip-archive,hardware-doc.dezren39/hatch,dezren39/darwin-nix,dezren39/hatch-personal,dezren39/cairn,dezren39/openchamberhave no.gitmodules;dezren39/openclaw-personalhas one but it only self-references (openclaw), not the fleet set.Fork network (
gh api repos/dezren39/fleet/forks; both forks report 0 forks of their own, so the network is one level deep today):dezren39/fleetmaindeveloping-today/fleetdeveloping-today-forks/fleetThese three are the dynamic scope set for phase 2:
fleet dispatch-test scandiscovers them (source + forks, recursively) instead of the MVP's hardcoded five-repo list; config[dispatch-test] scopesremains a pin/override.Cache wiring (found, not invented): the fleet repo's partial preloaded nix cache is the
ghcr.io/developing-today/fleet-build:fulljob-container image — per-repo dev-shell closures realised from each submodule'sflake.lockexactly as committed (containers/fleet-build/warm-manifest.txt+export.sh, published byfleet-build-container.yml) — plus the baked substituters (nix-cache.developing-today.workers.dev,developing-today.cachix.org). The generic workflow runs inside that image, following thefleet-run.ymlpattern.Phase 2 build follows in this thread.
dezren39 commentedon Nov 6, 2026
Phase 2 — execution model reworked to the corrected design ✅
PRs (all merged):
20fa4326) —fleet-config+fleet-dispatch-testrework. 13 crate tests pass (2 new).153d5c23) — the generic workflow, now living only there.What changed vs the MVP:
scan/submitresolve scopes per invocation: the fleet repo ([dispatch-test] fleet_repo, defaultdezren39/fleet) + its fork network (breadth-first, forks of forks).[dispatch-test] scopesis now a pin/override — when non-empty it is used verbatim; empty = discover. The MVP's hardcoded five source repos are gone.submit --submodule code --ref main --commands '…'(ref empty = the submodule stays at the umbrella's recorded SHA). Deliberate store migration:jobsgainssubmodule+commands(idempotentALTERin the verbs);target_refnow carries the submodule ref;scriptmirrorscommandsfor MVP-era readers. Legacy rows (no submodule) fail loudly in the workflow rather than guessing.fleet-dispatch-test.ymlin dezren39/fleet):workflow_dispatchonly, sole inputjob_id; fetches the row, checks out the fleet repo, inits only the named submodule (private ones via the copy'sGHCR_ORG_PATwhen present), fetches + checks out the named ref, runs the commands inside the submodule, and writes status/exit/output-tail back on every exit path; output log uploaded as an artifact. It runs inghcr.io/developing-today/fleet-build:full— the fleet repo's partial preloaded nix cache (per-submodule dev-shell closures from committed locks;NIX_CONFIGmirrorscontainers/fleet-build/export.sh, the fleet-run-proven wiring).Getting the workflow into the copies — a design fact found on the way: the org copies'
mainbranches are actions-only mirrors (rulesetmain: actions-only (commits happen upstream); sole bypass = the developing.today App). Direct pushes, PR merges, and merge-upstream are all ruleset-rejected (422) — by design. The sanctioned flow is thesync-upstreamworkflow (defined upstream, runs in the forks, pushes as the App). I closed the two file PRs I'd opened on the forks unmerged and dispatchedsync-upstreaminstead: run 42269001822 ✅ —developing-today-forks/fleetnow carries the workflow, active.One copy is not (yet) an execution home:
developing-today/fleethas Actions disabled repo-wide (dispatch returns 422 "Actions has been disabled for this repository"), so its sync can't run and scan finds no workflows there. Not flipped by this lane — it's a repo-settings decision. Scan handles it correctly today (ineligible); it becomes a home the moment Actions is enabled + one sync runs. ItsDISPATCH_TURSO_URLvar +DISPATCH_TURSO_TOKENsecret are already set (as on the other two copies), so nothing else blocks it.Live scan (new binary, post-merge):
Proof 1 — real build, scan-selected copy: job
dt-mw5aq0xn-e72f, submodulecode@main, commandsnix build .#fleet→ run 42269192018 on dezren39/fleet — succeeded, exit 0. The stored output tail shows the build inside the submodule checkout (substituting from cache.nixos.org, realising the fleet derivations) and ends with the freshly builtresult/bin/fleetansweringdispatch-test --help.Proof 2 — failure write-back, fork copy: job
dt-mw5aq8bd-5896, forced--repo developing-today-forks/fleet, submodulecode@main, commandsecho proof-failure-marker; git rev-parse HEAD; exit 3→ run 42269212209 — statusfailed, exit_code 3, output tail written back, including the ref evidence: submodule initialised at the recorded SHAb0c472d9, thenmainfetched and checked out at20fa4326(this phase's own code merge) before the commands ran.Phase 3 candidates unchanged from the design: no-inputs pull mode, App-token auth per scope, R2 return path.
dezren39 commentedon Nov 6, 2026
Correction to the Step-0 evidence above (one candidate detail was wrong; the conclusion is unchanged):
dezren39/hatchdoes have a.gitmodules— it surfaced in a slower verification pass after the phase completed. Its submodule set is a different, older one (repos/code→ developing-today/code,repos/opencode/repos/openchamber→ the developing-today originals, not developing-today-forks/*, plusrepos/nix→ dezren39/nix, two zettels, and dezren39/dezren39) — not the fleet set the gate specified (code + forks/opencode + forks/openchamber + darwin-nix + …).dezren39/fleetremains the only repo whose.gitmodulescontains the fleet's repos, so the identification stands; only the per-candidate note for hatch ("no .gitmodules") was inaccurate.dezren39 commentedon Nov 6, 2026
Intake review — fleet monitor (2026-11-06)
Related: issue #5663 (closed as superseded by this design), epic #5412 family (fleet multicall binary). No merged PR found at intake that closes this design item; the body states an MVP was built the same day, so a worker should verify what already landed before implementing.
Notes: design of record filed from Drew's 2026-11-06 direction; formalized an Acceptance criteria section (original body preserved verbatim above it). Effort/l because the full design spans scan/submit/status plus a job store, even if the MVP covers part of it.
Risks: token scope (classic PAT across five scopes) is the sensitive piece — the body's own follow-up (developing.today-fleet App installation tokens) should not be lost. Runner-capacity counts are documented approximations for queued runs.
Suggested approach: inventory what the same-day MVP already implements against the criteria above, close or split the remainder into implementation issues, and link them here.
dezren39 commentedon Nov 6, 2026
Codespaces / Actions / Blacksmith evaluation — results + saturation plan (2026-11-06)
Drew ruled 2026-11-06 13:54 CST: the evaluation is STILL WANTED, expanded — "explore Blacksmith and use all of Codespaces' actions in Blacksmith to the limit for test builds and compiles and other examples using the fleet binary." Full report:
goals/efficient-use-of-codespaces-actions-and-blacksmith/files/codespaces-actions-blacksmith-saturation-2026-11-06.md(hatch-personal). Headlines:Blacksmith — already ours; org-only; free pool is the budget
blacksmith-sh(installation 172729446) is installed on the developing-today org, all repos, not suspended — verified via the installations API today. Free tier is the standing state since 2026-10-18: 3,000 free minutes/mo per org, counted in 2-vCPU x64 minutes and weighted by size (4 vCPU burns 2/min, macOS M4 6 vCPU burns 20/min). Past the pool: $0.004/min per 2 vCPU x64, ARM $0.0025, Windows $0.008, macOS $0.08. No card, no paid signup, no spend.actions/cache(~400 MB/s, 25 GB/repo included); Docker/git caching on sticky disks at $0.50/GB/mo. No first-class Nix story — irrelevant for us, our jobs run in fleet-build:full with the R2 + Cachix substituters.Timed test — the same fleet-binary build on both runner kinds
nix build .#fleet, 2bb30755, fleet-build:full container:nix buildin fleet-run/org-run dies in 0 s — job containers run as root with no nix.conf ("experimental Nix feature 'nix-command' is disabled", run 42284554666). fleet-dispatch-test carries an explicit NIX_CONFIG; fleet-run/org-run commands must inline the experimental-features + substituter flags. Bench plumbing left in place:blacksmith-bench.ymlin developing-today/nix-cache (PR Bump checkmarx/ast-github-action from 2.0.11 to 2.0.18 #2), dispatch-only.Codespaces — 177.5 of 180 core-hours sitting unspent
ghtokens lack thecodespaceOAuth scope (403), the classic PAT has no codespace scope, and the fleet Apps hold no Codespaces permission. The single fix is one interactivegh auth refresh -h github.com -s codespaceon the laptop — flagged to Drew's queue as a 2-minute laptop step, not a blocker for the plan.Actions capacity — concurrency is the budget, not minutes
November gross, 100% discounted to net $0: personal 9,692 Linux min; org 152,727 Linux min (+2,863 ARM, 3,368 Windows). Public repos = unlimited free standard minutes; the Pro 3,000 min/mo binds only private repos. Concurrency: personal Pro 40 + each Free org 20 = 80 GitHub-hosted slots, plus Blacksmith's uncapped side-pool for org repos. macOS is scarcest everywhere (5/owner hosted; Blacksmith M4 at 20× pool burn).
Saturation plan (shape — full text in the report)
dezren39 commentedon Nov 6, 2026
Correction to the evaluation comment above (same day, 2026-11-06 20:16Z check)
One queue figure in my previous comment is withdrawn as unverified-and-wrong:
dezren39 commentedon Nov 6, 2026
Final addendum — the two org-run legs (2026-11-06, 20:38Z, jobs API)
Closing out the loose end from the evaluation: the redispatched org-run pair — 42285076694 (GitHub-hosted leg) and 42285084177 (Blacksmith leg) — was still queued 34.6 minutes after dispatch, setup jobs never assigned a runner, when I checked at 20:38Z and cancelled both (the measurement was complete; the direct-label bench in nix-cache had already produced the Blacksmith numbers, and the org GitHub-hosted build number exists from the personal pool's identical runner class).
So the org pool's verified queue picture for the day: ~5.7 min (first pair, cancelled) and 34.6 min, never started (second pair) — against 8 s (personal pool) and 12 s (Blacksmith) starts for identical work. No further runs are outstanding from this evaluation.
developing-today commentedon Nov 7, 2026
SETUP pass (2026-11-06 evening) — the evaluation above existed but nothing was wired to use it (Drew, 18:00 CST). Results:
1. org-run setup job now runs on Blacksmith by default — DONE + PROVEN.
PR #6639 (merged, 4e92da9) adds a
setup_runnerworkflow_dispatch input (blacksmith|github, default blacksmith) and points org-run's setup job at it; legs still follow the existingrunnerinput. No triggers added (dispatch-only per #5663).Proof — run 42315999625 (trivial
trueleg): setup created 00:04:59Z, started 00:05:06Z on a Blacksmith runner = 7 s queue latency (vs the 34.6 min never-assigned GitHub-hosted setup measured earlier today), completed successfully in 4 s. The same run's GitHub-hosted leg then waited 20m25s in the org queue (created 00:05:10Z, started 00:25:35Z) — the bottleneck, measured inside one run.2. Cold CPU-bound benchmark — DONE. Blacksmith ~1.4× on real compile.
The first benchmark tied because
nix build .#fleetwith substituters is cache/fetch-bound. New dispatch-only harnesscpu-bench.ymlin developing-today/nix-cache (PRs #3, #4, #5, #6) compiles the fleet crate workspace (pkgs/fleet@ 4e92da9; 10 crates, 65 compilation units per leg) from a clean checkout + clean CARGO_HOME, no substituters, no cargo caches, same container, cargo/rustc 1.99.0 both sides.Run 42317817936: Blacksmith 29.86 s vs GitHub-hosted 42.25 s (cargo "Finished" timings; COMPILE_SECONDS markers 30 vs 42 agree). Verdict: a real ~1.4× CPU edge, not the ~1.9× single-thread claim — and queue latency remains the larger, structural win.
Harness gotcha worth keeping: the fleet-build image ships Rust ONLY as a nix-store toolchain (
/nix/store/*-rust-default-1.99.0/bin/cargo) — not on root's PATH, not in any cargo home/profile; the harness now discovers it by glob.Total Blacksmith burn for this whole setup pass: ~5 weighted minutes of the org's 3,000/mo free pool (proofs + benchmark + failed harness iterations). No overage.
3. developing-today-forks installs (blacksmith-sh + coderabbitai) — BLOCKED on one Drew tap.
Verified by API readback: neither app is installed on the forks org (only claude, developing-today-backup, developing-today, developing-today-fleet are). The Blacksmith install was driven to the final click in the laptop's signed-in browser (org developing-today-forks, "All repositories", Install & Authorize) and stopped at GitHub's sudo-mode Confirm access gate (passkey/GitHub Mobile/authenticator = Drew's physical acts). A Helium tab is staged on that page; one ~30 s authentication completes the Blacksmith install and leaves sudo mode warm for hours, after which the CodeRabbit install is a two-minute follow-up. Filed as #6645 with the exact steps. Prize: a second 3,000-min/mo Blacksmith free pool + CodeRabbit coverage for opencode/openchamber (forks-org residents since 2026-11-04).
Full SETUP STATUS section appended to the saturation report in the goal workspace (codespaces-actions-blacksmith-saturation-2026-11-06.md §5). The saturation plan in §4 is unchanged — and now executable: org-run dispatches no longer gate on the org GitHub-hosted queue by default.
dezren39 commentedon Nov 7, 2026
Design Deliverables: Cold CPU-Bound Benchmark & Codespaces Overflow Seat Plan
Following Drew's 2026-11-06 direction on the Actions/Codespaces/Blacksmith saturation program, the complete design artifact has been produced at
/home/user/gemini-burn-2026-11-06/BENCH-CODESPACES-DESIGN.md. Below is the summary of both designs and the governing decision rules.(A) Cold CPU-Bound Benchmark Design (Deciding the 1.9× Silicon Claim)
The initial fleet binary benchmark tied (2m25s vs 2m29s) because Nix compilation with substituters is fetch/network-bound. Preliminary testing on a clean Rust compile (
pkgs/fleetincpu-bench.yml, run 42317817936) showed Blacksmith at 29.86 s vs GitHub-hosted 42.25 s (~1.41× speedup). The benchmark design formally decides the 1.9× claim:pkgs/fleet@4e92da931, 10 crates, 65 compilation units) compiled withcargo build --release --locked.ghcr.io/developing-today/fleet-build:fullusing the pinned image-baked toolchain (rustc 1.99.0in the/nix/store).ubuntu-24.04(2 vCPU, 8 GB RAM, Azure hypervisor).blacksmith-4vcpu-ubuntu-2404(4 vCPU, 16 GB RAM, bare-metal high-frequency desktop silicon).blacksmith-8vcpu-ubuntu-2404(8 vCPU, 32 GB RAM).$RUNNER_TEMP/cargo-targetand$RUNNER_TEMP/cargo-homecreated fresh per job and discarded.cargo vendor) during setup eliminates crates.io network latency variance from the compile timer.actions/cache, zero Blacksmith sticky disks/cache proxies, zero Nix substituters.nprocand inspects/proc/cpuinfo; ifnproc > expected_cores, the run is flagged (TIER_UPGRADE_DETECTED=true) and segregated from baseline statistics.lscpu),/usr/bin/time -vmetrics (wall clock, user/system CPU seconds, % CPU utilization, peak RSS), cargo finished time, and calculated pool-minute draw.cpu-bench-matrix.yml(workflow_dispatchONLY per code#5663).(B) Codespaces Standing-Overflow-Seat Plan
The dezren39 GitHub Pro account includes 180 core-hours/month compute + 20 GB storage, currently sitting ~98% unspent (~177.5 core-hours unspent in November).
dezren39/fleet):dezren39/fleetusingghcr.io/developing-today/fleet-build:fullto drop cold create times from ~27 min to ~1–2 min.updateContentCommandupdates public submodules in parallel and gracefully tolerates private submodules (hatch-personal,cairn) so prebuilds succeed without private token gates.main; template retention set strictly to 1 version (~1.86 GB storage).fleet-overflow-seat).developing-today/code:nix build .#fleet+ workspacecargo test --release.developing-today-forks/opencode:bun install && bun run build && bun test.developing-today-forks/openchamber:nix build .#openchamber+ test suite.dezren39/darwin-nix:nix flake check.cargo clean) and cleanly stop codespace (gh codespace stop).gh auth refresh -h github.com -s codespaceon Drew's laptop to unlock CLI control.Full design specification and workflow definitions are preserved in
/home/user/gemini-burn-2026-11-06/BENCH-CODESPACES-DESIGN.md.dezren39 commentedon Nov 7, 2026
Dispatch-test follow-up (2026-11-06 19:19 CST): Drew ruled "enable Actions on developing-today/fleet." On executing, live state was already enabled — verified twice: returns enabled=true, allowed_actions=all, and all 5 workflows (fleet-build container, fleet-build variant, fleet-run generic dispatch runner, fleet umbrella verification, sync-upstream) show state active. The Phase 2 note recording Actions as disabled repo-wide was stale. No settings change was needed; developing-today/fleet is an eligible dispatch home alongside dezren39/fleet.