The queue's API: dispatch at the top, last or after a queued run, move, and read the queues #197

Merged
agra merged 1 commit from task/3760-s2-the-queue-s-api into master 2026-10-31 00:49:13 +02:00
Owner

Tracker: #3760

Step 2 of #3672's planspec: agents and the web order, read and size a flow queue through the API.

What it delivers

  • POST /api/tasks/:id/flow-runs takes at: "top" | "last" (default last) or after: <flow run id>, and answers 201 with the flow run, queued or in whatever state its begin reached. The enqueued event records at or after and the position.
  • POST /api/flow-runs/:id/move takes {at} or {after}, places the queued run again, records moved with its position and answers the flow run.
  • POST /api/flow-runs/:id/stop stops a queued run, taking it out of its queue (from step 1, documented with the queue).
  • GET /api/queues answers every queue with a queued run or a holder; GET /api/projects/:id/queues answers the project's base-branch queue, then each other base of it with a queued run, a holder or set slots. A queue is {project_id, base, slots, going, queued, done_today}: going its holders in the order they began, queued its queued runs in order, done_today the runs it began that ended, done or stopped, since the start of the UTC day. A run begun outside the slots is in no queue's lists. PUT /api/projects/:id/queues answers the same queue shape.
  • A FlowRun answers from_queue and started_at; a queued one answers queue: {position, of, next, waits_on: [{task_id, project_id, title, kind}]}, next true on the run its queue begins when a slot frees; a holder answers behind, the runs queued in its queue.
  • docs/api.md gains a Queues section (routes, the queue shape, the move and its refusals, the slot rules) and the Flow runs changes; its Errors table gains not_queued and other_queue.
Refusal Answer
at and after together 400 invalid
after names no flow run 404
after names a run of another queue 409 other_queue
after names the run itself 400 invalid
a move of a run that is not queued; after a run that is not queued 409 not_queued

Tests

tests/flow_queue.sx pins each acceptance case over HTTP: a dispatch at: "top" goes first and one after a queued run goes right behind it; moves to the top, behind a later run and to the last reorder the queue; the queue reads answer going, queued and done_today (a run that ended before the start of the UTC day drops out, and a run begun outside the slots is in no list); a FlowRun answers its queue with next and waits_on (follows and blocked_by) or behind; and one case per refusal in the table.

Fail-before: the same tests/flow_queue.sx built against master's src prints 29 FAIL lines (every new check) and ends FLOW QUEUE FAIL (29 checks); at this head it ends FLOW QUEUE OK.

No web change: the step adds and changes no web/e2e golden.

Gates

  • sak-gate full, gate run 2 at bc2b2810: passed (72 sx tests, step9_release, deploy contract, 777 e2e passed with 1 skipped, 10 runner e2e).
Tracker: [#3760](https://sak.swipelab.com/tasks/3760) Step 2 of [#3672](https://sak.swipelab.com/tasks/3672)'s planspec: agents and the web order, read and size a flow queue through the API. ## What it delivers - `POST /api/tasks/:id/flow-runs` takes `at: "top" | "last"` (default `last`) or `after: <flow run id>`, and answers 201 with the flow run, `queued` or in whatever state its begin reached. The `enqueued` event records `at` or `after` and the position. - `POST /api/flow-runs/:id/move` takes `{at}` or `{after}`, places the queued run again, records `moved` with its position and answers the flow run. - `POST /api/flow-runs/:id/stop` stops a queued run, taking it out of its queue (from step 1, documented with the queue). - `GET /api/queues` answers every queue with a queued run or a holder; `GET /api/projects/:id/queues` answers the project's base-branch queue, then each other base of it with a queued run, a holder or set slots. A queue is `{project_id, base, slots, going, queued, done_today}`: `going` its holders in the order they began, `queued` its queued runs in order, `done_today` the runs it began that ended, done or stopped, since the start of the UTC day. A run begun outside the slots is in no queue's lists. `PUT /api/projects/:id/queues` answers the same queue shape. - A FlowRun answers `from_queue` and `started_at`; a queued one answers `queue: {position, of, next, waits_on: [{task_id, project_id, title, kind}]}`, `next` true on the run its queue begins when a slot frees; a holder answers `behind`, the runs queued in its queue. - docs/api.md gains a Queues section (routes, the queue shape, the move and its refusals, the slot rules) and the Flow runs changes; its Errors table gains `not_queued` and `other_queue`. | Refusal | Answer | | --- | --- | | `at` and `after` together | 400 `invalid` | | `after` names no flow run | 404 | | `after` names a run of another queue | 409 `other_queue` | | `after` names the run itself | 400 `invalid` | | a move of a run that is not queued; `after` a run that is not queued | 409 `not_queued` | ## Tests tests/flow_queue.sx pins each acceptance case over HTTP: a dispatch `at: "top"` goes first and one `after` a queued run goes right behind it; moves to the top, behind a later run and to the last reorder the queue; the queue reads answer `going`, `queued` and `done_today` (a run that ended before the start of the UTC day drops out, and a run begun outside the slots is in no list); a FlowRun answers its `queue` with `next` and `waits_on` (`follows` and `blocked_by`) or `behind`; and one case per refusal in the table. Fail-before: the same tests/flow_queue.sx built against master's `src` prints 29 `FAIL` lines (every new check) and ends `FLOW QUEUE FAIL (29 checks)`; at this head it ends `FLOW QUEUE OK`. No web change: the step adds and changes no `web/e2e` golden. ## Gates - `sak-gate full`, gate run 2 at bc2b2810: passed (72 sx tests, step9_release, deploy contract, 777 e2e passed with 1 skipped, 10 runner e2e).
POST /api/tasks/:id/flow-runs takes at, top or last, or after a queued flow
run, and POST /api/flow-runs/:id/move places a queued flow run again the
same way. GET /api/queues answers every queue with a queued run or a
holder, and GET /api/projects/:id/queues the project's base-branch queue
and each other queue of it with a queued run, a holder or set slots, each
with its slots, its holders, its queued runs in order and the runs it began
that ended since the start of the UTC day; PUT answers the queue so. A flow
run answers from_queue and started_at, a queued one its place in its queue
and what its task waits on, and a holder the runs queued behind it.
agra changed title from The queue's API: dispatch at the top, last or after a queued run, move, stop and read the queues to The queue's API: dispatch at the top, last or after a queued run, move, and read the queues 2026-10-31 00:28:02 +02:00
agra merged commit 787735e312 into master 2026-10-31 00:49:13 +02:00
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
sx/sak!197
No description provided.