Repository navigation
Fix paid usage settlement across resets, retries and late pricing - #4639
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Warden security clearance: clear. No blocking findings (security or desktop↔den sync) in this diff (696a45fd2982b5d475ca7d9351505f9b3d6d1cb1). Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run
Test evidence — dpa-policy-blocks-warm-managed-keys-without-revoking-customer-owned-models-or-an — ✅ passedSHA 2168549 · engine v1 ✅ passed · 18 expectations passed · 0 failed · 0 pending
[world] den(local) · [seed] api GET /v1/org · [seed] api PATCH /v1/inference ℹ️ ASSERTION — 1. Absent DPA flag permits real managed inferenceA pre-issued DB-backed key returned HTTP 200 and the independent upstream saw exactly one authenticated managed request.
ℹ️ ASSERTION — 2. Only allowlisted platform administrators may record DPA decisionsWorkspace admin and foreign admin received 403, anonymous caller 401, invalid payloads 400; independent storage still had no flag or audit events.
ℹ️ ASSERTION — 3. Warm-key denial is organization-bound and cannot be spoofed or retried aroundSame process, key, bearer and session: completion and models are 403, body/header scope spoofing, fallback payloads and retries add zero upstream calls. Same user in a second organization still completes with its own key; foreign membership does not confer access.
ℹ️ ASSERTION — 4. Managed denial follows source, not display nameName-only public PATCH is rejected with 400. A datastore-arranged rename preserves source=openwork; lists still hide it, direct connect stays redacted, and the warm inference key returns 403 with no upstream call. This does not claim public rename support.
ℹ️ ASSERTION — 5. Managed inventory and purchase admission are disabled without breaking connect syncUsable/manageable lists and resource snapshot hide managed providers. Direct connect stays 200 with null credentials and no models. Enable and both checkout forms return policy 403 without new keys or external HTTP attempts.
ℹ️ ASSERTION — 6. GET repair cannot restore missing managed member accessAfter arranging a missing member provider and revoked member key, both members' inference/list GETs returned 200 without changing stored keys/providers; the owner's pre-issued key remains 403.
ℹ️ ASSERTION — 7. New member acceptance does not provision managed access under DPAAn existing foreign account accepted a real invitation as an ordinary member; its scoped list is empty and independent storage contains no managed key or provider for that new membership.
ℹ️ ASSERTION — 8. Customer-owned providers survive branding overlap and route with delivered credentialsOwner and member list/connect the custom OpenRouter/OpenWork-branded provider, then use its delivered endpoint, model and credential for real HTTP completions witnessed as authenticated BYOK. Managed key stays blocked. This is a delivered-config client, not an OpenCode runtime claim.
ℹ️ ASSERTION — 9. Ordinary and raw BetterAuth metadata writes cannot set or erase the flagStrict Den writes rejected extra metadata/flag with 400; raw BetterAuth replacement and creation attempts returned 403. Flag remains true with exactly one approved audit event.
ℹ️ ASSERTION — 10. Approved unset restores the original key and records the transitionThe warm key returned 200 with explicit false; datastore audit identifies the approving actor, previous true, new false and reason.
ℹ️ ASSERTION — 11. Generated SDK carries the DPA body and preserves admin authorizationGenerated typed set/unset calls send the flag and reason and return the declared success body, verified against persisted metadata and audit transitions. A workspace admin using the same generated method receives 403 with no mutation or new audit.
ℹ️ ASSERTION — 12. Audit insertion and DPA mutation are atomicA real audit column outage caused admin PATCH 500; after storage recovery no event was added and the flag stayed false with the original key usable.
ℹ️ ASSERTION — 13. Concurrent ordinary/admin metadata changes preserve DPA and unrelated nested dataThree concurrent rounds of branding, capability and DPA updates all returned 200, preserved nested fixture metadata and all requested changes, added one audit each, and kept inference blocked.
ℹ️ ASSERTION — 14. Policy parsing and unavailable storage fail closedSerialized object true returns 403; malformed JSON, array, scalar, non-boolean flags and real missing metadata column return 503 with zero upstream calls. Restoring absent flag permits the original key.
ℹ️ ASSERTION — 15. Policy is re-read immediately before dispatchIndependent SQL processlist proved a request had passed initial admission and was blocked on limits. An approved policy change committed before releasing that lock. Same in-flight request returned 403 with zero upstream calls; unset restored 200.
ℹ️ ASSERTION — 16. Delayed checkout sync records purchase history without reactivationA real SDK checkout retrieval was held over the approved DPA transition. Release returned sync 200 and persisted active purchase quantity 7 plus checkout event ID. Revoked keys, absent managed providers and disabled inference metadata stayed unchanged; zero inference calls.
ℹ️ ASSERTION — 17. Signed delayed Stripe webhooks retain history without managed reactivationInvalid HMAC was rejected with 400 before any SDK read or history change. Real signature verification accepted completed and async-payment-success events, including repeated deliveries, with event IDs persisted. Keys/providers and disabled inference remained unchanged; no inference upstream calls.
ℹ️ ASSERTION — 18. Synthetic providers onlyDen/inference child environments blank real provider, Stripe and telemetry credentials. Stripe uses only a fixture key and loopback SDK transport. Preload refuses non-loopback HTTP; zero external attempts were recorded and every provider request carried the expected synthetic credential.
Test run created 2026-09-08T21:44:57.538Z · Source: |
696a45f to
2168549
Compare
Test evidence — paid-usage-keeps-its-admitted-windows-through-retries-reset-repricing-and-revoca — ✅ passedSHA 2168549 · engine v1 ✅ passed · 6 expectations passed · 0 failed · 0 pending
[world] den(local) · [seed] api GET /v1/org · [seed] api PATCH /v1/inference ℹ️ ASSERTION — 1. The additive accounting upgrade preserves paid history and reruns idempotentlyThe production bootstrap runner applied generated migration 0094 to a 0093 ledger with existing usage; ledger identity/time/cost and migration journal were unchanged on rerun.
ℹ️ ASSERTION — 2. Legacy reset ambiguity never silently restores forgiven usageA legacy receipt with no provider facts and a missing charge was acknowledged as durably deferred, not backfilled: old reset deletion is indistinguishable from interrupted settlement.
ℹ️ ASSERTION — 3. Exhaustion does not truncate settlement and reset survives replayConcurrent receipts charged all three original buckets once without changing limits; a missing charge repaired without double charging, and reset plus replay races preserved zero forgiven identities and the other member's usage.
ℹ️ ASSERTION — 4. Pricing and delivery changes do not create a second ledger identityMissing costs stayed nullable; complete costs promoted one row in place. Changed event IDs, later timestamps, different costs and a cross-key event collision did not alter its identity/time or charge again. Malformed inherited OTLP usage was 400; a real persistence outage was retryable 503.
ℹ️ ASSERTION — 5. Ambiguous history is retained without guessing a charge destinationOverlapping windows caused durable deferral with unchanged charges and bucket totals. After the fixture repaired that overlap, redelivery charged once using the original receipt.
ℹ️ ASSERTION — 6. Late usage settles original windows without re-enabling revoked or DPA-blocked accessThe real provider-key SQL lookup crossed a window boundary; the server trace kept its earlier admission timestamp. After rollover, revocation and DPA marking, all three old buckets settled, current windows/limits stayed identical, replay used durable time and new generation made no upstream call.
Test run created 2026-09-08T21:23:37.595Z · Source: |
There was a problem hiding this comment.
Warden security clearance: clear. No blocking findings (security or desktop↔den sync) in this diff (216854919a1c93167f5f44cf649a8892f8e8866b). Automated clearance satisfies the required-review gate only — a human still reviews and merges. Analysis run
Purpose
Account for already-admitted managed inference without losing late receipts,
charging twice, or undoing an administrator's usage reset. This is the accounting
follow-up deferred from #4471, not a budget or reservation feature.
Changes
windows, including provider-key delays and later key revocation/DPA disablement.
receipts. Preserve its attribution, original time and once-established charge;
complete later pricing promotes the same row. Blank/missing prices remain null.
reset identities so replay cannot resurrect forgiven usage; repair only genuine
missing charges. Never rewrite limits or advance current pointers to settle old work.
prior reset intent is unknowable. Invalid usage is 400; persistence failure is
retryable 503. No automatic reconciliation scheduler is added.
provider_usageJSON column through migration0094_managed_usage_facts.sql. Existing ledger rows remain unchanged.Current dev sync
Signed head
216854919a1c93167f5f44cf649a8892f8e8866b, rebased ontodev@54a7f0fa978de95806b78cec1d35ec89b7a2ba2c.The proxy conflict is resolved with both sides retained: accounting supplies the
server-owned original admission timestamp, while merged #4471 retains its stream
flag, cancellation signal, safe model identity, response validation and analytics
cleanup. Both DPA checks remain intact. This PR still targets dev independently;
it does not depend on #4468 or a browser branch.
Verification — Incomplete pending new-head CI and broader proof freshness
Passed on this exact head:
OPENWORK_WORLD_PLACE=local pnpm evals:pr specs/paid-usage-settlement.test.ts— 1 passed, 0 failed, 0 skipped; 6 assertion records. Real inference HTTP,
Den/admin-reset routes, disposable SQL and the real migration bootstrap runner.
It covers concurrent duplicate settlement, partial repair, reset/replay races,
pricing transitions, persistence failures, ambiguous windows, admission boundary
delays and late revoked/DPA settlement while neighboring usage stays unchanged.
placement: local (testkit resolvePlace; isolated app-less Den and inference).Supporting current checks: the merged proxy/webhook test command passed 71
tests with zero failures/skips;
git diff --checkpassed. No paid generation orproduction records used.
Historical, not new-head proof: at
696a45fd2, the separate DPA journey passed18 assertion records and CI was green after rerunning the packaged-smoke job. Its initial
attempt imported the packaged server and reached a healthy UI but failed the
emptySessionreadiness assertion; the unchanged rerun passed. This history isretained, not attributed to a proved baseline cause. The accounting and DPA evidence
were published in separate test-evidence sections below. The accounting receipt is
refreshed for this head; the separate DPA receipt remains historical. New-head CI and
any broader reruns are not yet claimed passed. Human review is still required.
The repository-wide boundary ratchet reports untouched benchmark/engine spec
violations; this new journey crosses real product boundaries. That broad failure
was not control-reproduced in this work, so it is not claimed pre-existing here.
It is separate from the passing focused journeys and required CI checks.
Rollout and limits
Apply the additive migration before new readers/writers and reconcile its sequence
with fresh dev before merging. The large generated snapshot is schema metadata.
Legacy deleted-charge ambiguity intentionally stays deferred: resolving it requires
an explicit operator decision, not a guessed charge. Reset forgives known current
charges, not receipts whose prices have not arrived. Provider
pricedis not apromise that deferred history has been reconciled.
No allowances, commercial pricing, strict dollar caps, free-Luna rules, catalog
delivery, UI, credentials, merge or deployment are changed. Live broadcasts and
production migration rollout remain unverified.
Integration
The response reliability change in #4471 is now on dev and is retained by this
integration. Reconcile overlapping paths with #4358 (gateway),
#3648 (status rollover) and #4620 (separate free allowance); none is imported here.
Details:
docs/managed-usage-settlement.md.