Skip to content

pm-dispatch(actions): documented numeric priority (10-90) always 400s — actions send it as a string, server only accepts names as strings #2679

Closed

Description

@dezren39

Problem

The reusable pm-dispatch composite actions document a numeric priority form they can never deliver (main 65d87df, actions added in PR #2678):

  • .github/actions/pm-dispatch-queue/action.yml — input priority: "Optional priority: 10-90 or critical|high|normal|low."
  • .github/actions/pm-dispatch-start/action.yml — same documented input.

Both actions build the request payload with jq --arg (queue action.yml payload step; start action.yml payload step):

payload="$(jq -n --arg priority "$INPUT_PRIORITY" ... \
  '{...} + (if $priority != "" then {priority: $priority} else {} end)')"

--arg always produces a JSON string, so a caller passing the documented numeric form sends {"priority": "50"}. The server's resolvePriority (pm-stack/dispatch/src/validate.ts:28-48) only accepts a string that is a scale name (critical|high|normal|low); a numeric string falls into the name lookup, misses, and throws ValidationError → HTTP 400 priority: unknown name "50". The numeric path (integer 10-90, snapped to the scale) is only reachable from raw API callers who send a real JSON number — never through the Actions, which are the sanctioned cross-repo entry point under the grants mesh.

So any workflow in any allowlisted repo that follows the action documentation and passes priority: "10" … "90" gets a hard 400 from both /v1/tasks and /v1/sessions, while the name form works.

Evidence (verified this run)

Laptop probe importing the real validate.ts (md5 c1f61d5acf5c85da71de798f4c7056b8, identical in the sandbox clone at main 65d87df and the laptop primary; probe at ~/git/fleet/probe-2026-10-30-laneB-priority/ on the laptop), feeding each parser the exact payload shape the actions construct:

A priority-input "50" (documented numeric form, via action) parseTaskRequest: THROW ValidationError status=400 msg=priority: unknown name "50" (use critical|high|normal|low or a number 10-90)
A priority-input "50" (documented numeric form, via action) parseSessionRequest: THROW ValidationError status=400 msg=priority: unknown name "50" (...)
B priority-input "10" (documented critical numeric, via action) parseTaskRequest: THROW ValidationError status=400 ...
B priority-input "10" (documented critical numeric, via action) parseSessionRequest: THROW ValidationError status=400 ...
C priority-input "high" (documented name form, via action) parseTaskRequest: OK priority=20
C priority-input "high" (documented name form, via action) parseSessionRequest: OK priority=20
D direct API numeric 50 (no action) parseTaskRequest: OK priority=50
D direct API numeric 50 (no action) parseSessionRequest: OK priority=50
E omitted priority (via action) parseTaskRequest: OK priority=40
E omitted priority (via action) parseSessionRequest: OK priority=40

No in-repo workflow passes priority to the actions yet (grep over .github/workflows/), so this bites the next caller — most likely another allowlisted repo following the published action docs — rather than a current in-repo call site.

Why it matters

The actions are the documented, OIDC-authenticated way for any allowlisted repo to enqueue or launch dispatch work, and their input contract advertises the queue's full 10-90 scale. A caller using it gets an opaque 400 ("unknown name") for a value the docs told them was valid, with the failing layer (action jq typing vs server validation) not obvious from either side alone.

Acceptance criteria

  • Passing any documented priority form through either composite action — numeric string "10"-"90" and the names — produces a request the server accepts, resolving to the same scale value a raw API caller gets for the numeric form.
  • The fix layer is pinned by triage: actions emit a JSON number for numeric input (e.g. a numeric branch in the jq construction), or the server accepts numeric strings in resolvePriority — one canonical behaviour, tested at that layer. (If the server route is chosen, note it also changes raw-API behaviour for "50" string callers; if the action route, both actions must change identically.)
  • Tests pin the through-the-action payload for a numeric priority (payload-shape test or a validate test fed the action-constructed JSON), plus the existing name/omitted cases.
  • The action input descriptions and the server contract agree after the fix; existing dispatch tests still pass.

Related: #2668 (dispatch launch-pipeline boundary-validation design) — this is a concrete instance of a request the boundary mis-classifies, filed separately because the defect is in the action/server contract, not the launch pipeline ordering.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    app/pm-stackpm-stack (Pad/Grist) in developing-today/code
    effort/xsTrivial: expected under 30 minutes of work
    on Oct 30, 2026
  2. dezren39 commented on Oct 30, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: filed

    • Agent: new-issue-creator (lane B, new-issue-creator-code-b)
    • Session / ID: cron new-issue-creator-code-b, run 2026-10-30T10:20Z (America/Chicago 05:20)
    • Found via: filed this run
    • Task: Triage the pm-dispatch composite-action numeric-priority contract bug: actions document 10-90 but send priority as a JSON string, which the server's resolvePriority rejects as an unknown name (verified by laptop probe against the real validate.ts).
    • Expectation: effort xs triage — pin the fix layer (action jq numeric branch vs server numeric-string acceptance), then route a small_fix packet.
    • Links: probe ~/git/fleet/probe-2026-10-30-laneB-priority/ (laptop); evidence in the issue body.
  3. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 31, 2026
  4. 8 remaining items

  5. removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 31, 2026
  6. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

    • Agent: queue worker, task 4416
    • State: parked after implementation; blocked on Git HTTPS push credentials.
    • Resume: worktree /home/user/git/fleet/4416-2679-numeric-priority, branch queue/4416-2679-numeric-priority, local commit 1c8061768; push commit, revalidate ownership, and open PR. Remote branch currently contains only the base commit.
    • Verification: dispatch bun test: 59 passed. No PR opened.
  7. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    and removed
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 31, 2026
  8. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

    • Agent: queue worker (repo-worker-code), lane E
    • Session / ID: queue task 4416 (resume)
    • Found via: queue claim
    • Task: Resume at targeted_tests_passed: commit 1c80617 was parked only for unavailable git push auth. Verified this shift: worktree clean, diff = validate.ts numeric-string branch + validate tests + README (packet scope); push auth works — branch pushed unchanged (remote verified at 1c80617 via ls-remote); full dispatch suite re-run on the laptop: 59 pass / 0 fail. PR opened from the pushed branch.
    • Expectation: effort/xs; done = PR green in CI + Codex clean -> merge -> close pm-dispatch(actions): documented numeric priority (10-90) always 400s — actions send it as a string, server only accepts names as strings #2679 -> complete fixed_merged.
    • Links: branch queue/4416-2679-numeric-priority @1c8061768
  9. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/pm-stackpm-stack (Pad/Grist) in developing-today/codeeffort/xsTrivial: expected under 30 minutes of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this item

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions