ADR-0072 — Tools & Plugins Panel: Operator-Toggleable Feature Flags
Status: Accepted Date: 2026-06-21 Deciders: VayuPress Maintainers Target release: v1.5.0
Context
The v1.5.0 "VayuOS" direction is a single, supreme admin surface that replaces the v1/v2/v3 split and exposes every operator capability in one place. One of its pillars is a Tools & Plugins panel: a registry of every platform module where the operator can see live status and switch toggleable modules on or off in a single click.
VayuPress is a sovereign single binary with zero CDN dependencies and no remote plugin marketplace. "Install" is therefore not a network action — every module already ships inside the binary. A module is either:
- built in (always present; e.g. diagrams, version history, redirects), or
- operator-toggleable via a persisted feature flag (e.g. the public-facing comments, newsletter signup, and webmention receiver).
We needed a way to turn the public surfaces off without tearing down their backing stores, so re-enabling is instant and lossless, and without inventing a second configuration mechanism alongside the existing settings store.
Decision
-
Feature flags live in the settings store. New
feature.*keys (feature.comments,feature.newsletter,feature.webmentions) join thesettings.AllKeysallowlist with a default of"on".Store.FeatureEnabledtreats unset/any-non-"off"value as enabled, so features default to available and only an explicit"off"disables them. Toggling reusesSetMany, which already invalidates the read cache, so the public gate sees the change immediately rather than waiting out the 30 s TTL. -
Enforcement happens at the request boundary. The public handlers (
handleCommentSubmit,handleNewsletterSubscribe,handleWebmentionReceive) consultFeatureEnabledafter the store-nil check and return403when the feature is off. Disabling never deallocates the store — operator-side management (moderation, lists) keeps working, and existing subscribers can still unsubscribe. -
The panel is a static registry rendered server-side.
toolRegistryenumerates every module with anid, label, description, category, glyph, an optionalFlagKey, and areadypredicate that reports whether the backing subsystem is wired. Toggleable modules render a switch; built-in modules render a static "Built-in" badge. All fields arehtml.EscapeString'd before emit, so the CSP posture (no inline styles, nonce'd scripts only, no external hosts) is preserved. -
The toggle endpoint is defence-in-depth.
POST /admin/v3/api/tools/togglesits behindrequireSessionOrAPIKeyandCSRFTokenMiddleware. It resolves the postedidto a flag via the registry and rejects anything not present insettings.FeatureKeys, so a built-in module can never be switched off — even if the registry and the allowlist drift,SetManyignores unknown keys. Every toggle is written to the structured log as an operator audit trail.
Consequences
- Operators get one-click control over public-facing modules with no restart and no data loss.
- The pattern generalises: adding a new toggleable module is a registry entry, a
feature.*key, and oneFeatureEnabledcheck at its entry point. - This panel is the first concrete step of the VayuOS consolidation; subsequent increments fold the remaining v1/v2/v3 surfaces (monitoring, governance, the unified editor) into the same shell.