Feature flag administration delivery slices¶
Delivered administration controls¶
Ordinary On, Off and Default actions submit in one click. Each row offers an optional comment, retained after failure and cleared after success. Automatic audit reasons, real-administrator authorization, revision checks, exact dependency confirmation and production read-only policy remain. Acceptance: ordinary clicks send one request without a dialog; dependency cancellation writes nothing; stale revisions never silently retry. No new flag is needed for this bounded improvement to the existing administration page.
Prior work and evidence¶
Inspected on Juniper, 2026-09-22, against the origin/main baseline of this PR. PR #3527 remains an open, documentation-only shared-provider proposal; this document supplements rather than replaces its architecture review gates. Its owner task has completed, with no implementation. Grouped rows (#3472), generated display names (#3488), and statistics pilot operations (#3523) have merged. The reviewed local Claude handovers for AF2 and flag retirement do not establish a newer generic-provider implementation. No Claude sessions were restarted or modified, and no existing worktree was repurposed.
Current source anchors:
- Catalog and dependency definitions
- Statistics deployment constraints
- API startup and 30-second refresh
- Browser snapshot and reconnect handling
- Environment mappings and service routing
No current production values or fleet convergence were measured during this task. Schema routing does not prove a service reads runtime overrides. Saved policy is not proof of application in every consumer. Existing API refresh can fail, and browser fallback polling is five minutes; neither promises immediate fleet-wide activation.
Ordered follow-ups and acceptance¶
- Expose truthful management and consumer metadata. Generate consumer names, scope, activation requirements and runtime/deployment constraints from a single catalog. Distinguish intended/declaration routing from verified consumers. Show deployment-only controls read-only with a reason; never offer a working-looking maintenance toggle that the server rejects. Preserve server validation as authority. Verify catalog parity, special-case statistics serving, and mixed-version clients.
- Delivered grouped controls. The reviewer workspace group applies
annotationFormV2,stageReviewRedesign,stageReviewDockview, andintegratedPdfViewertogether; PDF activation requires reload and form eligibility still applies. The supported statistics screening group controls Pages and ProjectOverview; it does not enable all statistics consumers. Individual controls remain available. The API advertises exact group membership with the snapshot. The UI shows configured and effective On/Off/Mixed values and refuses a group with missing members. A group request requires the current revision and commits every planned override plus one audit record in the existing Mongo transaction. Additional dependencies require exact confirmation; deployment-only requirements remain blocking. A revision conflict reloads without retry. An uncertain network/server failure refreshes state and warns that the outcome is unknown, rather than claiming nothing happened or issuing compensating writes. - Shared runtime authority after #3527 approval. Implement the proposal's minimal API/PM vertical slice with immutable snapshots, accepted defaults identity and recovery. Verify two instances of each participating service, cold start, reconnect, missed events, invalid resume state and stale/out-of-order responses. Expose saved/applied/unknown states and useful failures. Decide staleness and operation boundaries before migrating flags; do not silently change production policy. Start with an audited runtime-safe consumer, not statistics or a durable lifecycle gate.
- Statistics runtime domain transitions. Build on the existing pilot UI and its follow-ups #3524–#3526. Separate “Calculate and maintain”, “Use precomputed statistics” and “Build initial statistics”. Maintenance can remain on while reads are off. Preserve project enrollment, Freshness, epochs, compatibility and source-only invalidation. Initial build is an explicit operation with progress/failure, never an implied effect of enabling a switch. Test restart and partial host failure before enabling runtime maintenance. A generic group toggle cannot bypass these domain transitions.
- Other groups and retirement decisions. Consider Risk of Bias tool plus its AI-test control, and statistics consumer presets. Keep diagnostics/telemetry independent: similar category names do not establish a common lifecycle. Add a change-history view and clear environment identity before richer targeting. Staging/preview presets must never imply production promotion or alter preview seeding defaults.
Cross-service architecture proposal (not implemented)¶
The grouped endpoint improves persistence coherence; it does not solve fleet propagation.
The existing singleton override document and append-only audit collection remain the write
source. PUT api/runtime-feature-flags/groups/{key} uses the same real-admin check,
non-production policy, dependency evaluator and compatibility checks as individual edits.
A group advances one revision in the same transaction as its audit entry, including the
exact changed keys and group identity. Group IDs are immutable versioned contracts;
changing membership requires a new ID, preventing mixed-version replicas from applying
a different member set from the one advertised to the administrator. Transactions prevent partially persisted groups.
Mongo transaction retries still enforce the caller's expected revision. Revision broadcasts
are best-effort after commit; a notification failure does not undo a committed group.
The shared-provider proposal in #3527 should be implemented as follows after architecture approval:
- Authority and persistence: keep one environment policy with accepted catalog/defaults identity and monotonic revision. API is the authorized writer; API, PM and other migrated hosts evaluate immutable snapshots through a shared provider. GitOps remains defaults and the production authority until an explicit policy decision changes that. Persist accepted defaults identity so rolling versions cannot reinterpret the same override differently.
- Propagation and consistency: publish invalidations only after commit. Consumers fetch a complete policy and atomically replace their local snapshot, never mix individual flag updates. A Mongo watch plus periodic reconciliation must recover missed invalidations. Each operation captures one policy identity at its admission boundary. Diagnostics report saved revision and each known consumer's applied revision, version and observation time; absence or stale reporting is Unknown, not convergence. Do not promise simultaneous cross-service activation; durable operations need domain-specific fencing/epochs.
- Recovery: establish a watch/read boundary without a bootstrap gap; reject older revisions; retain the last accepted snapshot on transient refresh failure and report staleness. Define reviewed per-gate freshness limits before activation. On invalid resume tokens, incompatible catalogs or restart without an acceptable snapshot, reconcile from authoritative state and fail closed for affected gated operations. Reconnect requires a full fetch. Persisting an override must never be undone by a restart or permissive fallback.
- Statistics: runtime maintenance requires a coordinated domain transition over every mutation host, durable epochs, source-only invalidation and readiness checks. Generic flag persistence is insufficient. Read usage, maintenance and initial build stay distinct; project enrollment and Freshness remain mandatory independently of global group state.
- Rollout: first shadow-read and compare API/PM evaluations in non-production; then enable one audited runtime-safe consumer. Prove two instances per host, disconnect/reconnect, cold start, lost events, stale writers and unknown commits. Expand only after those tests and useful consumer diagnostics pass. Roll back through a new revision; never restore old documents over newer edits. Production rollout and flag retirement require separate reviewed decisions.
Current implementation limitations: API refreshes on a 30-second timer, browsers fetch on notification/reconnect and poll every five minutes, and PM does not consume the API override provider. Statistics maintenance remains deployment-owned. The admin group states are the API's effective snapshot, not an all-host acknowledgement or evidence that a project is ready.
Deployment-only and split-consumer inventory¶
This covers the Boolean FeatureFlags mappings plus the separately catalogued session limit. Operational configuration outside FeatureFlags (transport topology, notifier publication, cleanup authority, storage and identity writer floors) remains deployment configuration; being Boolean is not evidence that runtime mutation is safe.
| Control | Current boundary and reason | Runtime path |
|---|---|---|
DeletionLifecycle |
API/PM durable deletion protocol; absent from runtime catalog | Review coordinated lifecycle transition; retain deployment control now |
BulkStudyUpdateRequireCurrentExecutionVersion |
PM execution-version compatibility floor; absent from catalog | Keep compatibility floor deployment-managed pending protocol review |
IdentityClaimRecovery |
Identity admission/login/claim flow uses host options; absent from catalog | Separate identity-host design and authorization review |
ActiveReviewerTrackingEnabled |
API/PM and browser mapping, absent from runtime catalog; reviewer slot lifecycle | Audit reservation/release semantics before shared-provider migration |
PM BulkPdfUpload and SignalRActive |
Separate PM mappings; API/browser override does not establish PM runtime propagation | Audit PM consumers and operation boundaries; migrate through shared provider |
materializedProjectStatisticsWrites |
API/PM maintenance hosts use deployed values | Required coordinated runtime domain transition, not a permanent exception |
Seven statistics family gates: Screening, MembershipScreening, Annotation, MembershipAnnotation, QuestionAnswers, SearchPopulation, DerivedSummaries (all prefixed materializedProjectStatistics) |
Maintenance gates pinned to deployment by ProjectStatisticsRuntimeActivation |
Migrate with maintenance, preserving durable state and readiness |
materializedProjectStatisticsServing |
Runtime can stop reads, but cannot enable deployment-disabled serving | Coordinate maintenance/readiness and project scope first |
maxInProgressSessions |
Catalogued API setting; shared backend setting is not proof of a common runtime authority | Audit capacity consumers; do not migrate only to demonstrate propagation |
signalRActive, devMode, errorTracking, apmEnabled, logRocketEnabled,
integratedPdfViewer and zonelessChangeDetection are browser reload-bound runtime
flags, not environment-only flags. Statistics Pages, SignalR, Exports, ProjectOverview
and StageOverview consumer controls remain subject to serving and domain readiness.
Retirement/default-on recommendations for review¶
- Do not retire the four reviewer switches as one unit. Form eligibility/fallback, shell selection, evaluation-only docking and PDF lifecycle have distinct code paths. First collect acceptance and rollback evidence for each; consider default-on for the form/shell before optional docking, once those gates pass.
- Keep statistics write/read/family controls. They express different operational and durable safety responsibilities, not redundant names. Consumer presets can simplify operation without deleting rollback controls.
- Audit
newProgressIndicators,newStageSettings,newStageOverview,newScreeningOverviewandnewQuestionManagementfor maturity next. Their names suggest rollout gates, but names and production-enabled values are insufficient evidence. Require current consumer inventory, off-path usage, parity tests, supported rollback floor and an owner decision before recommending removal or changing defaults. - Keep configuration permissions distinct from presentation choices. The Configurable flags gate administrative capability and should not disappear as UI cleanup.
- Reuse the prior schema-v0 multi-option retirement evidence (PR #2713 / ADR-011), rather than creating a competing retirement. That handover explicitly records a writer compatibility floor; equivalent proof is required for other durable features.
All retirement and default changes remain proposals. This slice changes no deployed flags, production policy, backend authority or project activation state.