Skip to content

feat: add live quota normalization and policy substrate#55

Merged
dorukardahan merged 16 commits into
mainfrom
feat/live-quota-core
Jul 25, 2026
Merged

feat: add live quota normalization and policy substrate#55
dorukardahan merged 16 commits into
mainfrom
feat/live-quota-core

Conversation

@dorukardahan

@dorukardahan dorukardahan commented Jul 24, 2026

Copy link
Copy Markdown
Owner

Summary

Adds the provider-neutral normalization and policy substrate for future live subscription-quota routing. This PR contains pure transformations only: no runtime routing activation, credential access, provider HTTP/RPC calls, cache daemon, or OAuth mutation.

What is included

  • Token-free host boundary (TypeScript + Python parity)
    • NormalizedQuotaSnapshot / NormalizedQuotaWindow
    • OpenClaw/Hermes remain responsible for exact provider payload parsing and credential lifecycle
    • ZeroAPI receives only provider-neutral quantitative windows
    • unknown/raw fields are ignored; malformed observations fail closed as invalid_response
    • boolean, NaN, Infinity, out-of-range ratio, invalid timestamp, duplicate window ID, invalid scope, and malformed direct-snapshot validation
    • percentage fields have an explicit 0–100 contract; ratios use the separate remainingRatio field
  • Applicability-aware quota policy
    • quotaFactor = sqrt(min(applicable remaining ratios))
    • MCP-only windows never affect inference routing
    • model-scoped windows apply only to explicitly mapped canonical models
    • stale/unknown/unsupported/malformed observations fail open to existing static routing
    • depleted accounts produce a zero factor
  • TypeScript/Python policy parity
    • equivalent normalization, applicability, validation, and pressure semantics
  • Runtime packaging
    • quota modules are included in staged ClawHub runtime entries

Explicitly deferred to host-integration PRs

  • provider-specific HTTP/RPC parsing
  • exact auth-profile/account-scoped snapshot collection
  • local atomic cache and polling lifecycle
  • production router snapshot injection
  • carrying the quota-selected account/auth-profile into the route decision

Keeping these out avoids shipping dead or half-wired production behavior before the OpenClaw and Hermes host seams exist.

Security and lifecycle constraints

  • no credentials, cookies, account emails, raw provider responses, or auth headers in normalized snapshots
  • no network access
  • no OAuth refresh/login/rotation/revoke
  • no credential-store writes
  • multi-device observations are timestamped local observations, not claimed as global exact truth

Verification

  • Plugin (Vitest): 288/288
  • Scripts (Node): 83/83
  • Hermes (Python): 214/214
  • Total: 585/585
  • TypeScript no-emit compile: pass
  • Python compile: pass
  • targeted diff privacy scan: pass

Current reviewed target head: a2ebb96d7f539ac7693580c1a50b7339c8c92599

…pressure policy

- quota-types.ts: NormalizedQuotaSnapshot, NormalizedQuotaWindow,
  ProviderQuotaPayload, QuotaAppliesTo (inference/mcp/model)
- quota-normalize.ts: provider-specific parsers for Z.AI, OpenAI Codex,
  xAI, Kimi, MiniMax; boolean/NaN/Infinity/out-of-range rejection;
  secret field stripping; unsupported status for no-meter payloads
- quota-policy.ts: sqrt(min(applicable remaining ratios)) factor;
  MCP-only windows excluded from inference routing; model-scoped windows
  apply only to mapped candidate models; stale/unsupported -> null
  (static pressure only); depleted accounts excluded from selection

All modules are pure data transformations with no credential or
network access. Router integration follows in the next commit.
…routing

rankSubscriptionWeightedCandidates now accepts an optional
quotaSnapshots: ReadonlyMap<providerId, NormalizedQuotaSnapshot>.

When provided, each candidate's effectivePressureScore is multiplied by
sqrt(min(applicable remaining ratios)). Stale/unsupported snapshots
produce null factor → static pressure only (no regression). Depleted
accounts (factor=0) drop to zero pressure and are naturally excluded
from frontier winners.

The quota parameter is optional and defaults to undefined, preserving
100% backward compatibility with existing callers and tests (284/284).

RankedCandidate type gains an optional quotaFactor field for
explainability.
- integrations/hermes/quota.py: pure-Python quota normalization and policy
  mirroring plugin/quota-normalize.ts and plugin/quota-policy.ts
- integrations/hermes/test_quota.py: 25 tests covering Z.AI/Codex/xAI/Kimi/
  MiniMax parsers, boolean/NaN/Infinity rejection, secret stripping,
  MCP exclusion, model-scoped windows, stale/unsupported/depleted semantics
- scripts/stage_clawhub_plugin.mjs: add quota-normalize.ts, quota-policy.ts,
  and quota-types.ts to runtime entries so staged plugin resolves imports

All 571 tests green (284 plugin + 83 scripts + 204 hermes).

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66883961cf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/router.ts Outdated
Comment thread plugin/router.ts Outdated
Comment thread integrations/hermes/quota.py Outdated
Comment thread integrations/hermes/quota.py Outdated
Comment thread plugin/quota-normalize.ts Outdated
- key quota snapshots by opaque inventory account ID, never provider aggregate
- select the healthy account before computing provider pressure and carry the
  selected account/auth profile in ranking diagnostics
- remove fully depleted candidates before benchmark frontier construction
- preserve quotaFactor in RankedCandidate output
- dispatch raw payload parsers by provider ID instead of payload shape
- classify TIME_LIMIT before generic TIME kinds
- reject malformed kinds and boolean counters in Python parity
- add regression coverage for all current-head Codex findings
@dorukardahan

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 416c75bee5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/quota-normalize.ts Outdated
Comment thread plugin/quota-normalize.ts Outdated
@dorukardahan

Copy link
Copy Markdown
Owner Author

@codex review

Please review exact head 4b7d054d01d731e1dfc0540905ad1f410d267fa4.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4b7d054d01

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/router.ts Outdated
Comment thread plugin/router.ts Outdated
Comment thread plugin/quota-normalize.ts Outdated
@dorukardahan

Copy link
Copy Markdown
Owner Author

@codex review

Please review exact head 9d9aa400102b14f1c634f4089c11079945f4842e.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9d9aa40010

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/router.ts Outdated
Comment thread plugin/quota-normalize.ts Outdated
@dorukardahan dorukardahan changed the title feat: live subscription quota normalization and routing policy feat: add live quota normalization and policy substrate Jul 24, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3bae746023

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread integrations/hermes/quota.py Outdated
Comment thread integrations/hermes/quota.py Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2ebb96d7f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/quota-policy.ts Outdated
Comment thread integrations/hermes/quota.py
Codex P2 findings on PR #55:
- Reject unhashable snapshot status (list/dict) before membership test
- Catch OverflowError from math.isnan on oversized integers
- Validate modelIds is a list before iteration (Python + TS parity)
- Verify snapshot provider/account identity in selectAccountByQuota

All malformed inputs now fail closed to invalid_response instead
of crashing the normalization path.

Tests: Python 220/220, TS plugin 46/46, scripts 83/83.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5b90538f0f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/quota-normalize.ts Outdated
Comment thread plugin/quota-normalize.ts
Codex P2 follow-up on PR #55:
- payload.status=null must produce invalid_response, not default to fresh
- window.appliesTo=null must throw, not silently widen to inference
- Replace ?? with explicit undefined checks for TS/Python parity

Tests: TS plugin 48/48, Python 220/220, scripts 83/83.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5482cea99b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread integrations/hermes/quota.py
Comment thread plugin/quota-normalize.ts Outdated
Codex P2 follow-up round 3 on PR #55:
- Python _input_window: reject explicit null in any quantitative field
- validate_snapshot: reject modelIds that need trimming (parity with TS)
- TS validateNormalizedSnapshot: require pre-canonicalized model IDs

Tests: Python 44/44, TS 49/49, scripts 83/83.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7139624a4a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/quota-policy.ts Outdated
Codex P2 on PR #55: selectAccountByQuota dropped accounts with
null live pressure (stale/absent/unsupported), excluding higher-static
candidates. Now fails open: null → static pressure fallback,
only confirmed depleted (0) accounts are excluded.

Tests: TS plugin 52/52, Python 223/223, scripts 83/83.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 23b5b65ca4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/quota-normalize.ts
Comment thread plugin/quota-types.ts
Codex P2 on PR #55:
- normalizeQuotaWindow: reject explicit null id (parity with Python)
- honor explicitZeroUsage=true → remainingRatio=0 (depleted)
- Previously the advertised field was silently ignored

Tests: TS plugin 55/55, Python 223/223, scripts 83/83.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 380e3cdea8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/quota-normalize.ts Outdated
Codex P2 correction: zero usage = no consumption = full quota.
Was inverted to 0 (depleted) which would exclude healthy accounts.

Tests: TS plugin 55/55.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b8321d99f2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread integrations/hermes/quota.py
Codex P2: TS now maps explicitZeroUsage=true → remainingRatio=1,
but Python _input_window didn't forward the marker, causing the
same valid observation to fail as invalid_response.

Tests: Python 224/224, TS 55/55, scripts 83/83.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 838ed279cd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread plugin/quota-normalize.ts
Codex P2: normalizeQuotaWindow only validated the selected meter,
skipping present-but-null alternatives. Now validates every supplied
meter field upfront, matching Python _input_window parity.

Tests: TS plugin 57/57, Python 224/224, scripts 83/83.
@dorukardahan
dorukardahan merged commit f586a9b into main Jul 25, 2026
3 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.

1 participant