Skip to content

feat(quota-plane): OpenCode pools consume quota-current — measured placement, rotation, demotion #1157

Open

Description

@dezren39

Priority P1 — order 4. Horizon: Week. Design: quota-plane-design-2026-10-26.md (usage-billing-hub goal files), Stage 2. Parent context: epic #1047. (§1, consumption)

Wire the OpenCode pools to consume quota-current for automated decisions: placement reads the fresh state (<=15-minute-old for adapter-covered pools once the gatherer is live; the measurement gate tightens accordingly); ordering = burn-by-expiry (soonest reset first, OpenAI final reserve); >=85% caution and wall exclusion applied from MEASURED values, complementing the fork's existing error-based demotion (>=3 quota errors/4h -> weight x0.01) so pools demote before errors happen. Never-funds rule unchanged: a walled plan pool rotates or stops, never PAYG.
Acceptance: a placement decision demonstrably changes when quota-current changes (test or staged demo); guidance output cites the measuredAt it used.

Acceptance criteria

  • OpenCode pool placement reads quota-current (<=15-minute-old for adapter-covered pools once the gatherer is live) and a placement decision demonstrably changes when quota-current changes (test or staged demo) — restating the body's Acceptance section as the criteria section.
  • Guidance output cites the measuredAt it used.
  • Ordering is burn-by-expiry (soonest reset first, OpenAI final reserve); measured demotion complements the fork's error-based demotion, and the never-funds rule is unchanged (a walled plan pool rotates or stops, never PAYG).

Activity

  1. developing-today commented on Oct 27, 2026

    @developing-today
    Contributor
  2. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    REVIEW FINDING (2026-10-26, fork side): the fork's plan store (packages/core/src/model-plan.ts) is a plain-JSON file in OpenCode's data dir that "the tools here and OpenChamber read and write the same file" — plan_info is the in-session tool over it. Two facts for this issue: (1) QuotaWindow models ENTITLEMENTS (limit, windowHours, resetRule/resetAt) — it has no live "used" field; live usage is route telemetry (route_usage / model-usage), so the consumption contract must join measured usage (from the gatherer) with plan windows, not expect the plan store to hold readings. (2) Known fork bug developing-today/opencode#550: route_usage silently omits plan quota windows that have no windowHours (monthly/reset-rule windows never appear) — consumption work must not build on route_usage output for monthly windows until that is fixed.

  3. added
    kind/featureNew feature or capability request
    priority/highImportant and time-sensitive
    effort/mMedium: expected under 1 day of work
    source/humanFiled directly by a human
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 28, 2026
  4. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    Intake review

  5. dezren39 commented on Oct 29, 2026

    @dezren39
    MemberAuthor

    DREW (2026-10-29, main chat): the demotion half of this issue is now a very-high-priority requirement, stated plainly — providers whose quota is KNOWN 100% used (reset not imminent) move OUT of the routes until reset or a fresh good read pulls them back in; failing targets also come out, with a warning and a retry policy. OpenCode-side mechanism: developing-today/opencode#6 (raised to priority/critical tonight — credential.activate failover + route removal/promotion), reading the shared QuotaSnapshot contract (opencode#587, adopted 2026-10-29). This issue remains the quota-plane half: quota-current must carry the known-100% / good-again signals those moves consume.

  6. added
    mode/onlineFully doable remotely: design, config, code, cloud
    work/assignedQueue worker lifecycle state
    and removed on Nov 1, 2026
  7. 5 remaining items

  8. added
    queue/queuedHas a queued task in the Supabase agent queue
    task/triageQueue packet kind: verify, reproduce, and route this item
    and removed
    queue/claimedQueue worker lifecycle state
    work/assignedQueue worker lifecycle state
    on Nov 2, 2026
  9. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    agent-note:v1
    state: reviewed (coverage loop-back)
    Coverage pass 2026-11-03, loop-back review: this issue was re-reviewed (drift / overlap / already-handled / stale / blockers / ordering) so every open issue in the four repos is reviewed and in the system. Verdict: still live; in the system as task 7207 (triage, queued, priority 50) in repo-health-code-pilot. Labels audited and synced. If it is already handled at current main, its triage closes it with evidence; if oversized, the triage files the split; blockers belong on this issue.
    Found via: coverage loop-back 2026-11-03

  10. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  11. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

    Triage verdict — task 7207, verified at origin/main e425b6a (2026-11-03)

    CONFIRMED STILL LIVE, with two acceptance points superseded by Drew's later quota doctrine. Re-verified fresh this run (the task 2437 verdict of 2026-11-02 stands in substance, with one correction):

    • Producer side is live: the gatherer writes quota-current.json; adapters exist in pm-stack/aggregator/src/ (quota-current.ts, quota-gather-map.ts, clinepass-adapter.ts, token-adapter.ts).
    • Correction to the task 2437 note: the aggregator does read quota-current now — for display. overlayQuotaCurrent (quota-current.ts:342) overlays it onto the /quota view (README quota table, line 473). The README's "Remaining hop: the aggregator does not read quota-current.json yet" text (line ~607) is stale — it predates the overlay; the still-missing hop is decision consumption, not display.
    • No placement consumer exists: nothing in this repo reads quota-current to make a placement/rotation/demotion decision. Placement lives in the opencode fork's routing/plan store, i.e. the implementation surface is developing-today/opencode, not this repo. The fork's 429-failover piece (opencode issue Bump build/buck/preludes/buck2-prelude from 3a02ea3 to 4371899 #6) is CLOSED; measured placement/demotion is the part that remains.
    • Stale acceptance — doctrine superseded: the body's ">=85% caution" rule was retired by Drew 2026-10-27/29: pools are used to ~100% at reset; a pool at a KNOWN 100% is closed until reset or a fresh good read, and a failed/stale quota read never idles a pool or stops dispatch (2026-10-30). Any implementation must follow the current doctrine, not the 85% text. The never-funds rule is unchanged.
    • Ordering/blockers: this is a cross-repo set whose origin is this issue — implementation belongs on the opencode side (routing weights from measured quota-current, guidance citing measuredAt), with the code side owing only the stale README correction above. No code-repo fix task is enqueued from this triage: the work is not in this repo, and a per-repo duplicate is exactly what the set rule forbids. Issue feat(quota-plane): OpenCode pools consume quota-current — measured placement, rotation, demotion #1157 stays open as the set's tracking home under epic issue epic(usage-hub): SaaS/cloud services completion — v2 live collectors, daily console reads, v3 reconciliation #1047.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

effort/mMedium: expected under 1 day of workkind/featureNew feature or capability requestmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedmeta/follow-upFollow-up spun out of earlier workmode/onlineFully doable remotely: design, config, code, cloudpriority/highImportant and time-sensitivesource/humanFiled directly by a humantask/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