Skip to main content

Feature Gating System

Features in GhostPour have three states per tier, configured in config/tiers.yml. This drives both gradual rollout and upgrade conversions.

The Three States

StateBehavior
enabledRun the feature, apply results to the query, capture on response
teaserRun the feature, return metadata headers to client, but skip applying results. Used for upgrade nudges. Returns X-CQ-Gated: true header
disabledFeature doesn't run at all

How It Works

  1. config/features.yml defines each feature's metadata (display name, description, teaser copy, upgrade CTA)
  2. config/tiers.yml sets per-tier state for each feature under the tier's features: dict
  3. POST /v1/chat checks each feature's state for the user's tier and acts accordingly
  4. Client opt-out: ChatRequest.skip_teasers: ["feature_name"] — your app can suppress specific teaser features after the user dismisses a prompt

Example: Context Quilt Across Tiers

The teaser state is the key conversion driver — users see that the feature would help them, creating a natural upgrade incentive.

Adding a New Feature

  1. Add an entry in config/features.yml with display metadata:
# config/features.yml
your_feature:
display_name: "Your Feature"
description: "What it does when enabled"
teaser_description: "What the user sees in teaser mode"
upgrade_cta: "Upgrade to unlock this feature"
category: "intelligence"
service_module: "your_feature_service"
  1. Add per-tier state in config/tiers.yml:
# config/tiers.yml
free:
features:
your_feature: "disabled"
standard:
features:
your_feature: "teaser"
pro:
features:
your_feature: "enabled"
  1. Implement check(), apply(), on_response() functions in app/services/your_feature_service.py

Kill Switch

Change a feature from teaser or enableddisabled in tiers.yml and restart. No code changes needed.

Response Headers

For features in teaser or enabled state, GhostPour returns metadata headers your iOS app can use:

X-CQ-Matched: "3"                          // entities matched
X-CQ-Entities: "Bob Martinez,Widget 2.0" // entity names
X-CQ-Gated: "true" // teaser mode indicator

Your app reads these to decide whether to show an upgrade nudge or a feature indicator.