Skip to content

feat(gate): admit waiting commands first come, first served - #602

Merged
kixelated merged 3 commits into
mainfrom
quest/m1/gate-fifo-admission
Nov 10, 2026
Merged

kixelated merged 3 commits into
mainfrom
quest/m1/gate-fifo-admission

Conversation

@kixelated

@kixelated kixelated commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Finishes quest/m1/gate-fifo-admission.md.

Summary

quest gate used to have no queue: every waiter polled load and memory, and whoever saw room first started. With about 12 agents on one desktop, a command that ran in 84 s waited 77 minutes to start (moq-dev/moq.pro#3751).

Now waiting callers start in the order they arrived:

  • When a caller starts waiting, it adds a queued entry to the existing admission ledger. The queue is the order of those entries.
  • A caller counts every caller queued ahead of it as one more recent admission. It can start before them only while the host has room for all of them, so it never delays them. Only the head of the queue waits out the 5 s spacing. This keeps an idle host's burst starting at once instead of one at a time.
  • A queued entry holds a place, not a slot. It never counts as running or as recent load.
  • A place frees when its caller is admitted (the admission replaces it) or cancelled (admit removes it on the way out), or when its gate process ends (the same liveness check admissions use).
  • priority callers go ahead of the queue and never join it. quick callers join it but still start at QUICK_MS whatever their place.
  • A new waiting notice reads quest gate: waiting for commands queued earlier to start.
  • The README and admit's doc comment now describe this order. The old text said there was no fairness guarantee.

Choices made without asking

  • Room-for-everyone-ahead rule, not strict head-only. Under strict head-only, a burst on an idle host would start one command every 5 s. The rule above keeps bursts instant and still lets no one pass a caller it would delay.
  • Windows places expire unless refreshed. Windows has no process start time, so a reused process ID could hold the queue forever. So a place without a start time is refreshed by its waiter every 30 s and frees a minute after its last refresh. Linux and macOS places rely on the start time alone and never refresh.
  • Polling interval. A caller that is not at the head checks again every SETTLE_MS, the same as other waits.

Public API and wire impact

  • Admission gains an optional queued field, and Waiting gains "queue".
  • The on-disk ledger format adds queued: true entries. Older Quest builds still on the host read these as admissions, which makes them more conservative, not less. Per AGENTS.md there is no migration.
  • No CLI flag changes.

Validation

  • just check and just test pass locally: 1185 tests passed, 5 skipped, after merging main.
  • New tests in test/gate.test.ts cover:
    • arrival order: a later caller waits, then spaces itself after the earlier one, and starts first only when there is room for both
    • places freed by an ended gate, a reused process ID, a missing refresh, or cancellation, and a fresh unrefreshed place still holding
    • priority and quick relative to the queue
  • Not covered: the Windows refresh path itself. On Linux the test process always has a start time, so tests can't reach that branch. Its expiry is covered.

Merge with main

moq-dev/quest#604 removed --host reservations while this PR was open. The merge drops the queue's host handling and its host test; review round 2 covers the merged head.

Caused by

None: admission has had no queue since the gate was written.

Follow-ups

None.

Models

Size: M
Implementer: Claude Code, claude-opus-5-5, medium effort

🤖 Generated with Claude Code

(Written by Claude Opus 5.5 with medium effort)

Review

Rewritten by quest review after each round.

  • Reviewer: Codex, gpt-6.1-sol, medium effort
  • Session: 01a1c4e2-1b35-7d32-ba5a-56840be5908e, round 2
  • Head: fb0e0d2
  • Base: origin/main at b6b7197
  • Score: 9/10, The merge preserves the reviewed queue behavior while incorporating the base branch’s removal of host reservations, with no new actionable defects found by code inspection; builds and tests were not run as instructed.
  • Findings: none

@pullfrog

pullfrog Bot commented Nov 10, 2026

Copy link
Copy Markdown

Pullfrog  | Review this ➔

Each waiting caller records its place in the admission ledger and counts
every caller queued ahead of it as a recent admission, so a later caller
starts first only while the host has room for all of them, and only the
head of the queue waits out the spacing. Priority and host callers go
ahead of the queue; a quick caller still starts at its deadline.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@kixelated kixelated changed the title Gate admission is first come, first served feat(gate): admit waiting commands first come, first served Nov 10, 2026
@kixelated
kixelated marked this pull request as ready for review November 10, 2026 09:56
@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Gate admission now records waiting callers in a FIFO queue and evaluates queue order alongside host headroom and admission spacing. Priority callers bypass queue waits, while quick callers can enter at their deadline. Queue places are refreshed or removed as callers wait, start, cancel, or exit. The README documents the behavior, and tests cover queue ordering, exceptions, expiry, and cleanup.

Merge Risk: Minimal · up to fb0e0

The change adds first-come, first-served ordering for waiting gate commands, with documentation and tests. No concrete defect was identified, so it looks ready to merge.

Pre-merge checks: Passed 5

Check name Status Explanation
Title check Passed The title clearly summarizes the main change: quest gate now admits waiting commands in first-come, first-served order.
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentat…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description explains the FIFO admission changes, their behavior, and the related tests. It matches the changeset.
Full details: Docstring Coverage

Explanation

Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 2 functions across 2 files. (1 skipped: 1 unsupported.)

Finishing Touches

Simplify code

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

Recent review info

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 09fa5438-636d-4033-a36d-a5fd56b8c61a
Commits

Reviewing files that changed from the base of the PR and between b6b7197 and fb0e0d2.

Files selected for processing: 4

  • README.md
  • quest/m1/gate-fifo-admission.md
  • src/cli/gate.ts
  • test/gate.test.ts
Files with no reviewable changes: 1

  • quest/m1/gate-fifo-admission.md

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

…mission

# Conflicts:
#	src/cli/gate.ts
#	test/gate.test.ts

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed commit: cc14fa7

No actionable correctness findings in the inspected changes. Overall direction is coherent with the documented room-for-callers-ahead policy: queued places are excluded from running/recent admissions, admission replaces the place with a distinct ID for atomic-publish validation, and cancellation removes the place. The focused tests cover queue ordering, expiry and precedence interactions.

Verification limits: GitHub-only static review of all four changed-file patches and admission/ledger context; no builds or tests run independently. The Windows periodic-refresh branch remains untested as noted in the PR. GitHub currently reports mergeable=false, so this review does not cover the eventual conflict resolution or establish readiness to merge. Rechecked open/non-draft state, full head SHA and existing reviews immediately before posting.

@kixelated kixelated left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Automated review by review (OpenAI)

Reviewed commit: fb0e0d2
Base: b6b7197

Reviewed the merge/conflict resolution against previously reviewed cc14fa7. No new actionable findings. The resolution consistently incorporates #604's removal of host reservations while preserving queue accounting, cancellation cleanup, priority bypass and quick deadlines. The removed host-specific tests match the removed behavior; queue coverage remains.

Overall direction remains sound. GitHub now reports mergeable=true, resolving the earlier conflict limitation. Verification remains GitHub-only static comparison and inspection of the resulting admission function; no builds/tests run independently, and Windows refresh coverage remains a limitation. Rechecked state, full head SHA and reviews immediately before posting.

@kixelated
kixelated added this pull request to the merge queue Nov 10, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Nov 10, 2026
@moq-bot

moq-bot Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

quest land watch: the merge queue removed this pull request at fb0e0d2 because its merge_group build failed (failed_checks).

The land fixer works on it in the background, and the watcher re-enqueues it at the back of the queue once it is fixed or judged flaky, or hands it back here with what it needs.

Queue / Queue build / Build (job) failure at step Test:

…29|�[39m  git(s.repo, "checkout", "-qb", "temp");
    �[90m830|�[39m  git(s.repo, "config", "branch.temp.remote", "origin");
    �[90m   |�[39m      �[31m^�[39m
    �[90m831|�[39m  git(s.repo, "config", "branch.temp.merge", "refs/heads/feature");
    �[90m832|�[39m  const tracking = await quest("--root", s.repo, "review", "--responses…

�[31m�[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/2]⎯�[22m�[39m

�[41m�[1m FAIL �[22m�[49m test/review.test.ts�[2m > �[22ma differently named branch continues the session --branch names, and without it has its own
�[31m�[1mError�[22m: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".�[39m
�[36m �[2m❯�[22m <anonymous> test/review.test.ts:�[2m878:6�[22m�[39m
    �[90m876|�[39m   // Only the change's own directories bring their instructions.
    �[90m877|�[39m   for (const call of [first, second]) expect(JSON.stringify(call.argv)…
    �[90m878|�[39m  },

    �[90m   |�[39m      �[31m^�[39m
    �[90m879|�[39m );
    �[90m880|�[39m

�[31m�[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/2]⎯�[22m�[39m

�[2m Test Files �[22m �[1m�[31m1 failed�[39m�[22m�[2m | �[22m�[1m�[32m32 passed�[39m�[22m�[90m (33)�[39m
�[2m      Tests �[22m �[1m�[31m2 failed�[39m�[22m�[2m | �[22m�[1m�[32m1183 passed�[39m�[22m�[2m | �[22m�[33m5 skipped�[39m�[90m (1190)�[39m
�[2m   Start at �[22m 07:58:30
�[2m   Duration �[22m 314.32s�[2m (tests 88%, transform 10%, import 2%)�[22m


##[error]Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ <anonymous> test/review.test.ts:830:6



##[error]Error: Test timed out in 5000ms.
If this is a long-running test, pass a timeout value as the last argument or configure it globally with "testTimeout".
 ❯ <anonymous> test/review.test.ts:878:6


error: script "test" exited with code 1
error: recipe `_test` failed on line 32 with exit code 1
error: recipe `test` failed on line 29 with exit code 1
##[error]Process completed with exit code 1.
Post job cleanup.
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git version
git version 2.55.0
Temporarily overriding HOME='/var/cache/github-runner-work/_temp/0ff57bc4-713a-4f9a-9121-de7fda7553a8' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --global --add safe.directory /var/cache/github-runner-work/quest/quest
Removing SSH command configuration
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
Removing HTTP extra header
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :"
Removing includeIf entries pointing to credentials config files
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
Post job cleanup.
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git version
git version 2.55.0
Temporarily overriding HOME='/var/cache/github-runner-work/_temp/7d5ee57c-ea92-4d95-87e6-65dde4971972' before making global git config changes
Adding repository directory to the temporary git global config as a safe directory
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --global --add safe.directory /var/cache/github-runner-work/quest/quest
Removing SSH command configuration
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --local --name-only --get-regexp core\.sshCommand
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'core\.sshCommand' && git config --local --unset-all 'core.sshCommand' || :"
Removing HTTP extra header
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --local --name-only --get-regexp http\.https\:\/\/github\.com\/\.extraheader
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git submodule foreach --recursive sh -c "git config --local --name-only --get-regexp 'http\.https\:\/\/github\.com\/\.extraheader' && git config --local --unset-all 'http.https://github.com/.extraheader' || :"
Removing includeIf entries pointing to credentials config files
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git config --local --name-only --get-regexp ^includeIf\.gitdir:
[command]/nix/store/lg46w7hrjx7kylsh6645c9l975i8h43b-git-2.55.0/bin/git submodule foreach --recursive git config --local --show-origin --name-only --get-regexp remote.origin.url
A job completed hook has been configured by the self-hosted runner administrator
##[group]Run '/nix/store/gx2v6q84b0w43bafm0whkdx93qyxbpps-ci-cache-gc.sh/bin/ci-cache-gc.sh'
shell: /nix/store/1mv3qz005gkbalxfghk4y3s8ayv4d2dl-bash-interactive-5.3p15/bin/bash --noprofile --norc -e -o pipefail {0}
##[endgroup]
evicted 0 objects and 0 action results (17.2 KiB logical); 50.0 GiB logical remain
dropped 2 stale checkout records
dropped 2 session event streams
Cleaning up orphan processes

Queue / Queue (job) failure at step Require the build to pass:

Current runner version: '2.338.2'
##[group]Runner Image Provisioner
Hosted Compute Agent
Version: 20261028.624
Commit: 54898b74c23fde5556c9b3c3a2290865feef0dfe
Build Date: 2026-10-28T21:51:42Z
Worker ID: {a6738a91-d41a-4056-9cf7-d889482763f6}
Region: centralus
Cloud: Azure
##[endgroup]
##[group]Operating System
Ubuntu
26.04.1
LTS
##[endgroup]
##[group]Runner Image
Image: ubuntu-26.04
Version: 20261101.186.1
Included Software: https://github.com/actions/runner-images/blob/ubuntu26/20261101.186/images/ubuntu/Ubuntu2604-Readme.md
Image Release: https://github.com/actions/runner-images/releases/tag/ubuntu26%2F20261101.186
##[endgroup]
##[group]GITHUB_TOKEN Permissions
Contents: read
Metadata: read
PullRequests: read
##[endgroup]
Secret source: Actions
Cache mode: write
Prepare workflow directory
Prepare all required actions
Complete job name: Queue
##[group]Run [[ "$RESULT" == success ]] || { echo "::error::the queue build ended $RESULT" >&2; exit 1; }
�[36;1m[[ "$RESULT" == success ]] || { echo "::error::the queue build ended $RESULT" >&2; exit 1; }�[0m
shell: /usr/bin/bash -e {0}
env:
  RESULT: failure
##[endgroup]
##[error]the queue build ended failure
##[error]Process completed with exit code 1.
Cleaning up orphan processes

(written by quest land watch)

@moq-bot

moq-bot Bot commented Nov 10, 2026

Copy link
Copy Markdown
Contributor

Codex land fixer: fixer crashed (exit 1); run /quest-iterate. Recommendation: run /quest-iterate before picking it again.

quest land check: [Errno 32] Broken pipe

(written by Codex)

@kixelated
kixelated added this pull request to the merge queue Nov 10, 2026
Merged via the queue into main with commit 133ab15 Nov 10, 2026
17 checks passed
@kixelated
kixelated deleted the quest/m1/gate-fifo-admission branch November 10, 2026 17:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant