$features */ public function __construct( public string $modelLabel, public array $features, ) { foreach ($features as $f) { if (! $f instanceof ForecastFeature) { throw new InvalidArgumentException('Every spec entry must implement ForecastFeature'); } } } /** @return array */ public function names(): array { return array_map(fn (ForecastFeature $f): string => $f->name(), $this->features); } public function modelVersion(): string { $names = $this->names(); sort($names); $hash = substr(sha1(json_encode($names, JSON_THROW_ON_ERROR)), 0, 12); return $this->modelLabel.'-'.$hash; } /** @return array{model_label: string, features: array} */ public function toArray(): array { return [ 'model_label' => $this->modelLabel, 'features' => $this->names(), ]; } }