# Freemius go-live — WP BaseStation

**Written 2026-08-26, against v0.86.0. Product 37064 (Abcreative LLC).**
Artifact version: https://claude.ai/code/artifact/f1c7201e-a96f-4d31-9840-7864754adf45

Everything between v0.86.0 and taking money. The plugin side is done; what is left is
dashboard work, one code change, and five acceptance tests.

| | State |
|---|---|
| Plugin integration | **Built.** SDK 2.13.4 vendored, bridge live, tier logic fails closed. |
| Freemius dashboard | **Owed.** Plans, prices, a released deployment. ~1 hour. |
| Enforcement | **Off.** Both installs report `enforcing: false`; all 84 tools run free. |
| Blocking launch | Prices set · a released version · the shipping default flipped. |

Decisions Abe made 2026-08-26: three bulk tiers on one Pro plan; **annual + monthly, no
lifetime**; **no trial** — the Free tier is the trial.

---

## 0. What is already done (do not redo)

- Freemius product exists: **ID 37064**, public key `pk_d1c1d8adeac7cdacbf02e590fd8ed`,
  slug `wp-basestation`. SDK 2.13.4 vendored, unpacked from the tarball at build time,
  asserted at 201 files by CI.
- `class-dvc-freemius.php` reads entitlement **live** through the `dvc_license_tier`
  filter and never caches a Pro record — a cached record is the one failure mode that
  leaks entitlement (SDK removed or licence lapsed, record still says "pro" forever).
- Absent SDK ⇒ filter never registered ⇒ site is Free. Fails closed.
- **Two config flags settled the hard way — do not touch:**
  - `has_premium_version => true`. Setting it false made Freemius serve **zero plans**
    and crash its own pricing app (0.53.1, live on divibolt).
  - `menu.override_exact => true`. Without it the SDK replaces our top-level page with
    its opt-in screen, so a new customer's first sight of the plugin is a connect prompt
    instead of their connector URL and token.
- `is_org_compliant => false` (not on wordpress.org), `has_addons => false`,
  `has_paid_plans => true`.
- Secret key is never in the repo: sandbox reads `DVC_FS_SECRET_KEY` from wp-config on
  test sites only, and package.py gate 3b refuses any zip containing an `sk_` string.

---

## 1. Set the plans — Dashboard → WP BaseStation → **Plans**

**DO NOT DELETE THE FREE PLAN.** Freemius docs tell premium-only products to delete the
auto-generated Free plan. That advice does not apply here: Free is a real product tier
(36 tools, one bound page) and every unlicensed install needs a plan to sit on. Deleting
it leaves non-paying installs plan-less — the same empty-list condition that crashed the
pricing app in 0.53.1.

1. **Add Plan** → name `pro`, title `Pro`.
2. **Pricing** → single-site monthly + annual.
3. **Bulk Pricing → Add Bulk** → 10 sites, then again for unlimited. One plan, three
   price points — *not* three plans.
4. **Features** — those bullets are what a buyer reads at checkout.
5. Trial: leave off.
6. **Release plans to users** — toggle, top right of the Plans page. *Until it is on,
   Freemius serves the install zero plans.* Symptom is not an error, it is a pricing page
   that renders nothing. This is what bit 0.53.1.

---

## 2. Deploy — Dashboard → **Deployment** → **+ Add New Version**

- Upload `wp-basestation-0.86.0.zip` — the **gate-built** artifact, not a hand-made zip.
  It already contains the plugin root folder, which is what Freemius requires.
- Set release status to **Released**. Uploaded is not enough: the paid version is not
  downloadable or updatable by customers until the status changes.
- Freemius generates both a "free" and a "premium" artifact from the single upload. Ours
  are **identical by design** — we deliberately do not use `__premium_only` stripping,
  because the pitch is "audit what it does before you put it on a client's site" and a
  free build missing the code you would be buying undermines that. Two identical
  artifacts is correct, not a bug.

---

## 3. Pricing (recommended 2026-08-26)

Market, checked against each vendor's own pricing page that morning:

| Product | Free tier | Entry | Mid | Top | Lifetime |
|---|---|---|---|---|---|
| Divi Connect (Divi Love) | Unlimited sites | $39 · 1 site | $59 · 5 sites | $89 · 1,000 | $199 (50 licences, founding) |
| Novamira | Unlimited, open source | €49 · 3 sites | — | €149 · 1,000 | €299 |
| DiviOps | MIT open source | Pro pricing not published on a reachable page | | | |
| **WP BaseStation (proposed)** | 1 page, 36 tools | **$69 · 1** | **$149 · 10** | **$249 · unlimited** | none |

**Enter these:**

| Tier | Sites | Monthly | Annual | Annual = |
|---|---|---|---|---|
| Solo | 1 | $9 | $69 | 7.7 months |
| Studio *(mark most popular)* | 10 | $19 | $149 | 7.8 months |
| Agency | unlimited | $35 | $249 | 7.1 months |

Monthly ≈ ⅛ of annual on purpose. Closer and monthly cannibalises annual; further apart
and monthly stops being a real option. At this ratio anyone keeping the plugin past eight
months has an obvious reason to pay annually, and the project-shaped buyer (a two-month
build sprint) can still say yes.

**Why above the market.** Agency at $249 is 2.8× Divi Love's $89 unlimited. Defensible on
**category, not features-per-dollar**: Divi Love and Novamira are builders that help an AI
make pages; WP BaseStation is the only one that checks what got made. The real comparison for
the audit half is a standalone a11y/SEO scanner, priced far above a Divi module pack.

**If week one converts badly:** drop Agency to $179, leave Solo and Studio alone. Do not
discount the whole line — that teaches buyers to wait for the next sale, and the top tier
is where the category argument has to work hardest.

### Two pushbacks recorded
- **No lifetime is right, and it costs something.** Lifetime on a plugin that must track
  every Divi 5 release is an open-ended support liability, and Divi Love's is a scarcity
  play (50 licences). But both rivals offer one, so the anti-subscription buyer has two
  places to go and we are not one of them. Revisit post-launch at **3× annual**, not the
  2.2× the market is asking.
- **The Free tier may be too quiet to sell.** With no trial, Free → paid is the only path
  in, so Free does the whole job. One bound page proves the tools work but deliberately
  hides what is worth paying for (site-wide audit, fix-all). Consider letting Free run
  **read-only site-wide audits** — see every problem everywhere, fix only on the bound
  page. Costs nothing to give away; turns the upgrade prompt into a number the buyer
  already believes.

**Prerequisite:** the launch site still says "38 MCP tools" and "9 audit suites". Truth is
**84 and 6**. Do not put a premium price behind copy that undersells by half.

---

## 4. Sandbox checkout — staging only (Unlock Button)

Secret key from Dashboard → Settings → Keys. In `wp-config.php`, above "stop editing":

```php
define( 'WP_FS__DEV_MODE', true );
define( 'DVC_FS_SECRET_KEY', 'sk_…' );
define( 'WP_FS__SKIP_EMAIL_ACTIVATION', true );
```

`DVC_FS_SECRET_KEY` is ours and is what the Licensing panel reports on. The SDK also
honours `WP_FS__wp-basestation_SECRET_KEY` — that second switch once turned sandbox on
while our panel reported it off, which is why the panel now asks
`is_payments_sandbox()` instead of checking our own constant.

Then **Diagnostics → Licensing**: expect *Freemius SDK: loaded*, *Sandbox mode: ON*.
Opt in → Account → Upgrade. The checkout must show **"Prefill Form (Only visible in
Sandbox Mode)"** — that link is the proof the transaction is fake. Pay with
`4242 4242 4242 4242`, any future expiry, any CVC. Licensing panel Tier should read
**PRO**.

---

## 5. Turn the paywall on and prove it bites

```php
define( 'DVC_TIER_ENFORCE', true );
```

The constant wins over the DB option deliberately: it needs filesystem access, so it is
privileged by construction and unreachable by an agent, a compromised token, or the
plugin's own tools. It is also the rollback — set `false`, enforcement stops instantly,
no deploy.

Deactivate the licence (site is now Free) and run all five:

1. **A Pro tool refuses.** `station_audit_site` must refuse, and the refusal must carry a
   working upgrade URL.
2. **A free tool still runs.** `station_check_seo` on any page. All 36 free tools unaffected.
3. **The free page binds.** First write binds; a second page refuses; Overview → release;
   a different page then binds. The agent must not be able to release it.
4. **Re-activating the licence restores Pro.** All 48 Pro tools run again.
5. **Self-test still passes.** `station_run_self_test` `scope=all` stays 721/721 with
   enforcement on — the suite toggles the switch itself, then restores it.

---

## 6. THE CODE CHANGE STILL OWED — flip the shipping default

Enforcement ships dark: `DVC_License::enforcing()` falls back to
`get_option( 'dvc_tier_enforce', false )`. **A customer installing today gets all 84 tools
free forever.** Setting `DVC_TIER_ENFORCE` on staging does nothing for them — it is
per-install and no customer will add it.

v1.0.0 must flip that default to `true`, **with a QA pin asserting the default rather than
the current value**, or a later release quietly gives the product away again. Ship it as
its own release so the diff is unmistakable.

---

## 7. Before real money

- Remove `DVC_FS_SECRET_KEY` and `WP_FS__DEV_MODE` from anything that is not a test site.
  Sandbox checkouts take no money — leaving it on means real customers cannot pay.
- Confirm Licensing panel reads *Sandbox mode: off* on production.
- Update the launch site to 84 tools / 6 audit suites.
- Tag v1.0.0 (CI already fails a tag that does not match the plugin header).
- Run one real checkout on a live card, then refund it. A sandbox pass is not proof the
  production gateway is configured.

**Freemius's cut:** 4.7% revenue share + 2.3% for WordPress products ≈ 7%, plus ~3.5% to
the payment processor. At Agency annual that is ≈ $26 of $249. No fixed fees, nothing owed
before the first sale.

---

Steps 1, 2 and 4 use Freemius's currently documented labels — I have not seen inside the
dashboard. Sources: freemius.com plans/deployment/testing/checkout docs and pricing page,
divilove.com, novamira.ai/pricing (all fetched 2026-08-26).
