Document live-verified API gaps from the flux F8 soak #2

Merged
stephen merged 1 commit from docs/live-verified-gaps into main 2026-06-10 04:23:46 +00:00
Owner

GAPS.md: eight live-verified divergences between the vendored Forgejo 15.0.2 spec and a real deployed server (acme.fjord.host, Forgejo 11.0.14+gitea-1.22.0, probed 2026-06-09/10 during the flux F8 soak).

The two that cost real debugging time:

  1. runners/jobs answers "what could a runner with exactly these labels run": the labels param must fully cover a job's runs_on set or the job is omitted, no param returns nothing, and the empty result is JSON null rather than []. A poller passing no labels is permanently blind while every response is a 200.
  2. ActionRunJob.attempt/.handle are 15.x spec additions; servers inside the 7.0.0 version floor but below 15 serve the old eight-field shape, so generated types that require them silently drop every job.

The rest: the major Actions read surfaces (actions/runs, actions/workflows, both runner-list routes) 404 below the spec version; actions/tasks lists claimed tasks only; workflow_dispatch 204s into runs invisible to every API list surface; the contents API splits create (POST) and update (PUT+sha) unlike GitHub; no queued-job webhook exists (the poll-primary rationale); never-used --ephemeral runners leave offline records nothing sweeps (paragon #341 grew the sweep).

Each entry follows the OPERATIONS.md patch-hygiene shape: spec vs wire, which consumer it burned, and the condition that retires the entry. README's table gains a GAPS.md row.

Relevant to both contract consumers: anything generating from openapi.yaml compiles types for fields and endpoints a floor-compliant server may not serve, and nothing in the generated code warns about that.

GAPS.md: eight live-verified divergences between the vendored Forgejo 15.0.2 spec and a real deployed server (acme.fjord.host, Forgejo 11.0.14+gitea-1.22.0, probed 2026-06-09/10 during the flux F8 soak). The two that cost real debugging time: 1. `runners/jobs` answers "what could a runner with exactly these labels run": the `labels` param must fully cover a job's `runs_on` set or the job is omitted, no param returns nothing, and the empty result is JSON `null` rather than `[]`. A poller passing no labels is permanently blind while every response is a 200. 2. `ActionRunJob.attempt`/`.handle` are 15.x spec additions; servers inside the 7.0.0 version floor but below 15 serve the old eight-field shape, so generated types that require them silently drop every job. The rest: the major Actions read surfaces (`actions/runs`, `actions/workflows`, both runner-list routes) 404 below the spec version; `actions/tasks` lists claimed tasks only; `workflow_dispatch` 204s into runs invisible to every API list surface; the contents API splits create (POST) and update (PUT+sha) unlike GitHub; no queued-job webhook exists (the poll-primary rationale); never-used `--ephemeral` runners leave offline records nothing sweeps (paragon #341 grew the sweep). Each entry follows the OPERATIONS.md patch-hygiene shape: spec vs wire, which consumer it burned, and the condition that retires the entry. README's table gains a GAPS.md row. Relevant to both contract consumers: anything generating from `openapi.yaml` compiles types for fields and endpoints a floor-compliant server may not serve, and nothing in the generated code warns about that.
Document live-verified API gaps from the flux F8 soak
All checks were successful
CI / Contract drift (pull_request) Successful in 3s
8867b2a78e
Eight divergences between the vendored Forgejo 15.0.2 spec and a real
deployed server (acme.fjord.host, Forgejo 11.0.14), each verified by
probing the wire during the flux F8 soak:

- runners/jobs filters by full label cover, not membership, and
  returns JSON null when empty
- ActionRunJob.attempt/.handle are 15.x spec additions absent below
- actions/runs, actions/workflows, and the runner-list routes 404
- actions/tasks lists claimed tasks only
- workflow_dispatch 204s into runs invisible to every API list surface
- contents API splits create (POST) and update (PUT+sha), unlike GitHub
- no queued-job webhook exists (why flux is poll-primary)
- never-used ephemeral runners leave offline records nothing sweeps

Each entry records what the spec says, what the wire does, which
consumer it burned, and the retire condition, per OPERATIONS.md patch
hygiene.
Sign in to join this conversation.
No reviewers
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
rasterstate/forgejo-api-contract!2
No description provided.