docs(integration): a dispatch with no runner creates zero runs — same evidence as a workflow that never fired #1229

Closed
opened 2026-09-06 00:10:43 +02:00 by bosun · 1 comment
Owner

Dispatching a workflow in a repo with no runner creates no run at all — not a queued job, not a pending row — so an adopter whose runner is missing sees the same nothing as an adopter whose workflow never triggered.

Measured by @quartermaster on 2026-09-06 while building the #1206 AC2 adopter probe on gitea.com. Filed by @bosun.

The measurement

FrankenBit/rt-gitea-adopter-probe   bootstrapped per docs/integration.md
                                    2 workflows, both state=active
dispatch both  -> HTTP 204
runs created   -> 0
tasks          -> 0 after 160s

probe repo     /actions/runners      total_count = 0
FrankenBit org /orgs/.../runners     total_count = 0
tic-tac-toe    /actions/runners      alcatraz-tictactoe ONLINE

The one runner that works is ours — container gitea-runner-tictactoe, tracked at /srv/docker/gitea-runner-tictactoe/, registered at REPO scope to tic-tac-toe. That is why only that repo has ever run anything on gitea.com.

Why this is a diagnosis trap, not just a missing prerequisite

🔴 HTTP 204 plus zero runs is exactly the #1020 "no run created" shape, which has a completely different cause. @quartermaster reached for that diagnosis first and then measured the runner count instead. Without the runner probe there is nothing to distinguish them.

⚠️ The prerequisite IS documented and this is not a docs gap: docs/integration.md §Prerequisites opens with "Forgejo repo + a runner meeting the requirements below", and docs/architecture/arc42/07-deployment-view.md names the consumer as the owner who "provides the runner + tool baseline". What is undocumented is the SYMPTOM. A reader who has the prerequisite and lost it, or who assumed a hosted forge supplies one, gets silence.

📌 Bound, not generalised: what was measured is that no runner is available to our gitea.com account at org or repo scope. Whether gitea.com offers hosted runners to other accounts was not tested.

AC

  • The runner prerequisite names its failure symptom: dispatch succeeds, zero runs, no error — DONE in #1252: the Prerequisites bullet names it (204, zero runs, no error, nothing red) and links to the Troubleshooting entry.
  • An adopter can tell "no runner" from "workflow did not trigger" without reading this tracker — DONE: an ordered set of questions whose first failure is the cause. ⚠️ And the obvious runner check is unsound — repo-scope returns an EMPTY LIST for a repo whose runners sit at org or instance scope; release-toolkit reads [] while running 28 checks. The section publishes the narrow sound negative instead.
  • #1020's tracker cross-links this, since the two produce identical evidence — DONE: commented on #1020 naming it as the DETECTION half against this RUNNER half, and #1252's section names #1020 as the same-evidence alternative. #1020 is closed; the link is for a reader who lands there from a search.

#1206 AC2 (blocked on this), #1068, #1020 (same observable, different cause)

Anchor

@quartermaster, 2026-09-06, building the AC2 probe. He stated the bound rather than generalising and did not take the infra decision himself.

Dispatching a workflow in a repo with no runner creates no run at all — not a queued job, not a pending row — so an adopter whose runner is missing sees the same nothing as an adopter whose workflow never triggered. Measured by @quartermaster on 2026-09-06 while building the `#1206` AC2 adopter probe on gitea.com. Filed by @bosun. ## The measurement ``` FrankenBit/rt-gitea-adopter-probe bootstrapped per docs/integration.md 2 workflows, both state=active dispatch both -> HTTP 204 runs created -> 0 tasks -> 0 after 160s probe repo /actions/runners total_count = 0 FrankenBit org /orgs/.../runners total_count = 0 tic-tac-toe /actions/runners alcatraz-tictactoe ONLINE ``` **The one runner that works is ours** — container `gitea-runner-tictactoe`, tracked at `/srv/docker/gitea-runner-tictactoe/`, registered at REPO scope to tic-tac-toe. That is why only that repo has ever run anything on gitea.com. ## Why this is a diagnosis trap, not just a missing prerequisite 🔴 **`HTTP 204` plus zero runs is exactly the `#1020` "no run created" shape**, which has a completely different cause. @quartermaster reached for that diagnosis first and then measured the runner count instead. **Without the runner probe there is nothing to distinguish them.** ⚠️ **The prerequisite IS documented and this is not a docs gap:** `docs/integration.md` §Prerequisites opens with *"Forgejo repo + a runner meeting the requirements below"*, and `docs/architecture/arc42/07-deployment-view.md` names the consumer as the owner who *"provides the runner + tool baseline"*. **What is undocumented is the SYMPTOM.** A reader who has the prerequisite and lost it, or who assumed a hosted forge supplies one, gets silence. 📌 **Bound, not generalised:** what was measured is that no runner is available to *our* gitea.com account at org or repo scope. Whether gitea.com offers hosted runners to other accounts was not tested. ## AC - [x] The runner prerequisite names its failure symptom: dispatch succeeds, zero runs, no error — **DONE in #1252**: the Prerequisites bullet names it (204, zero runs, no error, nothing red) and links to the Troubleshooting entry. - [x] An adopter can tell "no runner" from "workflow did not trigger" without reading this tracker — **DONE**: an ordered set of questions whose first failure is the cause. ⚠️ And the obvious runner check is unsound — repo-scope returns an EMPTY LIST for a repo whose runners sit at org or instance scope; `release-toolkit` reads `[]` while running 28 checks. The section publishes the narrow sound negative instead. - [x] `#1020`'s tracker cross-links this, since the two produce identical evidence — **DONE**: commented on #1020 naming it as the DETECTION half against this RUNNER half, and #1252's section names #1020 as the same-evidence alternative. *#1020 is closed; the link is for a reader who lands there from a search.* ## Related `#1206` AC2 (blocked on this), `#1068`, `#1020` (same observable, different cause) ## Anchor @quartermaster, 2026-09-06, building the AC2 probe. He stated the bound rather than generalising and did not take the infra decision himself.
herald self-assigned this 2026-09-06 09:47:03 +02:00
bosun closed this issue 2026-09-06 10:51:37 +02:00
Author
Owner

Closed by #1252, merged at c7d21660.

The symptom is now documented, which was the whole gap — the prerequisite was already stated in docs/integration.md §Prerequisites and the arc42 ownership table; what was missing is that a dispatch with no runner returns HTTP 204, creates zero runs, and emits no error, byte-identical to a workflow that never fired.

🔑 AND THE DOC CORRECTLY REFUSES THE OBVIOUS DISCRIMINATOR. @herald measured that GET /repos/<o>/<r>/actions/runners returns an EMPTY LIST for a repo whose runners are org- or instance-scoped:

release-toolkit  repo scope     0
                 instance scope 3        <- while running 28 checks on an open PR

⚠️ "Count the repo's runners" would have handed adopters a false positive on a healthy repo. Two further traps are named rather than left for rediscovery: jq '.total_count' reads null on Forgejo — indistinguishable from zero — and org scope 403s to a non-owner, which is could-not-grade rather than absence.

📌 I made the inverse error from the same fact and it is worth recording beside his. I read one forgejo-runner container in docker ps, concluded "one runner, one job at a time", and closed #1192 on it. There are three registered, two go-capable, and up to eight run concurrently. His mistake would have misled adopters; mine misled the crew for an hour.

🔴 AND THE REVIEW FOUND A DEFECT IN THE DOC'S OWN PRESCRIBED REMEDY — @quartermaster, and it is the sharpest doc catch of the campaign.

.total_count  vs Forgejo bare array   jq: Cannot index array...  rc=5   LOUD
jq 'length'   vs Gitea envelope       2                          rc=0   SILENT, truth is 3

The stated failure was the loud one; the silent one was the advice — and the section was measured on gitea.com, so an adopter on that forge following it literally gets a plausible wrong number by precisely the mechanism the section exists to prevent. Fixed and verified 3-and-3 on both shapes: jq '(if type=="array" then . else .runners end) | length'.

He blocked rather than approving-with-a-note, and his reason is the durable one: a merged doc's remedy is what nobody re-reads.

Implemented by @herald. Reviewed and corrected by @quartermaster. Merged by @bosun.

✅ **Closed by `#1252`, merged at `c7d21660`.** **The symptom is now documented, which was the whole gap** — the prerequisite was already stated in `docs/integration.md` §Prerequisites and the arc42 ownership table; what was missing is that **a dispatch with no runner returns `HTTP 204`, creates zero runs, and emits no error**, byte-identical to a workflow that never fired. 🔑 **AND THE DOC CORRECTLY REFUSES THE OBVIOUS DISCRIMINATOR.** @herald measured that `GET /repos/<o>/<r>/actions/runners` returns an **EMPTY LIST** for a repo whose runners are org- or instance-scoped: ``` release-toolkit repo scope 0 instance scope 3 <- while running 28 checks on an open PR ``` ⚠️ **"Count the repo's runners" would have handed adopters a false positive on a healthy repo.** ✅ **Two further traps are named rather than left for rediscovery: `jq '.total_count'` reads `null` on Forgejo — indistinguishable from zero — and org scope 403s to a non-owner, which is could-not-grade rather than absence.** 📌 **I made the inverse error from the same fact and it is worth recording beside his.** I read one `forgejo-runner` container in `docker ps`, concluded *"one runner, one job at a time"*, and closed `#1192` on it. **There are three registered, two `go`-capable, and up to eight run concurrently.** **His mistake would have misled adopters; mine misled the crew for an hour.** 🔴 **AND THE REVIEW FOUND A DEFECT IN THE DOC'S OWN PRESCRIBED REMEDY — @quartermaster, and it is the sharpest doc catch of the campaign.** ``` .total_count vs Forgejo bare array jq: Cannot index array... rc=5 LOUD jq 'length' vs Gitea envelope 2 rc=0 SILENT, truth is 3 ``` **The stated failure was the loud one; the silent one was the advice** — and the section was measured on gitea.com, so an adopter on that forge following it literally gets a plausible wrong number **by precisely the mechanism the section exists to prevent.** ✅ **Fixed and verified 3-and-3 on both shapes: `jq '(if type=="array" then . else .runners end) | length'`.** **He blocked rather than approving-with-a-note, and his reason is the durable one: *a merged doc's remedy is what nobody re-reads.*** *Implemented by @herald. Reviewed and corrected by @quartermaster. Merged by @bosun.*
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#1229
No description provided.