M1: Implement Z.ai quota response parser #7
No reviewers
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
P1
P2
P3
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Creatidy/scarcity-router!7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "m1-zai-capacity-parser"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #6
Summary
Pure provider-edge parser for the Z.ai Coding Plan quota response, normalizing
a decoded payload plus a caller-supplied retrieval timestamp into the v1
CapacitySnapshotcontract (provider=zai,source=zai_usage_endpoint).Live acquisition (credential discovery, authenticated HTTP) is explicitly
not implemented and remains future work.
Commits on this branch (no merge commits):
198da5e— initial parser, fixture tests, docs status note9d588c1— review hardening (reset-unit validation, plan allowlist, structural fail-closed limits, requiredlevelkey, total window-ID generation)15657ba— provider package docstring terminology correction (parser scope, not collection)Parser boundary
scarcity_router/providers/zai.pyexposes exactly one public function:Pure parsing + normalization only. Zero I/O: no clock, no filesystem, no
environment, no network, no credentials; fully deterministic (same inputs →
identical snapshot). Failure paths use narrow deliberate checks — no broad
Exception, no rawKeyError/TypeErrorleakage.Envelope and success-schema validation
code(int, non-bool),msg(str),success(bool),datapresent. Broken envelope →schema_changed.code == 401→status=auth_required,windows=[],auth_requireddiagnostic; provider error text never enters output.
success=false, 403)→
status=unknown+telemetry_unknown(unevidenced as anything else).dataobject, thedata.levelkey present,data.limitsa list, andevery
limits[]entry an object carrying a stringtype. Any violation →schema_changedwithwindows=[]— no partial decoding, healthy siblingsare not preserved. These are schema incompatibilities, not per-window
degradation.
Provider mappings (adapter-owned, per U-004 evidence)
TOKENS_LIMIT (unit=3, number=5)→tokens/five_hour,duration_seconds=18000.TOKENS_LIMIT (unit=6, number=1)→tokens/weekly,duration_seconds=604800.Classification only from validated
(unit, number), never array position.TIME_LIMIT→resource="time", distinct non-token,kind="unknown", noduration_seconds(period semantics unevidenced),window_semantics_unknown.Unknown windows and unknown types
(unit, number), missing or non-integerunit/number: windowpreserved as
tokens/unknown, no invented duration, deterministic safewindow_id, pluswindow_semantics_unknown. Known siblings survive.type(including"") is preserved asunknown/unknown: no raw type text in output, noprovider-derived
window_id, and percentage/reset are omitted withexplicit
percentage_unknown/reset_unknown/window_semantics_unknowndiagnostics because their semantics are unvalidated for that type.
ok.Percentage normalization
Evidenced used orientation: valid non-bool integer
percentagein 0..100 →used_percent=percentage,remaining_percent=100-percentage, always emittedtogether.
percentage=0stays known zero (0/100); 100 stays known exhaustion(100/0). Missing, null, bool, string, float, negative, >100 → pair omitted +
window-scoped
percentage_unknown. Never defaulted.Reset normalization
nextResetTimeis evidenced as a 13-digit epoch-millisecond integer;only that representation normalizes: integer (bool-excluded), positive,
within the 13-digit band, representable → canonical UTC
YYYY-MM-DDTHH:MM:SS.sssZvia integer arithmetic (no float precision loss,UTC only). Epoch-seconds-shaped values (e.g. 10-digit), zero, negatives,
12-/14-digit values, non-integers and unrepresentable magnitudes are
rejected —
resets_atomitted + window-scopedreset_unknown— nevermisinterpreted through another unit. No wall-clock comparison.
Plan normalization
data.levelmust be present (structural requirement above); its valuenormalizes to
planonly via the adapter evidence allowlist, currently{"pro"}. Arbitrary safe-ID-shaped provider strings (plus,user-123,sk-example,pro2, uppercase, punctuation) omitplan—never sanitized, never copied into diagnostics.
Window identity
Deterministic adapter-owned ID from validated non-secret identity fields
only: fixed type token plus bounded components (
tokens_limit-3-5,time_limit-5-1). Generation is total: identity parts render as decimaldigits only when small non-negative integers, checked before any int→str
conversion, so arbitrary magnitudes (e.g.
10**5000) and negatives degradedeterministically to a non-colliding placeholder instead of raising; the
result always satisfies the v1 safe-ID grammar and 64-character limit. No
array index, raw JSON, account data or provider free-text. Fully unknown
window types omit
provider_metadataentirely.Fixture coverage
All six existing fixtures are exercised and unchanged:
quota-200-known-windows(full normalization + order independence),quota-200-unknown-window(sibling survives, no guessed period),quota-200-weekly-missing(no synthesis),quota-200-degraded-values(known-zero vs missing, omitted pair, null reset, valid degraded snapshot),
quota-schema-changed(fail-closed, no partial decode),quota-401-auth-failed(auth_required, no error-text leak).Additional focused tests: shuffled ordering; percentage 100 / negative /
Security / non-scope
No credential access, no Kilo auth reading, no environment inspection, no
HTTP/redirect/retry/timeout logic, no live requests; fixtures and tests
remain synthetic and redacted. Not implemented (explicitly out of scope):
live acquisition/collection, caching, freshness policy, CLI/REST/MCP, other
providers, capability catalog, selector, routing, generic provider
framework. No new dependencies; U-008 untouched.
Results
recommended, repo-managed uv env): 0 errors, 0 warnings,0 notes; type suppressions: 0; no gate or config changes.
uv sync --only-dev+make check: exit 0.git diff --check origin/main: clean;origin/main..HEAD: three scopedcommits, no merge commits.
scarcity_router/providers/{__init__,zai}.py,tests/test_zai_parser.py,docs/providers.md(status note only: Z.airesponse parser implemented and fixture-tested; live acquisition not
implemented; collector not marked done).
origin/main.kilo referenced this pull request2026-10-16 12:23:28 +00:00
kilo referenced this pull request2026-10-18 01:19:02 +00:00