CoolFace
Apppublic

onlycoding135/constrained-refactor-gauntlet

sourceHugging Faceupdated 5mo agoView on Hugging Face
0likes
generate_rules_v2.py206 linesDownload Raw Back to root
1import json2import os3 4rules = []5 6def add_rule(rid, cat, desc, check, spawns=None):7    if spawns is None:8        spawns = []9    rules.append({10        "id": rid,11        "category": cat,12        "description": desc,13        "trigger_condition": "edit_file",14        "check_condition": check,15        "spawns": spawns16    })17 18# STYLE19add_rule(1, "STYLE", "Function names must be snake_case.", r'regex pattern: r"def [a-z_0-9]+\("', [])20add_rule(2, "STYLE", "Class names must be CamelCase.", r'regex pattern: r"class [A-Z][a-zA-Z0-9]+\("', [])21add_rule(3, "STYLE", "Constants must be UPPER_SNAKE_CASE.", r'regex pattern: r"^[A-Z_0-9]+ = "', [])22add_rule(4, "STYLE", "Indentation must be exactly 4 spaces.", r'regex pattern: r"^ {4}[^ ]"', [])23add_rule(5, "STYLE", "No trailing whitespace allowed.", r'regex:no pattern match: [ \t]+$', [])24add_rule(6, "STYLE", "Maximum line length is 88 characters.", 'subprocess:ruff check passes', [])25add_rule(7, "STYLE", "All imports must be grouped: stdlib first, then third-party, then local.", 'subprocess:ruff check passes', [])26add_rule(8, "STYLE", "No wildcard imports allowed.", r'regex:no pattern match: from \w+ import \*', [])27add_rule(9, "STYLE", "Variables must be snake_case.", r'regex pattern: r"[a-z_0-9]+ = "', [])28add_rule(10, "STYLE", "Use single quotes for string literals.", r"regex pattern: r'.*'", [])29add_rule(11, "STYLE", "Use double quotes for docstrings.", r'regex pattern: r"\"\"\"(.*)\"\"\""', [])30add_rule(12, "STYLE", "Functions under 5 lines must have no inline comments.", 'ast_check:line_count <= 5', [])31add_rule(13, "STYLE", "Comments must have a space after the hash symbol.", r'regex pattern: r"# [A-Z]"', [])32add_rule(14, "STYLE", "No consecutive blank lines greater than 2.", r'regex:no pattern match: \n\n\n', [])33add_rule(15, "STYLE", "Use f-strings over .format().", r'regex pattern: r"f\'.*\'"', [])34add_rule(16, "STYLE", "No % formatting allowed.", r'regex:no pattern match: %\s*\w+', [])35add_rule(17, "STYLE", "Docstrings must use Sphinx format.", r'regex pattern: r":param|:return:"', [])36add_rule(18, "STYLE", "Return type annotations are required for all functions.", 'ast_check:has_type_hints', [])37add_rule(19, "STYLE", "Argument type annotations are required for all functions.", 'ast_check:has_type_hints', [])38add_rule(20, "STYLE", "All methods must have self or cls as first argument.", r'regex pattern: r"def \w+\((self|cls)"', [])39add_rule(21, "STYLE", "Private methods must start with an underscore.", r'regex pattern: r"def _[a-z_]+\("', [])40add_rule(22, "STYLE", "Dictionary keys must be strings explicitly.", r'regex pattern: r"\{[\'\"].*[\'\"]:"', [])41add_rule(23, "STYLE", "List comprehensions preferred over map function.", r'regex:no pattern match: map\(', [])42add_rule(24, "STYLE", "Generator expressions preferred over filter function.", r'regex:no pattern match: filter\(', [])43add_rule(25, "STYLE", "Use 'is' for None comparisons.", r'regex pattern: r"is None"', [])44add_rule(26, "STYLE", "Do not use == True or == False.", r'regex:no pattern match: == True|== False', [])45add_rule(27, "STYLE", "Explicit Exception names must be used in except blocks.", 'ast_check:no_bare_except', [])46add_rule(28, "STYLE", "Use context managers for file operations.", r'regex pattern: r"with open\("', [])47add_rule(29, "STYLE", "All functions must have docstrings.", 'ast_check:has_docstring', [12, 91, 118])48add_rule(30, "STYLE", "Module level docstring is required.", 'ast_check:has_docstring', [])49 50# STRUCTURAL51add_rule(31, "STRUCTURAL", "File must have a main block execution guard.", r'regex pattern: r"if __name__ == \"__main__\":"', [])52add_rule(32, "STRUCTURAL", "Classes should have an __init__ method.", r'regex pattern: r"def __init__\("', [])53add_rule(33, "STRUCTURAL", "Methods should not exceed 100 lines.", 'ast_check:line_count <= 100', [])54add_rule(34, "STRUCTURAL", "Classes should not exceed 500 lines.", 'ast_check:line_count <= 500', [])55add_rule(35, "STRUCTURAL", "No deeply nested loops (greater than 3 levels).", r'regex:no pattern match: for.*:\n\s*for.*:\n\s*for.*:\n\s*for', [])56add_rule(36, "STRUCTURAL", "Maximum 5 arguments per function.", 'subprocess:ruff check passes', [])57add_rule(37, "STRUCTURAL", "No global state modification allowed.", r'regex:no pattern match: global \w+', [])58add_rule(38, "STRUCTURAL", "Helper functions must be prefixed with utils_.", r'regex pattern: r"def utils_[a-z_]+\("', [])59add_rule(39, "STRUCTURAL", "Config files must be parsed using json or yaml load.", r'regex pattern: r"json\.load|yaml\.safe_load"', [])60add_rule(40, "STRUCTURAL", "FastAPI app instances must be named app.", r'regex pattern: r"app = FastAPI\("', [])61add_rule(41, "STRUCTURAL", "Routers must be named router.", r'regex pattern: r"router = APIRouter\("', [])62add_rule(42, "STRUCTURAL", "I/O bound functions must be async.", r'regex pattern: r"async def"', [])63add_rule(43, "STRUCTURAL", "Models must inherit from Pydantic BaseModel.", r'regex pattern: r"class \w+\(BaseModel\):"', [])64add_rule(44, "STRUCTURAL", "No file may exceed 200 lines.", 'ast_check:line_count <= 200', [91, 17])65add_rule(45, "STRUCTURAL", "Controllers must be placed in controllers directory.", 'file_exists:controllers', [])66add_rule(46, "STRUCTURAL", "Services must be placed in services directory.", 'file_exists:services', [])67add_rule(47, "STRUCTURAL", "Utilities must be placed in utils directory.", 'file_exists:utils', [])68add_rule(48, "STRUCTURAL", "Data Transfer Objects must be explicitly defined with DTO suffix.", r'regex pattern: r"class \w+DTO\("', [])69add_rule(49, "STRUCTURAL", "Responses must use a generic ResponseWrapper.", r'regex pattern: r"ResponseWrapper"', [])70add_rule(50, "STRUCTURAL", "Repositories must use SQLAlchemy Session.", r'regex pattern: r"Session"', [])71add_rule(51, "STRUCTURAL", "Custom exceptions must inherit from AppError.", r'regex pattern: r"class \w+\(AppError\):"', [])72add_rule(52, "STRUCTURAL", "Decorators must be used for authentication.", r'regex pattern: r"@requires_auth"', [])73add_rule(53, "STRUCTURAL", "Enums must be used for defining statuses.", r'regex pattern: r"class \w+\(Enum\):"', [])74add_rule(54, "STRUCTURAL", "Factory pattern must be used for complex object creation.", r'regex pattern: r"def create_\w+\("', [])75add_rule(55, "STRUCTURAL", "No function may exceed 50 lines.", 'ast_check:line_count <= 50', [56, 103])76add_rule(56, "STRUCTURAL", "All modules must be registered in module_registry.json.", 'json_contains:module_registry.json', [])77add_rule(57, "STRUCTURAL", "Test files must end in _test.py.", r'regex pattern: r".*_test\.py"', [])78add_rule(58, "STRUCTURAL", "Fixtures must reside in conftest.py.", 'file_exists:conftest.py', [])79add_rule(59, "STRUCTURAL", "Interfaces must inherit from ABC.", r'regex pattern: r"class \w+\(ABC\):"', [])80add_rule(60, "STRUCTURAL", "Only a single class is permitted per file.", 'subprocess:ruff check passes', [])81add_rule(61, "STRUCTURAL", "Pydantic must be used for all data validation.", r'regex pattern: r"from pydantic"', [])82add_rule(62, "STRUCTURAL", "TypeVars must be named explicitly.", r'regex pattern: r"\w+ = TypeVar\("', [])83add_rule(63, "STRUCTURAL", "Try blocks should not exceed 5 lines.", 'ast_check:line_count <= 5', [])84add_rule(64, "STRUCTURAL", "Finally blocks are required for cleanup operations.", r'regex pattern: r"finally:"', [])85add_rule(65, "STRUCTURAL", "Custom exceptions must initialize with messages.", r'regex pattern: r"super\(\)\.__init__\("', [])86add_rule(66, "STRUCTURAL", "Loggers must be instantiated with __name__.", r'regex pattern: r"logging\.getLogger\(__name__\)"', [])87add_rule(67, "STRUCTURAL", "Config must be injected via Dependency Injection.", r'regex pattern: r"Depends\(get_config\)"', [])88add_rule(68, "STRUCTURAL", "Data classes should be used for internal state.", r'regex pattern: r"@dataclass"', [])89add_rule(69, "STRUCTURAL", "Yield is preferred for processing large sequences.", r'regex pattern: r"yield "', [])90add_rule(70, "STRUCTURAL", "Properties must be used for computed class attributes.", r'regex pattern: r"@property"', [])91 92# SECURITY93add_rule(71, "SECURITY", "Passwords must be hashed before storage.", r'regex pattern: r"hash_password\("', [])94add_rule(72, "SECURITY", "Authentication tokens must use JWT.", r'regex pattern: r"jwt\.encode\("', [])95add_rule(73, "SECURITY", "Secrets must be loaded from the environment.", r'regex pattern: r"os\.getenv\("', [])96add_rule(74, "SECURITY", "No hardcoded API keys are allowed.", r'regex:no pattern match: api_key = [\'"][A-Za-z0-9]+[\'"]', [])97add_rule(75, "SECURITY", "CORS headers are required for all endpoints.", r'regex pattern: r"CORSMiddleware"', [])98add_rule(76, "SECURITY", "CSRF protection must be enabled.", r'regex pattern: r"csrf_protect\("', [])99add_rule(77, "SECURITY", "Rate limiting must be applied to public routes.", r'regex pattern: r"@limiter\.limit"', [])100add_rule(78, "SECURITY", "Content-Security-Policy header must be set.", r'regex pattern: r"Content-Security-Policy"', [])101add_rule(79, "SECURITY", "SQL injection prevention: no f-strings in database queries.", r'regex:no pattern match: execute\(f".*"\)', [])102add_rule(80, "SECURITY", "XSS prevention: user input must be escaped in HTML.", r'regex pattern: r"escape\("', [])103add_rule(81, "SECURITY", "Use safe_load for YAML parsing to prevent code execution.", r'regex pattern: r"yaml\.safe_load\("', [])104add_rule(82, "SECURITY", "Use defusedxml for parsing XML to prevent external entity attacks.", r'regex pattern: r"from defusedxml"', [])105add_rule(83, "SECURITY", "No hardcoded secrets allowed in the codebase.", r'regex:no pattern match: password|secret|key', [134])106add_rule(84, "SECURITY", "Auth tokens must expire in less than 1 hour.", r'regex pattern: r"exp=datetime\.utcnow\(\) \+ timedelta\(minutes=[1-5][0-9]\)"', [])107add_rule(85, "SECURITY", "Cookies must be marked as secure and httponly.", r'regex pattern: r"secure=True, httponly=True"', [])108add_rule(86, "SECURITY", "SSL verification must not be disabled in requests.", r'regex:no pattern match: verify=False', [])109add_rule(87, "SECURITY", "Hashlib must use sha256 or a stronger algorithm.", r'regex:no pattern match: hashlib\.md5|hashlib\.sha1', [])110add_rule(88, "SECURITY", "The secrets module must be used for cryptographically secure randomness.", r'regex pattern: r"import secrets"', [])111add_rule(89, "SECURITY", "The eval and exec functions are strictly prohibited.", r'regex:no pattern match: eval\(|exec\(', [])112add_rule(90, "SECURITY", "Subprocess calls must not use shell=True.", r'regex:no pattern match: shell=True', [])113add_rule(91, "SECURITY", "Timeout must be specified on all HTTP calls.", r'regex pattern: r"timeout=[0-9.]+"', [])114add_rule(92, "SECURITY", "PII data must be masked in application output.", r'regex pattern: r"mask_pii\("', [])115add_rule(93, "SECURITY", "Prevent directory traversal by securing file paths.", r'regex pattern: r"os\.path\.abspath|secure_filename"', [])116add_rule(94, "SECURITY", "S3 buckets must not have public-read access control lists.", r"regex:no pattern match: ACL='public-read'", [])117add_rule(95, "SECURITY", "Debug mode must be explicitly disabled in production.", r'regex pattern: r"debug=False"', [])118add_rule(96, "SECURITY", "JWT verification must be strictly enforced.", r'regex pattern: r"verify_signature=True"', [])119add_rule(97, "SECURITY", "Role-based access control must be verified before sensitive operations.", r'regex pattern: r"check_role\("', [])120add_rule(98, "SECURITY", "User input sizes must be limited to 1MB.", r'regex pattern: r"Content-Length.*< 1048576"', [])121add_rule(99, "SECURITY", "Audit logging is required for all administrative actions.", r'regex pattern: r"audit_logger\.info\("', [])122add_rule(100, "SECURITY", "User IDs must be obfuscated in application logs.", r'regex pattern: r"obfuscate_id\("', [])123 124# CONDITIONAL125add_rule(101, "CONDITIONAL", "If a route uses the POST method, it must return a 201 status code.", r'regex pattern: r"status_code=201"', [])126add_rule(102, "CONDITIONAL", "If a route uses the DELETE method, it must return a 204 status code.", r'regex pattern: r"status_code=204"', [])127add_rule(103, "CONDITIONAL", "If a file exceeds 200 lines, it must be split into multiple modules.", 'ast_check:line_count <= 200', [])128add_rule(104, "CONDITIONAL", "If a database model is updated, the Pydantic schema must also be updated.", 'rule_satisfied:43', [])129add_rule(105, "CONDITIONAL", "If caching is used, a Time-To-Live (TTL) must be explicitly set.", r'regex pattern: r"ttl=[0-9]+"', [])130add_rule(106, "CONDITIONAL", "If a route is async, it must use the await keyword internally.", r'regex pattern: r"await "', [])131add_rule(107, "CONDITIONAL", "If data is paginated, the response must include total_pages metadata.", r'regex pattern: r"total_pages"', [])132add_rule(108, "CONDITIONAL", "If a new environment variable is added, it must be documented in README.md.", 'file_exists:README.md', [])133add_rule(109, "CONDITIONAL", "If HTTP requests are made, the httpx library is preferred over requests.", r'regex:no pattern match: import requests', [])134add_rule(110, "CONDITIONAL", "If a dependency is injected, it must enable caching.", r'regex pattern: r"Depends\(.*use_cache=True\)"', [])135add_rule(111, "CONDITIONAL", "If a list is returned from an endpoint, it must be wrapped in a dictionary.", r'regex pattern: r"\{\"data\": \["', [])136add_rule(112, "CONDITIONAL", "If a custom Exception is raised, it must be logged prior.", r'regex pattern: r"logger\.error.*raise"', [])137add_rule(113, "CONDITIONAL", "If debug mode is true, verbose logging must be enabled.", 'rule_satisfied:95', [])138add_rule(114, "CONDITIONAL", "If a retry loop is implemented, a backoff factor must be configured.", r'regex pattern: r"backoff_factor"', [])139add_rule(115, "CONDITIONAL", "If a metric is emitted, it must include identifying tags.", r'regex pattern: r"tags=\{"', [])140add_rule(116, "CONDITIONAL", "If an email is sent, it must be executed as a background task.", r'regex pattern: r"background_tasks\.add_task"', [])141add_rule(117, "CONDITIONAL", "If the database is queried, a session context manager must be used.", r'regex pattern: r"with get_session\(\):"', [])142add_rule(118, "CONDITIONAL", "If an HTTP call is added, Rule 91 must be satisfied.", 'rule_satisfied:91', [])143add_rule(119, "CONDITIONAL", "If a custom JSON response is returned, the content-type must be application/json.", r'regex pattern: r"application/json"', [])144add_rule(120, "CONDITIONAL", "If an external API fails, the service must raise a 502 Bad Gateway.", r'regex pattern: r"status_code=502"', [])145add_rule(121, "CONDITIONAL", "If a UUID is generated, it must strictly be UUID4.", r'regex pattern: r"uuid4\("', [])146add_rule(122, "CONDITIONAL", "If a timezone is parsed, it must be normalized to UTC.", r'regex pattern: r"timezone\.utc"', [])147add_rule(123, "CONDITIONAL", "If a file is uploaded, it must be scanned for viruses.", r'regex pattern: r"scan_file\("', [])148add_rule(124, "CONDITIONAL", "If a user password is changed, all active sessions must be invalidated.", r'regex pattern: r"invalidate_sessions\("', [])149add_rule(125, "CONDITIONAL", "If an account is deleted, a soft delete is preferred over a hard delete.", r'regex pattern: r"is_deleted=True"', [])150add_rule(126, "CONDITIONAL", "If monetary values are calculated, the Decimal type must be used.", r'regex pattern: r"Decimal\("', [])151add_rule(127, "CONDITIONAL", "If float values are compared, math.isclose must be utilized.", r'regex pattern: r"math\.isclose\("', [])152add_rule(128, "CONDITIONAL", "If the random module is used, a seed is required for deterministic testing.", r'regex pattern: r"random\.seed\("', [])153add_rule(129, "CONDITIONAL", "If a singleton is instantiated, thread safety via locks is required.", r'regex pattern: r"Lock\(\)"', [])154add_rule(130, "CONDITIONAL", "If a subprocess command fails, stderr must be explicitly captured.", r'regex pattern: r"capture_output=True"', [])155 156# CONTRADICTORY157add_rule(131, "CONTRADICTORY", "All functions must use type hints for all arguments. (Conflicts with Rule 132)", 'ast_check:has_type_hints', [])158add_rule(132, "CONTRADICTORY", "Functions under 10 lines must avoid type hints to reduce visual clutter. (Conflicts with Rule 131)", r'regex:no pattern match: :[ a-zA-Z]+', [])159add_rule(133, "CONTRADICTORY", "Environment variables must be parsed strictly using a schema. (Conflicts with Rule 134)", r'regex pattern: r"EnvSchema\.parse_obj"', [])160add_rule(134, "CONTRADICTORY", "Secrets must be hardcoded in dev mode for ease of use. (Conflicts with Rule 133)", r'regex pattern: r"secret_key=\"dev_secret\""', [29])161add_rule(135, "CONTRADICTORY", "All database interactions must use raw SQL queries for performance reasons. (Conflicts with Rule 136)", r'regex pattern: r"cursor\.execute\(\"SELECT"', [])162add_rule(136, "CONTRADICTORY", "All database interactions must use an ORM to prevent SQL injection. (Conflicts with Rule 135)", r'regex pattern: r"session\.query\("', [])163add_rule(137, "CONTRADICTORY", "External API calls must catch all exceptions generically to prevent crashes. (Conflicts with Rule 138)", r'regex pattern: r"except Exception:"', [])164add_rule(138, "CONTRADICTORY", "External API calls must only catch specific exceptions like HTTPError. (Conflicts with Rule 137)", r'regex pattern: r"except httpx\.HTTPError:"', [])165add_rule(139, "CONTRADICTORY", "Logging must capture every request payload entirely for auditing purposes. (Conflicts with Rule 140)", r'regex pattern: r"logger\.info\(request\.body\)"', [])166add_rule(140, "CONTRADICTORY", "Logging must never capture request payloads to protect PII. (Conflicts with Rule 139)", r'regex:no pattern match: logger\.info\(request\.body\)', [])167add_rule(141, "CONTRADICTORY", "All endpoints must require an Authorization header. (Conflicts with Rule 144)", r'regex pattern: r"Header\(.*Authorization\)"', [])168add_rule(142, "CONTRADICTORY", "All functions must have inline comments explaining internal logic. (Conflicts with Rule 143)", r'regex pattern: r".*#.*"', [])169add_rule(143, "CONTRADICTORY", "Functions under 5 lines must have NO inline comments. (Conflicts with Rule 142)", 'ast_check:line_count <= 5', [])170add_rule(144, "CONTRADICTORY", "Public endpoints like /health must accept unauthenticated requests. (Conflicts with Rule 141)", r'regex:no pattern match: Header\(.*Authorization\)', [])171add_rule(145, "CONTRADICTORY", "Modules should import specific functions individually (from x import y). (Conflicts with Rule 146)", r'regex pattern: r"from \w+ import \w+"', [])172add_rule(146, "CONTRADICTORY", "Modules should import the whole package to prevent namespace collisions (import x). (Conflicts with Rule 145)", r'regex pattern: r"import \w+"', [])173add_rule(147, "CONTRADICTORY", "JSON responses must use camelCase keys for JavaScript compatibility. (Conflicts with Rule 148)", r'regex pattern: r"userName:"', [])174add_rule(148, "CONTRADICTORY", "JSON responses must use snake_case keys for Python consistency. (Conflicts with Rule 147)", r'regex pattern: r"user_name:"', [])175add_rule(149, "CONTRADICTORY", "Temporary files must be created in /tmp directly. (Conflicts with Rule 150)", r'regex pattern: r"open\(\'/tmp/.*\'\)"', [])176add_rule(150, "CONTRADICTORY", "Temporary files must use the tempfile module for secure generation. (Conflicts with Rule 149)", r'regex pattern: r"tempfile\.NamedTemporaryFile"', [])177 178# Sort rules by ID to ensure sequence179rules.sort(key=lambda x: x["id"])180 181# Generate markdown182output = []183output.append("# ENGINEERING STANDARDS")184output.append("")185 186current_category = ""187for rule in rules:188    if rule["category"] != current_category:189        current_category = rule["category"]190        output.append(f"## {current_category} RULES")191        output.append("")192    193    output.append(f"### Rule {rule['id']}")194    output.append(f"**Category**: {rule['category']}")195    output.append(f"**Description**: {rule['description']}")196    output.append(f"**Trigger condition**: {rule['trigger_condition']}")197    output.append(f"**Check condition**: {rule['check_condition']}")198    output.append(f"**Spawns**: {json.dumps(rule['spawns'])}")199    output.append("")200 201output_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), "environment", "ENGINEERING_STANDARDS.md")202with open(output_path, "w") as f:203    f.write("\n".join(output))204 205print("DONE")206