Darstellung
ADR 0007 — Multisite policy
Status: accepted Date: 2026-08-21
Context
WordPress multisite allows a plugin to be network-activated or activated per site, and state can live per blog or network-wide. Licensing has to pick one and be consistent, because a mixed model is worse than either choice.
The Phase 0 audit answered most of this. The plugin is already uniformly per-site:
Core\WpOptionswrapsget_optionexclusively. There is no*_site_optioncall anywhere insrc/.Activatorinstalls the schema per blog and hookswp_initialize_siteso a new blog gets its own tables.Uninstalleriterates blogs and purges each one independently.- Every table is prefixed with the blog's
$wpdb->prefix.
Decision
Licensing follows the existing model. Per-site scope, without exception.
| Aspect | Policy |
|---|---|
| Network activation | Supported. Each blog activates independently |
| Site-specific activation | Supported, identical code path |
| Licence scope | Per blog |
| Installation UUID scope | Per blog |
| Installation token scope | Per blog |
| Options | Per blog, via get_option |
| Cron event | Per blog |
| Network admin screen | Not implemented |
Each blog reports is_multisite, blog_id and network_home_url in every request, so the platform can recognise that twenty installations belong to one network and bill them as one customer if the product decides to. That decision belongs on the platform, not in the plugin.
One licence key may be entered on several blogs. Whether that is within the plan is the API's call, exactly as it is for separate single-site installs.
Consequences
Good:
- Zero new concepts. Licensing behaves like every other part of the plugin.
- Per-blog uninstall keeps working, including the opt-in purge.
- No blog can affect another blog's entitlements.
- A network admin screen can be added later as a read-only overview without changing the storage model.
Costs:
- A 200-site network needs 200 activations unless the platform recognises the network and bills it as one customer. This is a pricing decision, and the signals to make it are already transmitted. Recorded as risk R-10 in the Phase 0 audit.
- 200 blogs mean 200 cron events and 200 daily API calls. Bounded by the UUID-derived jitter, which spreads them across a three-hour window rather than firing together.
- A network administrator has no single screen showing every blog's licence.
Rejected
Network-wide licence in wp_sitemeta. It would be the only network-scoped state in the plugin, breaking the symmetry the rest of the code relies on. It would also break the per-blog uninstall path, and it would let one blog's administrator disconnect a sibling blog's licence — a privilege escalation between tenants that a per-site model does not have.
Network-only activation. Forces a model on customers running multisite for unrelated reasons, and there is no technical need for it.
A hybrid: network licence with per-blog override. Two sources of truth for the same question. The audit explicitly warned against a "random mixed solution", and this is exactly that.
Counting a network as one installation locally. The plugin would be deciding its own limit, which contradicts ADR 0001.