categorizer = new MiscCategorizer; } public function getName(): string { return 'Misc'; } /** * Override handle() to lock the passable when a hash/gibberish release is detected. */ public function handle(CategorizationPassable $passable, Closure $next): CategorizationPassable { // MiscPipe always runs regardless of shouldStopProcessing — it IS the first pipe. $passable->miscAnalysis = $this->categorizer->inspectSignals($passable->context); $result = $this->categorize($passable->context); // Record the result for debug $passable->updateBestResult($result, $this->getName()); // Lock to misc if this is a hashed/obfuscated/gibberish detection if ($result->isSuccessful() && $this->shouldLock($result)) { $passable->bestResult = $result; $passable->lockToMisc(); } return $next($passable); } protected function categorize(ReleaseContext $context): CategorizationResult { return $this->categorizer->categorize($context); } /** * Determine if a result should trigger the misc lock. */ private function shouldLock(CategorizationResult $result): bool { // Always lock OTHER_HASHED results if ($result->categoryId === Category::OTHER_HASHED) { return true; } // Lock OTHER_MISC results that were matched by hash/obfuscated/gibberish checks foreach (self::LOCK_PREFIXES as $prefix) { if (str_starts_with($result->matchedBy, $prefix)) { return true; } } return false; } }