Skip to content

feat(usage): enforce one free account per install (fair-use policy) - #159

Open
Fahad090NP wants to merge 4 commits into
ltmoerdani:mainfrom
Fahad090NP:feat/single-free-account-policy
Open

feat(usage): enforce one free account per install (fair-use policy)#159
Fahad090NP wants to merge 4 commits into
ltmoerdani:mainfrom
Fahad090NP:feat/single-free-account-policy

Conversation

@Fahad090NP

Copy link
Copy Markdown
Contributor

📝 What does this change?

A single-free-account fair-use policy so one person can't harvest OpenCode's free quota by registering multiple free accounts (inference is expensive for everyone).

The rule: exactly one free account is allowed per install. The moment 2+ free accounts are detected, free-model usage is blocked with a clear, actionable error. Paid usage is never blocked — multiple paid accounts are fine. Delete down to 1 free account (or make the extra one paid) and free models work again.

How an account is classified (per API-key fingerprint):

  • Free = a profile that uses a free model (*-free / big-pickle).
  • Paid = has an active Go subscription (checked via the official /zen/go/v1/usage endpoint) or successfully uses a paid model → exempt from the free limit.
  • Subscription lapsed? → Go accounts are re-classified within ~1 min via the usage sync; Zen accounts within 24h of the last paid use → they count as free again and the limit applies. Renewing re-confirms paid.

Coverage: new profiles and existing profiles (re-evaluated on every request), the Agents window, and vision-proxy requests. The block fires before the request is sent, so no quota is spent.

Code structure (4 commits, pure-logic separation):

  1. Pure policy module src/usage/freeAccountPolicy.ts + storage wrapper + 11 unit tests (src/test/freeAccountPolicy.test.ts) covering: single free allowed, 2nd free blocks, paid exemption, lapsed-sub re-classification, TTL renewal, delete-account recovery, round-trip persistence.
  2. Provider enforcement in provideLanguageModelChatResponse (+ paid confirmation on successful paid-model usage).
  3. Go subscription status wired from the usage sync into the policy.
  4. Delete Profile cleans the policy; the Usage quick-pick warns when free usage is blocked; Diagnostics now shows a "Free-Account Policy" section (free/paid fingerprints + blocked state) so the policy is transparent.

🧪 How did you test it?

  • npm run lint — all 7 steps green, incl. the 11 new policy unit tests.
  • Full gate re-run after each of the 4 commits.
  • Logic verified by scenario tests (can't test live with 2 free accounts myself — the Diagnostics section lets anyone confirm the state).

✅ Checklist

  • npm run compile passes
  • npm run lint passes
  • npm test passes
  • npm run package produces a VSIX (not run — code + tests only)
  • I tested it works (live multi-account verification still recommended)
  • I updated docs/CHANGELOG if needed (left for release-time per repo convention)

⚠️ Honest limitations (please read)

  1. Per-install deterrent, not identity proof. Two keys can't be proven to belong to one person; a determined user could bypass it on another machine or via the OpenCode CLI. It stops casual multi-account harvesting.
  2. An account that has never used anything yet can't be pre-classified — it's counted the moment it first uses a free model.
  3. Zen paid accounts have up to 24h grace after their last paid use (there's no subscription-check endpoint for Zen; Go has one, hence ~1 min).

PEACE BE UPON YOU 🤲

@Fahad090NP

Copy link
Copy Markdown
Contributor Author

If I ever had a wish for any of my PR to be approved, then this is the one. Not because I am jealous of the people who are using this trick to scam OpenCode and I am not, but because both Islam and then the ethics forbids such acts strictly. It was always be a difficult thing to let others think what I actually want to say.

Fi Amanillah.

@Fahad090NP

Copy link
Copy Markdown
Contributor Author

I do not want to hear anything other than any bug or inconsistency in my code. Either Merge, tell me what to improve, or Reject it.

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