Skip to content

release: v7.0.0 — voice-control consolidation + Polar payment route - #670

Merged
devswha merged 21 commits into
mainfrom
dev
Aug 2, 2026
Merged

release: v7.0.0 — voice-control consolidation + Polar payment route#670
devswha merged 21 commits into
mainfrom
dev

Conversation

@devswha

@devswha devswha commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Merges 19 commits from dev into main.

Highlights

Deploy expectations (Vercel auto-deploy on main)

  • /launch-config.js stays the six-field disabled shape.
  • /api/rewrite free tier keeps serving; pro tier keeps Polar license gate (401/403 fail-closed).
  • npm publish is NOT part of this merge; tag/publish happen separately.

Gates: release:check ✓, release:ready ✓, npm test 1664/0 ✓, lint ✓, preflight hold valid ✓.

devswha added 20 commits July 30, 2026 09:01
… pays for it

Found while measuring long-input cost for the character-cap decision; the cost
question turned out to be the smaller problem.

Ten real pipeline runs on the production prompt: a 146-character number-bearing
smoke and a 900-character digit-free document pass on the first attempt, while
every probe from 1,270 characters upward terminates in number_safety_failed with
numeric_claim_changed, including three coherent single documents at 1,270-1,624
characters. One diagnosed case had the original carrying claim number:1/1 and the
rewrite carrying none — the rewriter dropped a number-word and the gate refused,
which is the gate working as designed.

The cost falls on the customer. rewrite-handler states that the daily and monthly
counters increment fail-closed with no refund path, so a failed Pro request still
spends one of 100 monthly requests plus its characters against the 50,000 total
and returns an error, while both rewrite attempts bill us about $0.09. A customer
drafting number-bearing text can pay for a month and receive nothing, against an
account Polar holds to a 0.4% chargeback rate — and the card offers 'up to 20,000
characters each'.

Records the confounds rather than hiding them: the digit-free probes are
concatenated fragments whose topic jumps may provoke compression, the coherent
documents are patina's own unusually number-dense examples, and every row is n=1
for its size, so nothing here establishes a rate.

The four available responses each trade away something real — refund policy vs
abuse, retry budget vs margin, advertised ceiling vs Pro's reason to exist, or
changing the rewrite prompt — so the choice is left open rather than made
unilaterally.
…asoning cut

The scoring reasoning cut is scoped to request.provider === 'gemini'. The first
pass of this measurement never set that field, so it silently served the pre-cut
path and inflated the scorers. Isolated on the same 518-character input: scorer
thinking 923/497 and $0.0573 with the field unset, versus 0/0 and $0.0311 with
it set.

Two corrections follow. The production-path cost of a 518-character English
request is $0.0311, about $3.11 of COGS for a full 100-request month against
$8.49 net revenue — roughly 63% margin, better than the ~55% on record rather
than worse. An earlier draft read $0.05-0.058 as a margin problem; it was
measuring a path production does not use.

Also drops an unmeasured number: the note attributed 'roughly $0.09' to a
2,700-character document, which was the 19,540-character probe's figure
transposed onto a size never priced. Replaced with the measured $0.069-0.089
range and scoped to the probe it came from.

The number-safety findings are unaffected: failures occur at the rewrite stage
before scoring, and the rewrite call is excluded from the cut by design.
…fact

Six production runs on customer-shaped drafts, written as a product-update post
with ordinary numeric density, all terminate in done with every numeral
preserved: 1,190 characters with 6 numerals three times, and 2,400 characters
with 14 numerals three times. The gate does not fire on this material at either
length.

The earlier note claimed number-bearing documents fail the gate and framed it as
live customer harm. Both failing probe families were unlike customer prose:
patina's own examples/*.md are before/after documents dense with scores,
percentages and version strings, and the digit-free probes were unrelated
paragraphs concatenated to hit a length target, where topic jumps invite the
compression that drops a claim. Two families failing looked like corroboration
when they only shared the property of being unrepresentative, and the obvious
control was listed as future work instead of being run first.

Retraction kept in place rather than deleted, with the raw failing rows retained,
so the reasoning error stays visible.

Withdraws the recommendation to reduce the rewriter's numeral drift: on
customer-shaped input there is no measured drift to reduce, and changing the
rewrite prompt on this basis would be acting against an artifact.

What survives: rewrite-handler charges the monthly counters with no refund path,
so when the gate does fire a Pro customer loses quota and receives an error.
Wrong on its own terms, but a correctness issue rather than an emergency at this
trigger rate, and a refund path still needs a bound against crafted
always-failing input.
The Pro monthly cap could not be exercised directly — that needs a production
license, and the verification key was shredded after use while a confirmed
checkout session does not re-issue a customer token. Rather than leaving the
whole claim unevidenced, the layer underneath it was tested: the free tier's
hourly burst limit fired on production with 429 hourly burst exceeded after ten
requests in the window.

That matters because the Pro monthly cap runs through the same limiter, the same
KV, and the same HMAC-keyed bucket, differing only in key and window. So the
counters demonstrably increment and refuse in the deployed environment, which was
the open question. The 100-request threshold itself remains proven only against a
local handler, and the note now says exactly that rather than listing the cap as
wholly unverified.
Retain the iterative quality baseline under a neutral research-only name, migrate scoring and verification config ownership, default the playground to English, and synchronize release metadata to 7.0.0.
Fix rewrite output, config parity, and offline scoring
…o Polar

The LS account was declined (payment-provider-reset-20260729), so the hold
was certifying a dead route. The binding table now carries exactly the Polar
production tuple; the hold validates the PAY-B-BINDING-POLAR-v1 and
PAY-LIVE-RUNTIME-POLAR-v1 artifacts; POLAR_APPROVAL replaces LS_APPROVAL and
the secret blocker names the polar gate variables. The staging tier is
recorded as SUPERSEDED by the production zero-amount purchase evidence per
the owner's decision. LS evidence stays on disk, hash-frozen, as history.
Checkout stays disabled; enabling remains the owner's env-side act.
…unbook, reconcile Gate B

Review findings from the independent lane on #668: the migration doc's step 4
now names every null-evidence blocker that must clear before the checkout
flag flips; owner-actions-go-live.md is marked TERMINAL so the retired LS
identities cannot be provisioned from a current-looking runbook; Gate B in
pro-launch.md accepts the recorded staging supersession for the Polar route;
the unpinned Polar price ID is documented as a known limitation to close at
the next read-back artifact.
ops: rewrite the v6.4 hold and checkout bindings from Lemon Squeezy to Polar
Polar cleared all three review states on 2026-08-03 (account approved, payout
connected, identity verified — owner-observed dashboard). The production env
carries every required secret name; only the live-open pair
(PATINA_PRO_GATE_EVIDENCE_ID, PATINA_SYNTHETIC_PRO_LICENSE) is deliberately
absent, and PATINA_PRO_ALLOW_FREE_KEY is exactly false.
ops: POLAR_APPROVAL + SECRET_MANAGER evidence records
@vercel

vercel Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
patina Ready Ready Preview Aug 2, 2026 8:37pm

Request Review

@devswha
devswha merged commit 5970c24 into main Aug 2, 2026
8 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