# Lucos — Subscription & Token Consumption

**Status:** Product constitution (v1) — approved for epic breakdown  
**Date:** 2026-07-29  
**Related:** [TW-221](https://admedia-jira.atlassian.net/browse/TW-221) (roadmap pillar 1)  
**Confluence:** [Lucos — Subscription & Token Consumption (Product Constitution v1)](https://admedia-jira.atlassian.net/wiki/spaces/EN/pages/782925825/Lucos+Subscription+Token+Consumption+Product+Constitution+v1)  
**Supersedes:** Deferred TW-98 subscription/plan tickets (TW-118, TW-132–135, TW-144)

---

## 1. One-line constitution

> Lucos v1 sells **included agent/chat usage per seat** in **$ credits**. Free is forever useful with **weak AI** and a small credit pool. Pro/Team buy larger per-seat pools and frontier models. Soft degrade when over quota. Stripe for payments. Lucos-internal admin configures plans and inspects user↔plan.

---

## 2. Product ideology

### 2.1 What we sell

**Thin hybrid** (consumption-first):

| Lever | Role |
| --- | --- |
| **Primary** | Included **$ credit** pool per seat for agent + chat LLM usage |
| **Secondary hard gates** | Free model floor (weak/cheap only); Free indexed-repo cap; Team admin/seat features |

We are **not** selling “Agent only on Pro.” Everyone can use Agent; plans mainly buy **more capacity + better models**.

### 2.2 Why not pure capability or pure consumption

| Approach | Why not for v1 |
| --- | --- |
| Pure capability (A) | Too gated; poor Cursor parity; Free feels broken |
| Pure consumption (B) | Free can burn Opus in 3 turns; high COGS / bad Free UX |
| **Thin hybrid** | Free stays useful; Pro value is clear; abuse controlled |

### 2.3 Explicit non-goals (v1)

- Max Mode
- Workspace-level sub-budgets
- Org-pooled Team usage (Team is **per-seat**)
- Metering embeddings / indexing / RAG retrieval / web search / MCP as billable
- On-demand pay-as-you-go overage (soft degrade instead)
- Org-admin billing UI (only Lucos-internal admin for plan config)

---

## 3. Plans (v1 ladder)

| Plan | Audience | Included $ credits | Models | Indexed repos | Seats / admin |
| --- | --- | --- | --- | --- | --- |
| **Free** | Solo forever | Small monthly pool (TBD $ amount) | Weak / cheap only | **30** (admin-configurable) | Personal seat |
| **Pro** | Solo power | Larger monthly pool (TBD) | Frontier models allowed | **Unlimited** | Personal seat |
| **Team** | Orgs | Larger pool **per seat** (TBD) | Frontier models allowed | **Unlimited** | Per-seat allocation; Team admin features (SSO later) |

Notes:

- Exact dollar amounts / seat prices are **pricing TBD** — schema must make them configurable in admin.
- No Pro+ / Ultra in v1; can add later as larger credit packs.
- Annual billing discount is optional later; monthly via Stripe first.

---

## 4. Quota ownership

| Context | Owner | Pooling |
| --- | --- | --- |
| Solo Free / Pro | User’s personal seat (personal/virtual org of one) | N/A — one seat |
| Team | **Per seat** | **Not pooled** — teammate cannot burn another seat’s credits |
| Workspace | — | **Deferred** |

Entitlement resolution for a request:

1. Resolve authenticated user + active seat (personal or Team membership seat).
2. Load plan entitlements for that seat’s plan.
3. Check remaining $ credits on that seat for the current billing period.
4. Apply model allow-list and repo hard gates.
5. On success, meter LLM usage against the seat pool.

---

## 5. Unit of account: $ credits

### 5.1 Definition

- Usage is denominated in **USD credits** (Lucos credit balance).
- Each billable LLM call debits credits at **provider rates** (input / output / cache read / cache write), optionally with a configurable Lucos markup factor (default 1.0 until finance decides).
- Monthly included credits reset with the billing cycle; unused credits do **not** roll over (v1).

### 5.2 Rate card

Maintain an admin-configurable **model rate card**:

| Field | Purpose |
| --- | --- |
| `model_id` | Provider model identifier |
| `input_usd_per_1m` | Input token price |
| `output_usd_per_1m` | Output token price |
| `cache_read_usd_per_1m` | Cache read price |
| `cache_write_usd_per_1m` | Cache write price |
| `plan_allowlist` | Which plans may select this model |

### 5.3 Billable vs not billable (v1)

**Billable**

- Agent and chat LLM calls
- Token components: **input, output, cache read, cache write**
- All LLM calls inside a tool-loop for one user turn (sum of N calls)
- Partial tokens on failed/cancelled turns **after tokens were consumed**

**Not billable (v1)**

- Embeddings / indexing / repo sync
- RAG retrieval / vector search
- Web search tool calls (when added)
- MCP tool execution overhead (LLM tokens inside MCP-driven loops still bill if LLM ran)
- Tab / autocomplete (generous / unmetered)

---

## 6. Feature gates (thin hard gates)

### 6.1 Models

| Plan | Model access |
| --- | --- |
| Free | Weak / cheap models only (admin-configured allowlist) |
| Pro / Team | Frontier models allowed (admin-configured allowlist) |

IDE model picker must **hide or disable** models not on the seat’s plan (not silent fallback).

### 6.2 Indexed repositories

| Plan | Max indexed repos |
| --- | --- |
| Free | **30** (default), **configurable** in Lucos admin |
| Pro | Unlimited |
| Team | Unlimited |

Enforcement at import / enable-index paths. Error payload must include `plan_code`, `max_indexed_repos`, `current_count` for upgrade CTA.

### 6.3 Team-only features

- Seat management (invite / remove / assign plan seat)
- Centralized billing for the org via Stripe
- Future: SSO (not required for metering MVP)

### 6.4 Not in v1

- Max Mode
- Workspace sub-budgets

---

## 7. Over-quota policy: soft degrade

No hard brick of the IDE. Ladder:

| State | Behavior |
| --- | --- |
| &lt; 80% of included credits | Normal |
| 80–99% | Soft warning in IDE (remaining credits + upgrade CTA) |
| ≥ 100% (over included) | **Soft degrade**: force weak/cheap model path; disable Agent tools (Ask-only / no tool loop); clear in-product messaging + upgrade CTA |
| Safety net | Optional absolute abuse throttle (rate limit) — not a product hard-stop |

When a Pro/Team seat is over quota, degrade to the **Free-tier model/tool policy**, not a blank wall.

On-demand overage (pay more mid-cycle) is **out of scope for v1**; revisit after Stripe + metering are stable.

---

## 8. Free tier purpose

**Forever useful IDE with weak AI** — not a timed trial, not a brick.

- Full IDE experience
- Agent/chat available on weak models within small credit pool
- Tab / autocomplete generous
- Indexed repo cap = 30 (configurable)
- Soft degrade when pool empty (still Ask-only on weak model if we allow zero-cost path; otherwise Ask-only with upgrade CTA)

---

## 9. Surfaces

### 9.1 Lucos IDE

- Remaining credits / period usage
- Soft-warning banners and over-quota degrade messaging
- Upgrade / manage account deep links to web
- Plan-aware model picker

### 9.2 Web account portal

- Stripe checkout (upgrade / downgrade / cancel)
- Invoices and payment method
- Team seat management (Team plan)
- Usage history (seat-level)

### 9.3 Lucos-internal admin panel

**Audience:** Lucos operators only (not Team org admins in v1).

Capabilities:

1. **Plan catalog configuration**
   - Plan codes: `free`, `pro`, `team`
   - Included monthly $ credits
   - Model allowlists
   - `max_indexed_repos` (Free default 30; Pro/Team null/unlimited)
   - Feature flags per plan (extensible JSON)
2. **Rate card** — model $ rates
3. **User / seat inspection**
   - Which user has which plan
   - Seat credit balance / period usage
   - Org membership and Team seats
4. **Manual overrides** (support)
   - Assign/change plan
   - Grant bonus credits
   - Toggle subscription status for testing

---

## 10. Billing: Stripe

- Stripe is the **payment gateway** for Pro and Team.
- Free requires no Stripe customer until upgrade.
- Webhooks update Lucos subscription + seat records (`active`, `trialing`, `past_due`, `canceled`).
- Prefer Stripe Customer Portal / Checkout for cards and invoices; Lucos stores entitlements, not card PANs.
- Team: Stripe subscription with **quantity = seats** (or equivalent seat line items); Lucos maps seats to users.

### 10.1 Suggested webhook → Lucos mapping

| Stripe event | Lucos action |
| --- | --- |
| `checkout.session.completed` | Activate paid plan / create seats |
| `customer.subscription.updated` | Sync plan, seat quantity, status |
| `customer.subscription.deleted` | Downgrade to Free; enforce Free gates + soft degrade |
| `invoice.paid` | Renew period; reset included credits |
| `invoice.payment_failed` | Mark `past_due`; grace policy TBD (recommend soft degrade + banner) |

---

## 11. Data model (logical)

Minimal entities (implementation may map to Mongo collections):

```
plans
  plan_code, name, included_credits_usd, max_indexed_repos (null = unlimited),
  allowed_model_ids[], feature_flags{}, is_active, stripe_price_id?

model_rate_card
  model_id, input/output/cache rates, plan_allowlist[]

seats
  seat_id, user_id, org_id?, plan_code, stripe_subscription_item_id?,
  status, period_start, period_end

seat_usage_period
  seat_id, period_start, included_credits_usd, spent_credits_usd, updated_at

usage_events
  event_id, seat_id, user_id, org_id?, request_id, model_id,
  input_tokens, output_tokens, cache_read_tokens, cache_write_tokens,
  cost_usd, status (ok|partial|error), created_at

org_subscriptions (Team billing anchor)
  org_id, plan_code, stripe_customer_id, stripe_subscription_id, status, seat_quantity
```

---

## 12. System responsibilities

| Layer | Responsibility |
| --- | --- |
| **IDE** | Show usage, warnings, degrade UX, model picker filter, deep links |
| **Daemon** | Honor entitlement / degrade signals from cloud; do not invent local billing |
| **API gateway (`api.lucos.com`)** | Auth, seat resolution, plan gates (repos/models), pre-flight credit check, Stripe webhooks, metering store, admin APIs |
| **Cloud client (`lucos-cloud-client`)** | Indexing/upload path plan gates; pass trusted plan/seat context |
| **Agent / RAG (`adpilot-rag-service`)** | Emit token usage events; respect degrade mode headers |
| **Indexing engine** | No billing logic; respect upstream allow/deny only |
| **Admin panel + web portal** | Plan/rate config, user↔plan, Stripe Checkout/Portal, seats, usage history |

---

## 12a. Repository work assignments

Each Lucos repo owns a clear slice. **Billing truth and credit balances live in `api.lucos.com`**; other repos consume entitlements and emit usage — they do not own Stripe or credit math.

### Summary matrix

| Repo | Owns | Does not own |
| --- | --- | --- |
| `api.lucos.com` | Plans, seats, entitlements API, $ credit ledger, Stripe webhooks, repo/model gates, admin APIs, usage history APIs | IDE UX, local file execution |
| `Lucos-IDE` | Usage UI, warnings, soft-degrade UX, model picker filtering, upgrade deep links | Credit debit, Stripe |
| `local-daemon` | Preflight entitlement checks, surface `auth.forbidden` / degrade to IDE, forward cloud errors | Local billing state on disk |
| `lucos-cloud-client` | Indexing/upload Free repo-cap enforcement (30), trusted headers for plan/seat | Agent token metering |
| `adpilot-rag-service.com` | Emit per-LLM-call usage events (tokens → gateway meters $), honor degrade headers on agent/chat | Stripe, seat assignment |
| `adpilot-indexing-embedding-engine.com` | None for billing (embeddings not billable v1) | Plans, credits, Stripe |
| **Web account portal** (new or existing web app TBD) | Stripe Checkout/Customer Portal UX, Team seats UI, invoices, usage history pages | Gateway ledger internals |
| **Lucos-internal admin panel** (new; APIs on `api.lucos.com`) | Configure plans/features/rate card/repo limits; inspect user↔plan/spend; manual overrides | End-user checkout |

### Per-repo change list

#### 1. `api.lucos.com` (source of truth)

**Phase 0**

- Extend plan catalog: `included_credits_usd`, model allowlists, `max_indexed_repos` (Free default **30**, Pro/Team `null` = unlimited), feature flags
- Seat model: personal seat + Team per-seat (not pooled)
- Entitlements API for IDE/daemon (`/me` or `/entitlements`: plan, remaining credits, degrade flags, allowed models, repo limits)
- Admin APIs: CRUD plan config, rate card, list user↔plan, grant bonus credits, force plan assign

**Phase 1**

- `usage_events` ingest + idempotent credit debit on `seat_usage_period`
- Pre-flight credit / model checks on agent/chat proxy routes
- Soft-degrade signal in responses/headers when spent ≥ included
- Enforce Free indexed-repo cap on import/sync management routes

**Phase 2**

- Stripe Checkout + Customer Portal session endpoints
- Stripe webhooks → org/seat/plan sync, period reset on `invoice.paid`
- Team seat quantity sync from Stripe
- Usage history API for portal/IDE

#### 2. `Lucos-IDE`

**Phase 0–1**

- Consume entitlements API; cache briefly, refresh on 403/degrade
- Plan-aware model picker (hide/disable Free-disallowed models)
- Usage panel: remaining $, % used, period end
- Soft-warning banners at 80%+; over-quota messaging (Ask-only / weak model)
- Soft-degrade UX: disable Agent tools when cloud says degrade; clear upgrade CTA
- Deep links to web portal for upgrade/manage billing

**Phase 2**

- Post-checkout return handling / plan refresh after upgrade
- Optional in-chat remaining-credit affordance

#### 3. `local-daemon`

**Phase 0–1**

- Align entitlement checker with seat + $ credits + soft degrade (evolve beyond old Free=4-series / repo-count-only checks)
- Before cloud agent/chat calls: check entitlements; emit `auth.forbidden` / degrade events to IDE
- Never persist cloud JWT or credit balances on disk
- Pass through structured error codes (`MODEL_NOT_ALLOWED`, `CREDITS_EXHAUSTED`, `REPO_LIMIT_EXCEEDED`) for IDE CTAs

**Phase 2**

- Refresh entitlements after plan change notifications if exposed

#### 4. `lucos-cloud-client`

**Phase 0–1**

- Re-enable / implement Free **indexed repo limit = 30** (configurable via plan from gateway headers / entitlement lookup)
- Pro/Team: no repo cap
- Propagate `X-Plan-Code`, seat/user context on indexing APIs
- Return `REPO_LIMIT_EXCEEDED` with plan details for IDE/gateway messaging

**Out of scope:** agent token metering (RAG/gateway owns that)

#### 5. `adpilot-rag-service.com` (agent / chat / RAG)

**Phase 1**

- After each LLM completion in agent/chat paths: emit usage event (input/output/cache tokens, model, request/call ids)
- Respect gateway degrade headers: force weak model / Ask-only (no tool loop) when over quota
- Do not silently use frontier models for Free seats
- Embeddings / retrieval remain **non-billable** (no usage events for those)

**Phase 0**

- Accept trusted plan/seat/degrade context from gateway (headers or normalized body)

#### 6. `adpilot-indexing-embedding-engine.com`

**v1**

- **No subscription metering changes** — embeddings/indexing not billable
- Continue to trust upstream allow/deny (gateway / cloud-client already blocked over-cap Free imports)
- Optional later: emit non-billable operational metrics only (not credit debit)

#### 7. Web account portal (hosting TBD)

**Phase 2**

- Stripe Checkout for Pro / Team
- Stripe Customer Portal for payment method + invoices
- Team seat invite / assign / remove (per-seat credits)
- Usage history pages (calls gateway APIs)

#### 8. Lucos-internal admin panel (hosting TBD; APIs on `api.lucos.com`)

**Phase 0**

- UI to configure per-plan: credits, model allowlist, `max_indexed_repos`, feature flags
- UI to edit model rate card
- UI to search user → show plan, seat, spend, org membership
- Support overrides: assign plan, grant credits

### Cross-repo contract (must stay consistent)

| Contract | Producer | Consumers |
| --- | --- | --- |
| Entitlements payload (plan, credits remaining, degrade, allowed models, repo max) | `api.lucos.com` | IDE, daemon, optionally cloud-client |
| Trusted headers (`X-User-Id`, `X-Org-Id`, `X-Plan-Code`, `X-Seat-Id`, `X-Degrade-Mode`) | `api.lucos.com` | rag-service, lucos-cloud-client |
| Usage event schema (tokens + model + ids) | rag-service (and any future LLM callers) | `api.lucos.com` metering |
| Error codes (`MODEL_NOT_ALLOWED`, `CREDITS_EXHAUSTED`, `REPO_LIMIT_EXCEEDED`, …) | gateway / daemon | IDE CTAs |
| Stripe webhook → seat/plan | Stripe → `api.lucos.com` | IDE/daemon via entitlements refresh |

### Phase × repo checklist

| Phase | `api.lucos.com` | Lucos-IDE | local-daemon | lucos-cloud-client | rag-service | indexing-engine | Portal / Admin |
| --- | --- | --- | --- | --- | --- | --- | --- |
| **0 Wiring** | Plans, seats, entitlements, admin APIs | Entitlements client + model picker | Entitlement checker update | Repo cap 30 | Accept plan context | — | Admin UI |
| **1 Metering** | Ledger, degrade flags, repo gate | Usage panel + soft degrade UX | Forbidden/degrade events | Repo cap errors | Emit usage events + honor degrade | — | — |
| **2 Stripe** | Checkout, webhooks, seats sync | Upgrade deep links / refresh | Refresh entitlements | — | — | — | Portal + seats + invoices |
| **3 Polish** | History APIs, downgrade policy | History views | — | — | — | — | Org-admin later |

---

## 13. Enforcement flow (agent turn)

```text
User sends agent/chat turn
  → Gateway resolves seat + plan
  → If model not allowed → 403 model_not_allowed + upgrade CTA
  → If spent >= included → set degrade mode (weak model / Ask-only)
  → If Free repo import and count >= max → 403 repo_limit_exceeded
  → Proxy / run agent
  → On each LLM completion: emit usage_event (tokens + $)
  → Debit seat_usage_period (idempotent by event_id / request_id+call_id)
  → IDE polls or receives remaining credits in response headers/payload
```

---

## 14. UX copy principles

- Always show **remaining $** or **% used**, not raw tokens only (tokens optional detail).
- Over quota: explain *what still works* (Ask-only / weak model), not only what failed.
- Upgrade CTA links to web portal with plan context.
- Never silently swap models without telling the user when degrading.

---

## 15. Phased delivery (recommended)

### Phase 0 — Product wiring

- Plan catalog + admin config (credits, models, repo limit)
- Seat model (personal + Team per-seat)
- Entitlements API for IDE/daemon

### Phase 1 — Metering + soft degrade

- Usage events from agent/chat LLM path
- Credit debit + period rollups
- Soft warning + soft degrade
- IDE usage panel

### Phase 2 — Stripe + portal

- Checkout / Customer Portal
- Webhooks → plan/seat sync
- Team seat quantity
- Invoices

### Phase 3 — Polish

- Usage history UI
- Downgrade policies (Team → Free seats)
- Optional on-demand overage (future)
- Org-admin (non-Lucos) views (future)

---

## 16. Open pricing numbers (configure in admin; not blockers)

These must be set before launch but do not block engineering of the platform:

- [ ] Free included credits $/month
- [ ] Pro price + included credits $/month
- [ ] Team price per seat + included credits $/seat/month
- [ ] Exact Free model allowlist
- [ ] Exact Pro/Team model allowlist
- [ ] Lucos markup on provider rates (if any)
- [ ] `past_due` grace length

---

## 17. Decisions log

| # | Decision | Choice |
| --- | --- | --- |
| D1 | Sell model | Thin hybrid (consumption-first) |
| D2 | Plans | Free / Pro / Team |
| D3 | Unit | $ credits at provider rates |
| D4 | Solo quota | Personal seat |
| D5 | Team quota | Per-seat, not pooled |
| D6 | Workspace budgets | Deferred |
| D7 | Over quota | Soft degrade (warn → weak/Ask-only) |
| D8 | Billable | LLM input/output/cache tokens on agent+chat |
| D9 | Free purpose | Forever useful IDE + weak AI |
| D10 | Repo limits | Free 30 configurable; Pro/Team unlimited |
| D11 | Max Mode | Not in v1 |
| D12 | Tab/autocomplete | Unmetered / generous |
| D13 | Surfaces | IDE cues + web portal |
| D14 | Admin | Lucos-internal plan/user inspection |
| D15 | Payments | Stripe |
| D16 | Overage pay-as-you-go | Not in v1 |

---

## 18. Success criteria (product)

1. A Free user can use Lucos IDE indefinitely with weak AI and ≤30 indexed repos.
2. A Pro user gets frontier models and a larger monthly $ credit pool on their seat.
3. A Team org bills via Stripe per seat; each member has an isolated credit pool.
4. Hitting 100% credits soft-degrades instead of hard-breaking the IDE.
5. Lucos admins can change plan limits/models/repo caps without a code deploy.
6. Lucos admins can see which user is on which plan and their spend.
7. Users can upgrade/downgrade through Stripe-backed web portal; IDE surfaces usage and CTAs.

---

## 19. Next step

Create Jira epic under Tech Wiki (**TW**) for **Subscription & Token Consumption**, linked to [TW-221](https://admedia-jira.atlassian.net/browse/TW-221), with tasks/subtasks aligned to Phases 0–2 above.
