Files
rspade_system/app/RSpade/CodeQuality/Rules/PHP/PhpFallbackLegacy_CodeQualityRule.php
root f6fac6c4bc Fix bin/publish: copy docs.dist from project root
Fix bin/publish: use correct .env path for rspade_system
Fix bin/publish script: prevent grep exit code 1 from terminating script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-21 02:08:33 +00:00

121 lines
7.2 KiB
PHP
Executable File

<?php
namespace App\RSpade\CodeQuality\Rules\PHP;
use App\RSpade\CodeQuality\Rules\CodeQualityRule_Abstract;
class PhpFallbackLegacy_CodeQualityRule extends CodeQualityRule_Abstract
{
public function get_id(): string
{
return 'PHP-FALLBACK-01';
}
public function get_name(): string
{
return 'PHP Fallback/Legacy Code Check';
}
public function get_description(): string
{
return 'Enforces fail-loud principle - no fallback implementations allowed';
}
public function get_file_patterns(): array
{
return ['*.php'];
}
public function get_default_severity(): string
{
return 'critical';
}
/**
* Check PHP file for fallback/legacy code in comments and function calls (from line 1474)
* Enforces fail-loud principle - no fallback implementations allowed
*/
public function check(string $file_path, string $contents, array $metadata = []): void
{
// Skip vendor directories
if (str_contains($file_path, '/vendor/')) {
return;
}
// Skip CodeQuality directory
if (str_contains($file_path, '/CodeQuality/')) {
return;
}
// Skip RsxCheckCommand.php - it documents what the checks do
if (str_contains($file_path, 'RsxCheckCommand.php')) {
return;
}
// Use original content to check comments
$original_content = file_get_contents($file_path);
$lines = explode("\n", $original_content);
foreach ($lines as $line_num => $line) {
$line_number = $line_num + 1;
// Skip line if it's entirely a comment (starts with // after whitespace)
$trimmed_line = trim($line);
$is_line_comment = str_starts_with($trimmed_line, '//');
// Check for fallback or legacy in comments (case insensitive, with word boundaries)
// But allow fallback* or legacy* as marked exceptions
if (preg_match('/\/\/.*\b(fallback|legacy)\b(?!\*)/i', $line) ||
preg_match('/\/\*.*\b(fallback|legacy)\b(?!\*)/i', $line) ||
preg_match('/\*.*\b(fallback|legacy)\b(?!\*)/i', $line) ||
preg_match('/#.*\b(fallback|legacy)\b(?!\*)/i', $line)) { // Also check # comments
$this->add_violation(
$file_path,
$line_number,
"🚨 CRITICAL ARCHITECTURE VIOLATION: 'fallback' or 'legacy' detected - STOP IMMEDIATELY\n\nThis is NOT just a naming issue. The presence of 'fallback/legacy' often indicates:\n1. DEAD CODE handling conditions that no longer occur\n2. DUPLICATE IMPLEMENTATIONS still partially present\n3. INCOMPLETE MIGRATION from old to new systems\n4. VIOLATION TYPE HANDLERS for deprecated systems",
trim($line),
"REQUIRED IMMEDIATE ACTIONS:\n1. INVESTIGATE: Is this code actually reachable? Run grep for the condition it handles\n2. TRACE: What system/feature does this reference? Does it still exist anywhere?\n3. SEARCH: Are there duplicate implementations? (grep for related terms)\n4. VERIFY: If it's display code, does the violation type still get produced?\n\nFor AI/LLM agents: This is a P0 STOP-THE-WORLD violation. You MUST:\n- Immediately search for what triggers this code path\n- Report ALL findings to the user before making ANY changes\n- NEVER just rename or mark with asterisk without investigation\n- If dead code found, remove entirely (don't comment out)\n\nRemember: Dead fallback code is technical debt that causes debugging nightmares.\nEvery 'fallback' is a potential duplicate implementation waiting to cause PTSD.\n\nTo mark legitimate uses (extremely rare), add '*' after the word.",
'critical'
);
}
// Check for dual implementation patterns in single-line comments
// These patterns suggest old/new dual implementations which violate the no-fallback rule
if (preg_match('/\/\/.*\bold\W+.*\bnew\b/i', $line) || // "old" ... "new"
preg_match('/\/\/.*\bprevious\W+.*\bnew\b/i', $line) || // "previous" ... "new"
preg_match('/\/\/.*\bbackwards?\s+compatability/i', $line)) { // "backward(s) compatibility" (common misspelling)
$this->add_violation(
$file_path,
$line_number,
"🚨 CRITICAL DUAL IMPLEMENTATION VIOLATION: Comment suggests old/new or backwards compatibility patterns\n\nThis violates the fundamental architecture principle: There is NO 'old' and 'new' way - there is ONLY THE WAY.\nDual implementations cause:\n1. CONFUSION about which code path executes\n2. DUPLICATE CODE that diverges over time\n3. DEBUGGING NIGHTMARES when behavior differs\n4. MAINTENANCE BURDEN keeping both paths in sync",
trim($line),
"IMMEDIATE ACTION REQUIRED:\n1. IDENTIFY what 'old' vs 'new' refers to\n2. REMOVE the old implementation entirely\n3. UPDATE all references to use the single implementation\n4. DO NOT maintain backwards compatibility\n\nFor AI/LLM agents: This is a CRITICAL violation. You MUST:\n- Search for BOTH implementations referenced in the comment\n- Report findings to user before making changes\n- Remove the OLD implementation completely\n- Update all code to use the single 'new' (current) way\n- NEVER maintain dual implementations for compatibility\n\nRemember: There is only ONE way to do things. What's currently called 'new' IS the way.",
'critical'
);
}
// Check for function calls starting or ending with 'fallback'
// This catches: fallback(), fallback_loader(), $this->loader_fallback(), etc.
// But NOT: $this->document_fallback_loader() (fallback in middle)
if (!$is_line_comment) {
// Remove inline comments before checking
$code_part = preg_replace('/\/\/.*$/', '', $line);
$code_part = preg_replace('/\/\*.*?\*\//', '', $code_part);
// Check if function starting or ending with "fallback" exists in non-comment part
if (preg_match('/\b(fallback\w*|\w+fallback)\s*\(/i', $code_part)) {
$this->add_violation(
$file_path,
$line_number,
"🚨 CRITICAL: Fallback function call detected - INVESTIGATE IMMEDIATELY\n\nThis function name suggests duplicate implementation or legacy code path.",
trim($line),
"REQUIRED ACTIONS:\n1. TRACE where this function is defined and what calls it\n2. CHECK if this is handling a deprecated code path\n3. VERIFY no duplicate implementations exist\n4. If legitimate (rare), rename to describe actual purpose\n\nFor AI/LLM: STOP and investigate before ANY changes. Search for:\n- Function definition\n- All callers of this function\n- Related implementations\n\nNEVER just rename without understanding the full context.",
'critical'
);
}
}
}
}
}