Skip to content

fix(ai): command-code quota windows split their out-of-range disposition — percent clamped, label raw; non-positive resetAt published as a 1969/1970 date #1821

Closed

Description

@dezren39

Problem

parseCommandCodeCredits (packages/ai/src/quota/providers/command-code.ts) applies the out-of-range disposition to only half of each windowLimits window, and publishes non-positive resetAt values as real dates. The window contract in packages/ai/src/quota/types.ts (design #1794) requires the opposite on both counts:

  • Rule 5: "A window's fields agree — derived fields are computed from the published (post-disposition) values; the out-of-range disposition (clamp vs publish-truthfully) is the provider's stated choice, applied to the whole window, never split."
  • Rule 3: "Missing is null, and nulls the field — never a number… An absent reset is an honest null resetAt on the window."

Yet the types.ts inventory lists command-code as "Conforming", and the shared probe matrix (#1795) pins its rule-3 absent-reset case but no out-of-range windowLimits case — so the defects below are unpinned.

Evidence (verified this run, laptop probe at origin/main 4d2d9bf989)

Probe: ~/git/fleet/probe-2026-11-06-commandcode/probe.ts against the real parseCommandCodeCredits in worktree probe-2026-11-06-creator-0335:

  • Negative used — { windowLimits: { fiveHour: { used: -5, cap: 10, resetAt: 1893456000 } } } → usedPercent: 0, remainingPercent: 100, valueLabel: "-5 / 10". The percent is clamped but the label publishes the raw negative figure: the window disagrees with itself (the fix(ai): mistral quota budget window disagrees with itself — usedPercent clamped, usedAmount derived from the raw percentage #1785 mistral defect, in this provider's windowLimits loop at command-code.ts:85-90). The monthly path in the same function guards monthlyRemaining >= 0 (command-code.ts:63); the windowLimits loop has no used >= 0 guard at all.
  • Over-cap used — { used: 15, cap: 10 } → usedPercent: 100 but valueLabel: "15 / 10". Same split: clamped percent, truthful label. (Turso's stated publish-truthfully choice publishes both raw; a clamp choice must clamp both.)
  • Negative reset — { weekly: { used: 5, cap: 10, resetAt: -5000 } } → resetAt: -5000000, resetAtFormatted: "Wed, Dec 31, 4:36 PM" (1969). The local seconds→ms conversion at command-code.ts:89 (resetAt < 1_000_000_000_000 ? resetAt * 1000 : resetAt) never rejects non-positive values.
  • Zero reset — resetAt: 0 → resetAt: 0, formatted as the epoch (Dec 31, 1969 local) instead of the honest null the absent-reset case correctly publishes.
  • Control — { used: 5, cap: 10, resetAt: 1893456000 } → usedPercent: 50, resetAt: 1893456000000, label "5 / 10" (correct).

Why it matters

Quota windows drive pool gating and the dashboard/opencode quota rendering. A window whose percent says 0% while its label says "-5 / 10" (or 100% vs "15 / 10") presents two contradictory truths to every consumer, and a 1969/1970 reset date renders as a real reset time. These are exactly the payload-anomaly shapes the contract and the #1793 groq strictness fix exist to keep out of published quota state; command-code's windowLimits loop is the remaining unguarded one.

Acceptance criteria

  • One stated disposition for windowLimits windows, applied to the whole window: a negative used publishes no contradictory figure (no window, or a window whose percent and label agree), and an over-cap used has percent and label in agreement (both clamped or both truthful).
  • A non-positive resetAt (0 or negative, seconds or ms spelling) publishes resetAt: null (with null derived reset fields), never an epoch/1969 date; a valid positive reset is unchanged.
  • Probe-matrix cases in packages/ai/test/quota.test.ts pin all three shapes for parseCommandCodeCredits (negative used, over-cap used, non-positive resetAt), and the types.ts inventory row for command-code reflects the outcome.
  • Existing quota tests still pass, including the fix(ai): Command Code quota monthly window vanishes when remaining credits exceed the hard-coded 10 included — an over-limit payload reads as 'could not be parsed' #1744 monthly over-included and rule-3 absent-reset cases.

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    task/triageQueue packet kind: verify, reproduce, and route this item
    source/creatorFiled by the new-issue-creator job
    priority/normalOrdinary priority (the default)
    queue/queuedHas a queued task in the Supabase agent queue
    app/aiPackage: ai (pkgs/ or apps/ in this repo)
    effort/sSmall: expected under 2 hours of work
    on Nov 6, 2026
  2. dezren39 commented on Nov 6, 2026

    @dezren39
    Author

    🤖 Agent note · filed

  3. added
    work/assignedAn agent holds this item via the queue (claimed task)
    queue/claimedA queue worker has claimed the task for this item
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 6, 2026
  4. dezren39 commented on Nov 6, 2026

    @dezren39
    Author

    🤖 Agent note · picked up

  5. 14 remaining items

  6. added
    queue/claimedA queue worker has claimed the task for this item
    and removed
    queue/claimedA queue worker has claimed the task for this item
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Nov 6, 2026
  7. dezren39 commented on Nov 6, 2026

    @dezren39
    Author

    Queue task 10961 (lane opencode-a): fix implemented per the route decided in triage task 10957 — PR #1829: #1829

    • windowLimits loop clamps the whole window: percent and label both derive from one clamped used figure (negative → 0% 0 / <cap>; over-cap → 100% <cap> / <cap>).
    • Non-positive resetAt is nulled before the sec/ms conversion, so all derived reset fields are null instead of a 1969/1970 date.
    • Probe matrix added in packages/ai/test/quota.test.ts; types.ts inventory row updated. Verified on laptop: quota suite 72 pass / 0 fail, ai typecheck clean.

    Parked pending PR #1829 CI/review; resume by checking its checks and Codex findings, then merge per fleet standing rules if green.

  8. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    and removed
    queue/claimedA queue worker has claimed the task for this item
    on Nov 6, 2026
  9. added a commit that references this issue on Nov 6, 2026
  10. removed
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    work/assignedAn agent holds this item via the queue (claimed task)
    on Nov 6, 2026
  11. dezren39 commented on Nov 6, 2026

    @dezren39
    Author

    agent-note:v1 — state: completed via PR #1829 merged 2026-11-06; task 10961 complete. No Codex findings on #1829; mergeable clean; merge rested on diff vs acceptance + PR-recorded quota.test.ts 72 pass / typecheck clean.

  12. added a commit that references this issue on Nov 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    app/aiPackage: ai (pkgs/ or apps/ in this repo)effort/sSmall: expected under 2 hours 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/small-fixQueue packet kind: bounded fix with reproduction and targeted teststask/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