Skip to content

Document the admission-denial envelope - #72

Merged
agt merged 1 commit into
mainfrom
claude/funny-mccarthy-2438kp
Aug 22, 2026
Merged

agt merged 1 commit into
mainfrom
claude/funny-mccarthy-2438kp

Conversation

@agt

@agt agt commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

Sibling doc-only change to agt/gpu-reservation-app#319, which classifies every reservation admission denial so a client can tell a busy cluster from a request that can never be admitted.

RESERVATION-API.md and LOG-FIELDS.md are byte-identical shared artifacts — these are the same copies that land in the app repo, with a matching SHARED-ARTIFACTS.sha256.

Why it matters here

The contract told this controller that a 409 means "not feasible right now — the controller may retry later". Five gates behind that status never clear by waiting: non-membership, an unattached GPU class, max_gpus_per_reservation, max_reservation_hours, and a group past its valid_until. A pod refused for one of them is re-offered on every tick forever, burning a create round-trip and a lease.denied WARNING each round without ever reaching a human.

What the docs now say

An admission denial carries three fields beside the human-readable detail:

Field Meaning
code Which gate refused, from a published closed vocabulary
retryable Whether waiting can ever admit this same request
not_before Optional instant a scheduled denial is known to clear (also mirrored as Retry-After)

§4 gains a "Which denials are worth retrying" section with the contended / scheduled / structural table, the full code enum and what each gate is, and the compatibility rule: an absent or unrecognised code must be read as retryable. Status codes are unchanged, so this controller is unaffected until it opts in.

LOG-FIELDS.md documents the retryable field and records that reason= on the four *.denied events is that same published denial code — so an app line and a controller line join on the exact string.

Drift reconciled

RESERVATION-API.md was already out of sync between the two repos: this side's on-demand cancellation-grace paragraph never landed in the app. Each manifest recorded its own copy, so both passed --check locally while differing from each other. The app has now adopted this side's text, and the two copies agree again.

No controller code changes

Consuming the envelope — dropping a retryable: false pod out of the JIT retry loop and surfacing its reason as a pod event or annotation, and withholding it from the ondemand-admission offer set — is a separate effort, as agreed.

Testing

pytest tests/1432 passed, including test_shared_artifacts.py and test_log_grammar.py against the updated dictionary.


Generated by Claude Code

Sibling doc-only change to gpu-reservation-app: every reservation admission
gate there now classifies its denial, so a client can tell a busy cluster from
a request that can never be admitted.

A denial from an admission gate carries three fields beside the human-readable
detail — a published `code` naming the gate, a `retryable` bit, and an optional
`not_before` for the denials that clear at a computable instant — plus a
Retry-After header mirroring not_before. The status codes are unchanged, so a
controller that reads only detail is unaffected; §4 now documents which denials
are worth retrying, the full code vocabulary, and the rule that an absent or
unrecognised code must be read as retryable.

No controller code changes here. Consuming the envelope — dropping a
structurally infeasible pod out of the JIT retry loop and surfacing its reason,
and withholding it from the ondemand-admission offer set — is a separate
effort.

RESERVATION-API.md and LOG-FIELDS.md are byte-identical shared artifacts; the
manifest matches the app repo's. This also carries the app side up to the
on-demand cancellation-grace paragraph that had landed only here, so the two
copies agree again.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014kSKGcRQQh4kNZBe7TJTVf
@agt
agt marked this pull request as ready for review August 22, 2026 22:16
@agt
agt merged commit acbe4bc into main Aug 22, 2026
2 checks passed
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.

2 participants