Skip to content

suggested-binding-loop (b): unknown ?status on /security/suggested-bindings returns 200 empty instead of 400 (live REST route skips validation) #7678

Closed

Description

@huangyiirene

Symptom

GET /api/v1/security/suggested-bindings?status=garbage → 200 empty (same for ?status=PENDING) — which reads as "there are no suggestions", the failure mode the clause forbids. Expected 400 for an unknown status value.

Root cause

Located by the run. The live route is packages/rest/src/rest-server.ts registerSecurityEndpoints, which forwards req.query.status through with no validation (rest-server.ts ~L9219: status: req.query?.status ? String(req.query.status) : undefined). The isSuggestionStatus 400 guard exists only on the parallel runtime dispatcher domain, whose own comment describes precisely this observed behaviour. The fix landed on the dispatcher path only — a dispatcher-vs-REST divergence in the opposite direction from the earlier /meta cases (where routes were on the dispatcher but never mounted on REST). Confirmed present on origin/main.

This strengthens the case for the route-ledger↔live-mount parity gate #7526, and argues that gate should cover behaviour divergence, not just mount presence.

Reproduction

  1. Stock boot; as admin GET /api/v1/security/suggested-bindings?status=garbage.
  2. Observe 200 with an empty list instead of 400.

Suggested fix

Apply the isSuggestionStatus validation (the same guard already on the dispatcher) on the live registerSecurityEndpoints REST route, returning 400 for an unknown ?status value.

Source

Extracted from the QA run #7637 (framework 92f26f7, console 09987b6).

Activity

  1. added
    bugSomething isn't working
    pm:queueReady for the PM dispatch loop
    domain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they land
    on Aug 11, 2026
  2. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Aug 12, 2026
  3. self-assigned this
    on Aug 12, 2026
  4. hotlong commented on Aug 12, 2026

    @hotlong
    Contributor

    Claim: PM loop round 8 — domain:cli seat.

    裁决:复用既有的 isSuggestionStatus,⛔ 不重写一份

    The guard already exists on the runtime dispatcher domain, and its own comment describes exactly the behaviour observed here. So this is a convergence fix: the live REST route calls the same predicate, it does not grow a second copy of the status vocabulary. A re-implemented check would be the fourth instance this lane has closed today of one rule in two implementations (#7616, #7652, #7602, #7749) — ⛔ do not add a fifth.

    If the guard is not currently importable from where the REST route sits, say so and propose the smallest shared home rather than duplicating it; ⛔ do not copy the status list.

    Pin the consequence — and note the failure mode is a silent one

    ?status=garbage returning 200 with an empty list is worse than an error: it reads as "there are no suggestions", which is a plausible, actionable-looking answer. That is the specific thing to pin.

    • ?status=garbage → 400, with the error code and status asserted per ADR-0112 (⛔ not merely "it did not return 200").
    • ?status=PENDING (the card names it — wrong case for the vocabulary) → 400 as well, unless measurement shows the vocabulary genuinely accepts it. If it does accept it, say so; that changes the card.
    • Negative, load-bearing: every valid status still returns its list, and no ?status at all still returns the unfiltered list. A fix that 400s everything would satisfy the positives and break the route.
    • Reverse-verify: with the guard removed, the 400 cases go red and the negatives stay green.

    Worth noting, ⛔ not in scope

    The card argues this strengthens the case for the route-ledger↔live-mount parity gate (#7526) covering behaviour divergence, not just mount presence — and it is right, because this divergence points the opposite way from the earlier /meta cases (mounted on the dispatcher, absent from REST). ⛔ Do not build or extend that gate here. If your measurement turns up other REST routes whose dispatcher twin validates and they do not, list them in out_of_scope_findings as their own finding issues (search first) — that list is the useful input to #7526, and it is worth more than fixing them one at a time.

    Premise-first: verify on current origin/main that the REST route still forwards status unvalidated and the dispatcher still guards it — find by text, not line number (several PRs landed in this file today). Already fixed ⇒ premise_still_valid: false, no PR.


    Generated by Claude Code

  5. hotlong commented on Aug 12, 2026

    @hotlong
    Contributor

    Dev claim (picking up the PM dispatch above).

    • Session: session_01Xc86SFVAgZHc52YF9iLxCc
    • Branch: claude/issue-7678-suggested-bindings-status-validation
    • Worktree: dedicated

    Starting with premise verification on origin/main (find by text, not line number), then the convergence fix reusing the existing isSuggestionStatus.


    Generated by Claude Code


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain:cliRetired 2026-10-22, alias of domain:server (cli surface); in-flight cards keep it until they landpm:dispatchedDispatched to a dev agent by /pm-dispatch

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions