*/ private $caps; /** * @param string $tier Tier. * @param array $caps Caps. */ public function __construct( $tier, array $caps ) { $this->tier = $tier; $this->caps = $caps; } /** * @return string */ public function tier() { return $this->tier; } /** * @param string $capability Capability key. * @return bool */ public function can( $capability ) { return ! empty( $this->caps[ $capability ] ); } /** * Free baseline capability set. * * @return CapabilitySet */ public static function free() { return new self( 'free', array( 'cogs_wizard' => true, 'selected_coupon_preflight' => true, 'transaction_risk_promoted' => true, 'recent_orders_preview' => true, 'health_cli' => true, 'basic_health_ui' => true, 'acknowledge_loss_leader' => true, 'full_scan' => false, 'scheduled_scan' => false, 'category_thresholds' => false, 'category_assumed_cost' => false, 'baseline_order_monitor' => false, 'line_level_evidence' => false, 'price_history' => false, 'advanced_filters' => false, 'export' => false, 'advanced_diagnostics' => false, 'representative_fixed_cart_baskets' => false, 'advanced_cli' => false, 'pairwise_stacking' => false, 'publish_gate' => false, ) ); } /** * Pro companion capability set (V1.0 surface + V1.1 pairwise). * * @return CapabilitySet */ public static function pro() { return self::free()->with_enabled( array( 'full_scan' => true, 'scheduled_scan' => true, 'category_thresholds' => true, 'category_assumed_cost' => true, 'baseline_order_monitor' => true, 'line_level_evidence' => true, 'price_history' => true, 'advanced_filters' => true, 'export' => true, 'advanced_diagnostics' => true, 'representative_fixed_cart_baskets' => true, 'advanced_cli' => true, 'pairwise_stacking' => true, 'publish_gate' => false, ), 'pro' ); } /** * Pro expired: Free execution remains; Pro controls disabled; data retained read-only (FR-012 / ยง8.6). * * @return CapabilitySet */ public static function expired() { return new self( 'expired', self::free()->all() ); } /** * Entitlement temporarily unavailable (network/channel): last-known Free-safe surface. * * @return CapabilitySet */ public static function unavailable() { return new self( 'unavailable', self::free()->all() ); } /** * Corrupted entitlement payload: degrade to Free caps without fatal. * * @return CapabilitySet */ public static function corrupted() { return new self( 'corrupted', self::free()->all() ); } /** * Whether this tier may run Pro execution controls (scans, exports, etc.). * * @return bool */ public function allows_pro_execution() { return in_array( $this->tier, array( 'pro', 'direct' ), true ); } /** * Return a copy with capability overrides and optional new tier. * * @param array $enabled Caps to merge. * @param string|null $tier Optional tier override. * @return CapabilitySet */ public function with_enabled( array $enabled, $tier = null ) { return new self( null !== $tier ? (string) $tier : $this->tier, array_merge( $this->caps, $enabled ) ); } /** * @return array */ public function all() { return $this->caps; } }